[
  {
    "path": ".clangd",
    "content": "Diagnostics:\n  Suppress: 'pp_including_mainfile_in_preamble'\n\nInlayHints:\n  Enabled: No\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "*                    @Belliash\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--\n    1. Please speak English, this is the language all of us can speak and write.\n    2. Please take a moment to check that your issue doesn't already exist.\n    3. Please give all relevant information below for bug reports, because \n       incomplete details will be handled as an invalid report.\n-->\n\n## ExectOS Information\n - ExectOS Version (or commit ref):\n - System Architecture (eg. i686, amd64, ...):\n - Hypervisor Information (use `[X]`):\n   - [ ] Bare metal\n   - [ ] Bochs\n   - [ ] Hyper-V\n   - [ ] Qemu (KVM)\n   - [ ] Qemu (TCG)\n   - [ ] VirtualBox\n   - [ ] VmWare\n   - [ ] Other\n\n## Your problem description\nPlease provide here as much information as possible, including a code snippet if applicable.\n\n## Expected results\nDescribe here, what output and/or software behave did you expect.\n\n## Current results\nProvide here current result and program output.\n\n## Debug backtrace and logs\nProvide here logs and debug bugtrace if applicable.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\n    1. Please speak English, this is the language all of us can speak and write.\n    2. Please follow the CONTRIBUTING.md to make your changes smoothly merged.\n-->\n\n## Purpose\n_Do a quick recap of your work here._\n_If it fixes some bug, don't forget to mention it here._\n\n## Proposed changes\n_Describe what you propose to change/add/fix with this pull request._\n- \n- \n\n## TODO\n_Use a TODO when your pull request is Work in Progress._\n- [ ] \n- [ ] \n- [ ]\n\n## Agreements\n- [ ] I have read the Contributors License Agreement and I consent to those terms.\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Builds\nrun-name: ${{ github.actor }} runs Gitea Actions\non: [push]\n\njobs:\n  ExectOS:\n    strategy:\n      matrix:\n        arch: [amd64, i686]\n        build: [debug, release]\n    runs-on: oscw\n    container:\n      image: codingworkshop/oscw-runner:latest\n    steps:\n      - name: Clone repository\n        uses: actions/checkout@v3\n        with:\n          fetch-depth: 0\n      - name: Build ExectOS\n        run: |\n          echo \"charch ${{ matrix.arch }} && chbuild ${{ matrix.build }} && ./configure.sh && cd build-${{ matrix.arch }}-${{ matrix.build }} && xbuild -v && xbuild diskimg -v\" > build.cmds\n          xtchain < build.cmds\n      - name: Publish binaries\n        if: ${{ github.ref == 'refs/heads/master' }}\n        env:\n          OSCW_ARTIFACTS_HOSTNAME: ${{ secrets.OSCW_ARTIFACTS_HOSTNAME }}\n          OSCW_ARTIFACTS_USERNAME: ${{ secrets.OSCW_ARTIFACTS_USERNAME }}\n          OSCW_ARTIFACTS_USERKEY: ${{ secrets.OSCW_ARTIFACTS_USERKEY }}\n        run: |\n          tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-bin.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/binaries .\n          tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-sdk.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/sdk .\n          tar -I 'gzip' -cpf ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}-sym.tar.gz -C build-${{ matrix.arch }}-${{ matrix.build }}/output/symbols .\n          gzip -c build-${{ matrix.arch }}-${{ matrix.build }}/output/disk.img > ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}.img.gz\n          artifact_publish \"ExectOS-$(date +'%Y%m%d')-${GITHUB_SHA:0:10}-${{ matrix.arch }}-${{ matrix.build }}*.gz\" ExectOS\n"
  },
  {
    "path": ".gitignore",
    "content": ".cache\n.vscode\nbuild\nbuild-*\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "# Minimum CMake version requirement\ncmake_minimum_required(VERSION 3.19.0)\n\n# Lowercase target architecture\nstring(TOLOWER ${ARCH} ARCH)\n\n# Validate and set architectures specific definitions\nif(ARCH STREQUAL \"i686\")\n    add_definitions(-D__i386__ -D__i686__)\nelseif(ARCH STREQUAL \"amd64\")\n    add_definitions(-D__amd64__ -D__x86_64__)\nelse()\n    message(FATAL_ERROR \"Unknown target architecture (${ARCH}) set!\")\nendif()\n\n# Print target architecture\nmessage(\"-- Target architecture: ${ARCH}\")\n\n# Set the build type\nif(NOT BUILD_TYPE)\n    set(BUILD_TYPE DEBUG)\nendif()\nstring(TOUPPER ${BUILD_TYPE} BUILD_TYPE)\n\n# Set build type specific definitions\nif(BUILD_TYPE STREQUAL \"DEBUG\")\n    add_definitions(-DDBG=1)\n    set(CMAKE_BUILD_TYPE DEBUG)\nelse()\n    set(BUILD_TYPE RELEASE)\n    set(CMAKE_BUILD_TYPE NONE)\nendif()\n\n# Print build type\nmessage(\"-- Target build type: ${BUILD_TYPE}\")\n\n# Set toolchain file\nset(CMAKE_TOOLCHAIN_FILE \"sdk/cmake/toolchain.cmake\")\n\n# Set project name\nproject(EXECTOS)\n\n# Load all the CMake SDK\ninclude(sdk/cmake/baseaddress/${ARCH}.cmake)\ninclude(sdk/cmake/emulation.cmake)\ninclude(sdk/cmake/functions.cmake)\ninclude(sdk/cmake/version.cmake)\ninclude(sdk/cmake/xtchain.cmake)\n\n# Enable compilers\nenable_language(ASM C CXX)\n\n# Add project specific definitions\nadd_definitions(-D__XTOS__)\nadd_definitions(-DXTOS_SOURCE_DIR=\"${EXECTOS_SOURCE_DIR}\")\nadd_definitions(-DXTOS_BINARY_DIR=\"${EXECTOS_BINARY_DIR}\")\n\n# Add assembler flags\nadd_compiler_asmflags(-D__XTOS_ASSEMBLER__)\n\n# Compute __FILE__ definition\nfile(RELATIVE_PATH _PATH_PREFIX ${EXECTOS_BINARY_DIR} ${EXECTOS_SOURCE_DIR})\nadd_compiler_flags(-D__RELFILE__=\"&__FILE__[__FILE__[0] == '.' ? sizeof \\\\\\\"${_PATH_PREFIX}\\\\\\\" - 1 : sizeof XTOS_SOURCE_DIR]\")\n\n# Set the virtual disk image size (in MiB)\nset_disk_image_size(48)\n\n# Build all subprojects\nadd_subdirectory(boot)\nadd_subdirectory(drivers)\nadd_subdirectory(sdk)\nadd_subdirectory(xtoskrnl)\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## Contributing\nWe appreciate any form for contribution you want to make to the project! ExectOS is purely driven by passion, and we\ndedicate any and all available spare time to this project. Contributions of any kind are deerly welcome, but should\nfollow the below guidelines.\n\n## Where To Start?\nThere is a ton of work to do in ExectOS and we appreciate any help. If you are interested in writing features,\nporting drivers, fixing bugs, writing tests, creating documentation, or helping out in any other way, we would\nlove the help.\n\n## Wish List\nIf you are looking for a way to contribute, but you are not sure where to start, check our list of\n[open issues](https://git.codingworkshop.eu.org/xt-sys/exectos/issues). If you find interesting task and you are serious\nabout tackling one, feel free to contact us. We will be able to provide a more detailed information and suggestions\ntowards getting started.\n\n## Reporting Bugs\nWhen submitting issues, please take care that the bug report is not a duplicate of an already existing, open issue.\nPlease follow the template specified for issues.\n\n## Feature Requests\nExectOS is currently in early development stage, thus we do not accept feature requests yet. We focus currently on the\nsystem core components.\n\n## Submissions\nIf you want to contribute on the project please fork the repository, and contribute by opening a \n[Pull Request](https://git.codingworkshop.eu.org/xt-sys/exectos/pulls). There is a pull request template you can use.\nWhile doing this, please follow few, simple rules:\n * Provide your real name and e-mail address\n * Do not commit code that doesn't compile\n * Test your changes before committing\n * Always add descriptive log messages\n * Don't mix formatting changes with code changes\n\nGood luck!\n"
  },
  {
    "path": "COPYING.md",
    "content": "# GNU GENERAL PUBLIC LICENSE\nVersion 3, 29 June 2007\n\nCopyright (C) 2007 [Free Software Foundation, Inc.](http://fsf.org/)\n\nEveryone is permitted to copy and distribute verbatim copies of this license\ndocument, but changing it is not allowed.\n\n## Preamble\n\nThe GNU General Public License is a free, copyleft license for software and\nother kinds of works.\n\nThe licenses for most software and other practical works are designed to take\naway your freedom to share and change the works. By contrast, the GNU General\nPublic License is intended to guarantee your freedom to share and change all\nversions of a program--to make sure it remains free software for all its users.\nWe, the Free Software Foundation, use the GNU General Public License for most\nof our software; it applies also to any other work released this way by its\nauthors. You can apply it to your programs, too.\n\nWhen we speak of free software, we are referring to freedom, not price. Our\nGeneral Public Licenses are designed to make sure that you have the freedom to\ndistribute copies of free software (and charge for them if you wish), that you\nreceive source code or can get it if you want it, that you can change the\nsoftware or use pieces of it in new free programs, and that you know you can do\nthese things.\n\nTo protect your rights, we need to prevent others from denying you these rights\nor asking you to surrender the rights. Therefore, you have certain\nresponsibilities if you distribute copies of the software, or if you modify it:\nresponsibilities to respect the freedom of others.\n\nFor example, if you distribute copies of such a program, whether gratis or for\na fee, you must pass on to the recipients the same freedoms that you received.\nYou must make sure that they, too, receive or can get the source code. And you\nmust show them these terms so they know their rights.\n\nDevelopers that use the GNU GPL protect your rights with two steps:\n\n  1. assert copyright on the software, and\n  2. offer you this License giving you legal permission to copy, distribute\n     and/or modify it.\n\nFor the developers' and authors' protection, the GPL clearly explains that\nthere is no warranty for this free software. For both users' and authors' sake,\nthe GPL requires that modified versions be marked as changed, so that their\nproblems will not be attributed erroneously to authors of previous versions.\n\nSome devices are designed to deny users access to install or run modified\nversions of the software inside them, although the manufacturer can do so. This\nis fundamentally incompatible with the aim of protecting users' freedom to\nchange the software. The systematic pattern of such abuse occurs in the area of\nproducts for individuals to use, which is precisely where it is most\nunacceptable. Therefore, we have designed this version of the GPL to prohibit\nthe practice for those products. If such problems arise substantially in other\ndomains, we stand ready to extend this provision to those domains in future\nversions of the GPL, as needed to protect the freedom of users.\n\nFinally, every program is threatened constantly by software patents. States\nshould not allow patents to restrict development and use of software on\ngeneral-purpose computers, but in those that do, we wish to avoid the special\ndanger that patents applied to a free program could make it effectively\nproprietary. To prevent this, the GPL assures that patents cannot be used to\nrender the program non-free.\n\nThe precise terms and conditions for copying, distribution and modification\nfollow.\n\n## TERMS AND CONDITIONS\n\n### 0. Definitions.\n\n*This License* refers to version 3 of the GNU General Public License.\n\n*Copyright* also means copyright-like laws that apply to other kinds of works,\nsuch as semiconductor masks.\n\n*The Program* refers to any copyrightable work licensed under this License.\nEach licensee is addressed as *you*. *Licensees* and *recipients* may be\nindividuals or organizations.\n\nTo *modify* a work means to copy from or adapt all or part of the work in a\nfashion requiring copyright permission, other than the making of an exact copy.\nThe resulting work is called a *modified version* of the earlier work or a work\n*based on* the earlier work.\n\nA *covered work* means either the unmodified Program or a work based on the\nProgram.\n\nTo *propagate* a work means to do anything with it that, without permission,\nwould make you directly or secondarily liable for infringement under applicable\ncopyright law, except executing it on a computer or modifying a private copy.\nPropagation includes copying, distribution (with or without modification),\nmaking available to the public, and in some countries other activities as well.\n\nTo *convey* a work means any kind of propagation that enables other parties to\nmake or receive copies. Mere interaction with a user through a computer\nnetwork, with no transfer of a copy, is not conveying.\n\nAn interactive user interface displays *Appropriate Legal Notices* to the\nextent that it includes a convenient and prominently visible feature that\n\n  1. displays an appropriate copyright notice, and\n  2. tells the user that there is no warranty for the work (except to the\n     extent that warranties are provided), that licensees may convey the work\n     under this License, and how to view a copy of this License.\n\nIf the interface presents a list of user commands or options, such as a menu, a\nprominent item in the list meets this criterion.\n\n### 1. Source Code.\n\nThe *source code* for a work means the preferred form of the work for making\nmodifications to it. *Object code* means any non-source form of a work.\n\nA *Standard Interface* means an interface that either is an official standard\ndefined by a recognized standards body, or, in the case of interfaces specified\nfor a particular programming language, one that is widely used among developers\nworking in that language.\n\nThe *System Libraries* of an executable work include anything, other than the\nwork as a whole, that (a) is included in the normal form of packaging a Major\nComponent, but which is not part of that Major Component, and (b) serves only\nto enable use of the work with that Major Component, or to implement a Standard\nInterface for which an implementation is available to the public in source code\nform. A *Major Component*, in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system (if any) on\nwhich the executable work runs, or a compiler used to produce the work, or an\nobject code interpreter used to run it.\n\nThe *Corresponding Source* for a work in object code form means all the source\ncode needed to generate, install, and (for an executable work) run the object\ncode and to modify the work, including scripts to control those activities.\nHowever, it does not include the work's System Libraries, or general-purpose\ntools or generally available free programs which are used unmodified in\nperforming those activities but which are not part of the work. For example,\nCorresponding Source includes interface definition files associated with source\nfiles for the work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require, such as\nby intimate data communication or control flow between those subprograms and\nother parts of the work.\n\nThe Corresponding Source need not include anything that users can regenerate\nautomatically from other parts of the Corresponding Source.\n\nThe Corresponding Source for a work in source code form is that same work.\n\n### 2. Basic Permissions.\n\nAll rights granted under this License are granted for the term of copyright on\nthe Program, and are irrevocable provided the stated conditions are met. This\nLicense explicitly affirms your unlimited permission to run the unmodified\nProgram. The output from running a covered work is covered by this License only\nif the output, given its content, constitutes a covered work. This License\nacknowledges your rights of fair use or other equivalent, as provided by\ncopyright law.\n\nYou may make, run and propagate covered works that you do not convey, without\nconditions so long as your license otherwise remains in force. You may convey\ncovered works to others for the sole purpose of having them make modifications\nexclusively for you, or provide you with facilities for running those works,\nprovided that you comply with the terms of this License in conveying all\nmaterial for which you do not control copyright. Those thus making or running\nthe covered works for you must do so exclusively on your behalf, under your\ndirection and control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\nConveying under any other circumstances is permitted solely under the\nconditions stated below. Sublicensing is not allowed; section 10 makes it\nunnecessary.\n\n### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\nNo covered work shall be deemed part of an effective technological measure\nunder any applicable law fulfilling obligations under article 11 of the WIPO\ncopyright treaty adopted on 20 December 1996, or similar laws prohibiting or\nrestricting circumvention of such measures.\n\nWhen you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention is\neffected by exercising rights under this License with respect to the covered\nwork, and you disclaim any intention to limit operation or modification of the\nwork as a means of enforcing, against the work's users, your or third parties'\nlegal rights to forbid circumvention of technological measures.\n\n### 4. Conveying Verbatim Copies.\n\nYou may convey verbatim copies of the Program's source code as you receive it,\nin any medium, provided that you conspicuously and appropriately publish on\neach copy an appropriate copyright notice; keep intact all notices stating that\nthis License and any non-permissive terms added in accord with section 7 apply\nto the code; keep intact all notices of the absence of any warranty; and give\nall recipients a copy of this License along with the Program.\n\nYou may charge any price or no price for each copy that you convey, and you may\noffer support or warranty protection for a fee.\n\n### 5. Conveying Modified Source Versions.\n\nYou may convey a work based on the Program, or the modifications to produce it\nfrom the Program, in the form of source code under the terms of section 4,\nprovided that you also meet all of these conditions:\n\n  - a) The work must carry prominent notices stating that you modified it, and\n    giving a relevant date.\n  - b) The work must carry prominent notices stating that it is released under\n    this License and any conditions added under section 7. This requirement\n    modifies the requirement in section 4 to *keep intact all notices*.\n  - c) You must license the entire work, as a whole, under this License to\n    anyone who comes into possession of a copy. This License will therefore\n    apply, along with any applicable section 7 additional terms, to the whole\n    of the work, and all its parts, regardless of how they are packaged. This\n    License gives no permission to license the work in any other way, but it\n    does not invalidate such permission if you have separately received it.\n  - d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your work need\n    not make them do so.\n\nA compilation of a covered work with other separate and independent works,\nwhich are not by their nature extensions of the covered work, and which are not\ncombined with it such as to form a larger program, in or on a volume of a\nstorage or distribution medium, is called an *aggregate* if the compilation and\nits resulting copyright are not used to limit the access or legal rights of the\ncompilation's users beyond what the individual works permit. Inclusion of a\ncovered work in an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n### 6. Conveying Non-Source Forms.\n\nYou may convey a covered work in object code form under the terms of sections 4\nand 5, provided that you also convey the machine-readable Corresponding Source\nunder the terms of this License, in one of these ways:\n\n  - a) Convey the object code in, or embodied in, a physical product (including\n    a physical distribution medium), accompanied by the Corresponding Source\n    fixed on a durable physical medium customarily used for software\n    interchange.\n  - b) Convey the object code in, or embodied in, a physical product (including\n    a physical distribution medium), accompanied by a written offer, valid for\n    at least three years and valid for as long as you offer spare parts or\n    customer support for that product model, to give anyone who possesses the\n    object code either\n    1. a copy of the Corresponding Source for all the software in the product\n       that is covered by this License, on a durable physical medium\n       customarily used for software interchange, for a price no more than your\n       reasonable cost of physically performing this conveying of source, or\n    2. access to copy the Corresponding Source from a network server at no\n       charge.\n  - c) Convey individual copies of the object code with a copy of the written\n    offer to provide the Corresponding Source. This alternative is allowed only\n    occasionally and noncommercially, and only if you received the object code\n    with such an offer, in accord with subsection 6b.\n  - d) Convey the object code by offering access from a designated place\n    (gratis or for a charge), and offer equivalent access to the Corresponding\n    Source in the same way through the same place at no further charge. You\n    need not require recipients to copy the Corresponding Source along with the\n    object code. If the place to copy the object code is a network server, the\n    Corresponding Source may be on a different server operated by you or a\n    third party) that supports equivalent copying facilities, provided you\n    maintain clear directions next to the object code saying where to find the\n    Corresponding Source. Regardless of what server hosts the Corresponding\n    Source, you remain obligated to ensure that it is available for as long as\n    needed to satisfy these requirements.\n  - e) Convey the object code using peer-to-peer transmission, provided you\n    inform other peers where the object code and Corresponding Source of the\n    work are being offered to the general public at no charge under subsection\n    6d.\n\nA separable portion of the object code, whose source code is excluded from the\nCorresponding Source as a System Library, need not be included in conveying the\nobject code work.\n\nA *User Product* is either\n\n  1. a *consumer product*, which means any tangible personal property which is\n     normally used for personal, family, or household purposes, or\n  2. anything designed or sold for incorporation into a dwelling.\n\nIn determining whether a product is a consumer product, doubtful cases shall be\nresolved in favor of coverage. For a particular product received by a\nparticular user, *normally used* refers to a typical or common use of that\nclass of product, regardless of the status of the particular user or of the way\nin which the particular user actually uses, or expects or is expected to use,\nthe product. A product is a consumer product regardless of whether the product\nhas substantial commercial, industrial or non-consumer uses, unless such uses\nrepresent the only significant mode of use of the product.\n\n*Installation Information* for a User Product means any methods, procedures,\nauthorization keys, or other information required to install and execute\nmodified versions of a covered work in that User Product from a modified\nversion of its Corresponding Source. The information must suffice to ensure\nthat the continued functioning of the modified object code is in no case\nprevented or interfered with solely because modification has been made.\n\nIf you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as part of a\ntransaction in which the right of possession and use of the User Product is\ntransferred to the recipient in perpetuity or for a fixed term (regardless of\nhow the transaction is characterized), the Corresponding Source conveyed under\nthis section must be accompanied by the Installation Information. But this\nrequirement does not apply if neither you nor any third party retains the\nability to install modified object code on the User Product (for example, the\nwork has been installed in ROM).\n\nThe requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates for a\nwork that has been modified or installed by the recipient, or for the User\nProduct in which it has been modified or installed. Access to a network may be\ndenied when the modification itself materially and adversely affects the\noperation of the network or violates the rules and protocols for communication\nacross the network.\n\nCorresponding Source conveyed, and Installation Information provided, in accord\nwith this section must be in a format that is publicly documented (and with an\nimplementation available to the public in source code form), and must require\nno special password or key for unpacking, reading or copying.\n\n### 7. Additional Terms.\n\n*Additional permissions* are terms that supplement the terms of this License by\nmaking exceptions from one or more of its conditions. Additional permissions\nthat are applicable to the entire Program shall be treated as though they were\nincluded in this License, to the extent that they are valid under applicable\nlaw. If additional permissions apply only to part of the Program, that part may\nbe used separately under those permissions, but the entire Program remains\ngoverned by this License without regard to the additional permissions.\n\nWhen you convey a copy of a covered work, you may at your option remove any\nadditional permissions from that copy, or from any part of it. (Additional\npermissions may be written to require their own removal in certain cases when\nyou modify the work.) You may place additional permissions on material, added\nby you to a covered work, for which you have or can give appropriate copyright\npermission.\n\nNotwithstanding any other provision of this License, for material you add to a\ncovered work, you may (if authorized by the copyright holders of that material)\nsupplement the terms of this License with terms:\n\n  - a) Disclaiming warranty or limiting liability differently from the terms of\n    sections 15 and 16 of this License; or\n  - b) Requiring preservation of specified reasonable legal notices or author\n    attributions in that material or in the Appropriate Legal Notices displayed\n    by works containing it; or\n  - c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in reasonable\n    ways as different from the original version; or\n  - d) Limiting the use for publicity purposes of names of licensors or authors\n    of the material; or\n  - e) Declining to grant rights under trademark law for use of some trade\n    names, trademarks, or service marks; or\n  - f) Requiring indemnification of licensors and authors of that material by\n    anyone who conveys the material (or modified versions of it) with\n    contractual assumptions of liability to the recipient, for any liability\n    that these contractual assumptions directly impose on those licensors and\n    authors.\n\nAll other non-permissive additional terms are considered *further restrictions*\nwithin the meaning of section 10. If the Program as you received it, or any\npart of it, contains a notice stating that it is governed by this License along\nwith a term that is a further restriction, you may remove that term. If a\nlicense document contains a further restriction but permits relicensing or\nconveying under this License, you may add to a covered work material governed\nby the terms of that license document, provided that the further restriction\ndoes not survive such relicensing or conveying.\n\nIf you add terms to a covered work in accord with this section, you must place,\nin the relevant source files, a statement of the additional terms that apply to\nthose files, or a notice indicating where to find the applicable terms.\n\nAdditional terms, permissive or non-permissive, may be stated in the form of a\nseparately written license, or stated as exceptions; the above requirements\napply either way.\n\n### 8. Termination.\n\nYou may not propagate or modify a covered work except as expressly provided\nunder this License. Any attempt otherwise to propagate or modify it is void,\nand will automatically terminate your rights under this License (including any\npatent licenses granted under the third paragraph of section 11).\n\nHowever, if you cease all violation of this License, then your license from a\nparticular copyright holder is reinstated\n\n  - a) provisionally, unless and until the copyright holder explicitly and\n    finally terminates your license, and\n  - b) permanently, if the copyright holder fails to notify you of the\n    violation by some reasonable means prior to 60 days after the cessation.\n\nMoreover, your license from a particular copyright holder is reinstated\npermanently if the copyright holder notifies you of the violation by some\nreasonable means, this is the first time you have received notice of violation\nof this License (for any work) from that copyright holder, and you cure the\nviolation prior to 30 days after your receipt of the notice.\n\nTermination of your rights under this section does not terminate the licenses\nof parties who have received copies or rights from you under this License. If\nyour rights have been terminated and not permanently reinstated, you do not\nqualify to receive new licenses for the same material under section 10.\n\n### 9. Acceptance Not Required for Having Copies.\n\nYou are not required to accept this License in order to receive or run a copy\nof the Program. Ancillary propagation of a covered work occurring solely as a\nconsequence of using peer-to-peer transmission to receive a copy likewise does\nnot require acceptance. However, nothing other than this License grants you\npermission to propagate or modify any covered work. These actions infringe\ncopyright if you do not accept this License. Therefore, by modifying or\npropagating a covered work, you indicate your acceptance of this License to do\nso.\n\n### 10. Automatic Licensing of Downstream Recipients.\n\nEach time you convey a covered work, the recipient automatically receives a\nlicense from the original licensors, to run, modify and propagate that work,\nsubject to this License. You are not responsible for enforcing compliance by\nthird parties with this License.\n\nAn *entity transaction* is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations. If propagation of a covered work\nresults from an entity transaction, each party to that transaction who receives\na copy of the work also receives whatever licenses to the work the party's\npredecessor in interest had or could give under the previous paragraph, plus a\nright to possession of the Corresponding Source of the work from the\npredecessor in interest, if the predecessor has it or can get it with\nreasonable efforts.\n\nYou may not impose any further restrictions on the exercise of the rights\ngranted or affirmed under this License. For example, you may not impose a\nlicense fee, royalty, or other charge for exercise of rights granted under this\nLicense, and you may not initiate litigation (including a cross-claim or\ncounterclaim in a lawsuit) alleging that any patent claim is infringed by\nmaking, using, selling, offering for sale, or importing the Program or any\nportion of it.\n\n### 11. Patents.\n\nA *contributor* is a copyright holder who authorizes use under this License of\nthe Program or a work on which the Program is based. The work thus licensed is\ncalled the contributor's *contributor version*.\n\nA contributor's *essential patent claims* are all patent claims owned or\ncontrolled by the contributor, whether already acquired or hereafter acquired,\nthat would be infringed by some manner, permitted by this License, of making,\nusing, or selling its contributor version, but do not include claims that would\nbe infringed only as a consequence of further modification of the contributor\nversion. For purposes of this definition, *control* includes the right to grant\npatent sublicenses in a manner consistent with the requirements of this\nLicense.\n\nEach contributor grants you a non-exclusive, worldwide, royalty-free patent\nlicense under the contributor's essential patent claims, to make, use, sell,\noffer for sale, import and otherwise run, modify and propagate the contents of\nits contributor version.\n\nIn the following three paragraphs, a *patent license* is any express agreement\nor commitment, however denominated, not to enforce a patent (such as an express\npermission to practice a patent or covenant not to sue for patent\ninfringement). To *grant* such a patent license to a party means to make such\nan agreement or commitment not to enforce a patent against the party.\n\nIf you convey a covered work, knowingly relying on a patent license, and the\nCorresponding Source of the work is not available for anyone to copy, free of\ncharge and under the terms of this License, through a publicly available\nnetwork server or other readily accessible means, then you must either\n\n  1. cause the Corresponding Source to be so available, or\n  2. arrange to deprive yourself of the benefit of the patent license for this\n     particular work, or\n  3. arrange, in a manner consistent with the requirements of this License, to\n     extend the patent license to downstream recipients.\n\n*Knowingly relying* means you have actual knowledge that, but for the patent\nlicense, your conveying the covered work in a country, or your recipient's use\nof the covered work in a country, would infringe one or more identifiable\npatents in that country that you have reason to believe are valid.\n\nIf, pursuant to or in connection with a single transaction or arrangement, you\nconvey, or propagate by procuring conveyance of, a covered work, and grant a\npatent license to some of the parties receiving the covered work authorizing\nthem to use, propagate, modify or convey a specific copy of the covered work,\nthen the patent license you grant is automatically extended to all recipients\nof the covered work and works based on it.\n\nA patent license is *discriminatory* if it does not include within the scope of\nits coverage, prohibits the exercise of, or is conditioned on the non-exercise\nof one or more of the rights that are specifically granted under this License.\nYou may not convey a covered work if you are a party to an arrangement with a\nthird party that is in the business of distributing software, under which you\nmake payment to the third party based on the extent of your activity of\nconveying the work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory patent\nlicense\n\n  - a) in connection with copies of the covered work conveyed by you (or copies\n    made from those copies), or\n  - b) primarily for and in connection with specific products or compilations\n    that contain the covered work, unless you entered into that arrangement, or\n    that patent license was granted, prior to 28 March 2007.\n\nNothing in this License shall be construed as excluding or limiting any implied\nlicense or other defenses to infringement that may otherwise be available to\nyou under applicable patent law.\n\n### 12. No Surrender of Others' Freedom.\n\nIf conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not excuse\nyou from the conditions of this License. If you cannot convey a covered work so\nas to satisfy simultaneously your obligations under this License and any other\npertinent obligations, then as a consequence you may not convey it at all. For\nexample, if you agree to terms that obligate you to collect a royalty for\nfurther conveying from those to whom you convey the Program, the only way you\ncould satisfy both those terms and this License would be to refrain entirely\nfrom conveying the Program.\n\n### 13. Use with the GNU Affero General Public License.\n\nNotwithstanding any other provision of this License, you have permission to\nlink or combine any covered work with a work licensed under version 3 of the\nGNU Affero General Public License into a single combined work, and to convey\nthe resulting work. The terms of this License will continue to apply to the\npart which is the covered work, but the special requirements of the GNU Affero\nGeneral Public License, section 13, concerning interaction through a network\nwill apply to the combination as such.\n\n### 14. Revised Versions of this License.\n\nThe Free Software Foundation may publish revised and/or new versions of the GNU\nGeneral Public License from time to time. Such new versions will be similar in\nspirit to the present version, but may differ in detail to address new problems\nor concerns.\n\nEach version is given a distinguishing version number. If the Program specifies\nthat a certain numbered version of the GNU General Public License *or any later\nversion* applies to it, you have the option of following the terms and\nconditions either of that numbered version or of any later version published by\nthe Free Software Foundation. If the Program does not specify a version number\nof the GNU General Public License, you may choose any version ever published by\nthe Free Software Foundation.\n\nIf the Program specifies that a proxy can decide which future versions of the\nGNU General Public License can be used, that proxy's public statement of\nacceptance of a version permanently authorizes you to choose that version for\nthe Program.\n\nLater license versions may give you additional or different permissions.\nHowever, no additional obligations are imposed on any author or copyright\nholder as a result of your choosing to follow a later version.\n\n### 15. Disclaimer of Warranty.\n\nTHERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE\nLAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER\nPARTIES PROVIDE THE PROGRAM *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER\nEXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE\nQUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE\nDEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR\nCORRECTION.\n\n### 16. Limitation of Liability.\n\nIN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY\nCOPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS\nPERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,\nINCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE\nTHE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED\nINACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE\nPROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY\nHAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n### 17. Interpretation of Sections 15 and 16.\n\nIf the disclaimer of warranty and limitation of liability provided above cannot\nbe given local legal effect according to their terms, reviewing courts shall\napply local law that most closely approximates an absolute waiver of all civil\nliability in connection with the Program, unless a warranty or assumption of\nliability accompanies a copy of the Program in return for a fee.\n\n## END OF TERMS AND CONDITIONS ###\n\n### How to Apply These Terms to Your New Programs\n\nIf you develop a new program, and you want it to be of the greatest possible\nuse to the public, the best way to achieve this is to make it free software\nwhich everyone can redistribute and change under these terms.\n\nTo do so, attach the following notices to the program. It is safest to attach\nthem to the start of each source file to most effectively state the exclusion\nof warranty; and each file should have at least the *copyright* line and a\npointer to where the full notice is found.\n\n\t<one line to give the program's name and a brief idea of what it does.>\n\tCopyright (C) <year>  <name of author>\n\n\tThis program is free software: you can redistribute it and/or modify\n\tit under the terms of the GNU General Public License as published by\n\tthe Free Software Foundation, either version 3 of the License, or\n\t(at your option) any later version.\n\n\tThis program is distributed in the hope that it will be useful,\n\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\tGNU General Public License for more details.\n\n\tYou should have received a copy of the GNU General Public License\n\talong with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program does terminal interaction, make it output a short notice like\nthis when it starts in an interactive mode:\n\n\t<program>  Copyright (C) <year>  <name of author>\n\tThis program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n\tThis is free software, and you are welcome to redistribute it\n\tunder certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w` and `show c` should show the appropriate\nparts of the General Public License. Of course, your program's commands might\nbe different; for a GUI interface, you would use an *about box*.\n\nYou should also get your employer (if you work as a programmer) or school, if\nany, to sign a *copyright disclaimer* for the program, if necessary. For more\ninformation on this, and how to apply and follow the GNU GPL, see\n[http://www.gnu.org/licenses/](http://www.gnu.org/licenses/).\n\nThe GNU General Public License does not permit incorporating your program into\nproprietary programs. If your program is a subroutine library, you may consider\nit more useful to permit linking proprietary applications with the library. If\nthis is what you want to do, use the GNU Lesser General Public License instead\nof this License. But first, please read\n[http://www.gnu.org/philosophy/why-not-lgpl.html](http://www.gnu.org/philosophy/why-not-lgpl.html).\n"
  },
  {
    "path": "ExectOS.code-workspace",
    "content": "{\n\t\"folders\": [\n\t\t{\n\t\t\t\"path\": \".\"\n\t\t}\n\t],\n\t\"settings\": {\n\t\t\"clangd.arguments\": [\n\t\t\t\"--compile-commands-dir=${workspaceFolder}/build/\",\n\t\t\t\"--header-insertion=never\",\n\t\t\t\"--enable-config\",\n\t\t\t\"--log=verbose\"\n\t\t],\n\t\t\"editor.rulers\": [\n\t\t\t120\n\t\t],\n\t\t\"terminal.integrated.profiles.linux\": {\n\t\t\t\"xtchain\": {\n\t\t\t\t\"path\": \"xtchain\"\n\t\t\t}\n\t\t},\n\t\t\"terminal.integrated.defaultProfile.linux\": \"xtchain\",\n\t}\n}"
  },
  {
    "path": "README.md",
    "content": "<p align=center>\n  <a href=\"https://git.codingworkshop.eu.org/xt-sys/exectos\">\n    <img alt=\"GIT Repository\" src=\"https://img.shields.io/badge/Source-GIT-purple\">\n  </a>\n  <a href=\"https://git.codingworkshop.eu.org/xt-sys/exectos/activity/monthly\">\n    <img alt=\"Commits\" src=\"https://img.shields.io/github/commit-activity/m/xt-sys/exectos?label=Commits\">\n  </a>\n  <a href=\"https://git.codingworkshop.eu.org/xt-sys/exectos/actions\">\n    <img alt=\"Build Status\" src=\"https://codingworkshop.eu.org/actions.php?project=xt-sys/exectos\">\n  </a>\n  <a href=\"https://artifacts.codingworkshop.eu.org/ExectOS/?C=M&O=D\">\n    <img alt=\"CI/CD Artifacts\" src=\"https://img.shields.io/badge/Download-%F0%9F%A1%87-blueviolet\">\n  </a>\n  <a href=\"https://git.codingworkshop.eu.org/xt-sys/exectos/src/branch/master/COPYING.md\">\n    <img alt=\"License\" src=\"https://img.shields.io/badge/License-GPLv3-blue.svg\">\n  </a>\n  <a href=\"https://exectos.eu.org/ai-assisted\">\n    <img alt=\"AI Assisted\" src=\"https://img.shields.io/badge/AI-Assisted-darkcyan\">\n  </a>\n  <a href=\"https://github.com/sponsors/xt-sys/\">\n    <img alt=\"Sponsor\" src=\"https://img.shields.io/badge/Sponsor-%E2%9D%A4-red?logo=GitHub\">\n  </a>\n  <a href=\"https://discord.com/invite/zBzJ5qMGX7\">\n    <img alt=\"Discord\" src=\"https://img.shields.io/badge/Chat-Join%20Discord-success\">\n  </a>\n</p>\n\n---\n\n# ExectOS Operating System\nExectOS is an open-source, general purpose operating system written from scratch. It aims to be modular,\nmaintainable and compatible with existing software. It implements a brand new XT architecture and features\nown native application interface. On the backend, it contains a powerful driver model between device drivers\nand the kernel, that enables kernel level components to be upgraded without a need to recompile all drivers.\n\n# XT Architecture\nExectOS is a preemptive, reentrant multitasking operating system that implements the XT architecture which derives\nfrom NT architecture. It is modular, and consists of two main layers: microkernel and user modes. Its' kernel mode has\nfull access to the hardware and system resources and runs code in a protected memory area. It consists of executive\nservices, which is itself made up on many modules that do specific tasks, a kernel and drivers. Unlike the NT, system\ndoes not feature a separate Hardware Abstraction Layer (HAL) between the physical hardware and the rest of the OS.\nInstead, XT architecture integrates a hardware specific code with the kernel. The user mode is made up of subsystems\nand it has been designed to run applications written for many different types of operating systems. This allows to\nimplement any environment subsystem to support applications that are strictly written to the corresponding standard\n(eg. DOS, or POSIX).\n\n# Features\n * Modern, EFI enabled operating system\n * Runs on x86 and x86_64 architectures\n * Portable to other architectures\n * Modular design, open-source project\n * Own drivers for commonly used devices\n * NT drivers compatibility layer\n\n# Requirements\nExectOS is currently in a very early stage of development, so its specific requirements are not fully defined yet.\nHowever, based on the current design, it requires modern EFI hardware. You cannot boot ExectOS on a legacy BIOS\nright now, but there are plans to add BIOS support in the future.\n\n# Source structure\n| Directory        | Description                                                  |\n|------------------|--------------------------------------------------------------|\n| boot/bootdata    | default configuration and data needed to boot XTOS           |\n| boot/bootsect    | boot sector code (MBR & VBR) initializing the boot process   |\n| boot/xtldr       | XTOS boot loader source code                                 |\n| drivers          | XT native drivers source code                                |\n| sdk/cmake        | host toolchain configuration and build-related functions     |\n| sdk/firmware     | firmware enabling XTOS to boot on virtual machines           |\n| sdk/xtdk         | XT Software Development Kit headers                          |\n| services         | integral subsystems services source code                     |\n| subsystems       | environment subsystems source code                           |\n| xtoskrnl         | XTOS kernel source code                                      |\n\n# Build\nXTOS can only be built using [XTchain](https://git.codingworkshop.eu.org/xt-sys/xtchain), a dedicated toolchain designed\nspecifically for compiling XT software. XTChain is currently available for both Linux and Windows. Detailed instructions\non how to configure and run XTChain can be found [here](https://exectos.eu.org/contributing/setting-up-xtchain).\n\nWith the XTchain environment already running, navigate to the directory containing the ExectOS source code and use the\nfollowing commands to set the target build architecture and configure the sources:\n```\ncharch [i686|amd64]\nchbuild [DEBUG|RELEASE]\n./configure.sh\n```\nOnce the sources are configured, enter the build directory and compile the source code:\n```\ncd build\nxbuild\n```\nIt is also possible to build a disk image ready to use with QEMU with the following command:\n```\nxbuild diskimg\n```\n\n# Contributing\nThere is a ton of work to do in ExectOS and we appreciate any help. If you are interested in writing features,\nporting drivers, fixing bugs, writing tests, creating documentation, or helping out in any other way, we would\nlove the help. More details on how to contrubite can be found it [CONTRIBUTING.md](CONTRIBUTING.md) file.\n\n# Licensing\nExectOS is licensed to the public under the terms of the GNU General Public License, version 3. For more\ndetailed information check the [COPYING.md](COPYING.md) file.\n\n# GIT Mirrors\n * Main GIT Repository: https://git.codingworkshop.eu.org/xt-sys/exectos\n * GitHub Mirror: https://github.com/xt-sys/exectos\n * GitLab Mirror: https://gitlab.com/xt-sys/exectos\n\n# Contact\n * Discord Server: https://discord.com/invite/zBzJ5qMGX7\n"
  },
  {
    "path": "boot/CMakeLists.txt",
    "content": "add_subdirectory(bootdata)\nadd_subdirectory(bootsect)\nadd_subdirectory(xtldr)\n"
  },
  {
    "path": "boot/bootdata/CMakeLists.txt",
    "content": "add_subdirectory(xtldr)\n"
  },
  {
    "path": "boot/bootdata/xtldr/CMakeLists.txt",
    "content": "set_install_file(xtldr.ini efi/boot/xtldr)\n"
  },
  {
    "path": "boot/bootdata/xtldr/xtldr.ini",
    "content": "# This is the XT Boot Loader (XTLDR) configuration file. It follows an INI format and is divided into sections, which\n# contain a properties. Each property has a name and value delimited by an equal (=) character. Comments must start\n# with a semicolon (;) or a hash character (#) and run to the end of the line.\n#\n# Basic section is [XTLDR] which contains a bootloader specific options:\n# Debug        - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;\n#                it is also possible to specify custom port address with: COM0:[address],[baud_rate]\n# Default      - specifies which operating system listen in config file will be started if no choice is made\n# KeepLastBoot - specifies whether last booted OS should be stored in NVRAM and booted automatically next time, or not;\n#                this parameter takes 'true' or 'false' value\n# Modules      - supplies a list of modules that will be loaded in orded to extend XTLDR functionality\n# Timeout      - sets the countdown timer (in seconds) before the default OS get started automatically\n# Tune         - plays a tune on the pcspeaker right before the XTLDR boot menu shows up\n#\n# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type\n# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored\n# by the XT Boot Loader. The available options are:\n# BootModules  - supplies a list of additional modules that will be loaded just before invoking the boot protocol\n# SystemName   - sets a long operating system name that will be shown on the boot menu\n# SystemType   - specifies an OS type from a predefined list of supported boot protocols\n# SystemPath   - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)\n# KernelFile   - sets kernel filename with optional path relative to SystemPath\n# InitrdFile   - sets initramfs image filename with optional path relative to SystemPath\n# HalFile      - sets HAL filename with optional path relative to SystemPath\n# Parameters   - specifies extra boot options for the kernel\n\n[XTLDR]\nDebug=COM1,115200\nDefault=ExectOS\nKeepLastBoot=TRUE\nModules=beep\nTimeout=10\nTune=400 880 2 988 2 783 2 392 2 587 3\n\n[ExectOS]\nSystemName=\"ExectOS Operating System\"\nSystemType=XTOS\nBootModules=xtos_o\nSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS\nKernelFile=xtoskrnl.exe\nParameters=DEBUG=COM1,115200\n\n[ExectOS_FBDEBUG]\nSystemName=\"ExectOS Operating System (FBDEBUG)\"\nSystemType=XTOS\nBootModules=xtos_o\nSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS\nKernelFile=xtoskrnl.exe\nParameters=DEBUG=COM1,115200;SCREEN\n\n[ExectOS_NOXPA]\nSystemName=\"ExectOS Operating System (NOXPA)\"\nSystemType=XTOS\nBootModules=xtos_o\nSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS\nKernelFile=xtoskrnl.exe\nParameters=DEBUG=COM1,115200 NOXPA\n\n[ExectOS_NOXPA_FBDEBUG]\nSystemName=\"ExectOS Operating System (NOXPA / FBDEBUG)\"\nSystemType=XTOS\nBootModules=xtos_o\nSystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS\nKernelFile=xtoskrnl.exe\nParameters=DEBUG=COM1,115200;SCREEN NOXPA\n\n[Windows]\nSystemName=\"Microsoft Windows 2000\"\nSystemType=NT50\nBootModules=ntos\nSystemPath=multi(0)disk(0)rdisk(0)partition(2)/Windows\nKernelFile=ntoskrnl.exe\nHalFile=hal.dll\nParameters=/NOGUIBOOT /MININT\n\n[Linux]\nSystemName=\"GNU/Linux\"\nSystemType=LINUX\nBootModules=linux\nSystemPath=multi(0)disk(0)rdisk(0)partition(3)/boot\nKernelFile=vmlinuz\nInitrdFile=initramfs.cpio.gz\nParameters=root=/dev/xvda3 rootfstype=ext4\n\n[EFI Shell]\nSystemName=\"EFI Shell\"\nSystemType=CHAINLOADER\nBootModules=chainldr\nSystemPath=multi(0)disk(0)rdisk(0)partition(1)/efi/boot\nKernelFile=efishell.efi\n"
  },
  {
    "path": "boot/bootsect/CMakeLists.txt",
    "content": "# XT Boot Sector\nPROJECT(BOOTSECT)\n\nadd_definitions(\"-DARCH_ESP_SOURCE=\\\\\\\"${ARCH}/cpu.S\\\\\\\"\")\n\n# Compile boot sectors\ncompile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)\ncompile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)\n"
  },
  {
    "path": "boot/bootsect/amd64/cpu.S",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            boot/bootsect/amd64/cpu.S\n * DESCRIPTION:     Low-level support for CPU initialization\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n\nBuildPageMap:\n    /* Generate page map for first 1GB of memory */\n    pushaw\n    pushw %es\n    cld\n    movw $(0x1000 / 16), %ax\n    movw %ax, %es\n    xorw %di, %di\n    movl $(0x2000 | 0x07), %eax\n    stosl\n    xorl %eax, %eax\n    movw $1021, %cx\n    rep stosl\n    movw $(0x2000 / 16), %ax\n    movw %ax, %es\n    xorw %di, %di\n    movl $(0x3000 | 0x07), %eax\n    stosl\n    xorl %eax, %eax\n    movw $1021, %cx\n    rep stosl\n    movw $(0x3000 / 16), %ax\n    movw %ax, %es\n    xorw %di, %di\n    movw $512, %cx\n    movl $0x00000083, %eax\n.BuildPageMapLoop:\n    /* Identity map 512 pages of 2MB */\n    movl %eax, %es:(%di)\n    addl $2097152, %eax\n    addw $0x08, %di\n    loop .BuildPageMapLoop\n    popw %es\n    popaw\n    ret\n\nInitializeCpu:\n    /* Check if CPU supports CPUID, long mode and PAE */\n    pushal\n    pushfl\n    popl %eax\n    movl %eax, %ebx\n    xorl $0x00200000, %eax\n    pushl %eax\n    popfl\n    pushfl\n    popl %eax\n    cmpl %ebx, %eax\n    je CpuUnsupported\n    movl $0x01, %eax\n    cpuid\n    testl $0x40, %edx\n    jz CpuUnsupported\n    movl $0x80000000, %eax\n    cpuid\n    cmpl $0x80000000, %eax\n    jbe CpuUnsupported\n    movl $0x80000001, %eax\n    cpuid\n    testl $0x20000000, %edx\n    jz CpuUnsupported\n    popal\n    call LoadGdt\n    ret\n\nLoadGdt:\n    /* Load Global Descriptor Table */\n    lgdt .GdtPointer\n    ret\n\nRunStage2:\n    /* Switch to long mode and pass control to Stage 2 */\n    call BuildPageMap\n    call ParseExecutableHeader\n    xorl %edx, %edx\n    pushl %edx\n    pushl %eax\n    cli\n    xorw %ax, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %fs\n    movw %ax, %gs\n    movw %ax, %ss\n    movl %cr4, %eax\n    orl $0x00A0, %eax\n    movl %eax, %cr4\n    movl $0x00001000, %eax\n    movl %eax, %cr3\n    movl $0xC0000080, %ecx\n    rdmsr\n    orl $0x00000100, %eax\n    wrmsr\n    movl %cr0, %eax\n    orl $0x80000001, %eax\n    movl %eax, %cr0\n    ljmp $0x10, $.Stage2LongMode\n.code64\n.Stage2LongMode:\n    /* Set segments and stack, then jump to Stage 2 */\n    movw $0x18, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n    xorw %ax, %ax\n    movw %ax, %fs\n    movw %ax, %gs\n    popq %rax\n    xorq %rbx, %rbx\n    xorq %rcx, %rcx\n    xorq %rdx, %rdx\n    xorq %rsi, %rsi\n    xorq %rdi, %rdi\n    xorq %rbp, %rbp\n    jmp *%rax\n\n.code16\n.GdtDescriptor:\n    /* Global Descriptor Table */\n    .quad 0x0000000000000000\n    .quad 0x0000000000000000\n    .quad 0x00AF9A000000FFFF\n    .quad 0x00CF92000000FFFF\n    .quad 0x00009E000000FFFF\n    .quad 0x000092000000FFFF\n    .quad 0x00CF9B000000FFFF\n\n.GdtPointer:\n    /* Pointer to Global Descriptor Table */\n    .word .GdtPointer - .GdtDescriptor - 1\n    .long .GdtDescriptor\n\n.Stage2FileName:\n    /* Name of Stage 2 executable file */\n    .ascii \"BOOTX64 EFI\"\n"
  },
  {
    "path": "boot/bootsect/espboot.S",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            boot/bootsect/espboot.S\n * DESCRIPTION:     XT Boot Loader ESP boot code (FAT32)\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n.text\n.code16\n\n\n.global Start\nStart:\n    /* Jump to the real start to omit the BPB (BIOS Parameter Block) */\n    jmp RealStart\n    nop\n\n/* BIOS Parameter Block */\nOsName:\n    .ascii \"XTOS \"\nOsVersion:\n    .ascii \"1.0\"\nBytesPerSector:\n    .word 512\nSectorsPerCluster:\n    .byte 2\nReservedSectors:\n    .word 8\nFatCopies:\n    .byte 1\nRootDirEntries:\n    .word 1024\nTotalSectors:\n    .word 0\nMediaType:\n    .byte 0xF8\nSectorsPerFat:\n    .word 0\nSectorsPerTrack:\n    .word 17\nNumberOfHeads:\n    .word 0\nHiddenSectors:\n    .long 0\nTotalBigSectors:\n    .long 0x200000\nBigSectorsPerFat:\n    .long 0x1FE0\nExtendedFlags:\n    .word 0\nFsVersion:\n    .word 0\nRootDirStartCluster:\n    .long 0\nFSInfoSector:\n    .word 0\nBackupBootSector:\n    .word 6\nReserved:\n    .fill 12, 1, 0\nDriveNumber:\n    .byte 0x80\nCurrentHead:\n    .byte 0\nSignature:\n    .byte 0x29\nSerialNumber:\n    .long 0\nVolumeLabel:\n    .ascii \"NO NAME    \"\nFileSystem:\n    .ascii \"FAT32   \"\n\nRealStart:\n    /* Set segments and stack */\n    cli\n    cld\n    xorw %ax, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n    movw $0x7C00, %bp\n    leaw -16(%bp), %sp\n    sti\n\n    /* Get drive number */\n    cmpb $0xFF, DriveNumber - Start(%bp)\n    jne GetDriveParameters\n    movb %dl, DriveNumber - Start(%bp)\n\nGetDriveParameters:\n    /* Get drive parameters from the BIOS */\n    movb DriveNumber - Start(%bp), %dl\n    movb $0x08, %ah\n    movb $0x00, %al\n    int $0x13\n    jnc GetDriveSize\n    movw $0xFFFF, %cx\n    movb %cl, %dh\n\nGetDriveSize:\n    /* Get drive size from the BIOS */\n    movzbl %dh, %eax\n    incw %ax\n    movzbl %cl, %edx\n    andb $0x3F, %dl\n    mulw %dx\n    xchgb %cl, %ch\n    shrb $0x06, %ch\n    incw %cx\n    movzwl %cx, %ecx\n    mull %ecx\n    movl %eax, %edi\n\nVerifyBiosParameterBlock:\n    /* Verify the FAT32 BPB */\n    cmpw $0x00, SectorsPerFat - Start(%bp)\n    jne FsError\n    cmpw $0x00, FsVersion - Start(%bp)\n    ja FsError\n\nReadExtraCode:\n    /* Read second VBR sector with extra boot code (3 sectors starting from sector 2) */\n    movl HiddenSectors - Start(%bp), %eax\n    addl $0x02, %eax\n    movw $0x03, %cx\n    xorw %bx, %bx\n    movw %bx, %es\n    movw $0x7E00, %bx\n    call ReadSectors\n    jmp StartExtraCode\n\nReadSectors:\n    /* Check for extended BIOS functions and use it only if available */\n    pushw %es\n    pushal\n    movb $0x41, %ah\n    movw $0x55AA, %bx\n    movb DriveNumber - Start(%bp), %dl\n    int $0x13\n    jc .ReadCHS\n    cmpw $0xAA55, %bx\n    jne .ReadCHS\n    testb $0x01, %cl\n    jz .ReadCHS\n\n    /* Verify drive size and determine whether to use CHS or LBA */\n    cmpl %edi, %eax\n    jnb .ReadLBA\n\n.ReadCHS:\n    /* Read sectors using CHS */\n    popal\n\n.CHSLoop:\n    /* Read sector by sector using CHS */\n    pushw %cx\n    pushal\n    xorl %edx, %edx\n    movzwl SectorsPerTrack - Start(%bp), %ecx\n    divl %ecx\n    incb %dl\n    movb %dl, %cl\n    movl %eax, %edx\n    shrl $0x10, %edx\n    divw NumberOfHeads - Start(%bp)\n    movb %dl, %dh\n    movb DriveNumber - Start(%bp), %dl\n    movb %al, %ch\n    rorb $0x01, %ah\n    rorb $0x01, %ah\n    orb %ah, %cl\n    movw $0x0201, %ax\n    int $0x13\n    popal\n    popw %cx\n    jc DiskError\n    incl %eax\n    movw %es, %dx\n    addw $0x20, %dx\n    movw %dx, %es\n    loop .CHSLoop\n    popw %es\n    ret\n\n.ReadLBA:\n    /* Prepare DAP packet and read sectors using LBA */\n    popal\n    pushw %cx\n    pushal\n    pushw $0x00\n    pushw $0x00\n    pushl %eax\n    pushw %es\n    pushw %bx\n    pushw %cx\n    pushw $0x10\n    movw %sp, %si\n    movb DriveNumber - Start(%bp), %dl\n    movb $0x42, %ah\n    int $0x13\n    jc DiskError\n    addw $0x10, %sp\n    popal\n    popw %si\n    pushw %bx\n    movzwl %si, %ebx\n    addl %ebx, %eax\n    shll $0x05, %ebx\n    movw %es, %dx\n    addw %bx, %dx\n    movw %dx, %es\n    popw %bx\n    subw %si, %cx\n    jnz .ReadLBA\n    popw %es\n    ret\n\nDiskError:\n    /* Display disk error message and reboot */\n    movw $.MsgDiskError, %si\n    call Print\n    jmp Reboot\n\nFsError:\n    /* Display FS error message and reboot */\n    movw $.MsgFsError, %si\n    call Print\n    jmp Reboot\n\nPrint:\n    /* Simple routine to print messages */\n    lodsb\n    orb     %al, %al\n    jz      .DonePrint\n    movb    $0x0E, %ah\n    movw    $0x07, %bx\n    int     $0x10\n    jmp     Print\n.DonePrint:\n    retw\n\nReboot:\n    /* Display a message, wait for a key press and reboot */\n    movw $.MsgAnyKey, %si\n    call Print\n    xorw %ax, %ax\n    int $0x16\n    int $0x19\n\n.MsgAnyKey:\n    .ascii \"Press any key to restart...\\r\\n\\0\"\n\n.MsgDiskError:\n    .ascii \"Disk error!\\r\\n\\0\"\n\n.MsgFsError:\n    .ascii \"File system error!\\r\\n\\0\"\n\n/* Fill the rest of the VBR with zeros and add VBR signature at the end */\n.fill (510 - (. - Start)), 1, 0\n.word 0xAA55\n\n\nStartExtraCode:\n    /* Load XTLDR file from disk */\n    call LoadStage2\n\n    /* Enable A20 gate */\n    call EnableA20\n\n    /* Call architecture specific initialization code */\n    call InitializeCpu\n\n    /* Jump to Stage2 */\n    call RunStage2\n\nClear8042:\n    /* Clear 8042 PS/2 buffer */\n    nop\n    nop\n    nop\n    nop\n    inb $0x64, %al\n    cmpb $0xff, %al\n    je .Clear8042_Done\n    testb $0x02, %al\n    jnz Clear8042\n.Clear8042_Done:\n    ret\n\nEnableA20:\n    /* Enable A20 gate */\n    pushaw\n    call Clear8042\n    movb $0xD1, %al\n    outb %al, $0x64\n    call Clear8042\n    movb $0xDF, %al\n    outb %al, $0x60\n    call Clear8042\n    movb $0xFF, %al\n    outb %al, $0x64\n    call Clear8042\n    popaw\n    ret\n\nFindFatEntry:\n    /* Find a file or directory in the FAT table */\n    pushw %bx\n    pushw %cx\n    pushw %dx\n    pushw %si\n    pushw %di\n.FindFatCluster:\n    /* Find FAT32 cluster holding the entry */\n    cmp $0x0FFFFFF8, %eax\n    jae .FindEntryFail\n    pushl %eax\n    movw $0x0200, %bx\n    movw %bx, %es\n    call ReadCluster\n    popl %eax\n    movb SectorsPerCluster - Start(%bp), %cl\n    shlw $0x04, %cx\n    xorw %di, %di\n.FindEntryLoop:\n    /* Find the entry */\n    movb %es:(%di), %al\n    cmpb $0x00, %al\n    je .FindEntryFail\n    cmpb $0xE5, %al\n    je .FindSkipEntry\n    movb %es:0x0B(%di), %ah\n    cmpb $0x0F, %ah\n    je .FindSkipEntry\n    pushw %di\n    pushw %si\n    pushw %cx\n    movw $0x0B, %cx\n    repe cmpsb\n    popw %cx\n    popw %si\n    popw %di\n    jnz .FindSkipEntry\n    movw %es:0x1A(%di), %ax\n    movw %es:0x14(%di), %dx\n    shll $0x10, %edx\n    orl %edx, %eax\n    clc\n    jmp .FindEntryDone\n.FindSkipEntry:\n    /* Skip to the next entry */\n    addw $0x20, %di\n    decw %cx\n    jnz .FindEntryLoop\n    call GetFatEntry\n    jmp .FindFatCluster\n.FindEntryFail:\n    /* Error, file/directory not found */\n    stc\n.FindEntryDone:\n    /* Clean up the stack */\n    popw %di\n    popw %si\n    popw %dx\n    popw %cx\n    popw %bx\n    ret\n\nGetFatEntry:\n    /* Get FAT32 sector and offset from FAT table */\n    shll $0x02, %eax\n    movl %eax, %ecx\n    xorl %edx, %edx\n    movzwl BytesPerSector - Start(%bp), %ebx\n    pushl %ebx\n    divl %ebx\n    movzwl ReservedSectors - Start(%bp), %ebx\n    addl %ebx, %eax\n    movl HiddenSectors - Start(%bp), %ebx\n    addl %ebx, %eax\n    popl %ebx\n    decl %ebx\n    andl %ebx, %ecx\n    movzwl ExtendedFlags - Start(%bp), %ebx\n    andw $0x0F, %bx\n    jz LoadFatSector\n    cmpb FatCopies - Start(%bp), %bl\n    jae FsError\n    pushl %eax\n    movl BigSectorsPerFat - Start(%bp), %eax\n    mull %ebx\n    popl %edx\n    addl %edx, %eax\n\nLoadFatSector:\n    /* Load FAT32 sector from disk */\n    pushl %ecx\n    movw $0x9000, %bx\n    movw %bx, %es\n    cmpl %esi, %eax\n    je .LoadFatSectorDone\n    movl %eax, %esi\n    xorw %bx, %bx\n    movw $0x01, %cx\n    call ReadSectors\n.LoadFatSectorDone:\n    /* Clean up the stack */\n    popl %ecx\n    movl %es:(%ecx), %eax\n    andl $0x0FFFFFFF, %eax\n    ret\n\nLoadStage2:\n    /* Load Stage2 executable, first find file in the path */\n    movl $0xFFFFFFFF, %esi\n    pushl %esi\n    movl 0x7C2C, %eax\n    movw $.EfiDirName, %si\n    call FindFatEntry\n    jc Stage2NotLoaded\n    movw $.BootDirName, %si\n    call FindFatEntry\n    jc Stage2NotLoaded\n    movw $.Stage2FileName, %si\n    call FindFatEntry\n    jc Stage2NotLoaded\n    popl %esi\n    /* Load XTLDR file from disk */\n    cmpl $0x02, %eax\n    jb FileNotFound\n    cmpl $0x0FFFFFF8, %eax\n    jae FileNotFound\n    movw $(0xF800 / 16), %bx\n    movw %bx, %es\n.LoadStage2Loop:\n    /* Load file data from disk */\n    pushl %eax\n    xorw %bx, %bx\n    pushw %es\n    call ReadCluster\n    popw %es\n    xorw %bx, %bx\n    movb SectorsPerCluster - Start(%bp), %bl\n    shlw $0x05, %bx\n    movw %es, %ax\n    addw %bx, %ax\n    movw %ax, %es\n    popl %eax\n    pushw %es\n    call GetFatEntry\n    popw %es\n    cmpl $0x0FFFFFF8, %eax\n    jb .LoadStage2Loop\n    ret\n\nParseExecutableHeader:\n    /* Parse Stage2 PE/COFF executable header */\n    pushw %es\n    movw $(0xF800 / 16), %ax\n    movw %ax, %es\n    movl %es:60, %eax\n    addl $(4 + 20), %eax\n    movl %es:16(%eax), %eax\n    addl $0xF800, %eax\n    popw %es\n    ret\n\nReadCluster:\n    /* Read FAT32 cluster from disk */\n    decl %eax\n    decl %eax\n    xorl %edx, %edx\n    movzbl SectorsPerCluster - Start(%bp), %ebx\n    mull %ebx\n    pushl %eax\n    xorl %edx, %edx\n    movzbl FatCopies - Start(%bp), %eax\n    mull BigSectorsPerFat - Start(%bp)\n    movzwl ReservedSectors - Start(%bp), %ebx\n    addl %ebx, %eax\n    addl HiddenSectors - Start(%bp), %eax\n    popl %ebx\n    addl %ebx, %eax\n    xorw %bx, %bx\n    movzbw SectorsPerCluster - Start(%bp), %cx\n    call ReadSectors\n    ret\n\n/* Include architecture specific code */\n.include ARCH_ESP_SOURCE\n\nCpuUnsupported:\n    /* Display CPU unsupported message and reboot */\n    popal\n    movw $.MsgCpuUnsupported, %si\n    call Print\n    jmp Reboot\n\nFileNotFound:\n    /* Display XTLDR not found message and reboot */\n    movw $.MsgXtLdrNotFound, %si\n    call Print\n    jmp Reboot\n\nStage2NotLoaded:\n    /* Clean up the stack and display XTLDR not found message and reboot */\n    popl %esi\n    jmp FileNotFound\n\n.BootDirName:\n    /* Boot directory name */\n    .ascii \"BOOT       \"\n\n.EfiDirName:\n    /* EFI directory name */\n    .ascii \"EFI        \"\n\n.MsgCpuUnsupported:\n    .ascii \"CPU not supported!\\r\\n\\0\"\n\n.MsgXtLdrNotFound:\n    .ascii \"XTLDR Stage2 not found!\\r\\n\\0\"\n\n/* Fill the rest of the extra VBR with zeros and add signature */\n.fill (2043 - (. - Start)), 1, 0\n.ascii \"XTLDR\"\n"
  },
  {
    "path": "boot/bootsect/i686/cpu.S",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            boot/bootsect/i686/cpu.S\n * DESCRIPTION:     Low-level support for CPU initialization\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n\nBuildPageMap:\n    /* Generate page map for first 16MB of memory */\n    pushaw\n    pushw %es\n    cld\n    movw $(0x1000 >> 0x04), %ax\n    movw %ax, %es\n    xorw %di, %di\n    movl $(0x2000 | 0x03), %eax\n    stosl\n    movl $(0x3000 | 0x03), %eax\n    stosl\n    movl $(0x4000 | 0x03), %eax\n    stosl\n    movl $(0x5000 | 0x03), %eax\n    stosl\n    xorl %eax, %eax\n    movw $(1024 - 4), %cx\n    rep stosl\n    movl $0x00000003, %eax\n    movl $4, %edx\n    movw $(0x2000 >> 0x04), %bx\n.BuildPageMapLoop:\n    /* Identity map 1024 pages of 4KB */\n    movw %bx, %es\n    xorw %di, %di\n    pushl %edx\n    movw $1024, %cx\n.FillPageMapTable:\n    /* Fill the page table */\n    movl %eax, %es:(%di)\n    addl $4096, %eax\n    addw $0x04, %di\n    loop .FillPageMapTable\n    popl %edx\n    addw $(0x1000 >> 0x04), %bx\n    decl %edx\n    jnz .BuildPageMapLoop\n    popw %es\n    popaw\n    ret\n\nInitializeCpu:\n    /* Check if CPU supports CPUID */\n    pushal\n    pushfl\n    popl %eax\n    movl %eax, %ebx\n    xorl $0x00200000, %eax\n    pushl %eax\n    popfl\n    pushfl\n    popl %eax\n    cmpl %ebx, %eax\n    je CpuUnsupported\n    popal\n    call LoadGdt\n    ret\n\nLoadGdt:\n    /* Load Global Descriptor Table */\n    lgdt .GdtPointer\n    ret\n\nRunStage2:\n    /* Switch to protected mode and pass control to Stage 2 */\n    call BuildPageMap\n    call ParseExecutableHeader\n    pushl %eax\n    cli\n    movl %cr0, %eax\n    orl $0x01, %eax\n    movl %eax, %cr0\n    ljmp $0x08, $.Stage2ProtectedMode\n.code32\n.Stage2ProtectedMode:\n    /* Set segments and stack, then jump to Stage 2 */\n    movw $0x10, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n    xorw %ax, %ax\n    movw %ax, %fs\n    movw %ax, %gs\n    popl %eax\n    xorl %ebx, %ebx\n    xorl %ecx, %ecx\n    xorl %edx, %edx\n    xorl %esi, %esi\n    xorl %edi, %edi\n    xorl %ebp, %ebp\n    movl $0x1000, %ebx\n    movl %ebx, %cr3\n    movl %cr0, %ebx\n    orl $0x80000000, %ebx\n    movl %ebx, %cr0\n    jmp *%eax\n\n.code16\n.GdtDescriptor:\n    /* Global Descriptor Table */\n    .quad 0x0000000000000000\n    .quad 0x00CF9A000000FFFF\n    .quad 0x00CF92000000FFFF\n    .quad 0x00009E000000FFFF\n    .quad 0x000092000000FFFF\n\n.GdtPointer:\n    /* Pointer to Global Descriptor Table */\n    .word .GdtPointer - .GdtDescriptor - 1\n    .long .GdtDescriptor\n\n.Stage2FileName:\n    /* Name of Stage 2 executable file */\n    .ascii \"BOOTIA32EFI\"\n"
  },
  {
    "path": "boot/bootsect/mbrboot.S",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            boot/bootsect/amd64/mbrboot.S\n * DESCRIPTION:     XT Boot Loader MBR boot code\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <aiken@codingworkshop.eu.org>\n */\n\n.text\n.code16\n\n\n.global Start\nStart:\n    /* Set segments and stack */\n    cli\n    cld\n    xorw %ax, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n    movw $0x7C00, %bp\n    leaw -16(%bp), %sp\n    sti\n\n    /* Relocate MBR to 1FE0:7C00 */\n    movw $0x1FE0, %ax\n    movw %ax, %es\n    movw %bp, %si\n    movw %bp, %di\n    movw $256, %cx\n    rep movsw\n\n    /* Jump to the relocated MBR code */\n    jmp $0x1FE0, $RealStart\n\nRealStart:\n    /* Set segments */\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n\n    /* Print welcome message */\n    leaw .MsgXtosBoot, %si\n    call Print\n\n    /* Get BIOS boot drive and partition table offset */\n    lea 0x1BE(%bp), %si\n    movb %dl, .BootDrive\n    xorw %cx, %cx\n\nFindActivePartition:\n    /* Look for active partition */\n    movb (%si), %al\n    cmpb $0x80, %al\n    je PartitionFound\n    addw $16, %si\n    incw %cx\n    cmpw $4, %cx\n    jne FindActivePartition\n    jmp PartitionNotFound\n\nPartitionFound:\n    /* Save LBA start */\n    movl 8(%si), %eax\n    movl %eax, .LbaStart\n\n    /* Prepare Disk Address Packet (DAP) */\n    lea .Dap, %si\n    movb $0x10, 0(%si)\n    movb $0x00, 1(%si)\n    movw $1, 2(%si)\n    movw $0x7C00, 4(%si)\n    movw $0x0000, 6(%si)\n    movl .LbaStart, %eax\n    movl %eax, 8(%si)\n\n    /* Read Volume Boot Record (VBR) */\n    movb $0x42, %ah\n    movb .BootDrive, %dl\n    int $0x13\n    jc VbrReadFail\n\n    /* Verify VBR signature */\n    cmpw $0xAA55, (0x7C00 + 0x01FE)\n    jne InvalidSignature\n\n    /* Jump to the VBR code */\n    jmp $0x0000, $0x7C00\n\nInvalidSignature:\n    /* Invalid signature error */\n    leaw .MsgInvalidSignature, %si\n    call Print\n    jmp HaltSystem\n\nPartitionNotFound:\n    /* Active partition not found error */\n    leaw .MsgPartitionNotFound, %si\n    call Print\n    jmp HaltSystem\n\nVbrReadFail:\n    /* VBR read failed error */\n    leaw .MsgVbrReadFail, %si\n    call Print\n    jmp HaltSystem\n\nHaltSystem:\n    /* Disable interrupts and stop the CPU */\n    cli\n    hlt\n    jmp HaltSystem\n\nPrint:\n    /* Simple routine to print messages */\n    lodsb\n    orb     %al, %al\n    jz      DonePrint\n    movb    $0x0E, %ah\n    movw    $0x07, %bx\n    int     $0x10\n    jmp     Print\nDonePrint:\n    retw\n\n.BootDrive:\n    /* Storage for the boot drive number */\n    .byte 0\n\n.Dap:\n    /* Storage for the Disk Address Packet (DAP) */\n    .fill 16, 1, 0\n\n.LbaStart:\n    /* Storage for the LBA start */\n    .long 0\n\n.MsgInvalidSignature:\n    .asciz \"Invalid partition signature!\"\n\n.MsgPartitionNotFound:\n    .asciz \"Bootable partition not found!\"\n\n.MsgVbrReadFail:\n    .asciz \"VBR read failed!\"\n\n.MsgXtosBoot:\n    .asciz \"Starting XTOS boot loader...\\r\\n\"\n\n/* Fill the rest of the MBR with zeros and add MBR signature at the end */\n.fill (510 - (. - Start)), 1, 0\n.word 0xAA55\n"
  },
  {
    "path": "boot/xtldr/CMakeLists.txt",
    "content": "# XT Boot Loader\nPROJECT(XTLDR)\n\n# Build XTLDR modules\nadd_subdirectory(modules)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTLDR_SOURCE_DIR}/includes)\n\n# Specify list of library source code files\nlist(APPEND LIBXTLDR_SOURCE\n    ${XTLDR_SOURCE_DIR}/library/modproto.cc)\n\n# Specify list of source code files\nlist(APPEND XTLDR_SOURCE\n    ${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc\n    ${XTLDR_SOURCE_DIR}/biosutil.cc\n    ${XTLDR_SOURCE_DIR}/bootutil.cc\n    ${XTLDR_SOURCE_DIR}/config.cc\n    ${XTLDR_SOURCE_DIR}/console.cc\n    ${XTLDR_SOURCE_DIR}/data.cc\n    ${XTLDR_SOURCE_DIR}/debug.cc\n    ${XTLDR_SOURCE_DIR}/efiutils.cc\n    ${XTLDR_SOURCE_DIR}/memory.cc\n    ${XTLDR_SOURCE_DIR}/protocol.cc\n    ${XTLDR_SOURCE_DIR}/shell.cc\n    ${XTLDR_SOURCE_DIR}/textui.cc\n    ${XTLDR_SOURCE_DIR}/volume.cc\n    ${XTLDR_SOURCE_DIR}/xtldr.cc)\n\n# Link static XTLDR library\nadd_library(libxtldr ${LIBXTLDR_SOURCE})\n\n# Link bootloader executable\nadd_executable(xtldr ${XTLDR_SOURCE})\n\n# Add linker libraries\ntarget_link_libraries(xtldr libxtos)\n\n# Add linker options\ntarget_link_options(xtldr PRIVATE /ALIGN:512)\n\n# Set proper binary name and install target\nif(ARCH STREQUAL \"i686\")\n\tset(BINARY_NAME \"bootia32\")\nelseif(ARCH STREQUAL \"amd64\")\n\tset(BINARY_NAME \"bootx64\")\nendif()\nset_target_properties(xtldr PROPERTIES OUTPUT_NAME ${BINARY_NAME} SUFFIX .efi)\nset_install_target(xtldr efi/boot)\n\n# Set loader entrypoint and subsystem\nset_entrypoint(xtldr \"BlStartXtLoader\")\nset_imagebase(xtldr ${BASEADDRESS_XTLDR})\nset_linker_map(xtldr TRUE)\nset_subsystem(xtldr efi_application)\n"
  },
  {
    "path": "boot/xtldr/README.md",
    "content": "## XT Boot Loader (XTLDR)\nThe XTLDR, or XTOS Boot Loader, is an EFI (Extensible Firmware Interface) boot loader specifically designed for XTOS.\nAs an EFI boot loader, XTLDR operates exclusively with EFI-based hardware and is not compatible with non-EFI systems,\nlike old and deprecated BIOS.\n\nOne of the notable features of XTLDR is its modular design. The boot loader is divided into different modules, with only\nthe essential core being loaded during the boot process. This modular approach allows for a more efficient and\nstreamlined boot experience, as only the necessary functionality is loaded, reducing the boot time and system resource\nusage.\n\nXTLDR includes various modules that provide specific functionalities required for the boot process. For example, there is\na module dedicated to supporting the XTOS boot protocol, which is the specific protocol used by XTOS for loading and\nexecuting the OS kernel. Additionally, there is a module for handling PE/COFF (Portable Executable) binaries, which is\na commonly used format of executable files used by the XTOS.\n"
  },
  {
    "path": "boot/xtldr/arch/amd64/memory.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/arch/amd64/memory.cc\n * DESCRIPTION:     XT Boot Loader AMD64 specific memory management\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Maps boot loader related code and builds page map.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param SelfMapAddress\n *        Supplies a virtual address of the page tables.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,\n                     IN ULONG_PTR SelfMapAddress)\n{\n    PLIST_ENTRY ModulesList, ModulesListEntry;\n    PXTBL_MODULE_INFO ModuleInfo;\n    EFI_PHYSICAL_ADDRESS Address;\n    ULONGLONG LoaderSize;\n    EFI_STATUS Status;\n    PVOID LoaderBase;\n\n    /* Allocate pages for the Page Map */\n    Status = AllocatePages(AllocateAnyPages, 1, &Address);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        return Status;\n    }\n\n    /* Add new memory mapping for the page map itself */\n    Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory mapping failure */\n        return Status;\n    }\n\n    /* Assign and zero-fill memory used by page mappings */\n    PageMap->PtePointer = (PVOID)(UINT_PTR)Address;\n    RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);\n\n    /* Add page mapping itself to memory mapping */\n    Status = Memory::SelfMapPml(PageMap, SelfMapAddress);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* PML mapping failed */\n        return Status;\n    }\n\n    /* Map the trampoline code area */\n    Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS,\n                              1, LoaderFirmwareTemporary);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Mapping trampoline code failed */\n        return Status;\n    }\n\n    /* Get list of XTLDR modules */\n    ModulesList = Protocol::GetModulesList();\n    ModulesListEntry = ModulesList->Flink;\n    while(ModulesListEntry != ModulesList)\n    {\n        /* Get module info */\n        ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);\n\n        /* Map module code */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,\n                                  EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);\n\n        /* Check if mapping succeeded */\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Mapping module code failed */\n            return Status;\n        }\n\n        /* Get next module */\n        ModulesListEntry = ModulesListEntry->Flink;\n    }\n\n    /* Get boot loader image information */\n    XtLoader::GetLoaderImageInformation(&LoaderBase, &LoaderSize);\n\n    /* Make sure boot loader image base and size are set */\n    if(LoaderBase && LoaderSize)\n    {\n        /* Map boot loader code as well */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,\n                                  EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Mapping boot loader code failed */\n            return Status;\n        }\n    }\n    else\n    {\n        /* Boot loader image information re not available */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Iterates through the memory map and physically maps all virtual addresses to page tables.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    PXTBL_MEMORY_MAPPING Mapping;\n    PLIST_ENTRY ListEntry;\n    EFI_STATUS Status;\n\n    /* Iterate through and map all the mappings*/\n    Debug::Print(L\"Mapping and dumping EFI memory:\\n\");\n    ListEntry = PageMap->MemoryMap.Flink;\n    while(ListEntry != &PageMap->MemoryMap)\n    {\n        /* Take mapping from the list */\n        Mapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);\n\n        /* Check if virtual address is set */\n        if(Mapping->VirtualAddress)\n        {\n            /* Dump memory mapping */\n            Debug::Print(L\"   Type=%02lu, PhysicalBase=%.16P, VirtualBase=%.16P, Pages=%llu\\n\", Mapping->MemoryType,\n                         Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);\n\n            /* Map memory */\n            Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,\n                             (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory mapping failed */\n                return Status;\n            }\n        }\n\n        /* Take next element */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Returns next level of the Page Table.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param PageTable\n *        Supplies a pointer to the current Page Table.\n *\n * @param Entry\n *        Supplies an index of the current Page Table entry.\n *\n * @param NextPageTable\n *        Supplies a pointer to the memory area where the next Page Table level is returned.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,\n                         IN PVOID PageTable,\n                         IN SIZE_T Entry,\n                         OUT PVOID *NextPageTable)\n{\n    EFI_PHYSICAL_ADDRESS Address;\n    ULONGLONG PmlPointer = 0;\n    PHARDWARE_PTE PmlTable;\n    EFI_STATUS Status;\n\n    PmlTable = (PHARDWARE_PTE)PageTable;\n\n    /* Check if this is a valid table */\n    if(PmlTable[Entry].Valid)\n    {\n        /* Get PML pointer */\n        PmlPointer = PmlTable[Entry].PageFrameNumber;\n        PmlPointer <<= EFI_PAGE_SHIFT;\n    }\n    else\n    {\n        /* Allocate pages for new PML entry */\n        Status = AllocatePages(AllocateAnyPages, 1, &Address);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failure */\n            return Status;\n        }\n\n        /* Add new memory mapping */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory mapping failure */\n            return Status;\n        }\n\n        /* Fill allocated memory with zeros */\n        RTL::Memory::ZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);\n\n        /* Set paging entry settings */\n        PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;\n        PmlTable[Entry].Valid = 1;\n        PmlTable[Entry].Writable = 1;\n        PmlPointer = (ULONGLONG)Address;\n    }\n\n    /* Set next Page Map Level (PML) */\n    *NextPageTable = (PVOID)(ULONGLONG)PmlPointer;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Does the actual virtual memory mapping.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param VirtualAddress\n *        Supplies a virtual address of the mapping.\n *\n * @param PhysicalAddress\n *        Supplies a physical address of the mapping.\n *\n * @param NumberOfPages\n *        Supplies a number of the pages of the mapping.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,\n                IN ULONGLONG VirtualAddress,\n                IN ULONGLONG PhysicalAddress,\n                IN ULONGLONG NumberOfPages)\n{\n    PVOID Pml1, Pml2, Pml3, Pml4, Pml5;\n    SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;\n    PHARDWARE_PTE PmlTable;\n    SIZE_T PageFrameNumber;\n    EFI_STATUS Status;\n\n    /* Set the Page Frame Number (PFN) */\n    PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;\n\n    /* Do the recursive mapping */\n    while(NumberOfPages > 0)\n    {\n        /* Calculate the indices in the various Page Tables from the virtual address */\n        Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT;\n        Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT;\n        Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT;\n        Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT;\n        Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT;\n\n        /* Check page map level */\n        if(PageMap->PageMapLevel == 5)\n        {\n            /* Five level Page Map */\n            Pml5 = PageMap->PtePointer;\n\n            /* Get PML4 */\n            Status = GetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory mapping failure */\n                return Status;\n            }\n        }\n        else\n        {\n            /* Four level Page Map */\n            Pml4 = PageMap->PtePointer;\n        }\n\n        /* Get PML3 */\n        Status = GetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory mapping failure */\n            return Status;\n        }\n\n        /* Get PML 2 */\n        Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory mapping failure */\n            return Status;\n        }\n\n        /* Get PML1 */\n        Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory mapping failure */\n            return Status;\n        }\n\n        /* Set paging entry settings */\n        PmlTable = (PHARDWARE_PTE)Pml1;\n        RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE));\n        PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;\n        PmlTable[Pml1Entry].Valid = 1;\n        PmlTable[Pml1Entry].Writable = 1;\n\n        /* Take next virtual address and PFN */\n        VirtualAddress += EFI_PAGE_SIZE;\n        PageFrameNumber++;\n\n        /* Decrease number of pages left */\n        NumberOfPages--;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Creates a recursive self mapping for all PML levels.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param SelfMapAddress\n *        Supplies a virtual address of the page tables.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,\n                   IN ULONG_PTR SelfMapAddress)\n{\n    PHARDWARE_PTE PmlBase;\n    ULONGLONG PmlIndex;\n\n    /* Initialize PML base pointer */\n    PmlBase = (PHARDWARE_PTE)PageMap->PtePointer;\n\n    /* Check page map level */\n    if(PageMap->PageMapLevel == 5)\n    {\n        /* Calculate PML index based on provided self map address for PML5 */\n        PmlIndex = (SelfMapAddress >> MM_P5I_SHIFT) & 0x1FF;\n    }\n    else\n    {\n        /* Calculate PML index based on provided self map address for PML4 */\n        PmlIndex = (SelfMapAddress >> MM_PXI_SHIFT) & 0x1FF;\n    }\n\n    /* Add self-mapping */\n    RTL::Memory::ZeroMemory(&PmlBase[PmlIndex], sizeof(HARDWARE_PTE));\n    PmlBase[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;\n    PmlBase[PmlIndex].Valid = 1;\n    PmlBase[PmlIndex].Writable = 1;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n"
  },
  {
    "path": "boot/xtldr/arch/i686/memory.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/arch/i686/memory.cc\n * DESCRIPTION:     XT Boot Loader i686 specific memory management\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Maps boot loader related code and builds page map.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,\n                     IN ULONG_PTR SelfMapAddress)\n{\n    EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;\n    PLIST_ENTRY ModulesList, ModulesListEntry;\n    PXTBL_MODULE_INFO ModuleInfo;\n    ULONGLONG LoaderSize;\n    EFI_STATUS Status;\n    PVOID LoaderBase;\n    ULONG Index;\n\n    /* Check the page map level to determine which paging structure to create */\n    if(PageMap->PageMapLevel == 3)\n    {\n        /* Allocate a page for the 3-level page map structure (PAE enabled) */\n        Status = AllocatePages(AllocateAnyPages, 1, &Address);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failed, cannot proceed with page map creation */\n            return Status;\n        }\n\n        /* Add new memory mapping for the page map itself */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory mapping failure */\n            return Status;\n        }\n\n        /* Assign the allocated page to the page map and zero it out */\n        PageMap->PtePointer = (PVOID)(UINT_PTR)Address;\n        RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);\n\n        /* Allocate 4 pages for the Page Directories (PDs) */\n        Status = AllocatePages(AllocateAnyPages, 4, &DirectoryAddress);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failed, cannot proceed with page map creation */\n            return Status;\n        }\n\n        /* Add new memory mapping for the Page Directories (PDs) */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, DirectoryAddress, 4, LoaderMemoryData);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory mapping failure */\n            return Status;\n        }\n\n        /* Zero-fill the allocated memory for the Page Directories */\n        RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);\n\n        /* Fill the PDPT with pointers to the Page Directories */\n        for(Index = 0; Index < 4; Index++)\n        {\n            RTL::Memory::ZeroMemory(&((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index], sizeof(HARDWARE_MODERN_PTE));\n            ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber = DirectoryAddress / EFI_PAGE_SIZE;\n            ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].Valid = 1;\n            DirectoryAddress += EFI_PAGE_SIZE;\n        }\n    }\n    else\n    {\n        /* Allocate a page for the 2-level page map structure (PAE disabled) */\n        Status = AllocatePages(AllocateAnyPages, 1, &Address);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failed, cannot proceed with page map creation */\n            return Status;\n        }\n\n        /* Add new memory mapping for the page map itself */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory mapping failure */\n            return Status;\n        }\n\n        /* Assign the allocated page to the page map and zero it out */\n        PageMap->PtePointer = (PVOID)(UINT_PTR)Address;\n        RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);\n    }\n\n    /* Add page mapping itself to memory mapping */\n    Status = SelfMapPml(PageMap, SelfMapAddress);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* PML mapping failed */\n        return Status;\n    }\n\n    /* Map the trampoline code area */\n    Status = MapVirtualMemory(PageMap, MM_TRAMPOLINE_ADDRESS, MM_TRAMPOLINE_ADDRESS, 1, LoaderFirmwareTemporary);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Mapping trampoline code failed */\n        return Status;\n    }\n\n    /* Get list of XTLDR modules */\n    ModulesList = Protocol::GetModulesList();\n    ModulesListEntry = ModulesList->Flink;\n    while(ModulesListEntry != ModulesList)\n    {\n        /* Get module info */\n        ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);\n\n        /* Map module code */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)ModuleInfo->ModuleBase, (ULONGLONG)ModuleInfo->ModuleBase,\n                                  EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);\n\n        /* Check if mapping succeeded */\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Mapping module code failed */\n            return Status;\n        }\n\n        /* Get next module */\n        ModulesListEntry = ModulesListEntry->Flink;\n    }\n\n    /* Get boot loader image information */\n    XtLoader::GetLoaderImageInformation(&LoaderBase, &LoaderSize);\n\n    /* Make sure boot loader image base and size are set */\n    if(LoaderBase && LoaderSize)\n    {\n        /* Map boot loader code as well */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)LoaderBase, (ULONGLONG)LoaderBase,\n                                  EFI_SIZE_TO_PAGES(LoaderSize), LoaderFirmwareTemporary);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Mapping boot loader code failed */\n            return Status;\n        }\n    }\n    else\n    {\n        /* Boot loader image information re not available */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Iterates through the memory map and physically maps all virtual addresses to page tables.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    PXTBL_MEMORY_MAPPING Mapping;\n    PLIST_ENTRY ListEntry;\n    EFI_STATUS Status;\n\n    /* Iterate through and map all the mappings*/\n    Debug::Print(L\"Mapping and dumping EFI memory:\\n\");\n    ListEntry = PageMap->MemoryMap.Flink;\n    while(ListEntry != &PageMap->MemoryMap)\n    {\n        /* Take mapping from the list */\n        Mapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);\n\n        /* Check if virtual address is set */\n        if(Mapping->VirtualAddress)\n        {\n            /* Dump memory mapping */\n            Debug::Print(L\"   Type=%02lu, PhysicalBase=0x%.8llX, VirtualBase=0x%.8llX, Pages=%llu\\n\",\n                         Mapping->MemoryType, Mapping->PhysicalAddress,\n                         Mapping->VirtualAddress, Mapping->NumberOfPages);\n\n            /* Map memory */\n            Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,\n                             (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory mapping failed */\n                return Status;\n            }\n        }\n\n        /* Take next element */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Returns next level of the Page Table.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param PageTable\n *        Supplies a pointer to the current Page Table.\n *\n * @param Entry\n *        Supplies an index of the current Page Table entry.\n *\n * @param NextPageTable\n *        Supplies a pointer to the memory area where the next Page Table level is returned.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,\n                         IN PVOID PageTable,\n                         IN SIZE_T Entry,\n                         OUT PVOID *NextPageTable)\n{\n    EFI_PHYSICAL_ADDRESS Address;\n    ULONGLONG PmlPointer = 0;\n    EFI_STATUS Status;\n    PHARDWARE_LEGACY_PTE LegacyPmlTable;\n    PHARDWARE_MODERN_PTE PmlTable;\n    BOOLEAN ValidPte = FALSE;\n\n    /* Check page map level to determine PTE size */\n    if(PageMap->PageMapLevel >= 3)\n    {\n        /* 64-bit PTE for PML3 (PAE enabled) */\n        PmlTable = (PHARDWARE_MODERN_PTE)PageTable;\n        if(PmlTable[Entry].Valid)\n        {\n            /* Get page frame number from page table entry */\n            PmlPointer = PmlTable[Entry].PageFrameNumber;\n            ValidPte = TRUE;\n        }\n    }\n    else\n    {\n        /* 32-bit PTE for PML2 (PAE disabled) */\n        LegacyPmlTable = (PHARDWARE_LEGACY_PTE)PageTable;\n        if(LegacyPmlTable[Entry].Valid)\n        {\n            /* Get page frame number from page table entry */\n            PmlPointer = LegacyPmlTable[Entry].PageFrameNumber;\n            ValidPte = TRUE;\n        }\n    }\n\n    /* Check if page table entry is valid */\n    if(ValidPte)\n    {\n        /* Calculate the base address of the next page table */\n        PmlPointer <<= EFI_PAGE_SHIFT;\n    }\n    else\n    {\n        /* Allocate pages for new PML entry */\n        Status = AllocatePages(AllocateAnyPages, 1, &Address);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failure */\n            return Status;\n        }\n\n        /* Add new memory mapping */\n        Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory mapping failure */\n            return Status;\n        }\n\n        /* Fill allocated memory with zeros */\n        RTL::Memory::ZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);\n\n        /* Set paging entry settings based on level */\n        if(PageMap->PageMapLevel >= 3)\n        {\n            /* 64-bit PTE for PML3 (PAE enabled) */\n            PmlTable = (PHARDWARE_MODERN_PTE)PageTable;\n            PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;\n            PmlTable[Entry].Valid = 1;\n            PmlTable[Entry].Writable = 1;\n        }\n        else\n        {\n            /* 32-bit PTE for PML2 (PAE disabled) */\n            LegacyPmlTable = (PHARDWARE_LEGACY_PTE)PageTable;\n            LegacyPmlTable[Entry].PageFrameNumber = (UINT32)(Address / EFI_PAGE_SIZE);\n            LegacyPmlTable[Entry].Valid = 1;\n            LegacyPmlTable[Entry].Writable = 1;\n        }\n\n        /* Return the address of the new page table */\n        PmlPointer = (ULONGLONG)Address;\n    }\n\n    /* Set next Page Map Level (PML) */\n    *NextPageTable = (PVOID)(ULONGLONG)PmlPointer;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Does the actual virtual memory mapping.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param VirtualAddress\n *        Supplies a virtual address of the mapping.\n *\n * @param PhysicalAddress\n *        Supplies a physical address of the mapping.\n *\n * @param NumberOfPages\n *        Supplies a number of the pages of the mapping.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,\n                IN ULONGLONG VirtualAddress,\n                IN ULONGLONG PhysicalAddress,\n                IN ULONGLONG NumberOfPages)\n{\n    ULONGLONG PageFrameNumber;\n    PVOID Pml1, Pml2, Pml3;\n    SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;\n    PHARDWARE_LEGACY_PTE LegacyPmlTable;\n    PHARDWARE_MODERN_PTE PmlTable;\n    EFI_STATUS Status;\n\n    /* Set the Page Frame Number (PFN) */\n    PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;\n\n    /* Map all requested pages */\n    while(NumberOfPages > 0)\n    {\n        /* Check the paging mode to use the correct page table structure */\n        if(PageMap->PageMapLevel == 3)\n        {\n            /* Calculate the indices for PAE page tables */\n            Pml3Entry = (VirtualAddress >> 30) & 0x3;\n            Pml2Entry = (VirtualAddress >> 21) & 0x1FF;\n            Pml1Entry = (VirtualAddress >> 12) & 0x1FF;\n\n            /* Get Page Directory Pointer Table (PML3) */\n            Pml3 = PageMap->PtePointer;\n\n            /* Get Page Directory (PML2) */\n            Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to get the Page Table, abort mapping */\n                return Status;\n            }\n\n            /* Get Page Table (PML1) */\n            Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to get the Page Table, abort mapping */\n                return Status;\n            }\n\n            /* Set the 64-bit PTE entry */\n            PmlTable = (PHARDWARE_MODERN_PTE)Pml1;\n            RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE));\n            PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;\n            PmlTable[Pml1Entry].Valid = 1;\n            PmlTable[Pml1Entry].Writable = 1;\n        }\n        else\n        {\n            /* Calculate the indices for non-PAE page tables */\n            Pml2Entry = (VirtualAddress >> 22) & 0x3FF;\n            Pml1Entry = (VirtualAddress >> 12) & 0x3FF;\n\n            /* Get Page Directory (PML2) */\n            Pml2 = PageMap->PtePointer;\n\n            /* Get Page Table (PML1) */\n            Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to get the Page Table, abort mapping */\n                return Status;\n            }\n\n            /* Set the 32-bit PTE entry */\n            LegacyPmlTable = (PHARDWARE_LEGACY_PTE)Pml1;\n            RTL::Memory::ZeroMemory(&LegacyPmlTable[Pml1Entry], sizeof(HARDWARE_LEGACY_PTE));\n            LegacyPmlTable[Pml1Entry].PageFrameNumber = (UINT32)PageFrameNumber;\n            LegacyPmlTable[Pml1Entry].Valid = 1;\n            LegacyPmlTable[Pml1Entry].Writable = 1;\n        }\n\n        /* Take next virtual address and PFN */\n        VirtualAddress += EFI_PAGE_SIZE;\n        PageFrameNumber++;\n\n        /* Decrease number of pages left */\n        NumberOfPages--;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Creates a recursive self mapping for all PML levels.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param SelfMapAddress\n *        Supplies a virtual address of the page tables.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,\n                   IN ULONG_PTR SelfMapAddress)\n{\n    PHARDWARE_LEGACY_PTE LegacyPml;\n    PHARDWARE_MODERN_PTE Pml;\n    ULONGLONG PmlIndex;\n    ULONG Index;\n\n    /* Check page map level */\n    if(PageMap->PageMapLevel == 3)\n    {\n        /* Calculate PML index based on provided self map address */\n        PmlIndex = (SelfMapAddress >> MM_PDI_SHIFT) & 0x1FF;\n\n        /* Get Page Directory */\n        Pml = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[SelfMapAddress >> MM_PPI_SHIFT].PageFrameNumber * EFI_PAGE_SIZE);\n\n        /* Add self-mapping for PML3 (PAE enabled) */\n        for(Index = 0; Index < 4; Index++)\n        {\n            RTL::Memory::ZeroMemory(&Pml[PmlIndex + Index], sizeof(HARDWARE_MODERN_PTE));\n            Pml[PmlIndex + Index].PageFrameNumber = ((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[Index].PageFrameNumber;\n            Pml[PmlIndex + Index].Valid = 1;\n            Pml[PmlIndex + Index].Writable = 1;\n        }\n    }\n    else\n    {\n        LegacyPml = (PHARDWARE_LEGACY_PTE)PageMap->PtePointer;\n\n        /* Calculate PML index based on provided self map address */\n        PmlIndex = (SelfMapAddress >> MM_PDI_LEGACY_SHIFT);\n\n        /* Add self-mapping for PML2 (PAE disabled) */\n        RTL::Memory::ZeroMemory(&LegacyPml[PmlIndex], sizeof(HARDWARE_LEGACY_PTE));\n        LegacyPml[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE;\n        LegacyPml[PmlIndex].Valid = 1;\n        LegacyPml[PmlIndex].Writable = 1;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n"
  },
  {
    "path": "boot/xtldr/biosutil.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/biosutil.cc\n * DESCRIPTION:     Legacy BIOS support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Clears the entire screen and moves the cursor to the top-left corner.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nBiosUtils::ClearScreen()\n{\n    VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;\n    USHORT Blank;\n    UINT Index;\n\n    /* Set blank character */\n    Blank = (0x0F << 8) | L' ';\n\n    /* Fill the entire screen with blank characters */\n    for(Index = 0; Index < VgaWidth * VgaHeight; Index++)\n    {\n        VgaBuffer[Index] = Blank;\n    }\n\n    /* Reset cursor position to the top-left corner */\n    CursorX = 0;\n    CursorY = 0;\n\n    /* Update the hardware cursor position */\n    UpdateCursor();\n}\n\n/**\n * Formats the input string and prints it out to the screen.\n *\n * @param Format\n *        The formatted string that is to be written to the output.\n *\n * @param ...\n *        Depending on the format string, this routine might expect a sequence of additional arguments.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nBiosUtils::Print(IN PCWSTR Format,\n                 IN ...)\n{\n    RTL_PRINT_CONTEXT PrintContext;\n    VA_LIST Arguments;\n\n    /* Initialise the print contexts */\n    PrintContext.WriteWideCharacter = PutChar;\n\n    /* Initialise the va_list */\n    VA_START(Arguments, Format);\n\n    /* Format and print the string to the stdout */\n    RTL::WideString::FormatWideString(&PrintContext, (PWCHAR)Format, Arguments);\n\n    /* Clean up the va_list */\n    VA_END(Arguments);\n}\n\n/**\n * Writes a single wide character to the screen using legacy BIOS VGA text mode.\n *\n * @param Character\n *        The wide character to be printed.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nBiosUtils::PutChar(IN WCHAR Character)\n{\n    VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;\n    USHORT VgaCharacter;\n\n    /* Handle special characters */\n    if(Character == L'\\n')\n    {\n        /* Move to the next line */\n        CursorX = 0;\n        CursorY++;\n    }\n    else if(Character == L'\\r')\n    {\n        /* Move to the beginning of the current line */\n        CursorX = 0;\n    }\n    else\n    {\n        /* Print character and move cursor to the right */\n        VgaCharacter = (0x0F << 8) | (Character & 0xFF);\n        VgaBuffer[CursorY * VgaWidth + CursorX] = VgaCharacter;\n        CursorX++;\n    }\n\n    /* Handle moving to the next line if cursor is at the end of the line */\n    if(CursorX >= VgaWidth)\n    {\n        CursorX = 0;\n        CursorY++;\n    }\n\n    /* Handle scrolling if cursor is at the end of the screen */\n    if(CursorY >= VgaHeight)\n    {\n        ScrollScreen();\n        CursorY = VgaHeight - 1;\n    }\n\n    /* Update the hardware cursor position */\n    UpdateCursor();\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Scrolls the entire screen content up by one line and clears the last line.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nBiosUtils::ScrollScreen()\n{\n    VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;\n    USHORT Blank;\n    UINT Index;\n\n    /* Set blank character */\n    Blank = (0x0F << 8) | L' ';\n\n    /* Move every line up by one */\n    for(Index = 0; Index < (VgaHeight - 1) * VgaWidth; Index++)\n    {\n        VgaBuffer[Index] = VgaBuffer[Index + VgaWidth];\n    }\n\n    /* Clear the last line */\n    for(Index = (VgaHeight - 1) * VgaWidth; Index < VgaHeight * VgaWidth; Index++)\n    {\n        VgaBuffer[Index] = Blank;\n    }\n}\n\n/**\n * Updates the hardware cursor position on the screen.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nBiosUtils::UpdateCursor()\n{\n    USHORT Position;\n\n    /* Calculate cursor position */\n    Position = CursorY * VgaWidth + CursorX;\n\n    /* Send command to set the high byte of the cursor position */\n    HL::IoPort::WritePort8(0x3D4, 0x0E);\n    HL::IoPort::WritePort8(0x3D5, (UCHAR)((Position >> 8) & 0xFF));\n\n    /* Send command to set the low byte of the cursor position */\n    HL::IoPort::WritePort8(0x3D4, 0x0F);\n    HL::IoPort::WritePort8(0x3D5, (UCHAR)(Position & 0xFF));\n}\n"
  },
  {
    "path": "boot/xtldr/bootutil.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/bootutil.cc\n * DESCRIPTION:     Helper functions used by the boot protocol during system startup\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Checks if a specific option exists in the list of provided boot parameters.\n *\n * @param Parameters\n *        A pointer to the wide-character string containing the boot parameters, separated by spaces.\n *\n * @param Needle\n *        A pointer to the wide-character string representing the kernel option to find.\n *\n * @return This routine returns TRUE if the option is found, otherwise FALSE.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nBootUtils::GetBooleanParameter(IN PCWSTR Parameters,\n                               IN PCWSTR Needle)\n{\n    PCWSTR CurrentPosition, TokenEnd, TokenStart;\n    SIZE_T NeedleLength, TokenLength;\n\n    /* Validate input data and ensure the option is not an empty string */\n    if(Parameters == NULLPTR || Needle == NULLPTR || *Needle == L'\\0')\n    {\n        /* One of the parameters was invalid */\n        return FALSE;\n    }\n\n    CurrentPosition = Parameters;\n    NeedleLength = RTL::WideString::WideStringLength(Needle, 0);\n\n    /* Iterate through the entire parameters string */\n    while(*CurrentPosition != L'\\0')\n    {\n        /* Skip any leading whitespace to find the start of the token */\n        while(*CurrentPosition == L' ')\n        {\n            CurrentPosition++;\n        }\n\n        /* Check if end of the string has been reached */\n        if(*CurrentPosition == L'\\0')\n        {\n            /* End of string reached, no more tokens */\n            break;\n        }\n\n        /* Identify the boundaries of the current token */\n        TokenStart = CurrentPosition;\n        TokenEnd = TokenStart;\n        while(*TokenEnd != L'\\0' && *TokenEnd != L' ')\n        {\n            TokenEnd++;\n        }\n\n        /* Calculate the length of the token found */\n        TokenLength = TokenEnd - TokenStart;\n\n         /* Compare the token length */\n        if(TokenLength == NeedleLength)\n        {\n            /* Length matches, compare the strings */\n            if(RTL::WideString::CompareWideStringInsensitive(TokenStart, Needle, NeedleLength) == 0)\n            {\n                /* A match was found */\n                return TRUE;\n            }\n        }\n\n        /* Move the position past the current token to continue the search */\n        CurrentPosition = TokenEnd;\n    }\n\n    /* No match was found */\n    return FALSE;\n}\n"
  },
  {
    "path": "boot/xtldr/config.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/config.cc\n * DESCRIPTION:     XT Boot Loader Configuration\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Returns a boolean value of the specified configuration key.\n *\n * @param ConfigName\n *        Specifies the configuration key to return its boolean representation.\n *\n * @return This routine returns a boolean representation of the configuration value.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nConfiguration::GetBooleanValue(IN PCWSTR ConfigName)\n{\n    PWCHAR Value;\n\n    /* Get config value */\n    GetValue(ConfigName, &Value);\n\n    /* Check if option is enabled */\n    if(RTL::WideString::CompareWideStringInsensitive(Value, L\"ENABLED\", 0) == 0 ||\n       RTL::WideString::CompareWideStringInsensitive(Value, L\"ON\", 0) == 0 ||\n       RTL::WideString::CompareWideStringInsensitive(Value, L\"TRUE\", 0) == 0 ||\n       RTL::WideString::CompareWideStringInsensitive(Value, L\"YES\", 0) == 0)\n    {\n        /* This option is enabled */\n        return TRUE;\n    }\n\n    /* Return FALSE by default */\n    return FALSE;\n}\n\n/**\n * @brief Retrieves the value of a specific OS boot option from a list.\n *\n * @param Options\n *        A pointer to the head of a list of XTBL_CONFIG_ENTRY structures.\n *\n * @param OptionName\n *        A pointer to wide string that contains the name of the boot option to retrieve.\n *\n * @param OptionValue\n *        A pointer to a variable that receives a pointer to the retrieved boot option's value.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::GetBootOptionValue(IN PLIST_ENTRY Options,\n                                  IN PCWSTR OptionName,\n                                  OUT PWCHAR *OptionValue)\n{\n    PXTBL_CONFIG_ENTRY ConfigEntry;\n    PLIST_ENTRY ConfigList;\n    ULONG KeyLength, ValueLength;\n    EFI_STATUS Status;\n\n    /* Assume the option will not be found */\n    *OptionValue = NULLPTR;\n\n    /* Get the length of the option name we are looking for */\n    KeyLength = RTL::WideString::WideStringLength(OptionName, 0);\n\n    /* Start iterating from the first entry in the options list */\n    ConfigList = Options->Flink;\n    while(ConfigList != Options)\n    {\n        /* Get the container record for the current config entry */\n        ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink);\n\n        /* Compare the current entry's name with the requested option name */\n        if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, OptionName, KeyLength) == 0)\n        {\n            /* Found the option, now prepare to copy its value */\n            ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0);\n\n            /* Allocate memory for the output value string */\n            Status = Memory::AllocatePool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory allocation failure, print debug message and return status code */\n                Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n                *OptionValue = NULLPTR;\n                return Status;\n            }\n\n            /* Copy the value and NULL-terminate the new string */\n            RTL::Memory::CopyMemory(*OptionValue, ConfigEntry->Value, ValueLength * sizeof(WCHAR));\n            (*OptionValue)[ValueLength] = L'\\0';\n\n            /* Successfully retrieved the option value, return success */\n            return STATUS_EFI_SUCCESS;\n        }\n\n        /* Move to the next entry in the list */\n        ConfigList = ConfigList->Flink;\n    }\n\n    /* Option not found */\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Retrieves the list of user-editable boot options.\n *\n * @param OptionsArray\n *        A pointer to a variable that will receive the pointer to the array of editable option names.\n *\n * @param OptionsCount\n *        A pointer to a variable that will be updated with the number of elements in the OptionsArray.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConfiguration::GetEditableOptions(OUT PCWSTR **OptionsArray,\n                                  OUT PULONG OptionsCount)\n{\n    ULONG Count = 0;\n\n    /* Return a pointer to the global array of editable options */\n    *OptionsArray = EditableConfigOptions;\n\n    /* Calculate the number of elements in the array */\n    while(EditableConfigOptions[Count])\n    {\n        Count++;\n    }\n\n    /* Return the number of elements */\n    *OptionsCount = Count;\n}\n\n/**\n * Returns a value of the specified configuration key.\n *\n * @param ConfigName\n *        Specifies the configuration key to return its value.\n *\n * @return This routine returns a pointer to the configuration value, or NULLPTR if key was not found.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::GetValue(IN PCWSTR ConfigName,\n                        OUT PWCHAR *ConfigValue)\n{\n    PXTBL_CONFIG_ENTRY ConfigEntry;\n    PLIST_ENTRY ConfigListEntry;\n    SIZE_T KeyLength, ValueLength;\n    EFI_STATUS Status;\n    PWCHAR Value;\n\n    /* Assume the option will not be found */\n    *ConfigValue = NULLPTR;\n\n    /* Get config entry name length */\n    KeyLength = RTL::WideString::WideStringLength(ConfigName, 0);\n\n    /* Iterate through config entries */\n    ConfigListEntry = Config.Flink;\n    while(ConfigListEntry != &Config)\n    {\n        /* Get config entry */\n        ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink);\n\n        /* Check if requested configuration found */\n        if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, ConfigName, KeyLength) == 0)\n        {\n            /* Get value length */\n            ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0);\n\n            /* Allocate memory for value */\n            Status = Memory::AllocatePool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)&Value);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory allocation failure, return NULLPTR */\n                Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n                return Status;\n            }\n\n            /* Copy value and return it */\n            RTL::Memory::CopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR));\n            Value[ValueLength] = L'\\0';\n            *ConfigValue = Value;\n            return STATUS_EFI_SUCCESS;\n        }\n\n        /* Move to the next config entry */\n        ConfigListEntry = ConfigListEntry->Flink;\n    }\n\n    /* Config entry not found, return NULLPTR */\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Initializes a list of operating systems for XTLDR boot menu.\n *\n * @param MenuEntries\n *        Supplies a pointer to memory area where operating systems list will be stored.\n *\n * @param EntriesCount\n *        Supplies a pointer to memory area where number of menu entries will be stored.\n *\n * @param DefaultId\n *        Supplies a pointer to memory area where ID of default menu entry will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::InitializeBootMenuList(IN ULONG MaxNameLength,\n                                      OUT PXTBL_BOOTMENU_ITEM *MenuEntries,\n                                      OUT PULONG EntriesCount,\n                                      OUT PULONG DefaultId)\n{\n    EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID;\n    PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName;\n    PLIST_ENTRY MenuEntrySectionList, MenuEntryList;\n    PXTBL_CONFIG_SECTION MenuEntrySection;\n    PXTBL_CONFIG_ENTRY MenuEntryOption;\n    ULONG DefaultOS, NameLength,NumberOfEntries;\n    PXTBL_BOOTMENU_ITEM OsList;\n    EFI_STATUS Status;\n\n    /* Set default values */\n    DefaultOS = 0;\n    NumberOfEntries = 0;\n\n    /* Get default menu entry from configuration */\n    Configuration::GetValue(L\"DEFAULT\", &DefaultMenuEntry);\n\n    /* Check if configuration allows to use last booted OS */\n    if(Configuration::GetBooleanValue(L\"KEEPLASTBOOT\"))\n    {\n        /* Attempt to get last booted Operating System from NVRAM */\n        Status = EfiUtils::GetEfiVariable(&VendorGuid, L\"XtLdrLastBootOS\", (PVOID*)&LastBooted);\n        if(Status == STATUS_EFI_SUCCESS)\n        {\n            /* Set default menu entry to last booted OS */\n            DefaultMenuEntry = LastBooted;\n        }\n    }\n\n    /* Iterate through menu items to get a total number of entries */\n    MenuEntrySectionList = BootMenuList->Flink;\n    while(MenuEntrySectionList != BootMenuList)\n    {\n        /* Increase number of menu entries, and simply get next item */\n        NumberOfEntries++;\n        MenuEntrySectionList = MenuEntrySectionList->Flink;\n    }\n\n    /* Allocate memory for the OS list depending on the item count */\n    Status = Memory::AllocatePool(NumberOfEntries * sizeof(XTBL_BOOTMENU_ITEM), (PVOID*)&OsList);\n    if(Status != STATUS_EFI_SUCCESS || !OsList)\n    {\n        /* Memory allocation failure */\n        return STATUS_EFI_OUT_OF_RESOURCES;\n    }\n\n    /* Reset counter and iterate through all menu items once again */\n    NumberOfEntries = 0;\n    MenuEntrySectionList = BootMenuList->Flink;\n    while(MenuEntrySectionList != BootMenuList)\n    {\n        /* NULLify menu entry name */\n        MenuEntryName = NULLPTR;\n\n        /* Get menu section */\n        MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink);\n\n        /* Check if this is the default menu entry */\n        if((RTL::WideString::WideStringLength(MenuEntrySection->SectionName, 0) == RTL::WideString::WideStringLength(DefaultMenuEntry, 0)) &&\n           (RTL::WideString::CompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0))\n        {\n            /* Set default OS ID */\n            DefaultOS = NumberOfEntries;\n        }\n\n        /* Iterate through all entry parameters */\n        MenuEntryList = MenuEntrySection->Options.Flink;\n        while(MenuEntryList != &MenuEntrySection->Options)\n        {\n            /* Get menu entry parameter */\n            MenuEntryOption = CONTAIN_RECORD(MenuEntryList, XTBL_CONFIG_ENTRY, Flink);\n\n            /* Check if this is the menu entry display name */\n            if(RTL::WideString::CompareWideStringInsensitive(MenuEntryOption->Name, L\"SYSTEMNAME\", 0) == 0)\n            {\n                /* Set menu entry display name */\n                MenuEntryName = MenuEntryOption->Value;\n            }\n\n            /* Get next parameter for this menu entry */\n            MenuEntryList = MenuEntryList->Flink;\n        }\n\n        /* Add OS to the boot menu list */\n        OsList[NumberOfEntries].FullName = MenuEntryName;\n        OsList[NumberOfEntries].ShortName = MenuEntrySection->SectionName;\n        OsList[NumberOfEntries].Options = &MenuEntrySection->Options;\n\n        /* Check if the menu entry name fits the maximum length */\n        NameLength = RTL::WideString::WideStringLength(MenuEntryName, 0);\n        if(NameLength > MaxNameLength)\n        {\n            /* Menu entry name is too long, allocate memory for shorter name visible in the boot menu */\n            Status = Memory::AllocatePool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory allocation failure */\n                return STATUS_EFI_OUT_OF_RESOURCES;\n            }\n\n            /* Copy shorter name and append \"...\" at the end */\n            RTL::Memory::CopyMemory(VisibleName, MenuEntryName, (MaxNameLength - 3) * sizeof(WCHAR));\n            RTL::Memory::CopyMemory(VisibleName + MaxNameLength - 3, L\"...\", 3 * sizeof(WCHAR));\n            VisibleName[MaxNameLength] = L'\\0';\n\n            /* Set visible menu entry name */\n            OsList[NumberOfEntries].EntryName = VisibleName;\n        }\n        else\n        {\n            /* Menu entry name fits the maximum length, use it as is */\n            OsList[NumberOfEntries].EntryName = MenuEntryName;\n        }\n\n        /* Get next menu entry */\n        MenuEntrySectionList = MenuEntrySectionList->Flink;\n        NumberOfEntries++;\n    }\n\n    /* Set return values */\n    *DefaultId = DefaultOS;\n    *EntriesCount = NumberOfEntries;\n    *MenuEntries = OsList;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Initializes the XTLDR configuration subsystem.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConfiguration::InitializeConfiguration()\n{\n    /* Initialize XTLDR configuration linked lists */\n    RTL::LinkedList::InitializeListHead(&Config);\n}\n\n/**\n * Loads and parses XTLDR configuration file.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::LoadConfiguration()\n{\n    PLIST_ENTRY SectionListEntry;\n    EFI_STATUS Status;\n    PCHAR ConfigData;\n\n    /* Initialize configuration pointer */\n    RTL::LinkedList::InitializeListHead(&ConfigSections);\n\n    /* Read data from configuration file */\n    Status = ReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L\"XTLDR.INI\", &ConfigData);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to read config file, try with architecture specific directory */\n        Status = ReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L\"XTLDR.INI\", &ConfigData);\n    }\n\n    /* Check if configuration was read successfully */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to load configuration */\n        Debug::Print(L\"Failed to load FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Parse configuration data */\n    Status = ParseConfigFile(ConfigData, &ConfigSections);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to parse configuration */\n        Debug::Print(L\"Failed to parse FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Iterate through config sections */\n    SectionListEntry = ConfigSections.Flink;\n    while(SectionListEntry != &ConfigSections)\n    {\n        /* Get config section */\n        PXTBL_CONFIG_SECTION Section = CONTAIN_RECORD(SectionListEntry, XTBL_CONFIG_SECTION, Flink);\n\n        /* Look for global XTLDR configuration section */\n        if(RTL::WideString::CompareWideStringInsensitive(Section->SectionName, L\"XTLDR\", 5) == 0)\n        {\n            /* Update global configuration */\n            UpdateConfiguration(&Section->Options);\n\n            /* Remove XTLDR section from the list */\n            RTL::LinkedList::RemoveEntryList(SectionListEntry);\n            break;\n        }\n\n        /* Move to the next section */\n        SectionListEntry = SectionListEntry->Flink;\n    }\n\n    /* Update boot menu OS list */\n    BootMenuList = &ConfigSections;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Parses command line arguments and updates global configuration.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::ParseCommandLine(VOID)\n{\n    EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;\n    PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;\n    PWCHAR Argument, Key, LastArg, Value;\n    PXTBL_CONFIG_ENTRY Option;\n    EFI_STATUS Status;\n    SIZE_T KeyLength, ValueLength;\n    LIST_ENTRY Config;\n\n    /* Initialize configuration list */\n    RTL::LinkedList::InitializeListHead(&Config);\n\n    /* Handle loaded image protocol */\n    Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(XtLoader::GetEfiImageHandle(),\n                                                                         &LIPGuid, (PVOID *)&LoadedImage);\n    if(Status == STATUS_EFI_SUCCESS)\n    {\n        /* Check if launched from UEFI shell */\n        if(LoadedImage && LoadedImage->LoadOptions)\n        {\n            /* Tokenize provided options */\n            Argument = RTL::WideString::TokenizeWideString((PWCHAR)LoadedImage->LoadOptions, L\" \", &LastArg);\n\n            /* Iterate over all arguments passed to boot loader */\n            while(Argument != NULLPTR)\n            {\n                /* Store key name */\n                Key = Argument;\n\n                /* Find end of the key */\n                while(*Argument != L'=' && *Argument != L'\\0' && *Argument != L'\\n')\n                {\n                    /* Advance to the next character */\n                    Argument++;\n                }\n\n                /* Mark end of the key and advance to the next character */\n                *Argument = L'\\0';\n                Argument++;\n\n                /* Store value */\n                Value = Argument;\n\n                /* Find end of the value */\n                while(*Argument != L'\\0' && *Argument != L'\\n')\n                {\n                    /* Advance to the next character */\n                    Argument++;\n                }\n\n                /* Mark end of the value and advance to the next character */\n                *Argument = L'\\0';\n                Argument++;\n\n                /* Get length of the key and its value */\n                KeyLength = RTL::WideString::WideStringLength(Key, 0);\n                ValueLength = RTL::WideString::WideStringLength(Value, 0);\n\n                /* Check if argument is valid */\n                if(KeyLength == 0 || ValueLength == 0)\n                {\n                    /* Invalid argument, skip to the next one */\n                    continue;\n                }\n\n                /* Allocate memory for new option */\n                Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option);\n                if(Status == STATUS_EFI_SUCCESS)\n                {\n                    /* Allocate more memory for option name */\n                    Status = Memory::AllocatePool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name);\n                    if(Status == STATUS_EFI_SUCCESS)\n                    {\n                        /* Allocate even more memory for option value */\n                        Status = Memory::AllocatePool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value);\n                    }\n                }\n                if(Status != STATUS_EFI_SUCCESS)\n                {\n                    /* Some memory allocation failed */\n                    return Status;\n                }\n\n                /* Set entry name and value */\n                RTL::Memory::CopyMemory(Option->Name, Key, (KeyLength * sizeof(WCHAR)));\n                RTL::Memory::CopyMemory(Option->Value, Value, (ValueLength * sizeof(WCHAR)));\n                Option->Name[KeyLength] = L'\\0';\n                Option->Value[ValueLength] = L'\\0';\n\n                /* Add entry to the list */\n                RTL::LinkedList::InsertTailList(&Config, &Option->Flink);\n\n                /* Take next argument */\n                Argument = RTL::WideString::TokenizeWideString(NULLPTR, L\" \", &LastArg);\n            }\n\n            /* Update global configuration */\n            UpdateConfiguration(&Config);\n        }\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Parses configuration INI file.\n *\n * @param RawConfig\n *        Suplies a pointer to configuration INI file to be parsed.\n *\n * @param Configuration\n *        Supplies a pointer to memory region where parsed configuration will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::ParseConfigFile(IN CONST PCHAR RawConfig,\n                               OUT PLIST_ENTRY Configuration)\n{\n    SIZE_T SectionLength, KeyLength, ValueLength;\n    PCHAR InputData, Key, SectionName, Value;\n    PXTBL_CONFIG_SECTION Section;\n    PXTBL_CONFIG_ENTRY Option;\n    EFI_STATUS Status;\n\n    /* Initialize pointers */\n    InputData = RawConfig;\n    Section = NULLPTR;\n    Option = NULLPTR;\n    SectionName = NULLPTR;\n    Key = NULLPTR;\n    Value = NULLPTR;\n\n    /* Analyze configuration data until end of file is reached */\n    while(*InputData != '\\0')\n    {\n        if(*InputData == ';' || *InputData == '#')\n        {\n            /* Skip comment until end of the line */\n            while(*InputData != '\\0' && *InputData != '\\n')\n            {\n                /* Advance to the next character */\n                InputData++;\n            }\n        }\n        else if(*InputData == ' ' || *InputData == '\\t' || *InputData == '\\r' || *InputData == '\\n')\n        {\n            /* Skip whitespaces */\n            InputData++;\n        }\n        else if(*InputData == '[')\n        {\n            /* Skip leading bracket */\n            InputData++;\n\n            /* Store section name */\n            SectionName = InputData;\n\n            /* Find end of the section name */\n            while(*InputData != ']' && *InputData != '\\0' && *InputData != '\\r' && *InputData != '\\n')\n            {\n                /* Advance to the next character */\n                InputData++;\n            }\n\n            /* Check if end of the section name is reached */\n            if(*InputData != ']')\n            {\n                /* Section name does not end */\n                return STATUS_EFI_INVALID_PARAMETER;\n            }\n\n            /* Mark end of the section name and advance to the next character */\n            *InputData = '\\0';\n            InputData++;\n\n            /* Remove leading and trailing spaces from section name */\n            SectionName = RTL::String::TrimString(SectionName);\n\n            /* Find length of the section name */\n            SectionLength = RTL::String::StringLength(SectionName, 0);\n\n            /* Allocate memory for new section */\n            Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section);\n            if(Status == STATUS_EFI_SUCCESS)\n            {\n                /* Allocate more memory for section name */\n                Status = Memory::AllocatePool(sizeof(WCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName);\n            }\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Some memory allocation failed */\n                return Status;\n            }\n\n            /* Initialize new section and convert its name to wide string */\n            RTL::LinkedList::InitializeListHead(&Section->Options);\n            RTL::String::StringToWideString(Section->SectionName, (PCSTR*)&SectionName, SectionLength);\n\n            /* Ensure string is NULL-terminated and add new section to the configuration list */\n            Section->SectionName[SectionLength] = L'\\0';\n            RTL::LinkedList::InsertTailList(Configuration, &Section->Flink);\n        }\n        else\n        {\n            /* Store key */\n            Key = InputData;\n\n            /* Find end of the key */\n            while(*InputData != '=' && *InputData != '\\0' && *InputData != '\\r' && *InputData != '\\n')\n            {\n                /* Advance to the next character */\n                InputData++;\n            }\n\n            /* Check if end of the key is reached */\n            if(*InputData != '=')\n            {\n                /* Key name does not end */\n                return STATUS_EFI_INVALID_PARAMETER;\n            }\n\n            /* Mark end of the key and advance to the next character */\n            *InputData = 0;\n            InputData++;\n\n            /* Skip all leading spaces in the value */\n            while(*InputData == ' ')\n            {\n                /* Advance to the next character */\n                InputData++;\n            }\n\n            /* Store value */\n            Value = InputData;\n\n            /* Find end of the value */\n            while(*InputData != '\\0' && *InputData != '\\r' && *InputData != '\\n')\n            {\n                /* Advance to the next character */\n                InputData++;\n            }\n\n            /* Mark end of the value and advance to the next character */\n            *InputData = 0;\n            InputData++;\n\n            /* Remove leading and trailing spaces from key and value */\n            Key = RTL::String::TrimString(Key);\n            Value = RTL::String::TrimString(Value);\n\n            /* Find length of the key and its value */\n            KeyLength = RTL::String::StringLength(Key, 0);\n            ValueLength = RTL::String::StringLength(Value, 0);\n\n            /* Allocate memory for new option */\n            Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option);\n            if(Status == STATUS_EFI_SUCCESS)\n            {\n                /* Allocate more memory for option name */\n                Status = Memory::AllocatePool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name);\n                if(Status == STATUS_EFI_SUCCESS)\n                {\n                    /* Allocate even more memory for option value */\n                    Status = Memory::AllocatePool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value);\n                }\n            }\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Some memory allocation failed */\n                return Status;\n            }\n\n            /* Remove leading quotes from the value */\n            if(*Value == '\"' || *Value == '\\'')\n            {\n                Value++;\n            }\n\n            /* Remove trailing quotes from the value */\n            if(Value[ValueLength - 2] == '\"' || Value[ValueLength - 2] == '\\'')\n            {\n                Value[ValueLength - 2] = '\\0';\n            }\n\n            /* Convert key and value to wide strings */\n            RTL::String::StringToWideString(Option->Name, (PCSTR*)&Key, RTL::String::StringLength(Key, 0) + 1);\n            RTL::String::StringToWideString(Option->Value, (PCSTR*)&Value, RTL::String::StringLength(Value, 0) + 1);\n\n            /* Ensure strings are NULL-terminated and add new option to the list */\n            Option->Name[KeyLength] = L'\\0';\n            Option->Value[ValueLength] = L'\\0';\n            RTL::LinkedList::InsertTailList(&Section->Options, &Option->Flink);\n        }\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Loads configuration file from the specified directory on the FS0:/ drive.\n *\n * @param ConfigDirectory\n *        Specifies a path to the directory containing the configuration file.\n *\n * @param ConfigFile\n *        Specifies the name of the configuration file.\n *\n * @param ConfigData\n *        Provides a buffer to store the data read from the configuration file.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::ReadConfigFile(IN PCWSTR ConfigDirectory,\n                              IN PCWSTR ConfigFile,\n                              OUT PCHAR *ConfigData)\n{\n    PEFI_FILE_HANDLE DirHandle, FsHandle;\n    EFI_HANDLE DiskHandle;\n    EFI_STATUS Status;\n    SIZE_T FileSize;\n\n    /* Open EFI volume */\n    Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open a volume */\n        return Status;\n    }\n\n    /* Open specified directory, containing the configuration file and close the FS immediately */\n    Status = FsHandle->Open(FsHandle, &DirHandle, (PWCHAR)ConfigDirectory, EFI_FILE_MODE_READ, 0);\n    FsHandle->Close(FsHandle);\n\n    /* Check if directory opened successfully */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open directory */\n        Volume::CloseVolume(&DiskHandle);\n        return Status;\n    }\n\n    /* Read configuration file and close directory */\n    Status = Volume::ReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize);\n    DirHandle->Close(DirHandle);\n\n    /* Close EFI volume */\n    Volume::CloseVolume(&DiskHandle);\n\n    /* Return read status */\n    return Status;\n}\n\n\n/**\n * Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist.\n *\n * @param Options\n *       A pointer to the head of a list of XTBL_CONFIG_ENTRY structures.\n *\n * @param OptionName\n *       A pointer to a wide string that contains the name of the boot option to set.\n *\n * @param OptionValue\n *       A pointer to a wide string that contains the new value for the boot option.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::SetBootOptionValue(IN PLIST_ENTRY Options,\n                                  IN PCWSTR OptionName,\n                                  IN PCWSTR OptionValue)\n{\n    PXTBL_CONFIG_ENTRY ConfigEntry;\n    PLIST_ENTRY ConfigList;\n    ULONG Length;\n    EFI_STATUS Status;\n\n    /* Get the length of the option name we are looking for */\n    Length = RTL::WideString::WideStringLength(OptionName, 0);\n\n    /* Start iterating from the first entry in the options list */\n    ConfigList = Options->Flink;\n    while(ConfigList != Options)\n    {\n        /* Get the container record for the current config entry */\n        ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink);\n\n        /* Compare the current entry's name with the requested option name */\n        if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0)\n        {\n            /* Found the option, get its length */\n            Length = RTL::WideString::WideStringLength(OptionValue, 0);\n\n            /* Reallocate memory for the new value */\n            Status = Memory::FreePool(ConfigEntry->Value);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to free memory, return status code */\n                return Status;\n            }\n\n            /* Allocate new memory for the updated value */\n            Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory allocation failure, print debug message and return status code */\n                Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\\\n\", Status);\n                return Status;\n            }\n\n            /* Copy the value and NULL-terminate the new string */\n            RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));\n            ConfigEntry->Value[Length] = L'\\0';\n            return STATUS_EFI_SUCCESS;\n        }\n\n        /* Move to the next entry in the list */\n        ConfigList = ConfigList->Flink;\n    }\n\n    /* Option not found, allocate memory for the new one */\n    Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, print debug message and return status code */\n        Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\\\n\", Status);\n        return Status;\n    }\n\n    /* Allocate memory for the option name */\n    Length = RTL::WideString::WideStringLength(OptionName, 0);\n    Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, print debug message and return status code */\n        Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\\\n\", Status);\n        Memory::FreePool(ConfigEntry);\n        return Status;\n    }\n\n    /* Copy the option name and NULL-terminate the new string */\n    RTL::Memory::CopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR));\n    ConfigEntry->Name[Length] = L'\\0';\n\n    /* Allocate memory for the option value */\n    Length = RTL::WideString::WideStringLength(OptionValue, 0);\n    Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, print debug message and return status code */\n        Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\\\n\", Status);\n        Memory::FreePool(ConfigEntry->Name);\n        Memory::FreePool(ConfigEntry);\n        return Status;\n    }\n\n    /* Copy the value and NULL-terminate the new string */\n    RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));\n    ConfigEntry->Value[Length] = L'\\0';\n\n    /* Insert the new config entry at the end of the options list */\n    RTL::LinkedList::InsertTailList(Options, &ConfigEntry->Flink);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Updates existing configuration value.\n *\n * @param ConfigName\n *        Specifies the configuration key to update.\n *\n * @param ConfigValue\n *        Specifies the new configuration value.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConfiguration::SetValue(IN PCWSTR ConfigName,\n                        IN PCWSTR ConfigValue)\n{\n    PXTBL_CONFIG_ENTRY ConfigEntry;\n    PLIST_ENTRY ConfigListEntry;\n    EFI_STATUS Status;\n    SIZE_T Length;\n\n    /* Get config entry name length */\n    Length = RTL::WideString::WideStringLength(ConfigName, 0);\n\n    /* Iterate through config entries */\n    ConfigListEntry = Config.Flink;\n    while(ConfigListEntry != &Config)\n    {\n        /* Get config entry */\n        ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink);\n\n        /* Check if requested configuration found */\n        if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0)\n        {\n            /* Check new config value length */\n            Length = RTL::WideString::WideStringLength(ConfigValue, 0);\n\n            /* Reallocate memory for new config value */\n            Status = Memory::FreePool(ConfigEntry->Value);\n            if(Status == STATUS_EFI_SUCCESS)\n            {\n                /* Successfully freed memory, allocate a new pool */\n                Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);\n            }\n\n            /* Check memory reallocation status */\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to reallocate memory */\n                return Status;\n            }\n\n            /* Update config value */\n            RTL::Memory::CopyMemory(ConfigEntry->Value, ConfigValue, Length * sizeof(WCHAR));\n            ConfigEntry->Value[Length] = L'\\0';\n\n            /* Return success */\n            return STATUS_EFI_SUCCESS;\n        }\n\n        /* Move to the next config entry */\n        ConfigListEntry = ConfigListEntry->Flink;\n    }\n\n    /* Config entry not found */\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Adds new XTLDR configuration entries to the global configuration list. Existing entries are not overwritten.\n *\n * @param NewConfig\n *        Supplies a pointer to a linked list containing new configuration entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConfiguration::UpdateConfiguration(IN PLIST_ENTRY NewConfig)\n{\n    PXTBL_CONFIG_ENTRY ConfigEntry;\n    PWCHAR ConfigValue;\n    PLIST_ENTRY ConfigListEntry, NextListEntry;\n\n    /* Iterate through new config entries */\n    ConfigListEntry = NewConfig->Flink;\n    while(ConfigListEntry != NewConfig)\n    {\n        /* Get new config entry */\n        ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink);\n\n        /* Get next config entry */\n        NextListEntry = ConfigListEntry->Flink;\n\n        /* Make sure config entry does not exist yet */\n        GetValue(ConfigEntry->Name, &ConfigValue);\n        if(ConfigValue == NULLPTR)\n        {\n            /* Remove new config entry from input list and put it into global config list */\n            RTL::LinkedList::RemoveEntryList(&ConfigEntry->Flink);\n            RTL::LinkedList::InsertTailList(&Config, &ConfigEntry->Flink);\n        }\n\n        /* Move to the next new config entry */\n        ConfigListEntry = NextListEntry;\n    }\n}\n"
  },
  {
    "path": "boot/xtldr/console.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/console.cc\n * DESCRIPTION:     EFI console support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Clears a specified line on the UEFI text console.\n *\n * @param LineNo\n *        Supplies a line number to clear.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::ClearLine(IN ULONGLONG LineNo)\n{\n    UINT_PTR Index, ResX, ResY;\n\n    /* Query console mode */\n    QueryMode(&ResX, &ResY);\n\n    /* Set cursor position and clear line */\n    SetCursorPosition(0, LineNo);\n    for(Index = 0; Index < ResX; Index++)\n    {\n        /* Clear line */\n        Write(L\" \");\n    }\n}\n\n/**\n * This routine clears the UEFI console screen.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::ClearScreen()\n{\n    /* Clear screen */\n    XtLoader::GetEfiSystemTable()->ConOut->ClearScreen(XtLoader::GetEfiSystemTable()->ConOut);\n}\n\n/**\n * Disables the cursor on the UEFI console.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::DisableCursor()\n{\n    XtLoader::GetEfiSystemTable()->ConOut->EnableCursor(XtLoader::GetEfiSystemTable()->ConOut, FALSE);\n}\n\n/**\n * Enables the cursor on the UEFI console.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::EnableCursor()\n{\n    XtLoader::GetEfiSystemTable()->ConOut->EnableCursor(XtLoader::GetEfiSystemTable()->ConOut, TRUE);\n}\n\n/**\n * This routine initializes the EFI console.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::InitializeConsole()\n{\n    /* Clear console buffers */\n    XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, TRUE);\n    XtLoader::GetEfiSystemTable()->ConOut->Reset(XtLoader::GetEfiSystemTable()->ConOut, TRUE);\n    XtLoader::GetEfiSystemTable()->StdErr->Reset(XtLoader::GetEfiSystemTable()->StdErr, TRUE);\n\n    /* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might\n     * set different mode that do not fit on the screen, causing a text to be displayed offscreen */\n    if(XtLoader::GetEfiSystemTable()->ConOut->Mode->Mode != 0)\n    {\n        /* Set console mode to 0, which is standard, 80x25 text mode */\n        SetMode(0);\n    }\n\n    /* Clear screen and enable cursor */\n    SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n    ClearScreen();\n    EnableCursor();\n}\n\n/**\n * This routine formats the input string and prints it out to the stdout and serial console.\n *\n * @param Format\n *        The formatted string that is to be written to the output.\n *\n * @param ...\n *        Depending on the format string, this routine might expect a sequence of additional arguments.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::Print(IN PCWSTR Format,\n               IN ...)\n{\n    RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;\n    VA_LIST Arguments;\n\n    /* Initialise the print contexts */\n    ConsolePrintContext.WriteWideCharacter = PutChar;\n    SerialPrintContext.WriteWideCharacter = Debug::PutChar;\n\n    /* Initialise the va_list */\n    VA_START(Arguments, Format);\n\n    /* Format and print the string to the stdout */\n    RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);\n\n    /* Print to serial console only if not running under OVMF */\n    if(RTL::WideString::CompareWideString(XtLoader::GetEfiSystemTable()->FirmwareVendor, L\"EDK II\", 6) != 0)\n    {\n        /* Check if debugging enabled and if EFI serial port is fully initialized */\n        if(DEBUG && Debug::SerialPortReady())\n        {\n            /* Format and print the string to the serial console */\n            RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);\n        }\n    }\n\n    /* Clean up the va_list */\n    VA_END(Arguments);\n}\n\n/**\n * Writes a character to the default EFI console.\n *\n * @param Character\n *        The integer promotion of the character to be written.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nConsole::PutChar(IN WCHAR Character)\n{\n    WCHAR Buffer[2];\n\n    /* Check if character is a newline ('\\n') */\n    if(Character == L'\\n')\n    {\n        /* Print carriage return ('\\r') as well */\n        PutChar(L'\\r');\n    }\n\n    /* Write character to the screen console */\n    Buffer[0] = Character;\n    Buffer[1] = 0;\n    XtLoader::GetEfiSystemTable()->ConOut->OutputString(XtLoader::GetEfiSystemTable()->ConOut, Buffer);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Queries information concerning the output device’s supported text mode.\n *\n * @param ResX\n *        Supplies a buffer to receive the horizontal resolution.\n *\n * @param ResY\n *        Supplies a buffer to receive the vertical resolution.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::QueryMode(OUT PUINT_PTR ResX,\n                   OUT PUINT_PTR ResY)\n{\n    XtLoader::GetEfiSystemTable()->ConOut->QueryMode(XtLoader::GetEfiSystemTable()->ConOut,\n                                                     XtLoader::GetEfiSystemTable()->ConOut->Mode->Mode, ResX, ResY);\n}\n\n/**\n * Reads a keystroke from the input device.\n *\n * @param Key\n *        Supplies a pointer to the EFI_INPUT_KEY structure that will receive the keystroke.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConsole::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)\n{\n    /* Clear the key structure to prevent ghost keystrokes */\n    Key->ScanCode = 0;\n    Key->UnicodeChar = 0;\n\n    /* Read the keystroke from the EFI input console */\n    return XtLoader::GetEfiSystemTable()->ConIn->ReadKeyStroke(XtLoader::GetEfiSystemTable()->ConIn, Key);\n}\n\n/**\n * Resets the console input device and clears its input buffer.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::ResetInputBuffer()\n{\n    XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, FALSE);\n}\n\n/**\n * Sets the foreground and background colors.\n *\n * @param Attribute\n *        Specifies the foreground and background colors (bits 0..3 are fg, and bits 4..6 are bg color).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::SetAttributes(IN ULONGLONG Attributes)\n{\n    XtLoader::GetEfiSystemTable()->ConOut->SetAttribute(XtLoader::GetEfiSystemTable()->ConOut, Attributes);\n}\n\n/**\n * Sets new coordinates of the console cursor position.\n *\n * @param PosX\n *        Specifies the new X coordinate of the cursor.\n *\n * @param PosY\n *        Specifies the new Y coordinate of the cursor.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::SetCursorPosition(IN ULONGLONG PosX,\n                           IN ULONGLONG PosY)\n{\n    XtLoader::GetEfiSystemTable()->ConOut->SetCursorPosition(XtLoader::GetEfiSystemTable()->ConOut, PosX, PosY);\n}\n\n/**\n * Sets the output console device to the requested mode.\n *\n * @param Mode\n *        Supplies a text mode number to set.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nConsole::SetMode(IN ULONGLONG Mode)\n{\n    return XtLoader::GetEfiSystemTable()->ConOut->SetMode(XtLoader::GetEfiSystemTable()->ConOut, Mode);\n}\n\n/**\n * Displays the string on the device at the current cursor location.\n *\n * @param String\n *        The string to be displayed.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nConsole::Write(IN PCWSTR String)\n{\n    XtLoader::GetEfiSystemTable()->ConOut->OutputString(XtLoader::GetEfiSystemTable()->ConOut, (PWSTR)String);\n}\n"
  },
  {
    "path": "boot/xtldr/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/data.cc\n * DESCRIPTION:     XT Boot Loader global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/* Legacy BIOS cursor X position */\nUSHORT BiosUtils::CursorX = 0;\n\n/* Legacy BIOS cursor Y position */\nUSHORT BiosUtils::CursorY = 0;\n\n/* Legacy BIOS screen height */\nCONST USHORT BiosUtils::VgaHeight = 25;\n\n/* Legacy BIOS screen width */\nCONST USHORT BiosUtils::VgaWidth = 80;\n\n/* XT Boot Loader menu list */\nPLIST_ENTRY Configuration::BootMenuList = NULLPTR;\n\n/* XT Boot Loader configuration list */\nLIST_ENTRY Configuration::Config;\n\n/* XT Boot Loader loaded configuration */\nLIST_ENTRY Configuration::ConfigSections;\n\n/* List of user-editable boot options */\nPCWSTR Configuration::EditableConfigOptions[] = {\n    L\"BootModules\", L\"SystemType\", L\"SystemPath\",\n    L\"KernelFile\",  L\"InitrdFile\", L\"HalFile\",\n    L\"Parameters\", NULLPTR\n};\n\n/* XT Boot Loader serial ports list */\nULONG Debug::ComPortList[COMPORT_COUNT] = COMPORT_ADDRESS;\n\n/* A list of enabled debug ports */\nULONG Debug::EnabledDebugPorts;\n\n/* XT Boot Loader serial port handle */\nCPPORT Debug::SerialPort;\n\n/* XT Boot Loader registered boot protocol list */\nLIST_ENTRY Protocol::BootProtocols;\n\n/* XT Boot Loader protocol */\nXTBL_LOADER_PROTOCOL Protocol::LoaderProtocol;\n\n/* XT Boot Loader loaded modules list */\nLIST_ENTRY Protocol::LoadedModules;\n\n/* XT Boot Loader shell exit flag */\nBOOLEAN Shell::ExitRequest;\n\n/* XT Boot Loader shell history buffer */\nWCHAR Shell::History[XTBL_SH_HISTORY_ENTRIES][XTBL_SH_MAX_LINE_LENGTH];\n\n/* XT Boot Loader shell history count */\nULONG Shell::HistoryCount = 0;\n\n/* XT Boot Loader shell history index */\nULONG Shell::HistoryIndex = 0;\n\n/* XT Boot Loader shell commands list */\nLIST_ENTRY Shell::ShellCommands;\n\n/* List of available block devices */\nLIST_ENTRY Volume::EfiBlockDevices;\n\n/* Pointer to the boot menu callback routine */\nPBL_XT_BOOT_MENU XtLoader::BootMenu = NULLPTR;\n\n/* EFI Image Handle */\nEFI_HANDLE XtLoader::EfiImageHandle;\n\n/* EFI System Table */\nPEFI_SYSTEM_TABLE XtLoader::EfiSystemTable;\n\n/* XT Boot Loader status data */\nXTBL_STATUS XtLoader::LoaderStatus = {0};\n"
  },
  {
    "path": "boot/xtldr/debug.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/debug.cc\n * DESCRIPTION:     XT Boot Loader debugging support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Enables I/O space access to all serial controllers found on the PCI(E) root bridge.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nDebug::ActivateSerialIOController()\n{\n    EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;\n    PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev;\n    USHORT Bus, Device, Function, Command;\n    UINT_PTR Index, PciHandleSize;\n    PEFI_HANDLE PciHandle = NULLPTR;\n    PCI_COMMON_HEADER PciHeader;\n    EFI_STATUS Status;\n    ULONGLONG Address;\n\n    /* Allocate memory for single EFI_HANDLE, what should be enough in most cases */\n    PciHandleSize = sizeof(EFI_HANDLE);\n    Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        return Status;\n    }\n\n    /* Get all instances of PciRootBridgeIo */\n    Status = XtLoader::GetEfiSystemTable()->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR,\n                                                                       &PciHandleSize, PciHandle);\n    if(Status == STATUS_EFI_BUFFER_TOO_SMALL)\n    {\n        /* Reallocate more memory as requested by UEFI */\n        Memory::FreePool(PciHandle);\n        Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory reallocation failure */\n            return Status;\n        }\n\n        /* Second attempt to get instances of PciRootBridgeIo */\n        Status = XtLoader::GetEfiSystemTable()->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR,\n                                                                           &PciHandleSize, PciHandle);\n    }\n\n    /* Make sure successfully obtained PciRootBridgeIo instances */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get PciRootBridgeIo instances */\n        return Status;\n    }\n\n    /* Enumerate all devices for each handle, which decides a segment and a bus number range */\n    for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++)\n    {\n        /* Get inferface from the protocol */\n        Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to get interface */\n            return Status;\n        }\n\n        /* Enumerate whole PCI bridge */\n        for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++)\n        {\n            /* Enumerate all devices for each bus */\n            for(Device = 0; Device < PCI_MAX_DEVICES; Device++)\n            {\n                /* Enumerate all functions for each devices */\n                for(Function = 0; Function < PCI_MAX_FUNCTION; Function++)\n                {\n                    /* Read configuration space */\n                    Address = ((ULONGLONG)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) +\n                                           (((UINT_PTR) Function) << 8) + ((UINT_PTR) 0)));\n                    PciDev->Pci.Read(PciDev, EfiPciIoWidthUint32, Address, sizeof (PciHeader) / sizeof (UINT), &PciHeader);\n\n                    /* Check if device exists */\n                    if(PciHeader.VendorId == PCI_INVALID_VENDORID)\n                    {\n                        /* Skip non-existen device */\n                        continue;\n                    }\n\n                    /* Check if device is serial controller or multiport serial controller */\n                    if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02))\n                    {\n                        /* Enable I/O space access */\n                        Address |= 0x4;\n                        Command = PCI_ENABLE_IO_SPACE;\n                        Status = PciDev->Pci.Write(PciDev, EfiPciIoWidthUint16, Address, 1, &Command);\n                    }\n                }\n            }\n        }\n    }\n\n    /* Return SUCCESS */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine initializes the XTLDR debug console.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nDebug::InitializeDebugConsole()\n{\n    ULONG PortAddress, PortNumber, BaudRate;\n    PWCHAR DebugConfiguration, DebugPort, LastPort;\n    EFI_STATUS Status;\n\n    /* Set default serial port options */\n    PortAddress = 0;\n    PortNumber = 0;\n    BaudRate = 0;\n\n    /* Get debug configuration */\n    Configuration::GetValue(L\"DEBUG\", &DebugConfiguration);\n\n    /* Make sure any debug options are provided and debug console is not initialized yet */\n    if(DebugConfiguration && EnabledDebugPorts == 0)\n    {\n        /* Find all debug ports */\n        DebugPort = RTL::WideString::TokenizeWideString(DebugConfiguration, L\";\", &LastPort);\n\n        /* Iterate over all debug ports */\n        while(DebugPort != NULLPTR)\n        {\n            /* Check what port is set for debugging */\n            if(RTL::WideString::CompareWideStringInsensitive(DebugPort, L\"COM\", 3) == 0)\n            {\n                /* Read COM port number */\n                DebugPort += 3;\n                while(*DebugPort >= '0' && *DebugPort <= '9')\n                {\n                    /* Get port number */\n                    PortNumber *= 10;\n                    PortNumber += *DebugPort - '0';\n                    DebugPort++;\n                }\n\n                /* Check if custom COM port address supplied */\n                if(PortNumber == 0 && RTL::WideString::CompareWideStringInsensitive(DebugPort, L\":0x\", 3) == 0)\n                {\n                    /* COM port address provided */\n                    DebugPort += 3;\n                    while((*DebugPort >= '0' && *DebugPort <= '9') ||\n                          (*DebugPort >= 'A' && *DebugPort <= 'F') ||\n                          (*DebugPort >= 'a' && *DebugPort <= 'f'))\n                    {\n                        /* Get port address */\n                        PortAddress *= 16;\n                        if(*DebugPort >= '0' && *DebugPort <= '9')\n                        {\n                            PortAddress += *DebugPort - '0';\n                        }\n                        else if(*DebugPort >= 'A' && *DebugPort <= 'F')\n                        {\n                            PortAddress += *DebugPort - 'A' + 10;\n                        }\n                        else if(*DebugPort >= 'a' && *DebugPort <= 'f')\n                        {\n                            PortAddress += *DebugPort - 'a' + 10;\n                        }\n                        DebugPort++;\n                    }\n                }\n\n                /* Look for additional COM port parameters */\n                if(*DebugPort == ',')\n                {\n                    /* Baud rate provided */\n                    DebugPort++;\n                    while(*DebugPort >= '0' && *DebugPort <= '9')\n                    {\n                        /* Get baud rate */\n                        BaudRate *= 10;\n                        BaudRate += *DebugPort - '0';\n                        DebugPort++;\n                    }\n                }\n\n                /* Enable debug port */\n                EnabledDebugPorts |= XTBL_DEBUGPORT_SERIAL;\n            }\n            else if(RTL::WideString::CompareWideStringInsensitive(DebugPort, L\"SCREEN\", 5) == 0)\n            {\n                /* Enable debug port */\n                EnabledDebugPorts |= XTBL_DEBUGPORT_SCREEN;\n            }\n            else\n            {\n                /* Unsupported debug port specified */\n                Console::Print(L\"ERROR: Unsupported debug port ('%S') specified\\n\", DebugPort);\n                EfiUtils::SleepExecution(3000);\n            }\n\n            /* Take next debug port */\n            DebugPort = RTL::WideString::TokenizeWideString(NULLPTR, L\";\", &LastPort);\n        }\n\n        /* Check if serial debug port is enabled */\n        if(EnabledDebugPorts & XTBL_DEBUGPORT_SERIAL)\n        {\n            /* Try to initialize COM port */\n            Status = InitializeSerialPort(PortNumber, PortAddress, BaudRate);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Remove serial debug port, as COM port initialization failed and return */\n                EnabledDebugPorts &= ~XTBL_DEBUGPORT_SERIAL;\n                return Status;\n            }\n        }\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine initializes the serial debug console.\n *\n * @param PortNumber\n *        Supplies a port number.\n *\n * @param PortAddress\n *        Supplies an address of the COM port.\n *\n * @param BaudRate\n *        Supplies an optional port baud rate.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nDebug::InitializeSerialPort(IN ULONG PortNumber,\n                            IN ULONG PortAddress,\n                            IN ULONG BaudRate)\n{\n    EFI_STATUS EfiStatus;\n    XTSTATUS Status;\n\n    /* Check if custom COM port address supplied */\n    if(!PortAddress)\n    {\n        /* We support only a pre-defined number of ports */\n        if(PortNumber > COMPORT_COUNT)\n        {\n            /* Fail if wrong/unsupported port used */\n            return STATUS_INVALID_PARAMETER;\n        }\n\n        /* Check if serial port is set */\n        if(PortNumber == 0)\n        {\n            /* Use COM1 by default */\n            PortNumber = 1;\n        }\n\n        /* Set custom port address based on the port number and print debug message */\n        PortAddress = ComPortList[PortNumber - 1];\n        Console::Print(L\"Initializing serial console at port COM%d\\n\", PortNumber);\n    }\n    else\n    {\n        /* Custom port address supplied, print debug message */\n        Console::Print(L\"Initializing serial console at COM port address: 0x%lX\\n\", PortAddress);\n    }\n\n    /* Initialize COM port */\n    Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate);\n\n    /* Port not found under supplied address */\n    if(Status == STATUS_NOT_FOUND && PortAddress)\n    {\n        /* This might be PCI(E) serial controller, try to activate I/O space access first */\n        EfiStatus = ActivateSerialIOController();\n        if(EfiStatus == STATUS_EFI_SUCCESS)\n        {\n            /* Try to reinitialize COM port */\n            Console::Print(L\"Enabled I/O space access for all PCI(E) serial controllers found\\n\");\n            Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate);\n        }\n    }\n\n    /* Check COM port initialization status code */\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Serial port initialization failed, mark as not ready */\n        return STATUS_EFI_NOT_READY;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine formats the input string and prints it out to the debug ports.\n *\n * @param Format\n *        The formatted string that is to be written to the output.\n *\n * @param ...\n *        Depending on the format string, this routine might expect a sequence of additional arguments.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nDebug::Print(IN PCWSTR Format,\n             IN ...)\n{\n    RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;\n    VA_LIST Arguments;\n\n    /* Check if debugging enabled and if EFI serial port is fully initialized */\n    if(DEBUG)\n    {\n        /* Initialize the print contexts */\n        ConsolePrintContext.WriteWideCharacter = Console::PutChar;\n        SerialPrintContext.WriteWideCharacter = PutChar;\n\n        /* Initialise the va_list */\n        VA_START(Arguments, Format);\n\n        /* Check if serial debug port is enabled */\n        if((EnabledDebugPorts & XTBL_DEBUGPORT_SERIAL) && (SerialPort.Flags & COMPORT_FLAG_INIT))\n        {\n            /* Format and print the string to the serial console */\n            RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);\n        }\n\n        /* Check if screen debug port is enabled and Boot Services are still available */\n        if((EnabledDebugPorts & XTBL_DEBUGPORT_SCREEN) && (XtLoader::GetBootServicesStatus() == TRUE))\n        {\n            /* Format and print the string to the screen */\n            RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);\n        }\n\n        /* Clean up the va_list */\n        VA_END(Arguments);\n    }\n}\n\n/**\n * Writes a character to the serial console.\n *\n * @param Character\n *        The integer promotion of the character to be written.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nDebug::PutChar(IN WCHAR Character)\n{\n    WCHAR Buffer[2];\n\n    /* Write character to the serial console */\n    Buffer[0] = Character;\n    Buffer[1] = 0;\n    return HL::ComPort::WriteComPort(&SerialPort, Buffer[0]);\n}\n\n/**\n * Determines if the serial port has been successfully initialized and is ready for communication.\n *\n * @return This routine returns TRUE if the serial port is initialized and ready, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nDebug::SerialPortReady()\n{\n    return (SerialPort.Flags & COMPORT_FLAG_INIT);\n}\n"
  },
  {
    "path": "boot/xtldr/efiutils.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/efiutils.cc\n * DESCRIPTION:     EFI related routines for XT Boot Loader\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Reboots into UEFI firmware setup interface.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::EnterFirmwareSetup()\n{\n    EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID;\n    PULONGLONG SetupSupport = NULLPTR;\n    ULONGLONG Indications;\n    EFI_STATUS Status;\n\n    /* Check if booting into firmware interface is supported */\n    Status = GetEfiVariable(&Guid, L\"OsIndicationsSupported\", (PVOID*)&SetupSupport);\n    if(Status != STATUS_EFI_SUCCESS || !(*SetupSupport & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))\n    {\n        /* Reboot into firmware setup is not supported */\n        Debug::Print(L\"WARNING: Reboot into firmware setup interface not supported\\n\");\n        if(SetupSupport)\n        {\n            Memory::FreePool((PVOID)SetupSupport);\n        }\n        return STATUS_EFI_UNSUPPORTED;\n    }\n\n    Memory::FreePool((PVOID)SetupSupport);\n\n    /* Get the value of OsIndications variable */\n    Indications = 0;\n    Status = GetEfiVariable(&Guid, L\"OsIndications\", (PVOID*)&Indications);\n\n    /* Enable FW setup on next boot */\n    Indications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;\n    Status = SetEfiVariable(&Guid, L\"OsIndications\", (PVOID)&Indications, sizeof(Indications));\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to update OsIndications variable */\n        return Status;\n    }\n\n    /* Reboot into firmware setup */\n    RebootSystem();\n\n    /* Must not reach this point, just make the compiler happy */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Exits EFI boot services.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::ExitBootServices()\n{\n    PEFI_MEMORY_MAP MemoryMap;\n    EFI_STATUS Status;\n    ULONG Counter;\n\n    /* Boot Services might be partially shutdown, so mark them as unavailable */\n    XtLoader::DisableBootServices();\n\n    /* Allocate buffer for EFI memory map */\n    Status = Memory::AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Zero fill the buffer and initialize counter */\n    RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));\n    Counter = 0xFF;\n\n    /* Attempt to exit boot services */\n    while(Counter > 0)\n    {\n        /* Get memory map each time as it can change between two calls */\n        Status = Memory::GetMemoryMap(MemoryMap);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to get new memory map */\n            return Status;\n        }\n\n        /* Exit boot services */\n        Status = XtLoader::GetEfiSystemTable()->BootServices->ExitBootServices(XtLoader::GetEfiImageHandle(),\n                                                                               MemoryMap->MapKey);\n        if(Status == STATUS_EFI_SUCCESS)\n        {\n            break;\n        }\n\n        /* Decrement counter */\n        Counter--;\n    }\n\n    /* Return EFI status code */\n    return Status;\n}\n\n/**\n * Gets the address of a reqested system configuration table.\n *\n * @param TableGuid\n *        Supplies a GUID of the configuration table.\n *\n * @param Table\n *        Supplies a pointer to the memory area where the table address will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::GetConfigurationTable(IN PEFI_GUID TableGuid,\n                                OUT PVOID *Table)\n{\n    SIZE_T Index;\n\n    /* Iterate through all system configuration tables */\n    for(Index = 0; Index < XtLoader::GetEfiSystemTable()->NumberOfTableEntries; Index++)\n    {\n        /* Check if this table matches requested table */\n        if(RTL::Guid::CompareGuids((PGUID)&(XtLoader::GetEfiSystemTable()->ConfigurationTable[Index].VendorGuid),\n                                   (PGUID)TableGuid))\n        {\n            /* Found requested table, return success */\n            *Table = XtLoader::GetEfiSystemTable()->ConfigurationTable[Index].VendorTable;\n            return STATUS_EFI_SUCCESS;\n        }\n    }\n\n    /* Table not found */\n    *Table = NULLPTR;\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Gets the value of the EFI variable.\n *\n * @param Vendor\n *        Supplies a pointer to the unique vendor GUID.\n *\n * @param VariableName\n *        Supplies a pointer to tge NULL-terminated string containing the variable name.\n *\n * @param VariableValue\n *        Supplies a pointer to the buffer, where the variable value will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::GetEfiVariable(IN PEFI_GUID Vendor,\n                         IN PCWSTR VariableName,\n                         OUT PVOID *VariableValue)\n{\n    EFI_STATUS Status;\n    PVOID Buffer;\n    UINT_PTR Size = 0;\n\n    /* Allocate a buffer for storing a variable's value */\n    Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR);\n    Status = Memory::AllocatePool(Size, (PVOID*)&Buffer);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        return Status;\n    }\n\n    /* Attempt to get variable value */\n    Status = XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)VariableName, Vendor, NULLPTR,\n                                                                         &Size, Buffer);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get variable, probably not found such one */\n        return Status;\n    }\n\n    /* Get variable value and return success */\n    *VariableValue = Buffer;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Returns a random value based on the initialized RNG buffer.\n *\n * @param RNGBuffer\n *        Supplies a pointer to the RNG buffer.\n *\n * @return This routine returns a random value.\n *\n * @since XT 1.0\n *\n * @see https://en.wikipedia.org/wiki/Xorshift\n */\nXTCDECL\nULONGLONG\nEfiUtils::GetRandomValue(IN OUT PULONGLONG RNGBuffer)\n{\n    /* Recalculate RNG buffer with XORSHIFT */\n    *RNGBuffer ^= *RNGBuffer >> 12;\n    *RNGBuffer ^= *RNGBuffer << 25;\n    *RNGBuffer ^= *RNGBuffer >> 27;\n\n    /* Return random value */\n    return *RNGBuffer * 0x2545F4914F6CDD1D;\n}\n\n/**\n * Checks whether SecureBoot is enabled or not.\n *\n * @return Numeric representation of SecureBoot status (0 = Disabled, >0 = Enabled, <0 SetupMode).\n *\n * @since XT 1.0\n */\nXTCDECL\nINT_PTR\nEfiUtils::GetSecureBootStatus()\n{\n    EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID;\n    INT_PTR SecureBootStatus = 0;\n    INT_PTR VarValue = 0;\n    UINT_PTR Size;\n\n    Size = sizeof(INT_PTR);\n    if(XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)L\"SecureBoot\", &VarGuid,\n       NULLPTR, &Size, &VarValue) == STATUS_EFI_SUCCESS)\n    {\n        SecureBootStatus = VarValue;\n        Size = sizeof(INT_PTR);\n        if((XtLoader::GetEfiSystemTable()->RuntimeServices->GetVariable((PWCHAR)L\"SetupMode\", &VarGuid,\n           NULLPTR, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0)\n        {\n            SecureBootStatus = -1;\n        }\n    }\n\n    /* Return SecureBoot status */\n    return SecureBootStatus;\n}\n\n/**\n * Initializes the RNG buffer with random bytes from the default EFI RNG algorithm.\n *\n * @param RNGBuffer\n *        Supplies a pointer to the RNG buffer.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::InitializeEntropy(PULONGLONG RNGBuffer)\n{\n    EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID;\n    PEFI_RNG_PROTOCOL Rng;\n    EFI_STATUS Status;\n    ULONGLONG Seed;\n\n    /* Initialize variables */\n    Rng = NULLPTR;\n    Seed = 0;\n\n    /* Locate RNG protocol */\n    Status = XtLoader::GetEfiSystemTable()->BootServices->LocateProtocol(&RngGuid, NULLPTR, (PVOID *)&Rng);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to locate RNG protocol, return status code */\n        return Status;\n    }\n\n    /* Get RNG value using the default algorithm */\n    Status = Rng->GetRNG(Rng, NULLPTR, 8, (PUCHAR)&Seed);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get RNG value, return status code */\n        return Status;\n    }\n\n    /* Initialize RNG state and return success */\n    *RNGBuffer = Seed ? Seed : 1;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Loads an EFI image into memory.\n *\n * @param DevicePath\n *        Specifies a device path from which the image is loaded.\n *\n * @param ImageData\n *        Supplies a pointer to the memory are containing a copy of the EFI image.\n *\n * @param ImageSize\n *        Supplies the size (in bytes) of the EFI image.\n *\n * @param ImageHandle\n *        Supplies a pointer to the memory area, where an EFI_image handle will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,\n                       IN PVOID ImageData,\n                       IN SIZE_T ImageSize,\n                       OUT PEFI_HANDLE ImageHandle)\n{\n    /* Load EFI image */\n    return XtLoader::GetEfiSystemTable()->BootServices->LoadImage(FALSE, XtLoader::GetEfiImageHandle(), DevicePath,\n                                                                  ImageData, ImageSize, ImageHandle);\n}\n\n/**\n * Reboots the machine.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::RebootSystem()\n{\n    /* Reboot machine */\n    return XtLoader::GetEfiSystemTable()->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULLPTR);\n}\n\n/**\n * Sets a value of an EFI variable.\n *\n * @param Vendor\n *        Supplies a pointer to the unique vendor GUID.\n *\n * @param VariableName\n *        Supplies a pointer to tge NULL-terminated string containing the variable name.\n *\n * @param VariableValue\n *        Supplies the contents of the variable.\n *\n * @param Size\n *        Supplies the size of the variable data buffer.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::SetEfiVariable(IN PEFI_GUID Vendor,\n                         IN PCWSTR VariableName,\n                         IN PVOID VariableValue,\n                         IN UINT_PTR Size)\n{\n    ULONG Attributes;\n\n    /* Set EFI variable */\n    Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\n    return XtLoader::GetEfiSystemTable()->RuntimeServices->SetVariable((PWCHAR)VariableName, Vendor, Attributes,\n                                                                       Size, VariableValue);\n}\n\n/**\n * Shuts down the machine.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::ShutdownSystem()\n{\n    /* Shutdown machine */\n    return XtLoader::GetEfiSystemTable()->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULLPTR);\n}\n\n/**\n * Puts the system to sleep for the specified number of milliseconds.\n *\n * @param Milliseconds\n *        Supplies the number of milliseconds to sleep.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nEfiUtils::SleepExecution(IN ULONG_PTR Milliseconds)\n{\n    XtLoader::GetEfiSystemTable()->BootServices->Stall(Milliseconds * 1000);\n}\n\n/**\n * Executes a loaded EFI image entry point.\n *\n * @param ImageHandle\n *        Provides a handle of loaded image, that will be started.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::StartEfiImage(IN EFI_HANDLE ImageHandle)\n{\n    return XtLoader::GetEfiSystemTable()->BootServices->StartImage(ImageHandle, NULLPTR, NULLPTR);\n}\n\n/**\n * Waits for one or more EFI events.\n *\n * @param NumberOfEvents\n *        Supplies the number of events to wait for.\n *\n * @param Event\n *        Supplies the array of events to wait for.\n *\n * @param Index\n *        Receives the index of the event that was signaled.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nEfiUtils::WaitForEfiEvent(IN UINT_PTR NumberOfEvents,\n                          IN PEFI_EVENT Event,\n                          OUT PUINT_PTR Index)\n{\n    return XtLoader::GetEfiSystemTable()->BootServices->WaitForEvent(NumberOfEvents, Event, Index);\n}\n"
  },
  {
    "path": "boot/xtldr/includes/libxtos.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/includes/libxtos.hh\n * DESCRIPTION:     XT Loader to LIBXTOS interface\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTLDR_LIBXTOS_HH\n#define __XTLDR_LIBXTOS_HH\n\n#include <xtblapi.h>\n\n\n/* Minimal forward references for AR classes used by XTLDR */\nnamespace AR\n{\n    class CpuFunctions\n    {\n        public:\n            STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);\n            STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);\n            STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);\n            STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,\n                                                     IN UINT_PTR Value);\n    };\n\n    class ProcessorSupport\n    {\n        public:\n            STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,\n                                                       OUT PVOID *TrampolineCode,\n                                                       OUT PULONG_PTR TrampolineSize);\n    };\n}\n\n/* Minimal forward references for HL classes used by XTLDR */\nnamespace HL\n{\n    class ComPort\n    {\n        public:\n            STATIC XTCDECL XTSTATUS InitializeComPort(IN OUT PCPPORT Port,\n                                                      IN PUCHAR PortAddress,\n                                                      IN ULONG BaudRate);\n            STATIC XTCDECL XTSTATUS WriteComPort(IN PCPPORT Port,\n                                                 IN UCHAR Byte);\n    };\n\n    class IoPort\n    {\n        public:\n            STATIC XTCDECL UCHAR ReadPort8(IN USHORT Port);\n            STATIC XTCDECL USHORT ReadPort16(IN USHORT Port);\n            STATIC XTCDECL ULONG ReadPort32(IN USHORT Port);\n            STATIC XTCDECL VOID WritePort8(IN USHORT Port,\n                                           IN UCHAR Value);\n            STATIC XTCDECL VOID WritePort16(IN USHORT Port,\n                                            IN USHORT Value);\n            STATIC XTCDECL VOID WritePort32(IN USHORT Port,\n                                            IN ULONG Value);\n    };\n}\n\n/* Minimal forward references for RTL classes used by XTLDR */\nnamespace RTL\n{\n    class Guid\n    {\n        public:\n            STATIC XTAPI BOOLEAN CompareGuids(IN PGUID Guid1,\n                                              IN PGUID Guid2);\n    };\n\n    class LinkedList\n    {\n        public:\n            STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);\n            STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,\n                                               IN PLIST_ENTRY Entry);\n            STATIC XTCDECL VOID InsertTailList(IN OUT PLIST_ENTRY ListHead,\n                                               IN PLIST_ENTRY Entry);\n            STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);\n    };\n\n    class Memory\n    {\n        public:\n            STATIC XTAPI SIZE_T CompareMemory(IN PCVOID LeftBuffer,\n                                              IN PCVOID RightBuffer,\n                                              IN SIZE_T Length);\n            STATIC XTAPI VOID CopyMemory(OUT PVOID Destination,\n                                         IN PCVOID Source,\n                                         IN SIZE_T Length);\n            STATIC XTAPI VOID MoveMemory(OUT PVOID Destination,\n                                         IN PCVOID Source,\n                                         IN SIZE_T Length);\n            STATIC XTAPI VOID SetMemory(OUT PVOID Destination,\n                                        IN UCHAR Byte,\n                                        IN SIZE_T Length);\n            STATIC XTAPI VOID ZeroMemory(OUT PVOID Destination,\n                                         IN SIZE_T Length);\n    };\n\n    class String\n    {\n        public:\n            STATIC XTAPI SIZE_T CompareString(IN PCSTR String1,\n                                              IN PCSTR String2,\n                                              IN SIZE_T Length);\n            STATIC XTAPI SIZE_T StringLength(IN PCSTR String,\n                                             IN SIZE_T MaxLength);\n            STATIC XTAPI SIZE_T StringToWideString(OUT PWCHAR Destination,\n                                                   IN PCSTR *Source,\n                                                   IN SIZE_T Length);\n            STATIC XTAPI PCHAR TrimString(IN PCHAR String);\n    };\n\n    class WideString\n    {\n        public:\n            STATIC XTAPI SIZE_T CompareWideString(IN PCWSTR String1,\n                                                  IN PCWSTR String2,\n                                                  IN SIZE_T Length);\n            STATIC XTAPI SIZE_T CompareWideStringInsensitive(IN PCWSTR String1,\n                                                             IN PCWSTR String2,\n                                                             IN SIZE_T Length);\n            STATIC XTAPI PWCHAR ConcatenateWideString(OUT PWCHAR Destination,\n                                                      IN PWCHAR Source,\n                                                      IN SIZE_T Count);\n            STATIC XTAPI XTSTATUS FormatWideString(IN PRTL_PRINT_CONTEXT Context,\n                                                   IN PCWSTR Format,\n                                                   IN VA_LIST ArgumentList);\n            STATIC XTAPI PWCHAR TokenizeWideString(IN PWCHAR String,\n                                                   IN PCWSTR Delimiter,\n                                                   IN OUT PWCHAR *SavePtr);\n            STATIC XTAPI SIZE_T WideStringLength(IN PCWSTR String,\n                                                 IN SIZE_T MaxLength);\n    };\n}\n\n#endif /* __XTLDR_LIBXTOS_HH */\n"
  },
  {
    "path": "boot/xtldr/includes/xtldr.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/includes/xtldr.hh\n * DESCRIPTION:     Top level header for XTLDR\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTLDR_XTLDR_HH\n#define __XTLDR_XTLDR_HH\n\n#include <xtblapi.h>\n#include <xtver.h>\n\n#include <libxtos.hh>\n\n\nclass BiosUtils\n{\n    private:\n        STATIC USHORT CursorX;\n        STATIC USHORT CursorY;\n        STATIC CONST USHORT VgaHeight;\n        STATIC CONST USHORT VgaWidth;\n\n    public:\n        STATIC XTCDECL VOID ClearScreen();\n        STATIC XTCDECL VOID Print(IN PCWSTR Format,\n                                  IN ...);\n        STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);\n\n    private:\n        STATIC XTCDECL VOID ScrollScreen();\n        STATIC XTCDECL VOID UpdateCursor();\n};\n\nclass BootUtils\n{\n    public:\n        STATIC XTCDECL BOOLEAN GetBooleanParameter(IN PCWSTR Parameters,\n                                                   IN PCWSTR Needle);\n};\n\nclass Configuration\n{\n    private:\n        STATIC PLIST_ENTRY BootMenuList;\n        STATIC LIST_ENTRY Config;\n        STATIC LIST_ENTRY ConfigSections;\n        STATIC PCWSTR EditableConfigOptions[];\n\n    public:\n        STATIC XTCDECL BOOLEAN GetBooleanValue(IN PCWSTR ConfigName);\n        STATIC XTCDECL EFI_STATUS GetBootOptionValue(IN PLIST_ENTRY Options,\n                                                     IN PCWSTR OptionName,\n                                                     OUT PWCHAR *OptionValue);\n        STATIC XTCDECL VOID GetEditableOptions(OUT PCWSTR **OptionsArray,\n                                               OUT PULONG OptionsCount);\n        STATIC XTCDECL EFI_STATUS GetValue(IN PCWSTR ConfigName,\n                                           OUT PWCHAR *ConfigValue);\n        STATIC XTCDECL EFI_STATUS InitializeBootMenuList(IN ULONG MaxNameLength,\n                                                         OUT PXTBL_BOOTMENU_ITEM *MenuEntries,\n                                                         OUT PULONG EntriesCount,\n                                                         OUT PULONG DefaultId);\n        STATIC XTCDECL VOID InitializeConfiguration();\n        STATIC XTCDECL EFI_STATUS LoadConfiguration();\n        STATIC XTCDECL EFI_STATUS ParseCommandLine();\n        STATIC XTCDECL EFI_STATUS SetBootOptionValue(IN PLIST_ENTRY Options,\n                                                     IN PCWSTR OptionName,\n                                                     IN PCWSTR OptionValue);\n\n    private:\n        STATIC XTCDECL EFI_STATUS ParseConfigFile(IN CONST PCHAR RawConfig,\n                                                  OUT PLIST_ENTRY Configuration);\n        STATIC XTCDECL EFI_STATUS ReadConfigFile(IN PCWSTR ConfigDirectory,\n                                                 IN PCWSTR ConfigFile,\n                                                 OUT PCHAR *ConfigData);\n        STATIC XTCDECL EFI_STATUS SetValue(IN PCWSTR ConfigName,\n                                           IN PCWSTR ConfigValue);\n        STATIC XTCDECL VOID UpdateConfiguration(IN PLIST_ENTRY NewConfig);\n};\n\nclass Console\n{\n    public:\n        STATIC XTCDECL VOID ClearLine(IN ULONGLONG LineNo);\n        STATIC XTCDECL VOID ClearScreen();\n        STATIC XTCDECL VOID DisableCursor();\n        STATIC XTCDECL VOID EnableCursor();\n        STATIC XTCDECL VOID InitializeConsole();\n        STATIC XTCDECL VOID Print(IN PCWSTR Format,\n                                  IN ...);\n        STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);\n        STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX,\n                                      OUT PUINT_PTR ResY);\n        STATIC XTCDECL EFI_STATUS ReadKeyStroke(OUT PEFI_INPUT_KEY Key);\n        STATIC XTCDECL VOID ResetInputBuffer();\n        STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes);\n        STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX,\n                                              IN ULONGLONG PosY);\n        STATIC XTCDECL VOID Write(IN PCWSTR String);\n\n    private:\n        STATIC XTCDECL EFI_STATUS SetMode(IN ULONGLONG Mode);\n};\n\nclass Debug\n{\n    private:\n        STATIC ULONG ComPortList[COMPORT_COUNT];\n        STATIC ULONG EnabledDebugPorts;\n        STATIC CPPORT SerialPort;\n\n    public:\n            STATIC XTCDECL EFI_STATUS InitializeDebugConsole();\n            STATIC XTCDECL VOID Print(IN PCWSTR Format,\n                                      IN ...);\n            STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);\n            STATIC XTCDECL BOOLEAN SerialPortReady();\n\n    private:\n        STATIC XTCDECL EFI_STATUS ActivateSerialIOController();\n        STATIC XTCDECL EFI_STATUS InitializeSerialPort(IN ULONG PortNumber,\n                                                       IN ULONG PortAddress,\n                                                       IN ULONG BaudRate);\n};\n\nclass EfiUtils\n{\n    public:\n        STATIC XTCDECL EFI_STATUS EnterFirmwareSetup();\n        STATIC XTCDECL EFI_STATUS ExitBootServices();\n        STATIC XTCDECL EFI_STATUS GetConfigurationTable(IN PEFI_GUID TableGuid,\n                                                       OUT PVOID *Table);\n        STATIC XTCDECL EFI_STATUS GetEfiVariable(IN PEFI_GUID Vendor,\n                                                 IN PCWSTR VariableName,\n                                                 OUT PVOID *VariableValue);\n        STATIC XTCDECL ULONGLONG GetRandomValue(IN OUT PULONGLONG RNGBuffer);\n        STATIC XTCDECL INT_PTR GetSecureBootStatus();\n        STATIC XTCDECL EFI_STATUS InitializeEntropy(PULONGLONG RNGBuffer);\n        STATIC XTCDECL EFI_STATUS LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,\n                                               IN PVOID ImageData,\n                                               IN SIZE_T ImageSize,\n                                               OUT PEFI_HANDLE ImageHandle);\n        STATIC XTCDECL EFI_STATUS RebootSystem();\n        STATIC XTCDECL EFI_STATUS SetEfiVariable(IN PEFI_GUID Vendor,\n                                                 IN PCWSTR VariableName,\n                                                 IN PVOID VariableValue,\n                                                 IN UINT_PTR Size);\n        STATIC XTCDECL EFI_STATUS ShutdownSystem();\n        STATIC XTCDECL VOID SleepExecution(IN ULONG_PTR Milliseconds);\n        STATIC XTCDECL EFI_STATUS StartEfiImage(IN EFI_HANDLE ImageHandle);\n        STATIC XTCDECL EFI_STATUS WaitForEfiEvent(IN UINT_PTR NumberOfEvents,\n                                                  IN PEFI_EVENT Event,\n                                                  OUT PUINT_PTR Index);\n};\n\nclass Memory\n{\n    public:\n        STATIC XTCDECL EFI_STATUS AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType,\n                                                IN ULONGLONG NumberOfPages,\n                                                OUT PEFI_PHYSICAL_ADDRESS Memory);\n        STATIC XTCDECL EFI_STATUS AllocatePool(IN UINT_PTR Size,\n                                               OUT PVOID *Memory);\n        STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,\n                                               IN ULONG_PTR SelfMapAddress);\n        STATIC XTCDECL EFI_STATUS CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap);\n        STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,\n                                            IN EFI_PHYSICAL_ADDRESS Memory);\n        STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);\n        STATIC XTCDECL VOID GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,\n                                             OUT PULONG NumberOfMappings);\n        STATIC XTCDECL EFI_STATUS GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap);\n        STATIC XTCDECL PVOID GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,\n                                               IN PVOID PhysicalAddress);\n        STATIC XTCDECL VOID InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,\n                                              IN SHORT PageMapLevel,\n                                              IN PAGE_SIZE PageSize);\n        STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,\n                                               IN OUT PVOID *BaseAddress,\n                                               IN BOOLEAN IdentityMapping,\n                                               IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);\n        STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,\n                                          IN ULONGLONG VirtualAddress,\n                                          IN ULONGLONG PhysicalAddress,\n                                          IN ULONGLONG NumberOfPages);\n        STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,\n                                                   IN ULONGLONG VirtualAddress,\n                                                   IN ULONGLONG PhysicalAddress,\n                                                   IN ULONGLONG NumberOfPages,\n                                                   IN LOADER_MEMORY_TYPE MemoryType);\n        STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,\n                                                      IN PVOID PhysicalBase,\n                                                      IN PVOID VirtualBase);\n        STATIC XTCDECL EFI_STATUS PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,\n                                                        IN OUT PLIST_ENTRY ListHead,\n                                                        IN PVOID PhysicalBase,\n                                                        IN PVOID VirtualBase);\n\n    private:\n        STATIC XTCDECL LOADER_MEMORY_TYPE GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);\n        STATIC XTCDECL EFI_STATUS GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,\n                                                   IN PVOID PageTable,\n                                                   IN SIZE_T Entry,\n                                                   OUT PVOID *NextPageTable);\n        STATIC XTCDECL EFI_STATUS SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,\n                                             IN ULONG_PTR SelfMapAddress);\n};\n\nclass Protocol\n{\n    private:\n        STATIC LIST_ENTRY BootProtocols;\n        STATIC XTBL_LOADER_PROTOCOL LoaderProtocol;\n        STATIC LIST_ENTRY LoadedModules;\n\n    public:\n        STATIC XTCDECL EFI_STATUS CloseProtocol(IN PEFI_HANDLE Handle,\n                                                IN PEFI_GUID ProtocolGuid);\n        STATIC XTCDECL EFI_STATUS FindBootProtocol(IN PCWSTR SystemType,\n                                                   OUT PEFI_GUID BootProtocolGuid);\n        STATIC XTCDECL PLIST_ENTRY GetModulesList();\n        STATIC XTCDECL EFI_STATUS InstallProtocol(IN PVOID Interface,\n                                                 IN PEFI_GUID Guid);\n        STATIC XTCDECL VOID InitializeProtocol();\n        STATIC XTCDECL EFI_STATUS InvokeBootProtocol(IN PWCHAR ShortName,\n                                                     IN PLIST_ENTRY OptionsList);\n        STATIC XTCDECL EFI_STATUS LoadModule(IN PWCHAR ModuleName);\n        STATIC XTCDECL EFI_STATUS LoadModules(IN PWCHAR ModulesList);\n        STATIC XTCDECL EFI_STATUS LocateProtocolHandles(OUT PEFI_HANDLE *Handles,\n                                                        OUT PUINT_PTR Count,\n                                                        IN PEFI_GUID ProtocolGuid);\n        STATIC XTCDECL EFI_STATUS OpenProtocol(OUT PEFI_HANDLE Handle,\n                                               OUT PVOID *ProtocolHandler,\n                                               IN PEFI_GUID ProtocolGuid);\n        STATIC XTCDECL EFI_STATUS OpenProtocolHandle(IN EFI_HANDLE Handle,\n                                                     OUT PVOID *ProtocolHandler,\n                                                     IN PEFI_GUID ProtocolGuid);\n        STATIC XTCDECL EFI_STATUS RegisterBootProtocol(IN PCWSTR SystemType,\n                                                       IN PEFI_GUID BootProtocolGuid);\n        STATIC XTCDECL EFI_STATUS InstallXtLoaderProtocol();\n\n    private:\n        STATIC XTCDECL EFI_STATUS GetModuleInformation(IN PWCHAR SectionData,\n                                                       IN ULONG SectionSize,\n                                                       OUT PXTBL_MODULE_INFO ModuleInfo);\n        STATIC XTCDECL EFI_STATUS GetModuleInfoStrings(IN PWCHAR SectionData,\n                                                       IN ULONG SectionSize,\n                                                       OUT PWCHAR **ModInfo,\n                                                       OUT PULONG InfoCount);\n};\n\nclass Shell\n{\n    private:\n        STATIC BOOLEAN ExitRequest;\n        STATIC WCHAR History[XTBL_SH_HISTORY_ENTRIES][XTBL_SH_MAX_LINE_LENGTH];\n        STATIC ULONG HistoryCount;\n        STATIC ULONG HistoryIndex;\n        STATIC LIST_ENTRY ShellCommands;\n\n    public:\n        STATIC XTCDECL EFI_STATUS RegisterCommand(IN PCWSTR Command,\n                                                  IN PCWSTR Description,\n                                                  IN PBL_SHELL_COMMAND Handler);\n        STATIC XTCDECL VOID StartLoaderShell();\n\n    private:\n        STATIC XTCDECL VOID CommandExit(IN ULONG Argc,\n                                        IN PWCHAR *Argv);\n        STATIC XTCDECL VOID CommandHelp(IN ULONG Argc,\n                                        IN PWCHAR *Argv);\n        STATIC XTCDECL VOID CommandInsmod(IN ULONG Argc,\n                                          IN PWCHAR *Argv);\n        STATIC XTCDECL VOID CommandLsmod(IN ULONG Argc,\n                                         IN PWCHAR *Argv);\n        STATIC XTCDECL VOID CommandPoweroff(IN ULONG Argc,\n                                            IN PWCHAR *Argv);\n        STATIC XTCDECL VOID CommandReboot(IN ULONG Argc,\n                                          IN PWCHAR *Argv);\n        STATIC XTCDECL VOID CommandVersion(IN ULONG Argc,\n                                           IN PWCHAR *Argv);\n        STATIC XTCDECL VOID ExecuteCommand(IN ULONG Argc,\n                                           IN PWCHAR *Argv);\n        STATIC XTCDECL EFI_STATUS ParseCommand(IN PWCHAR CommandLine,\n                                               OUT PULONG Argc,\n                                               OUT PWCHAR **Argv);\n        STATIC XTCDECL VOID PrintPrompt();\n        STATIC XTCDECL VOID PrintPromptLine(IN PWCHAR Buffer,\n                                            IN ULONG BufferLength,\n                                            IN ULONG CursorPosition,\n                                            IN ULONG PreviousBufferLength);\n        STATIC XTCDECL VOID ReadCommand(OUT PWCHAR Buffer,\n                                        IN ULONG BufferSize);\n        STATIC XTCDECL VOID RegisterBuiltinCommands();\n};\n\nclass TextUi\n{\n    public:\n        STATIC XTCDECL VOID DisplayBootMenu();\n        STATIC XTCDECL VOID DisplayErrorDialog(IN PCWSTR Caption,\n                                               IN PCWSTR Message);\n        STATIC XTCDECL VOID DisplayInfoDialog(IN PCWSTR Caption,\n                                              IN PCWSTR Message);\n        STATIC XTCDECL VOID DisplayInputDialog(IN PCWSTR Caption,\n                                               IN PCWSTR Message,\n                                               IN OUT PWCHAR *InputFieldText);\n        STATIC XTCDECL XTBL_DIALOG_HANDLE DisplayProgressDialog(IN PCWSTR Caption,\n                                                                IN PCWSTR Message,\n                                                                IN UCHAR Percentage);\n        STATIC XTCDECL VOID UpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle,\n                                              IN PCWSTR Message,\n                                              IN UCHAR Percentage);\n\n    private:\n        STATIC XTCDECL VOID DetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle,\n                                                   IN PCWSTR Message);\n        STATIC XTCDECL VOID DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry);\n        STATIC XTCDECL VOID DrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle);\n        STATIC XTCDECL VOID DrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,\n                                              IN PWCHAR MenuEntry,\n                                              IN UINT Position,\n                                              IN BOOLEAN Highlighted);\n        STATIC XTCDECL VOID DrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle,\n                                          IN PCWSTR Caption,\n                                          IN PCWSTR Message);\n        STATIC XTCDECL VOID DrawButton(IN PXTBL_DIALOG_HANDLE Handle);\n        STATIC XTCDECL VOID DrawInputField(IN PXTBL_DIALOG_HANDLE Handle,\n                                           IN PWCHAR InputFieldText);\n        STATIC XTCDECL VOID DrawMessage(IN PXTBL_DIALOG_HANDLE Handle,\n                                        IN PCWSTR Message);\n        STATIC XTCDECL VOID DrawProgressBar(IN PXTBL_DIALOG_HANDLE Handle,\n                                            IN UCHAR Percentage);\n        STATIC XTCDECL VOID DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle);\n        STATIC XTCDECL EFI_STATUS DrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,\n                                                    IN PCWSTR OptionName,\n                                                    IN PCWSTR OptionValue,\n                                                    IN UINT Position,\n                                                    IN BOOLEAN Highlighted);\n};\n\nclass Volume\n{\n    private:\n        STATIC LIST_ENTRY EfiBlockDevices;\n\n    public:\n        STATIC XTCDECL EFI_STATUS CloseVolume(IN PEFI_HANDLE VolumeHandle);\n        STATIC XTCDECL EFI_STATUS EnumerateBlockDevices();\n        STATIC XTCDECL EFI_STATUS FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,\n                                                       IN CONST PWCHAR FileSystemPath,\n                                                       OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath);\n        STATIC XTCDECL EFI_STATUS GetEfiPath(IN PWCHAR SystemPath,\n                                             OUT PWCHAR *EfiPath);\n        STATIC XTCDECL EFI_STATUS GetDevicePath(IN PWCHAR SystemPath,\n                                                OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,\n                                                OUT PWCHAR *ArcName,\n                                                OUT PWCHAR *Path);\n        STATIC XTCDECL EFI_STATUS OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,\n                                             OUT PEFI_HANDLE DiskHandle,\n                                             OUT PEFI_FILE_HANDLE *FsHandle);\n        STATIC XTCDECL EFI_STATUS ReadFile(IN PEFI_FILE_HANDLE DirHandle,\n                                           IN PCWSTR FileName,\n                                           OUT PVOID *FileData,\n                                           OUT PSIZE_T FileSize);\n\n\n    private:\n        STATIC XTCDECL EFI_STATUS DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices);\n        STATIC XTCDECL EFI_STATUS DissectArcPath(IN PWCHAR SystemPath,\n                                                 OUT PWCHAR *ArcName,\n                                                 OUT PWCHAR *Path,\n                                                 OUT PUSHORT DriveType,\n                                                 OUT PULONG DriveNumber,\n                                                 OUT PULONG PartNumber);\n        STATIC XTCDECL PEFI_DEVICE_PATH_PROTOCOL DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);\n        STATIC XTCDECL EFI_STATUS FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,\n                                                          OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode);\n        STATIC XTCDECL BOOLEAN FindParentBlockDevice(IN PLIST_ENTRY BlockDevices,\n                                                     IN PEFI_BLOCK_DEVICE_DATA ChildNode,\n                                                     OUT PEFI_BLOCK_DEVICE_DATA *ParentNode);\n};\n\nclass XtLoader\n{\n    private:\n        STATIC PBL_XT_BOOT_MENU BootMenu;\n        STATIC EFI_HANDLE EfiImageHandle;\n        STATIC PEFI_SYSTEM_TABLE EfiSystemTable;\n        STATIC XTBL_STATUS LoaderStatus;\n\n    public:\n        STATIC XTCDECL VOID DisableBootServices();\n        STATIC XTCDECL BOOLEAN GetBootServicesStatus();\n        STATIC XTCDECL EFI_HANDLE GetEfiImageHandle();\n        STATIC XTCDECL PEFI_SYSTEM_TABLE GetEfiSystemTable();\n        STATIC XTCDECL VOID GetLoaderImageInformation(PVOID *LoaderBase,\n                                                      PULONGLONG LoaderSize);\n        STATIC XTCDECL INT_PTR GetSecureBootStatus();\n        STATIC XTCDECL VOID InitializeBootLoader(IN EFI_HANDLE ImageHandle,\n                                                 IN PEFI_SYSTEM_TABLE SystemTable);\n        STATIC XTCDECL VOID RegisterBootMenu(IN PVOID BootMenuRoutine);\n        STATIC XTCDECL VOID ShowBootMenu();\n};\n\n#endif /* __XTLDR_XTLDR_HH */\n"
  },
  {
    "path": "boot/xtldr/library/modproto.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/library/modproto.cc\n * DESCRIPTION:     XT Boot Loader protocol support for XTLDR modules\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Finds and opens the XT Boot Loader protocol. This routine should be called by module to access XTLDR protocol.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param ProtocolHandler\n *        Receives the pointer to the XT Boot Loader protocol.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nEFI_STATUS\nBlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,\n                   IN EFI_HANDLE ImageHandle,\n                   OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler)\n{\n    EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID;\n    PEFI_HANDLE Handles = NULLPTR;\n    EFI_STATUS Status;\n    UINT_PTR Count;\n    UINT Index;\n\n    /* Try to locate the handles */\n    Status = SystemTable->BootServices->LocateHandleBuffer(ByProtocol, &ProtocolGuid, NULLPTR, &Count, &Handles);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Unable to get handles */\n        return Status;\n    }\n\n    /* Check if any handles returned */\n    if(Count > 0)\n    {\n        /* Iterate through all given handles */\n        for(Index = 0; Index < Count; Index++)\n        {\n            /* Try to open protocol */\n            Status = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid,\n                                                             (PVOID*)ProtocolHandler, ImageHandle, NULLPTR,\n                                                             EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);\n\n            /* Check if successfully opened the loader protocol */\n            if(Status == STATUS_EFI_SUCCESS)\n            {\n                /* Protocol found and successfully opened */\n                break;\n            }\n        }\n    }\n\n    /* Free handles */\n    SystemTable->BootServices->FreePool(Handles);\n\n    /* Make sure the loaded protocol has been found */\n    if(*ProtocolHandler == NULLPTR)\n    {\n        /* Protocol not found */\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n"
  },
  {
    "path": "boot/xtldr/memory.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/memory.cc\n * DESCRIPTION:     XT Boot Loader memory management\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * This routine allocates one or more 4KB pages.\n *\n * @param NumberOfPages\n *        The number of contiguous 4KB pages to allocate.\n *\n * @param Memory\n *        The pointer to a physical address.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType,\n                      IN ULONGLONG NumberOfPages,\n                      OUT PEFI_PHYSICAL_ADDRESS Memory)\n{\n    return XtLoader::GetEfiSystemTable()->BootServices->AllocatePages(AllocationType, EfiLoaderData,\n                                                                      NumberOfPages, Memory);\n}\n\n/**\n * This routine allocates a pool memory.\n *\n * @param Size\n *        The number of bytes to allocate from the pool.\n *\n * @param Memory\n *        The pointer to a physical address.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::AllocatePool(IN UINT_PTR Size,\n                     OUT PVOID *Memory)\n{\n    /* Allocate pool */\n    return XtLoader::GetEfiSystemTable()->BootServices->AllocatePool(EfiLoaderData, Size, Memory);\n}\n\n/**\n * This routine frees memory pages.\n *\n * @param NumberOfPages\n *        The number of contiguous 4 KB pages to free.\n *\n * @param Memory\n *        The base physical address of the pages to be freed.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::FreePages(IN ULONGLONG NumberOfPages,\n                  IN EFI_PHYSICAL_ADDRESS Memory)\n{\n    return XtLoader::GetEfiSystemTable()->BootServices->FreePages(Memory, NumberOfPages);\n}\n\n/**\n * Returns pool memory to the system.\n *\n * @param Memory\n *        The pointer to the buffer to free.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::FreePool(IN PVOID Memory)\n{\n    /* Free pool */\n    return XtLoader::GetEfiSystemTable()->BootServices->FreePool(Memory);\n}\n\n/**\n * Converts EFI memory type to XTLDR memory type.\n *\n * @param EfiMemoryType\n *        Specifies EFI memory type.\n *\n * @return This routine returns a mapped XTLDR memory type.\n *\n * @since XT 1.0\n */\nXTCDECL\nLOADER_MEMORY_TYPE\nMemory::GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)\n{\n    LOADER_MEMORY_TYPE MemoryType;\n\n    /* Check EFI memory type and convert to XTLDR memory type */\n    switch(EfiMemoryType)\n    {\n        case EfiACPIMemoryNVS:\n        case EfiACPIReclaimMemory:\n        case EfiPalCode:\n        case EfiReservedMemoryType:\n            MemoryType = LoaderSpecialMemory;\n            break;\n        case EfiRuntimeServicesCode:\n        case EfiRuntimeServicesData:\n        case EfiMemoryMappedIO:\n        case EfiMemoryMappedIOPortSpace:\n            MemoryType = LoaderFirmwarePermanent;\n            break;\n        case EfiBootServicesData:\n        case EfiLoaderCode:\n        case EfiLoaderData:\n            MemoryType = LoaderFirmwareTemporary;\n            break;\n        case EfiUnusableMemory:\n            MemoryType = LoaderBad;\n            break;\n        default:\n            MemoryType = LoaderFree;\n            break;\n    }\n\n    /* Return XTLDR memory type */\n    return MemoryType;\n}\n\n/**\n * Returns the number of mappings in the page mapping structure.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param NumberOfMappings\n *        Supplies a pointer to memory area where the number of mappings is returned.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nMemory::GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,\n                         OUT PULONG NumberOfMappings)\n{\n    /* Return number of mappings */\n    *NumberOfMappings = PageMap->MapSize;\n}\n\n/**\n * Returns the memory descriptors which define a memory map of all the physical memory ranges reserved by the UEFI.\n *\n * @param MemoryMap\n *        Supplies a pointer to the buffer where memory map will be written.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)\n{\n    EFI_STATUS Status;\n\n    if(MemoryMap == NULLPTR)\n    {\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    MemoryMap->Map = NULLPTR;\n    MemoryMap->MapSize = 0;\n\n    /* Get memory map */\n    do\n    {\n        /* Attempt do get EFI memory map */\n        Status = XtLoader::GetEfiSystemTable()->BootServices->GetMemoryMap(&MemoryMap->MapSize,\n                                                                           MemoryMap->Map,\n                                                                           &MemoryMap->MapKey,\n                                                                           &MemoryMap->DescriptorSize,\n                                                                           &MemoryMap->DescriptorVersion);\n        if(Status == STATUS_EFI_SUCCESS)\n        {\n            /* Go further if succeeded */\n            break;\n        }\n        else if(Status != STATUS_EFI_BUFFER_TOO_SMALL)\n        {\n            /* Some error occurred */\n            if(MemoryMap->Map)\n            {\n                /* Free allocated memory */\n                FreePool(MemoryMap->Map);\n            }\n            return Status;\n        }\n\n        /* Allocate the desired amount of memory */\n        MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize;\n        AllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map);\n    }\n    while(Status == STATUS_EFI_BUFFER_TOO_SMALL);\n\n    /* Make sure memory map is set */\n    if(MemoryMap->Map == NULLPTR)\n    {\n        /* Something went wrong */\n        return STATUS_EFI_NO_MAPPING;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Attempts to find a virtual address of the specified physical address in memory mappings.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param PhysicalAddress\n *        Supplies a physical address to search for in the mappings.\n *\n * @return This routine returns a corresponding virtual address found in the mappings.\n *\n * @since XT 1.0\n */\nXTCDECL\nPVOID\nMemory::GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,\n                          IN PVOID PhysicalAddress)\n{\n    PXTBL_MEMORY_MAPPING Mapping;\n    PLIST_ENTRY ListEntry;\n\n    /* Iterate over memory mappings in order to find descriptor containing a physical address */\n    ListEntry = PageMap->MemoryMap.Flink;\n    while(ListEntry != &PageMap->MemoryMap)\n    {\n        /* Get mapping from linked list */\n        Mapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);\n\n        /* Make sure any virtual address is set */\n        if(Mapping->VirtualAddress)\n        {\n            /* Check if provided physical address is in range of this mapping */\n            if(((UINT_PTR)PhysicalAddress >= (UINT_PTR)Mapping->PhysicalAddress) &&\n               ((UINT_PTR)PhysicalAddress < ((UINT_PTR)Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE))))\n            {\n                /* Calculate virtual address based on the mapping and return it */\n                return (PVOID)(((UINT_PTR)PhysicalAddress - (UINT_PTR)Mapping->PhysicalAddress) + (UINT_PTR)Mapping->VirtualAddress);\n            }\n        }\n\n        /* Get next element from the list */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Mapping not found, return 0 */\n    return 0;\n}\n\n/**\n * Initializes the page mapping structures.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param PageMapLevel\n *        Specifies a number of of paging structures levels.\n *\n * @param PageSize\n *        Specifies a page size (currently it has no effect).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nMemory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,\n                          IN SHORT PageMapLevel,\n                          IN PAGE_SIZE PageSize)\n{\n    /* Initialize memory mappings */\n    RTL::LinkedList::InitializeListHead(&PageMap->MemoryMap);\n    PageMap->MapSize = 0;\n\n    /* Set page map size/level and memory map address */\n    PageMap->PageMapLevel = PageMapLevel;\n    PageMap->PageSize = PageSize;\n}\n\n/**\n * Adds EFI memory mapping to the page mapping structure.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param BaseAddress\n *        Supplies a virtual address, where EFI memory will be mapped.\n *\n * @param IdentityMapping\n *        Specifies whether EFI non-free memory should be mapped by identity or sequential mapping.\n *\n * @param GetMemoryTypeRoutine\n *        Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,\n                     IN OUT PVOID *BaseAddress,\n                     IN BOOLEAN IdentityMapping,\n                     IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)\n{\n    ULONGLONG MaxAddress, VirtualAddress;\n    PEFI_MEMORY_DESCRIPTOR Descriptor;\n    LOADER_MEMORY_TYPE MemoryType;\n    PEFI_MEMORY_MAP MemoryMap;\n    SIZE_T DescriptorCount;\n    EFI_STATUS Status;\n    SIZE_T Index;\n\n    /* Set virtual address as specified in argument */\n    VirtualAddress = (ULONGLONG)*BaseAddress;\n\n    /* Check if custom memory type routine is specified */\n    if(GetMemoryTypeRoutine == NULLPTR)\n    {\n        /* Use default memory type routine */\n        GetMemoryTypeRoutine = GetLoaderMemoryType;\n    }\n\n    /* Allocate and zero-fill buffer for EFI memory map */\n    AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);\n    RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));\n\n    /* Get EFI memory map */\n    Status = GetMemoryMap(MemoryMap);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get EFI memory map */\n        return Status;\n    }\n\n    /* Calculate descriptors count and get first one */\n    Descriptor = MemoryMap->Map;\n    DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize;\n\n    /* Iterate through all descriptors from the memory map */\n    for(Index = 0; Index < DescriptorCount; Index++)\n    {\n        /* Check page map level */\n        if(PageMap->PageMapLevel == 2)\n        {\n            /* Limit physical address to 4GB in legacy mode */\n            MaxAddress = 0xFFFFFFFF;\n        }\n        else if(PageMap->PageMapLevel == 3)\n        {\n            /* Limit physical address to 64GB in PAE mode */\n            MaxAddress = 0xFFFFFFFFFULL;\n        }\n\n        /* Check page map level */\n        if(PageMap->PageMapLevel == 2 || PageMap->PageMapLevel == 3)\n        {\n            /* Check if physical address starts beyond limit */\n            if(Descriptor->PhysicalStart >= MaxAddress)\n            {\n                /* Go to the next descriptor */\n                Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);\n                continue;\n            }\n\n            /* Check if memory descriptor exceeds the lowest physical page */\n            if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MaxAddress)\n            {\n                /* Truncate memory descriptor to the lowest supported physical page */\n                Descriptor->NumberOfPages = (MaxAddress - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;\n            }\n        }\n\n        {\n            /* Skip EFI reserved memory */\n            if(Descriptor->Type == EfiReservedMemoryType)\n            {\n                /* Go to the next descriptor */\n                Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);\n                continue;\n            }\n\n            /* Convert EFI memory type into XTLDR memory type */\n            MemoryType = GetMemoryTypeRoutine((EFI_MEMORY_TYPE)Descriptor->Type);\n\n            /* Do memory mappings depending on memory type */\n            if(MemoryType == LoaderFirmwareTemporary)\n            {\n                /* Map EFI firmware code */\n                Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart,\n                                          Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);\n            }\n            else if(MemoryType != LoaderFree)\n            {\n                /* Check mapping strategy */\n                if(IdentityMapping)\n                {\n                    /* Add any non-free memory using identity mapping */\n                    Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart + KSEG0_BASE, Descriptor->PhysicalStart,\n                                              Descriptor->NumberOfPages, MemoryType);\n                }\n                else\n                {\n                    /* Add any non-free memory using sequential mapping */\n                    Status = MapVirtualMemory(PageMap, VirtualAddress, Descriptor->PhysicalStart,\n                                              Descriptor->NumberOfPages, MemoryType);\n\n                    /* Update virtual address */\n                    VirtualAddress = VirtualAddress + (Descriptor->NumberOfPages * MM_PAGE_SIZE);\n                }\n            }\n            else\n            {\n                /* Map all other memory as loader free */\n                Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,\n                                          Descriptor->NumberOfPages, LoaderFree);\n            }\n\n            /* Make sure memory mapping succeeded */\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Mapping failed */\n                return Status;\n            }\n        }\n\n        /* Grab next descriptor */\n        Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);\n    }\n\n    /* Always map first page */\n    Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, 0, 1, LoaderFirmwarePermanent);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Mapping failed */\n        return Status;\n    }\n\n    /* Map BIOS ROM and VRAM */\n    Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, 0xA0000, 0x60, LoaderFirmwarePermanent);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Mapping failed */\n        return Status;\n    }\n\n    /* Store next valid virtual address and return success */\n    *BaseAddress = (PVOID)VirtualAddress;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Adds a physical to virtual address mappings.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param VirtualAddress\n *        Supplies a virtual address where the physical address should be mapped.\n *\n * @param PhysicalAddress\n *        Supplies a physical address which will be mapped.\n *\n * @param NumberOfPages\n *        Supplies a number of pages that will be mapped.\n *\n * @param MemoryType\n *        Supplies the type of mapped memory that will be assigned to the memory descriptor.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,\n                         IN ULONGLONG VirtualAddress,\n                         IN ULONGLONG PhysicalAddress,\n                         IN ULONGLONG NumberOfPages,\n                         IN LOADER_MEMORY_TYPE MemoryType)\n{\n    PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;\n    ULONGLONG PhysicalAddressEnd, PhysicalAddress2End;\n    PLIST_ENTRY ListEntry, MappingListEntry;\n    SIZE_T NumberOfMappedPages;\n    EFI_STATUS Status;\n\n    /* Allocate memory for new mapping */\n    Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID *)&Mapping1);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        return Status;\n    }\n\n    /* Set mapping fields */\n    Mapping1->PhysicalAddress = PhysicalAddress;\n    Mapping1->VirtualAddress = VirtualAddress;\n    Mapping1->NumberOfPages = NumberOfPages;\n    Mapping1->MemoryType = MemoryType;\n\n    /* Calculate the end of the physical address */\n    PhysicalAddressEnd = PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1;\n\n    /* Iterate through all the mappings already set to insert new mapping at the correct place */\n    ListEntry = PageMap->MemoryMap.Flink;\n    while(ListEntry != &PageMap->MemoryMap)\n    {\n        /* Take a mapping from the list and calculate its end of physical address */\n        Mapping2 = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);\n        PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;\n\n        /* Check if new mapping is a subset of an existing mapping */\n        if(Mapping1->PhysicalAddress >= Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)\n        {\n            /* Make sure it's memory type is the same */\n            if(Mapping1->MemoryType == Mapping2->MemoryType)\n            {\n                /* Free the unused mapping structure and return success */\n                FreePool(Mapping1);\n                return STATUS_EFI_SUCCESS;\n            }\n        }\n\n        /* Check if they overlap */\n        if(PhysicalAddressEnd > Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)\n        {\n            /* Make sure it's memory type is LoaderFree */\n            if(Mapping2->MemoryType != LoaderFree)\n            {\n                /* LoaderFree memory type is strictly expected */\n                return STATUS_EFI_INVALID_PARAMETER;\n            }\n\n            /* Calculate number of pages for this mapping */\n            NumberOfMappedPages = (PhysicalAddress2End - PhysicalAddressEnd) / EFI_PAGE_SIZE;\n            if(NumberOfMappedPages > 0)\n            {\n                /* Pages associated to the mapping, allocate memory for it */\n                Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3);\n                if(Status != STATUS_EFI_SUCCESS)\n                {\n                    /* Memory allocation failure */\n                    return Status;\n                }\n\n                /* Set mapping fields */\n                Mapping3->PhysicalAddress = PhysicalAddressEnd + 1;\n                Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;\n                Mapping3->NumberOfPages = NumberOfMappedPages;\n                Mapping3->MemoryType = Mapping2->MemoryType;\n\n                /* Insert new mapping in front of the list and increase page map size */\n                RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);\n                PageMap->MapSize++;\n            }\n\n            /* Calculate number of pages and the end of the physical address */\n            Mapping2->NumberOfPages = ((PUCHAR)PhysicalAddressEnd + 1 -\n                                       (PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;\n            PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;\n        }\n\n        /* Check if they overlap */\n        if(Mapping1->PhysicalAddress > Mapping2->PhysicalAddress && Mapping1->PhysicalAddress < PhysicalAddress2End)\n        {\n            /* Make sure it's memory type is LoaderFree */\n            if(Mapping2->MemoryType != LoaderFree)\n            {\n                /* LoaderFree memory type is strictly expected */\n                return STATUS_EFI_INVALID_PARAMETER;\n            }\n\n            /* Calculate number of pages for this mapping */\n            NumberOfMappedPages = ((PUCHAR)PhysicalAddress2End + 1 - (PUCHAR)Mapping1->PhysicalAddress) / EFI_PAGE_SIZE;\n            if(NumberOfMappedPages > 0)\n            {\n                /* Pages associated to the mapping, allocate memory for it */\n                Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3);\n                if(Status != STATUS_EFI_SUCCESS)\n                {\n                    /* Memory allocation failure */\n                    return Status;\n                }\n\n                /* Set mapping fields */\n                Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;\n                Mapping3->VirtualAddress = (ULONGLONG)NULLPTR;\n                Mapping3->NumberOfPages = NumberOfMappedPages;\n                Mapping3->MemoryType = Mapping2->MemoryType;\n\n                /* Insert new mapping in front of the list and increase page map size */\n                RTL::LinkedList::InsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);\n                PageMap->MapSize++;\n            }\n\n            /* Calculate number of pages and the end of the physical address */\n            Mapping2->NumberOfPages = ((PUCHAR)Mapping1->PhysicalAddress -\n                                       (PUCHAR)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;\n            PhysicalAddress2End = Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;\n        }\n\n        /* Check if mapping is really needed */\n        if((Mapping2->PhysicalAddress >= Mapping1->PhysicalAddress && PhysicalAddress2End <= PhysicalAddressEnd) ||\n           (Mapping2->NumberOfPages == 0))\n        {\n            /* Make sure it's memory type is LoaderFree */\n            if(Mapping2->MemoryType != LoaderFree)\n            {\n                /* LoaderFree memory type is strictly expected */\n                return STATUS_EFI_INVALID_PARAMETER;\n            }\n\n            /* Store address of the next mapping */\n            MappingListEntry = ListEntry->Flink;\n\n            /* Remove mapping from the list and free up it's memory */\n            RTL::LinkedList::RemoveEntryList(&Mapping2->ListEntry);\n            Status = FreePool(Mapping2);\n            ListEntry = MappingListEntry;\n\n            /* Decrease page map size and go to the next mapping */\n            PageMap->MapSize--;\n            continue;\n        }\n\n        /* Determine physical address order */\n        if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress)\n        {\n            /* Insert new mapping in front of the list and increase page map size */\n            RTL::LinkedList::InsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry);\n            PageMap->MapSize++;\n\n            /* Return success */\n            return STATUS_EFI_SUCCESS;\n        }\n\n        /* Get next mapping from the list */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Insert new mapping to the tail of the list and increase page map size */\n    RTL::LinkedList::InsertTailList(&PageMap->MemoryMap, &Mapping1->ListEntry);\n    PageMap->MapSize++;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Converts physical address to virtual address based on physical base and virtual base.\n *\n * @param PhysicalAddress\n *        Specifies physical address that will be converted to virtual address.\n *\n * @param PhysicalBase\n *        Supplies a physical base address.\n *\n * @param VirtualBase\n *        Supplies a virtual base address.\n *\n * @return This routine returns a mapped virtual address.\n *\n * @since XT 1.0\n */\nXTCDECL\nPVOID\nMemory::PhysicalAddressToVirtual(IN PVOID PhysicalAddress,\n                                 IN PVOID PhysicalBase,\n                                 IN PVOID VirtualBase)\n{\n    /* Convert physical address to virtual address */\n    return (PUCHAR)VirtualBase + ((PUCHAR)PhysicalAddress - (PUCHAR)PhysicalBase);\n}\n\n/**\n * Converts whole linked list addressing from physical to virtual for future use after enabling paging.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that serves as the list header.\n *\n * @param PhysicalBase\n *        Supplies a physical base address.\n *\n * @param VirtualBase\n *        Supplies a virtual base address.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nMemory::PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,\n                              IN OUT PLIST_ENTRY ListHead,\n                              IN PVOID PhysicalBase,\n                              IN PVOID VirtualBase)\n{\n    PLIST_ENTRY ListEntry, NextEntry;\n\n    /* Make sure list is properly initialized */\n    if(ListHead->Flink == 0 || ListHead->Blink == 0)\n    {\n        /* List not initialized, return error code */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Iterate through all elements */\n    ListEntry = ListHead->Flink;\n    while(ListEntry != ListHead)\n    {\n        /* Save physical address of the next element */\n        NextEntry = ListEntry->Flink;\n\n        /* Convert the address of this element to VirtualAddress */\n        if(ListEntry->Blink == ListHead)\n        {\n            /* Find virtual address of list head */\n            ListEntry->Blink = (PLIST_ENTRY)GetVirtualAddress(PageMap, ListEntry->Blink);\n        }\n        else\n        {\n            /* Convert list entry */\n            ListEntry->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase);\n        }\n        if(ListEntry->Flink == ListHead)\n        {\n            /* Convert list head */\n            ListEntry->Flink = ListHead->Flink->Blink;\n        }\n        else\n        {\n            /* Convert list entry */\n            ListEntry->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase);\n        }\n\n        /* Get to the next element*/\n        ListEntry = NextEntry;\n    }\n\n    /* Convert list head */\n    ListHead->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase);\n    ListHead->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n"
  },
  {
    "path": "boot/xtldr/modules/CMakeLists.txt",
    "content": "add_subdirectory(acpi)\nadd_subdirectory(beep)\nadd_subdirectory(chainldr)\nadd_subdirectory(dummy)\nadd_subdirectory(framebuf)\nadd_subdirectory(pecoff)\nadd_subdirectory(xtos_o)\n"
  },
  {
    "path": "boot/xtldr/modules/acpi/CMakeLists.txt",
    "content": "# XT Boot Loader ACPI Support Module\nPROJECT(XTLDR_ACPI)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTLDR_ACPI_SOURCE_DIR}/includes)\n\n# Specify list of source code files\nlist(APPEND XTLDR_ACPI_SOURCE\n    ${XTLDR_ACPI_SOURCE_DIR}/acpi.cc\n    ${XTLDR_ACPI_SOURCE_DIR}/data.cc)\n\n# Link module executable\nadd_executable(acpi ${XTLDR_ACPI_SOURCE})\n\n# Add linker libraries\ntarget_link_libraries(acpi libxtldr libxtos)\n\n# Set proper binary name and install target\nset_target_properties(acpi PROPERTIES SUFFIX .efi)\nset_install_target(acpi efi/boot/xtldr/modules)\n\n# Set module entrypoint and subsystem\nset_entrypoint(acpi \"XtLdrModuleMain\")\nset_linker_map(acpi TRUE)\nset_subsystem(acpi efi_boot_service_driver)\n"
  },
  {
    "path": "boot/xtldr/modules/acpi/acpi.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/acpi/acpi.cc\n * DESCRIPTION:     XTLDR ACPI Support Module\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <acpi.hh>\n\n\n/* ACPI module information */\nMODULE_AUTHOR(L\"Rafal Kupiec <belliash@codingworkshop.eu.org>\");\nMODULE_DESCRIPTION(L\"ACPI support\");\nMODULE_LICENSE(L\"GPLv3\");\nMODULE_VERSION(L\"0.1\");\n\n\n/**\n * Attempts to get XSDP. If it is not found or checksum mismatch, it will try to get RSDP instead.\n *\n * @param AcpiTable\n *        Suplies a pointer to memory area where XSDP or RSRP address will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nAcpi::GetAcpiDescriptionPointer(OUT PVOID *AcpiTable)\n{\n    PVOID Rsdp;\n\n    /* Try to get XSDP (ACPI 2.0) from system configuration tables */\n    if(GetXsdpTable(&Rsdp) == STATUS_EFI_SUCCESS)\n    {\n        /* XSDP found, return success */\n        *AcpiTable = Rsdp;\n        return STATUS_EFI_SUCCESS;\n    }\n\n    /* Try to get RSDP (ACPI 1.0) from system configuration tables */\n    if(GetRsdpTable(&Rsdp) == STATUS_EFI_SUCCESS)\n    {\n        /* RSDP found, return success */\n        *AcpiTable = Rsdp;\n        return STATUS_EFI_SUCCESS;\n    }\n\n    /* Neither XSDP nor RSDP found */\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Finds ACPI description table with given signature.\n *\n * @param Signature\n *        Supplies the signature of the desired ACPI table.\n *\n * @param PreviousTable\n *        Supplies a pointer to the table to start searching from.\n *\n * @param AcpiTable\n *        Supplies a pointer to memory area where ACPI table address will be stored, or NULLPTR if not found.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nAcpi::GetAcpiTable(IN CONST UINT Signature,\n                   IN PVOID PreviousTable,\n                   OUT PVOID *AcpiTable)\n{\n    PACPI_DESCRIPTION_HEADER TableHeader;\n    SIZE_T RsdtIndex, TableIndex;\n    EFI_STATUS Status;\n    SIZE_T TableCount;\n    PACPI_RSDP Rsdp;\n    PACPI_RSDT Rsdt;\n    BOOLEAN Xsdp;\n\n    /* Return NULLPTR by default if requested table not found */\n    *AcpiTable = NULLPTR;\n\n    /* Get Root System Description Table Pointer */\n    Status = GetAcpiDescriptionPointer((PVOID*)&Rsdp);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* ACPI tables not found, return error */\n        return Status;\n    }\n\n    /* Check if it is XSDP (ACPI 2.0) or RSDP (ACPI 1.0) */\n    if(Rsdp->Revision >= 2 && Rsdp->XsdtAddress)\n    {\n        /* XSDP (ACPI 2.0) */\n        Xsdp = TRUE;\n        Rsdt = (PACPI_RSDT)(UINT_PTR)Rsdp->XsdtAddress;\n        TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;\n    }\n    else\n    {\n        /* RSDP (ACPI 1.0) */\n        Xsdp = FALSE;\n        Rsdt = (PACPI_RSDT)(UINT_PTR)Rsdp->RsdtAddress;\n        TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;\n    }\n\n    /* Iterate over all ACPI tables */\n    for(TableIndex = 0; TableIndex < TableCount; TableIndex++)\n    {\n        /* Get table headers in reverse order */\n        RsdtIndex = TableCount - TableIndex - 1;\n\n        /* Check if XSDP or RSDT is used */\n        if(Xsdp)\n        {\n            /* Get table header from XSDT */\n            TableHeader = (PACPI_DESCRIPTION_HEADER)(ULONG_PTR)((PULONGLONG)Rsdt->Tables)[RsdtIndex];\n        }\n        else\n        {\n            /* Get table header from RSDT */\n            TableHeader = (PACPI_DESCRIPTION_HEADER)(ULONG_PTR)((PULONG)Rsdt->Tables)[RsdtIndex];\n        }\n\n        /* Check if previous table provided */\n        if(PreviousTable != NULLPTR)\n        {\n            /* Check if this is a table previously found */\n            if(TableHeader == (PVOID)PreviousTable)\n            {\n                /* Unset previous table */\n                PreviousTable = NULLPTR;\n            }\n\n            /* Skip to next ACPI table */\n            continue;\n        }\n\n        /* Verify table signature */\n        if((TableHeader->Signature == Signature))\n        {\n            /* Found requested ACPI table */\n            break;\n        }\n    }\n\n    /* Make sure table was found */\n    if(TableHeader->Signature != Signature)\n    {\n        /* ACPI table not found, return error */\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* Don't validate FADT on old, broken firmwares with ACPI 2.0 or older */\n    if(TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2)\n    {\n        /* Validate table checksum */\n        if(!ValidateAcpiTable(TableHeader, TableHeader->Length))\n        {\n            /* Checksum mismatch, return error */\n            return STATUS_EFI_CRC_ERROR;\n        }\n    }\n\n    /* Found valid ACPI table, return success */\n    *AcpiTable = TableHeader;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Gets the Advanced Programmable Interrupt Controller (APIC) base address.\n *\n * @param ApicBase\n *        Supplies a pointer to memory area where APIC base address will be stored.\n *\n * @return This routine returns an EFI status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nAcpi::GetApicBase(OUT PVOID *ApicBase)\n{\n    CPUID_REGISTERS CpuRegisters;\n\n    /* Prepare CPUID registers to query for APIC support */\n    XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;\n\n    /* Query CPUID */\n    XtLdrProtocol->Cpu.CpuId(&CpuRegisters);\n\n    /* Check if APIC present */\n    if((CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) == 0)\n    {\n        /* APIC is not supported by the CPU */\n        return STATUS_EFI_UNSUPPORTED;\n    }\n\n    /* Get APIC base address */\n    *ApicBase = (PVOID)((UINT_PTR)XtLdrProtocol->Cpu.ReadModelSpecificRegister(0x1B) & 0xFFFFF000);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Gets RSDP (ACPI 1.0) from EFI system configuration\n *\n * @param AcpiTable\n *        Suplies a pointer to memory area where RSDP address will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nAcpi::GetRsdpTable(OUT PVOID *AcpiTable)\n{\n    EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI_TABLE_GUID;\n    EFI_STATUS Status;\n    PVOID RsdpTable;\n\n    /* Get RSDP (ACPI 1.0) table from system configuration tables */\n    Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &RsdpTable);\n    if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(RsdpTable, 20))\n    {\n        /* RSDP not found or checksum mismatch */\n        *AcpiTable = NULLPTR;\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* RSDP found, return success */\n    *AcpiTable = RsdpTable;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Gets SMBIOS from EFI system configuration\n *\n * @param SmBiosTable\n *        Suplies a pointer to memory area where SMBIOS address will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nAcpi::GetSMBiosTable(OUT PVOID *SmBiosTable)\n{\n    EFI_GUID SmBiosGuid = EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID;\n    PSMBIOS_TABLE_HEADER SmBios;\n    EFI_STATUS Status;\n\n    /* Get SMBIOS table from system configuration tables */\n    Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBiosGuid, (PVOID*)&SmBios);\n    if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length))\n    {\n        /* SMBIOS not found or checksum mismatch */\n        *SmBiosTable = NULLPTR;\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* SMBIOS found, return success */\n    *SmBiosTable = SmBios;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Gets SMBIOS3 from EFI system configuration\n *\n * @param SmBiosTable\n *        Suplies a pointer to memory area where SMBIOS3 address will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nAcpi::GetSMBios3Table(OUT PVOID *SmBiosTable)\n{\n    EFI_GUID SmBios3Guid = EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID;\n    PSMBIOS3_TABLE_HEADER SmBios;\n    EFI_STATUS Status;\n\n    /* Get SMBIOS3 table from system configuration tables */\n    Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBios3Guid, (PVOID*)&SmBios);\n    if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length))\n    {\n        /* SMBIOS3 not found or checksum mismatch */\n        *SmBiosTable = NULLPTR;\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* SMBIOS3 found, return success */\n    *SmBiosTable = SmBios;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Gets XSDP (ACPI 2.0) from EFI system configuration\n *\n * @param AcpiTable\n *        Suplies a pointer to memory area where XSDP address will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nAcpi::GetXsdpTable(OUT PVOID *AcpiTable)\n{\n    EFI_GUID AcpiGuid = EFI_CONFIG_TABLE_ACPI20_TABLE_GUID;\n    EFI_STATUS Status;\n    PVOID XsdpTable;\n\n    /* Get XSDP (ACPI 2.0) from system configuration tables */\n    Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &XsdpTable);\n    if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(XsdpTable, 36))\n    {\n        /* XSDP not found or checksum mismatch */\n        *AcpiTable = NULLPTR;\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* XSDP found, return success */\n    *AcpiTable = XsdpTable;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Initializes ACPI module by opening XTLDR protocol and installing ACPI protocol.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nAcpi::InitializeModule(IN EFI_HANDLE ImageHandle,\n                       IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    EFI_GUID Guid = XT_ACPI_PROTOCOL_GUID;\n    EFI_STATUS Status;\n\n    /* Open the XTLDR protocol */\n    Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open the protocol, return error */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Set routines available via ACPI protocol */\n    AcpiProtocol.GetAcpiDescriptionPointer = GetAcpiDescriptionPointer;\n    AcpiProtocol.GetAcpiTable = GetAcpiTable;\n    AcpiProtocol.GetApicBase = GetApicBase;\n    AcpiProtocol.GetRsdpTable = GetRsdpTable;\n    AcpiProtocol.GetSMBiosTable = GetSMBiosTable;\n    AcpiProtocol.GetSMBios3Table = GetSMBios3Table;\n    AcpiProtocol.GetXsdpTable = GetXsdpTable;\n\n    /* Install ACPI protocol */\n    return XtLdrProtocol->Protocol.Install(&AcpiProtocol, &Guid);\n}\n\n/**\n * Validates given ACPI table by calculating its checksum.\n *\n * @param Buffer\n *        Supplies a pointer to the table to checksum.\n *\n * @param Size\n *        Supplies the size of the table, in bytes.\n *\n * @return This routine returns TRUE if the table is valid, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nAcpi::ValidateAcpiTable(IN PVOID Buffer,\n                        IN UINT_PTR Size)\n{\n    PUCHAR Pointer;\n    UCHAR Sum;\n\n    /* Initialize variables */\n    Sum = 0;\n    Pointer = (PUCHAR)Buffer;\n\n    /* Calculate checksum of given table */\n    while(Size != 0)\n    {\n        Sum = (UCHAR)(Sum + *Pointer);\n        Pointer += 1;\n        Size -= 1;\n    }\n\n    /* Return calculated checksum */\n    return (Sum == 0) ? TRUE : FALSE;\n}\n\n/**\n * This routine is the entry point of the XT EFI boot loader module.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtLdrModuleMain(IN EFI_HANDLE ImageHandle,\n                IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    /* Initialize ACPI module */\n    return Acpi::InitializeModule(ImageHandle, SystemTable);\n}\n"
  },
  {
    "path": "boot/xtldr/modules/acpi/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/acpi/data.cc\n * DESCRIPTION:     ACPI module global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <acpi.hh>\n\n\n/* ACPI Protocol */\nXTBL_ACPI_PROTOCOL Acpi::AcpiProtocol;\n\n/* XTLDR protocol handler */\nPXTBL_LOADER_PROTOCOL Acpi::XtLdrProtocol;\n"
  },
  {
    "path": "boot/xtldr/modules/acpi/includes/acpi.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/acpi/includes/acpi.hh\n * DESCRIPTION:     XTLDR ACPI module header file\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTLDR_ACPI_ACPI_HH\n#define __XTLDR_ACPI_ACPI_HH\n\n#include <xtblapi.h>\n\n\n/* ACPI module for XTLDR */\nclass Acpi\n{\n    private:\n        STATIC XTBL_ACPI_PROTOCOL AcpiProtocol;\n        STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;\n\n    public:\n        STATIC XTCDECL EFI_STATUS GetAcpiDescriptionPointer(OUT PVOID *AcpiTable);\n        STATIC XTCDECL EFI_STATUS GetAcpiTable(IN CONST UINT Signature,\n                                               IN PVOID PreviousTable,\n                                               OUT PVOID *AcpiTable);\n        STATIC XTCDECL EFI_STATUS GetApicBase(OUT PVOID *ApicBase);\n        STATIC XTCDECL EFI_STATUS GetRsdpTable(OUT PVOID *AcpiTable);\n        STATIC XTCDECL EFI_STATUS GetSMBiosTable(OUT PVOID *SmBiosTable);\n        STATIC XTCDECL EFI_STATUS GetSMBios3Table(OUT PVOID *SmBiosTable);\n        STATIC XTCDECL EFI_STATUS GetXsdpTable(OUT PVOID *AcpiTable);\n        STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,\n                                                   IN PEFI_SYSTEM_TABLE SystemTable);\n\n    private:\n        STATIC XTCDECL BOOLEAN ValidateAcpiTable(IN PVOID Buffer,\n                                                 IN UINT_PTR Size);\n};\n\n#endif /* __XTLDR_ACPI_ACPI_HH */\n"
  },
  {
    "path": "boot/xtldr/modules/beep/CMakeLists.txt",
    "content": "# XT Boot Loader Beep Module\nPROJECT(XTLDR_BEEP)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTLDR_BEEP_SOURCE_DIR}/includes)\n\n# Specify list of source code files\nlist(APPEND XTLDR_BEEP_SOURCE\n    ${XTLDR_BEEP_SOURCE_DIR}/beep.cc\n    ${XTLDR_BEEP_SOURCE_DIR}/data.cc)\n\n# Link module executable\nadd_executable(beep ${XTLDR_BEEP_SOURCE})\n\n# Add linker libraries\ntarget_link_libraries(beep libxtldr libxtos)\n\n# Set proper binary name and install target\nset_target_properties(beep PROPERTIES SUFFIX .efi)\nset_install_target(beep efi/boot/xtldr/modules)\n\n# Set module entrypoint and subsystem\nset_entrypoint(beep \"XtLdrModuleMain\")\nset_linker_map(beep TRUE)\nset_subsystem(beep efi_boot_service_driver)\n"
  },
  {
    "path": "boot/xtldr/modules/beep/beep.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/beep/beep.cc\n * DESCRIPTION:     XTLDR Beep Module\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <beep.hh>\n\n\n/* Beep module information */\nMODULE_AUTHOR(L\"Rafal Kupiec <belliash@codingworkshop.eu.org>\");\nMODULE_DESCRIPTION(L\"Plays a GRUB compatible tune via PC speaker\");\nMODULE_LICENSE(L\"GPLv3\");\nMODULE_VERSION(L\"0.1\");\n\n\n/**\n * Disables the PC speaker.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nBeep::DisableToneBeep()\n{\n    UCHAR Status;\n\n    /* Stop the PC speaker */\n    Status = XtLdrProtocol->IoPort.Read8(0x61);\n    XtLdrProtocol->IoPort.Write8(0x61, Status & 0xFC);\n}\n\n/**\n * Enables the PC speaker and plays a sound.\n *\n * @param Pitch\n *        Specifies a pitch (in Hz) of the sound.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nBeep::EnableToneBeep(IN UINT Pitch)\n{\n    UINT Counter;\n    UCHAR Status;\n\n    /* Pitch only in range of 20..20000 */\n    if(Pitch < 20)\n    {\n        Pitch = 20;\n    }\n    else if(Pitch > 20000)\n    {\n        Pitch = 20000;\n    }\n\n    /* Set the desired frequency of the PIT clock */\n    Counter = 0x1234DD / Pitch;\n    XtLdrProtocol->IoPort.Write8(0x43, 0xB6);\n    XtLdrProtocol->IoPort.Write8(0x43, 0xB6);\n    XtLdrProtocol->IoPort.Write8(0x42, (UCHAR) Counter & 0xFF);\n    XtLdrProtocol->IoPort.Write8(0x42, (UCHAR) (Counter >> 8) & 0xFF);\n\n    /* Start the PC speaker */\n    Status = XtLdrProtocol->IoPort.Read8(0x61);\n    XtLdrProtocol->IoPort.Write8(0x61, Status | 0x03);\n}\n\n/**\n * Initializes BEEP module by opening XTLDR protocol and playing the tune.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nBeep::InitializeModule(IN EFI_HANDLE ImageHandle,\n                       IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    EFI_STATUS Status;\n    PWCHAR Tune;\n\n    /* Open the XTLDR protocol */\n    Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open the protocol, return error */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Play the tune set in the configuration */\n    XtLdrProtocol->Config.GetValue(L\"TUNE\", &Tune);\n    PlayTune(Tune);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine plays a tune.\n *\n * @param Arguments\n *        Optional list of parameters provided with the command.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nBeep::PlayTune(IN PWCHAR Arguments)\n{\n    LONG Pitch, Duration, Tempo;\n    PWCHAR Argument, LastArgument;\n\n    /* Reset pitch and duration */\n    Duration = -1;\n    Pitch = -1;\n    Tempo = -1;\n\n    /* Tokenize provided list of arguments */\n    Argument = XtLdrProtocol->WideString.Tokenize(Arguments, L\" \", &LastArgument);\n\n    /* Iterate over all arguments */\n    while(Argument != NULLPTR)\n    {\n        /* Check if tempo, pitch and duration are set */\n        if(Tempo < 0)\n        {\n            /* Set the tempo */\n            Tempo = WideStringToNumber(Argument);\n        }\n        else if(Pitch < 0)\n        {\n            /* Set the pitch */\n            Pitch = WideStringToNumber(Argument);\n        }\n        else\n        {\n            /* Set the duration */\n            Duration = WideStringToNumber(Argument);\n\n            /* Check pitch value */\n            if(Pitch > 0)\n            {\n                /* Emit the beep tone */\n                EnableToneBeep(Pitch);\n            }\n            else\n            {\n                /* Stop emitting beep tone */\n                DisableToneBeep();\n            }\n\n            /* Wait for duration time */\n            XtLdrProtocol->Utils.SleepExecution(60000 * Duration / Tempo);\n\n            /* Reset pitch and duration */\n            Pitch = -1;\n            Duration = -1;\n        }\n\n        /* Get next argument */\n        Argument = XtLdrProtocol->WideString.Tokenize(NULLPTR, L\" \", &LastArgument);\n    }\n\n    /* Stop emitting beep tone */\n    DisableToneBeep();\n}\n\n/**\n * Converts a wide string into a number.\n *\n * @param String\n *        Supplies an input wide string.\n *\n * @return This routine returns the number that was converted from the wide string.\n *\n * @since XT 1.0\n */\nXTCDECL\nUINT\nBeep::WideStringToNumber(IN PWCHAR String)\n{\n    ULONG Number = 0;\n\n    /* Iterate over all characters until '\\0' found */\n    do\n    {\n        /* Check if this is a digit */\n        if(*String - '0' < 10)\n        {\n            /* Add another digit to the number */\n            Number *= 10;\n            Number += *String - '0';\n        }\n    }\n    while(*++String != L'\\0');\n\n    /* Return number */\n    return Number;\n}\n\n/**\n * This routine is the entry point of the XT EFI boot loader module.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtLdrModuleMain(IN EFI_HANDLE ImageHandle,\n                IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    /* Initialize BEEP module */\n    return Beep::InitializeModule(ImageHandle, SystemTable);\n}\n"
  },
  {
    "path": "boot/xtldr/modules/beep/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/beep/data.cc\n * DESCRIPTION:     BEEP module global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <beep.hh>\n\n\n/* XTLDR protocol handler */\nPXTBL_LOADER_PROTOCOL Beep::XtLdrProtocol;\n"
  },
  {
    "path": "boot/xtldr/modules/beep/includes/beep.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/beep/includes/beep.hh\n * DESCRIPTION:     XTLDR Beep Module header file\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTLDR_BEEP_BEEP_HH\n#define __XTLDR_BEEP_BEEP_HH\n\n#include <xtblapi.h>\n\n\n/* BEEP module for XTLDR */\nclass Beep\n{\n    private:\n        STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;\n\n    public:\n        STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,\n                                                   IN PEFI_SYSTEM_TABLE SystemTable);\n        STATIC XTCDECL VOID PlayTune(IN PWCHAR Arguments);\n\n    private:\n        STATIC XTCDECL VOID DisableToneBeep();\n        STATIC XTCDECL VOID EnableToneBeep(IN UINT Pitch);\n        STATIC XTCDECL UINT WideStringToNumber(IN PWCHAR String);\n};\n\n#endif /* __XTLDR_BEEP_BEEP_HH */\n"
  },
  {
    "path": "boot/xtldr/modules/chainldr/CMakeLists.txt",
    "content": "# XTLDR Chain Loader Module\nPROJECT(XTLDR_CHAINLDR)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTLDR_CHAINLDR_SOURCE_DIR}/includes)\n\n# Specify list of source code files\nlist(APPEND XTLDR_CHAINLDR_SOURCE\n    ${XTLDR_CHAINLDR_SOURCE_DIR}/chainldr.cc\n    ${XTLDR_CHAINLDR_SOURCE_DIR}/data.cc)\n\n# Link module executable\nadd_executable(chainldr ${XTLDR_CHAINLDR_SOURCE})\n\n# Add linker libraries\ntarget_link_libraries(chainldr libxtldr libxtos)\n\n# Set proper binary name and install target\nset_target_properties(chainldr PROPERTIES SUFFIX .efi)\nset_install_target(chainldr efi/boot/xtldr/modules)\n\n# Set module entrypoint and subsystem\nset_entrypoint(chainldr \"XtLdrModuleMain\")\nset_linker_map(chainldr TRUE)\nset_subsystem(chainldr efi_boot_service_driver)\n"
  },
  {
    "path": "boot/xtldr/modules/chainldr/chainldr.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/chainldr/chainldr.cc\n * DESCRIPTION:     XTLDR Chain Loader\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <chainldr.hh>\n\n\n/* ChainLoader module information */\nMODULE_AUTHOR(L\"Rafal Kupiec <belliash@codingworkshop.eu.org>\");\nMODULE_DESCRIPTION(L\"XTLDR Chain Loader\");\nMODULE_LICENSE(L\"GPLv3\");\nMODULE_VERSION(L\"0.1\");\n\n\n/**\n * Chainloads another boot loader.\n *\n * @param Parameters\n *        Input parameters with detailed system configuration.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)\n{\n    EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;\n    EFI_MEMMAP_DEVICE_PATH MemoryDevicePath[2];\n    PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;\n    EFI_HANDLE DiskHandle, LoaderHandle;\n    PEFI_FILE_HANDLE FsHandle, BootDir;\n    EFI_STATUS Status;\n    SIZE_T LoaderSize;\n    PVOID LoaderData;\n\n    /* Check if image file is provided */\n    if(Parameters->KernelFile == NULLPTR)\n    {\n        /* No image filename provided, return error code */\n        XtLdrProtocol->Debug.Print(L\"ERROR: No EFI image filename provided\\n\");\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Open EFI volume */\n    Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open a volume, return error code */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Unable to open boot volume (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Open boot directory and close FS handle */\n    Status = FsHandle->Open(FsHandle, &BootDir, Parameters->EfiPath, EFI_FILE_MODE_READ, 0);\n    FsHandle->Close(FsHandle);\n\n    /* Check if system path directory opened successfully */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open directory */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Unable to open system boot directory (Status Code: 0x%zX)\\n\", Status);\n\n        /* Close volume and return error code */\n        XtLdrProtocol->Disk.CloseVolume(&DiskHandle);\n        return Status;\n    }\n\n    /* Read EFI image file from disk and close both directory and EFI volume */\n    Status = XtLdrProtocol->Disk.ReadFile(BootDir, Parameters->KernelFile, &LoaderData, &LoaderSize);\n    BootDir->Close(BootDir);\n    XtLdrProtocol->Disk.CloseVolume(&DiskHandle);\n\n    /* Setup device path for EFI image */\n    MemoryDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);\n    MemoryDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8;\n    MemoryDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH;\n    MemoryDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP;\n    MemoryDevicePath[0].MemoryType = EfiLoaderData;\n    MemoryDevicePath[0].StartingAddress = (UINT_PTR)LoaderData;\n    MemoryDevicePath[0].EndingAddress = (UINT_PTR)LoaderData + LoaderSize;\n    MemoryDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);\n    MemoryDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8;\n    MemoryDevicePath[1].Header.Type = EFI_END_DEVICE_PATH;\n    MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;\n\n    /* Load EFI image */\n    Status = XtLdrProtocol->Utils.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath,\n                                               LoaderData, LoaderSize, &LoaderHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to chainload EFI binary, return error code */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Unable to chainload '%S' (Status Code: 0x%zX)\\n\",\n                                   Parameters->KernelFile, Status);\n        return Status;\n    }\n\n    /* Access loaded image protocol */\n    Status = XtLdrProtocol->Protocol.OpenHandle(LoaderHandle, (PVOID *)&LoadedImage, &LIPGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open EFI_LOADED_IMAGE_PROTOCOL, return error code */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Unable to access binary interface (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Check if parameters provided */\n    if(Parameters->Parameters)\n    {\n        /* Pass arguments to chainloaded image */\n        LoadedImage->LoadOptionsSize = XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) * sizeof(WCHAR);\n        LoadedImage->LoadOptions = Parameters->Parameters;\n    }\n\n    /* Set device handle as LoadImage() is not going to do it */\n    LoadedImage->DeviceHandle = DiskHandle;\n\n    /* Chainload EFI image */\n    return XtLdrProtocol->Utils.StartEfiImage(LoaderHandle);\n}\n\n/**\n * Initializes CHAINLDR module by opening XTLDR protocol and installing CHAINLOADER protocol.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nChainLoader::InitializeModule(IN EFI_HANDLE ImageHandle,\n                              IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    EFI_GUID Guid = XT_CHAIN_BOOT_PROTOCOL_GUID;\n    EFI_STATUS Status;\n\n    /* Open the XTLDR protocol */\n    Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open the protocol, return error */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Set routines available via ChainLoader boot protocol */\n    BootProtocol.BootSystem = BootSystem;\n\n    /* Register XTOS boot protocol */\n    XtLdrProtocol->Boot.RegisterProtocol(L\"CHAINLOADER\", &Guid);\n\n    /* Install XTOS protocol */\n    return XtLdrProtocol->Protocol.Install(&BootProtocol, &Guid);\n}\n\n/**\n * This routine is the entry point of the XT EFI boot loader module.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtLdrModuleMain(IN EFI_HANDLE ImageHandle,\n                IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    /* Initialize CHAINLDR module */\n    return ChainLoader::InitializeModule(ImageHandle, SystemTable);\n}\n"
  },
  {
    "path": "boot/xtldr/modules/chainldr/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/chainldr/data.cc\n * DESCRIPTION:     CHAINLDR module global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <chainldr.hh>\n\n\n/* ChainLoader Boot Protocol */\nXTBL_BOOT_PROTOCOL ChainLoader::BootProtocol;\n\n/* XTLDR protocol handler */\nPXTBL_LOADER_PROTOCOL ChainLoader::XtLdrProtocol;\n"
  },
  {
    "path": "boot/xtldr/modules/chainldr/includes/chainldr.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/chainldr/includes/chainldr.hh\n * DESCRIPTION:     XTLDR Chain Loader header file\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTLDR_CHAINLDR_CHAINLDR_HH\n#define __XTLDR_CHAINLDR_CHAINLDR_HH\n\n#include <xtblapi.h>\n\n\n/* CHAINLDR module for XTLDR */\nclass ChainLoader\n{\n    private:\n        STATIC XTBL_BOOT_PROTOCOL BootProtocol;\n        STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;\n\n    public:\n        STATIC XTCDECL EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);\n        STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,\n                                                   IN PEFI_SYSTEM_TABLE SystemTable);\n};\n\n#endif /* __XTLDR_CHAINLDR_CHAINLDR_HH */\n"
  },
  {
    "path": "boot/xtldr/modules/dummy/CMakeLists.txt",
    "content": "# XT Boot Loader Dummy Module\nPROJECT(XTLDR_DUMMY)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTLDR_DUMMY_SOURCE_DIR}/includes)\n\n# Specify list of source code files\nlist(APPEND XTLDR_DUMMY_SOURCE\n    ${XTLDR_DUMMY_SOURCE_DIR}/dummy.cc\n    ${XTLDR_DUMMY_SOURCE_DIR}/data.cc)\n\n# Link module executable\nadd_executable(dummy ${XTLDR_DUMMY_SOURCE})\n\n# Add linker libraries\ntarget_link_libraries(dummy libxtldr)\n\n# Set proper binary name and install target\nset_target_properties(dummy PROPERTIES SUFFIX .efi)\nset_install_target(dummy efi/boot/xtldr/modules)\n\n# Set module entrypoint and subsystem\nset_entrypoint(dummy \"XtLdrModuleMain\")\nset_linker_map(dummy TRUE)\nset_subsystem(dummy efi_boot_service_driver)\n"
  },
  {
    "path": "boot/xtldr/modules/dummy/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/dummy/data.cc\n * DESCRIPTION:     Dummy XTLDR module global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <dummy.hh>\n\n\n/* Dummy Boot Protocol handler */\nXTBL_BOOT_PROTOCOL Dummy::DummyProtocol;\n\n/* XTLDR protocol handler */\nPXTBL_LOADER_PROTOCOL Dummy::XtLdrProtocol;\n"
  },
  {
    "path": "boot/xtldr/modules/dummy/dummy.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/dummy/dummy.cc\n * DESCRIPTION:     XTLDR Dummy Module\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <dummy.hh>\n\n\n/* Dummy module information */\nMODULE_AUTHOR(L\"Rafal Kupiec <belliash@codingworkshop.eu.org>\");\nMODULE_DESCRIPTION(L\"XTLDR Dummy Module\");\nMODULE_LICENSE(L\"GPLv3\");\nMODULE_VERSION(L\"0.1\");\n\n\n/**\n * Stub boot routine.\n *\n * @param Parameters\n *        Supplies all parameters associated with the chosen boot menu entry.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nDummy::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)\n{\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Initializes DUMMY module by opening XTLDR protocol and installing DUMMY protocol.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nDummy::InitializeModule(IN EFI_HANDLE ImageHandle,\n                        IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    EFI_GUID DummyGuid = XT_DUMMY_BOOT_PROTOCOL_GUID;\n    EFI_STATUS Status;\n\n    /* Open the XTLDR protocol */\n    Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open the protocol, return error */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Set boot protocol routines */\n    DummyProtocol.BootSystem = BootSystem;\n\n    /* Register XTOS boot protocol */\n    XtLdrProtocol->Boot.RegisterProtocol(L\"DUMMYOS\", &DummyGuid);\n\n    /* Register DUMMY protocol as XTOS boot protocol */\n    return XtLdrProtocol->Protocol.Install(&DummyProtocol, &DummyGuid);\n}\n\n/**\n * This routine is the entry point of the XT EFI boot loader module.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtLdrModuleMain(IN EFI_HANDLE ImageHandle,\n                IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    /* Initialize DUMMY module */\n    return Dummy::InitializeModule(ImageHandle, SystemTable);\n}\n"
  },
  {
    "path": "boot/xtldr/modules/dummy/includes/dummy.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/dummy/includes/dummy.hh\n * DESCRIPTION:     XTLDR Dummy Module header file\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTLDR_DUMMY_DUMMY_HH\n#define __XTLDR_DUMMY_DUMMY_HH\n\n#include <xtblapi.h>\n\n\n/* DUMMY module for XTLDR */\nclass Dummy\n{\n    private:\n        STATIC XTBL_BOOT_PROTOCOL DummyProtocol;\n        STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;\n\n    public:\n        STATIC EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);\n        STATIC EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,\n                                           IN PEFI_SYSTEM_TABLE SystemTable);\n};\n\n#endif/* __XTLDR_DUMMY_DUMMY_HH */\n"
  },
  {
    "path": "boot/xtldr/modules/framebuf/CMakeLists.txt",
    "content": "# XTLDR FrameBuffer support module\nPROJECT(XTLDR_FRAMEBUF)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTLDR_FRAMEBUF_SOURCE_DIR}/includes)\n\n# Specify list of source code files\nlist(APPEND XTLDR_FRAMEBUF_SOURCE\n    ${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.cc\n    ${XTLDR_FRAMEBUF_SOURCE_DIR}/data.cc)\n\n# Link bootloader executable\nadd_executable(framebuf ${XTLDR_FRAMEBUF_SOURCE})\n\n# Add linker libraries\ntarget_link_libraries(framebuf libxtldr)\n\n# Set proper binary name and install target\nset_target_properties(framebuf PROPERTIES SUFFIX .efi)\nset_install_target(framebuf efi/boot/xtldr/modules)\n\n# Set module entrypoint and subsystem\nset_entrypoint(framebuf \"XtLdrModuleMain\")\nset_linker_map(framebuf TRUE)\nset_subsystem(framebuf efi_boot_service_driver)\n"
  },
  {
    "path": "boot/xtldr/modules/framebuf/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/framebuf/data.cc\n * DESCRIPTION:     EFI framebuffer module global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <framebuf.hh>\n\n\n/* Framebuffer display information */\nXTBL_FRAMEBUFFER_INFORMATION FrameBuffer::DisplayInfo;\n\n/* Framebuffer protocol handler */\nXTBL_FRAMEBUFFER_PROTOCOL FrameBuffer::FbProtocol;\n\n/* XTLDR protocol handler */\nPXTBL_LOADER_PROTOCOL FrameBuffer::XtLdrProtocol;\n"
  },
  {
    "path": "boot/xtldr/modules/framebuf/framebuf.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/framebuf/framebuf.cc\n * DESCRIPTION:     EFI framebuffer support module for XTLDR\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <framebuf.hh>\n\n\n/* PE/COFF_O module information */\nMODULE_AUTHOR(L\"Rafal Kupiec <belliash@codingworkshop.eu.org>\");\nMODULE_DESCRIPTION(L\"EFI FB (FrameBuffer) support\");\nMODULE_LICENSE(L\"GPLv3\");\nMODULE_VERSION(L\"0.2\");\n\n\n/**\n * Finds a PCI Display Adapter and returns its framebuffer address.\n *\n * @param Address\n *        Supplies a pointer to the memory area where framebuffer address will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nFrameBuffer::FindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address)\n{\n    EFI_GUID PciIoGuid = EFI_PCI_IO_PROTOCOL_GUID;\n    PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR BarInfo;\n    PEFI_PCI_IO_PROTOCOL IoProtocol;\n    ULONGLONG FramebufAddressLength;\n    PCI_TYPE0_DEVICE PciDevice;\n    PVOID FramebufAddress;\n    UINT_PTR HandlesCount;\n    EFI_HANDLE *Handles;\n    EFI_STATUS Status;\n    UINT Index;\n\n    /* Initialize variables */\n    FramebufAddressLength = 0;\n    Handles = NULLPTR;\n\n    /* Locate EFI_PCI_IO_PROTOCOL handles */\n    Status = XtLdrProtocol->Protocol.LocateHandles(&Handles, &HandlesCount, &PciIoGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get handles, return error code */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Failed to get handles (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Iterate through handles */\n    for(Index = 0; Index < HandlesCount; Index++)\n    {\n        /* Open EFI_PCI_IO_PROTOCOL handle */\n        Status = XtLdrProtocol->Protocol.OpenHandle(Handles[Index], (PVOID *)&IoProtocol, &PciIoGuid);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to open protocol, continue with next handle */\n            XtLdrProtocol->Debug.Print(L\"ERROR: Failed to open protocol (Status Code: 0x%zX)\\n\", Status);\n            continue;\n        }\n\n        /* Read PCI controller registers from PCI configuration space */\n        Status = IoProtocol->Pci.Read(IoProtocol, EfiPciIoWidthUint32, 0, sizeof(PciDevice) / sizeof(UINT), &PciDevice);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to read PCI device class */\n            XtLdrProtocol->Debug.Print(L\"ERROR: Failed to read class (Status Code: 0x%zX)\\n\", Status);\n\n            /* Close protocol and continue with next handle */\n            XtLdrProtocol->Protocol.Close(&Handles[Index], &PciIoGuid);\n            continue;\n        }\n\n        /* Check if device is a graphics adapter */\n        if(PciDevice.Hdr.ClassCode[2] != 0x03)\n        {\n            /* Not a graphics adapter, close protocol and continue with next handle */\n            XtLdrProtocol->Protocol.Close(&Handles[Index], &PciIoGuid);\n            continue;\n        }\n\n        /* Iterate through all PCI device's Base Address Registers (BARs) */\n        for(UINT Bars = 0; Bars < 6; Bars++)\n        {\n            /* Get BAR attributes */\n            Status = IoProtocol->GetBarAttributes(IoProtocol, Bars, NULLPTR, (VOID **)&BarInfo);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to get BAR attributes, continue with next BAR */\n                continue;\n            }\n\n            /* Check if this BAR is 'Memory Range' of 'ACPI QWORD Address Space' */\n            if(BarInfo->SpaceDescriptor == EFI_ACPI_ADDRESS64_SPACE_DESCRIPTOR &&\n               BarInfo->ResourceType == EFI_ACPI_ADDRESS_SPACE_TYPE_MEMORY)\n            {\n                /* Check if this BAR is the biggest we've seen so far */\n                if(BarInfo->AddressLength > FramebufAddressLength)\n                {\n                    /* The biggest BAR should be the framebuffer; save its address and length */\n                    FramebufAddress = (PVOID)(ULONG_PTR)(BarInfo->AddressRangeMin << 16);\n                    FramebufAddressLength = BarInfo->AddressLength;\n                }\n            }\n        }\n\n        /* Close handle and continue with next one */\n        XtLdrProtocol->Protocol.Close(&Handles[Index], &PciIoGuid);\n    }\n\n    /* Set framebuffer address and return success */\n    *Address = (EFI_PHYSICAL_ADDRESS)FramebufAddress;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Calculates color mask and shift based upon pixel bit mask.\n *\n * @param PixelBitMask\n *        Provides a pixel bit mask.\n *\n * @param ColorSize\n *        Supplies a pointer to the memory area where the color size will be stored.\n *\n * @param ColorShift\n *        Supplies a pointer to the memory area where the color shift (position) will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nFrameBuffer::GetColorMask(IN UINT PixelBitMask,\n                          OUT PUSHORT ColorSize,\n                          OUT PUSHORT ColorShift)\n{\n    UINT Shift, Size;\n\n    /* Initialize variables */\n    Shift = 0;\n    Size = 0;\n\n    /* Make sure EfiMask is not zero */\n    if(PixelBitMask)\n    {\n        /* Get color shift */\n        while((PixelBitMask & 1) == 0)\n        {\n            Shift++;\n            PixelBitMask >>= 1;\n        }\n\n        /* Get color size */\n        while((PixelBitMask & 1) == 1)\n        {\n            Size++;\n            PixelBitMask >>= 1;\n        }\n\n    }\n\n    /* Set color mask and shift */\n    *ColorShift = Shift;\n    *ColorSize = Size;\n}\n\n/**\n * Provides an EFI Frame Buffer protocol driver name used for initialization.\n *\n * @param Protocol\n *        Supplies a pointer to the memory area where framebuffer driver information will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nFrameBuffer::GetDisplayDriver(OUT PEFI_GRAPHICS_PROTOCOL Protocol)\n{\n        /* Check if framebuffer is initialized */\n    if(!DisplayInfo.Initialized)\n    {\n        /* Return error if framebuffer is not initialized */\n        return STATUS_EFI_NOT_READY;\n    }\n\n    /* Copy framebuffer driver information */\n    *Protocol = DisplayInfo.Protocol;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Returns information about EFI Frame Buffer.\n *\n * @param FbInfo\n *        Supplies a pointer to the memory area where framebuffer information will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nFrameBuffer::GetDisplayInformation(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase,\n                                   OUT PULONG_PTR FrameBufferSize,\n                                   OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo)\n{\n    /* Check if framebuffer is initialized */\n    if(!DisplayInfo.Initialized)\n    {\n        /* Return error if framebuffer is not initialized */\n        return STATUS_EFI_NOT_READY;\n    }\n\n    /* Set basic framebuffer information */\n    *FrameBufferBase = DisplayInfo.FrameBufferBase;\n    *FrameBufferSize = DisplayInfo.FrameBufferSize;\n\n    /* Set framebuffer mode information */\n    ModeInfo->Width = DisplayInfo.ModeInfo.Width;\n    ModeInfo->Height = DisplayInfo.ModeInfo.Height;\n    ModeInfo->Depth = DisplayInfo.ModeInfo.Depth;\n    ModeInfo->RefreshRate = DisplayInfo.ModeInfo.RefreshRate;\n    ModeInfo->BitsPerPixel = DisplayInfo.ModeInfo.BitsPerPixel;\n    ModeInfo->BytesPerPixel = DisplayInfo.ModeInfo.BytesPerPixel;\n    ModeInfo->PixelsPerScanLine = DisplayInfo.ModeInfo.PixelsPerScanLine;\n    ModeInfo->Pitch = DisplayInfo.ModeInfo.Pitch;\n    ModeInfo->PixelFormat = DisplayInfo.ModeInfo.PixelFormat;\n    ModeInfo->PixelInformation = DisplayInfo.ModeInfo.PixelInformation;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n\n/**\n * Gets information about the current display mode and stores it in internal structure.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nFrameBuffer::GetModeInformation()\n{\n    PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;\n    EFI_PIXEL_BITMASK PixelBitMask;\n    XTSTATUS Status;\n    UINT_PTR Size;\n\n    switch(DisplayInfo.Protocol)\n    {\n        case GOP:\n            /* Query GOP mode information */\n            Status = DisplayInfo.Driver.Gop->QueryMode(DisplayInfo.Driver.Gop,\n                                                          DisplayInfo.Driver.Gop->Mode->Mode,\n                                                          &Size, &ModeInfo);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to get GOP mode information, return error */\n                return Status;\n            }\n\n            /* Get pixel bit mask information */\n            GetPixelInformation(&DisplayInfo.Driver.Gop->Mode->Info->PixelInformation);\n\n            /* Store GOP framebuffer information */\n            DisplayInfo.ModeInfo.Width = DisplayInfo.Driver.Gop->Mode->Info->HorizontalResolution;\n            DisplayInfo.ModeInfo.Height = DisplayInfo.Driver.Gop->Mode->Info->VerticalResolution;\n            DisplayInfo.ModeInfo.Depth = DisplayInfo.ModeInfo.BitsPerPixel;\n            DisplayInfo.ModeInfo.PixelsPerScanLine = DisplayInfo.Driver.Gop->Mode->Info->PixelsPerScanLine;\n            DisplayInfo.ModeInfo.Pitch = DisplayInfo.ModeInfo.PixelsPerScanLine *\n                                            (DisplayInfo.ModeInfo.BitsPerPixel / 8);\n            DisplayInfo.ModeInfo.RefreshRate = 0;\n\n            /* Store pixel format information and frame buffer size */\n            DisplayInfo.ModeInfo.PixelFormat = DisplayInfo.Driver.Gop->Mode->Info->PixelFormat;\n            DisplayInfo.FrameBufferSize = DisplayInfo.Driver.Gop->Mode->FrameBufferSize;\n            break;\n        case UGA:\n            /* Query UGA mode information */\n            Status = DisplayInfo.Driver.Uga->GetMode(DisplayInfo.Driver.Uga, &DisplayInfo.ModeInfo.Width,\n                                                        &DisplayInfo.ModeInfo.Height, &DisplayInfo.ModeInfo.Depth,\n                                                        &DisplayInfo.ModeInfo.RefreshRate);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to get UGA mode information, return error */\n                return Status;\n            }\n\n            /* Get pixel bit mask information */\n            PixelBitMask = (EFI_PIXEL_BITMASK){0, 0, 0, 0};\n            GetPixelInformation(&PixelBitMask);\n\n            /* Store UGA framebuffer information */\n            DisplayInfo.ModeInfo.PixelsPerScanLine = DisplayInfo.ModeInfo.Width;\n            DisplayInfo.ModeInfo.Pitch = DisplayInfo.ModeInfo.PixelsPerScanLine *\n                                            (DisplayInfo.ModeInfo.BitsPerPixel / 8);\n\n            /* Store pixel format information and recalculate frame buffer size */\n            DisplayInfo.ModeInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\n            DisplayInfo.FrameBufferSize = DisplayInfo.ModeInfo.Width *\n                                             DisplayInfo.ModeInfo.Height *\n                                             DisplayInfo.ModeInfo.BytesPerPixel + 1024;\n            break;\n        default:\n            /* This should never be reached as no other display driver is supported */\n            break;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/** \n * Gets pixel information based on the reported pixel format.\n *\n * @param FrameBufferInfo\n *        Supplies a pointer to the framebuffer information structure.\n *\n * @param PixelsBitMask\n *        Supplies a pointer to the pixel bit mask information provided by EFI graphics protocol.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nFrameBuffer::GetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask)\n{\n    UINT CompoundMask;\n\n    /* Check reported pixel format */\n    switch(DisplayInfo.ModeInfo.PixelFormat)\n    {\n        case PixelBlueGreenRedReserved8BitPerColor:\n            /* BGRR, 32 bits per pixel */\n            DisplayInfo.ModeInfo.BitsPerPixel = 32;\n            DisplayInfo.ModeInfo.PixelInformation.BlueShift = 0;\n            DisplayInfo.ModeInfo.PixelInformation.BlueSize = 8;\n            DisplayInfo.ModeInfo.PixelInformation.GreenShift = 8;\n            DisplayInfo.ModeInfo.PixelInformation.GreenSize = 8;\n            DisplayInfo.ModeInfo.PixelInformation.RedShift = 16;\n            DisplayInfo.ModeInfo.PixelInformation.RedSize = 8;\n            DisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24;\n            DisplayInfo.ModeInfo.PixelInformation.ReservedSize = 8;\n            break;\n        case PixelRedGreenBlueReserved8BitPerColor:\n            /* RGBR, 32 bits per pixel */\n            DisplayInfo.ModeInfo.BitsPerPixel = 32;\n            DisplayInfo.ModeInfo.PixelInformation.BlueShift = 16;\n            DisplayInfo.ModeInfo.PixelInformation.BlueSize = 8;\n            DisplayInfo.ModeInfo.PixelInformation.GreenShift = 8;\n            DisplayInfo.ModeInfo.PixelInformation.GreenSize = 8;\n            DisplayInfo.ModeInfo.PixelInformation.RedShift = 0;\n            DisplayInfo.ModeInfo.PixelInformation.RedSize = 8;\n            DisplayInfo.ModeInfo.PixelInformation.ReservedShift = 24;\n            DisplayInfo.ModeInfo.PixelInformation.ReservedSize = 8;\n            break;\n        case PixelBitMask:\n            /* Assume 32 bits per pixel */\n            DisplayInfo.ModeInfo.BitsPerPixel = 32;\n\n            /* Calculate compound mask */\n            CompoundMask = PixelsBitMask->RedMask |\n                           PixelsBitMask->GreenMask |\n                           PixelsBitMask->BlueMask |\n                           PixelsBitMask->ReservedMask;\n\n            /* Recalculate bits per pixel */\n            while((CompoundMask & (1 << 31)) == 0)\n            {\n                DisplayInfo.ModeInfo.BitsPerPixel--;\n                CompoundMask <<= 1;\n            }\n\n            /* Set pixel information */\n            GetColorMask(PixelsBitMask->RedMask, &DisplayInfo.ModeInfo.PixelInformation.RedSize,\n                         &DisplayInfo.ModeInfo.PixelInformation.RedShift);\n            GetColorMask(PixelsBitMask->GreenMask, &DisplayInfo.ModeInfo.PixelInformation.GreenSize,\n                         &DisplayInfo.ModeInfo.PixelInformation.GreenShift);\n            GetColorMask(PixelsBitMask->BlueMask, &DisplayInfo.ModeInfo.PixelInformation.BlueSize,\n                         &DisplayInfo.ModeInfo.PixelInformation.BlueShift);\n            GetColorMask(PixelsBitMask->ReservedMask, &DisplayInfo.ModeInfo.PixelInformation.ReservedSize,\n                         &DisplayInfo.ModeInfo.PixelInformation.ReservedShift);\n            break;\n        default:\n            /* Unknown pixel format */\n            DisplayInfo.ModeInfo.BitsPerPixel = 0;\n            DisplayInfo.ModeInfo.PixelInformation.BlueShift = 0;\n            DisplayInfo.ModeInfo.PixelInformation.BlueSize = 0;\n            DisplayInfo.ModeInfo.PixelInformation.GreenShift = 0;\n            DisplayInfo.ModeInfo.PixelInformation.GreenSize = 0;\n            DisplayInfo.ModeInfo.PixelInformation.RedShift = 0;\n            DisplayInfo.ModeInfo.PixelInformation.RedSize = 0;\n            DisplayInfo.ModeInfo.PixelInformation.ReservedShift = 0;\n            DisplayInfo.ModeInfo.PixelInformation.ReservedSize = 0;\n            break;\n    }\n\n    /* Calculate bytes per pixel based on bits per pixel */\n    DisplayInfo.ModeInfo.BytesPerPixel = DisplayInfo.ModeInfo.BitsPerPixel >> 3;\n}\n\n/**\n * Determines the preferred (native) screen resolution from EDID. This works only with GOP.\n *\n * @param PreferredWidth\n *        Supplies a pointer to the memory area where preferred screen width will be stored.\n *\n * @param PreferredHeight\n *        Supplies a pointer to the memory area where preferred screen height will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nFrameBuffer::GetPreferredScreenResolution(OUT PUINT PreferredWidth,\n                                          OUT PUINT PreferredHeight)\n{\n    EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;\n    EFI_GUID EdidGuid = EFI_EDID_ACTIVE_PROTOCOL_GUID;\n    PEFI_EDID_ACTIVE_PROTOCOL ActiveEdid;\n    EFI_STATUS Status;\n\n    /* Check if framebuffer is initialized */\n    if(!DisplayInfo.Initialized)\n    {\n        /* Framebuffer not ready to use EDID protocol */\n        return STATUS_EFI_NOT_READY;\n    }\n\n    /* Check if GOP device driver is used */\n    if(DisplayInfo.Protocol != GOP)\n    {\n        /* Unsupported device driver */\n        return STATUS_EFI_UNSUPPORTED;\n    }\n\n    /* Open EDID protocol */\n    Status = XtLdrProtocol->Protocol.OpenHandle(DisplayInfo.Handle, (PVOID *)&ActiveEdid, &EdidGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open EDID protocol, close GOP protocol and return */\n        XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid);\n        return Status;\n    }\n\n    /* Return preferred screen resolution */\n    *PreferredWidth = ActiveEdid->Edid[0x38] | ((ActiveEdid->Edid[0x3A] & 0xF0) << 4);\n    *PreferredHeight = ActiveEdid->Edid[0x3B] | ((ActiveEdid->Edid[0x3D] & 0xF0) << 4);\n\n    /* Close EDID & GOP protocols */\n    XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &EdidGuid);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Initializes FrameBuffer device on GOP and UGA compatible adapters.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nFrameBuffer::InitializeDisplay()\n{\n    EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;\n    EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID;\n    PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION GopModeInfo;\n    UINT Depth, QueryMode, Refresh;\n    UINT_PTR InfoSize;\n    EFI_STATUS Status;\n\n    /* Check if framebuffer already initialized */\n    if(!DisplayInfo.Initialized)\n    {\n        /* Print debug message */\n        XtLdrProtocol->Debug.Print(L\"Initializing framebuffer device\\n\");\n\n        /* Attempt to open EFI GOP protocol */\n        Status = XtLdrProtocol->Protocol.Open(&DisplayInfo.Handle, (PVOID*)&DisplayInfo.Driver.Gop, &GopGuid);\n\n        /* Check if Graphics Output Protocol (GOP) is available */\n        if(Status == STATUS_EFI_SUCCESS)\n        {\n            /* Check if there are any video modes available */\n            if(DisplayInfo.Driver.Gop->Mode->MaxMode == 0)\n            {\n                /* No video modes available */\n                XtLdrProtocol->Debug.Print(L\"ERROR: No GOP video mode available\\n\");\n\n                /* Close GOP protocol and return error */\n                XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid);\n                return STATUS_EFI_UNSUPPORTED;\n            }\n\n            /* Query current graphics mode */\n            QueryMode = DisplayInfo.Driver.Gop->Mode == NULLPTR ? 0 : DisplayInfo.Driver.Gop->Mode->Mode;\n            Status = DisplayInfo.Driver.Gop->QueryMode(DisplayInfo.Driver.Gop, QueryMode, &InfoSize, &GopModeInfo);\n            if(Status == STATUS_EFI_NOT_STARTED)\n            {\n                /* Set the mode to circumvent buggy UEFI firmware */\n                Status = DisplayInfo.Driver.Gop->SetMode(DisplayInfo.Driver.Gop, 0);\n            }\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Unable to query GOP modes */\n                XtLdrProtocol->Debug.Print(L\"ERROR: Failed to get GOP native mode (Status Code: 0x%zX)\\n\");\n\n                /* Close GOP protocol and return error */\n                XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid);\n                return STATUS_EFI_UNSUPPORTED;\n            }\n\n            /* Store frame buffer base address and protocol used */\n            DisplayInfo.FrameBufferBase = DisplayInfo.Driver.Gop->Mode->FrameBufferBase;\n            DisplayInfo.DefaultMode = DisplayInfo.Driver.Gop->Mode->Mode;\n            DisplayInfo.Protocol = GOP;\n\n            /* Get current mode information */\n            Status = GetModeInformation();\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Unable to get mode information */\n                XtLdrProtocol->Debug.Print(L\"ERROR: Failed to get GOP mode information (Status Code: 0x%zX)\\n\");\n\n                /* Close GOP protocol and return error */\n                XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid);\n                return STATUS_EFI_UNSUPPORTED;\n            }\n\n            /* Found GOP */\n            XtLdrProtocol->Debug.Print(L\"Found EFI-GOP compatible display adapter @ %P (%zu bytes)\\n\",\n                                       DisplayInfo.FrameBufferBase, DisplayInfo.FrameBufferSize);\n\n            /* Close GOP protocol */\n            Status = XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &GopGuid);\n        }\n        else\n        {\n            /* GOP is unavailable, attempt to open UGA protocol */\n            Status = XtLdrProtocol->Protocol.Open(&DisplayInfo.Handle, (PVOID*)&DisplayInfo.Driver.Uga, &UgaGuid);\n\n            /* Check if Universal Graphics Adapter (UGA) is available */\n            if(Status == STATUS_EFI_SUCCESS)\n            {\n                /* Get current video mode */\n                Status = DisplayInfo.Driver.Uga->GetMode(DisplayInfo.Driver.Uga, &DisplayInfo.ModeInfo.Width,\n                                                            &DisplayInfo.ModeInfo.Height, &Depth, &Refresh);\n                if(Status != STATUS_EFI_SUCCESS)\n                {\n                    /* Unable to get current UGA mode */\n                    XtLdrProtocol->Debug.Print(L\"ERROR: Failed to get current UGA mode (Status Code: 0x%zX)\\n\", Status);\n\n                    /* Close UGA protocol and return error */\n                    XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &UgaGuid);\n                    return STATUS_EFI_DEVICE_ERROR;\n                }\n\n                /* Find framebuffer address */\n                Status = FindFramebufferAddress(&DisplayInfo.FrameBufferBase);\n                if(Status != STATUS_EFI_SUCCESS)\n                {\n                    /* Unable to find framebuffer address */\n                    XtLdrProtocol->Debug.Print(L\"ERROR: Failed to get EFI FB address (Status Code: 0x%zX)\\n\", Status);\n\n                    /* Close UGA protocol and return error */\n                    XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &UgaGuid);\n                    return STATUS_EFI_DEVICE_ERROR;\n                }\n\n                /* Store framebuffer protocol information */\n                DisplayInfo.DefaultMode = 0;\n                DisplayInfo.Protocol = UGA;\n\n                /* Get mode information */\n                Status = GetModeInformation();\n                if(Status != STATUS_EFI_SUCCESS)\n                {\n                    /* Unable to get mode information */\n                    XtLdrProtocol->Debug.Print(L\"ERROR: Failed to get UGA mode information (Status Code: 0x%zX)\\n\");\n                    return STATUS_EFI_UNSUPPORTED;\n                }\n\n                /* Found UGA */\n                XtLdrProtocol->Debug.Print(L\"Found EFI-UGA compatible display adapter @ %P (%zu bytes)\\n\",\n                                           DisplayInfo.FrameBufferBase, DisplayInfo.FrameBufferSize);\n\n                /* Close UGA protocol */\n                XtLdrProtocol->Protocol.Close(&DisplayInfo.Handle, &UgaGuid);\n            }\n        }\n\n        /* Make sure framebuffer initialized properly */\n        if(DisplayInfo.Protocol == NONE)\n        {\n            /* GOP and UGA unavailable */\n            XtLdrProtocol->Debug.Print(L\"WARNING: No display adapter found!\\n\");\n            return STATUS_EFI_NOT_FOUND;\n        }\n\n        XtLdrProtocol->Debug.Print(L\"Current screen resolution is %ux%ux%u\\n\", DisplayInfo.ModeInfo.Width,\n                                   DisplayInfo.ModeInfo.Height, DisplayInfo.ModeInfo.BitsPerPixel);\n\n        /* Set framebuffer initialization flag */\n        DisplayInfo.Initialized = TRUE;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes FRAMEBUF module by opening XTLDR protocol and installing FRAMEBUF protocol.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nFrameBuffer::InitializeModule(IN EFI_HANDLE ImageHandle,\n                              IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    EFI_GUID Guid = XT_FRAMEBUFFER_PROTOCOL_GUID;\n    EFI_STATUS Status;\n\n    /* Open the XTLDR protocol */\n    Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open loader protocol */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Set initial framebuffer state */\n    DisplayInfo.Protocol = NONE;\n    DisplayInfo.Initialized = FALSE;\n\n    /* Set routines available via XTLDR framebuffer protocol */\n    FbProtocol.GetDisplayDriver = GetDisplayDriver;\n    FbProtocol.GetDisplayInformation = GetDisplayInformation;\n    FbProtocol.GetPreferredScreenResolution = GetPreferredScreenResolution;\n    FbProtocol.Initialize = InitializeDisplay;\n    FbProtocol.SetScreenResolution = SetScreenResolution;\n\n    /* Register XTOS boot protocol */\n    return XtLdrProtocol->Protocol.Install(&FbProtocol, &Guid);\n}\n\n/**\n * Sets custom screen resolution, based on the provided width and height.\n *\n * @param Width\n *        Supplies the width of the screen.\n *\n * @param Height\n *        Supplies the height of the screen.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nFrameBuffer::SetScreenResolution(IN UINT Width,\n                                 IN UINT Height)\n{\n    PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;\n    BOOLEAN ModeChanged;\n    EFI_STATUS Status;\n    UINT_PTR Size;\n    UINT Mode;\n\n    /* Check if framebuffer is initialized */\n    if(!DisplayInfo.Initialized)\n    {\n        /* Framebuffer not ready to change screen mode */\n        return STATUS_EFI_NOT_READY;\n    }\n\n    ModeChanged = FALSE;\n\n    /* Change screen mode depending on display adapter protocol */\n    switch(DisplayInfo.Protocol)\n    {\n        case GOP:\n            /* GOP available, check if user specified screen resolution */\n            if(Width == 0 || Height == 0)\n            {\n                /* No resolution specified, temporarily set lowest supported screen resolution */\n                Status = DisplayInfo.Driver.Gop->SetMode(DisplayInfo.Driver.Gop, 1);\n                if(Status == STATUS_EFI_SUCCESS)\n                {\n                    /* Restore default graphics mode */\n                    Status = DisplayInfo.Driver.Gop->SetMode(DisplayInfo.Driver.Gop, DisplayInfo.DefaultMode);\n                    ModeChanged = (Status == STATUS_EFI_SUCCESS) ? TRUE : FALSE;\n                }\n            }\n            else\n            {\n                /* User specified screen resolution, find a corresponding mode */\n                Mode = 1;\n                while(Mode <= DisplayInfo.Driver.Gop->Mode->MaxMode)\n                {\n                    /* Get mode information */\n                    Status = DisplayInfo.Driver.Gop->QueryMode(DisplayInfo.Driver.Gop, Mode, &Size, &ModeInfo);\n                    if(Status == STATUS_EFI_SUCCESS && Size >= sizeof(*ModeInfo) && ModeInfo != NULLPTR)\n                    {\n                        /* Check if match found */\n                        if(ModeInfo->HorizontalResolution == Width && ModeInfo->VerticalResolution == Height)\n                        {\n                            /* Found corresponding mode, attempt to set it */\n                            Status = DisplayInfo.Driver.Gop->SetMode(DisplayInfo.Driver.Gop, Mode);\n                            if(Status == STATUS_EFI_SUCCESS)\n                            {\n                                /* New mode set correctly, use it */\n                                ModeChanged = TRUE;\n                                break;\n                            }\n                        }\n                    }\n\n                    /* Try with next mode */\n                    Mode++;\n                }\n            }\n            break;\n        case UGA:\n            /* Set UGA screen mode, trying to keep current color depth and refresh rate */\n            Status = DisplayInfo.Driver.Uga->SetMode(DisplayInfo.Driver.Uga, Width, Height,\n                                                        DisplayInfo.ModeInfo.Depth,\n                                                        DisplayInfo.ModeInfo.RefreshRate);\n            if(Status == STATUS_EFI_SUCCESS)\n            {\n                /* New mode set correctly, use it */\n                ModeChanged = TRUE;\n            }\n            break;\n        default:\n            /* This should never be reached */\n            break;\n    }\n\n    if(!ModeChanged)\n    {\n        /* Failed to change screen mode */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Failed to change screen mode to %ux%u (Status Code: 0x%zX)\\n\",\n                                   Width, Height, Status);\n        return STATUS_EFI_UNSUPPORTED;\n    }\n\n    /* Get new screen mode information */\n    Status = GetModeInformation();\n    if(Status == STATUS_EFI_SUCCESS)\n    {\n        XtLdrProtocol->Debug.Print(L\"Changed screen resolution to %ux%ux%u\\n\", DisplayInfo.ModeInfo.Width,\n                                   DisplayInfo.ModeInfo.Height, DisplayInfo.ModeInfo.BitsPerPixel);\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine is the entry point of the XT EFI boot loader module.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtLdrModuleMain(IN EFI_HANDLE ImageHandle,\n                IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    /* Initialize FRAMEBUF module */\n    return FrameBuffer::InitializeModule(ImageHandle, SystemTable);\n}\n"
  },
  {
    "path": "boot/xtldr/modules/framebuf/includes/framebuf.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/framebuf/includes/framebuf.hh\n * DESCRIPTION:     EFI Framebuffer support module header file\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTLDR_MODULES_FRAMEBUF_HH\n#define __XTLDR_MODULES_FRAMEBUF_HH\n\n#include <xtblapi.h>\n\n\nclass FrameBuffer\n{\n    private:\n        STATIC XTBL_FRAMEBUFFER_INFORMATION DisplayInfo;\n        STATIC XTBL_FRAMEBUFFER_PROTOCOL FbProtocol;\n        STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;\n\n    public:\n        STATIC XTCDECL EFI_STATUS GetDisplayDriver(OUT PEFI_GRAPHICS_PROTOCOL Protocol);\n        STATIC XTCDECL EFI_STATUS GetDisplayInformation(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase,\n                                                        OUT PULONG_PTR FrameBufferSize,\n                                                        OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo);\n        STATIC XTCDECL EFI_STATUS GetPreferredScreenResolution(OUT PUINT PreferredWidth,\n                                                               OUT PUINT PreferredHeight);\n        STATIC XTCDECL EFI_STATUS InitializeDisplay();\n        STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,\n                                                   IN PEFI_SYSTEM_TABLE SystemTable);\n        STATIC XTCDECL EFI_STATUS SetScreenResolution(IN UINT Width,\n                                                      IN UINT Height);\n\n    private:\n        STATIC EFI_STATUS FindFramebufferAddress(OUT PEFI_PHYSICAL_ADDRESS Address);\n        STATIC XTCDECL VOID GetColorMask(IN UINT EfiMask,\n                                         OUT PUSHORT ColorSize,\n                                         OUT PUSHORT ColorShift);\n        STATIC XTCDECL EFI_STATUS GetModeInformation();\n        STATIC XTCDECL VOID GetPixelInformation(IN PEFI_PIXEL_BITMASK PixelsBitMask);\n};\n\n#endif /* __XTLDR_MODULES_FRAMEBUF_HH */\n"
  },
  {
    "path": "boot/xtldr/modules/pecoff/CMakeLists.txt",
    "content": "# XTLDR PE/COFF image support module\nPROJECT(XTLDR_PECOFF)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTLDR_PECOFF_SOURCE_DIR}/includes)\n\n# Specify list of source code files\nlist(APPEND XTLDR_PECOFF_SOURCE\n    ${XTLDR_PECOFF_SOURCE_DIR}/data.cc\n    ${XTLDR_PECOFF_SOURCE_DIR}/pecoff.cc)\n\n# Link module executable\nadd_executable(pecoff ${XTLDR_PECOFF_SOURCE})\n\n# Add linker libraries\ntarget_link_libraries(pecoff libxtldr libxtos)\n\n# Set proper binary name and install target\nset_target_properties(pecoff PROPERTIES SUFFIX .efi)\nset_install_target(pecoff efi/boot/xtldr/modules)\n\n# Set module entrypoint and subsystem\nset_entrypoint(pecoff \"XtLdrModuleMain\")\nset_linker_map(pecoff TRUE)\nset_subsystem(pecoff efi_boot_service_driver)\n"
  },
  {
    "path": "boot/xtldr/modules/pecoff/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/pecoff/globals.cc\n * DESCRIPTION:     Basic PE/COFF executable file format global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <pecoff.hh>\n\n\n/* XTOS PE/COFF Image Protocol */\nXTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoff::PeProtocol;\n\n/* EFI XT Loader Protocol */\nPXTBL_LOADER_PROTOCOL PeCoff::XtLdrProtocol;\n"
  },
  {
    "path": "boot/xtldr/modules/pecoff/includes/pecoff.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/pecoff/includes/pecoff.hh\n * DESCRIPTION:     Basic PE/COFF executable file format support header\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTLDR_PECOFF_HH\n#define __XTLDR_PECOFF_HH\n\n#include <xtblapi.h>\n\n\n/* PE/COFF module for XTLDR */\nclass PeCoff\n{\n    private:\n        STATIC XTBL_EXECUTABLE_IMAGE_PROTOCOL PeProtocol;\n        STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;\n\n    public:\n        STATIC XTCDECL EFI_STATUS GetEntryPoint(IN PVOID ImagePointer,\n                                                OUT PVOID *EntryPoint);\n        STATIC XTCDECL EFI_STATUS GetFileSize(IN PVOID ImagePointer,\n                                              OUT PULONGLONG FileSize);\n        STATIC XTCDECL EFI_STATUS GetImageSize(IN PVOID ImagePointer,\n                                               OUT PUINT ImageSize);\n        STATIC XTCDECL EFI_STATUS GetMachineType(IN PVOID ImagePointer,\n                                                 OUT PUSHORT MachineType);\n        STATIC XTCDECL EFI_STATUS GetSection(IN PVOID ImagePointer,\n                                             IN PCHAR SectionName,\n                                             OUT PULONG *RawData);\n        STATIC XTCDECL EFI_STATUS GetSubSystem(IN PVOID ImagePointer,\n                                               OUT PUSHORT SubSystem);\n        STATIC XTCDECL EFI_STATUS GetVersion(IN PVOID ImagePointer,\n                                             OUT PUSHORT Version);\n        STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,\n                                                   IN PEFI_SYSTEM_TABLE SystemTable);\n        STATIC XTCDECL EFI_STATUS LoadImage(IN PEFI_FILE_HANDLE FileHandle,\n                                            IN LOADER_MEMORY_TYPE MemoryType,\n                                            IN PVOID VirtualAddress,\n                                            OUT PVOID *ImagePointer);\n        STATIC XTCDECL EFI_STATUS RelocateImage(IN PVOID ImagePointer,\n                                                IN EFI_VIRTUAL_ADDRESS Address);\n        STATIC XTCDECL EFI_STATUS UnloadImage(IN PVOID ImagePointer);\n        STATIC XTCDECL EFI_STATUS VerifyImage(IN PVOID ImagePointer);\n\n    private:\n        STATIC XTCDECL EFI_STATUS RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image);\n};\n\n#endif /* __XTLDR_PECOFF_HH */\n"
  },
  {
    "path": "boot/xtldr/modules/pecoff/pecoff.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/pecoff/pecoff.cc\n * DESCRIPTION:     Basic PE/COFF executable file format support module\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <pecoff.hh>\n\n\n/* PE/COFF_O module information */\nMODULE_AUTHOR(L\"Rafal Kupiec <belliash@codingworkshop.eu.org>\");\nMODULE_DESCRIPTION(L\"Basic PE/COFF executable file format support\");\nMODULE_LICENSE(L\"GPLv3\");\nMODULE_VERSION(L\"0.1\");\n\n\n/**\n * Returns the address of the entry point.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @param EntryPoint\n *        Supplies a pointer to the memory area where address of the image entry point will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::GetEntryPoint(IN PVOID ImagePointer,\n                      OUT PVOID *EntryPoint)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->PeHeader)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Check PE/COFF image type */\n    if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Get entry point from 64-bit optional header */\n        *EntryPoint = (PUCHAR)Image->VirtualAddress + Image->PeHeader->OptionalHeader64.AddressOfEntryPoint;\n    }\n    else\n    {\n        /* Get entry point from 32-bit optional header */\n        *EntryPoint = (PUCHAR)Image->VirtualAddress + Image->PeHeader->OptionalHeader32.AddressOfEntryPoint;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Returns the size of the loaded PE/COFF file.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @param ImageSize\n *        Supplies a pointer to the memory area where file size will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::GetFileSize(IN PVOID ImagePointer,\n                    OUT PULONGLONG FileSize)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->ImageSize)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Get image size and return success */\n    *FileSize = Image->FileSize;\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Returns the size of the loaded PE/COFF image.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @param ImageSize\n *        Supplies a pointer to the memory area where image size will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::GetImageSize(IN PVOID ImagePointer,\n                     OUT PUINT ImageSize)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->ImageSize)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Get image size and return success */\n    *ImageSize = Image->ImageSize;\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Returns the machine type of the PE/COFF image.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @param MachineType\n *        Supplies a pointer to the memory area where a value defined for the 'machine' field will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::GetMachineType(IN PVOID ImagePointer,\n                       OUT PUSHORT MachineType)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->PeHeader)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Get image machine type and return success */\n    *MachineType = Image->PeHeader->FileHeader.Machine;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Returns an address to the specified section in the PE/COFF image.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @param SectionName\n *        Supplies a name of the requested section.\n *\n * @param RawData\n *        Supplies a pointer to the memory area where the address of the requested section will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::GetSection(IN PVOID ImagePointer,\n                   IN PCHAR SectionName,\n                   OUT PULONG *RawData)\n{\n    PPECOFF_IMAGE_SECTION_HEADER SectionHeader;\n    PPECOFF_IMAGE_CONTEXT Image;\n    SIZE_T SectionNameLength;\n    USHORT SectionIndex;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->PeHeader)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Check PE/COFF image type */\n    if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Find section header in 64-bit optional header */\n        SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&Image->PeHeader->OptionalHeader64 +\n                                                       Image->PeHeader->FileHeader.SizeOfOptionalHeader);\n    }\n    else\n    {\n        /* Find section header in 32-bit optional header */\n        SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&Image->PeHeader->OptionalHeader32 +\n                                                       Image->PeHeader->FileHeader.SizeOfOptionalHeader);\n    }\n\n    /* Get section name length */\n    SectionNameLength = XtLdrProtocol->String.Length(SectionName, 0);\n\n    /* Iterate through all image sections */\n    for(SectionIndex = 0; SectionIndex < Image->PeHeader->FileHeader.NumberOfSections; SectionIndex++)\n    {\n        /* Check section name */\n        if(XtLdrProtocol->String.Compare((PCHAR)SectionHeader[SectionIndex].Name, SectionName, SectionNameLength) == 0)\n        {\n            /* Store section address and return */\n            *RawData = (PULONG)((PUCHAR)Image->Data + SectionHeader[SectionIndex].PointerToRawData);\n            return STATUS_EFI_SUCCESS;\n        }\n    }\n\n    /* Section not found if reached here */\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Returns an information about subsystem that is required to run PE/COFF image.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @param SubSystem\n *        Supplies a pointer to the memory area storing a value defined for the 'subsystem' field of the image.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::GetSubSystem(IN PVOID ImagePointer,\n                     OUT PUSHORT SubSystem)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->PeHeader)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Check PE/COFF image type */\n    if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Get image subsystem from 64-bit optional header */\n        *SubSystem = Image->PeHeader->OptionalHeader64.Subsystem;\n    }\n    else\n    {\n        /* Get image subsystem from 32-bit optional header */\n        *SubSystem = Image->PeHeader->OptionalHeader32.Subsystem;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Returns an information about major image version.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @param Version\n *        Supplies a pointer to the memory area storing a major image version.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::GetVersion(IN PVOID ImagePointer,\n                   OUT PUSHORT Version)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->PeHeader)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Check PE/COFF image type */\n    if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Get image major version from 64-bit optional header */\n        *Version = Image->PeHeader->OptionalHeader64.MajorImageVersion;\n    }\n    else\n    {\n        /* Get image major version from 32-bit optional header */\n        *Version = Image->PeHeader->OptionalHeader32.MajorImageVersion;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Initializes PECOFF module by opening XTLDR protocol and installing PECOFF protocol.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::InitializeModule(IN EFI_HANDLE ImageHandle,\n                         IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    EFI_GUID Guid = XT_PECOFF_IMAGE_PROTOCOL_GUID;\n    EFI_STATUS Status;\n\n    /* Open the XTLDR protocol */\n    Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open loader protocol */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Set routines available via PE/COFF image protocol */\n    PeProtocol.GetEntryPoint = GetEntryPoint;\n    PeProtocol.GetFileSize = GetFileSize;\n    PeProtocol.GetImageSize = GetImageSize;\n    PeProtocol.GetMachineType = GetMachineType;\n    PeProtocol.GetSection = GetSection;\n    PeProtocol.GetSubSystem = GetSubSystem;\n    PeProtocol.GetVersion = GetVersion;\n    PeProtocol.LoadImage = LoadImage;\n    PeProtocol.RelocateImage = RelocateImage;\n    PeProtocol.UnloadImage = UnloadImage;\n    PeProtocol.VerifyImage = VerifyImage;\n\n    /* Register PE/COFF protocol */\n    return XtLdrProtocol->Protocol.Install(&PeProtocol, &Guid);\n}\n\n/**\n * Loads a PE/COFF image file.\n *\n * @param FileHandle\n *        The handle of the opened portable executable (PE) file.\n *\n * @param MemoryType\n *        Supplies the type of memory to be assigned to the memory descriptor.\n *\n * @param VirtualAddress\n *        Optional virtual address pointing to the memory area where PE/COFF file will be loaded.\n *\n * @param Image\n *        Supplies pointer to the memory area where loaded PE/COFF image context will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::LoadImage(IN PEFI_FILE_HANDLE FileHandle,\n                  IN LOADER_MEMORY_TYPE MemoryType,\n                  IN PVOID VirtualAddress,\n                  OUT PVOID *ImagePointer)\n{\n    EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID;\n    PPECOFF_IMAGE_SECTION_HEADER SectionHeader;\n    PPECOFF_IMAGE_CONTEXT ImageData;\n    EFI_PHYSICAL_ADDRESS Address;\n    PEFI_FILE_INFO FileInfo;\n    UINT_PTR ReadSize;\n    EFI_STATUS Status;\n    UINT SectionSize;\n    SIZE_T Pages;\n    PUCHAR Data;\n    UINT Index;\n\n    /* Set required size for getting file information */\n    ReadSize = sizeof(EFI_FILE_INFO) + 32;\n\n    /* Allocate necessary amount of memory */\n    Status = XtLdrProtocol->Memory.AllocatePool(ReadSize, (PVOID *)&FileInfo);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* First attempt to get file information */\n    Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo);\n    if(Status == STATUS_EFI_BUFFER_TOO_SMALL)\n    {\n        /* Buffer it too small, but EFI tells the required size, let's reallocate */\n        XtLdrProtocol->Memory.FreePool(&FileInfo);\n        Status = XtLdrProtocol->Memory.AllocatePool(ReadSize, (PVOID *)&FileInfo);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failure */\n            XtLdrProtocol->Debug.Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n            return Status;\n        }\n\n        /* Second attempt to get file information */\n        Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo);\n    }\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Unable to get file information */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Failed to get PE/COFF file information (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Allocate memory for storing image data */\n    Status = XtLdrProtocol->Memory.AllocatePool(sizeof(PECOFF_IMAGE_CONTEXT), (PVOID *)&ImageData);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Store file size and memory type, nullify data and free up memory */\n    ImageData->Data = NULLPTR;\n    ImageData->FileSize = FileInfo->FileSize;\n    ImageData->MemoryType = MemoryType;\n    XtLdrProtocol->Memory.FreePool(FileInfo);\n\n    /* Calculate number of pages */\n    Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize);\n\n    /* Allocate pages */\n    Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Pages allocation failure */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Pages allocation failure (Status Code: 0x%zX)\\n\", Status);\n        XtLdrProtocol->Memory.FreePool(ImageData);\n        return Status;\n    }\n\n    /* Read PE/COFF image */\n    ReadSize = Pages * EFI_PAGE_SIZE;\n    Data = (PUCHAR)(UINT_PTR)Address;\n    Status = FileHandle->Read(FileHandle, &ReadSize, Data);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to read data */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Failed to read PE/COFF image file (Status Code: 0x%zX)\\n\", Status);\n        XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);\n        XtLdrProtocol->Memory.FreePool(ImageData);\n        return Status;\n    }\n\n    /* Extract DOS and PE headers */\n    ImageData->DosHeader = (PPECOFF_IMAGE_DOS_HEADER)Data;\n    ImageData->PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUCHAR)Data + ImageData->DosHeader->PeHeaderOffset);\n\n    /* Validate headers */\n    Status = PeCoff::VerifyImage(ImageData);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Header validation failed, probably broken or invalid PE/COFF image */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Invalid PE/COFF image headers (Status Code: 0x%zX)\\n\", Status);\n        XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);\n        XtLdrProtocol->Memory.FreePool(ImageData);\n        return Status;\n    }\n\n    /* Make sure image is executable */\n    if (!(ImageData->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_EXECUTABLE_IMAGE))\n    {\n        /* Loaded image is not executable */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Non-executable PE/COFF image loaded\\n\");\n        XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);\n        XtLdrProtocol->Memory.FreePool(ImageData);\n        return STATUS_EFI_LOAD_ERROR;\n    }\n\n    /* Store image size depending on the PE/COFF image type */\n    if(ImageData->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Store 64-bit image size */\n        ImageData->ImageSize = ImageData->PeHeader->OptionalHeader64.SizeOfImage;\n    }\n    else\n    {\n        /* Store 32-bit image size */\n        ImageData->ImageSize = ImageData->PeHeader->OptionalHeader32.SizeOfImage;\n    }\n\n    /* Calculate number of image pages */\n    ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize);\n\n    /* Allocate image pages */\n    Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ImageData->ImagePages, &Address);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Pages reallocation failure */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Pages reallocation failure (Status Code: 0x%zX)\\n\", Status);\n        XtLdrProtocol->Memory.FreePool(ImageData);\n        return Status;\n    }\n\n    /* Store image data and virtual address */\n    ImageData->Data = (PUCHAR)(UINT_PTR)Address;\n    ImageData->PhysicalAddress = (PVOID)(UINT_PTR)Address;\n    if(VirtualAddress)\n    {\n        /* Virtual address passed to this routine */\n        ImageData->VirtualAddress = VirtualAddress;\n    }\n    else\n    {\n        /* Virtual address not specified, use physical address */\n        ImageData->VirtualAddress = (PVOID)(UINT_PTR)Address;\n    }\n\n    /* Check the PE/COFF image type */\n    if(ImageData->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Copy all PE32+ sections */\n        XtLdrProtocol->Memory.CopyMemory(ImageData->Data, Data, ImageData->PeHeader->OptionalHeader64.SizeOfHeaders);\n\n        /* Find PE32+ section header */\n        SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&ImageData->PeHeader->OptionalHeader64 +\n                                                       ImageData->PeHeader->FileHeader.SizeOfOptionalHeader);\n    }\n    else\n    {\n        /* Copy all PE32 sections */\n        XtLdrProtocol->Memory.CopyMemory(ImageData->Data, Data, ImageData->PeHeader->OptionalHeader64.SizeOfHeaders);\n\n        /* Find PE32 section header */\n        SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&ImageData->PeHeader->OptionalHeader64 +\n                                                       ImageData->PeHeader->FileHeader.SizeOfOptionalHeader);\n    }\n\n    /* Load each section into memory */\n    for(Index = 0; Index < ImageData->PeHeader->FileHeader.NumberOfSections; Index++)\n    {\n        /* Check section raw data size and section virtual size */\n        if(SectionHeader[Index].SizeOfRawData < SectionHeader[Index].Misc.VirtualSize)\n        {\n            /* Use raw data size if it is smaller than virtual size */\n            SectionSize = SectionHeader[Index].SizeOfRawData;\n        }\n        else\n        {\n            /* User virtual size otherwise */\n            SectionSize = SectionHeader[Index].Misc.VirtualSize;\n        }\n\n        /* Make sure section is available */\n        if(SectionSize > 0 && SectionHeader[Index].PointerToRawData != 0)\n        {\n            /* Copy section */\n            XtLdrProtocol->Memory.CopyMemory((PUCHAR)ImageData->Data + SectionHeader[Index].VirtualAddress,\n                                             Data + SectionHeader[Index].PointerToRawData, SectionSize);\n        }\n\n        /* Check if raw size is shorter than virtual size */\n        if(SectionSize < SectionHeader[Index].Misc.VirtualSize)\n        {\n            /* Fill remaining space with zeroes */\n            XtLdrProtocol->Memory.ZeroMemory((PUCHAR)ImageData->Data + SectionHeader[Index].VirtualAddress + SectionSize,\n                                             SectionHeader[Index].Misc.VirtualSize - SectionSize);\n        }\n    }\n\n    /* Free pages */\n    XtLdrProtocol->Memory.FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages);\n\n    /* Perform relocation fixups */\n    Status = PeCoff::RelocateLoadedImage(ImageData);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to relocate image */\n        XtLdrProtocol->Debug.Print(L\"ERROR: PE/COFF image relocation failed (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Store image data */\n    *ImagePointer = ImageData;\n\n    /* Return SUCCESS */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Relocates PE/COFF image to the specified address.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @param Address\n *        Specifies destination address of memory region, where image should be relocated.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::RelocateImage(IN PVOID ImagePointer,\n                      IN EFI_VIRTUAL_ADDRESS Address)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n    ULONGLONG ImageBase, OldVirtualAddress;\n    EFI_STATUS Status;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Store original virtual address */\n    OldVirtualAddress = (UINT_PTR)Image->VirtualAddress;\n\n    /* Check PE/COFF image type */\n    if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* This is 64-bit PE32+, store its image base address */\n        ImageBase = Image->PeHeader->OptionalHeader64.ImageBase;\n    }\n    else\n    {\n        /* This is 32-bit PE32, store its image base address */\n        ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;\n    }\n\n    /* Overwrite virtual address and relocate image once again */\n    Image->VirtualAddress = (PVOID)(Address - OldVirtualAddress + ImageBase);\n    Status = PeCoff::RelocateLoadedImage(Image);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Relocation failed */\n        return Status;\n    }\n\n    /* Store new image virtual address */\n    Image->VirtualAddress = (PVOID)Address;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Relocates a loaded PE/COFF image.\n *\n * @param Image\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::RelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)\n{\n    PPECOFF_IMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;\n    PPECOFF_IMAGE_DATA_DIRECTORY DataDirectory;\n    USHORT Offset, Type, Count;\n    PUSHORT TypeOffset;\n    ULONGLONG ImageBase;\n    PUINT Address;\n    PULONGLONG LongPtr;\n    PUINT ShortPtr;\n\n    /* Make sure image is not stripped */\n    if(Image->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_RELOCS_STRIPPED)\n    {\n        /* No relocation information found */\n        XtLdrProtocol->Debug.Print(L\"WARNING: PE/COFF image is stripped and contains no information about relocations\\n\");\n        return STATUS_EFI_SUCCESS;\n    }\n\n    /* Check PE/COFF image type */\n    if(Image->PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Set relocation data directory and image base address */\n        DataDirectory = &Image->PeHeader->OptionalHeader64.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];\n        ImageBase = Image->PeHeader->OptionalHeader64.ImageBase;\n\n        /* Check if loaded 64-bit PE32+ image should be relocated */\n        if(Image->PeHeader->OptionalHeader64.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||\n        DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))\n        {\n            /* No need to relocate the image */\n            return STATUS_EFI_SUCCESS;\n        }\n    }\n    else\n    {\n        /* Set relocation data directory and image base address */\n        DataDirectory = &Image->PeHeader->OptionalHeader32.DataDirectory[PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC];\n        ImageBase = Image->PeHeader->OptionalHeader32.ImageBase;\n\n        /* Check if loaded 32-bit PE32 image should be relocated */\n        if(Image->PeHeader->OptionalHeader32.NumberOfRvaAndSizes <= PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC ||\n        DataDirectory->VirtualAddress == 0 || DataDirectory->Size < sizeof(PECOFF_IMAGE_BASE_RELOCATION))\n        {\n            /* No need to relocate the image */\n            return STATUS_EFI_SUCCESS;\n        }\n    }\n\n    /* Set relocation pointers */\n    RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)Image->Data + DataDirectory->VirtualAddress);\n    RelocationEnd = (PPECOFF_IMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + DataDirectory->Size);\n\n    /* Do relocations */\n    while(RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0)\n    {\n        /* Calculate number of relocations needed, address and type offset */\n        Count = (RelocationDir->SizeOfBlock - sizeof(PECOFF_IMAGE_BASE_RELOCATION)) / sizeof(USHORT);\n        Address = (PUINT)((PUCHAR)Image->Data + RelocationDir->VirtualAddress);\n        TypeOffset = (PUSHORT)((PUCHAR)RelocationDir + sizeof(PECOFF_IMAGE_BASE_RELOCATION));\n\n        /* Do relocations */\n        while(Count--)\n        {\n            /* Calculate offset and relocation type */\n            Offset = *TypeOffset & 0xFFF;\n            Type = *TypeOffset >> 12;\n\n            /* Check if end of the loaded address reached */\n            if((PVOID)(PUSHORT)(Address + Offset) >= (PUCHAR)Image->Data + Image->ImageSize)\n            {\n                /* Do not relocate after the end of loaded image */\n                break;\n            }\n\n            /* Make sure we are not going to relocate into .reloc section */\n            if((ULONG_PTR)(Address + Offset) < (ULONG_PTR)RelocationDir ||\n               (ULONG_PTR)(Address + Offset) >= (ULONG_PTR)RelocationEnd)\n            {\n                /* Apply relocation fixup */\n                switch (Type)\n                {\n                    case PECOFF_IMAGE_REL_BASED_ABSOLUTE:\n                        /* No relocation required */\n                        break;\n                    case PECOFF_IMAGE_REL_BASED_DIR64:\n                        /* 64-bit relocation */\n                        LongPtr = (PULONGLONG)((PUCHAR)Address + Offset);\n                        *LongPtr = *LongPtr - ImageBase + (UINT_PTR)Image->VirtualAddress;\n                        break;\n                    case PECOFF_IMAGE_REL_BASED_HIGHLOW:\n                        /* 32-bit relocation of hight and low half of address */\n                        ShortPtr = (PUINT)((PUCHAR)Address + Offset);\n                        *ShortPtr = *ShortPtr - ImageBase + (UINT_PTR)Image->VirtualAddress;\n                        break;\n                    default:\n                        /* Unknown or unsupported relocation type */\n                        return STATUS_EFI_UNSUPPORTED;\n                }\n            }\n            /* Increment the type offset */\n            TypeOffset++;\n        }\n\n        /* Next relocation */\n        RelocationDir = (PPECOFF_IMAGE_BASE_RELOCATION)((PUCHAR)RelocationDir + RelocationDir->SizeOfBlock);\n    }\n\n    /* Return SUCCESS */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Unloads a PE/COFF image file and frees allocated memory.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::UnloadImage(IN PVOID ImagePointer)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n    EFI_STATUS Status;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->Data)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Free memory allocated for the image */\n    Status = XtLdrProtocol->Memory.FreePages(Image->ImagePages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Image->Data);\n    Status |= XtLdrProtocol->Memory.FreePool(Image);\n\n    /* Return status */\n    return Status;\n}\n\n/**\n * Validates a PE/COFF image headers.\n *\n * @param ImagePointer\n *        Supplies a pointer to the PE/COFF context structure representing the loaded image.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nPeCoff::VerifyImage(IN PVOID ImagePointer)\n{\n    PPECOFF_IMAGE_CONTEXT Image;\n\n    /* Get PE/COFF image pointer*/\n    Image = (PPECOFF_IMAGE_CONTEXT)ImagePointer;\n\n    /* Validate input data */\n    if(!Image || !Image->PeHeader)\n    {\n        /* Invalid parameter passed */\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Validate file size */\n    if(Image->FileSize < sizeof(PECOFF_IMAGE_DOS_HEADER))\n    {\n        /* PE/COFF image shorter than DOS header, return error*/\n        return STATUS_EFI_END_OF_FILE;\n    }\n\n    /* Validate DOS header */\n    if(Image->DosHeader->Magic != PECOFF_IMAGE_DOS_SIGNATURE)\n    {\n        /* Invalid DOS signature, return error */\n        return STATUS_EFI_INCOMPATIBLE_VERSION;\n    }\n\n    /* Validate PE header */\n    if(Image->PeHeader->Signature != PECOFF_IMAGE_NT_SIGNATURE &&\n       Image->PeHeader->Signature != PECOFF_IMAGE_XT_SIGNATURE)\n    {\n        /* Invalid PE signature, return error */\n        return STATUS_EFI_INCOMPATIBLE_VERSION;\n    }\n\n    /* Validate optional header */\n    if(Image->PeHeader->OptionalHeader32.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC &&\n       Image->PeHeader->OptionalHeader64.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Invalid optional header signature, return error */\n        return STATUS_EFI_INCOMPATIBLE_VERSION;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine is the entry point of the XT EFI boot loader module.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtLdrModuleMain(IN EFI_HANDLE ImageHandle,\n                IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    /* Initialize PECOFF module */\n    return PeCoff::InitializeModule(ImageHandle, SystemTable);\n}\n"
  },
  {
    "path": "boot/xtldr/modules/xtos_o/CMakeLists.txt",
    "content": "# XT Boot Loader\nPROJECT(XTLDR_XTOS_O)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTLDR_XTOS_O_SOURCE_DIR}/includes)\n\n# Specify list of source code files\nlist(APPEND XTLDR_XTOS_O_SOURCE\n    ${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.cc\n    ${XTLDR_XTOS_O_SOURCE_DIR}/data.cc\n    ${XTLDR_XTOS_O_SOURCE_DIR}/xtos.cc)\n\n# Link bootloader executable\nadd_executable(xtos_o ${XTLDR_XTOS_O_SOURCE})\n\n# Add linker libraries\ntarget_link_libraries(xtos_o libxtos libxtldr)\n\n# Set proper binary name and install target\nset_target_properties(xtos_o PROPERTIES SUFFIX .efi)\nset_install_target(xtos_o efi/boot/xtldr/modules)\n\n# Set module entrypoint and subsystem\nset_entrypoint(xtos_o \"XtLdrModuleMain\")\nset_linker_map(xtos_o TRUE)\nset_subsystem(xtos_o efi_boot_service_driver)\n"
  },
  {
    "path": "boot/xtldr/modules/xtos_o/amd64/memory.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/amd64/memory.cc\n * DESCRIPTION:     EFI memory management for AMD64 target\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\nXTCDECL\nEFI_STATUS\nXtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    EFI_STATUS Status;\n\n    /* Build page map */\n    Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to build page map */\n        XtLdrProtocol->Debug.Print(L\"Failed to build page map (Status code: %zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Map memory for hardware layer */\n    Status = MapHardwareMemoryPool(PageMap);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to map memory for hardware layer */\n        XtLdrProtocol->Debug.Print(L\"Failed to map memory for hardware leyer (Status code: %zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Determines the appropriate EFI memory mapping strategy for the AMD64 architecture.\n *\n * @return This routine returns TRUE, what results in an identity mapping.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nXtos::DetermineMappingStrategy()\n{\n    /* Use an identity mapping strategy */\n    return TRUE;\n}\n\n/**\n * Determines the appropriate paging level (PML) for the AMD64 architecture.\n *\n * @param Parameters\n *        A pointer to the wide character string containing the kernel boot parameters.\n *\n * @return This routine returns the appropriate page map level (5 if LA57 is enabled, 4 otherwise).\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG\nXtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)\n{\n    CPUID_REGISTERS CpuRegisters;\n\n    /* Prepare CPUID registers to query for STD7 features */\n    XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;\n\n    /* Query CPUID */\n    XtLdrProtocol->Cpu.CpuId(&CpuRegisters);\n\n    /* Verify if the CPU supports the STD7 feature leaf (0x00000007) */\n    if(CpuRegisters.Eax >= CPUID_GET_STANDARD7_FEATURES)\n    {\n        /* Prepare CPUID registers to query for LA57 support */\n        XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;\n\n        /* Query CPUID */\n        XtLdrProtocol->Cpu.CpuId(&CpuRegisters);\n\n        /* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */\n        if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) &&\n           !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L\"NOXPA\")))\n        {\n            /* Enable LA57 (PML5) */\n            return 5;\n        }\n    }\n\n    /* Disable LA57 and use PML4 by default */\n    return 4;\n}\n\n/**\n * Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    EFI_STATUS Status;\n    EFI_PHYSICAL_ADDRESS TrampolineAddress;\n    PXT_TRAMPOLINE_ENTRY TrampolineEntry;\n    ULONG_PTR TrampolineSize;\n    PVOID TrampolineCode;\n\n    /* Check the configured page map level to set the LA57 state accordingly */\n    if(PageMap->PageMapLevel == 5)\n    {\n        /* Get the trampoline code information */\n        XtLdrProtocol->BootUtils.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize);\n        if(TrampolineCode == NULLPTR || TrampolineSize == 0)\n        {\n            /* Failed to get trampoline information */\n            XtLdrProtocol->Debug.Print(L\"Failed to get trampoline information\\n\");\n            return STATUS_EFI_INVALID_PARAMETER;\n        }\n\n        /* Set the address of the trampoline code below 1MB */\n        TrampolineAddress = MM_TRAMPOLINE_ADDRESS;\n\n        /* Allocate pages for the trampoline */\n        Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to allocate memory for trampoline code */\n            XtLdrProtocol->Debug.Print(L\"Failed to allocate memory for trampoline code (Status code: %zX)\\n\", Status);\n            return Status;\n        }\n\n        /* Set the trampoline entry point and copy its code into the allocated buffer */\n        TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress;\n        XtLdrProtocol->Memory.CopyMemory((PVOID)TrampolineEntry, TrampolineCode, TrampolineSize);\n    }\n\n    /* Exit EFI Boot Services */\n    XtLdrProtocol->Debug.Print(L\"Exiting EFI boot services\\n\");\n    Status = XtLdrProtocol->Utils.ExitBootServices();\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to exit boot services */\n        XtLdrProtocol->Debug.Print(L\"Failed to exit boot services (Status code: %zX)\\n\", Status);\n        return STATUS_EFI_ABORTED;\n    }\n\n    /* Check the configured page map level to set the LA57 state accordingly */\n    if(PageMap->PageMapLevel == 5)\n    {\n        /* Enable Linear Address 57-bit (LA57) extension */\n        XtLdrProtocol->Debug.Print(L\"Enabling Linear Address 57-bit (LA57)\\n\");\n\n        /* Execute the trampoline to enable LA57 and write PML5 to CR3 */\n        TrampolineEntry((UINT64)PageMap->PtePointer);\n    }\n    else\n    {\n        /* Disable Linear Address 57-bit (LA57) extension */\n        XtLdrProtocol->Debug.Print(L\"Disabling Linear Address 57-bit (LA57)\\n\");\n\n        /* Write PML4 to CR3 and enable paging */\n        XtLdrProtocol->Cpu.WriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);\n        XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) | CR0_PG);\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Maps the page table for hardware layer addess space.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;\n    EFI_PHYSICAL_ADDRESS Address;\n    EFI_STATUS Status;\n    ULONG Index;\n\n    if(PageMap->PageMapLevel == 5)\n    {\n        /* Get P5E (PML5) base address */\n        P5eBase = (PHARDWARE_PTE)PageMap->PtePointer;\n\n        /* Check if P5E entry already exists */\n        if(!P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid)\n        {\n            /* No valid P5E, allocate memory */\n            Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory allocation failure, return error */\n                return Status;\n            }\n\n            /* Map hardware memory */\n            XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n\n            /* Zero fill memory used by P5E */\n            XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);\n\n            /* Make P5E valid */\n            P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Valid = 1;\n            P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;\n            P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].Writable = 1;\n\n            /* Set PXE base address */\n            PxeBase = (PHARDWARE_PTE)(UINT_PTR)Address;\n        }\n        else\n        {\n            /* Set PXE base address based on existing P5E */\n            PxeBase = (PHARDWARE_PTE)((P5eBase[(MM_HARDWARE_VA_START >> MM_P5I_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);\n        }\n    }\n    else\n    {\n        /* Get PXE (PML4) base address */\n        PxeBase = (PHARDWARE_PTE)PageMap->PtePointer;\n    }\n\n    /* Check if PXE entry already exists */\n    if(!PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid)\n    {\n        /* No valid PXE, allocate memory */\n        Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failure, return error */\n            return Status;\n        }\n\n        /* Map hardware memory */\n        XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n\n        /* Zero fill memory used by PXE */\n        XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);\n\n        /* Make PXE valid */\n        PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Valid = 1;\n        PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;\n        PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].Writable = 1;\n\n        /* Set PPE base address */\n        PpeBase = (PHARDWARE_PTE)(UINT_PTR)Address;\n    }\n    else\n    {\n        /* Set PPE base address based on existing PXE */\n        PpeBase = (PHARDWARE_PTE)((PxeBase[(MM_HARDWARE_VA_START >> MM_PXI_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);\n    }\n\n    /* Check if PPE entry already exists */\n    if(!PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid)\n    {\n        /* No valid PPE, allocate memory */\n        Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failure, return error */\n            return Status;\n        }\n\n        /* Map hardware memory */\n        XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n\n        /* Zero fill memory used by PPE */\n        XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);\n\n        /* Make PPE valid */\n        PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Valid = 1;\n        PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].PageFrameNumber = Address / EFI_PAGE_SIZE;\n        PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].Writable = 1;\n\n        /* Set PDE base address */\n        PdeBase = (PHARDWARE_PTE)Address;\n    }\n    else\n    {\n        /* Set PDE base address, based on existing PPE */\n        PdeBase = (PHARDWARE_PTE)((PpeBase[(MM_HARDWARE_VA_START >> MM_PPI_SHIFT) & 0x1FF].PageFrameNumber) << EFI_PAGE_SHIFT);\n    }\n\n    /* Loop through 2 PDE entries */\n    for(Index = 0 ; Index < 2 ; Index++)\n    {\n        /* Check if PDE entry already exists */\n        if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)\n        {\n            /* No valid PDE, allocate memory */\n            Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory allocation failure, return error */\n                return Status;\n            }\n\n            /* Map hardware memory */\n            XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n\n            /* Zero fill memory used by PDE */\n            XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);\n\n            /* Make PDE valid */\n            PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid = 1;\n            PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].PageFrameNumber = Address / EFI_PAGE_SIZE;\n            PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Writable = 1;\n        }\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n"
  },
  {
    "path": "boot/xtldr/modules/xtos_o/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/xtos/data.cc\n * DESCRIPTION:     XTOS module global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* XTOS Boot Protocol */\nXTBL_BOOT_PROTOCOL Xtos::BootProtocol;\n\n/* XTOS PE/COFF Image Protocol */\nPXTBL_EXECUTABLE_IMAGE_PROTOCOL Xtos::PeCoffProtocol;\n\n/* EFI XT Loader Protocol */\nPXTBL_LOADER_PROTOCOL Xtos::XtLdrProtocol;\n"
  },
  {
    "path": "boot/xtldr/modules/xtos_o/i686/memory.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/i686/memory.cc\n * DESCRIPTION:     EFI memory management for i686 target\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\nXTCDECL\nEFI_STATUS\nXtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    ULONG_PTR SelfMapAddress;\n    EFI_STATUS Status;\n\n    /* Initialize self map address */\n    if(PageMap->PageMapLevel == 3)\n    {\n        /* For PML3 (PAE) use PTE base address */\n        SelfMapAddress = MM_PTE_BASE;\n    }\n    else\n    {\n        /* For PML2 (PAE disabled) use legacy PDE base address */\n        SelfMapAddress = MM_PDE_LEGACY_BASE;\n    }\n\n    /* Build page map */\n    Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, SelfMapAddress);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to build page map */\n        XtLdrProtocol->Debug.Print(L\"Failed to build page map (Status code: %zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Map memory for hardware layer */\n    Status = MapHardwareMemoryPool(PageMap);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to map memory for hardware layer */\n        XtLdrProtocol->Debug.Print(L\"Failed to map memory for hardware layer (Status code: %zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Determines the appropriate EFI memory mapping strategy for the i686 architecture.\n *\n * @return This routine returns FALSE, what results in a sequential mapping.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nXtos::DetermineMappingStrategy()\n{\n    /* Use a sequential mapping strategy */\n    return FALSE;\n}\n\n/**\n * Determines the appropriate paging level (PML) for the i686 architecture.\n *\n * @param Parameters\n *        A pointer to the wide character string containing the kernel boot parameters.\n *\n * @return This routine returns the appropriate page map level (3 if PAE is enabled, 2 otherwise).\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG\nXtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)\n{\n    CPUID_REGISTERS CpuRegisters;\n\n    /* Prepare CPUID registers to query for PAE support */\n    XtLdrProtocol->Memory.ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;\n\n    /* Query CPUID */\n    XtLdrProtocol->Cpu.CpuId(&CpuRegisters);\n\n    /* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */\n    if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) &&\n       !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L\"NOXPA\")))\n    {\n        /* Enable PAE (PML3) */\n        return 3;\n    }\n\n    /* Disable PAE and use PML2 by default */\n    return 2;\n}\n\n/**\n * Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    EFI_STATUS Status;\n\n    /* Exit EFI Boot Services */\n    XtLdrProtocol->Debug.Print(L\"Exiting EFI boot services\\n\");\n    Status = XtLdrProtocol->Utils.ExitBootServices();\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to exit boot services */\n        XtLdrProtocol->Debug.Print(L\"Failed to exit boot services (Status code: %zX)\\n\", Status);\n        return STATUS_EFI_ABORTED;\n    }\n\n    /* Disable paging */\n    XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) & ~CR0_PG);\n\n    /* Check the configured page map level to set the PAE state accordingly */\n    if(PageMap->PageMapLevel == 3)\n    {\n        /* Enable Physical Address Extension (PAE) */\n        XtLdrProtocol->Debug.Print(L\"Enabling Physical Address Extension (PAE)\\n\");\n        XtLdrProtocol->Cpu.WriteControlRegister(4, XtLdrProtocol->Cpu.ReadControlRegister(4) | CR4_PAE);\n    }\n    else\n    {\n        /* Disable Physical Address Extension (PAE) */\n        XtLdrProtocol->Debug.Print(L\"Disabling Physical Address Extension (PAE)\\n\");\n        XtLdrProtocol->Cpu.WriteControlRegister(4, XtLdrProtocol->Cpu.ReadControlRegister(4) & ~CR4_PAE);\n    }\n\n    /* Write page mappings to CR3 */\n    XtLdrProtocol->Cpu.WriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);\n\n    /* Enable paging */\n    XtLdrProtocol->Cpu.WriteControlRegister(0, XtLdrProtocol->Cpu.ReadControlRegister(0) | CR0_PG);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Maps the page table for hardware layer addess space.\n *\n * @param PageMap\n *        Supplies a pointer to the page mapping structure.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    EFI_PHYSICAL_ADDRESS Address;\n    PHARDWARE_LEGACY_PTE LegacyPdeBase;\n    PHARDWARE_MODERN_PTE PdeBase;\n    EFI_STATUS Status;\n\n    /* Allocate memory */\n    Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, 1, &Address);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, return error */\n        return Status;\n    }\n\n    /* Zero fill allocated memory */\n    XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);\n\n    /* Map hardware memory */\n    XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);\n\n    /* Check if PAE is enabled (3-level paging) */\n    if(PageMap->PageMapLevel == 3)\n    {\n        /* Get PDE base address (PAE enabled) */\n        PdeBase = (PHARDWARE_MODERN_PTE)(((PHARDWARE_MODERN_PTE)PageMap->PtePointer)[MM_HARDWARE_VA_START >> MM_PPI_SHIFT].PageFrameNumber << MM_PAGE_SHIFT);\n\n        /* Make PDE valid */\n        XtLdrProtocol->Memory.ZeroMemory(&PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF], sizeof(HARDWARE_MODERN_PTE));\n        PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].PageFrameNumber = Address >> MM_PAGE_SHIFT;\n        PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Valid = 1;\n        PdeBase[(MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF].Writable = 1;\n    }\n    else\n    {\n        /* Get PDE base address (PAE disabled) */\n        LegacyPdeBase = (PHARDWARE_LEGACY_PTE)PageMap->PtePointer;\n\n        /* Check for a conflicting PDE */\n        if(LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Valid)\n        {\n            /* PDE already exists and is valid, nothing to do */\n            return STATUS_EFI_SUCCESS;\n        }\n\n        /* Make PDE valid  */\n        XtLdrProtocol->Memory.ZeroMemory(&LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT], sizeof(HARDWARE_LEGACY_PTE));\n        LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Valid = 1;\n        LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].PageFrameNumber = Address >> MM_PAGE_SHIFT;\n        LegacyPdeBase[MM_HARDWARE_VA_START >> MM_PDI_LEGACY_SHIFT].Writable = 1;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n"
  },
  {
    "path": "boot/xtldr/modules/xtos_o/includes/xtos.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/xtos/includes/xtos.hh\n * DESCRIPTION:     XTOS boot protocol support header\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTLDR_MODULES_XTOS_HH\n#define __XTLDR_MODULES_XTOS_HH\n\n#include <xtblapi.h>\n\n\n/* XTOS kernel entry point */\ntypedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);\n\n/* XTOS trampoline entry point */\ntypedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap);\n\n\n/* XTOS module for XTLDR */\nclass Xtos\n{\n    private:\n        STATIC XTBL_BOOT_PROTOCOL BootProtocol;\n        STATIC PXTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoffProtocol;\n        STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;\n\n    public:\n        STATIC XTCDECL EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);\n        STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,\n                                                   IN PEFI_SYSTEM_TABLE SystemTable);\n\n    private:\n        STATIC XTCDECL EFI_STATUS AddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings,\n                                                          IN PVOID VirtualAddress,\n                                                          IN PVOID PhysicalAddress,\n                                                          IN UINT NumberOfPages,\n                                                          IN LOADER_MEMORY_TYPE MemoryType);\n        STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap);\n        STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);\n        STATIC XTCDECL BOOLEAN DetermineMappingStrategy();\n        STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);\n        STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);\n        STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,\n                                                  IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,\n                                                  IN PULONG_PTR FrameBufferSize,\n                                                  IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);\n        STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,\n                                                          IN EFI_PHYSICAL_ADDRESS PhysicalBase,\n                                                          IN PVOID VirtualBase,\n                                                          OUT PLIST_ENTRY MemoryDescriptorList);\n        STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,\n                                                         IN EFI_PHYSICAL_ADDRESS PhysicalBase,\n                                                         IN PVOID VirtualBase,\n                                                         IN PVOID FrameBufferVirtualBase,\n                                                         OUT PLIST_ENTRY SystemResourcesList);\n        STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,\n                                                    IN PVOID PhysicalAddress,\n                                                    OUT PVOID *VirtualAddress);\n        STATIC XTCDECL EFI_STATUS InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap);\n        STATIC XTCDECL EFI_STATUS InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,\n                                                        IN PVOID *VirtualAddress,\n                                                        IN PXTBL_BOOT_PARAMETERS Parameters);\n        STATIC XTCDECL EFI_STATUS InitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,\n                                                          IN OUT PVOID *MemoryMapAddress);\n        STATIC XTCDECL EFI_STATUS LoadModule(IN PEFI_FILE_HANDLE BootDir,\n                                             IN PWCHAR FileName,\n                                             IN PVOID VirtualAddress,\n                                             IN LOADER_MEMORY_TYPE MemoryType,\n                                             OUT PPECOFF_IMAGE_CONTEXT *ImageContext);\n        STATIC XTCDECL EFI_STATUS MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap);\n        STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN PLIST_ENTRY MemoryMappings,\n                                                   IN UINT_PTR VirtualAddress,\n                                                   IN UINT_PTR PhysicalAddress,\n                                                   IN UINT NumberOfPages,\n                                                   IN OUT PVOID *PtePointer);\n        STATIC XTCDECL EFI_STATUS RunBootSequence(IN PEFI_FILE_HANDLE BootDir,\n                                                  IN PXTBL_BOOT_PARAMETERS Parameters);\n};\n\n#endif /* __XTLDR_MODULES_XTOS_HH */\n"
  },
  {
    "path": "boot/xtldr/modules/xtos_o/xtos.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/modules/xtos/xtos.cc\n * DESCRIPTION:     XTOS boot protocol support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* XTOS module information */\nMODULE_AUTHOR(L\"Rafal Kupiec <belliash@codingworkshop.eu.org>\");\nMODULE_DESCRIPTION(L\"XTOS boot protocol support\");\nMODULE_DEPENDENCY(L\"acpi framebuf pecoff\");\nMODULE_LICENSE(L\"GPLv3\");\nMODULE_VERSION(L\"0.1\");\n\n\n/**\n * Starts the operating system according to the provided parameters using XTOS boot protocol.\n *\n * @param Parameters\n *        Input parameters with detailed system configuration like boot device or kernel path.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)\n{\n    EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID;\n    EFI_HANDLE DiskHandle, ProtocolHandle;\n    PEFI_FILE_HANDLE FsHandle, BootDir;\n    PWCHAR SystemPath;\n    EFI_STATUS Status;\n\n    /* Print debug message */\n    XtLdrProtocol->Debug.Print(L\"XTOS boot protocol activated\\n\");\n\n    /* Open the XT PE/COFF protocol */\n    Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&PeCoffProtocol, &PeCoffProtocolGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open loader protocol */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Unable to load PE/COFF image protocol\\n\");\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Check device path */\n    if(Parameters->DevicePath == NULLPTR)\n    {\n        /* No device path set */\n        XtLdrProtocol->Debug.Print(L\"ERROR: No device path provided, unable to boot system\\n\");\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Check if system path is set */\n    if(Parameters->SystemPath != NULLPTR)\n    {\n        /* Make sure system path begins with backslash, the only separator supported by EFI */\n        if(Parameters->SystemPath[0] == '/')\n        {\n            /* Replace directory separator if needed */\n            Parameters->SystemPath[0] = '\\\\';\n        }\n\n        /* Validate system path */\n        SystemPath = &Parameters->SystemPath[1];\n        while(*SystemPath)\n        {\n            /* Make sure it does not point to any subdirectory and not contains special characters */\n            if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10))\n            {\n                /* Invalid path specified */\n                XtLdrProtocol->Debug.Print(L\"ERROR: System path does not point to the valid XTOS installation\\n\");\n                return STATUS_EFI_INVALID_PARAMETER;\n            }\n            /* Check next character in the path */\n            SystemPath++;\n        }\n    }\n    else\n    {\n        /* Fallback to '/ExectOS' by default */\n        XtLdrProtocol->Debug.Print(L\"WARNING: No system path set, falling back to defaults\\n\");\n        Parameters->SystemPath = (PWCHAR)L\"\\\\ExectOS\";\n    }\n\n    /* Check if kernel file is set */\n    if(Parameters->KernelFile == NULLPTR)\n    {\n        /* No kernel filename set, fallback to default */\n        XtLdrProtocol->Debug.Print(L\"WARNING: No kernel file specified, falling back to defaults\\n\");\n        Parameters->KernelFile = (PWCHAR)L\"xtoskrnl.exe\";\n    }\n\n    /* Check if provided any kernel boot arguments */\n    if(Parameters->Parameters == NULLPTR)\n    {\n        /* No argument supplied */\n        Parameters->Parameters = (PWCHAR)L\"\";\n    }\n\n    /* Print a debug message */\n    XtLdrProtocol->Debug.Print(L\"[XTOS] ARC Path: %S\\n\"\n                               L\"[XTOS] System Path: %S\\n\"\n                               L\"[XTOS] Kernel File: %S\\n\"\n                               L\"[XTOS] Boot Arguments: %S\\n\",\n                               Parameters->ArcName, Parameters->SystemPath,\n                               Parameters->KernelFile, Parameters->Parameters);\n\n    /* Open EFI volume */\n    Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open a volume */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Unable to open boot volume\\n\");\n        return Status;\n    }\n\n    /* System path has to point to the boot directory */\n    XtLdrProtocol->WideString.Concatenate(Parameters->SystemPath, (PWCHAR)L\"\\\\Boot\", 0);\n\n    /* Open XTOS system boot directory */\n    Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0);\n    FsHandle->Close(FsHandle);\n\n    /* Check if system path directory opened successfully */\n    if(Status == STATUS_EFI_NOT_FOUND)\n    {\n        /* Directory not found, nothing to load */\n        XtLdrProtocol->Debug.Print(L\"ERROR: System boot directory not found\\n\");\n\n        /* Close volume */\n        XtLdrProtocol->Disk.CloseVolume(&DiskHandle);\n        return Status;\n    }\n    else if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open directory */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Unable to open system boot directory\\n\");\n        XtLdrProtocol->Disk.CloseVolume(&DiskHandle);\n        return Status;\n    }\n\n    /* Start boot sequence */\n    return RunBootSequence(BootDir, Parameters);\n}\n\n/**\n * Returns information about frame buffer in XTOS compatible format.\n *\n * @param InformationBlock\n *        A pointer to memory area containing XT structure where all the information will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nXtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,\n                            IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,\n                            IN PULONG_PTR FrameBufferSize,\n                            IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo)\n{\n    /* Fill in frame buffer resource */\n    FrameBufferResource->Header.PhysicalAddress = (PVOID)*FrameBufferBase;\n    FrameBufferResource->Header.ResourceType = SystemResourceFrameBuffer;\n    FrameBufferResource->Header.ResourceSize = sizeof(SYSTEM_RESOURCE_FRAMEBUFFER);\n    FrameBufferResource->BufferSize = *FrameBufferSize;\n    FrameBufferResource->Width = FrameBufferModeInfo->Width;\n    FrameBufferResource->Height = FrameBufferModeInfo->Height;\n    FrameBufferResource->Depth = FrameBufferModeInfo->Depth;\n    FrameBufferResource->BitsPerPixel = FrameBufferModeInfo->BitsPerPixel;\n    FrameBufferResource->PixelsPerScanLine = FrameBufferModeInfo->PixelsPerScanLine;\n    FrameBufferResource->Pitch = FrameBufferModeInfo->Pitch;\n    FrameBufferResource->Pixels.BlueShift = FrameBufferModeInfo->PixelInformation.BlueShift;\n    FrameBufferResource->Pixels.BlueSize = FrameBufferModeInfo->PixelInformation.BlueSize;\n    FrameBufferResource->Pixels.GreenShift = FrameBufferModeInfo->PixelInformation.GreenShift;\n    FrameBufferResource->Pixels.GreenSize = FrameBufferModeInfo->PixelInformation.GreenSize;\n    FrameBufferResource->Pixels.RedShift = FrameBufferModeInfo->PixelInformation.RedShift;\n    FrameBufferResource->Pixels.RedSize = FrameBufferModeInfo->PixelInformation.RedSize;\n    FrameBufferResource->Pixels.ReservedShift = FrameBufferModeInfo->PixelInformation.ReservedShift;\n    FrameBufferResource->Pixels.ReservedSize = FrameBufferModeInfo->PixelInformation.ReservedSize;\n}\n\nXTCDECL\nEFI_STATUS\nXtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,\n                              IN EFI_PHYSICAL_ADDRESS PhysicalBase,\n                              IN PVOID VirtualBase,\n                              OUT PLIST_ENTRY MemoryDescriptorList)\n{\n    PLOADER_MEMORY_DESCRIPTOR Descriptor;\n    PXTBL_MEMORY_MAPPING MemoryMapping;\n    PLIST_ENTRY ListEntry;\n\n    /* Initialize the descriptor pointer to the start of the allocated physical buffer */\n    Descriptor = (PLOADER_MEMORY_DESCRIPTOR)PhysicalBase;\n\n    /* Get the first entry from the internal boot loader memory map */\n    ListEntry = PageMap->MemoryMap.Flink;\n\n    /* Iterate through the internal memory map and populate the loader descriptor list */\n    while(ListEntry != &PageMap->MemoryMap)\n    {\n        /* Retrieve the internal memory mapping record from the current list entry */\n        MemoryMapping = CONTAIN_RECORD(ListEntry, XTBL_MEMORY_MAPPING, ListEntry);\n\n        /* Transfer memory type and address information to the kernel descriptor */\n        Descriptor->MemoryType = MemoryMapping->MemoryType;\n        Descriptor->BasePage = (UINT_PTR)(MemoryMapping->PhysicalAddress / EFI_PAGE_SIZE);\n        Descriptor->PageCount = (ULONG)MemoryMapping->NumberOfPages;\n\n        /* Link the entry */\n        XtLdrProtocol->LinkedList.InsertTail(MemoryDescriptorList, &Descriptor->ListEntry);\n\n        /* Move to the next slot in the allocated buffer */\n        Descriptor++;\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Convert all physical link pointers in the list to their corresponding virtual addresses */\n    XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)PhysicalBase, VirtualBase);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\nXTCDECL\nEFI_STATUS\nXtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,\n                             IN EFI_PHYSICAL_ADDRESS PhysicalBase,\n                             IN PVOID VirtualBase,\n                             IN PVOID FrameBufferVirtualBase,\n                             OUT PLIST_ENTRY SystemResourcesList)\n{\n    XTSTATUS Status;\n    EFI_HANDLE ProtocolHandle;\n    EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID;\n    EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;\n    PXTBL_ACPI_PROTOCOL AcpiProtocol;\n    PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;\n    XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;\n    EFI_PHYSICAL_ADDRESS FbAddress;\n    EFI_PHYSICAL_ADDRESS OriginalPhysicalBase;\n    ULONG_PTR FbSize;\n    PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;\n    PSYSTEM_RESOURCE_ACPI AcpiResource;\n\n    /* Save original physical base */\n    OriginalPhysicalBase = PhysicalBase;\n\n    AcpiResource = (PSYSTEM_RESOURCE_ACPI)PhysicalBase;\n    XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));\n\n    /* Load ACPI protocol */\n    Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        return Status;\n    }\n\n    AcpiResource->Header.ResourceType = SystemResourceAcpi;\n    AcpiResource->Header.ResourceSize = sizeof(SYSTEM_RESOURCE_ACPI);\n\n    /* Get APIC and XSDP/RSDP addresses */\n    AcpiProtocol->GetApicBase(&AcpiResource->ApicBase);\n    AcpiProtocol->GetAcpiDescriptionPointer(&AcpiResource->Header.PhysicalAddress);\n\n    /* No need to map ACPI */\n    AcpiResource->Header.VirtualAddress = 0;\n\n    XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);\n\n    /* Close ACPI protocol */\n    XtLdrProtocol->Protocol.Close(&ProtocolHandle, &AcpiGuid);\n\n    PhysicalBase = PhysicalBase + sizeof(SYSTEM_RESOURCE_ACPI);\n    FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)PhysicalBase;\n    XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));\n\n    /* Load FrameBuffer protocol */\n    Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);\n    if(Status == STATUS_EFI_SUCCESS)\n    {\n        /* Get FrameBuffer information */\n        Status = FrameBufProtocol->GetDisplayInformation(&FbAddress, &FbSize, &FbModeInfo);\n        if(Status == STATUS_EFI_SUCCESS)\n        {\n\n            /* Store information about FrameBuffer device */\n            GetDisplayInformation(FrameBufferResource, &FbAddress, &FbSize, &FbModeInfo);\n        }\n    }\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        return Status;\n    }\n\n    /* Assign the pre-mapped virtual address to the resource block */\n    FrameBufferResource->Header.VirtualAddress = FrameBufferVirtualBase;\n    XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);\n\n    XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);\n\n    /* Convert list pointers to virtual */\n    XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, (PVOID)OriginalPhysicalBase, VirtualBase);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Checks if APIC is present in the system and finds its base address.\n *\n * @param MemoryMappings\n *        Supplies a pointer to linked list containing all memory mappings.\n *\n * @return This routine returns an EFI status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)\n{\n    EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID;\n    PXTBL_ACPI_PROTOCOL AcpiProtocol;\n    EFI_HANDLE ProtocolHandle;\n    PVOID ApicBaseAddress;\n    EFI_STATUS Status;\n\n    /* Open ACPI protocol */\n    Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* ACPI protocol not found */\n        return Status;\n    }\n\n    /* Get APIC base address */\n    Status = AcpiProtocol->GetApicBase(&ApicBaseAddress);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get APIC base address */\n        return Status;\n    }\n\n    /* Map APIC base address */\n    XtLdrProtocol->Memory.MapVirtualMemory(PageMap, APIC_BASE, (ULONGLONG)ApicBaseAddress, 1, LoaderFirmwarePermanent);\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Initializes and maps the kernel initialization block.\n *\n * @param MemoryMappings\n *        Supplies a pointer to linked list containing all memory mappings.\n *\n * @param VirtualAddress\n *        Supplies a pointer to the next valid, free and available virtual address.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,\n                            IN OUT PVOID *VirtualAddress,\n                            IN PXTBL_BOOT_PARAMETERS Parameters)\n{\n    EFI_PHYSICAL_ADDRESS FbPhysicalAddress, PhysicalBlock, PhysicalDescriptor, PhysicalResources;\n    PVOID FbVirtualAddress, VirtualBlock, VirtualResources, VirtualDescriptor;\n    UINT BlockPages, DescriptorPages, FbPages, ParametersSize, ResourcesPages;\n    XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;\n    PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;\n    PKERNEL_INITIALIZATION_BLOCK LoaderBlock;\n    EFI_HANDLE ProtocolHandle;\n    EFI_STATUS Status;\n    ULONG_PTR FbSize;\n\n    EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;\n\n    /* Initialize Framebuffer information */\n    FbPhysicalAddress = 0;\n    FbSize = 0;\n    FbVirtualAddress = NULLPTR;\n    FbPages = 0;\n\n    /* Calculate size of parameters */\n    ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);\n\n    /* Calculate number of pages needed for initialization block */\n    BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);\n    ResourcesPages = EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));\n\n    /* Query Framebuffer size for allocation */\n    if(XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid) == STATUS_EFI_SUCCESS)\n    {\n        /* Get FrameBuffer information */\n        FrameBufProtocol->GetDisplayInformation(&FbPhysicalAddress, &FbSize, &FbModeInfo);\n        XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);\n    }\n    FbPages = EFI_SIZE_TO_PAGES(FbSize);\n\n    /* Precommit page map to allocate memory */\n    XtLdrProtocol->Memory.CommitPageMap(PageMap);\n\n    /* Calculate number of pages needed for memory descriptor list */\n    DescriptorPages = EFI_SIZE_TO_PAGES(PageMap->MapSize * sizeof(LOADER_MEMORY_DESCRIPTOR) * 2);\n\n    /* Allocate memory for the kernel initialization block and boot parameters */\n    Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &PhysicalBlock);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, return status code */\n        return Status;\n    }\n\n    /* Allocate memory for the system resources data structures */\n    Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ResourcesPages, &PhysicalResources);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, return status code */\n        return Status;\n    }\n\n    /* Allocate memory for the memory descriptor list */\n    Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, DescriptorPages, &PhysicalDescriptor);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, return status code */\n        return Status;\n    }\n\n    /* Map the Kernel Initialization Block into virtual memory and advance the virtual address pointer */\n    VirtualBlock = *VirtualAddress;\n    XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualBlock, PhysicalBlock, BlockPages, LoaderSystemBlock);\n    *VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);\n\n    /* Map the system resources physical memory into virtual address space and update the allocation pointer */\n    VirtualResources = *VirtualAddress;\n    XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualResources, PhysicalResources, ResourcesPages, LoaderFirmwarePermanent);\n    *VirtualAddress = (PUINT8)*VirtualAddress + (ResourcesPages * EFI_PAGE_SIZE);\n\n    /* Check if a framebuffer was detected and requires memory mapping */\n    if(FbPages > 0)\n    {\n        /* Map the framebuffer physical memory range into virtual address space */\n        FbVirtualAddress = *VirtualAddress;\n        XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FbVirtualAddress, FbPhysicalAddress, FbPages, LoaderFirmwarePermanent);\n        *VirtualAddress = (PUINT8)*VirtualAddress + (FbPages * EFI_PAGE_SIZE);\n    }\n\n    /* Map the allocated physical memory for memory descriptors into the virtual address space */\n    VirtualDescriptor = *VirtualAddress;\n    XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualDescriptor, PhysicalDescriptor, DescriptorPages, LoaderMemoryData);\n    *VirtualAddress = (PUINT8)*VirtualAddress + (DescriptorPages * EFI_PAGE_SIZE);\n\n    /* Set basic loader block properties */\n    XtLdrProtocol->Memory.ZeroMemory((PVOID)PhysicalBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);\n    LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)PhysicalBlock;\n    LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);\n    LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;\n    LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;\n\n    /* Set LoaderInformation block properties */\n    LoaderBlock->LoaderInformation.DbgPrint = (PVOID)XtLdrProtocol->Debug.Print;\n\n    /* Set FirmwareInformation block properties */\n    LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi;\n    // LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = EfiSystemTable->Hdr.Revision;\n    LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;\n\n    /* Copy parameters to kernel initialization block */\n    LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)VirtualBlock + sizeof(KERNEL_INITIALIZATION_BLOCK));\n    XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),\n                                     Parameters->Parameters, ParametersSize);\n\n    /* Commit mappings */\n    XtLdrProtocol->Memory.CommitPageMap(PageMap);\n\n    /* Initialize system resources list */\n    XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);\n    Status = GetSystemResourcesList(PageMap, PhysicalResources, VirtualResources, FbVirtualAddress, &LoaderBlock->SystemResourcesListHead);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to initialize system resources list, return status code */\n        return Status;\n    }\n\n    /* Initialize memory descriptor list */\n    XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);\n    Status = GetMemoryDescriptorList(PageMap, PhysicalDescriptor, VirtualDescriptor, &LoaderBlock->MemoryDescriptorListHead);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to initialize memory descriptor list, return status code */\n        return Status;\n    }\n\n    /* Set boot image size */\n    LoaderBlock->BootImageSize = (PFN_NUMBER)(((ULONGLONG)*VirtualAddress - KSEG0_BASE) / EFI_PAGE_SIZE);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\nXTCDECL\nEFI_STATUS\nXtos::InitializeModule(IN EFI_HANDLE ImageHandle,\n                       IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID;\n    EFI_STATUS Status;\n\n    /* Open the XTLDR protocol */\n    Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open loader protocol */\n        return STATUS_EFI_PROTOCOL_ERROR;\n    }\n\n    /* Set routines available via XTOS boot protocol */\n    BootProtocol.BootSystem = Xtos::BootSystem;\n\n    /* Register XTOS boot protocol */\n    XtLdrProtocol->Boot.RegisterProtocol(L\"XTOS\", &Guid);\n\n    /* Install XTOS protocol */\n    return XtLdrProtocol->Protocol.Install(&BootProtocol, &Guid);\n}\n\n/**\n * Loads XTOS PE/COFF module.\n *\n * @param SystemDir\n *        An EFI handle to the opened system directory containing a module that will be loaded.\n *\n * @param FileName\n *        An on disk filename of the module that will be loaded.\n *\n * @param VirtualAddress\n *        Optional virtual address pointing to the memory area where PE/COFF file will be loaded.\n *\n * @param MemoryType\n *        Supplies the type of memory to be assigned to the memory descriptor.\n *\n * @param ImageContext\n *        Supplies pointer to the memory area where loaded PE/COFF image context will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::LoadModule(IN PEFI_FILE_HANDLE SystemDir,\n                 IN PWCHAR FileName,\n                 IN PVOID VirtualAddress,\n                 IN LOADER_MEMORY_TYPE MemoryType,\n                 OUT PPECOFF_IMAGE_CONTEXT *ImageContext)\n{\n    PEFI_FILE_HANDLE ModuleHandle;\n    USHORT MachineType, SubSystem;\n    EFI_STATUS Status;\n\n    /* Print debug message */\n    XtLdrProtocol->Debug.Print(L\"Loading %S ... \\n\", FileName);\n\n    /* Open module file */\n    Status = SystemDir->Open(SystemDir, &ModuleHandle, FileName, EFI_FILE_MODE_READ, 0);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Unable to open the file */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Failed to open '%S'\\n\", FileName);\n        return Status;\n    }\n\n    /* Load the PE/COFF image file */\n    Status = PeCoffProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID*)ImageContext);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Unable to load the file */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Failed to load '%S'\\n\", FileName);\n        return Status;\n    }\n\n    /* Close image file */\n    ModuleHandle->Close(ModuleHandle);\n\n    /* Check PE/COFF image machine type compatibility */\n    PeCoffProtocol->GetMachineType(*ImageContext, &MachineType);\n    if(MachineType != _ARCH_IMAGE_MACHINE_TYPE)\n    {\n        /* Machine type mismatch */\n        XtLdrProtocol->Debug.Print(L\"ERROR: Loaded incompatible PE/COFF image (machine type mismatch)\\n\");\n        return STATUS_EFI_INCOMPATIBLE_VERSION;\n    }\n\n    /* Check PE/COFF image subsystem */\n    PeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem);\n    if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL &&\n       SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION &&\n       SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER)\n    {\n        XtLdrProtocol->Debug.Print(L\"WARNING: Loaded PE/COFF image with non-XT subsystem set\\n\");\n    }\n\n    /* Print debug message */\n    XtLdrProtocol->Debug.Print(L\"Loaded %S at PA: %P, VA: %P\\n\", FileName,\n                               (*ImageContext)->PhysicalAddress, (*ImageContext)->VirtualAddress);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine initiates an XTOS boot sequence.\n *\n * @param BootDir\n *        An EFI handle to the XTOS boot directory.\n *\n * @param Parameters\n *        Input parameters with detailed system configuration like boot device or kernel path.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,\n                      IN PXTBL_BOOT_PARAMETERS Parameters)\n{\n    EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;\n    EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;\n    PKERNEL_INITIALIZATION_BLOCK KernelParameters;\n    PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;\n    PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;\n    PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;\n    PVOID VirtualAddress;\n    PXT_ENTRY_POINT KernelEntryPoint;\n    EFI_HANDLE ProtocolHandle;\n    EFI_STATUS Status;\n    XTBL_PAGE_MAPPING PageMap;\n    BOOLEAN IdentityMapping;\n\n    /* Initialize XTOS startup sequence */\n    XtLdrProtocol->Debug.Print(L\"Initializing XTOS startup sequence\\n\");\n\n    /* Load FrameBuffer protocol */\n    Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);\n    if(Status == STATUS_EFI_SUCCESS)\n    {\n        /* Make sure FrameBuffer is initialized */\n        FrameBufProtocol->Initialize();\n        FrameBufProtocol->SetScreenResolution(0, 0);\n    }\n\n    /* Close FrameBuffer protocol */\n    XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);\n\n    /* Determine whether to use a sequential or an identity mapping strategy */\n    IdentityMapping = DetermineMappingStrategy();\n\n    /* Set base virtual memory area for the kernel mappings */\n    VirtualAddress = (PVOID)(KSEG0_BASE);\n\n    /* Initialize virtual memory mappings */\n    XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);\n\n    /* Map all EFI memory regions */\n    Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualAddress, IdentityMapping, NULLPTR);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Mapping failed */\n        return Status;\n    }\n\n    /* Check mapping strategy */\n    if(IdentityMapping)\n    {\n        /* Adjust virtual address to skip the identity-mapped physical range */\n        VirtualAddress = (PVOID)((ULONGLONG)VirtualAddress + 0x800000000);\n    }\n\n    /* Load the kernel */\n    Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to load the kernel */\n        return Status;\n    }\n\n    /* Add kernel image memory mapping */\n    Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, (ULONGLONG)ImageContext->VirtualAddress,\n                                                    (ULONGLONG)ImageContext->PhysicalAddress, ImageContext->ImagePages,\n                                                    LoaderSystemCode);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        return Status;\n    }\n\n    /* Set next valid virtual address right after the kernel */\n    VirtualAddress = (PUINT8)VirtualAddress + (ImageContext->ImagePages * EFI_PAGE_SIZE);\n\n    /* Find and map APIC base address */\n    Status = InitializeApicBase(&PageMap);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to setup kernel initialization block */\n        XtLdrProtocol->Debug.Print(L\"Failed to initialize APIC (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Build page map */\n    Status = BuildPageMap(&PageMap);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        XtLdrProtocol->Debug.Print(L\"Failed to build page map (Status code: %zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Store virtual address of kernel initialization block for future kernel call */\n    KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;\n\n    /* Setup and map kernel initialization block */\n    Status = InitializeLoaderBlock(&PageMap, &VirtualAddress, Parameters);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to setup kernel initialization block */\n        XtLdrProtocol->Debug.Print(L\"Failed to setup kernel initialization block (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Get kernel entry point */\n    PeCoffProtocol->GetEntryPoint(ImageContext, (PVOID*)&KernelEntryPoint);\n\n    /* Close boot directory handle */\n    BootDir->Close(BootDir);\n\n    /* Enable paging */\n    XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid);\n    Status = EnablePaging(&PageMap);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to enable paging */\n        XtLdrProtocol->Debug.Print(L\"Failed to enable paging (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Call XTOS kernel */\n    XtLdrProtocol->Debug.Print(L\"Booting the XTOS kernel\\n\");\n    KernelEntryPoint(KernelParameters);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine is the entry point of the XT EFI boot loader module.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nXtLdrModuleMain(IN EFI_HANDLE ImageHandle,\n                IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    /* Initialize XTOS module */\n    return Xtos::InitializeModule(ImageHandle, SystemTable);\n}\n"
  },
  {
    "path": "boot/xtldr/protocol.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/protocol.cc\n * DESCRIPTION:     XT Boot Loader protocol support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Closes a protocol on a provided handle.\n *\n * @param Handle\n *        Supplies a handle for the protocol interface that was previously opened.\n *\n * @param ProtocolGuid\n *        Supplies a unique protocol GUID.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::CloseProtocol(IN PEFI_HANDLE Handle,\n                        IN PEFI_GUID ProtocolGuid)\n{\n    return XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handle, ProtocolGuid,\n                                                                      XtLoader::GetEfiImageHandle(), NULLPTR);\n}\n\n/**\n * Finds a boot protocol for specified system type.\n *\n * @param SystemType\n *        Specifies the system type to search for.\n *\n * @param BootProtocolGuid\n *        Receives the GUID of the registered boot protocol, that supports specified system.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::FindBootProtocol(IN PCWSTR SystemType,\n                           OUT PEFI_GUID BootProtocolGuid)\n{\n    PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry;\n    PLIST_ENTRY ProtocolListEntry;\n\n    ProtocolListEntry = BootProtocols.Flink;\n    while(ProtocolListEntry != &BootProtocols)\n    {\n        /* Get boot protocol entry */\n        ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink);\n\n        /* Check if this boot protocol supports specified system */\n        if(RTL::WideString::CompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0)\n        {\n            /* Boot protocol matched, return success */\n            *BootProtocolGuid = ProtocolEntry->Guid;\n            return STATUS_EFI_SUCCESS;\n        }\n\n        /* Move to the next registered boot protocol */\n        ProtocolListEntry = ProtocolListEntry->Flink;\n    }\n\n    /* Boot protocol not found, return error */\n    return STATUS_EFI_NOT_FOUND;\n}\n\n/**\n * Returns a linked list of all loaded modules.\n *\n * @return This routine returns a pointer to a linked list of all loaded modules.\n *\n * @since XT 1.0\n *\n * @todo This is a temporary solution and it should be replaced by a complex API allowing to map modules.\n */\nXTCDECL\nPLIST_ENTRY\nProtocol::GetModulesList()\n{\n    /* Return a pointer to a list of all loaded modules */\n    return &LoadedModules;\n}\n\nXTCDECL\nVOID\nProtocol::InitializeProtocol()\n{\n    /* Initialize list of loaded modules and boot protocols */\n    RTL::LinkedList::InitializeListHead(&BootProtocols);\n    RTL::LinkedList::InitializeListHead(&LoadedModules);\n}\n\n/**\n * Installs XTLDR protocol interface.\n *\n * @param Guid\n *        Specifies a unique protocol GUID.\n *\n * @param Interface\n *        Supplies a pointer to the protocol interface, or NULLPTR if there is no structure associated.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::InstallProtocol(IN PVOID Interface,\n                          IN PEFI_GUID Guid)\n{\n    EFI_HANDLE Handle = NULLPTR;\n\n    /* Install protocol interface */\n    return XtLoader::GetEfiSystemTable()->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE,\n                                                                                 Interface);\n}\n\n/**\n * Loads all necessary modules and invokes boot protocol.\n *\n * @param ShortName\n *        Supplies a pointer to a short name of the chosen boot menu entry.\n *\n * @param OptionsList\n *        Supplies a pointer to list of options associated with chosen boot menu entry.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::InvokeBootProtocol(IN PWCHAR ShortName,\n                             IN PLIST_ENTRY OptionsList)\n{\n    EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID;\n    XTBL_BOOT_PARAMETERS BootParameters;\n    PXTBL_BOOT_PROTOCOL BootProtocol;\n    PLIST_ENTRY OptionsListEntry;\n    PXTBL_CONFIG_ENTRY Option;\n    EFI_GUID BootProtocolGuid;\n    SIZE_T ModuleListLength;\n    PWCHAR ModulesList;\n    EFI_HANDLE Handle;\n    EFI_STATUS Status;\n\n    /* Initialize boot parameters and a list of modules */\n    RTL::Memory::ZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS));\n    ModulesList = NULLPTR;\n\n    /* Iterate through all options provided by boot menu entry and propagate boot parameters */\n    OptionsListEntry = OptionsList->Flink;\n    while(OptionsListEntry != OptionsList)\n    {\n        /* Get option */\n        Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink);\n\n        /* Look for boot protocol and modules list */\n        if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L\"BOOTMODULES\", 0) == 0)\n        {\n            /* Check a length of modules list */\n            ModuleListLength = RTL::WideString::WideStringLength(Option->Value, 0);\n\n            Status = Memory::AllocatePool(sizeof(WCHAR) * (ModuleListLength + 1), (PVOID *)&ModulesList);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to allocate memory, print error message and return status code */\n                Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n                return STATUS_EFI_OUT_OF_RESOURCES;\n            }\n\n            /* Make a copy of modules list */\n            RTL::Memory::CopyMemory(ModulesList, Option->Value, sizeof(WCHAR) * (ModuleListLength + 1));\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L\"SYSTEMTYPE\", 0) == 0)\n        {\n            /* Boot protocol found */\n            BootParameters.SystemType = Option->Value;\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L\"SYSTEMPATH\", 0) == 0)\n        {\n            /* System path found, get volume device path */\n            Status = Volume::GetDevicePath(Option->Value, &BootParameters.DevicePath,\n                                           &BootParameters.ArcName, &BootParameters.SystemPath);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to find volume */\n                Debug::Print(L\"ERROR: Failed to find volume device path (Status Code: 0x%zX)\\n\", Status);\n                return Status;\n            }\n\n            /* Get EFI compatible system path */\n            Status = Volume::GetEfiPath(BootParameters.SystemPath, &BootParameters.EfiPath);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to get EFI path */\n                Debug::Print(L\"ERROR: Failed to get EFI path (Status Code: 0x%zX)\\n\", Status);\n                return Status;\n            }\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L\"KERNELFILE\", 0) == 0)\n        {\n            /* Kernel file name found */\n            BootParameters.KernelFile = Option->Value;\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L\"INITRDFILE\", 0) == 0)\n        {\n            /* Initrd file name found */\n            BootParameters.InitrdFile = Option->Value;\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L\"HALFILE\", 0) == 0)\n        {\n            /* Hal file name found */\n            BootParameters.HalFile = Option->Value;\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L\"PARAMETERS\", 0) == 0)\n        {\n            /* Kernel parameters found */\n            BootParameters.Parameters = Option->Value;\n        }\n\n        /* Move to the next option entry */\n        OptionsListEntry = OptionsListEntry->Flink;\n    }\n\n    /* Load all necessary modules */\n    Status = LoadModules(ModulesList);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to load modules, print error message and return status code */\n        Debug::Print(L\"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\\n\", Status);\n        return STATUS_EFI_NOT_READY;\n    }\n\n    /* Attempt to get boot protocol GUID */\n    Status = FindBootProtocol(BootParameters.SystemType, &BootProtocolGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get boot protocol GUID */\n        Debug::Print(L\"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%zX)\\n\", Status);\n        return STATUS_EFI_UNSUPPORTED;\n    }\n\n    /* Open boot protocol */\n    Status = OpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open boot protocol */\n        Debug::Print(L\"ERROR: Failed to open boot protocol (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Check if chosen operating system should be saved */\n    if(Configuration::GetBooleanValue(L\"KEEPLASTBOOT\"))\n    {\n        /* Save chosen operating system in NVRAM */\n        Status = EfiUtils::SetEfiVariable(&VendorGuid, L\"XtLdrLastBootOS\", (PVOID)ShortName, RTL::WideString::WideStringLength(ShortName, 0) * sizeof(WCHAR));\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to save chosen Operating System */\n            Debug::Print(L\"WARNING: Failed to save chosen Operating System in NVRAM (Status Code: 0x%zX)\\n\", Status);\n        }\n    }\n\n    /* Boot Operating System */\n    return BootProtocol->BootSystem(&BootParameters);\n}\n\n/**\n * Loads a specified XTLDR module from disk.\n *\n * @param ModuleName\n *        Specifies the name of the module to load.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::LoadModule(IN PWCHAR ModuleName)\n{\n    EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;\n    PLIST_ENTRY DepsListEntry, ModuleListEntry;\n    EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];\n    PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;\n    PEFI_FILE_HANDLE DirHandle, FsHandle;\n    EFI_HANDLE DiskHandle, ModuleHandle;\n    PPECOFF_IMAGE_SECTION_HEADER SectionHeader;\n    PPECOFF_IMAGE_DOS_HEADER DosHeader;\n    PPECOFF_IMAGE_PE_HEADER PeHeader;\n    PXTBL_MODULE_DEPS ModuleDependency;\n    PXTBL_MODULE_INFO ModuleInfo;\n    WCHAR ModuleFileName[24];\n    ULONG ModuleNameLength;\n    USHORT SectionIndex;\n    PWCHAR SectionData;\n    SIZE_T ModuleSize;\n    EFI_STATUS Status;\n    PVOID ModuleData;\n\n    ModuleListEntry = LoadedModules.Flink;\n    while(ModuleListEntry != &LoadedModules)\n    {\n        /* Get module information */\n        ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink);\n\n        if(RTL::WideString::CompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)\n        {\n            /* Module already loaded */\n            Debug::Print(L\"WARNING: Module '%S' already loaded!\\n\", ModuleName);\n            return STATUS_EFI_SUCCESS;\n        }\n\n        /* Move to next module */\n        ModuleListEntry = ModuleListEntry->Flink;\n    }\n\n    /* Print debug message */\n    Debug::Print(L\"Loading module '%S' ...\\n\", ModuleName);\n\n    /* Calculate module name length */\n    ModuleNameLength = RTL::WideString::WideStringLength(ModuleName, 0) + 1;\n\n    /* Set module path */\n    RTL::Memory::CopyMemory(ModuleFileName, ModuleName, ModuleNameLength * sizeof(WCHAR));\n    RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L\".EFI\", 0);\n\n    /* Open EFI volume */\n    Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open a volume */\n        return Status;\n    }\n\n    /* Open XTLDR modules common directory */\n    Status = FsHandle->Open(FsHandle, &DirHandle, (PWCHAR)XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Modules directory not found, attempt to open XTLDR architecture specific modules directory */\n        Status = FsHandle->Open(FsHandle, &DirHandle, (PWCHAR)XTBL_ARCH_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0);\n    }\n\n    /* Close FS handle */\n    FsHandle->Close(FsHandle);\n\n    /* Check if modules directory opened successfully */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open directory */\n        Volume::CloseVolume(&DiskHandle);\n        return Status;\n    }\n\n    /* Read module file from disk and close directory and EFI volume */\n    Status = Volume::ReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize);\n    DirHandle->Close(DirHandle);\n    Volume::CloseVolume(&DiskHandle);\n\n    /* Make sure module file was read successfully */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to read file */\n        return Status;\n    }\n\n    /* Allocate memory for module information block */\n    Status = Memory::AllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to allocate memory */\n        return Status;\n    }\n\n    /* Zero module information block */\n    RTL::Memory::ZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));\n\n    /* Setup PE/COFF EFI image headers */\n    DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData;\n    PeHeader = (PPECOFF_IMAGE_PE_HEADER)((PUCHAR)ModuleData + DosHeader->PeHeaderOffset);\n\n    /* Check PE/COFF image type*/\n    if(PeHeader->OptionalHeader32.Magic == PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)\n    {\n        /* Get PE32+ (64-bit) image section headers */\n        SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader64 +\n                                                       PeHeader->FileHeader.SizeOfOptionalHeader);\n    }\n    else\n    {\n        /* Get PE32 (32-bit) image section headers */\n        SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader32 +\n                                                       PeHeader->FileHeader.SizeOfOptionalHeader);\n    }\n\n    /* Look for .modinfo section */\n    for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)\n    {\n        if(RTL::String::CompareString((PCHAR)SectionHeader[SectionIndex].Name, \".modinfo\", 8) == 0)\n        {\n            /* Module information section found */\n            SectionData = (PWCHAR)((PUCHAR)ModuleData + SectionHeader[SectionIndex].PointerToRawData);\n\n            /* Get module information */\n            Status = GetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to read module information */\n                return Status;\n            }\n        }\n    }\n\n    /* Iterate through module dependencies */\n    DepsListEntry = ModuleInfo->Dependencies.Flink;\n    while(DepsListEntry != &ModuleInfo->Dependencies)\n    {\n        /* Get module dependency information */\n        ModuleDependency = CONTAIN_RECORD(DepsListEntry, XTBL_MODULE_DEPS, Flink);\n\n        /* Make sure dependency list contains a valid module name */\n        if(ModuleDependency->ModuleName == NULLPTR || ModuleDependency->ModuleName[0] == L'\\0')\n        {\n            /* Invalid module name found, just skip this step */\n            break;\n        }\n\n        /* Load dependency module */\n        Debug::Print(L\"Module '%S' requires '%S' ...\\n\", ModuleName, ModuleDependency->ModuleName);\n        Status = LoadModule(ModuleDependency->ModuleName);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to load module, print error message and return status code */\n            Debug::Print(L\"Failed to load dependency module '%S' (Status Code: 0x%zX)\\n\",\n                         ModuleDependency->ModuleName, Status);\n            return STATUS_EFI_UNSUPPORTED;\n        }\n\n        /* Move to the next dependency */\n        DepsListEntry = DepsListEntry->Flink;\n    }\n\n    /* Setup module device path */\n    ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);\n    ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8;\n    ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH;\n    ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP;\n    ModuleDevicePath[0].MemoryType = EfiLoaderData;\n    ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData;\n    ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize;\n    ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);\n    ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8;\n    ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH;\n    ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;\n\n    /* Load EFI image */\n    Debug::Print(L\"Starting module '%S' ...\\n\", ModuleName);\n    Status = EfiUtils::LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Check if caused by secure boot */\n        if(Status == STATUS_EFI_ACCESS_DENIED && XtLoader::GetSecureBootStatus() >= 1)\n        {\n            /* SecureBoot signature validation failed */\n            Debug::Print(L\"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\\n\", ModuleName);\n        }\n        else\n        {\n            /* Failed to load module */\n            Debug::Print(L\"ERROR: Unable to load module '%S' (Status Code: 0x%zX)\\n\", ModuleName, Status);\n        }\n\n        /* Return error status code */\n        return Status;\n    }\n\n    /* Access module interface for further module type check */\n    Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage,\n                                                                       XtLoader::GetEfiImageHandle(), NULLPTR,\n                                                                       EFI_OPEN_PROTOCOL_GET_PROTOCOL);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open LoadedImage protocol */\n        Debug::Print(L\"ERROR: Unable to access module interface (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */\n    if(LoadedImage->ImageCodeType != EfiBootServicesCode)\n    {\n        /* Different type set, probably 'runtime driver', refuse to load it */\n        Debug::Print(L\"ERROR: Loaded module is not a boot system driver\\n\");\n\n        /* Close protocol and skip module */\n        XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);\n    }\n\n    /* Allocate memory for module name */\n    Status = Memory::AllocatePool(ModuleNameLength * sizeof(WCHAR), (PVOID *)&ModuleInfo->ModuleName);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to allocate memory for module name, return error */\n        Debug::Print(L\"ERROR: Failed to allocate memory (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Copy module name */\n    RTL::Memory::CopyMemory(ModuleInfo->ModuleName, ModuleName, ModuleNameLength * sizeof(WCHAR));\n\n    /* Save additional module information, not found in '.modinfo' section */\n    ModuleInfo->ModuleBase = LoadedImage->ImageBase;\n    ModuleInfo->ModuleSize = LoadedImage->ImageSize;\n    ModuleInfo->Revision = LoadedImage->Revision;\n    ModuleInfo->UnloadModule = LoadedImage->Unload;\n\n    /* Close loaded image protocol */\n    XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);\n\n    /* Start EFI image */\n    Status = EfiUtils::StartEfiImage(ModuleHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to start module image */\n        Debug::Print(L\"ERROR: Failed to start module '%S' (Status Code: 0x%zX)\\n\", ModuleName, Status);\n        return Status;\n    }\n\n    /* Add module to the list of loaded modules */\n    RTL::LinkedList::InsertTailList(&LoadedModules, &ModuleInfo->Flink);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Helper routine to load all modules supplied in the configuration file.\n *\n * @param ModulesList\n *        Supplies a space separated list of XTLDR modules to load (mostly read from configuration file).\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::LoadModules(IN PWCHAR ModulesList)\n{\n    PWCHAR LastModule, Module;\n    EFI_STATUS ReturnStatus, Status;\n\n    /* Set default return value */\n    ReturnStatus = STATUS_EFI_SUCCESS;\n\n    if(ModulesList != NULLPTR)\n    {\n        /* Tokenize provided list of modules */\n        Module = RTL::WideString::TokenizeWideString(ModulesList, L\" \", &LastModule);\n\n        /* Iterate over all arguments passed to boot loader */\n        while(Module != NULLPTR)\n        {\n            Status = LoadModule(Module);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Failed to load module, print error message and set new return value */\n                Debug::Print(L\"ERROR: Failed to load module '%S' (Status Code: 0x%zX)\\n\", Module, Status);\n                ReturnStatus = STATUS_EFI_LOAD_ERROR;\n            }\n\n            /* Take next module from the list */\n            Module = RTL::WideString::TokenizeWideString(NULLPTR, L\" \", &LastModule);\n        }\n    }\n\n    /* Return success */\n    return ReturnStatus;\n}\n\n/**\n * Returns an array of handles that support the requested protocol.\n *\n * @param Handles\n *        Supplies the address where a pointer to all handles found for the protocol interface.\n *\n * @param Count\n *        Provides a number of the returned handles.\n *\n * @param ProtocolGuid\n *        Supplies a pointer to the unique protocol GUID.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::LocateProtocolHandles(OUT PEFI_HANDLE *Handles,\n                                OUT PUINT_PTR Count,\n                                IN PEFI_GUID ProtocolGuid)\n{\n    return XtLoader::GetEfiSystemTable()->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULLPTR,\n                                                                           Count, Handles);\n}\n\n/**\n * Locates and opens the requested XT Boot Loader or EFI protocol.\n *\n * @param Handle\n *        Supplies the address where a pointer to the handle for the protocol interface.\n *\n * @param ProtocolHandler\n *        Supplies the address where a pointer to the opened protocol is returned.\n *\n * @param ProtocolGuid\n *        Supplies a pointer to the unique protocol GUID.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::OpenProtocol(OUT PEFI_HANDLE Handle,\n                       OUT PVOID *ProtocolHandler,\n                       IN PEFI_GUID ProtocolGuid)\n{\n    PEFI_HANDLE Handles = NULLPTR;\n    EFI_STATUS Status;\n    UINT_PTR Count;\n    UINT Index;\n\n    /* Try to locate the handles */\n    Status = LocateProtocolHandles(&Handles, &Count, ProtocolGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Unable to get handles */\n        return Status;\n    }\n\n    /* Check if any handles returned */\n    if(Count > 0)\n    {\n        /* Iterate through all given handles */\n        for(Index = 0; Index < Count; Index++)\n        {\n            /* Try to open protocol */\n            Status = OpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid);\n\n            /* Check if successfully opened the loader protocol */\n            if(Status == STATUS_EFI_SUCCESS)\n            {\n                /* Protocol found and successfully opened */\n                *Handle = Handles[Index];\n                break;\n            }\n        }\n    }\n\n    /* Free handles */\n    XtLoader::GetEfiSystemTable()->BootServices->FreePool(Handles);\n\n    /* Make sure the loaded protocol has been found */\n    if(*ProtocolHandler == NULLPTR)\n    {\n        /* Protocol not found */\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* Return success */\n\treturn STATUS_EFI_SUCCESS;\n}\n\n/**\n * Opens the requested XT Boot Loader or EFI protocol, if it is supported by the handle.\n *\n * @param Handle\n *        Supplies a handle for the protocol interface that is being opened.\n *\n * @param ProtocolHandler\n *        Supplies the address where a pointer to the opened protocol is returned.\n *\n * @param ProtocolGuid\n *        Supplies a pointer to the unique protocol GUID.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::OpenProtocolHandle(IN EFI_HANDLE Handle,\n                             OUT PVOID *ProtocolHandler,\n                             IN PEFI_GUID ProtocolGuid)\n{\n    return XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(Handle, ProtocolGuid, ProtocolHandler,\n                                                                     XtLoader::GetEfiImageHandle(),\n                                                                     NULLPTR, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);\n}\n\n/**\n * Registers a known boot protocol for a specified OS.\n *\n * @param SystemType\n *        Supplies the type of the OS, such as \"LINUX\", \"XTOS\", etc. that is supported by the boot protocol.\n *\n * @param BootProtocolGuid\n *        Supplies a pointer to the unique protocol GUID.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::RegisterBootProtocol(IN PCWSTR SystemType,\n                               IN PEFI_GUID BootProtocolGuid)\n{\n    PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry;\n    PLIST_ENTRY ProtocolListEntry;\n    EFI_STATUS Status;\n\n    ProtocolListEntry = BootProtocols.Flink;\n    while(ProtocolListEntry != &BootProtocols)\n    {\n        /* Get boot protocol entry */\n        ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink);\n\n        /* Check if boot protocol already registered for specified system */\n        if(RTL::WideString::CompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0)\n        {\n            /* Boot protocol already registered */\n            return STATUS_EFI_ABORTED;\n        }\n\n        /* Move to the next registered boot protocol */\n        ProtocolListEntry = ProtocolListEntry->Flink;\n    }\n\n    /* Create new boot protocol entry */\n    Status = Memory::AllocatePool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        return STATUS_EFI_OUT_OF_RESOURCES;\n    }\n\n    /* Set protocol properties and add it to the list */\n    ProtocolEntry->SystemType = (PWCHAR)SystemType;\n    ProtocolEntry->Guid = *BootProtocolGuid;\n    RTL::LinkedList::InsertTailList(&BootProtocols, &ProtocolEntry->Flink);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Reads information from the '.modinfo' section and populates the module information structure.\n *\n * @param SectionData\n *        Supplies a pointer to the module's information section data.\n *\n * @param SectionSize\n *        Supplies an expected size of the section data.\n *\n * @param ModuleInfo\n *        Supplies a pointer to the module information structure that will be filled by data from module's info section.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::GetModuleInformation(IN PWCHAR SectionData,\n                               IN ULONG SectionSize,\n                               OUT PXTBL_MODULE_INFO ModuleInfo)\n{\n    PXTBL_MODULE_DEPS ModuleDependencies;\n    PXTBL_MODULE_AUTHORS ModuleAuthors;\n    PWCHAR Dependency, Key, LastStr;\n    ULONG Index, Count;\n    EFI_STATUS Status;\n    PWCHAR *Strings;\n\n    /* Initialize authors and dependencies lists */\n    RTL::LinkedList::InitializeListHead(&ModuleInfo->Authors);\n    RTL::LinkedList::InitializeListHead(&ModuleInfo->Dependencies);\n\n    /* Get information strings from '.modinfo' section */\n    Status = GetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get information strings */\n        return Status;\n    }\n\n    /* Parse information strings */\n    for(Index = 0; Index < Count; Index++)\n    {\n        /* Store the key */\n        Key = Strings[Index];\n\n        /* Find the end of the key and the beginning of the value */\n        while(*Strings[Index] != L'=' && *Strings[Index] != L'\\0' && *Strings[Index] != L'\\n')\n        {\n            /* Move to the next character */\n            Strings[Index]++;\n        }\n\n        /* Make sure value is NULL-terminated */\n        *Strings[Index] = L'\\0';\n        Strings[Index]++;\n\n        /* Parse information string key */\n        if(RTL::WideString::CompareWideString(Key, L\"author\", 6) == 0)\n        {\n            /* Allocate memory for module author */\n            Status = Memory::AllocatePool(sizeof(XTBL_MODULE_AUTHORS), (PVOID*)&ModuleAuthors);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                /* Memory allocation failure */\n                return Status;\n            }\n\n            /* Store module's author */\n            ModuleAuthors->AuthorName = Strings[Index];\n            RTL::LinkedList::InsertTailList(&ModuleInfo->Authors, &ModuleAuthors->Flink);\n        }\n        else if(RTL::WideString::CompareWideString(Key, L\"description\", 11) == 0)\n        {\n            /* Store module's description */\n            ModuleInfo->ModuleDescription = Strings[Index];\n        }\n        else if(RTL::WideString::CompareWideString(Key, L\"license\", 7) == 0)\n        {\n            /* Store module's license */\n            ModuleInfo->License = Strings[Index];\n        }\n        else if(RTL::WideString::CompareWideString(Key, L\"softdeps\", 6) == 0)\n        {\n            /* Tokenize value to get module's single dependency */\n            Dependency = RTL::WideString::TokenizeWideString(Strings[Index], L\" \", &LastStr);\n            while(Dependency != NULLPTR)\n            {\n                /* Allocate memory for module dependency */\n                Status = Memory::AllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies);\n                if(Status != STATUS_EFI_SUCCESS)\n                {\n                    /* Memory allocation failure */\n                    return Status;\n                }\n\n                /* Store module's dependency */\n                ModuleDependencies->ModuleName = Dependency;\n                RTL::LinkedList::InsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink);\n\n                /* Get next dependency from single value if available */\n                Dependency = RTL::WideString::TokenizeWideString(NULLPTR, L\" \", &LastStr);\n            }\n        }\n        else if(RTL::WideString::CompareWideString(Key, L\"version\", 7) == 0)\n        {\n            /* Store module's version */\n            ModuleInfo->Version = Strings[Index];\n        }\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Reads raw data from the '.modinfo' section and populates an array of strings.\n *\n * @param SectionData\n *        Supplies a pointer to the module's information section data.\n *\n * @param SectionSize\n *        Supplies an expected size of the section data.\n *\n * @param ModInfo\n *        Supplies a pointer to memory area, where an array of strings read from the section will be stored.\n *\n * @param InfoCount\n *        Supplies a pointer to variable that will receive the number of strings found in the section.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::GetModuleInfoStrings(IN PWCHAR SectionData,\n                               IN ULONG SectionSize,\n                               OUT PWCHAR **ModInfo,\n                               OUT PULONG InfoCount)\n{\n    ULONG Count, Index, ArrayIndex;\n    PCWSTR InfoStrings;\n    EFI_STATUS Status;\n    PWCHAR *Array;\n    PWCHAR String;\n    ULONG DataSize;\n\n    /* Check input parameters */\n    InfoStrings = SectionData;\n    if(!InfoStrings || !SectionSize)\n    {\n        /* Invalid input parameters */\n        *ModInfo = NULLPTR;\n        *InfoCount = 0;\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Calculate the size of the data based on the size of the section */\n    DataSize = SectionSize / sizeof(WCHAR);\n\n    /* Skip zero padding at the beginning */\n    while(DataSize > 0 && *InfoStrings == L'\\0')\n    {\n        InfoStrings++;\n        DataSize--;\n    }\n\n    /* Make sure there is at least one string available */\n    if(DataSize < 1)\n    {\n        /* No strings found */\n        *ModInfo = NULLPTR;\n        *InfoCount = 0;\n        return STATUS_EFI_END_OF_FILE;\n    }\n\n    /* Count number of strings */\n    Index = 0;\n    Count = 0;\n    while(Index < DataSize)\n    {\n        /* Found start of a new string */\n        Count++;\n\n        /* Go to the end of the string */\n        while(Index < DataSize && InfoStrings[Index] != L'\\0')\n        {\n            Index++;\n        }\n        /* Skip all NULL terminators */\n        while(Index < DataSize && InfoStrings[Index] == L'\\0')\n        {\n            Index++;\n        }\n    }\n\n    /* Allocate memory for the pointer array and the string data */\n    Status = Memory::AllocatePool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to allocate memory */\n        return STATUS_EFI_OUT_OF_RESOURCES;\n    }\n\n    /* The string buffer is located right after the pointer array */\n    String = (PWCHAR)(Array + Count + 1);\n\n    /* Copy the raw string data */\n    RTL::Memory::CopyMemory(String, InfoStrings, DataSize * sizeof(WCHAR));\n\n    /* Ensure the entire buffer is NULL-terminated for safety */\n    String[DataSize] = L'\\0';\n\n    /* Set the last element of the pointer array to NULLPTR */\n    Array[Count] = NULLPTR;\n\n    /* Populate the array with pointers to the strings within the buffer */\n    Index = 0;\n    ArrayIndex = 0;\n    while(Index < DataSize && ArrayIndex < Count)\n    {\n        /* Set pointer to the beginning of the string */\n        Array[ArrayIndex++] = &String[Index];\n\n        /* Find the end of the current string */\n        while(Index < DataSize && String[Index] != L'\\0')\n        {\n            Index++;\n        }\n\n        /* Skip all NULL terminators to find the beginning of the next string */\n        while(Index < DataSize && String[Index] == L'\\0')\n        {\n            Index++;\n        }\n    }\n\n    /* Return array of strings and its size */\n    *ModInfo = Array;\n    *InfoCount = Count;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine installs XTLDR protocol for further usage by modules.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nProtocol::InstallXtLoaderProtocol()\n{\n    EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID;\n\n    /* Set all routines available via loader protocol */\n    LoaderProtocol.Boot.FindProtocol = FindBootProtocol;\n    LoaderProtocol.Boot.InitializeMenuList = Configuration::InitializeBootMenuList;\n    LoaderProtocol.Boot.InvokeProtocol = InvokeBootProtocol;\n    LoaderProtocol.Boot.RegisterMenu = XtLoader::RegisterBootMenu;\n    LoaderProtocol.Boot.RegisterProtocol = RegisterBootProtocol;\n    LoaderProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter;\n    LoaderProtocol.BootUtils.GetTrampolineInformation = AR::ProcessorSupport::GetTrampolineInformation;\n    LoaderProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue;\n    LoaderProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue;\n    LoaderProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions;\n    LoaderProtocol.Config.GetValue = Configuration::GetValue;\n    LoaderProtocol.Config.SetBootOptionValue = Configuration::SetBootOptionValue;\n    LoaderProtocol.Console.ClearLine = Console::ClearLine;\n    LoaderProtocol.Console.ClearScreen = Console::ClearScreen;\n    LoaderProtocol.Console.DisableCursor = Console::DisableCursor;\n    LoaderProtocol.Console.EnableCursor = Console::EnableCursor;\n    LoaderProtocol.Console.Print = Console::Print;\n    LoaderProtocol.Console.QueryMode = Console::QueryMode;\n    LoaderProtocol.Console.ReadKeyStroke = Console::ReadKeyStroke;\n    LoaderProtocol.Console.ResetInputBuffer = Console::ResetInputBuffer;\n    LoaderProtocol.Console.SetAttributes = Console::SetAttributes;\n    LoaderProtocol.Console.SetCursorPosition = Console::SetCursorPosition;\n    LoaderProtocol.Console.Write = Console::Write;\n    LoaderProtocol.Cpu.CpuId = AR::CpuFunctions::CpuId;\n    LoaderProtocol.Cpu.ReadControlRegister = AR::CpuFunctions::ReadControlRegister;\n    LoaderProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunctions::ReadModelSpecificRegister;\n    LoaderProtocol.Cpu.WriteControlRegister = AR::CpuFunctions::WriteControlRegister;\n    LoaderProtocol.Debug.Print = Debug::Print;\n    LoaderProtocol.Disk.CloseVolume = Volume::CloseVolume;\n    LoaderProtocol.Disk.OpenVolume = Volume::OpenVolume;\n    LoaderProtocol.Disk.ReadFile = Volume::ReadFile;\n    LoaderProtocol.IoPort.Read8 = HL::IoPort::ReadPort8;\n    LoaderProtocol.IoPort.Read16 = HL::IoPort::ReadPort16;\n    LoaderProtocol.IoPort.Read32 = HL::IoPort::ReadPort32;\n    LoaderProtocol.IoPort.Write8 = HL::IoPort::WritePort8;\n    LoaderProtocol.IoPort.Write16 = HL::IoPort::WritePort16;\n    LoaderProtocol.IoPort.Write32 = HL::IoPort::WritePort32;\n    LoaderProtocol.LinkedList.InitializeHead = RTL::LinkedList::InitializeListHead;\n    LoaderProtocol.LinkedList.InsertHead = RTL::LinkedList::InsertHeadList;\n    LoaderProtocol.LinkedList.InsertTail = RTL::LinkedList::InsertTailList;\n    LoaderProtocol.LinkedList.RemoveEntry = RTL::LinkedList::RemoveEntryList;\n    LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages;\n    LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool;\n    LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap;\n    LoaderProtocol.Memory.CommitPageMap = Memory::CommitPageMap;\n    LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;\n    LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;\n    LoaderProtocol.Memory.FreePages = Memory::FreePages;\n    LoaderProtocol.Memory.FreePool = Memory::FreePool;\n    LoaderProtocol.Memory.GetMappingsCount = Memory::GetMappingsCount;\n    LoaderProtocol.Memory.GetMemoryMap = Memory::GetMemoryMap;\n    LoaderProtocol.Memory.GetVirtualAddress = Memory::GetVirtualAddress;\n    LoaderProtocol.Memory.InitializePageMap = Memory::InitializePageMap;\n    LoaderProtocol.Memory.MapEfiMemory = Memory::MapEfiMemory;\n    LoaderProtocol.Memory.MapPage = Memory::MapPage;\n    LoaderProtocol.Memory.MapVirtualMemory = Memory::MapVirtualMemory;\n    LoaderProtocol.Memory.MoveMemory = RTL::Memory::MoveMemory;\n    LoaderProtocol.Memory.PhysicalAddressToVirtual = Memory::PhysicalAddressToVirtual;\n    LoaderProtocol.Memory.PhysicalListToVirtual = Memory::PhysicalListToVirtual;\n    LoaderProtocol.Memory.SetMemory = RTL::Memory::SetMemory;\n    LoaderProtocol.Memory.ZeroMemory = RTL::Memory::ZeroMemory;\n    LoaderProtocol.Protocol.Close = CloseProtocol;\n    LoaderProtocol.Protocol.GetModulesList = GetModulesList;\n    LoaderProtocol.Protocol.Install = InstallProtocol;\n    LoaderProtocol.Protocol.LocateHandles = LocateProtocolHandles;\n    LoaderProtocol.Protocol.Open = OpenProtocol;\n    LoaderProtocol.Protocol.OpenHandle = OpenProtocolHandle;\n    LoaderProtocol.Shell.RegisterCommand = Shell::RegisterCommand;\n    LoaderProtocol.String.Compare = RTL::String::CompareString;\n    LoaderProtocol.String.Length = RTL::String::StringLength;\n    LoaderProtocol.String.ToWideString = RTL::String::StringToWideString;\n    LoaderProtocol.String.Trim = RTL::String::TrimString;\n    LoaderProtocol.Tui.DisplayErrorDialog = TextUi::DisplayErrorDialog;\n    LoaderProtocol.Tui.DisplayInfoDialog = TextUi::DisplayInfoDialog;\n    LoaderProtocol.Tui.DisplayInputDialog = TextUi::DisplayInputDialog;\n    LoaderProtocol.Tui.DisplayProgressDialog = TextUi::DisplayProgressDialog;\n    LoaderProtocol.Tui.UpdateProgressBar = TextUi::UpdateProgressBar;\n    LoaderProtocol.Utils.EnterFirmwareSetup = EfiUtils::EnterFirmwareSetup;\n    LoaderProtocol.Utils.ExitBootServices = EfiUtils::ExitBootServices;\n    LoaderProtocol.Utils.GetConfigurationTable = EfiUtils::GetConfigurationTable;\n    LoaderProtocol.Utils.GetEfiVariable = EfiUtils::GetEfiVariable;\n    LoaderProtocol.Utils.GetRandomValue = EfiUtils::GetRandomValue;\n    LoaderProtocol.Utils.GetSecureBootStatus = EfiUtils::GetSecureBootStatus;\n    LoaderProtocol.Utils.InitializeEntropy = EfiUtils::InitializeEntropy;\n    LoaderProtocol.Utils.LoadEfiImage = EfiUtils::LoadEfiImage;\n    LoaderProtocol.Utils.RebootSystem = EfiUtils::RebootSystem;\n    LoaderProtocol.Utils.SetEfiVariable = EfiUtils::SetEfiVariable;\n    LoaderProtocol.Utils.ShutdownSystem = EfiUtils::ShutdownSystem;\n    LoaderProtocol.Utils.SleepExecution = EfiUtils::SleepExecution;\n    LoaderProtocol.Utils.StartEfiImage = EfiUtils::StartEfiImage;\n    LoaderProtocol.Utils.WaitForEfiEvent = EfiUtils::WaitForEfiEvent;\n    LoaderProtocol.WideString.Compare = RTL::WideString::CompareWideString;\n    LoaderProtocol.WideString.CompareInsensitive = RTL::WideString::CompareWideStringInsensitive;\n    LoaderProtocol.WideString.Concatenate = RTL::WideString::ConcatenateWideString;\n    LoaderProtocol.WideString.Format = RTL::WideString::FormatWideString;\n    LoaderProtocol.WideString.Length = RTL::WideString::WideStringLength;\n    LoaderProtocol.WideString.Tokenize = RTL::WideString::TokenizeWideString;\n\n    /* Register XTLDR loader protocol */\n    Debug::Print(L\"Registering XT loader protocol\\n\");\n    return InstallProtocol(&LoaderProtocol, &Guid);\n}\n"
  },
  {
    "path": "boot/xtldr/shell.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/shell.cc\n * DESCRIPTION:     XT Boot Loader shell\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Implements the built-in `exit` command. Sets the exit flag to signal the main\n * shell loop to terminate and return control to the boot menu.\n *\n * @param Argc\n *        Supplies the number of arguments provided by the user.\n *\n * @param Argv\n *        Supplies a list of arguments provided by the user.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::CommandExit(IN ULONG Argc,\n                   IN PWCHAR *Argv)\n{\n    /* Signal the main shell loop to stop and return to the boot menu */\n    ExitRequest = TRUE;\n}\n\n/**\n * Implements the built-in `help` command. Prints a list of available commands alongside their descriptions.\n *\n * @param Argc\n *        Supplies the number of arguments provided by the user.\n *\n * @param Argv\n *        Supplies a list of arguments provided by the user.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::CommandHelp(IN ULONG Argc,\n                   IN PWCHAR *Argv)\n{\n    PXTBL_SHELL_COMMAND CommandEntry;\n    PLIST_ENTRY ListEntry;\n\n    /* Print a header line */\n    Console::Print(L\"Available commands:\\n\\n\");\n\n    /* Walk the registered commands list */\n    ListEntry = ShellCommands.Flink;\n    while(ListEntry != &ShellCommands)\n    {\n        /* Retrieve the current command entry */\n        CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);\n\n        /* Print the command name in a highlighted color */\n        Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_WHITE);\n        Console::Print(L\"  %-12S\", CommandEntry->Command);\n\n        /* Print the description in the default color */\n        Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n        Console::Print(L\" %S\\n\", CommandEntry->Description);\n\n        /* Advance to the next entry */\n        ListEntry = ListEntry->Flink;\n    }\n}\n\n/**\n * Implements the built-in `insmod` command. Loads an XTLDR module by its name.\n *\n * @param Argc\n *        Supplies the number of arguments provided by the user.\n *\n * @param Argv\n *        Supplies a list of arguments provided by the user.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::CommandInsmod(IN ULONG Argc,\n                     IN PWCHAR *Argv)\n{\n    EFI_STATUS Status;\n\n    /* Check if the module name was provided */\n    if(Argc != 2)\n    {\n        /* Print usage message and return */\n        Console::Print(L\"Usage: insmod <module_name>\\n\");\n        return;\n    }\n\n    /* Load the module */\n    Status = Protocol::LoadModule(Argv[1]);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to load module, print error message */\n        Console::Print(L\"ERROR: Failed to load module '%S' (Status: 0x%llx).\\n\", Argv[1], Status);\n    }\n}\n\n/**\n * Implements the built-in `lsmod`  command. Lists all loaded XTLDR modules.\n *\n * @param Argc\n *        Supplies the number of arguments provided by the user.\n *\n * @param Argv\n *        Supplies a list of arguments provided by the user.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::CommandLsmod(IN ULONG Argc,\n                    IN PWCHAR *Argv)\n{\n    PXTBL_MODULE_INFO ModuleInfo;\n    PLIST_ENTRY ModulesList;\n    PLIST_ENTRY ListEntry;\n\n    /* Print header */\n    Console::Print(L\"Module Name       Version           Base Address          Size\\n\");\n    Console::Print(L\"----------------------------------------------------------------------\\n\");\n\n    /* Get modules list */\n    ModulesList = Protocol::GetModulesList();\n    if(ModulesList == NULLPTR)\n    {\n        /* No modules loaded */\n        return;\n    }\n\n    /* Iterate over all loaded modules */\n    ListEntry = ModulesList->Flink;\n    while(ListEntry != ModulesList)\n    {\n        /* Retrieve the module information */\n        ModuleInfo = CONTAIN_RECORD(ListEntry, XTBL_MODULE_INFO, Flink);\n\n        /* Print module information */\n        Console::Print(L\"%-16S  %-16S  0x%016llx    %llu\\n\",\n                       ModuleInfo->ModuleName, ModuleInfo->Version,\n                       (ULONGLONG)ModuleInfo->ModuleBase, ModuleInfo->ModuleSize);\n\n        /* Advance to the next entry */\n        ListEntry = ListEntry->Flink;\n    }\n}\n\n/**\n * Implements the built-in `poweroff` command. Shuts down the machine.\n *\n * @param Argc\n *        Supplies the number of arguments provided by the user.\n *\n * @param Argv\n *        Supplies a list of arguments provided by the user.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::CommandPoweroff(IN ULONG Argc,\n                       IN PWCHAR *Argv)\n{\n    /* Attempt to power off the machine */\n    Console::Print(L\"Powering off...\\n\");\n    EfiUtils::ShutdownSystem();\n\n    /* The poweroff call failed, print error message */\n    Console::Print(L\"ERROR: Failed to power off the machine\\n\");\n}\n\n/**\n * Implements the built-in `reboot` command. Performs a normal system restart via the EFI runtime services.\n * When the '/EFI' parameter is supplied, the routine instead schedules a reboot into the UEFI firmware setup interface.\n *\n * @param Argc\n *        Supplies the number of arguments provided by the user.\n *\n * @param Argv\n *        Supplies a list of arguments provided by the user.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::CommandReboot(IN ULONG Argc,\n                     IN PWCHAR *Argv)\n{\n    /* Check if the /EFI flag was specified */\n    if(Argc > 1 && RTL::WideString::CompareWideStringInsensitive(Argv[1], L\"/EFI\", 0) == 0)\n    {\n        /* Attempt to reboot into firmware setup */\n        Console::Print(L\"Rebooting into UEFI firmware setup...\\n\");\n        EfiUtils::EnterFirmwareSetup();\n\n        /* The firmware does not support this feature, print error message */\n        Console::Print(L\"ERROR: Reboot into firmware setup interface not supported.\\n\");\n    }\n    else\n    {\n        /* Perform a standard system reboot */\n        Console::Print(L\"Rebooting...\\n\");\n        EfiUtils::RebootSystem();\n\n        /* The reboot call failed, print error message */\n        Console::Print(L\"ERROR: Failed to reboot the machine\\n\");\n    }\n}\n\n/**\n * Implements the built-in `ver` command. Prints the bootloader identification string.\n *\n * @param Argc\n *        Supplies the number of arguments provided by the user.\n *\n * @param Argv\n *        Supplies a list of arguments provided by the user.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::CommandVersion(IN ULONG Argc,\n                      IN PWCHAR *Argv)\n{\n    /* Check if debugging enabled */\n    if(DEBUG)\n    {\n        /* Print debug version of XTLDR version string */\n        Console::Print(L\"XTLDR Boot Loader v%d.%d (%s-%s)\\n\",\n                       XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH);\n    }\n    else\n    {\n        /* Print standard XTLDR version string */\n        Console::Print(L\"XTLDR Boot Loader v%d.%d\\n\", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR);\n    }\n}\n\n/**\n * Looks up the given command name in the registered shell commands list and invokes the corresponding handler.\n *\n * @param Argc\n *        Supplies the number of arguments in the argument vector, including the command name itself.\n *\n * @param Argv\n *        Supplies a pointer to the argument vector. First argument is the command name.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::ExecuteCommand(IN ULONG Argc,\n                      IN PWCHAR *Argv)\n{\n    PXTBL_SHELL_COMMAND CommandEntry;\n    PLIST_ENTRY ListEntry;\n\n    /* Walk through the list of registered shell commands */\n    ListEntry = ShellCommands.Flink;\n    while(ListEntry != &ShellCommands)\n    {\n        /* Retrieve the shell command entry from the list node */\n        CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);\n\n        /* Perform a case-insensitive comparison against the command name */\n        if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Argv[0], 0) == 0)\n        {\n            /* Command matches, invoke its handler and return */\n            CommandEntry->Handler(Argc, Argv);\n            return;\n        }\n\n        /* Advance to the next registered command */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* No matching command was found, print error message */\n    Console::Print(L\"ERROR: '%S' is not recognized as a valid command.\\n\", Argv[0]);\n}\n\n/**\n * Splits the supplied raw command line string into an argument count and an argument vector suitable\n * for command dispatch. The input string is tokenized by whitespace.\n *\n * @param CommandLine\n *        Supplies a mutable wide-character string containing the raw command line.\n *\n * @param Argc\n *        Receives the number of arguments found in the command line.\n *\n * @param Argv\n *        Receives a pointer to an allocated array of wide-character string pointers, one for each argument.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nShell::ParseCommand(IN PWCHAR CommandLine,\n                    OUT PULONG Argc,\n                    OUT PWCHAR **Argv)\n{\n    PWCHAR *ArgumentVector, TempLine;\n    ULONG ArgumentCount;\n    EFI_STATUS Status;\n\n    /* Initialize argument count */\n    ArgumentCount = 0;\n\n    /* Count the tokens to determine the size of the argument vector */\n    TempLine = CommandLine;\n    while(*TempLine != L'\\0')\n    {\n        /* Skip leading spaces */\n        while(*TempLine == L' ')\n        {\n            /* Move to the next character */\n            TempLine++;\n        }\n\n        /* Check if the end of the string was reached */\n        if(*TempLine == L'\\0')\n        {\n            /* End of the string, break the loop */\n            break;\n        }\n\n        /* One more argument found */\n        ArgumentCount++;\n\n        /* Skip the characters of the token */\n        while(*TempLine != L'\\0' && *TempLine != L' ')\n        {\n            /* Move to the next character */\n            TempLine++;\n        }\n    }\n\n    /* Check if the command line was empty */\n    if(ArgumentCount == 0)\n    {\n        /* Set argument count and vector to zero and NULL */\n        *Argc = 0;\n        *Argv = NULLPTR;\n\n        /* Return success */\n        return STATUS_EFI_SUCCESS;\n    }\n\n    /* Allocate memory for the argument vector */\n    Status = Memory::AllocatePool(ArgumentCount * sizeof(PWCHAR), (PVOID *)&ArgumentVector);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, return status code */\n        return Status;\n    }\n\n    /* Reset argument count and temp line */\n    ArgumentCount = 0;\n    TempLine = CommandLine;\n\n    /* Walk through the command line */\n    while(*TempLine != L'\\0')\n    {\n        /* Skip leading whitespace */\n        while(*TempLine == L' ')\n        {\n            /* Move to the next character */\n            TempLine++;\n        }\n\n        /* Check if the end of the string was reached */\n        if(*TempLine == L'\\0')\n        {\n            /* End of string reached, break the loop */\n            break;\n        }\n\n        /* Record token */\n        ArgumentVector[ArgumentCount] = TempLine;\n        ArgumentCount++;\n\n        /* Advance past the token characters */\n        while(*TempLine != L'\\0' && *TempLine != L' ')\n        {\n            /* Move to the next character */\n            TempLine++;\n        }\n\n        /* Check if token was NULL-terminated */\n        if(*TempLine != L'\\0')\n        {\n            /* NULL-terminate the token and move to the next character */\n            *TempLine = L'\\0';\n            TempLine++;\n        }\n    }\n\n    /* Return results to the caller */\n    *Argc = ArgumentCount;\n    *Argv = ArgumentVector;\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Prints XTLDR shell prompt.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::PrintPrompt()\n{\n    /* Set prompt color */\n    Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);\n\n    /* Print prompt at the start of the line */\n    Console::Print(L\"\\rXTLDR> \");\n\n    /* Reset standard shell colors */\n    Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n}\n\n/**\n * Prints the whole prompt line, including the current command line and the cursor position.\n *\n * @param Buffer\n *        Supplies a pointer to the buffer containing the command line.\n *\n * @param BufferLength\n *        Supplies the buffer text length.\n *\n * @param CursorPosition\n *        Supplies the current cursor position.\n *\n * @param PreviousBufferLength\n *        Supplies the previous buffer text length to clear artifacts.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::PrintPromptLine(IN PWCHAR Buffer,\n                       IN ULONG BufferLength,\n                       IN ULONG CursorPosition,\n                       IN ULONG PreviousBufferLength)\n{\n    INT32 TargetX, TargetY;\n    WCHAR SavedChar;\n    ULONG Index;\n\n    /* Print the prompt */\n    PrintPrompt();\n\n    /* Temporarily truncate the string to capture cursor position */\n    SavedChar = Buffer[CursorPosition];\n    Buffer[CursorPosition] = L'\\0';\n\n    /* Print up to the cursor position */\n    Console::Print(L\"%S\", Buffer);\n\n    /* Capture target cursor coordinates from the EFI text mode structure */\n    TargetX = XtLoader::GetEfiSystemTable()->ConOut->Mode->CursorColumn;\n    TargetY = XtLoader::GetEfiSystemTable()->ConOut->Mode->CursorRow;\n\n    /* Restore the character and print the remainder of the buffer */\n    Buffer[CursorPosition] = SavedChar;\n    Console::Print(L\"%S\", Buffer + CursorPosition);\n\n    /* Check if the previous buffer was longer than the current one */\n    if(PreviousBufferLength > BufferLength)\n    {\n        /* Clear artifacts from the previous longer line */\n        for(Index = 0; Index < (PreviousBufferLength - BufferLength); Index++)\n        {\n            /* Print a white space */\n            Console::Print(L\" \");\n        }\n    }\n\n    /* Move the cursor back to the correct target position */\n    Console::SetCursorPosition(TargetX, TargetY);\n}\n\n/**\n * Reads a complete line of input from the shell console into the supplied buffer.\n *\n * @param Buffer\n *        Supplies a pointer to a wide-character buffer that receives the entered command line.\n *\n * @param BufferSize\n *        Supplies the capacity of the buffer, in wide characters.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::ReadCommand(OUT PWCHAR Buffer,\n                   IN ULONG BufferSize)\n{\n    ULONG BufferLength, CursorPosition, OldBufferLength;\n    UINT_PTR EventIndex;\n    EFI_INPUT_KEY Key;\n\n    /* Start with an empty buffer */\n    CursorPosition = 0;\n    BufferLength = 0;\n    Buffer[0] = L'\\0';\n\n    /* Reset history index */\n    HistoryIndex = HistoryCount;\n\n    /* Read characters until the user submits the command line */\n    while(TRUE)\n    {\n        /* Wait until a key event is available */\n        EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &EventIndex);\n\n        /* Read the keystroke from the input device */\n        Console::ReadKeyStroke(&Key);\n\n        /* Capture the previous line length to wipe possible artifacts */\n        OldBufferLength = BufferLength;\n\n        /* Check the keystroke */\n        if(Key.UnicodeChar == 0x0D)\n        {\n            /* ENTER key pressed, terminate the buffer and move to a new line */\n            Buffer[BufferLength] = L'\\0';\n            Console::Print(L\"\\n\");\n\n            /* Check if the buffer is not empty */\n            if(BufferLength > 0)\n            {\n                /* Check if the history is not full */\n                if(HistoryCount < XTBL_SH_HISTORY_ENTRIES)\n                {\n                    /* Store command in history and increment history count */\n                    RTL::Memory::CopyMemory(History[HistoryCount], Buffer, (BufferLength + 1) * sizeof(WCHAR));\n                    HistoryCount++;\n                }\n                else\n                {\n                    /* Shift history entries to fit new command */\n                    RTL::Memory::MoveMemory(History[0],\n                                            History[1],\n                                            (XTBL_SH_HISTORY_ENTRIES - 1) * XTBL_SH_MAX_LINE_LENGTH * sizeof(WCHAR));\n                    RTL::Memory::CopyMemory(History[XTBL_SH_HISTORY_ENTRIES - 1],\n                                            Buffer,\n                                            (BufferLength + 1) * sizeof(WCHAR));\n                }\n            }\n\n            /* Return the command line to the caller */\n            return;\n        }\n        else if(Key.ScanCode == 0x01)\n        {\n            /* UP key pressed, go back in history */\n            if(HistoryIndex > 0)\n            {\n                /* Decrement history index */\n                HistoryIndex--;\n\n                /* Copy history entry to buffer and update cursor position */\n                BufferLength = RTL::WideString::WideStringLength(History[HistoryIndex], XTBL_SH_MAX_LINE_LENGTH - 1);\n                RTL::Memory::CopyMemory(Buffer, History[HistoryIndex], (BufferLength + 1) * sizeof(WCHAR));\n                CursorPosition = BufferLength;\n\n                /* Reprint the prompt line */\n                PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n            }\n\n            /* Continue to the next iteration */\n            continue;\n        }\n        else if(Key.ScanCode == 0x02)\n        {\n            /* DOWN key pressed, go forward in history */\n            if(HistoryIndex < HistoryCount)\n            {\n                /* Increment history index */\n                HistoryIndex++;\n\n                /* Check if we are at the end of history */\n                if(HistoryIndex == HistoryCount)\n                {\n                    /* End of history, show empty prompt */\n                    Buffer[0] = L'\\0';\n                    BufferLength = 0;\n                    CursorPosition = 0;\n                }\n                else\n                {\n                    /* Copy history entry to buffer and update cursor position */\n                    BufferLength = RTL::WideString::WideStringLength(History[HistoryIndex],\n                                                                     XTBL_SH_MAX_LINE_LENGTH - 1);\n                    RTL::Memory::CopyMemory(Buffer, History[HistoryIndex], (BufferLength + 1) * sizeof(WCHAR));\n                    CursorPosition = BufferLength;\n                }\n\n                /* Reprint the prompt line */\n                PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n            }\n\n            /* Continue to the next iteration */\n            continue;\n        }\n        else if(Key.ScanCode == 0x03)\n            {\n            /* RIGHT key pressed, move cursor right */\n            if(CursorPosition < BufferLength)\n            {\n                /* Increment cursor position */\n                CursorPosition++;\n\n                /* Reprint the prompt line */\n                PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n            }\n\n            /* Continue to the next iteration */\n            continue;\n        }\n        else if(Key.ScanCode == 0x04)\n        {\n            /* LEFT key pressed, move cursor left */\n            if(CursorPosition > 0)\n            {\n                /* Decrement cursor position */\n                CursorPosition--;\n\n                /* Reprint the prompt line */\n                PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n            }\n\n            /* Continue to the next iteration */\n            continue;\n        }\n        else if(Key.ScanCode == 0x05)\n        {\n            /* HOME key pressed, move cursor to beginning */\n            if (CursorPosition > 0)\n            {\n                /* Set cursor position to beginning of the line and reprint the prompt line */\n                CursorPosition = 0;\n                PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n            }\n\n            /* Continue to the next iteration */\n            continue;\n        }\n        else if(Key.ScanCode == 0x06)\n        {\n            /* END key pressed, move cursor to end */\n            if (CursorPosition < BufferLength)\n            {\n                /* Set cursor position to end of the line and reprint the prompt line */\n                CursorPosition = BufferLength;\n                PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n            }\n\n            /* Continue to the next iteration */\n            continue;\n        }\n        else if(Key.ScanCode == 0x17)\n        {\n            /* ESC key pressed, discard the current input, move to a new line and reprint the prompt */\n            Buffer[0] = L'\\0';\n            Console::Print(L\"\\n\");\n            PrintPrompt();\n\n            /* Reset cursor position, buffer length and history index */\n            CursorPosition = 0;\n            BufferLength = 0;\n            HistoryIndex = HistoryCount;\n\n            /* Continue reading the command line */\n            continue;\n        }\n        else if(Key.ScanCode == 0x08)\n        {\n            /* DELETE key pressed, remove character at cursor */\n            if(CursorPosition < BufferLength)\n            {\n                /* Move memory to remove the character at cursor */\n                RTL::Memory::MoveMemory(Buffer + CursorPosition,\n                                        Buffer + CursorPosition + 1,\n                                        (BufferLength - CursorPosition) * sizeof(WCHAR));\n\n                /* Decrement buffer length and reprint the prompt line */\n                BufferLength--;\n                PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n            }\n\n            /* Continue to the next iteration */\n            continue;\n        }\n        else if(Key.UnicodeChar == 0x08)\n        {\n            /* BACKSPACE key pressed, delete character before cursor */\n            if(CursorPosition > 0)\n            {\n                /* Move memory to remove the character before cursor */\n                RTL::Memory::MoveMemory(Buffer + CursorPosition - 1,\n                                        Buffer + CursorPosition,\n                                        (BufferLength - CursorPosition + 1) * sizeof(WCHAR));\n\n                /* Decrement cursor position and buffer length */\n                CursorPosition--;\n                BufferLength--;\n\n                /* Reprint the prompt line */\n                PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n            }\n\n            /* Continue reading the command line */\n            continue;\n        }\n        else if(Key.UnicodeChar == 0)\n        {\n            /* Ignore non-printable characters */\n            continue;\n        }\n\n        /* Make sure there is room in the buffer (reserve one slot for NULL terminator) */\n        if(BufferLength < BufferSize - 1)\n        {\n            /* Insert character in the middle or end of the buffer */\n            RTL::Memory::MoveMemory(Buffer + CursorPosition + 1,\n                                    Buffer + CursorPosition,\n                                    (BufferLength - CursorPosition + 1) * sizeof(WCHAR));\n            Buffer[CursorPosition] = Key.UnicodeChar;\n\n            /* Increment cursor position and buffer length */\n            CursorPosition++;\n            BufferLength++;\n\n            /* Reprint the prompt line */\n            PrintPromptLine(Buffer, BufferLength, CursorPosition, OldBufferLength);\n        }\n    }\n}\n\n/**\n * Registers a new command in the XTLDR shell.\n *\n * @param Command\n *        Supplies the command keyword that the user types at the shell prompt.\n *\n * @param Description\n *        Supplies a short help string displayed by the 'help' command.\n *\n * @param Handler\n *        Supplies a pointer to the function that implements the command.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nShell::RegisterCommand(IN PCWSTR Command,\n                       IN PCWSTR Description,\n                       IN PBL_SHELL_COMMAND Handler)\n{\n    PXTBL_SHELL_COMMAND CommandEntry;\n    PLIST_ENTRY ListEntry;\n    EFI_STATUS Status;\n\n    /* Verify that a command with this name has not already been registered */\n    ListEntry = ShellCommands.Flink;\n    while(ListEntry != &ShellCommands)\n    {\n        /* Retrieve the existing shell command entry */\n        CommandEntry = CONTAIN_RECORD(ListEntry, XTBL_SHELL_COMMAND, Flink);\n\n        /* Compare command names case-insensitively */\n        if(RTL::WideString::CompareWideStringInsensitive(CommandEntry->Command, Command, 0) == 0)\n        {\n            /* Duplicate command name, return error */\n            return STATUS_EFI_INVALID_PARAMETER;\n        }\n\n        /* Advance to the next entry */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Allocate memory for the new command entry */\n    Status = Memory::AllocatePool(sizeof(XTBL_SHELL_COMMAND), (PVOID *)&CommandEntry);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, return error */\n        return STATUS_EFI_OUT_OF_RESOURCES;\n    }\n\n    /* Populate the new command entry */\n    CommandEntry->Command = (PWCHAR)Command;\n    CommandEntry->Description = (PWCHAR)Description;\n    CommandEntry->Handler = Handler;\n\n    /* Append the command to the global shell commands list */\n    RTL::LinkedList::InsertTailList(&ShellCommands, &CommandEntry->Flink);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Registers all built-in shell commands that are provided by the XTLDR.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::RegisterBuiltinCommands()\n{\n    /* Register all built-in shell commands */\n    RegisterCommand(L\"exit\", L\"Exits the shell and returns to the boot menu\", CommandExit);\n    RegisterCommand(L\"help\", L\"Displays a list of all available shell commands\", CommandHelp);\n    RegisterCommand(L\"insmod\", L\"Loads a specific XTLDR module\", CommandInsmod);\n    RegisterCommand(L\"lsmod\", L\"Displays a list of loaded modules\", CommandLsmod);\n    RegisterCommand(L\"poweroff\", L\"Shuts down the machine\", CommandPoweroff);\n    RegisterCommand(L\"reboot\", L\"Reboots the machine (/EFI to enter firmware setup)\", CommandReboot);\n    RegisterCommand(L\"ver\", L\"Displays the boot loader version information\", CommandVersion);\n}\n\n/**\n * Initializes the command list, registers the built-in commands and enters an interactive XTLDR shell loop.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nShell::StartLoaderShell()\n{\n    WCHAR CommandLine[XTBL_SH_MAX_LINE_LENGTH];\n    PWCHAR *ArgumentVector;\n    ULONG ArgumentCount;\n    EFI_STATUS Status;\n\n    /* Initialize console */\n    Console::InitializeConsole();\n\n    /* Initialize the shell commands list */\n    RTL::LinkedList::InitializeListHead(&ShellCommands);\n\n    /* Register all built-in commands */\n    RegisterBuiltinCommands();\n\n    /* Clear the shell exit request flag */\n    ExitRequest = FALSE;\n\n    /* Main XTLDR shell loop */\n    while(!ExitRequest)\n    {\n        /* Display the shell prompt */\n        PrintPrompt();\n\n        /* Read a command line */\n        ReadCommand(CommandLine, XTBL_SH_MAX_LINE_LENGTH);\n\n        /* Parse the command line into a list of arguments */\n        Status = ParseCommand(CommandLine, &ArgumentCount, &ArgumentVector);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Parsing failed, print error and continue */\n            Console::Print(L\"ERROR: Failed to parse command line (Status: 0x%llx).\\n\\n\", Status);\n            continue;\n        }\n\n        /* Check if command line is empty */\n        if(ArgumentCount == 0)\n        {\n            /* Skip empty command line */\n            continue;\n        }\n\n        /* Check if command line starts with a comment symbol (#) */\n        if(ArgumentVector[0][0] != L'#')\n        {\n            /* Dispatch the command */\n            ExecuteCommand(ArgumentCount, ArgumentVector);\n        }\n\n        /* Free the argument vector */\n        Memory::FreePool(ArgumentVector);\n\n        /* Print a trailing blank line for visual separation */\n        Console::Print(L\"\\n\");\n    }\n}\n"
  },
  {
    "path": "boot/xtldr/textui.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/textui.cc\n * DESCRIPTION:     Text console User Interface (TUI) support for XT Boot Loader\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Determines dialog box size based on enabled components and message length.\n *\n * @param Handle\n *        Supplies a pointer to the dialog box handle.\n *\n * @param Message\n *        Supplies a pointer to the message string put on the dialog box.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle,\n                               IN PCWSTR Message)\n{\n    UINT_PTR Width, Height, LineLength;\n    SIZE_T Index, MessageLength;\n    UCHAR Attributes;\n    ULONG Mask;\n\n    /* Set minimum dialog window size */\n    Height = 4;\n    Width = 36;\n\n    /* Zero line length */\n    LineLength = 0;\n\n    /* Adjust window height according to enabled components */\n    Mask = 1;\n    Attributes = Handle->Attributes;\n    while(Mask)\n    {\n        /* Check enabled components that affect dialog window size */\n        switch(Attributes & Mask)\n        {\n            case XTBL_TUI_DIALOG_ACTIVE_BUTTON:\n            case XTBL_TUI_DIALOG_INACTIVE_BUTTON:\n                Height += 1;\n                break;\n            case XTBL_TUI_DIALOG_ACTIVE_INPUT:\n            case XTBL_TUI_DIALOG_INACTIVE_INPUT:\n            case XTBL_TUI_DIALOG_PROGRESS_BAR:\n                Height += 2;\n                break;\n        }\n\n        /* Update component attributes mask */\n        Attributes &= ~Mask;\n        Mask <<= 1;\n    }\n\n    /* Check if input field is active */\n    if(Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT))\n    {\n        /* Set maximum dialog window width to fit input field */\n        Width = XTBL_TUI_MAX_DIALOG_WIDTH;\n    }\n\n    /* Get message length and count dialog window dimensions */\n    MessageLength = RTL::WideString::WideStringLength(Message, 0);\n    for(Index = 0; Index < MessageLength; Index++)\n    {\n        /* Check if this is multiline message */\n        if(Message[Index] == L'\\n' || Index == MessageLength - 1)\n        {\n            /* Check if this line exceeds current dialog window width */\n            if(LineLength > Width)\n            {\n                /* Update dialog window width */\n                Width = LineLength;\n            }\n\n            /* Increase dialog window height to fit next line */\n            Height++;\n            LineLength = 0;\n        }\n        else\n        {\n            /* Increase dialog window width to fit next character */\n            LineLength++;\n        }\n    }\n\n    /* Add more space to dialog window to fit side borders */\n    Width += 4;\n\n    /* Get console resolution */\n    Console::QueryMode(&Handle->ResX, &Handle->ResY);\n\n    /* Make sure dialog window fits in the buffer */\n    if(Width > XTBL_TUI_MAX_DIALOG_WIDTH)\n    {\n        /* Set maximum dialog window width */\n        Width = XTBL_TUI_MAX_DIALOG_WIDTH;\n    }\n\n    /* Make sure dialog window fits on the screen (X axis) and it is not too small for input field */\n    if(Width > (Handle->ResX - 2))\n    {\n        /* Set maximum dialog window width */\n        Width = Handle->ResX - 2;\n    }\n\n    /* Make sure dialog window fits on the screen (Y axis)*/\n    if(Height > (Handle->ResY - 2))\n    {\n        /* Set maximum dialog window height */\n        Height = Handle->ResY - 2;\n    }\n\n    /* Set dialog window final dimensions */\n    Handle->PosX = (Handle->ResX - Width) / 2;\n    Handle->PosY = (Handle->ResY - Height) / 2;\n    Handle->Width = Width;\n    Handle->Height = Height;\n}\n\n/**\n * Displays a simple TUI-based boot menu.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DisplayBootMenu()\n{\n    XTBL_DIALOG_HANDLE Handle;\n    PXTBL_BOOTMENU_ITEM MenuEntries = NULLPTR;\n    ULONG Index;\n    ULONG HighligtedEntryId, OldHighligtedEntryId, NumberOfEntries, TopVisibleEntry, VisibleEntries;\n    BOOLEAN RedrawBootMenu, RedrawEntries;\n    UINT_PTR EventIndex;\n    EFI_EVENT Events[2];\n    EFI_INPUT_KEY Key;\n    EFI_EVENT TimerEvent;\n    EFI_STATUS Status;\n    LONG TimeOut;\n    PWCHAR TimeOutString;\n\n    /* Draw boot menu */\n    DrawBootMenu(&Handle);\n\n    /* Initialize boot menu list */\n    TopVisibleEntry = 0;\n    Status = Configuration::InitializeBootMenuList(Handle.Width - 4, &MenuEntries, &NumberOfEntries, &HighligtedEntryId);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to initialize boot menu list, exit into XTLDR shell */\n        return;\n    }\n\n    /* Calculate how many entries can be visible in the menu box */\n    VisibleEntries = Handle.Height - 2;\n\n    /* Adjust the view if the default entry is not initially visible */\n    if(HighligtedEntryId >= VisibleEntries)\n    {\n        /* Scroll the view to make the highlighted entry the last visible one */\n        TopVisibleEntry = HighligtedEntryId - VisibleEntries + 1;\n    }\n\n    /* Get timeout from the configuration */\n    Configuration::GetValue(L\"TIMEOUT\", &TimeOutString);\n    TimeOut = -1;\n\n    /* Check if timeout is specified */\n    if(TimeOutString != NULLPTR)\n    {\n        /* Convert timeout string to number */\n        TimeOut = 0;\n        while(*TimeOutString >= '0' && *TimeOutString <= '9')\n        {\n            TimeOut *= 10;\n            TimeOut += *TimeOutString - '0';\n            TimeOutString++;\n        }\n    }\n\n    /* Set redraw flags to not redraw the menu itself, but fill it with entries */\n    RedrawBootMenu = FALSE;\n    RedrawEntries = TRUE;\n\n    /* Infinite boot menu loop */\n    while(TRUE)\n    {\n        /* Redraw boot menu frame if requested */\n        if(RedrawBootMenu)\n        {\n            DrawBootMenu(&Handle);\n            RedrawBootMenu = FALSE;\n            RedrawEntries = TRUE;\n        }\n\n        /* Sanity check to ensure we do not display more entries than possible */\n        if(VisibleEntries > NumberOfEntries)\n        {\n            VisibleEntries = NumberOfEntries;\n        }\n\n        /* Check if there is anything to show in the boot menu */\n        if(NumberOfEntries > 0)\n        {\n            /* Check if we need to redraw boot menu entries */\n            if(RedrawEntries)\n            {\n                /* Iterate through all menu entries */\n                for(Index = 0; Index < VisibleEntries; Index++)\n                {\n                    /* Draw menu entry */\n                    DrawBootMenuEntry(&Handle, MenuEntries[TopVisibleEntry + Index].EntryName,\n                                      Index, (BOOLEAN)((TopVisibleEntry + Index) == HighligtedEntryId));\n                }\n\n                /* Clear redraw entries flag */\n                RedrawEntries = FALSE;\n            }\n        }\n        else\n        {\n            /* No menu entries found, show error message */\n            DisplayErrorDialog(L\"XTLDR\", L\"No boot menu entries found in the configuration. Falling back to shell.\");\n\n            /* Exit into XTLDR shell */\n            return;\n        }\n\n        /* Create a timer event for controlling the timeout of the boot menu */\n        Status = XtLoader::GetEfiSystemTable()->BootServices->CreateEvent(EFI_EVENT_TIMER, EFI_TPL_CALLBACK,\n                                                                          NULLPTR, NULLPTR, &TimerEvent);\n        if(Status == STATUS_EFI_SUCCESS)\n        {\n            /* Setup new EFI timer */\n            Status = XtLoader::GetEfiSystemTable()->BootServices->SetTimer(TimerEvent, TimerPeriodic, 10000000);\n        }\n\n        /* Check is EFI timer was successfully created */\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Timer creation failed, disable the timer */\n            TimeOut = -1;\n        }\n\n        /* Initialize EFI events */\n        Events[0] = XtLoader::GetEfiSystemTable()->ConIn->WaitForKey;\n        Events[1] = TimerEvent;\n\n        /* Flush keyboard buffer out of any keystrokes */\n        XtLoader::GetEfiSystemTable()->ConIn->Reset(XtLoader::GetEfiSystemTable()->ConIn, FALSE);\n\n        /* Store old highlighted entry */\n        OldHighligtedEntryId = HighligtedEntryId;\n\n        /* Infinite boot menu event loop */\n        while(TRUE)\n        {\n            /* Wait for EFI event */\n            EfiUtils::WaitForEfiEvent(2, Events, &EventIndex);\n\n            /* Check which event was received */\n            if(EventIndex == 0)\n            {\n                /* Key pressed, check if timer is still active */\n                if(TimeOut != -1)\n                {\n                    /* Disable the timer */\n                    TimeOut = -1;\n\n                    /* Cancel timer event */\n                    XtLoader::GetEfiSystemTable()->BootServices->SetTimer(TimerEvent, TimerCancel, 0);\n\n                    /* Remove the timer message */\n                    Console::ClearLine(Handle.PosY + Handle.Height + 4);\n                }\n\n                /* Read key stroke */\n                Console::ReadKeyStroke(&Key);\n\n                if(Key.ScanCode == 0x03 || Key.UnicodeChar == 0x0D)\n                {\n                    /* ENTER or RightArrow key pressed, boot the highlighted OS */\n                    Console::SetAttributes(Handle.DialogColor | Handle.TextColor);\n                    Console::ClearLine(Handle.PosY + Handle.Height + 4);\n                    Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4);\n                    Console::Print(L\"Booting '%S' now...\\n\", MenuEntries[HighligtedEntryId].FullName);\n\n                    /* Boot the highlighted (chosen) OS */\n                    Status = Protocol::InvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName,\n                                                          MenuEntries[HighligtedEntryId].Options);\n                    if(Status != STATUS_SUCCESS)\n                    {\n                        /* Failed to boot OS */\n                        Debug::Print(L\"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\\n\",\n                                     MenuEntries[HighligtedEntryId].FullName, Status);\n                        DisplayErrorDialog(L\"XTLDR\", L\"Failed to startup the selected Operating System.\");\n                        RedrawBootMenu = TRUE;\n                    }\n\n                    /* Break from boot menu event loop to redraw whole boot menu */\n                    break;\n                }\n                else if(Key.ScanCode == 0x01)\n                {\n                    /* UpArrow key pressed, go to previous entry if possible */\n                    if(HighligtedEntryId > 0)\n                    {\n                        /* Highlight previous entry */\n                        OldHighligtedEntryId = HighligtedEntryId;\n                        HighligtedEntryId--;\n\n                        /* Check if we need to scroll the view */\n                        if(HighligtedEntryId < TopVisibleEntry)\n                        {\n                            /* Scroll the view */\n                            TopVisibleEntry = HighligtedEntryId;\n                            RedrawEntries = TRUE;\n                            break;\n                        }\n\n                        /* Redraw new highlighted entry and the old one */\n                        DrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName,\n                                          OldHighligtedEntryId - TopVisibleEntry, (BOOLEAN)FALSE);\n                        DrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName,\n                                          HighligtedEntryId - TopVisibleEntry, (BOOLEAN)TRUE);\n                    }\n                }\n                else if(Key.ScanCode == 0x02)\n                {\n                    /* DownArrow key pressed, go to next entry if possible */\n                    if(HighligtedEntryId < NumberOfEntries - 1)\n                    {\n                        /* Highlight next entry */\n                        OldHighligtedEntryId = HighligtedEntryId;\n                        HighligtedEntryId++;\n\n                        /* Check if we need to scroll the view */\n                        if(HighligtedEntryId >= TopVisibleEntry + VisibleEntries)\n                        {\n                            /* Scroll the view */\n                            TopVisibleEntry = HighligtedEntryId - VisibleEntries + 1;\n                            RedrawEntries = TRUE;\n                            break;\n                        }\n\n                        /* Redraw new highlighted entry and the old one */\n                        DrawBootMenuEntry(&Handle, MenuEntries[OldHighligtedEntryId].EntryName,\n                                          OldHighligtedEntryId - TopVisibleEntry, (BOOLEAN)FALSE);\n                        DrawBootMenuEntry(&Handle, MenuEntries[HighligtedEntryId].EntryName,\n                                          HighligtedEntryId - TopVisibleEntry, (BOOLEAN)TRUE);\n                    }\n                }\n                else if(Key.ScanCode == 0x09)\n                {\n                    /* PageUp key pressed, go to top entry */\n                    if(HighligtedEntryId != 0)\n                    {\n                        /* Highlight first entry */\n                        HighligtedEntryId = 0;\n                        TopVisibleEntry = 0;\n                        RedrawEntries = TRUE;\n                        break;\n                    }\n                }\n                else if(Key.ScanCode == 0x0A)\n                {\n                    /* PageDown key pressed, go to bottom entry */\n                    if(HighligtedEntryId != NumberOfEntries - 1)\n                    {\n                        /* Highlight last entry */\n                        HighligtedEntryId = NumberOfEntries - 1;\n                        TopVisibleEntry = (NumberOfEntries > VisibleEntries) ? (NumberOfEntries - VisibleEntries) : 0;\n                        RedrawEntries = TRUE;\n                        break;\n                    }\n                }\n                else if(Key.ScanCode == 0x0B)\n                {\n                    /* F1 key pressed, show help */\n                    DisplayInfoDialog(L\"XTLDR\", L\"XTLDR, the XTOS Boot Loader for UEFI and EFI-based machines.\\n\"\n                                                L\" \\n\"\n                                                L\"Use arrow keys (Up/Down) to change the highlighted entry and\\n\"\n                                                L\"PgUp/PgDown keys to jump to the first/last position.\\n\"\n                                                L\" \\n\"\n                                                L\"Press ENTER key to boot the highlighted boot menu entry.\\n\"\n                                                L\"Press 'e' key to edit the highlighted menu entry.\\n\"\n                                                L\"Press 's' key to exit into XTLDR shell (enters advanced mode).\\n\"\n                                                L\" \\n\"\n                                                L\"F1 shows this help, F10 reboots into UEFI firmware interface,\\n\"\n                                                L\"F11 reboots the machine and F12 turns it off.\\n\"\n                                                L\" \\n\"\n                                                L\" \\n\"\n                                                L\"XTLDR is a part of the ExectOS Operating System.\\n\"\n                                                L\"Visit https://exectos.eu.org/ for more information.\");\n\n                    /* Break from boot menu event loop to redraw whole boot menu */\n                    RedrawBootMenu = TRUE;\n                    break;\n                }\n                else if(Key.ScanCode == 0x14)\n                {\n                    /* F10 key pressed, reboot into UEFI setup interface */\n                    EfiUtils::EnterFirmwareSetup();\n                    DisplayErrorDialog(L\"XTLDR\", L\"Reboot into firmware setup interface not supported!\");\n                    RedrawBootMenu = TRUE;\n\n                    /* Break from boot menu event loop to redraw whole boot menu */\n                    break;\n                }\n                else if(Key.ScanCode == 0x15)\n                {\n                    /* F11 key pressed, reboot the machine */\n                    EfiUtils::RebootSystem();\n                    DisplayErrorDialog(L\"XTLDR\", L\"Failed to reboot the machine!\");\n                    RedrawBootMenu = TRUE;\n\n                    /* Break from boot menu event loop to redraw whole boot menu */\n                    break;\n                }\n                else if(Key.ScanCode == 0x16)\n                {\n                    /* F12 key pressed, shutdown the machine */\n                    EfiUtils::ShutdownSystem();\n                    DisplayErrorDialog(L\"XTLDR\", L\"Failed to shutdown the machine!\");\n                    RedrawBootMenu = TRUE;\n\n                    /* Break from boot menu event loop to redraw whole boot menu */\n                    break;\n                }\n                else if(Key.UnicodeChar == 0x65)\n                {\n                    /* 'e' key pressed, edit the highlighted entry */\n                    DisplayEditMenu(&MenuEntries[HighligtedEntryId]);\n                    RedrawBootMenu = TRUE;\n\n                    /* Break from boot menu event loop to redraw whole boot menu */\n                    break;\n                }\n                else if(Key.UnicodeChar == 0x73)\n                {\n                    /* 's' key pressed, exit into XTLDR shell */\n                    return;\n                }\n            }\n            else\n            {\n                /* Timer tick, check if time out expired */\n                if(TimeOut > 0)\n                {\n                    /* Update a message and decrease timeout value */\n                    Console::SetAttributes(Handle.DialogColor | Handle.TextColor);\n                    Console::ClearLine(Handle.PosY + Handle.Height + 4);\n                    Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4);\n                    Console::Print(L\"The highlighted position will be booted automatically in %ld seconds.\", TimeOut);\n                    TimeOut--;\n                }\n                else if(TimeOut == 0)\n                {\n                    /* Time out expired, update a message */\n                    Console::SetAttributes(Handle.DialogColor | Handle.TextColor);\n                    Console::ClearLine(Handle.PosY + Handle.Height + 4);\n                    Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4);\n                    Console::Print(L\"Booting '%S' now...\\n\", MenuEntries[HighligtedEntryId].FullName);\n\n                    /* Disable the timer just in case booting OS fails */\n                    TimeOut = -1;\n\n                    /* Boot the highlighted (default) OS */\n                    Status = Protocol::InvokeBootProtocol(MenuEntries[HighligtedEntryId].ShortName,\n                                                          MenuEntries[HighligtedEntryId].Options);\n                    if(Status != STATUS_SUCCESS)\n                    {\n                        /* Failed to boot OS */\n                        Debug::Print(L\"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\\n\",\n                                     MenuEntries[HighligtedEntryId].FullName, Status);\n                        DisplayErrorDialog(L\"XTLDR\", L\"Failed to startup the selected Operating System.\");\n                        RedrawBootMenu = TRUE;\n                    }\n                    break;\n                }\n            }\n        }\n    }\n}\n\n/**\n * Displays a simple TUI-based edit menu.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry)\n{\n    ULONG HighligtedOptionId, Index, NumberOfOptions, OldHighligtedOptionId, TopVisibleEntry, VisibleEntries;\n    XTBL_DIALOG_HANDLE Handle;\n    BOOLEAN RedrawEditMenu, RedrawEntries;\n    EFI_INPUT_KEY Key;\n    UINT_PTR EventIndex;\n    PWCHAR NewValue, OriginalValue, Value, ValueToEdit;\n    PCWSTR OptionName, *EditableOptions;\n    EFI_STATUS Status;\n\n    /* Draw edit menu */\n    DrawEditMenu(&Handle);\n\n    /* Get the list of user editable options */\n    Configuration::GetEditableOptions(&EditableOptions, &NumberOfOptions);\n\n    /* Calculate how many entries can be visible in the menu box */\n    VisibleEntries = Handle.Height - 2;\n\n    /* Assume the first option is highlighted by default */\n    HighligtedOptionId = 0;\n    OldHighligtedOptionId = 0;\n    TopVisibleEntry = 0;\n\n    /* Set redraw flags to not redraw the menu itself, but fill it with entries */\n    RedrawEditMenu = FALSE;\n    RedrawEntries = TRUE;\n\n    /* Infinite edit menu loop */\n    while(TRUE)\n    {\n        /* Redraw edit menu frame if requested */\n        if(RedrawEditMenu)\n        {\n            DrawEditMenu(&Handle);\n            RedrawEditMenu = FALSE;\n            RedrawEntries = TRUE;\n        }\n\n        /* Sanity check to ensure we do not display more entries than possible */\n        if(VisibleEntries > NumberOfOptions)\n        {\n            VisibleEntries = NumberOfOptions;\n        }\n\n        /* Check if we need to redraw boot menu entries */\n        if(RedrawEntries)\n        {\n            /* Iterate through all menu entries */\n            for(Index = 0; Index < VisibleEntries; Index++)\n            {\n                /* Draw menu entry */\n                Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[TopVisibleEntry + Index], &Value);\n                DrawEditMenuEntry(&Handle, EditableOptions[TopVisibleEntry + Index], Value, Index,\n                                  (BOOLEAN)((TopVisibleEntry + Index) == HighligtedOptionId));\n\n                /* Free allocated value string if needed */\n                if(Value != NULLPTR)\n                {\n                    Memory::FreePool(Value);\n                }\n            }\n\n            /* Clear redraw entries flag */\n            RedrawEntries = FALSE;\n        }\n\n        /* Wait for EFI event and read key stroke */\n        EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &EventIndex);\n        Console::ReadKeyStroke(&Key);\n\n        /* Check key press scan code */\n        if(Key.UnicodeChar == 0x0D || Key.UnicodeChar == 0x65)\n        {\n            /* ENTER or 'e' key pressed, edit the highlighted option */\n            OptionName = EditableOptions[HighligtedOptionId];\n            Configuration::GetBootOptionValue(MenuEntry->Options, OptionName, &OriginalValue);\n\n            /* If the original value is NULLPTR, use an empty string for editing */\n            if(OriginalValue == NULLPTR)\n            {\n                ValueToEdit = (PWCHAR)L\"\";\n            }\n            else\n            {\n                ValueToEdit = OriginalValue;\n            }\n\n            /* Display input dialog to edit the option value */\n            NewValue = ValueToEdit;\n            DisplayInputDialog(OptionName, L\"Enter new value:\", &NewValue);\n\n            /* Check if the value was changed */\n            if(NewValue != ValueToEdit)\n            {\n                /* Update the boot option with the new value and free the old value */\n                Configuration::SetBootOptionValue(MenuEntry->Options, OptionName, NewValue);\n                Memory::FreePool(NewValue);\n            }\n\n            /* Free the original value if it was allocated */\n            if(OriginalValue != NULLPTR)\n            {\n                Memory::FreePool(OriginalValue);\n            }\n\n            /* Mark the edit menu for redraw */\n            RedrawEditMenu = TRUE;\n        }\n        else if(Key.ScanCode == 0x01)\n        {\n            /* UpArrow key pressed, go to previous entry if possible */\n            if(HighligtedOptionId > 0)\n            {\n                /* Highlight previous entry */\n                OldHighligtedOptionId = HighligtedOptionId;\n                HighligtedOptionId--;\n\n                /* Check if we need to scroll the view */\n                if(HighligtedOptionId < TopVisibleEntry)\n                {\n                    /* Scroll the view */\n                    TopVisibleEntry = HighligtedOptionId;\n                    RedrawEntries = TRUE;\n                    continue;\n                }\n\n                /* Redraw old highlighted entry */\n                Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value);\n                DrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, (BOOLEAN)FALSE);\n\n                /* Free allocated value string if needed */\n                if(Value != NULLPTR)\n                {\n                    Memory::FreePool(Value);\n                }\n\n                /* Redraw new highlighted entry */\n                Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value);\n                DrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, (BOOLEAN)TRUE);\n\n                /* Free allocated value string if needed */\n                if(Value != NULLPTR)\n                {\n                    Memory::FreePool(Value);\n                }\n            }\n        }\n        else if(Key.ScanCode == 0x02)\n        {\n            /* DownArrow key pressed, go to next entry if possible */\n            if(HighligtedOptionId < NumberOfOptions - 1)\n            {\n                /* Highlight next entry */\n                OldHighligtedOptionId = HighligtedOptionId;\n                HighligtedOptionId++;\n\n                /* Check if we need to scroll the view */\n                if(HighligtedOptionId >= TopVisibleEntry + VisibleEntries)\n                {\n                    /* Scroll the view */\n                    TopVisibleEntry = HighligtedOptionId - VisibleEntries + 1;\n                    RedrawEntries = TRUE;\n                    continue;\n                }\n\n                /* Redraw old highlighted entry */\n                Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[OldHighligtedOptionId], &Value);\n                DrawEditMenuEntry(&Handle, EditableOptions[OldHighligtedOptionId], Value, OldHighligtedOptionId - TopVisibleEntry, (BOOLEAN)FALSE);\n\n                /* Free allocated value string if needed */\n                if(Value != NULLPTR)\n                {\n                    Memory::FreePool(Value);\n                }\n\n                /* Redraw new highlighted entry */\n                Configuration::GetBootOptionValue(MenuEntry->Options, EditableOptions[HighligtedOptionId], &Value);\n                DrawEditMenuEntry(&Handle, EditableOptions[HighligtedOptionId], Value, HighligtedOptionId - TopVisibleEntry, (BOOLEAN)TRUE);\n\n                /* Free allocated value string if needed */\n                if(Value != NULLPTR)\n                {\n                    Memory::FreePool(Value);\n                }\n            }\n        }\n        else if(Key.ScanCode == 0x09)\n        {\n            /* PageUp key pressed, go to top entry */\n            if(HighligtedOptionId != 0)\n            {\n                /* Highlight first entry */\n                HighligtedOptionId = 0;\n                TopVisibleEntry = 0;\n                RedrawEntries = TRUE;\n            }\n        }\n        else if(Key.ScanCode == 0x0A)\n        {\n            /* PageDown key pressed, go to bottom entry */\n            if(HighligtedOptionId != NumberOfOptions - 1)\n            {\n                /* Highlight last entry */\n                HighligtedOptionId = NumberOfOptions - 1;\n                TopVisibleEntry = (NumberOfOptions > VisibleEntries) ? (NumberOfOptions - VisibleEntries) : 0;\n                RedrawEntries = TRUE;\n            }\n        }\n        else if(Key.ScanCode == 0x14)\n        {\n            /* F10 key pressed, boot the OS */\n            Console::SetAttributes(Handle.DialogColor | Handle.TextColor);\n            Console::ClearLine(Handle.PosY + Handle.Height + 4);\n            Console::SetCursorPosition(4, Handle.PosY + Handle.Height + 4);\n            Console::Print(L\"Booting '%S' now...\\n\", MenuEntry->FullName);\n\n            /* Boot the OS */\n            Status = Protocol::InvokeBootProtocol(MenuEntry->ShortName, MenuEntry->Options);\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to boot OS */\n                Debug::Print(L\"ERROR: Failed to boot '%S' (Status Code: 0x%zX)\\n\", MenuEntry->FullName, Status);\n                DisplayErrorDialog(L\"XTLDR\", L\"Failed to startup the selected Operating System.\");\n                RedrawEditMenu = TRUE;\n            }\n\n            /* Return to the edit menu */\n            continue;\n        }\n        else if(Key.ScanCode == 0x17)\n        {\n            /* ESC key pressed, exit edit menu */\n            break;\n        }\n    }\n}\n\n/**\n * Displays a red error dialog box with the specified caption and message.\n *\n * @param Caption\n *        Supplies a caption string put on the dialog box.\n *\n * @param Message\n *        Supplies a message string put on the dialog box.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DisplayErrorDialog(IN PCWSTR Caption,\n                           IN PCWSTR Message)\n{\n    XTBL_DIALOG_HANDLE Handle;\n    EFI_INPUT_KEY Key;\n    UINT_PTR Index;\n\n    /* Set dialog window attributes */\n    Handle.Attributes = XTBL_TUI_DIALOG_ERROR_BOX | XTBL_TUI_DIALOG_ACTIVE_BUTTON;\n\n    /* Determine dialog window size and position */\n    DetermineDialogBoxSize(&Handle, Message);\n\n    /* Disable cursor and draw dialog box */\n    Console::DisableCursor();\n    DrawDialogBox(&Handle, Caption, Message);\n\n    /* Draw active button */\n    DrawButton(&Handle);\n\n    /* Initialize key stroke */\n    Key.ScanCode = 0;\n    Key.UnicodeChar = 0;\n\n    /* Wait until ENTER or ESC key is pressed */\n    while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D)\n    {\n        /* Wait for key press and read key stroke */\n        EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &Index);\n        Console::ReadKeyStroke(&Key);\n        Console::ResetInputBuffer();\n    }\n\n    /* Clear screen to remove dialog box */\n    Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n    Console::ClearScreen();\n}\n\n/**\n * Displays a blue informational dialog box with the specified caption and message.\n *\n * @param Caption\n *        Supplies a caption string put on the dialog box.\n *\n * @param Message\n *        Supplies a message string put on the dialog box.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DisplayInfoDialog(IN PCWSTR Caption,\n                          IN PCWSTR Message)\n{\n    XTBL_DIALOG_HANDLE Handle;\n    EFI_INPUT_KEY Key;\n    UINT_PTR Index;\n\n    /* Set dialog window attributes */\n    Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_BUTTON;\n\n    /* Determine dialog window size and position */\n    DetermineDialogBoxSize(&Handle, Message);\n\n    /* Disable cursor and draw dialog box */\n    Console::DisableCursor();\n    DrawDialogBox(&Handle, Caption, Message);\n\n    /* Draw active button */\n    DrawButton(&Handle);\n\n    /* Initialize key stroke */\n    Key.ScanCode = 0;\n    Key.UnicodeChar = 0;\n\n    /* Wait until ENTER or ESC key is pressed */\n    while(Key.ScanCode != 0x17 && Key.UnicodeChar != 0x0D)\n    {\n        /* Wait for key press and read key stroke */\n        EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &Index);\n        Console::ReadKeyStroke(&Key);\n        Console::ResetInputBuffer();\n    }\n\n    /* Clear screen to remove dialog box */\n    Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n    Console::ClearScreen();\n}\n\n/**\n * Displays a blue informational dialog box with the specified caption and message and an input field.\n *\n * @param Caption\n *        Specifies a caption string put on the dialog box.\n *\n * @param Message\n *        Specifies a message string put on the dialog box.\n *\n * @param InputFieldText\n *        Specifies a pointer to the input field text that will be edited.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DisplayInputDialog(IN PCWSTR Caption,\n                           IN PCWSTR Message,\n                           IN OUT PWCHAR *InputFieldText)\n{\n    SIZE_T InputFieldLength, TextCursorPosition, TextIndex, TextPosition;\n    XTBL_DIALOG_HANDLE Handle;\n    PWCHAR InputFieldBuffer;\n    EFI_INPUT_KEY Key;\n    EFI_STATUS Status;\n    UINT_PTR Index;\n\n    /* Set dialog window attributes */\n    Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_BUTTON;\n\n    /* Determine dialog window size and position */\n    DetermineDialogBoxSize(&Handle, Message);\n\n    /* Disable cursor and draw dialog box */\n    Console::DisableCursor();\n    DrawDialogBox(&Handle, Caption, Message);\n\n    /* Draw inactive button */\n    DrawButton(&Handle);\n\n    /* Draw active input field */\n    DrawInputField(&Handle, *InputFieldText);\n\n    /* Initialize key stroke */\n    Key.ScanCode = 0;\n    Key.UnicodeChar = 0;\n\n    /* Determine input field length */\n    InputFieldLength = RTL::WideString::WideStringLength(*InputFieldText, 0);\n\n    /* Allocate a buffer for storing the input field text */\n    Status = Memory::AllocatePool(2048 * sizeof(WCHAR), (PVOID *)&InputFieldBuffer);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, print error message and return */\n        Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n        DisplayErrorDialog(L\"XTLDR\", L\"Failed to allocate memory for input field buffer.\");\n        return;\n    }\n\n    /* Copy input text into edit buffer */\n    RTL::Memory::CopyMemory(InputFieldBuffer, *InputFieldText, InputFieldLength * sizeof(WCHAR));\n    InputFieldBuffer[InputFieldLength] = L'\\0';\n\n    /* Start at first character */\n    TextPosition = 0;\n    Console::SetCursorPosition(Handle.PosX + 4 + TextPosition, Handle.PosY + Handle.Height - 4);\n\n    /* Wait until ENTER or ESC key is pressed */\n    while(TRUE)\n    {\n        /* Wait for key press and read key stroke */\n        EfiUtils::WaitForEfiEvent(1, &(XtLoader::GetEfiSystemTable()->ConIn->WaitForKey), &Index);\n        Console::ReadKeyStroke(&Key);\n\n        /* Check key press scan code */\n        if(Key.ScanCode == 0x17)\n        {\n            /* ESC key pressed, return */\n            break;\n        }\n        else if(Key.UnicodeChar == 0x09)\n        {\n            /* TAB key pressed, toggle input field and button */\n            Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_INPUT | XTBL_TUI_DIALOG_INACTIVE_INPUT);\n            Handle.Attributes ^= (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON);\n        }\n        else if(Key.ScanCode == 0x03)\n        {\n            /* RIGHT key pressed, move cursor forward */\n            if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition < InputFieldLength)\n            {\n                TextPosition++;\n            }\n        }\n        else if(Key.ScanCode == 0x04)\n        {\n            /* LEFT key pressed, move cursor back */\n            if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && TextPosition > 0)\n            {\n                TextPosition--;\n            }\n        }\n        else if(Key.ScanCode == 0x05)\n        {\n            /* HOME key pressed, move cursor to the beginning */\n            if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)\n            {\n                TextPosition = 0;\n            }\n        }\n        else if(Key.ScanCode == 0x06)\n        {\n            /* END key pressed, move cursor to the end */\n            if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)\n            {\n                TextPosition = InputFieldLength;\n            }\n        }\n        else if(Key.ScanCode == 0x08)\n        {\n            /* DELETE key pressed, delete character */\n            if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)\n            {\n                /* Check if buffer is not empty */\n                if(InputFieldLength > 0 && TextPosition < InputFieldLength)\n                {\n                    /* Delete character */\n                    RTL::Memory::MoveMemory(InputFieldBuffer + TextPosition, InputFieldBuffer + TextPosition + 1,\n                                  (InputFieldLength - TextPosition) * sizeof(WCHAR));\n\n                    /* Decrement length and NULL terminate string */\n                    InputFieldLength--;\n                    InputFieldBuffer[InputFieldLength] = L'\\0';\n                }\n            }\n        }\n        else if(Key.UnicodeChar == 0x08)\n        {\n            /* BACKSPACE key pressed, delete character */\n            if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)\n            {\n                /* Check if buffer is not empty */\n                if(InputFieldLength > 0 && TextPosition > 0 && TextPosition <= InputFieldLength)\n                {\n                    /* Move memory to overwrite the character to the left of the cursor */\n                    RTL::Memory::MoveMemory(InputFieldBuffer + TextPosition - 1, InputFieldBuffer + TextPosition,\n                                  (InputFieldLength - TextPosition + 1) * sizeof(WCHAR));\n\n                    /* Decrement length, position and NULL terminate string */\n                    TextPosition--;\n                    InputFieldLength--;\n                    InputFieldBuffer[InputFieldLength] = L'\\0';\n                }\n            }\n        }\n        else if(Key.UnicodeChar == 0x0D)\n        {\n            /* ENTER key pressed, update input buffer */\n            *InputFieldText = InputFieldBuffer;\n            break;\n        }\n        else\n        {\n            /* Other key pressed, add character to the buffer */\n            if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT && Key.UnicodeChar != 0)\n            {\n                /* Check if buffer is full */\n                if(InputFieldLength < 2047)\n                {\n                    /* Insert character at current position */\n                    RTL::Memory::MoveMemory(InputFieldBuffer + TextPosition + 1, InputFieldBuffer + TextPosition,\n                                  (InputFieldLength - TextPosition) * sizeof(WCHAR));\n                    InputFieldBuffer[TextPosition] = Key.UnicodeChar;\n\n                    /* Increment length, position and NULL terminate string */\n                    TextPosition++;\n                    InputFieldLength++;\n                    InputFieldBuffer[InputFieldLength] = L'\\0';\n                }\n            }\n        }\n\n        /* Calculate text index and cursor position */\n        if(TextPosition > (Handle.Width - 9))\n        {\n            TextIndex = TextPosition - (Handle.Width - 9);\n            TextCursorPosition = Handle.Width - 9;\n        }\n        else\n        {\n            TextIndex = 0;\n            TextCursorPosition = TextPosition;\n        }\n\n        /* Redraw input field and button */\n        DrawButton(&Handle);\n        DrawInputField(&Handle, &InputFieldBuffer[TextIndex]);\n\n        /* Set cursor position if input field is active */\n        if(Handle.Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)\n        {\n            Console::SetCursorPosition(Handle.PosX + 4 + TextCursorPosition, Handle.PosY + Handle.Height - 4);\n        }\n    }\n\n    /* Clear screen to remove dialog box */\n    Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n    Console::ClearScreen();\n}\n\n/**\n * Displays a blue informational dialog box with the specified caption and message and a progress bar.\n *\n * @param Caption\n *        Supplies a caption string put on the dialog box.\n *\n * @param Message\n *        Supplies a message string put on the dialog box.\n *\n * @param Percentage\n *        Specifies the percentage progress of the progress bar.\n *\n * @return This routine returns a dialog box handle needed to update the progress bar.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTBL_DIALOG_HANDLE\nTextUi::DisplayProgressDialog(IN PCWSTR Caption,\n                              IN PCWSTR Message,\n                              IN UCHAR Percentage)\n{\n    XTBL_DIALOG_HANDLE Handle;\n\n    /* Set dialog window attributes */\n    Handle.Attributes = XTBL_TUI_DIALOG_GENERIC_BOX | XTBL_TUI_DIALOG_PROGRESS_BAR;\n\n    /* Determine dialog window size and position */\n    DetermineDialogBoxSize(&Handle, Message);\n\n    /* Disable cursor and draw dialog box */\n    Console::DisableCursor();\n    DrawDialogBox(&Handle, Caption, Message);\n\n    /* Draw active button */\n    DrawProgressBar(&Handle, Percentage);\n\n    /* Return dialog handle */\n    return Handle;\n}\n\n/**\n * Draws a text UI-based boot menu.\n *\n * @param Handle\n *        Supplies a pointer to the boot menu handle.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle)\n{\n    /* Query console screen resolution */\n    Console::QueryMode(&Handle->ResX, &Handle->ResY);\n\n    /* Set boot menu parameters */\n    Handle->Attributes = 0;\n    Handle->DialogColor = EFI_TEXT_BGCOLOR_BLACK;\n    Handle->TextColor = EFI_TEXT_FGCOLOR_LIGHTGRAY;\n    Handle->PosX = 3;\n    Handle->PosY = 3;\n    Handle->Width = Handle->ResX - 6;\n    Handle->Height = Handle->ResY - 10;\n\n    /* Clear screen and disable cursor */\n    Console::SetAttributes(Handle->DialogColor | Handle->TextColor);\n    Console::ClearScreen();\n    Console::DisableCursor();\n\n    /* Check if debugging enabled */\n    if(DEBUG)\n    {\n        /* Print debug version of XTLDR banner */\n        Console::SetCursorPosition((Handle->ResX - 44) / 2, 1);\n        Console::Print(L\"XTLDR Boot Loader v%d.%d (%s-%s)\\n\",\n                       XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH);\n    }\n    else\n    {\n        /* Print standard XTLDR banner */\n        Console::SetCursorPosition((Handle->ResX - 22) / 2, 1);\n        Console::Print(L\"XTLDR Boot Loader v%d.%d\\n\", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR);\n    }\n\n    /* Draw empty dialog box for boot menu */\n    DrawDialogBox(Handle, NULLPTR, NULLPTR);\n\n    /* Print help message below the boot menu */\n    Console::SetCursorPosition(0, Handle->PosY + Handle->Height);\n    Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n    Console::Print(L\"    Use cursors to change the selection. Press ENTER key to boot the chosen\\n\"\n                   L\"    Operating System, 'e' to edit it before booting or 's' for XTLDR shell.\\n\"\n                   L\"    Additional help available after pressing F1 key.\");\n}\n\n/**\n * Draws boot menu entry at the specified position.\n *\n * @param Handle\n *        Supplies a pointer to the boot menu handle.\n *\n * @param MenuEntry\n *        Supplies a pointer to the buffer containing a menu entry name.\n *\n * @param Position\n *        Specifies entry position on the list in the boot menu.\n *\n * @param Highlighted\n *        Specifies whether this entry should be highlighted or not.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,\n                          IN PWCHAR MenuEntry,\n                          IN UINT Position,\n                          IN BOOLEAN Highlighted)\n{\n    UINT Index;\n\n    /* Move cursor to the right position */\n    Console::SetCursorPosition(5, 4 + Position);\n\n    /* Check whether this entry should be highlighted */\n    if(Highlighted)\n    {\n        /* Highlight this entry */\n        Console::SetAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK);\n    }\n    else\n    {\n        /* Set default colors */\n        Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n    }\n\n    /* Clear menu entry */\n    for(Index = 0; Index < Handle->Width - 4; Index++)\n    {\n        Console::Print(L\" \");\n    }\n\n    /* Print menu entry */\n    Console::SetCursorPosition(5, 4 + Position);\n    Console::Print(L\"%S\\n\", MenuEntry);\n}\n\n/**\n * Draws dialog box with caption and message.\n *\n * @param Handle\n *        Supplies a pointer to the dialog box handle.\n *\n * @param Caption\n *        Specifies a caption string put on the dialog box.\n *\n * @param Message\n *        Specifies a message string put on the dialog box.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle,\n                      IN PCWSTR Caption,\n                      IN PCWSTR Message)\n{\n    WCHAR BoxLine[XTBL_TUI_MAX_DIALOG_WIDTH];\n    SIZE_T CaptionLength;\n    UINT_PTR PosX, PosY;\n\n    /* Set dialog colors */\n    if(Handle->Attributes & XTBL_TUI_DIALOG_ERROR_BOX)\n    {\n        /* Error dialog with red background and brown button */\n        Handle->DialogColor = EFI_TEXT_BGCOLOR_RED;\n        Handle->TextColor = EFI_TEXT_FGCOLOR_WHITE;\n    }\n    else if(Handle->Attributes & XTBL_TUI_DIALOG_GENERIC_BOX)\n    {\n        /* Generic dialog with blue background and cyan button */\n        Handle->DialogColor = EFI_TEXT_BGCOLOR_BLUE;\n        Handle->TextColor = EFI_TEXT_FGCOLOR_WHITE;\n    }\n\n    /* Set dialog box colors */\n    Console::SetAttributes(Handle->DialogColor | 0x0F);\n\n    /* Iterate through dialog box lines */\n    for(PosY = Handle->PosY; PosY < Handle->PosY + Handle->Height; PosY++)\n    {\n        /* Set cursor position in the appropriate place */\n        Console::SetCursorPosition(Handle->PosX, PosY);\n\n        /* Draw dialog box */\n        if(PosY == Handle->PosY)\n        {\n            /* Draw top line of the dialog box, starting from the left corner */\n            BoxLine[0] = EFI_TEXT_BOX_DOWN_RIGHT;\n\n            /* Check if there is a caption for this dialog */\n            if(Caption != NULLPTR)\n            {\n                /* Get caption length */\n                CaptionLength = RTL::WideString::WideStringLength(Caption, 0);\n\n                /* Start caption area with vertical line */\n                BoxLine[1] = EFI_TEXT_BOX_VERTICAL_LEFT;\n\n                /* Fill caption area with spaces */\n                for(PosX = 2; PosX < CaptionLength + 4; PosX++)\n                {\n                    BoxLine[PosX] = ' ';\n                }\n\n                /* End caption area with vertical line */\n                BoxLine[CaptionLength + 4] = EFI_TEXT_BOX_VERTICAL_RIGHT;\n            }\n            else\n            {\n                /* No caption, -4 because of left and right vertical lines and corresponding spaces */\n                CaptionLength = -4;\n            }\n\n            /* Draw bottom line */\n            for(PosX = CaptionLength + 5; PosX < Handle->Width - 1; PosX++)\n            {\n                BoxLine[PosX] = EFI_TEXT_BOX_HORIZONTAL;\n            }\n\n            /* End with top right corner */\n            BoxLine[Handle->Width - 1] = EFI_TEXT_BOX_DOWN_LEFT;\n        }\n        else if(PosY == Handle->PosY + Handle->Height - 1)\n        {\n            /* Draw bottom line of the dialog box, starting from the left corner */\n            BoxLine[0] = EFI_TEXT_BOX_UP_LEFT;\n\n            /* Fill bottom with horizontal line */\n            for(PosX = 1; PosX < Handle->Width - 1; PosX++)\n            {\n                BoxLine[PosX] = EFI_TEXT_BOX_HORIZONTAL;\n            }\n\n            /* End with bottom right corner */\n            BoxLine[Handle->Width - 1] = EFI_TEXT_BOX_UP_RIGHT;\n        }\n        else\n        {\n            /* Draw the middle of the dialog box */\n            BoxLine[0] = EFI_TEXT_BOX_VERTICAL;\n\n            /* Fill dialog box with spaces */\n            for(PosX = 1; PosX < Handle->Width - 1; PosX++)\n            {\n                BoxLine[PosX] = ' ';\n            }\n\n            /* End with vertical line */\n            BoxLine[Handle->Width - 1] = EFI_TEXT_BOX_VERTICAL;\n        }\n\n        /* Add NULL terminator to the end of the line */\n        BoxLine[Handle->Width] = 0;\n\n        /* Write the line to the console */\n        Console::Write(BoxLine);\n    }\n\n    /* Make sure there is a caption to print */\n    if(Caption != NULLPTR)\n    {\n    /* Write dialog box caption */\n        Console::SetCursorPosition(Handle->PosX + 3, Handle->PosY);\n        Console::Print(L\"%S\", Caption);\n    }\n\n    /* Make sure there is a message to print */\n    if(Message != NULLPTR)\n    {\n        /* Write a message on the dialog box */\n        DrawMessage(Handle, Message);\n    }\n}\n\n/**\n * Draws an active or inactive button in the dialog box, depending on the attributes.\n *\n * @param Handle\n *        Supplies a pointer to the dialog box handle.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DrawButton(IN PXTBL_DIALOG_HANDLE Handle)\n{\n    ULONG ButtonColor, TextColor;\n\n    /* Set dialog button colors */\n    if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_BUTTON)\n    {\n        /* This is an active button */\n        if(Handle->Attributes & XTBL_TUI_DIALOG_ERROR_BOX)\n        {\n            /* This is an error dialog box */\n            ButtonColor = EFI_TEXT_BGCOLOR_BROWN;\n            TextColor = EFI_TEXT_FGCOLOR_WHITE;\n        }\n        else\n        {\n            /* This is a generic dialog box */\n            ButtonColor = EFI_TEXT_BGCOLOR_CYAN;\n            TextColor = EFI_TEXT_FGCOLOR_WHITE;\n        }\n    }\n    else\n    {\n        /* This is an inactive button */\n        ButtonColor = EFI_TEXT_BGCOLOR_LIGHTGRAY;\n        TextColor = EFI_TEXT_FGCOLOR_BLACK;\n    }\n\n    /* Disable cursor and draw dialog button */\n    Console::DisableCursor();\n    Console::SetAttributes(ButtonColor | TextColor);\n    Console::SetCursorPosition(Handle->ResX / 2 - 4, Handle->PosY + Handle->Height - 2);\n    Console::Print(L\"[  OK  ]\");\n}\n\n/**\n * Draws an active or inactive input field in the dialog box, depending on the attributes.\n *\n * @param Handle\n *        Supplies a pointer to the dialog box handle.\n *\n * @param InputFieldText\n *        Supplies a pointer to the wide char string that will be displayed in the input field.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DrawInputField(IN PXTBL_DIALOG_HANDLE Handle,\n                       IN PWCHAR InputFieldText)\n{\n    WCHAR InputField[XTBL_TUI_MAX_DIALOG_WIDTH];\n    ULONG InputColor, TextColor;\n    UINT_PTR Index, Position;\n    SIZE_T Length;\n\n    /* Set dialog button colors */\n    if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)\n    {\n        /* This is an active input field */\n        if(Handle->Attributes & XTBL_TUI_DIALOG_ERROR_BOX)\n        {\n            /* This is an error dialog box */\n            InputColor = EFI_TEXT_BGCOLOR_BROWN;\n            TextColor = EFI_TEXT_FGCOLOR_WHITE;\n        }\n        else\n        {\n            /* This is a generic dialog box */\n            InputColor = EFI_TEXT_BGCOLOR_CYAN;\n            TextColor = EFI_TEXT_FGCOLOR_WHITE;\n        }\n    }\n    else\n    {\n        /* This is an inactive input field */\n        InputColor = EFI_TEXT_BGCOLOR_LIGHTGRAY;\n        TextColor = EFI_TEXT_FGCOLOR_BLACK;\n    }\n\n    /* Set progress bar color and position */\n    Console::SetAttributes(InputColor | TextColor);\n    Position = (Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3;\n    Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position);\n\n    /* Draw input field */\n    for(Index = 0; Index < Handle->Width - 8; Index++)\n    {\n        /* Fill input field with spaces */\n        InputField[Index] = L' ';\n    }\n\n    /* Disable cursor and write input field to console */\n    Console::DisableCursor();\n    Console::Write(InputField);\n\n    /* Check input field text length */\n    Length = RTL::WideString::WideStringLength(InputFieldText, 0);\n    if(Length > (Handle->Width - 9))\n    {\n        /* Text longer than input field width, display only part of it */\n        Length = Handle->Width - 9;\n    }\n\n    /* Copy a part of input field text to input field */\n    for(Index = 0; Index < Length; Index++)\n    {\n        /* Write input field text */\n        InputField[Index] = InputFieldText[Index];\n    }\n\n    /* Add NULL terminator to the end of the line */\n    InputField[Handle->Width] = 0;\n\n    /* Write input field text */\n    Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position);\n    Console::Write(InputField);\n\n    /* Check if this is an active input field */\n    if(Handle->Attributes & XTBL_TUI_DIALOG_ACTIVE_INPUT)\n    {\n        /* Enable cursor for active input field */\n        Console::EnableCursor();\n    }\n}\n\n/**\n * Draws a message on the dialog box specified by the handle.\n *\n * @param Handle\n *        Supplies a pointer to the dialog box handle.\n *\n * @param Message\n *        Supplies a message that will be displayed on the dialog box.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DrawMessage(IN PXTBL_DIALOG_HANDLE Handle,\n                    IN PCWSTR Message)\n{\n    PWCHAR Msg, MsgLine, LastMsgLine;\n    SIZE_T Index, Length, LineLength;\n    EFI_STATUS Status;\n    ULONG Line;\n\n    /* Allocate memory for dialog box message */\n    Length = RTL::WideString::WideStringLength(Message, 0);\n    Status = Memory::AllocatePool(Length * sizeof(WCHAR), (PVOID *)&Msg);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure, print debug message and return */\n        Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n        return;\n    }\n\n    /* Make a copy of dialog box message */\n    RTL::Memory::CopyMemory(Msg, Message, Length * sizeof(WCHAR));\n    Msg[Length] = 0;\n\n    /* Tokenize dialog box message */\n    MsgLine = RTL::WideString::TokenizeWideString(Msg, L\"\\n\", &LastMsgLine);\n\n    /* Iterate through message lines */\n    Line = 0;\n    while(MsgLine)\n    {\n        /* Determine line length */\n        LineLength = RTL::WideString::WideStringLength(MsgLine, 0);\n\n        /* Write line in the dialog box */\n        Console::SetCursorPosition(Handle->PosX + 2, Handle->PosY + 2 + Line);\n        Console::SetAttributes(Handle->DialogColor | Handle->TextColor);\n        Console::Print(L\"%S\", MsgLine);\n\n        /* Check if message line is shorter than the dialog box working area */\n        if(LineLength < Handle->Width - 4)\n        {\n            /* Fill the rest of the line with spaces */\n            for(Index = LineLength; Index < Handle->Width - 4; Index++)\n            {\n                Console::Print(L\" \");\n            }\n        }\n\n        /* Get next line */\n        MsgLine = RTL::WideString::TokenizeWideString(NULLPTR, L\"\\n\", &LastMsgLine);\n        Line++;\n    }\n}\n\n/**\n * Draws a progress bar component in the dialog box.\n *\n * @param Handle\n *        Supplies a pointer to the dialog box handle.\n *\n * @param Percentage\n *        Specifies the percentage progress of the progress bar.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DrawProgressBar(IN PXTBL_DIALOG_HANDLE Handle,\n                        IN UCHAR Percentage)\n{\n    UINT_PTR Index, ProgressLength, ProgressBarLength;\n    WCHAR ProgressBar[XTBL_TUI_MAX_DIALOG_WIDTH];\n    UINT_PTR Position;\n\n    /* Determine progress bar length and calculate progress */\n    ProgressBarLength = Handle->Width - 8;\n    ProgressLength = (ProgressBarLength * Percentage) / 100;\n\n    /* Set progress bar color and position */\n    Console::SetAttributes(EFI_TEXT_FGCOLOR_YELLOW);\n    Position = (Handle->Attributes & (XTBL_TUI_DIALOG_ACTIVE_BUTTON | XTBL_TUI_DIALOG_INACTIVE_BUTTON)) ? 4 : 3;\n    Console::SetCursorPosition(Handle->PosX + 4, Handle->PosY + Handle->Height - Position);\n\n    /* Draw progress bar */\n    for(Index = 0; Index < ProgressBarLength; Index++)\n    {\n        /* Fill progress bar */\n        if(Index < ProgressLength)\n        {\n            /* Fill with full block */\n            ProgressBar[Index] = EFI_TEXT_BOX_FULL_BLOCK;\n        }\n        else\n        {\n            /* Fill with light block */\n            ProgressBar[Index] = EFI_TEXT_BOX_LIGHT_BLOCK;\n        }\n    }\n\n    /* Terminate progress bar string */\n    ProgressBar[Index] = 0;\n\n    /* Disable cursor and write progress bar to console */\n    Console::DisableCursor();\n    Console::Write(ProgressBar);\n}\n\n/**\n * Draws a text-based boot edition menu.\n *\n * @param Handle\n *        Supplies a pointer to the edition menu handle.\n *\n * @return This function does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle)\n{\n    /* Query console screen resolution */\n    Console::QueryMode(&Handle->ResX, &Handle->ResY);\n\n    /* Set boot menu parameters */\n    Handle->Attributes = 0;\n    Handle->DialogColor = EFI_TEXT_BGCOLOR_BLACK;\n    Handle->TextColor = EFI_TEXT_FGCOLOR_LIGHTGRAY;\n    Handle->PosX = 3;\n    Handle->PosY = 3;\n    Handle->Width = Handle->ResX - 6;\n    Handle->Height = Handle->ResY - 10;\n\n    /* Clear screen and disable cursor */\n    Console::SetAttributes(Handle->DialogColor | Handle->TextColor);\n    Console::ClearScreen();\n    Console::DisableCursor();\n\n    /* Check if debugging enabled */\n    if(DEBUG)\n    {\n        /* Print debug version of XTLDR banner */\n        Console::SetCursorPosition((Handle->ResX - 44) / 2, 1);\n        Console::Print(L\"XTLDR Boot Loader v%d.%d (%s-%s)\\n\",\n                       XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR, XTOS_VERSION_DATE, XTOS_VERSION_HASH);\n    }\n    else\n    {\n        /* Print standard XTLDR banner */\n        Console::SetCursorPosition((Handle->ResX - 22) / 2, 1);\n        Console::Print(L\"XTLDR Boot Loader v%d.%d\\n\", XTLDR_VERSION_MAJOR, XTLDR_VERSION_MINOR);\n    }\n\n    /* Draw empty dialog box for boot menu */\n    DrawDialogBox(Handle, L\"Edit Options\", NULLPTR);\n\n    /* Print help message below the edit menu */\n    Console::SetCursorPosition(0, Handle->PosY + Handle->Height);\n    Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n    Console::Print(L\"    Use cursors to change the selection. Press ENTER key to edit the chosen\\n\"\n                   L\"    option, ESC to return to the main boot menu or F10 to boot.\\n\");\n}\n\n/**\n * Draws edit menu entry at the specified position.\n *\n * @param Handle\n *        Supplies a pointer to the boot menu handle.\n *\n * @param OptionName\n *        Supplies a pointer to the buffer containing a part of the menu entry name (an option name).\n *\n * @param OptionValue\n *        Supplies a pointer to the buffer containing a part of the menu entry name (an option value).\n *\n * @param Position\n *        Specifies entry position on the list in the boot menu.\n *\n * @param Highlighted\n *        Specifies whether this entry should be highlighted or not.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nTextUi::DrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,\n                          IN PCWSTR OptionName,\n                          IN PCWSTR OptionValue,\n                          IN UINT Position,\n                          IN BOOLEAN Highlighted)\n{\n    BOOLEAN Allocation;\n    PCWSTR DisplayValue, ShortValue;\n    UINT Index;\n    ULONG OptionNameLength, OptionValueLength, OptionWidth;\n    EFI_STATUS Status;\n\n    /* Assume no allocation was made */\n    Allocation = FALSE;\n\n    /* Set display value depending on input */\n    DisplayValue = (OptionValue != NULLPTR) ? OptionValue : L\"\";\n\n    /* Determine lengths */\n    OptionNameLength = RTL::WideString::WideStringLength(OptionName, 0);\n    OptionValueLength = RTL::WideString::WideStringLength(DisplayValue, 0);\n    OptionWidth = Handle->Width - 4 - (OptionNameLength + 2);\n\n    /* Check if value needs to be truncated */\n    if(OptionValueLength > OptionWidth)\n    {\n        /* Allocate buffer for new, shortened value */\n        Status = Memory::AllocatePool((OptionWidth + 1) * sizeof(WCHAR), (PVOID *)&ShortValue); // This allocates PWCHAR\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failure, print debug message and return */\n            Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n            return Status;\n        }\n\n        /* Copy a desired value length into the allocated buffer and append \"...\" */\n        RTL::Memory::CopyMemory((PWCHAR)ShortValue, DisplayValue, (OptionWidth - 3) * sizeof(WCHAR));\n        RTL::Memory::CopyMemory((PWCHAR)ShortValue + OptionWidth - 3, L\"...\", 3 * sizeof(WCHAR));\n        ((PWCHAR)ShortValue)[OptionWidth] = L'\\0';\n\n        /* Mark that allocation was made and set new display value */\n        Allocation = TRUE;\n        DisplayValue = ShortValue;\n    }\n\n    /* Move cursor to the right position */\n    Console::SetCursorPosition(5, 4 + Position);\n\n    /* Check whether this entry should be highlighted */\n    if(Highlighted)\n    {\n        /* Highlight this entry */\n        Console::SetAttributes(EFI_TEXT_BGCOLOR_LIGHTGRAY | EFI_TEXT_FGCOLOR_BLACK);\n    }\n    else\n    {\n        /* Set default colors */\n        Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);\n    }\n\n    /* Clear menu entry */\n    for(Index = 0; Index < Handle->Width - 4; Index++)\n    {\n        Console::Print(L\" \");\n    }\n\n    /* Print menu entry */\n    Console::SetCursorPosition(5, 4 + Position);\n    Console::Print(L\"%S: %S\", OptionName, DisplayValue);\n\n    /* Check if allocation was made */\n    if(Allocation)\n    {\n        /* Free allocated memory */\n        Memory::FreePool((PVOID)DisplayValue);\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Updates the progress bar on the dialog box.\n *\n * @param Handle\n *        Supplies a pointer to the dialog box handle.\n *\n * @param Message\n *        Supplies a new message that will be put on the dialog box, while updating the progress bar.\n *\n * @param Percentage\n *        Specifies the new percentage progress of the progress bar.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nTextUi::UpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle,\n                          IN PCWSTR Message,\n                          IN UCHAR Percentage)\n{\n    /* Check if message needs an update */\n    if(Message != NULLPTR)\n    {\n        /* Update a message on the dialog box */\n        DrawMessage(Handle, Message);\n    }\n\n    /* Update progress bar */\n    DrawProgressBar(Handle, Percentage);\n}\n"
  },
  {
    "path": "boot/xtldr/volume.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/volume.cc\n * DESCRIPTION:     XTLDR volume support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * This routine closes an EFI volume handle.\n *\n * @param VolumeHandle\n *        Specifies a handle of opened volume.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::CloseVolume(IN PEFI_HANDLE VolumeHandle)\n{\n    EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;\n\n    /* Make sure a handle specified */\n    if(VolumeHandle != NULLPTR)\n    {\n        /* Close a handle */\n        return XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(VolumeHandle, &LIPGuid,\n                                                                          XtLoader::GetEfiImageHandle(), NULLPTR);\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Discovers and enumerates a block devices available to EFI system.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::EnumerateBlockDevices()\n{\n    EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;\n    EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;\n    EFI_HANDLE BootDeviceHandle = NULLPTR, DeviceHandle = NULLPTR;\n    EFI_LOADED_IMAGE_PROTOCOL* LoadedImage;\n    PEFI_DEVICE_PATH_PROTOCOL DevicePath = NULLPTR, LastNode = NULLPTR;\n    PEFI_BLOCK_DEVICE_DATA ParentNode = NULLPTR;\n    PEFI_BLOCK_DEVICE_DATA BlockDeviceData;\n    PEFI_BLOCK_DEVICE BlockDevice;\n    LIST_ENTRY BlockDevices;\n    PLIST_ENTRY ListEntry;\n    EFI_STATUS Status;\n    PEFI_ACPI_HID_DEVICE_PATH AcpiDevice;\n    PEFI_HARDDRIVE_DEVICE_PATH HDPath;\n    PEFI_BLOCK_IO_MEDIA Media;\n    PEFI_GUID PartitionGuid;\n    ULONG DriveNumber, PartitionNumber;\n    USHORT DriveType;\n    ULONG CDCount = 0, FDCount = 0, HDCount = 0, RDCount = 0;\n\n    /* Get the device handle of the image that is running */\n    Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(XtLoader::GetEfiImageHandle(), &LoadedImageProtocolGuid,\n                                                                         (VOID**)&LoadedImage);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to get boot device handle */\n        Debug::Print(L\"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Save the boot device handle */\n    BootDeviceHandle = LoadedImage->DeviceHandle;\n\n    /* Initialize list entries */\n    RTL::LinkedList::InitializeListHead(&BlockDevices);\n    RTL::LinkedList::InitializeListHead(&EfiBlockDevices);\n\n    /* Discover EFI block devices and store them in linked list */\n    Status = DiscoverEfiBlockDevices(&BlockDevices);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        Debug::Print(L\"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Identify all discovered devices */\n    ListEntry = BlockDevices.Flink;\n    while(ListEntry != &BlockDevices)\n    {\n        /* Get data for the next discovered device. */\n        BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);\n        PartitionGuid = NULLPTR;\n\n        /* Find last node */\n        Status = FindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Skip this device if its last node cannot be found, as it is required for classification */\n            Debug::Print(L\"WARNING: Block device last node not found\\n\");\n            ListEntry = ListEntry->Flink;\n            continue;\n        }\n\n        /* Initialize drive type before attempting to classify the device */\n        DriveType = XTBL_BOOT_DEVICE_UNKNOWN;\n\n        /* Locate the parent for this block device to ensure it is not an orphaned entry */\n        if(!FindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode))\n        {\n            /* Orphaned device found. Log a warning and skip it as it cannot be properly classified */\n            Debug::Print(L\"WARNING: No parent device found, skipping orphaned media device path\\n\");\n            ListEntry = ListEntry->Flink;\n            continue;\n        }\n\n        /* Verify that media information is available, as some devices may not report it */\n        if(!BlockDeviceData->BlockIo->Media)\n        {\n            /* The device is unusable without media info, log a warning and skip it */\n            Debug::Print(L\"WARNING: Block device is missing media information\\n\");\n            ListEntry = ListEntry->Flink;\n            continue;\n        }\n        Media = BlockDeviceData->BlockIo->Media;\n\n        /* Check last node type */\n        if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP)\n        {\n            /* Check for Floppy EISA identifiers */\n            AcpiDevice = (PEFI_ACPI_HID_DEVICE_PATH)LastNode;\n            if(AcpiDevice->HID == 0x60441D0 || AcpiDevice->HID == 0x70041D0 || AcpiDevice->HID == 0x70141D1)\n            {\n                /* Floppy drive found */\n                DriveType = XTBL_BOOT_DEVICE_FLOPPY;\n                DriveNumber = FDCount++;\n                PartitionNumber = 0;\n\n                /* Print debug message */\n                Debug::Print(L\"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\\n\",\n                             DriveNumber, Media->MediaPresent, Media->ReadOnly);\n            }\n        }\n        else if((LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_CDROM_DP) ||\n                (LastNode->Type == EFI_MESSAGING_DEVICE_PATH &&\n                 (LastNode->SubType == EFI_MESSAGING_ATAPI_DP || LastNode->SubType == EFI_MESSAGING_SATA_DP) &&\n                 Media->MediaPresent && Media->RemovableMedia))\n        {\n            /* Optical drive found */\n            DriveType = XTBL_BOOT_DEVICE_CDROM;\n            DriveNumber = CDCount++;\n            PartitionNumber = 0;\n\n            /* Print debug message */\n            Debug::Print(L\"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\\n\",\n                         DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly);\n        }\n        else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP)\n        {\n            /* Hard disk partition found */\n            HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode;\n            DriveType = XTBL_BOOT_DEVICE_HARDDISK;\n            DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1;\n            PartitionNumber = HDPath->PartitionNumber;\n            PartitionGuid = (PEFI_GUID)HDPath->Signature;\n\n            /* Check if this is the EFI System Partition (ESP) */\n            if(BootDeviceHandle != NULLPTR)\n            {\n                /* Allocate memory for device path */\n                DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);\n                if(DevicePath != NULLPTR)\n                {\n                    /* Check if this is the boot device */\n                    Status = XtLoader::GetEfiSystemTable()->BootServices->LocateDevicePath(&BlockIoGuid, &DevicePath,\n                                                                                           &DeviceHandle);\n                    if(Status == STATUS_EFI_SUCCESS && DeviceHandle == BootDeviceHandle)\n                    {\n                        /* Mark partition as ESP */\n                        DriveType |= XTBL_BOOT_DEVICE_ESP;\n                    }\n                }\n            }\n\n            /* Print debug message */\n            Debug::Print(L\"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, \"\n                         L\"MBRType: %u, GUID: {%V}, PartSize: %lluB) %S\\n\",\n                         DriveNumber, PartitionNumber, HDPath->MBRType,\n                         PartitionGuid, HDPath->PartitionSize * Media->BlockSize,\n                         (DriveType & XTBL_BOOT_DEVICE_ESP) ? L\"(ESP)\" : L\"\");\n        }\n        else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_RAMDISK_DP)\n        {\n            /* RAM disk found */\n            DriveType = XTBL_BOOT_DEVICE_RAMDISK;\n            DriveNumber = RDCount++;\n            PartitionNumber = 0;\n\n            /* Print debug message */\n            Debug::Print(L\"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\\n\",\n                         DriveNumber, Media->MediaPresent);\n        }\n\n        /* Make sure the device found has valid type set */\n        if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN)\n        {\n            /* Allocate memory for block device */\n            Status = Memory::AllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice);\n            if(Status != STATUS_EFI_SUCCESS)\n            {\n                Debug::Print(L\"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\\n\", Status);\n                return STATUS_EFI_OUT_OF_RESOURCES;\n            }\n\n            /* Initialize block device */\n            BlockDevice->DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);\n            BlockDevice->DriveType = DriveType;\n            BlockDevice->DriveNumber = DriveNumber;\n            BlockDevice->PartitionNumber = PartitionNumber;\n            BlockDevice->PartitionGuid = PartitionGuid;\n\n            /* Add block device to global list */\n            RTL::LinkedList::InsertTailList(&EfiBlockDevices, &BlockDevice->ListEntry);\n        }\n\n        /* Get next entry from linked list */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Finds an EFI device path for a specified path on a given file system.\n *\n * @param FsHandle\n *        The handle of the corresponding file system.\n *\n * @param FileSystemPath\n *        Specifies a path on the corresponding file system.\n *\n * @param DevicePath\n *        Specifies a pointer to the memory area, where found device path will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,\n                       IN CONST PWCHAR FileSystemPath,\n                       OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath)\n{\n    EFI_STATUS Status;\n    SIZE_T FsPathLength, DevicePathLength = 0;\n    PEFI_FILEPATH_DEVICE_PATH FilePath = NULLPTR;\n    PEFI_DEVICE_PATH_PROTOCOL EndDevicePath;\n    PEFI_DEVICE_PATH_PROTOCOL DevicePathHandle;\n\n    /* Set local device path handle */\n    DevicePathHandle = FsHandle;\n\n    /* Find the end device path node */\n    while(TRUE) {\n        /* Make sure there is a next node */\n        if(*(PUSHORT)DevicePathHandle->Length == 0)\n        {\n            /* End device path not found */\n            return STATUS_EFI_NOT_FOUND;\n        }\n\n        /* Check if end device path node found */\n        if(DevicePathHandle->Type == EFI_END_DEVICE_PATH)\n        {\n            /* End device path node found */\n            break;\n        }\n\n        /* Get next node */\n        DevicePathLength += *(PUSHORT)DevicePathHandle->Length;\n        DevicePathHandle = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathHandle + *(PUSHORT)DevicePathHandle->Length);\n    }\n\n    /* Check real path length */\n    FsPathLength = RTL::WideString::WideStringLength(FileSystemPath, 0) * sizeof(WCHAR);\n\n    /* Allocate memory pool for device path */\n    Status = Memory::AllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL),\n                                     (PVOID *)DevicePath);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        return Status;\n    }\n\n    /* Set file path */\n    RTL::Memory::CopyMemory(*DevicePath, FsHandle, DevicePathLength);\n    FilePath = (PEFI_FILEPATH_DEVICE_PATH)((PUCHAR)*DevicePath + DevicePathLength);\n    FilePath->Header.Type = EFI_MEDIA_DEVICE_PATH;\n    FilePath->Header.SubType = EFI_MEDIA_FILEPATH_DP;\n    FilePath->Header.Length[0] = (UCHAR)FsPathLength + FIELD_OFFSET(EFI_FILEPATH_DEVICE_PATH, PathName) + sizeof(WCHAR);\n    FilePath->Header.Length[1] = FilePath->Header.Length[0] >> 8;\n\n    /* Set device path end node */\n    RTL::Memory::CopyMemory(FilePath->PathName, FileSystemPath, FsPathLength + sizeof(WCHAR));\n    EndDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)&FilePath->PathName[(FsPathLength / sizeof(WCHAR)) + 1];\n    EndDevicePath->Type = EFI_END_DEVICE_PATH;\n    EndDevicePath->SubType = EFI_END_ENTIRE_DP;\n    EndDevicePath->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);\n    EndDevicePath->Length[1] = 0;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Creates a copy of the system path with EFI standard directory separators.\n *\n * @param SystemPath\n *        Supplies a pointer to the system path.\n *\n * @param EfiPath\n *        Supplies a pointer to the memory area, where EFI path will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::GetEfiPath(IN PWCHAR SystemPath,\n                   OUT PWCHAR *EfiPath)\n{\n    SIZE_T Index, PathLength;\n    EFI_STATUS Status;\n\n    /* Get system path length */\n    PathLength = RTL::WideString::WideStringLength(SystemPath, 0);\n\n    /* Allocate memory for storing EFI path */\n    Status = Memory::AllocatePool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to allocate memory, print error message and return status code */\n        Debug::Print(L\"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n\", Status);\n        return STATUS_EFI_OUT_OF_RESOURCES;\n    }\n\n    /* Make a copy of SystemPath string */\n    RTL::Memory::CopyMemory(*EfiPath, SystemPath, sizeof(WCHAR) * (PathLength + 1));\n\n    /* Replace directory separator if needed to comply with EFI standard */\n    for(Index = 0; Index < PathLength; Index++)\n    {\n        if((*EfiPath)[Index] == L'/')\n        {\n            /* Replace '/' with '\\' */\n            (*EfiPath)[Index] = L'\\\\';\n        }\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Finds a volume device path based on the specified ARC name or UUID.\n *\n * @param SystemPath\n *        An input string containing ARC/UUID path.\n *\n * @param DevicePath\n *        Supplies a pointer to memory region where device path will be stored.\n *\n * @param Path\n *        Supplies a pointer to the memory area, where path on device will be saved.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::GetDevicePath(IN PWCHAR SystemPath,\n                      OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,\n                      OUT PWCHAR *ArcName,\n                      OUT PWCHAR *Path)\n{\n    PEFI_BLOCK_DEVICE Device;\n    USHORT DriveType;\n    ULONG DriveNumber;\n    ULONG PartNumber;\n    PWCHAR Volume;\n    ULONG PathLength;\n    PLIST_ENTRY ListEntry;\n    EFI_STATUS Status;\n\n    /* Make sure this is not set */\n    *DevicePath = NULLPTR;\n\n    /* Find volume path and its length */\n    Volume = SystemPath;\n    while(*Volume != '/' && *Volume != '\\\\' && *Volume != '\\0')\n    {\n        Volume++;\n    }\n    PathLength = Volume - SystemPath;\n\n    /* Check if valume path specified */\n    if(PathLength == 0)\n    {\n        /* No volume path available */\n        *Path = SystemPath;\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* Check system path format */\n    if(SystemPath[0] == '{')\n    {\n        if(PathLength == GUID_STRING_LENGTH)\n        {\n            /* This is EFI GUID */\n            Debug::Print(L\"WARNING: EFI/GPT GUID in system path is not supported\\n\");\n            return STATUS_EFI_UNSUPPORTED;\n        }\n        else if(PathLength == PARTUUID_STRING_LENGTH)\n        {\n            /* This is MBR UUID */\n            Debug::Print(L\"WARNING: MBR partition UUID in system path is not supported\\n\");\n            return STATUS_EFI_UNSUPPORTED;\n        }\n        else\n        {\n            /* Invalid UUID format */\n            return STATUS_EFI_INVALID_PARAMETER;\n        }\n    }\n    else\n    {\n        /* Defaults to ARC path, dissect it */\n        Status = DissectArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber);\n    }\n\n    /* Check if volume path parsed successfully */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to parse system path */\n        Debug::Print(L\"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\\n\", SystemPath, Status);\n        return Status;\n    }\n\n    /* Look for block device corresponding to dissected ARC path */\n    ListEntry = EfiBlockDevices.Flink;\n    while(ListEntry != &EfiBlockDevices)\n    {\n        /* Check if this is the volume we are looking for */\n        Device = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE, ListEntry);\n        if(DriveType == XTBL_BOOT_DEVICE_ESP)\n        {\n            /* ESP requested, verify if flag is set for this device */\n            if((Device->DriveType & XTBL_BOOT_DEVICE_ESP) != 0)\n            {\n                /* Found volume */\n                *DevicePath = Device->DevicePath;\n                break;\n            }\n        }\n        else\n        {\n            if(((Device->DriveType & DriveType) == DriveType) &&\n               (Device->DriveNumber == DriveNumber) &&\n               (Device->PartitionNumber == PartNumber))\n            {\n                /* Found volume */\n                *DevicePath = Device->DevicePath;\n                break;\n            }\n        }\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Check if volume was found */\n    if(*DevicePath == NULLPTR)\n    {\n        /* Volume not found */\n        Debug::Print(L\"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\\n\",\n                     DriveType, DriveNumber, PartNumber);\n        return STATUS_EFI_NOT_FOUND;\n    }\n\n    /* return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine opens an EFI volume and corresponding filesystem.\n *\n * @param DevicePath\n *        Specifies a device path of the volume to open. If not specifies, uses image protocol by default.\n *\n * @param DiskHandle\n *        The handle of the opened disk volume.\n *\n * @param FsHandle\n *        The handle of the opened file system.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,\n                   OUT PEFI_HANDLE DiskHandle,\n                   OUT PEFI_FILE_HANDLE *FsHandle)\n{\n    EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;\n    EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;\n    PEFI_SIMPLE_FILE_SYSTEM_PROTOCOL FileSystemProtocol;\n    PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;\n    EFI_STATUS Status;\n\n    /* Check if device path has been passed or not */\n    if(DevicePath != NULLPTR)\n    {\n        /* Locate the device path */\n        Status = XtLoader::GetEfiSystemTable()->BootServices->LocateDevicePath(&SFSGuid, &DevicePath, DiskHandle);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to locate device path */\n            return Status;\n        }\n    }\n    else\n    {\n        /* Open the image protocol if no device path specified */\n        Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(XtLoader::GetEfiImageHandle(),\n                                                                           &LIPGuid,\n                                                                           (PVOID *)&ImageProtocol,\n                                                                           XtLoader::GetEfiImageHandle(),\n                                                                           NULLPTR,\n                                                                           EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Failed to open image protocol */\n            return Status;\n        }\n\n        /* Store disk handle */\n        *DiskHandle = ImageProtocol->DeviceHandle;\n    }\n\n    /* Open the filesystem protocol */\n    Status = XtLoader::GetEfiSystemTable()->BootServices->OpenProtocol(*DiskHandle, &SFSGuid,\n                                                                       (PVOID *)&FileSystemProtocol,\n                                                                       XtLoader::GetEfiImageHandle(), NULLPTR,\n                                                                       EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);\n\n    /* Check if filesystem protocol opened successfully */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open the filesystem protocol, close volume */\n        CloseVolume(DiskHandle);\n        return Status;\n    }\n\n    /* Open the corresponding filesystem */\n    Status = FileSystemProtocol->OpenVolume(FileSystemProtocol, FsHandle);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open the filesystem, close volume */\n        CloseVolume(DiskHandle);\n        return Status;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Reads data from the file.\n *\n * @param DirHandle\n *        Supplies a handle of the opened filesystem directory.\n *\n * @param FileName\n *        Supplies the name of the file to read.\n *\n * @param FileData\n *        Provides a buffer to store the data read from the file.\n *\n * @param FileSize\n *        Provides a pointer to the variable to store a size of the buffer.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::ReadFile(IN PEFI_FILE_HANDLE DirHandle,\n                 IN PCWSTR FileName,\n                 OUT PVOID *FileData,\n                 OUT PSIZE_T FileSize)\n{\n    EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID;\n    EFI_PHYSICAL_ADDRESS Address;\n    PEFI_FILE_HANDLE FileHandle;\n    PEFI_FILE_INFO FileInfo;\n    EFI_STATUS Status;\n    UINT_PTR ReadSize;\n    SIZE_T Pages;\n\n    Status = DirHandle->Open(DirHandle, &FileHandle, (PWCHAR)FileName, EFI_FILE_MODE_READ,\n                             EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to open file */\n        return Status;\n    }\n\n    /* Set required size for getting file information */\n    ReadSize = sizeof(EFI_FILE_INFO) + 32;\n\n    /* Allocate necessary amount of memory */\n    Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Memory allocation failure */\n        FileHandle->Close(FileHandle);\n        return Status;\n    }\n\n    /* First attempt to get file information */\n    FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo);\n    if(Status == STATUS_EFI_BUFFER_TOO_SMALL)\n    {\n        /* Buffer is too small, but EFI tells the required size, so reallocate */\n        Memory::FreePool(&FileInfo);\n        Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failure */\n            FileHandle->Close(FileHandle);\n            return Status;\n        }\n\n        /* Second attempt to get file information */\n        Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo);\n    }\n\n    /* Check if file information got successfully */\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Unable to get file information */\n        FileHandle->Close(FileHandle);\n        Memory::FreePool(&FileInfo);\n        return Status;\n    }\n\n    /* Store file size and calculate number of pages */\n    *FileSize = FileInfo->FileSize;\n    Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize);\n\n    /* Allocate pages */\n    Status = Memory::AllocatePages(AllocateAnyPages, Pages, &Address);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Pages allocation failure */\n        FileHandle->Close(FileHandle);\n        Memory::FreePool(&FileInfo);\n        return Status;\n    }\n\n    /* Calculate number of bytes to read and zero memory */\n    ReadSize = Pages * EFI_PAGE_SIZE;\n    *FileData = (PCHAR)(UINT_PTR)Address;\n    RTL::Memory::ZeroMemory(*FileData, ReadSize);\n\n    /* Read data from the file */\n    Status = FileHandle->Read(FileHandle, &ReadSize, *FileData);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to read data */\n        FileHandle->Close(FileHandle);\n        Memory::FreePool(&FileInfo);\n        Memory::FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData);\n        return Status;\n    }\n\n    /* Close handle and free memory */\n    FileHandle->Close(FileHandle);\n    Memory::FreePool(FileInfo);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Gets a list of block devices from an EFI enabled BIOS.\n *\n * @param BlockDevices\n *        Supplies a pointer to a variable to receive a list of EFI block devices.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)\n{\n    EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;\n    EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;\n    PEFI_DEVICE_PATH_PROTOCOL DevicePath;\n    PEFI_BLOCK_DEVICE_DATA BlockDevice;\n    UINT_PTR HandlesCount, Index;\n    PEFI_HANDLE Handles = NULLPTR;\n    PEFI_BLOCK_IO_PROTOCOL Io;\n    EFI_STATUS Status;\n\n    /* Locate handles which support the disk I/O interface */\n    Status = Protocol::LocateProtocolHandles(&Handles, &HandlesCount, &IoGuid);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to locate handles */\n        Debug::Print(L\"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Iterate through all handles */\n    for(Index = 0; Index < HandlesCount; Index++)\n    {\n        /* Print debug message */\n        Debug::Print(L\"Opening %lu block device from %lu discovered\\n\", Index + 1, HandlesCount);\n\n        /* Open I/O protocol for given handle */\n        Io = NULLPTR;\n        Status = Protocol::OpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid);\n        if(Status != STATUS_EFI_SUCCESS || Io == NULLPTR)\n        {\n            /* Failed to open I/O protocol, skip it */\n            Debug::Print(L\"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\\n\", Status);\n            continue;\n        }\n\n        /* Check if this is iPXE stub */\n        if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U)\n        {\n            /* Skip stub as it is non-functional */\n            Debug::Print(L\"WARNING: Skipping iPXE stub block I/O protocol\");\n            continue;\n        }\n\n        /* Check if DevicePath protocol is supported by this handle */\n        DevicePath = NULLPTR;\n        Status = XtLoader::GetEfiSystemTable()->BootServices->HandleProtocol(Handles[Index], &DevicePathGuid,\n                                                                             (PVOID *)&DevicePath);\n        if(Status != STATUS_EFI_SUCCESS || DevicePath == NULLPTR)\n        {\n            /* Device failed to handle DP protocol */\n            Debug::Print(L\"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\\n\", Status);\n            XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &IoGuid,\n                                                                       XtLoader::GetEfiImageHandle(), NULLPTR);\n            continue;\n        }\n\n        /* Allocate memory for block device */\n        Status = Memory::AllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Memory allocation failure */\n            Debug::Print(L\"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\\n\", Status);\n            XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid,\n                                                                       XtLoader::GetEfiImageHandle(), NULLPTR);\n            XtLoader::GetEfiSystemTable()->BootServices->CloseProtocol(Handles[Index], &IoGuid,\n                                                                       XtLoader::GetEfiImageHandle(), NULLPTR);\n            return Status;\n        }\n\n        /* Store new block device into a linked list */\n        BlockDevice->BlockIo = Io;\n        BlockDevice->DevicePath = DevicePath;\n        RTL::LinkedList::InsertTailList(BlockDevices, &BlockDevice->ListEntry);\n    }\n\n    /* Free handles buffer */\n    Memory::FreePool(Handles);\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * Dissects a specified ARC name and provides detailed information about corresponding device and on disk path.\n *\n * @param SystemPath\n *        Supplies an input ARC path.\n *\n * @param Path\n *        Specifies a pointer to variable, where on disk path will be saved.\n *\n * @param DriveType\n *        Supplies a pointer to the variable that receives a drive type.\n *\n * @param DriveNumber\n *        Supplies a pointer to the variable that receives a drive number.\n *\n * @param PartNumber\n *        Supplies a pointer to the variable that receives a parition number if applicable, otherwise stores 0 (zero).\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::DissectArcPath(IN PWCHAR SystemPath,\n                       OUT PWCHAR *ArcName,\n                       OUT PWCHAR *Path,\n                       OUT PUSHORT DriveType,\n                       OUT PULONG DriveNumber,\n                       OUT PULONG PartNumber)\n{\n    PWCHAR ArcPath, LocalArcName;\n    ULONG ArcLength = 0;\n\n    /* Set default values */\n    *DriveType = XTBL_BOOT_DEVICE_UNKNOWN;\n    *DriveNumber = 0;\n    *PartNumber = 0;\n\n    /* Look for the ARC path */\n    if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L\"ramdisk(0)\", 0) == 0)\n    {\n        /* This is RAM disk */\n        ArcLength = 10;\n        *DriveType = XTBL_BOOT_DEVICE_RAMDISK;\n    }\n    else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L\"multi(0)esp(0)\", 0) == 0)\n    {\n        /* This is ESP */\n        ArcLength = 14;\n        *DriveType = XTBL_BOOT_DEVICE_ESP;\n    }\n    else if(RTL::WideString::CompareWideStringInsensitive(SystemPath, L\"multi(0)disk(0)\", 0) == 0)\n    {\n        /* This is a multi-disk port */\n        ArcLength = 15;\n        ArcPath = SystemPath + ArcLength;\n\n        /* Check for disk type */\n        if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L\"cdrom(\", 0) == 0)\n        {\n            /* This is an optical drive */\n            ArcLength += 6;\n\n            /* Find drive number */\n            while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\\0')\n            {\n                if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9')\n                {\n                    /* Calculate drive number */\n                    *DriveNumber *= 10;\n                    *DriveNumber += SystemPath[ArcLength] - '0';\n                }\n                ArcLength++;\n            }\n\n            /* Set proper drive type */\n            *DriveType = XTBL_BOOT_DEVICE_CDROM;\n            ArcLength++;\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L\"fdisk(\", 0) == 0)\n        {\n            /* This is a floppy drive */\n            ArcLength += 6;\n\n            /* Find drive number */\n            while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\\0')\n            {\n                if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9')\n                {\n                    /* Calculate drive number */\n                    *DriveNumber *= 10;\n                    *DriveNumber += SystemPath[ArcLength] - '0';\n                }\n                ArcLength++;\n            }\n\n            /* Set proper drive type */\n            *DriveType = XTBL_BOOT_DEVICE_FLOPPY;\n            ArcLength++;\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L\"rdisk(\", 0) == 0)\n        {\n            /* This is a hard disk */\n            ArcLength += 6;\n\n            /* Find drive number */\n            while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\\0')\n            {\n                if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9')\n                {\n                    /* Calculate drive number */\n                    *DriveNumber *= 10;\n                    *DriveNumber += SystemPath[ArcLength] - '0';\n                }\n                ArcLength++;\n            }\n\n            /* Set proper drive type */\n            *DriveType = XTBL_BOOT_DEVICE_HARDDISK;\n            ArcLength++;\n            ArcPath = SystemPath + ArcLength;\n\n            /* Look for a partition */\n            if(RTL::WideString::CompareWideStringInsensitive(ArcPath, L\"partition(\", 0) == 0)\n            {\n                /* Partition information found */\n                ArcLength += 10;\n\n                /* Find partition number */\n                while(SystemPath[ArcLength] != ')' && SystemPath[ArcLength] != '\\0')\n                {\n                    if(SystemPath[ArcLength] >= '0' && SystemPath[ArcLength] <= '9')\n                    {\n                        /* Calculate partition number */\n                        *PartNumber *= 10;\n                        *PartNumber += SystemPath[ArcLength] - '0';\n                    }\n                    ArcLength++;\n                }\n                ArcLength++;\n            }\n        }\n        else\n        {\n            /* Unsupported disk type */\n            return STATUS_EFI_UNSUPPORTED;\n        }\n    }\n    else\n    {\n        /* Unsupported ARC path */\n        return STATUS_EFI_UNSUPPORTED;\n    }\n\n    /* Store the path if possible */\n    if(Path)\n    {\n        *Path = SystemPath + ArcLength;\n    }\n\n    /* Store ARC name if possible */\n    if(ArcName)\n    {\n        Memory::AllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName);\n        RTL::Memory::CopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR));\n        LocalArcName[ArcLength] = '\\0';\n        *ArcName = LocalArcName;\n    }\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine duplicates a device path object.\n *\n * @param DevicePath\n *        An input device path that is going to be clonned.\n *\n * @return Returns a duplicate of input device path.\n *\n * @since XT 1.0\n */\nXTCDECL\nPEFI_DEVICE_PATH_PROTOCOL\nVolume::DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)\n{\n    PEFI_DEVICE_PATH_PROTOCOL DevicePathNode;\n    PEFI_DEVICE_PATH_PROTOCOL DevicePathClone;\n    EFI_STATUS Status;\n    UINT Length = 0;\n\n    /* Check if the input device path is NULL pointer */\n    if(!DevicePath)\n    {\n        /* Nothing to duplicate */\n        return NULLPTR;\n    }\n\n    /* Start iterating from the beginning of the device path */\n    DevicePathNode = DevicePath;\n\n    /* Get the device path length */\n    while(TRUE)\n    {\n        Length += *(PUSHORT)DevicePathNode->Length;\n        if(DevicePathNode->Type == EFI_END_DEVICE_PATH)\n        {\n            break;\n        }\n        DevicePathNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)DevicePathNode + *(PUSHORT)DevicePathNode->Length);\n    }\n\n    /* Check length */\n    if(Length == 0)\n    {\n        /* Nothing to duplicate */\n        return NULLPTR;\n    }\n\n    /* Allocate memory for the new device path */\n    Status = Memory::AllocatePool(Length, (PVOID *)&DevicePathClone);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to allocate memory */\n        Debug::Print(L\"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\\n\", Status);\n        return NULLPTR;\n    }\n\n    /* Copy the device path */\n    RTL::Memory::CopyMemory(DevicePathClone, DevicePath, Length);\n\n    /* Return the cloned object */\n    return DevicePathClone;\n}\n\n/**\n * Attempts to find a last node of the EFI block device.\n *\n * @param DevicePath\n *        An input device path.\n *\n * @param LastNode\n *        A pointer to the buffer where last node will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nVolume::FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,\n                                OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode)\n{\n    PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode;\n\n    /* Make sure end is not reached yet */\n    if(DevicePath->Type == EFI_END_DEVICE_PATH)\n    {\n        /* End reached, nothing to do */\n        LastNode = NULLPTR;\n        return STATUS_EFI_INVALID_PARAMETER;\n    }\n\n    /* Fast forward to the last node */\n    EndNode = DevicePath;\n    while(EndNode->Type != EFI_END_DEVICE_PATH)\n    {\n        NextNode = EndNode;\n        EndNode = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)EndNode + *(PUSHORT)EndNode->Length);\n    }\n\n    /* Store last node found */\n    *LastNode = NextNode;\n\n    /* Return success */\n    return STATUS_EFI_SUCCESS;\n}\n\n/**\n * This routine attempts to find a parent device of the provided block device.\n *\n * @param BlockDevice\n *        A linked list of discovered block devices.\n *\n * @param ChildNode\n *        Block device that is looking for a parent device.\n *\n * @param ParentNode\n *        A pointer to memory region where pointer to the parent node will be provided.\n *\n * @return This routine returns TRUE if parent node has been found, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nVolume::FindParentBlockDevice(IN PLIST_ENTRY BlockDevices,\n                              IN PEFI_BLOCK_DEVICE_DATA ChildNode,\n                              OUT PEFI_BLOCK_DEVICE_DATA *ParentNode)\n{\n    PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath;\n    PEFI_BLOCK_DEVICE_DATA BlockDeviceData;\n    UINT ChildLength, ParentLength;\n    PLIST_ENTRY ListEntry;\n\n    ListEntry = BlockDevices->Flink;\n    while(ListEntry != BlockDevices)\n    {\n        /* Take block device from the list */\n        BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);\n\n        /* A device cannot be its own parent */\n        if (BlockDeviceData == ChildNode)\n        {\n            /* Move to the next device */\n            ListEntry = ListEntry->Flink;\n            continue;\n        }\n\n        ChildDevicePath = ChildNode->DevicePath;\n        ParentDevicePath = BlockDeviceData->DevicePath;\n\n        /* Iterate nodes */\n        while(TRUE)\n        {\n            /* Check if the parent device is a match */\n            if(ParentDevicePath->Type == EFI_END_DEVICE_PATH)\n            {\n                /* Parent device is a match */\n                *ParentNode = BlockDeviceData;\n                return TRUE;\n            }\n\n            /* Get child and parent node lengths */\n            ChildLength = *(PUSHORT)ChildDevicePath->Length;\n            ParentLength = *(PUSHORT)ParentDevicePath->Length;\n\n            /* Check if nodes match */\n            if((ChildLength != ParentLength) ||\n               (RTL::Memory::CompareMemory(ChildDevicePath, ParentDevicePath, ParentLength) != ParentLength))\n            {\n                /* Nodes do not match, this is not a valid parent */\n                break;\n            }\n\n            /* Move to the next child and parent nodes */\n            ChildDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)ChildDevicePath + ChildLength);\n            ParentDevicePath = (PEFI_DEVICE_PATH_PROTOCOL)((PUCHAR)ParentDevicePath + ParentLength);\n        }\n\n        /* Get next entry from linked list */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Apparently not found a parent node */\n    return FALSE;\n}\n"
  },
  {
    "path": "boot/xtldr/xtldr.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtldr/xtldr.cc\n * DESCRIPTION:     XTOS UEFI Boot Loader\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtldr.hh>\n\n\n/**\n * Disables access to EFI Boot Services.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nXtLoader::DisableBootServices()\n{\n    LoaderStatus.BootServices = FALSE;\n\n}\n\n/**\n * Queries the availability of EFI Boot Services.\n *\n * @return This routine returns TRUE if EFI Boot Services are available, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nXtLoader::GetBootServicesStatus()\n{\n    return LoaderStatus.BootServices;\n}\n\n/**\n * Retrieves the EFI image handle.\n *\n * @return This routine returns a handle to the EFI-loaded image.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_HANDLE\nXtLoader::GetEfiImageHandle()\n{\n    return XtLoader::EfiImageHandle;\n}\n\n/**\n * Retrieves the EFI system table pointer.\n *\n * @return This routine returns a pointer to the EFI system table.\n *\n * @since XT 1.0\n */\nXTCDECL\nPEFI_SYSTEM_TABLE\nXtLoader::GetEfiSystemTable()\n{\n    return XtLoader::EfiSystemTable;\n}\n\n/**\n * Provides base address and size of the XTLDR image.\n *\n * @param LoaderBase\n *        Supplies a pointer to a variable that receives the base address of the XTLDR image.\n *\n * @param LoaderSize\n *        Supplies a pointer to a variable that receives the size of the XTLDR image.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nXtLoader::GetLoaderImageInformation(PVOID *LoaderBase,\n                                    PULONGLONG LoaderSize)\n{\n    *LoaderBase = XtLoader::LoaderStatus.LoaderBase;\n    *LoaderSize = XtLoader::LoaderStatus.LoaderSize;\n}\n\n/**\n * Retrieves the Secure Boot status.\n *\n * @return This routine returns SecureBoot status.\n *\n * @since XT 1.0\n */\nXTCDECL\nINT_PTR\nXtLoader::GetSecureBootStatus()\n{\n    return LoaderStatus.SecureBoot;\n}\n\n/**\n * Initializes EFI Boot Loader (XTLDR).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nXtLoader::InitializeBootLoader(IN EFI_HANDLE ImageHandle,\n                               IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;\n    PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;\n    EFI_HANDLE Handle;\n    EFI_STATUS Status;\n\n    /* Set the system table and image handle */\n    EfiImageHandle = ImageHandle;\n    EfiSystemTable = SystemTable;\n\n    /* Set current XTLDR's EFI BootServices status */\n    LoaderStatus.BootServices = TRUE;\n\n    /* Initialize console */\n    Console::InitializeConsole();\n\n    /* Print XTLDR version */\n    Console::Print(L\"XTLDR boot loader v%s\\n\", XTOS_VERSION);\n\n    /* Initialize XTLDR protocol */\n    Protocol::InitializeProtocol();\n\n    /* Initialize XTLDR configuration */\n    Configuration::InitializeConfiguration();\n\n    /* Store SecureBoot status */\n    LoaderStatus.SecureBoot = EfiUtils::GetSecureBootStatus();\n\n    /* Attempt to open EFI LoadedImage protocol */\n    Status = Protocol::OpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid);\n    if(Status == STATUS_EFI_SUCCESS)\n    {\n        /* Store boot loader image base and size */\n        LoaderStatus.LoaderBase = LoadedImage->ImageBase;\n        LoaderStatus.LoaderSize = LoadedImage->ImageSize;\n\n        /* Check if debug is enabled */\n        if(DEBUG)\n        {\n            /* Protocol opened successfully, print useful debug information */\n            Console::Print(L\"\\n---------- BOOTLOADER DEBUG ----------\\n\"\n                           L\"Pointer Size       : %d\\n\"\n                           L\"Image Base Address : %P\\n\"\n                           L\"Image Base Size    : 0x%lX\\n\"\n                           L\"Image Revision     : 0x%lX\\n\"\n                           L\"Secure Boot Status : %zd\\n\"\n                           L\"--------------------------------------\\n\",\n                           sizeof(PVOID),\n                           LoadedImage->ImageBase,\n                           LoadedImage->ImageSize,\n                           LoadedImage->Revision,\n                           LoaderStatus.SecureBoot);\n            EfiUtils::SleepExecution(3000);\n        }\n\n        /* Close EFI LoadedImage protocol */\n        Protocol::CloseProtocol(&Handle, &LipGuid);\n    }\n}\n\n/**\n * Registers a boot menu callback routine, that will be used to display alternative boot menu.\n *\n * @param BootMenuRoutine\n *        Supplies a pointer to the boot menu callback routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nXtLoader::RegisterBootMenu(IN PVOID BootMenuRoutine)\n{\n    /* Set boot menu routine */\n    BootMenu = (PBL_XT_BOOT_MENU)BootMenuRoutine;\n}\n\n/**\n * Invokes either a custom boot menu handler, if one has been registered, or displays the default boot menu.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nXtLoader::ShowBootMenu()\n{\n    /* Check if custom boot menu registered */\n    if(BootMenu != NULLPTR)\n    {\n        /* Display alternative boot menu */\n        BootMenu();\n    }\n    else\n    {\n        /* Display default boot menu */\n        TextUi::DisplayBootMenu();\n    }\n}\n\n/**\n * This routine is the entry point of the XT EFI boot loader.\n *\n * @param ImageHandle\n *        Firmware-allocated handle that identifies the image.\n *\n * @param SystemTable\n *        Provides the EFI system table.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nEFI_STATUS\nBlStartXtLoader(IN EFI_HANDLE ImageHandle,\n                IN PEFI_SYSTEM_TABLE SystemTable)\n{\n    PWCHAR Modules;\n    EFI_STATUS Status;\n\n    /* Check if system is EFI-based and provided parameters are valid */\n    if(ImageHandle == NULLPTR || SystemTable == NULLPTR)\n    {\n        /* Invalid parameters, print error message using BIOS calls and hang */\n        BiosUtils::ClearScreen();\n        BiosUtils::Print(L\"XTLDR requires EFI-based system!\");\n        for(;;);\n    }\n\n    /* Initialize XTLDR and */\n    XtLoader::InitializeBootLoader(ImageHandle, SystemTable);\n\n    /* Parse configuration options passed from UEFI shell */\n    Status = Configuration::ParseCommandLine();\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to parse command line options */\n        TextUi::DisplayErrorDialog(L\"XTLDR\", L\"Failed to parse command line parameters.\");\n    }\n\n    /* Attempt to early initialize debug console */\n    if(DEBUG)\n    {\n        Status = Debug::InitializeDebugConsole();\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Initialization failed, notify user on stdout */\n            TextUi::DisplayErrorDialog(L\"XTLDR\", L\"Failed to initialize debug console.\");\n        }\n    }\n\n    /* Load XTLDR configuration file */\n    Status = Configuration::LoadConfiguration();\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to load/parse config file */\n        TextUi::DisplayErrorDialog(L\"XTLDR\", L\"Failed to load and parse configuration file \");\n    }\n\n    /* Reinitialize debug console if it was not initialized earlier */\n    if(DEBUG)\n    {\n        Status = Debug::InitializeDebugConsole();\n        if(Status != STATUS_EFI_SUCCESS)\n        {\n            /* Initialization failed, notify user on stdout */\n            TextUi::DisplayErrorDialog(L\"XTLDR\", L\"Failed to initialize debug console.\");\n        }\n    }\n\n    /* Disable watchdog timer */\n    Status = XtLoader::GetEfiSystemTable()->BootServices->SetWatchdogTimer(0, 0x10000, 0, NULLPTR);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to disable the timer, print message */\n        Debug::Print(L\"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\\n\", Status);\n    }\n\n    /* Install loader protocol */\n    Status = Protocol::InstallXtLoaderProtocol();\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to register loader protocol */\n        Debug::Print(L\"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Load all necessary modules */\n    Configuration::GetValue(L\"MODULES\", &Modules);\n    Status = Protocol::LoadModules(Modules);\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to load modules */\n        Debug::Print(L\"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\\n\", Status);\n        TextUi::DisplayErrorDialog(L\"XTLDR\", L\"Failed to load some XTLDR modules.\");\n    }\n\n    /* Discover and enumerate EFI block devices */\n    Status = Volume::EnumerateBlockDevices();\n    if(Status != STATUS_EFI_SUCCESS)\n    {\n        /* Failed to enumerate block devices */\n        Debug::Print(L\"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\\n\", Status);\n        return Status;\n    }\n\n    /* Main boot loader loop */\n    while(TRUE)\n    {\n        /* Show boot menu */\n        XtLoader::ShowBootMenu();\n\n        /* Fallback to shell, if boot menu returned */\n        Shell::StartLoaderShell();\n    }\n\n    /* This point should be never reached, if this happen return error code */\n    return STATUS_EFI_LOAD_ERROR;\n}\n"
  },
  {
    "path": "configure.ps1",
    "content": "# PROJECT:     ExectOS\n# LICENSE:     See the COPYING.md in the top level directory\n# FILE:        configure.ps1\n# DESCRIPTION: Project configuration script for preparing the build environment\n# DEVELOPERS:  Aiken Harris <harraiken91@gmail.com>\n\n# Check XTchain\nif (-not $env:XTCVER) {\n    Write-Error \"XTChain not detected or corrupted!\"\n    exit 1\n}\n\n# Set target architecture defaulting to amd64\n$ARCH = if ($env:TARGET) { $env:TARGET } else { \"amd64\" }\n\n# Set target build type defaulting to Debug\n$env:BUILD_TYPE = if ($env:BUILD_TYPE -in @(\"Debug\", \"Release\")) { $env:BUILD_TYPE } else { \"Debug\" }\n\n# Set variables\n$EXECTOS_SOURCE_DIR = $PSScriptRoot\n$EXECTOS_BINARY_DIR = Join-Path $EXECTOS_SOURCE_DIR \"build-$ARCH-$($env:BUILD_TYPE.ToLower())\"\n\n# Create build directory\nif (-not (Test-Path $EXECTOS_BINARY_DIR)) {\n    Write-Host \"Creating build directory: $EXECTOS_BINARY_DIR\"\n    New-Item -ItemType Directory -Path $EXECTOS_BINARY_DIR -Force | Out-Null\n}\n\nSet-Location $EXECTOS_BINARY_DIR\n\n# Delete old cache\nRemove-Item \"CMakeCache.txt\", \"host-tools/CMakeCache.txt\" -ErrorAction SilentlyContinue\n\n# Configure project using CMake\n& cmake -G Ninja \"-DARCH:STRING=$ARCH\" \"-DBUILD_TYPE:STRING=$($env:BUILD_TYPE)\" $EXECTOS_SOURCE_DIR\n\n# Check if configuration succeeded\nif ($LASTEXITCODE -ne 0) {\n    Write-Error \"Configure script failed.\"\n    exit 1\n}\n\n$ARCH | Out-File -Encoding ASCII -NoNewline \"build.arch\"\nWrite-Host \"Configure completed. Run 'xbuild' to build ExectOS.\""
  },
  {
    "path": "configure.sh",
    "content": "#!/bin/bash\n# PROJECT:     ExectOS\n# LICENSE:     See the COPYING.md in the top level directory\n# FILE:        configure.sh\n# DESCRIPTION: Project configuration script for preparing the build environment\n# DEVELOPERS:  Rafal Kupiec <belliash@codingworkshop.eu.org>\n\n\n# Check XTCHain\nif [ \"x${XTCVER}\" = \"x\" ]; then\n\techo \"XTChain not detected or corrupted!\"\n\texit 1\nfi\n\n# Set target architecture\n: ${ARCH:=${TARGET}}\n: ${ARCH:=amd64}\n\n# Set target build type\n: ${BUILD_TYPE:=${BUILD_TYPE}}\n: ${BUILD_TYPE:=DEBUG}\n\n# Set variables\nEXECTOS_SOURCE_DIR=$(cd `dirname ${0}` && pwd)\nEXECTOS_BINARY_DIR=build-${ARCH}-${BUILD_TYPE,,}\n\n# Create directories if needed\nif [ \"${EXECTOS_SOURCE_DIR}\" = \"${PWD}\" ]; then\n\techo Creating directories in ${EXECTOS_BINARY_DIR}\n\tmkdir -p \"${EXECTOS_BINARY_DIR}\"\n\tcd \"${EXECTOS_BINARY_DIR}\"\nfi\n\n# Delete old cache\nrm -f CMakeCache.txt host-tools/CMakeCache.txt\n\n# Configure project\ncmake -G Ninja -DARCH:STRING=${ARCH} -DBUILD_TYPE:STRING=${BUILD_TYPE} \"${EXECTOS_SOURCE_DIR}\"\n\n# Check if configuration succeeded\nif [ ${?} -ne 0 ]; then\n    echo \"Configure script failed.\"\n    exit 1\nelse\n\techo \"${ARCH}\" > build.arch\n    echo \"Configure script completed. Enter '${EXECTOS_BINARY_DIR}' directory and execute 'xbuild' to build ExectOS.\"\nfi\n"
  },
  {
    "path": "drivers/CMakeLists.txt",
    "content": "add_subdirectory(ntosdrv)\n"
  },
  {
    "path": "drivers/ntosdrv/CMakeLists.txt",
    "content": "# NTOS compatibility driver\nPROJECT(NTOSDRV)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk)\n\n# Specify list of source code files\nlist(APPEND NTOSDRV_SOURCE\n    ${NTOSDRV_SOURCE_DIR}/ntosdrv.cc\n    ${NTOSDRV_SOURCE_DIR}/rtl.cc)\n\n# Set module definition SPEC file\nset_specfile(ntosdrv.spec ntosdrv.sys)\n\n# Link bootloader executable\nadd_executable(ntosdrv ${NTOSDRV_SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/ntosdrv.def)\n\n# Add linker libraries\ntarget_link_libraries(ntosdrv xtoskrnl)\n\n# Set proper binary name and install target\nset_target_properties(ntosdrv PROPERTIES SUFFIX .sys)\nset_install_target(ntosdrv \"exectos/drivers\")\n\n# Set loader entrypoint and subsystem\nset_entrypoint(ntosdrv \"XtDriverEntry\")\nset_linker_map(ntosdrv TRUE)\nset_ordinals(ntosdrv TRUE)\nset_subsystem(ntosdrv native xt_native_driver)\n"
  },
  {
    "path": "drivers/ntosdrv/ntosdrv.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            drivers/ntosdrv/ntosdrv.cc\n * DESCRIPTION:     NTOS compatibility driver\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtkmapi.h>\n\n\n/**\n * This routine is the entry point of the driver.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nXTSTATUS\nXtDriverEntry(VOID)\n{\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "drivers/ntosdrv/ntosdrv.spec",
    "content": "# NT compatibilty layer exports\n@ fastcall ExRundownCompleted(ptr) ExCompleteRundownProtection\n@ stdcall RtlFillMemory(ptr long long)\n"
  },
  {
    "path": "drivers/ntosdrv/rtl.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            drivers/ntosdrv/rtl.cc\n * DESCRIPTION:     NTOS compatibility driver runtime library\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtkmapi.h>\n\n\n/**\n * This routine fills a section of memory with a specified byte.\n *\n * @param Destination\n *        Supplies a pointer to the buffer to fill.\n *\n * @param Length\n *        Specifies a number of bytes to store in memory.\n *\n * @param Byte\n *        Supplies a pattern to fill memory.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlFillMemory(OUT PVOID Destination,\n              IN SIZE_T Length,\n              IN UCHAR Byte)\n{\n    /* Fill the buffer with specified byte */\n    RtlSetMemory(Destination, Byte, Length);\n}\n"
  },
  {
    "path": "sdk/CMakeLists.txt",
    "content": "add_subdirectory(\"xtadk\")\n\nset_sdk_target(\"xtdk/\" \"include\")\n"
  },
  {
    "path": "sdk/cmake/README.md",
    "content": "## Cmake Build System\nThis directory contains a set of .cmake files that provide the necessary configuration and functionality for the build\nprocess. These files provide the necessary toolchain configuration, additional functions for the build system, and QEMU\nconfiguration for testing the XT Operating System.\n"
  },
  {
    "path": "sdk/cmake/baseaddress/amd64.cmake",
    "content": "# Set base addresses for all modules\nset(BASEADDRESS_XTLDR    0x000000000000F800)\nset(BASEADDRESS_XTOSKRNL 0x0000000140000000)\n"
  },
  {
    "path": "sdk/cmake/baseaddress/i686.cmake",
    "content": "# Set base addresses for all modules\nset(BASEADDRESS_XTLDR    0x0000F800)\nset(BASEADDRESS_XTOSKRNL 0x00400000)\n"
  },
  {
    "path": "sdk/cmake/emulation.cmake",
    "content": "# Architecture specific QEMU settings\nif(ARCH STREQUAL i686)\n\tset(QEMU_COMMAND \"qemu-system-i386\")\nelseif(ARCH STREQUAL amd64)\n\tset(QEMU_COMMAND \"qemu-system-x86_64\")\nendif()\n\n# This target creates a disk image\nadd_custom_target(diskimg\n                  DEPENDS install\n                  COMMAND diskimg -c ${EXECTOS_BINARY_DIR}/output/binaries -f 32 -o ${EXECTOS_BINARY_DIR}/output/disk.img -s ${PROJECT_DISK_IMAGE_SIZE}\n                  -m ${EXECTOS_BINARY_DIR}/boot/bootsect/mbrboot.bin -v ${EXECTOS_BINARY_DIR}/boot/bootsect/espboot.bin\n                  VERBATIM)\n\nfind_program(BOCHS_EMULATOR bochs)\nif(BOCHS_EMULATOR)\n    # This target starts up a BOCHS+BIOS virtual machine\n    add_custom_target(bochsvm\n                      DEPENDS diskimg\n                      COMMAND bochs -f ../sdk/firmware/bochsrc_${ARCH}.cfg -q -unlock\n                      VERBATIM USES_TERMINAL)\nendif()\n\nfind_program(QEMU_EMULATOR ${QEMU_COMMAND})\nif(QEMU_EMULATOR)\n    if(CMAKE_HOST_LINUX)\n        # This target starts up a QEMU+OVMF virtual machine using KVM accelerator\n        add_custom_target(testefikvm\n                          DEPENDS install\n                          COMMAND ${QEMU_COMMAND} -name \"ExectOS-${ARCH}-EFI-KVM\" -machine type=q35,kernel_irqchip=on,accel=kvm,mem-merge=off,vmport=off -enable-kvm -cpu host,-hypervisor,+topoext\n                                                  -smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none\n                                                  -bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd\n                                                  -hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries\n                                                  -boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio\n                          VERBATIM USES_TERMINAL)\n    elseif(CMAKE_HOST_WIN32)\n        # This target starts up a QEMU+OVMF virtual machine using WHPX accelerator\n        add_custom_target(testefiwhpx\n                          DEPENDS install\n                          COMMAND ${QEMU_COMMAND} -name \"ExectOS-${ARCH}-EFI-WHPX\" -machine type=q35,kernel_irqchip=off,accel=whpx,mem-merge=off,vmport=off\n                                                  -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none\n                                                  -bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd\n                                                  -hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries\n                                                  -boot menu=on -d int -M smm=off -no-reboot -no-shutdown -serial stdio\n                          VERBATIM USES_TERMINAL)\n    endif()\n\n    # This target starts up a QEMU+OVMF virtual machine using TCG accelerator\n    add_custom_target(testefitcg\n                      DEPENDS install\n                      COMMAND ${QEMU_COMMAND} -name \"ExectOS-${ARCH}-EFI-TCG\" -machine type=q35,accel=tcg -cpu max,-hypervisor\n                                              -smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none\n                                              -bios ${EXECTOS_SOURCE_DIR}/sdk/firmware/ovmf_${ARCH}.fd\n                                              -hda fat:rw:${EXECTOS_BINARY_DIR}/output/binaries\n                                              -boot menu=on -d int -no-reboot -no-shutdown -serial stdio\n                      VERBATIM USES_TERMINAL)\n\n    if(CMAKE_HOST_LINUX)\n        # This target starts up a QEMU+SEABIOS virtual machine using KVM accelerator\n        add_custom_target(testkvm\n                          DEPENDS diskimg\n                          COMMAND ${QEMU_COMMAND} -name \"ExectOS-${ARCH}-BIOS-KVM\" -machine type=q35,kernel_irqchip=on,accel=kvm,mem-merge=off,vmport=off -enable-kvm -cpu host,-hypervisor,+topoext\n                                                  -smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none\n                                                  -hda ${EXECTOS_BINARY_DIR}/output/disk.img\n                                                  -boot menu=on -d int -no-reboot -no-shutdown -serial stdio\n                          VERBATIM USES_TERMINAL)\n    elseif(CMAKE_HOST_WIN32)\n        # This target starts up a QEMU+SEABIOS virtual machine using WHPX accelerator\n        add_custom_target(testwhpx\n                          DEPENDS diskimg\n                          COMMAND ${QEMU_COMMAND} -name \"ExectOS-${ARCH}-BIOS-WHPX\" -machine type=q35,kernel_irqchip=off,accel=whpx,mem-merge=off,vmport=off\n                                                  -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none\n                                                  -hda ${EXECTOS_BINARY_DIR}/output/disk.img\n                                                  -boot menu=on -d int -no-reboot -no-shutdown -serial stdio\n                          VERBATIM USES_TERMINAL)\n    endif()\n\n    # This target starts up a QEMU+SEABIOS virtual machine using TCG accelerator\n    add_custom_target(testtcg\n                      DEPENDS diskimg\n                      COMMAND ${QEMU_COMMAND} -name \"ExectOS-${ARCH}-BIOS-TCG\" -machine type=q35,accel=tcg -cpu max,-hypervisor\n                                              -smp 2,sockets=1,cores=1,threads=2 -m 4G -overcommit mem-lock=off -rtc clock=host,base=localtime,driftfix=none\n                                              -hda ${EXECTOS_BINARY_DIR}/output/disk.img\n                                              -boot menu=on -d int -no-reboot -no-shutdown -serial stdio\n                      VERBATIM USES_TERMINAL)\nendif()\n"
  },
  {
    "path": "sdk/cmake/functions.cmake",
    "content": "# This function enables the addition of ASM compiler switches\nfunction(add_compiler_asmflags FLAGS)\n    if(NOT ${ARGC} EQUAL 1)\n        message(FATAL_ERROR \"Invalid number of arguments passed to add_compiler_asmflags() function\")\n    endif()\n    set(CMAKE_ASM_FLAGS \"${CMAKE_ASM_FLAGS} ${FLAGS}\" PARENT_SCOPE)\nendfunction()\n\n# This function enables the addition of C compiler switches\nfunction(add_compiler_cflags FLAGS)\n    if(NOT ${ARGC} EQUAL 1)\n        message(FATAL_ERROR \"Invalid number of arguments passed to add_compiler_cflags() function\")\n    endif()\n    set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} ${FLAGS}\" PARENT_SCOPE)\nendfunction()\n\n# This function enables the addition of C/C++ compilers switches\nfunction(add_compiler_ccxxflags FLAGS)\n    if(NOT ${ARGC} EQUAL 1)\n        message(FATAL_ERROR \"Invalid number of arguments passed to add_compiler_ccxxflags() function\")\n    endif()\n    set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} ${FLAGS}\" PARENT_SCOPE)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} ${FLAGS}\" PARENT_SCOPE)\nendfunction()\n\n# This function enables the addition of C++ compiler switches\nfunction(add_compiler_cxxflags FLAGS)\n    if(NOT ${ARGC} EQUAL 1)\n        message(FATAL_ERROR \"Invalid number of arguments passed to add_compiler_cxxflags() function\")\n    endif()\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} ${FLAGS}\" PARENT_SCOPE)\nendfunction()\n\n# This function enables the addition of ASM/C/C++ compilers switches\nfunction(add_compiler_flags FLAGS)\n    if(NOT ${ARGC} EQUAL 1)\n        message(FATAL_ERROR \"Invalid number of arguments passed to add_compiler_flags() function\")\n    endif()\n    set(CMAKE_ASM_FLAGS \"${CMAKE_ASM_FLAGS} ${FLAGS}\" PARENT_SCOPE)\n    set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} ${FLAGS}\" PARENT_SCOPE)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} ${FLAGS}\" PARENT_SCOPE)\nendfunction()\n\n# This function enables the addition of linker switches\nfunction(add_linker_flags FLAGS)\n    if(NOT ${ARGC} EQUAL 1)\n        message(FATAL_ERROR \"Invalid number of arguments passwd to add_linker_flags() function\")\n    endif()\n    foreach(TYPE EXE MODULE SHARED)\n        set(CMAKE_${TYPE}_LINKER_FLAGS \"${CMAKE_${TYPE}_LINKER_FLAGS} ${FLAGS}\" PARENT_SCOPE)\n    endforeach()\nendfunction()\n\n# This function enabled the addition of linker switches for specified module\nfunction(add_module_linker_flags MODULE FLAGS)\n    if(NOT ${ARGC} EQUAL 2)\n        message(FATAL_ERROR \"Invalid number of arguments passwd to add_module_linker_flags() function\")\n    endif()\n    set_module_property(${MODULE} LINK_FLAGS ${FLAGS})\nendfunction()\n\n# This function compiles XT Assembly Development Kit\nfunction(generate_xtadk TARGET_NAME SOURCE_FILES)\n    # Define the absolute destination path for the generated header file\n    set(HEADER_OUTPUT \"${EXECTOS_BINARY_DIR}/sdk/includes/${TARGET_NAME}.h\")\n    get_filename_component(HEADER_OUTPUT_DIRECTORY \"${HEADER_OUTPUT}\" DIRECTORY)\n\n    # Tokenize global CXX flags into a list to ensure correct argument expansion\n    separate_arguments(COMPILER_FLAGS NATIVE_COMMAND \"${CMAKE_CXX_FLAGS}\")\n\n    # Resolve and tokenize build-configuration specific flags\n    string(TOUPPER \"${CMAKE_BUILD_TYPE}\" BUILD_TYPE)\n    if(BUILD_TYPE)\n        separate_arguments(BUILD_TYPE_SPECIFIC_FLAGS NATIVE_COMMAND \"${CMAKE_CXX_FLAGS_${BUILD_TYPE}}\")\n    endif()\n\n    # Retrieve compiler definitions, include paths, and options\n    get_directory_property(COMPILE_DEFINITIONS COMPILE_DEFINITIONS)\n    get_directory_property(INCLUDE_DIRECTORIES INCLUDE_DIRECTORIES)\n    get_directory_property(COMPILE_OPTIONS COMPILE_OPTIONS)\n\n    # Initialize the final compiler argument list\n    set(COMPILER_ARGUMENTS \"\")\n    list(APPEND COMPILER_ARGUMENTS ${COMPILER_FLAGS} ${BUILD_TYPE_SPECIFIC_FLAGS})\n\n    # Transform definitions into MSVC-style\n    foreach(DEFINITION ${COMPILE_DEFINITIONS})\n        list(APPEND COMPILER_ARGUMENTS \"/D${DEFINITION}\")\n    endforeach()\n\n    # Transform include paths into MSVC-style\n    foreach(INCLUDE_PATH ${INCLUDE_DIRECTORIES})\n        list(APPEND COMPILER_ARGUMENTS \"/I${INCLUDE_PATH}\")\n    endforeach()\n\n    # Append all supplemental compiler options\n    list(APPEND COMPILER_ARGUMENTS ${COMPILE_OPTIONS})\n    set(COLLECTED_ASSEMBLY_OUTPUTS \"\")\n\n    # Iterate through each source file to create individual assembly generation rules\n    foreach(SOURCE_FILE_PATH ${SOURCE_FILES})\n        # Extract the base filename\n        get_filename_component(FILENAME_WITHOUT_EXTENSION \"${SOURCE_FILE_PATH}\" NAME_WE)\n\n        # Define the unique output path for the intermediate assembly file\n        set(CURRENT_ASSEMBLY_OUTPUT \"${CMAKE_CURRENT_BINARY_DIR}/${FILENAME_WITHOUT_EXTENSION}.S\")\n        list(APPEND COLLECTED_ASSEMBLY_OUTPUTS \"${CURRENT_ASSEMBLY_OUTPUT}\")\n        get_filename_component(CURRENT_ASSEMBLY_DIRECTORY \"${CURRENT_ASSEMBLY_OUTPUT}\" DIRECTORY)\n\n        # Execute the compiler to generate assembly code\n        add_custom_command(\n            OUTPUT \"${CURRENT_ASSEMBLY_OUTPUT}\"\n            COMMAND ${CMAKE_COMMAND} -E make_directory \"${CURRENT_ASSEMBLY_DIRECTORY}\"\n            COMMAND ${CMAKE_CXX_COMPILER}\n                ${COMPILER_ARGUMENTS}\n                /c /FAs /Fa${CURRENT_ASSEMBLY_OUTPUT}\n                -- ${SOURCE_FILE_PATH}\n            DEPENDS \"${SOURCE_FILE_PATH}\"\n            COMMENT \"Generating XTADK Assembly: ${FILENAME_WITHOUT_EXTENSION}\"\n            VERBATIM\n            COMMAND_EXPAND_LISTS\n        )\n    endforeach()\n\n    # Aggregate all generated assembly units into a single consolidated XTADK header\n    add_custom_command(\n        OUTPUT \"${HEADER_OUTPUT}\"\n        COMMAND ${CMAKE_COMMAND} -E make_directory \"${HEADER_OUTPUT_DIRECTORY}\"\n        COMMAND xtadkgen ${COLLECTED_ASSEMBLY_OUTPUTS} -O \"${HEADER_OUTPUT}\"\n        DEPENDS ${COLLECTED_ASSEMBLY_OUTPUTS}\n        COMMENT \"Generating XTADK header: ${TARGET_NAME}\"\n        VERBATIM\n    )\n\n    # Establish the generation target and expose the header directory via an interface library\n    add_custom_target(${TARGET_NAME}_gen DEPENDS \"${HEADER_OUTPUT}\")\n    add_library(${TARGET_NAME} INTERFACE)\n    add_dependencies(${TARGET_NAME} ${TARGET_NAME}_gen)\n    target_include_directories(${TARGET_NAME} INTERFACE \"${EXECTOS_BINARY_DIR}/sdk/includes\")\nendfunction()\n\n# This function compiles an assembly bootsector file into a flat binary\nfunction(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)\n    set(BINARY_NAME \"${NAME}.bin\")\n    set(OBJECT_NAME \"${NAME}.obj\")\n\n    get_directory_property(DEFS COMPILE_DEFINITIONS)\n    foreach(def ${DEFS})\n        list(APPEND ASM_DEFS \"-D${def}\")\n    endforeach()\n\n    add_custom_command(\n        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}\n        COMMAND ${CMAKE_ASM_COMPILER}\n            /nologo\n            --target=i386-none-elf\n            ${ASM_DEFS}\n            -I${CMAKE_CURRENT_SOURCE_DIR}\n            /Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}\n            -c -- ${SOURCE}\n        COMMAND ${CMAKE_ASM_LINKER}\n            -m elf_i386\n            --image-base=0\n            --oformat binary\n            -Ttext=${BASEADDR}\n            --entry=_start${ENTRYPOINT}\n            -o ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}\n            ${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}\n        DEPENDS ${SOURCE}\n    )\n\n    add_custom_target(${NAME} ALL\n        DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}\n    )\nendfunction()\n\n# This function sets the the qemu disk image size (in MiB)\nfunction(set_disk_image_size SIZE)\n\tMATH(EXPR DISK_BLOCKS ${SIZE}*1024*1024/512)\n\tMATH(EXPR PART_BLOCKS ${DISK_BLOCKS}-2048)\n\tset(PROJECT_DISK_IMAGE_SIZE ${SIZE} CACHE INTERNAL \"PROJECT_DISK_IMAGE_SIZE\")\n\tset(PROJECT_DISK_IMAGE_BLOCKS ${DISK_BLOCKS} CACHE INTERNAL \"PROJECT_DISK_IMAGE_BLOCKS\")\n\tset(PROJECT_PART_IMAGE_BLOCKS ${PART_BLOCKS} CACHE INTERNAL \"PROJECT_PART_IMAGE_BLOCKS\")\nendfunction()\n\n# This function installs specified directory recursively under destination directory\nfunction(set_install_dir DIRECTORY DESTINATION)\n    install(DIRECTORY ${DIRECTORY} DESTINATION ${EXECTOS_BINARY_DIR}/output/binaries/${DESTINATION})\nendfunction()\n\n# This function installs specified file under destination directory\nfunction(set_install_file FILENAME DESTINATION)\n    install(FILES ${FILENAME} DESTINATION ${EXECTOS_BINARY_DIR}/output/binaries/${DESTINATION})\nendfunction()\n\n# This function installs specified target results under destination directory\nfunction(set_install_target TARGET DESTINATION)\n    set_target_properties(${TARGET} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY \"${EXECTOS_BINARY_DIR}/output/sdk/lib\")\n    install(TARGETS ${TARGET} DESTINATION ${EXECTOS_BINARY_DIR}/output/binaries/${DESTINATION})\nendfunction()\n\n# This function sets a property for specified module\nfunction(set_module_property MODULE PROPERTY FLAGS)\n    if(NOT ${ARGC} EQUAL 3)\n        message(FATAL_ERROR \"Invalid number of arguments passwd to add_module_property() function\")\n    endif()\n    get_target_property(VAL ${MODULE} ${PROPERTY})\n    if(VAL)\n        set(VAL \"${VAL} ${FLAGS}\")\n    else()\n        set(VAL \"${FLAGS}\")\n    endif()\n    set_property(TARGET ${MODULE} PROPERTY ${PROPERTY} ${VAL})\nendfunction()\n\nfunction(set_sdk_target FILENAME DESTINATION)\n    install(DIRECTORY ${FILENAME} DESTINATION ${EXECTOS_BINARY_DIR}/output/sdk/${DESTINATION})\nendfunction()\n\n# This function is responsible for compiling module SPEC file\nfunction(set_specfile SPECFILE EXPORTNAME)\n    if(NOT ${ARGC} EQUAL 2)\n        message(FATAL_ERROR \"Invalid number of arguments passed to set_specfile() function\")\n    endif()\n    get_filename_component(FILENAME ${SPECFILE} NAME_WE)\n    add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.def ${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.c\n                       COMMAND ${CMAKE_SPEC_COMPILER} -a=${ARCH} -n=${EXPORTNAME} -d=${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.c ${CMAKE_CURRENT_SOURCE_DIR}/${SPECFILE})\nendfunction()\n"
  },
  {
    "path": "sdk/cmake/toolchain.cmake",
    "content": "# Set target operating system name\nset(CMAKE_SYSTEM_NAME Windows)\n\n# Set toolchain compilers\nset(CMAKE_ASM_COMPILER clang-cl)\nset(CMAKE_ASM_LINKER ld.lld)\nset(CMAKE_C_COMPILER clang-cl)\nset(CMAKE_CXX_COMPILER clang-cl)\nset(CMAKE_LINKER lld-link)\nset(CMAKE_MC_COMPILER wmc)\nset(CMAKE_RC_COMPILER wrc)\nset(CMAKE_SPEC_COMPILER xtcspecc)\n\n# Assume that ASM and C/C++ compilers are working\nset(CMAKE_ASM_COMPILER_WORKS 1)\nset(CMAKE_C_COMPILER_WORKS 1)\nset(CMAKE_CXX_COMPILER_WORKS 1)\n\n# Set C/C++ standard and disable extensions\nset(CMAKE_C_EXTENSIONS OFF)\nset(CMAKE_CXX_EXTENSIONS OFF)\nset(CMAKE_C_STANDARD 23)\nset(CMAKE_CXX_STANDARD 23)\n\n# Disable standard C and C++ libraries\nset(CMAKE_C_STANDARD_LIBRARIES \"\" CACHE INTERNAL \"\")\nset(CMAKE_CXX_STANDARD_LIBRARIES \"\" CACHE INTERNAL \"\")\n\n# Clean linker flags\nset(CMAKE_STATIC_LINKER_FLAGS \"\")\nset(CMAKE_MODULE_LINKER_FLAGS \"\")\nset(CMAKE_EXE_LINKER_FLAGS \"\")\nset(CMAKE_SHARED_LINKER_FLAGS \"\")\n"
  },
  {
    "path": "sdk/cmake/version/xtver.h.cmake",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            includes/cmake/version/xtver.h.cmake\n * DESCRIPTION:     XT version information - generated by toolchain\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTGEN_XTVER_H\n#define __XTGEN_XTVER_H\n\n#define XTOS_VERSION                     \"@XTOS_VERSION_MAJOR@.@XTOS_VERSION_MINOR@-@XTOS_VERSION_BUILD@\"\n#define XTOS_VERSION_MAJOR               @XTOS_VERSION_MAJOR@\n#define XTOS_VERSION_MINOR               @XTOS_VERSION_MINOR@\n#define XTOS_VERSION_BUILD               \"@XTOS_VERSION_BUILD@\"\n#define XTOS_VERSION_HASH                \"@XTOS_VERSION_HASH@\"\n\n#define XTOS_VERSION_ARCH                \"@ARCH@\"\n#define XTOS_VERSION_DATE                \"@XTOS_VERSION_DATE@\"\n#define XTOS_VERSION_FULLDATE            \"@XTOS_VERSION_FULLDATE@\"\n#define XTOS_VERSION_YEAR                \"@XTOS_VERSION_YEAR@\"\n\n#define XTOS_COMPATIBLE_MAJOR            @XTOS_COMPATIBLE_MAJOR@\n#define XTOS_COMPATIBLE_MINOR            @XTOS_COMPATIBLE_MINOR@\n#define XTOS_COMPATIBLE_BUILD            @XTOS_COMPATIBLE_BUILD@\n#define XTOS_COMPATIBLE_VERSION          @XTOS_COMPATIBLE_VERSION@\n#define XTOS_COMPATIBLE_VERSION_BUILD    @XTOS_COMPATIBLE_VERSION@@XTOS_COMPATIBLE_BUILD@\n\n#define XTOS_COMPILER_NAME               \"@CMAKE_C_COMPILER_ID@\"\n#define XTOS_COMPILER_VERSION            \"@CMAKE_C_COMPILER_VERSION@\"\n\n#define XTLDR_VERSION_MAJOR              @XTLDR_VERSION_MAJOR@\n#define XTLDR_VERSION_MINOR              @XTLDR_VERSION_MINOR@\n\n#endif /* __XTGEN_XTVER_H */\n"
  },
  {
    "path": "sdk/cmake/version.cmake",
    "content": "# Set XTOS version\nset(XTOS_VERSION_MAJOR \"0\")\nset(XTOS_VERSION_MINOR \"1\")\nset(XTOS_VERSION_BUILD \"devel\")\n\n# Set XTOS NT compatibility version\nset(XTOS_COMPATIBLE_MAJOR \"6\")\nset(XTOS_COMPATIBLE_MINOR \"3\")\nset(XTOS_COMPATIBLE_VERSION \"0x0603\")\nset(XTOS_COMPATIBLE_BUILD \"9600\")\n\n# Set XTLDR version\nset(XTLDR_VERSION_MAJOR \"0\")\nset(XTLDR_VERSION_MINOR \"1\")\n\n# Set common XTOS version variables\nstring(TIMESTAMP XTOS_VERSION_YEAR %Y)\nstring(TIMESTAMP XTOS_VERSION_DATE \"%Y%m%d\")\nstring(TIMESTAMP XTOS_VERSION_FULLDATE \"%d/%m/%Y %H:%M UTC\" UTC)\n\n# Set latest GIT revision\nset(XTOS_VERSION_HASH \"unknown\")\nif(EXISTS \"${EXECTOS_SOURCE_DIR}/.git\")\n        execute_process(COMMAND git describe --abbrev=10 --long --always\n        WORKING_DIRECTORY ${EXECTOS_SOURCE_DIR}\n        OUTPUT_VARIABLE XTOS_VERSION_HASH\n        OUTPUT_STRIP_TRAILING_WHITESPACE)\nendif()\n\n# Prepare xtver.h header file\nadd_custom_target(xtver ALL COMMAND ${CMAKE_COMMAND} -E touch ${EXECTOS_SOURCE_DIR}/sdk/cmake/version/xtver.h.cmake)\nconfigure_file(sdk/cmake/version/xtver.h.cmake ${EXECTOS_BINARY_DIR}/sdk/includes/xtver.h)\ninclude_directories(${EXECTOS_BINARY_DIR}/sdk/includes)\n"
  },
  {
    "path": "sdk/cmake/xtchain.cmake",
    "content": "# Architecture specific flags\nif(ARCH STREQUAL i686)\n    add_compiler_flags(\"-m32 --target=i686-pc-windows-msvc\")\n    add_linker_flags(\"/machine:X86\")\n    set(HOTPATCH_LINKER_FLAG \"/FUNCTIONPADMIN:5\")\nelseif(ARCH STREQUAL amd64)\n    add_compiler_flags(\"-m64 --target=x86_64-pc-windows-msvc\")\n    add_linker_flags(\"/machine:X64\")\n    set(HOTPATCH_LINKER_FLAG \"/FUNCTIONPADMIN:6\")\nendif()\n\n# Set build optimisation\nif(BUILD_TYPE STREQUAL \"DEBUG\")\n    add_compiler_ccxxflags(\"/GS- /Zi /Ob0 /Od\")\n    add_linker_flags(\"/DEBUG /INCREMENTAL:NO /OPT:REF /OPT:NOICF /PDBSOURCEPATH:build\")\nelse()\n    add_compiler_ccxxflags(\"/GS- /Ob2 /Ot /Ox /Oy\")\n    add_linker_flags(\"/INCREMENTAL:NO /OPT:REF /OPT:ICF\")\nendif()\n\n# Enable string pooling\nadd_compiler_ccxxflags(\"-GF\")\n\n# Disable builtin CRT library\nadd_compiler_ccxxflags(\"-Zl\")\n\n# Disable RTTI and buffer security checks\nadd_compiler_ccxxflags(\"-GR- -GS-\")\n\n# Disable thread-safe initialization\nadd_compiler_flags(\"-Zc:threadSafeInit-\")\n\n# Enable function level linking\nadd_compiler_ccxxflags(\"-Gy\")\n\n# Enable Structured Exception Handling (SEH)\nadd_compiler_ccxxflags(\"-EHa\")\n\n# Control warnings levels\nadd_compiler_ccxxflags(\"-W3 -w14115\")\nadd_compiler_ccxxflags(\"-wd4200 -wd4214 -wd4244 -wd4290 -wd4800\")\nadd_compiler_ccxxflags(\"-we4013 -we4020 -we4022 -we4028 -we4047 -we4098 -we4101 -we4113 -we4129 -we4133\")\nadd_compiler_ccxxflags(\"-we4163 -we4189 -we4229 -we4311 -we4312 -we4313 -we4477 -we4603 -we4700 -we4715 -we4716\")\n\n# Disable warnings about specific features\nadd_compiler_ccxxflags(\"-nostdinc -Wno-char-subscripts -Wno-incompatible-library-redeclaration -Wno-microsoft-anon-tag\")\nadd_compiler_ccxxflags(\"-Wno-microsoft-enum-forward-reference -Wno-multichar -Wno-parentheses-equality -Wno-undefined-inline\")\nadd_compiler_ccxxflags(\"-Wno-gnu-folding-constant\")\n\n# Disable compiler builtins\nadd_compiler_ccxxflags(\"-fno-builtin\")\n\n# Set symbols and libraries output directory\nset(CMAKE_PDB_OUTPUT_DIRECTORY \"${EXECTOS_BINARY_DIR}/output/symbols\")\nset(LIBRARY_OUTPUT_PATH \"${EXECTOS_BINARY_DIR}/output/sdk/lib\")\n\n# Set linker flags\nadd_linker_flags(\"${HOTPATCH_LINKER_FLAG} /LARGEADDRESSAWARE /IGNORE:4039 /IGNORE:4104 /MANIFEST:NO /NODEFAULTLIB /SAFESEH:NO\")\n\n# Set runtime library\nset(CMAKE_MSVC_RUNTIME_LIBRARY \"\")\n\n# Set default subsystem\nset(CMAKE_CREATE_CONSOLE_EXE \"\")\n\n# Export compile commands for clangd\nset(CMAKE_EXPORT_COMPILE_COMMANDS on)\n\n# This function sets entrypoint of the binary\nfunction(set_entrypoint MODULE ENTRYPOINT)\n    if(${ENTRYPOINT} STREQUAL \"0\")\n        add_module_linker_flags(${MODULE} \"/NOENTRY\")\n    else()\n        add_module_linker_flags(${MODULE} \"/ENTRY:${ENTRYPOINT}\")\n    endif()\nendfunction()\n\n# This function sets imagebase address of the binary\nfunction(set_imagebase MODULE IMAGEBASE)\n    add_module_linker_flags(${MODULE} \"/BASE:${IMAGEBASE}\")\nendfunction()\n\n# This function enables or disables map file generation for specified module\nfunction(set_linker_map MODULE STATE)\n    if(NOT ${ARGC} EQUAL 2)\n        message(FATAL_ERROR \"Invalid number of arguments passed to set_ordinals() function\")\n    endif()\n    if(STATE STREQUAL \"TRUE\")\n        add_module_linker_flags(${MODULE} \"/MAP:${CMAKE_CURRENT_BINARY_DIR}/${MODULE}.map\")\n    endif()\nendfunction()\n\n# This function enables or disables binary ordinals export for specified module\nfunction(set_ordinals MODULE STATE)\n    if(NOT ${ARGC} EQUAL 2)\n        message(FATAL_ERROR \"Invalid number of arguments passed to set_ordinals() function\")\n    endif()\n    set_module_property(${MODULE} ENABLE_EXPORTS ${STATE})\nendfunction()\n\n# This functions sets PE/COFF subsystem and XTOS version of the binary\nfunction(set_subsystem MODULE SUBSYSTEM)\n    string(TOUPPER ${SUBSYSTEM} SUBSYSTEM)\n    add_module_linker_flags(${MODULE} \"/SUBSYSTEM:${SUBSYSTEM},6.03\")\n    add_module_linker_flags(${MODULE} \"/VERSION:6.03\")\n    if(${ARGC} EQUAL 3)\n        set(XTSUBSYSTEM ${ARGN})\n        add_custom_command(TARGET ${MODULE} POST_BUILD COMMAND exetool \"$<TARGET_FILE:${MODULE}>\" ${XTSUBSYSTEM})\n    endif()\nendfunction()\n"
  },
  {
    "path": "sdk/firmware/README.md",
    "content": "## Open Virtual Machine Firmware (OVMF)\nThis directory contains the essential components of the Open Virtual Machine Firmware (OVMF), which provides\nan open-source implementation of the Unified Extensible Firmware Interface (UEFI) for virtual machines.\n\nThe ovmf_code files contain the CPU architecture specific UEFI firmware code, which serves as the initial boot code\nfor virtual machines used to test the XTOS. It includes the necessary instructions and functions to initialize hardware,\nload the operating system, and provide various system services during the boot process. The ovmf_code file is\nresponsible for establishing a UEFI environment within the virtual machine, enabling it to boot and operate effectively.\n\nThe ovmf_pure files contains the minimum version of the CPU specific UEFI firmware code, suitable for use with Bochs.\n\nThe ovmf_vars files, store UEFI variables, which are used to store and retrieve system configuration information, such as\nboot options, device settings, and system preferences. The ovmf_vars file contains the persistent variables specific to\na virtual machine, allowing it to maintain its configuration across multiple boot sessions.\n\n## BOCHS ROM BIOS\nThe rombios.bin file contains the ROM BIOS image for Bochs. This image is distributed under the GNU Lesser General Public\nLicense (LGPL).\n\n## Video BIOS (LGPL'd VGABios)\nThe vgabios.bin file contains the Video Bios for Bochs and QEMU. This VGA Bios is very specific to the emulated VGA card.\nIt is NOT meant to drive a physical vga card. It also implements support for VBE version 2.0.\n"
  },
  {
    "path": "sdk/firmware/bochsrc_amd64.cfg",
    "content": "# configuration file generated by Bochs\nplugin_ctrl: usb_xhci=false, serial=true, e1000=false, extfpuirq=true, parallel=true, usb_uhci=false, biosdev=true, unmapped=true, gameport=true, ne2k=false, speaker=true, iodebug=false, pcipnic=false, usb_ohci=false\nconfig_interface: textconfig\ndisplay_library: x\nmemory: host=64, guest=64\nromimage: file=\"../sdk/firmware/rombios.bin\", address=0x00000000, options=none\nvgaromimage: file=\"../sdk/firmware/vgabios.bin\"\nboot: disk\nfloppy_bootsig_check: disabled=0\nfloppya: type=1_44\n# no floppyb\nata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14\nata0-master: type=disk, path=\"output/disk.img\", mode=flat, cylinders=0, heads=0, spt=0, sect_size=512, model=\"Generic 1234\", biosdetect=auto, translation=auto\nata0-slave: type=none\nata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15\nata1-master: type=none\nata1-slave: type=none\nata2: enabled=false\nata3: enabled=false\noptromimage1: file=none\noptromimage2: file=none\noptromimage3: file=none\noptromimage4: file=none\noptramimage1: file=none\noptramimage2: file=none\noptramimage3: file=none\noptramimage4: file=none\npci: enabled=1, chipset=i440fx, slot1=cirrus, slot2=none, slot3=none, slot4=none, slot5=none\nvga: extension=cirrus, update_freq=5, realtime=1, ddc=builtin\ncpu: count=1:1:1, ips=400000000, quantum=16, model=corei7_sandy_bridge_2600k, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0\nprint_timestamps: enabled=0\nport_e9_hack: enabled=0\nprivate_colormap: enabled=0\nclock: sync=none, time0=local, rtc_sync=0\n# no cmosimage\nlog: -\nlogprefix: %t%e%d\ndebug: action=ignore\ninfo: action=report\nerror: action=report\npanic: action=ask\nkeyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none\nmouse: type=ps2, enabled=false, toggle=ctrl+mbutton\ncom1: enabled=true, mode=null\ncom2: enabled=false\ncom3: enabled=false\ncom4: enabled=false\nparport1: enabled=true, file=none\nparport2: enabled=false\nspeaker: enabled=true, mode=system\n"
  },
  {
    "path": "sdk/firmware/bochsrc_i686.cfg",
    "content": "# configuration file generated by Bochs\nplugin_ctrl: usb_xhci=false, serial=true, e1000=false, extfpuirq=true, parallel=true, usb_uhci=false, biosdev=true, unmapped=true, gameport=true, ne2k=false, speaker=true, iodebug=false, pcipnic=false, usb_ohci=false\nconfig_interface: textconfig\ndisplay_library: x\nmemory: host=64, guest=64\nromimage: file=\"../sdk/firmware/rombios.bin\", address=0x00000000, options=none\nvgaromimage: file=\"../sdk/firmware/vgabios.bin\"\nboot: disk\nfloppy_bootsig_check: disabled=0\nfloppya: type=1_44\n# no floppyb\nata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14\nata0-master: type=disk, path=\"output/disk.img\", mode=flat, cylinders=0, heads=0, spt=0, sect_size=512, model=\"Generic 1234\", biosdetect=auto, translation=auto\nata0-slave: type=none\nata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15\nata1-master: type=none\nata1-slave: type=none\nata2: enabled=false\nata3: enabled=false\noptromimage1: file=none\noptromimage2: file=none\noptromimage3: file=none\noptromimage4: file=none\noptramimage1: file=none\noptramimage2: file=none\noptramimage3: file=none\noptramimage4: file=none\npci: enabled=1, chipset=i440fx, slot1=cirrus, slot2=none, slot3=none, slot4=none, slot5=none\nvga: extension=cirrus, update_freq=5, realtime=1, ddc=builtin\ncpu: count=1:1:1, ips=400000000, quantum=16, model=corei7_sandy_bridge_2600k, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0\nprint_timestamps: enabled=0\nport_e9_hack: enabled=0\nprivate_colormap: enabled=0\nclock: sync=none, time0=local, rtc_sync=0\n# no cmosimage\nlog: -\nlogprefix: %t%e%d\ndebug: action=ignore\ninfo: action=report\nerror: action=report\npanic: action=ask\nkeyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none\nmouse: type=ps2, enabled=false, toggle=ctrl+mbutton\ncom1: enabled=true, mode=null\ncom2: enabled=false\ncom3: enabled=false\ncom4: enabled=false\nparport1: enabled=true, file=none\nparport2: enabled=false\nspeaker: enabled=true, mode=system\n"
  },
  {
    "path": "sdk/xtadk/CMakeLists.txt",
    "content": "# XT Assembly Development Kit\nPROJECT(XTADK)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTADK_SOURCE_DIR}/includes)\n\n# Specify list of XTADK source code files\nlist(APPEND XTADK_SOURCE\n    ${XTADK_SOURCE_DIR}/${ARCH}/ke.cc)\n\n# Generate assembly header from XTADK sources\ngenerate_xtadk(xtadk \"${XTADK_SOURCE}\")\n"
  },
  {
    "path": "sdk/xtadk/amd64/ke.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtadk/amd64/ke.cc\n * DESCRIPTION:     ADK generator for AMD64 version of Kernel Library\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtkmapi.h>\n#include <adkdefs.h>\n\n\n/**\n * Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nGenerateAssemblyDefinitions(VOID)\n{\n    /* Generate KTRAP_FRAME offsets */\n    ADK_OFFSET(KTRAP_FRAME, Xmm0);\n    ADK_OFFSET(KTRAP_FRAME, Xmm1);\n    ADK_OFFSET(KTRAP_FRAME, Xmm2);\n    ADK_OFFSET(KTRAP_FRAME, Xmm3);\n    ADK_OFFSET(KTRAP_FRAME, Xmm4);\n    ADK_OFFSET(KTRAP_FRAME, Xmm5);\n    ADK_OFFSET(KTRAP_FRAME, Xmm6);\n    ADK_OFFSET(KTRAP_FRAME, Xmm7);\n    ADK_OFFSET(KTRAP_FRAME, Xmm8);\n    ADK_OFFSET(KTRAP_FRAME, Xmm9);\n    ADK_OFFSET(KTRAP_FRAME, Xmm10);\n    ADK_OFFSET(KTRAP_FRAME, Xmm11);\n    ADK_OFFSET(KTRAP_FRAME, Xmm12);\n    ADK_OFFSET(KTRAP_FRAME, Xmm13);\n    ADK_OFFSET(KTRAP_FRAME, Xmm14);\n    ADK_OFFSET(KTRAP_FRAME, Xmm15);\n    ADK_OFFSET(KTRAP_FRAME, MxCsr);\n    ADK_OFFSET(KTRAP_FRAME, PreviousMode);\n    ADK_OFFSET(KTRAP_FRAME, Cr2);\n    ADK_OFFSET(KTRAP_FRAME, Cr3);\n    ADK_OFFSET(KTRAP_FRAME, Dr0);\n    ADK_OFFSET(KTRAP_FRAME, Dr1);\n    ADK_OFFSET(KTRAP_FRAME, Dr2);\n    ADK_OFFSET(KTRAP_FRAME, Dr3);\n    ADK_OFFSET(KTRAP_FRAME, Dr6);\n    ADK_OFFSET(KTRAP_FRAME, Dr7);\n    ADK_OFFSET(KTRAP_FRAME, SegDs);\n    ADK_OFFSET(KTRAP_FRAME, SegEs);\n    ADK_OFFSET(KTRAP_FRAME, SegFs);\n    ADK_OFFSET(KTRAP_FRAME, SegGs);\n    ADK_OFFSET(KTRAP_FRAME, Rax);\n    ADK_OFFSET(KTRAP_FRAME, Rbx);\n    ADK_OFFSET(KTRAP_FRAME, Rcx);\n    ADK_OFFSET(KTRAP_FRAME, Rdx);\n    ADK_OFFSET(KTRAP_FRAME, R8);\n    ADK_OFFSET(KTRAP_FRAME, R9);\n    ADK_OFFSET(KTRAP_FRAME, R10);\n    ADK_OFFSET(KTRAP_FRAME, R11);\n    ADK_OFFSET(KTRAP_FRAME, R12);\n    ADK_OFFSET(KTRAP_FRAME, R13);\n    ADK_OFFSET(KTRAP_FRAME, R14);\n    ADK_OFFSET(KTRAP_FRAME, R15);\n    ADK_OFFSET(KTRAP_FRAME, Rsi);\n    ADK_OFFSET(KTRAP_FRAME, Rdi);\n    ADK_OFFSET(KTRAP_FRAME, Rbp);\n    ADK_OFFSET(KTRAP_FRAME, Vector);\n    ADK_OFFSET(KTRAP_FRAME, ErrorCode);\n    ADK_OFFSET(KTRAP_FRAME, ExceptionFrame);\n    ADK_OFFSET(KTRAP_FRAME, Rip);\n    ADK_OFFSET(KTRAP_FRAME, SegCs);\n    ADK_OFFSET(KTRAP_FRAME, Flags);\n    ADK_OFFSET(KTRAP_FRAME, Rsp);\n    ADK_OFFSET(KTRAP_FRAME, SegSs);\n\n    /* Generate KTRAP_FRAME size and REGISTERS_SIZE */\n    ADK_SIZE(KTRAP_FRAME);\n    ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Rax);\n\n    /* Generate PROCESSOR_START_BLOCK offsets */\n    ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, Started);\n}\n"
  },
  {
    "path": "sdk/xtadk/i686/ke.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtadk/i686/ke.cc\n * DESCRIPTION:     ADK generator for i686 version of Kernel Library\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtkmapi.h>\n#include <adkdefs.h>\n\n\n/**\n * Generates a definitions file for the Kernel Library used by the XTOS kernel assembly code\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nGenerateAssemblyDefinitions(VOID)\n{\n    /* Generate KTRAP_FRAME offsets */\n    ADK_OFFSET(KTRAP_FRAME, PreviousMode);\n    ADK_OFFSET(KTRAP_FRAME, Cr2);\n    ADK_OFFSET(KTRAP_FRAME, Cr3);\n    ADK_OFFSET(KTRAP_FRAME, Dr0);\n    ADK_OFFSET(KTRAP_FRAME, Dr1);\n    ADK_OFFSET(KTRAP_FRAME, Dr2);\n    ADK_OFFSET(KTRAP_FRAME, Dr3);\n    ADK_OFFSET(KTRAP_FRAME, Dr6);\n    ADK_OFFSET(KTRAP_FRAME, Dr7);\n    ADK_OFFSET(KTRAP_FRAME, SegDs);\n    ADK_OFFSET(KTRAP_FRAME, SegEs);\n    ADK_OFFSET(KTRAP_FRAME, SegFs);\n    ADK_OFFSET(KTRAP_FRAME, SegGs);\n    ADK_OFFSET(KTRAP_FRAME, Eax);\n    ADK_OFFSET(KTRAP_FRAME, Ebx);\n    ADK_OFFSET(KTRAP_FRAME, Ecx);\n    ADK_OFFSET(KTRAP_FRAME, Edx);\n    ADK_OFFSET(KTRAP_FRAME, Esi);\n    ADK_OFFSET(KTRAP_FRAME, Edi);\n    ADK_OFFSET(KTRAP_FRAME, Ebp);\n    ADK_OFFSET(KTRAP_FRAME, Vector);\n    ADK_OFFSET(KTRAP_FRAME, ErrorCode);\n    ADK_OFFSET(KTRAP_FRAME, Eip);\n    ADK_OFFSET(KTRAP_FRAME, SegCs);\n    ADK_OFFSET(KTRAP_FRAME, Flags);\n    ADK_OFFSET(KTRAP_FRAME, Esp);\n    ADK_OFFSET(KTRAP_FRAME, SegSs);\n\n    /* Generate KTRAP_FRAME size and REGISTERS_SIZE */\n    ADK_SIZE(KTRAP_FRAME);\n    ADK_SIZE_FROM(REGISTERS_SIZE, KTRAP_FRAME, Eax);\n\n    /* Generate PROCESSOR_START_BLOCK offsets */\n    ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);\n    ADK_OFFSET(PROCESSOR_START_BLOCK, Started);\n}\n"
  },
  {
    "path": "sdk/xtadk/includes/adkdefs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtadk/adkdefs.h\n * DESCRIPTION:     Definitions for XTADK\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTADK_ADKDEFS_H\n#define __XTADK_ADKDEFS_H\n\n\n/* Macros for calculating structure size and offsets for assembler code */\n#define ADK_DEFINE(Symbol, Value)              __asm__ volatile(\"\\n\\t# ==> \" #Symbol \" %c0\" : : \"i\" ((SIZE_T)(Value)))\n#define ADK_OFFSET(Structure, Member)          ADK_DEFINE(Structure ## _ ## Member, FIELD_OFFSET(Structure, Member))\n#define ADK_SIZE(Structure)                    ADK_DEFINE(Structure ## _SIZE, sizeof(Structure))\n#define ADK_SIZE_FROM(Name, Structure, Member) ADK_DEFINE(Structure ## _ ## Name, sizeof(Structure) - FIELD_OFFSET(Structure, Member))\n\n#endif /* __XTADK_ADKDEFS_H */\n"
  },
  {
    "path": "sdk/xtdk/README.md",
    "content": "## XT Development Kit (XTDK)\nThe XTDK, or XT Development Kit is a comprehensive set of headers designed to facilitate the development of both kernel\nmode drivers and native XT applications. It includes two main headers: xtkmapi.h and xtumapi.h.\n\nThe xtkmapi.h header is primarily used for kernel mode development, specifically for building drivers. It provides\ndevelopers with the necessary definitions and functions required to interact with the kernel and access system\nresources. With this header, developers can write efficient and secure kernel mode drivers for the XT operating system.\n\nThe xtumapi.h header is tailored for user mode development. It encompasses all the essential components needed for\ncreating user mode applications on the XT platform. This header exposes the definitions and public functions exported by\nXTOS, allowing developers to leverage the capabilities of the operating system and build powerful user mode applications.\n\nBy utilizing XTDK, developers can harness the full potential of the XT operating system and seamlessly write both kernel\nmode drivers and user mode applications. The provided headers streamline the development process by offering\na standardized set of functions and definitions, reducing the complexity and effort required to create software for the\nXT platform.\n"
  },
  {
    "path": "sdk/xtdk/amd64/artypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/amd64/artypes.h\n * DESCRIPTION:     AMD64 architecture library structure definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_AMD64_ARTYPES_H\n#define __XTDK_AMD64_ARTYPES_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include ARCH_HEADER(xtstruct.h)\n\n\n/* Control Register 0 constants */\n#define CR0_PE                                          0x00000001\n#define CR0_MP                                          0x00000002\n#define CR0_EM                                          0x00000004\n#define CR0_TS                                          0x00000008\n#define CR0_ET                                          0x00000010\n#define CR0_NE                                          0x00000020\n#define CR0_WP                                          0x00010000\n#define CR0_AM                                          0x00040000\n#define CR0_NW                                          0x20000000\n#define CR0_CD                                          0x40000000\n#define CR0_PG                                          0x80000000\n\n/* Control Register 4 constants */\n#define CR4_VME                                         0x00000001\n#define CR4_PVI                                         0x00000002\n#define CR4_TSD                                         0x00000004\n#define CR4_DE                                          0x00000008\n#define CR4_PSE                                         0x00000010\n#define CR4_PAE                                         0x00000020\n#define CR4_MCE                                         0x00000040\n#define CR4_PGE                                         0x00000080\n#define CR4_PCE                                         0x00000100\n#define CR4_FXSR                                        0x00000200\n#define CR4_XMMEXCPT                                    0x00000400\n#define CR4_UMIP                                        0x00000800\n#define CR4_LA57                                        0x00001000\n#define CR4_VMXE                                        0x00002000\n#define CR4_SMXE                                        0x00004000\n#define CR4_FSGSBASE                                    0x00010000\n#define CR4_PCIDE                                       0x00020000\n#define CR4_XSAVE                                       0x00040000\n#define CR4_KL                                          0x00080000\n#define CR4_SMEP                                        0x00100000\n#define CR4_SMAP                                        0x00200000\n#define CR4_PKE                                         0x00400000\n#define CR4_CET                                         0x00800000\n#define CR4_PKS                                         0x01000000\n#define CR4_UINTR                                       0x02000000\n#define CR4_LASS                                        0x08000000\n#define CR4_LAM_SUP                                     0x10000000\n\n/* Descriptors size */\n#define GDT_ENTRIES                                     128\n#define IDT_ENTRIES                                     256\n\n/* Initial MXCSR control */\n#define INITIAL_MXCSR                                   0x1F80\n\n/* Page Attributes Table types */\n#define PAT_TYPE_STRONG_UC                              0ULL\n#define PAT_TYPE_USWC                                   1ULL\n#define PAT_TYPE_WT                                     4ULL\n#define PAT_TYPE_WP                                     5ULL\n#define PAT_TYPE_WB                                     6ULL\n#define PAT_TYPE_WEAK_UC                                7ULL\n\n/* Segment defintions */\n#define SEGMENT_CS                                      0x2E\n#define SEGMENT_DS                                      0x3E\n#define SEGMENT_ES                                      0x26\n#define SEGMENT_SS                                      0x36\n#define SEGMENT_FS                                      0x64\n#define SEGMENT_GS                                      0x65\n\n/* MSR values */\n#define X86_MSR_SYSENTER_CS                             0x00000174\n#define X86_MSR_SYSENTER_ESP                            0x00000175\n#define X86_MSR_SYSENTER_EIP                            0x00000176\n#define X86_MSR_POWER_CONTROL                           0x000001FC\n#define X86_MSR_PAT                                     0x00000277\n#define X86_MSR_EFER                                    0xC0000080\n#define X86_MSR_STAR                                    0xC0000081\n#define X86_MSR_LSTAR                                   0xC0000082\n#define X86_MSR_CSTAR                                   0xC0000083\n#define X86_MSR_FMASK                                   0xC0000084\n#define X86_MSR_FSBASE                                  0xC0000100\n#define X86_MSR_GSBASE                                  0xC0000101\n#define X86_MSR_KERNEL_GSBASE                           0xC0000102\n#define X86_MSR_TSC_AUX                                 0xC0000103\n\n/* Processor features in the EFER MSR */\n#define X86_MSR_EFER_SCE                                (1 <<  0)\n#define X86_MSR_EFER_LME                                (1 <<  8)\n#define X86_MSR_EFER_LMA                                (1 << 10)\n#define X86_MSR_EFER_NXE                                (1 << 11)\n#define X86_MSR_EFER_SVME                               (1 << 12)\n#define X86_EFER_LMSLE                                  (1 << 13)\n#define X86_EFER_FFXSR                                  (1 << 14)\n#define X86_EFER_TCE                                    (1 << 15)\n#define X86_EFER_AUTOIBRS                               (1 << 21)\n\n/* X86 EFLAG bit masks definitions */\n#define X86_EFLAGS_NF_MASK                              0x00000000 /* None */\n#define X86_EFLAGS_CF_MASK                              0x00000001 /* Carry */\n#define X86_EFLAGS_PF_MASK                              0x00000004 /* Parity */\n#define X86_EFALGS_AF_MASK                              0x00000010 /* Aux Carry */\n#define X86_EFLAGS_ZF_MASK                              0x00000040 /* Zero */\n#define X86_EFLAGS_SF_MASK                              0x00000080 /* Sign */\n#define X86_EFLAGS_TF_MASK                              0x00000100 /* Trap */\n#define X86_EFLAGS_IF_MASK                              0x00000200 /* Interrupt */\n#define X86_EFLAGS_DF_MASK                              0x00000400 /* Direction */\n#define X86_EFLAGS_OF_MASK                              0x00000800 /* Overflow */\n#define X86_EFLAGS_IOPL_MASK                            0x00003000 /* I/O Privilege */\n#define X86_EFLAGS_NT_MASK                              0x00004000 /* Nested Task */\n#define X86_EFLAGS_SIGN_MASK                            0x00008000 /* Sign */\n#define X86_EFLAGS_RF_MASK                              0x00010000 /* Resume */\n#define X86_EFLAGS_V86_MASK                             0x00020000 /* Virtual 8086 */\n#define X86_EFLAGS_AC_MASK                              0x00040000 /* Alignment Check */\n#define X86_EFLAGS_VIF_MASK                             0x00080000 /* Virtual Interrupt */\n#define X86_EFLAGS_VIP_MASK                             0x00100000 /* Virtual Interrupt Pending */\n#define X86_EFLAGS_ID_MASK                              0x00200000 /* Identification */\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* CPU vendor enumeration list */\ntypedef enum _CPU_VENDOR\n{\n    CPU_VENDOR_AMD = 0x68747541,\n    CPU_VENDOR_INTEL = 0x756E6547,\n    CPU_VENDOR_UNKNOWN = 0xFFFFFFFF\n} CPU_VENDOR, *PCPU_VENDOR;\n\n/* CPUID advanced power management features (0x80000007) enumeration list */\ntypedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT\n{\n    CPUID_FEATURES_EDX_TS                     = 1 << 0, /* Temperature Sensor */\n    CPUID_FEATURES_EDX_FIS                    = 1 << 1, /* Frequency ID Selection */\n    CPUID_FEATURES_EDX_VIS                    = 1 << 2, /* Voltage ID Selection */\n    CPUID_FEATURES_EDX_TTS                    = 1 << 3, /* ThermaTrip Support */\n    CPUID_FEATURES_EDX_HTC                    = 1 << 4, /* Hardware Thermal Throttling */\n    CPUID_FEATURES_EDX_STC                    = 1 << 5, /* Software Thermal Throttling */\n    CPUID_FEATURES_EDX_TSCI                   = 1 << 8 /* TSC Invariant */\n} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;\n\n/* CPUID extended features (0x80000001) enumeration list */\ntypedef enum _CPUID_FEATURES_EXTENDED\n{\n    CPUID_FEATURES_ECX_LAHF_SAHF              = 1 << 0,\n    CPUID_FEATURES_ECX_CMP_LEGACY             = 1 << 1,\n    CPUID_FEATURES_ECX_SVM                    = 1 << 2,\n    CPUID_FEATURES_ECX_EXT_APIC_SPACE         = 1 << 3,\n    CPUID_FEATURES_ECX_ALT_MOV_CR8            = 1 << 4,\n    CPUID_FEATURES_ECX_LZCNT                  = 1 << 5,\n    CPUID_FEATURES_ECX_SSE4A                  = 1 << 6,\n    CPUID_FEATURES_ECX_MISALIGNED_SSE         = 1 << 7,\n    CPUID_FEATURES_ECX_PREFETCHW              = 1 << 8,\n    CPUID_FEATURES_ECX_OSVW                   = 1 << 9,\n    CPUID_FEATURES_ECX_IBS                    = 1 << 10,\n    CPUID_FEATURES_ECX_XOP                    = 1 << 11,\n    CPUID_FEATURES_ECX_SKINIT                 = 1 << 12,\n    CPUID_FEATURES_ECX_WDT                    = 1 << 13,\n    CPUID_FEATURES_ECX_LWP                    = 1 << 15,\n    CPUID_FEATURES_ECX_FMA4                   = 1 << 16,\n    CPUID_FEATURES_ECX_TCE                    = 1 << 17,\n    CPUID_FEATURES_ECX_NODEID                 = 1 << 19,\n    CPUID_FEATURES_ECX_TBM                    = 1 << 21,\n    CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS    = 1 << 22,\n    CPUID_FEATURES_ECX_PERFCTR_EXT_CORE       = 1 << 23,\n    CPUID_FEATURES_ECX_PERFCTR_EXT_NB         = 1 << 24,\n    CPUID_FEATURES_ECX_DATA_BREAKPOINT_EXT    = 1 << 26,\n    CPUID_FEATURES_ECX_PERF_TSC               = 1 << 27,\n    CPUID_FEATURES_ECX_PERFCTR_EXT_L2I        = 1 << 28,\n    CPUID_FEATURES_ECX_MONITORX_MWAITX        = 1 << 29,\n    CPUID_FEATURES_ECX_CODEBP_ADDRMASK_EXT    = 1 << 30,\n    CPUID_FEATURES_EDX_SYSCALL_SYSRET         = 1 << 11,\n    CPUID_FEATURES_EDX_NX                     = 1 << 20,\n    CPUID_FEATURES_EDX_AMD_MMX_EXT            = 1 << 22,\n    CPUID_FEATURES_EDX_FFXSR                  = 1 << 25,\n    CPUID_FEATURES_EDX_1G_PAGES               = 1 << 26,\n    CPUID_FEATURES_EDX_RDTSCP                 = 1 << 27,\n    CPUID_FEATURES_EDX_LONG_MODE              = 1 << 29,\n    CPUID_FEATURES_EDX_3DNOW_EXT              = 1 << 30,\n    CPUID_FEATURES_EDX_3DNOW                  = 1 << 31\n} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;\n\n/* CPUID Thermal and Power Management features (0x00000006) enumeration list */\ntypedef enum _CPUID_FEATURES_POWER_MANAGEMENT\n{\n    CPUID_FEATURES_EAX_DTHERM                  = 1 << 0,\n    CPUID_FEATURES_EAX_IDA                     = 1 << 1,\n    CPUID_FEATURES_EAX_ARAT                    = 1 << 2,\n    CPUID_FEATURES_EAX_PLN                     = 1 << 4,\n    CPUID_FEATURES_EAX_PTS                     = 1 << 6,\n    CPUID_FEATURES_EAX_HWP                     = 1 << 7,\n    CPUID_FEATURES_EAX_HWP_NOTIFY              = 1 << 8,\n    CPUID_FEATURES_EAX_HWP_ACT_WINDOW          = 1 << 9,\n    CPUID_FEATURES_EAX_HWP_EPP                 = 1 << 10,\n    CPUID_FEATURES_EAX_HWP_PKG_REQ             = 1 << 11,\n    CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,\n    CPUID_FEATURES_EAX_HFI                     = 1 << 19\n} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;\n\n/* CPUID STD1 features (0x00000001) enumeration list */\ntypedef enum _CPUID_FEATURES_STANDARD1\n{\n    CPUID_FEATURES_ECX_SSE3                   = 1 << 0,\n    CPUID_FEATURES_ECX_PCLMUL                 = 1 << 1,\n    CPUID_FEATURES_ECX_DTES64                 = 1 << 2,\n    CPUID_FEATURES_ECX_MONITOR                = 1 << 3,\n    CPUID_FEATURES_ECX_DS_CPL                 = 1 << 4,\n    CPUID_FEATURES_ECX_VMX                    = 1 << 5,\n    CPUID_FEATURES_ECX_SMX                    = 1 << 6,\n    CPUID_FEATURES_ECX_EST                    = 1 << 7,\n    CPUID_FEATURES_ECX_TM2                    = 1 << 8,\n    CPUID_FEATURES_ECX_SSSE3                  = 1 << 9,\n    CPUID_FEATURES_ECX_CID                    = 1 << 10,\n    CPUID_FEATURES_ECX_SDBG                   = 1 << 11,\n    CPUID_FEATURES_ECX_FMA                    = 1 << 12,\n    CPUID_FEATURES_ECX_CX16                   = 1 << 13,\n    CPUID_FEATURES_ECX_XTPR                   = 1 << 14,\n    CPUID_FEATURES_ECX_PDCM                   = 1 << 15,\n    CPUID_FEATURES_ECX_PCID                   = 1 << 17,\n    CPUID_FEATURES_ECX_DCA                    = 1 << 18,\n    CPUID_FEATURES_ECX_SSE4_1                 = 1 << 19,\n    CPUID_FEATURES_ECX_SSE4_2                 = 1 << 20,\n    CPUID_FEATURES_ECX_X2APIC                 = 1 << 21,\n    CPUID_FEATURES_ECX_MOVBE                  = 1 << 22,\n    CPUID_FEATURES_ECX_POPCNT                 = 1 << 23,\n    CPUID_FEATURES_ECX_TSC_DEADLINE           = 1 << 24,\n    CPUID_FEATURES_ECX_AES                    = 1 << 25,\n    CPUID_FEATURES_ECX_XSAVE                  = 1 << 26,\n    CPUID_FEATURES_ECX_OSXSAVE                = 1 << 27,\n    CPUID_FEATURES_ECX_AVX                    = 1 << 28,\n    CPUID_FEATURES_ECX_F16C                   = 1 << 29,\n    CPUID_FEATURES_ECX_RDRAND                 = 1 << 30,\n    CPUID_FEATURES_ECX_HYPERVISOR             = 1 << 31,\n    CPUID_FEATURES_EDX_FPU                    = 1 << 0,\n    CPUID_FEATURES_EDX_VME                    = 1 << 1,\n    CPUID_FEATURES_EDX_DE                     = 1 << 2,\n    CPUID_FEATURES_EDX_PSE                    = 1 << 3,\n    CPUID_FEATURES_EDX_TSC                    = 1 << 4,\n    CPUID_FEATURES_EDX_MSR                    = 1 << 5,\n    CPUID_FEATURES_EDX_PAE                    = 1 << 6,\n    CPUID_FEATURES_EDX_MCE                    = 1 << 7,\n    CPUID_FEATURES_EDX_CX8                    = 1 << 8,\n    CPUID_FEATURES_EDX_APIC                   = 1 << 9,\n    CPUID_FEATURES_EDX_SEP                    = 1 << 11,\n    CPUID_FEATURES_EDX_MTRR                   = 1 << 12,\n    CPUID_FEATURES_EDX_PGE                    = 1 << 13,\n    CPUID_FEATURES_EDX_MCA                    = 1 << 14,\n    CPUID_FEATURES_EDX_CMOV                   = 1 << 15,\n    CPUID_FEATURES_EDX_PAT                    = 1 << 16,\n    CPUID_FEATURES_EDX_PSE36                  = 1 << 17,\n    CPUID_FEATURES_EDX_PSN                    = 1 << 18,\n    CPUID_FEATURES_EDX_CLFLUSH                = 1 << 19,\n    CPUID_FEATURES_EDX_DS                     = 1 << 21,\n    CPUID_FEATURES_EDX_ACPI                   = 1 << 22,\n    CPUID_FEATURES_EDX_MMX                    = 1 << 23,\n    CPUID_FEATURES_EDX_FXSR                   = 1 << 24,\n    CPUID_FEATURES_EDX_SSE                    = 1 << 25,\n    CPUID_FEATURES_EDX_SSE2                   = 1 << 26,\n    CPUID_FEATURES_EDX_SS                     = 1 << 27,\n    CPUID_FEATURES_EDX_HTT                    = 1 << 28,\n    CPUID_FEATURES_EDX_TM                     = 1 << 29,\n    CPUID_FEATURES_EDX_IA64                   = 1 << 30,\n    CPUID_FEATURES_EDX_PBE                    = 1 << 31\n} CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;\n\n/* CPUID STD7 features (0x00000007, subleaf 0) enumeration list */\ntypedef enum _CPUID_FEATURES_STANDARD7_LEAF0\n{\n    CPUID_FEATURES_EBX_FSGSBASE               = 1 << 0,\n    CPUID_FEATURES_EBX_TSC_ADJUST             = 1 << 1,\n    CPUID_FEATURES_EBX_SGX                    = 1 << 2,\n    CPUID_FEATURES_EBX_BMI1                   = 1 << 3,\n    CPUID_FEATURES_EBX_HLE                    = 1 << 4,\n    CPUID_FEATURES_EBX_AVX2                   = 1 << 5,\n    CPUID_FEATURES_EBX_FDP_DEPRECATION        = 1 << 6,\n    CPUID_FEATURES_EBX_SMEP                   = 1 << 7,\n    CPUID_FEATURES_EBX_BMI2                   = 1 << 8,\n    CPUID_FEATURES_EBX_ERMS                   = 1 << 9,\n    CPUID_FEATURES_EBX_INVPCID                = 1 << 10,\n    CPUID_FEATURES_EBX_RTM                    = 1 << 11,\n    CPUID_FEATURES_EBX_QOS_MONITORING         = 1 << 12,\n    CPUID_FEATURES_EBX_DEPRECATE_FCS_FDS      = 1 << 13,\n    CPUID_FEATURES_EBX_MPX                    = 1 << 14,\n    CPUID_FEATURES_EBX_QOS_ENFORCEMENT        = 1 << 15,\n    CPUID_FEATURES_EBX_AVX512F                = 1 << 16,\n    CPUID_FEATURES_EBX_AVX512DQ               = 1 << 17,\n    CPUID_FEATURES_EBX_RDSEED                 = 1 << 18,\n    CPUID_FEATURES_EBX_ADX                    = 1 << 19,\n    CPUID_FEATURES_EBX_SMAP                   = 1 << 20,\n    CPUID_FEATURES_EBX_AVX512IFMA52           = 1 << 21,\n    CPUID_FEATURES_EBX_CLFLUSHOPT             = 1 << 23,\n    CPUID_FEATURES_EBX_CLWB                   = 1 << 24,\n    CPUID_FEATURES_EBX_PROCESSOR_TRACE        = 1 << 25,\n    CPUID_FEATURES_EBX_AVX512PF               = 1 << 26,\n    CPUID_FEATURES_EBX_AVX512ER               = 1 << 27,\n    CPUID_FEATURES_EBX_AVX512CD               = 1 << 28,\n    CPUID_FEATURES_EBX_SHA                    = 1 << 29,\n    CPUID_FEATURES_EBX_AVX512BW               = 1 << 30,\n    CPUID_FEATURES_EBX_AVX512VL               = 1 << 31,\n    CPUID_FEATURES_ECX_PREFETCHWT1            = 1 << 0,\n    CPUID_FEATURES_ECX_AVX512_VBMI            = 1 << 1,\n    CPUID_FEATURES_ECX_UMIP                   = 1 << 2,\n    CPUID_FEATURES_ECX_PKU                    = 1 << 3,\n    CPUID_FEATURES_ECX_OSPKE                  = 1 << 4,\n    CPUID_FEATURES_ECX_WAITPKG                = 1 << 5,\n    CPUID_FEATURES_ECX_AVX512_VBMI2           = 1 << 6,\n    CPUID_FEATURES_ECX_CET_SS                 = 1 << 7,\n    CPUID_FEATURES_ECX_GFNI                   = 1 << 8,\n    CPUID_FEATURES_ECX_VAES                   = 1 << 9,\n    CPUID_FEATURES_ECX_VPCLMULQDQ             = 1 << 10,\n    CPUID_FEATURES_ECX_AVX512_VNNI            = 1 << 11,\n    CPUID_FEATURES_ECX_AVX512_BITALG          = 1 << 12,\n    CPUID_FEATURES_ECX_TME                    = 1 << 13,\n    CPUID_FEATURES_ECX_AVX512_VPOPCNTDQ       = 1 << 14,\n    CPUID_FEATURES_ECX_LA57                   = 1 << 16,\n    CPUID_FEATURES_ECX_RDPID                  = 1 << 22,\n    CPUID_FEATURES_ECX_KEYLOCKER              = 1 << 23,\n    CPUID_FEATURES_ECX_BUS_LOCK_DETECT        = 1 << 24,\n    CPUID_FEATURES_ECX_CLDEMOTE               = 1 << 25,\n    CPUID_FEATURES_ECX_MOVDIRI                = 1 << 27,\n    CPUID_FEATURES_ECX_MOVDIR64B              = 1 << 28,\n    CPUID_FEATURES_ECX_ENQCMD                 = 1 << 29,\n    CPUID_FEATURES_ECX_SGX_LAUNCH_CONFIG      = 1 << 30,\n    CPUID_FEATURES_ECX_PKS                    = 1 << 31,\n    CPUID_FEATURES_EDX_SGX_KEYS               = 1 << 1,\n    CPUID_FEATURES_EDX_AVX512_4VNNIW          = 1 << 2,\n    CPUID_FEATURES_EDX_AVX512_4FMAPS          = 1 << 3,\n    CPUID_FEATURES_EDX_FAST_SHORT_REP_MOV     = 1 << 4,\n    CPUID_FEATURES_EDX_UINTR                  = 1 << 5,\n    CPUID_FEATURES_EDX_AVX512_VPINTERSECT     = 1 << 8,\n    CPUID_FEATURES_EDX_SRBDS_CTRL             = 1 << 9,\n    CPUID_FEATURES_EDX_MD_CLEAR               = 1 << 10,\n    CPUID_FEATURES_EDX_RTM_ALWAYS_ABORT       = 1 << 11,\n    CPUID_FEATURES_EDX_RTM_FORCE_ABORT        = 1 << 13,\n    CPUID_FEATURES_EDX_SERIALIZE              = 1 << 14,\n    CPUID_FEATURES_EDX_HYBRID                 = 1 << 15,\n    CPUID_FEATURES_EDX_TSXLDTRK               = 1 << 16,\n    CPUID_FEATURES_EDX_PCONFIG                = 1 << 18,\n    CPUID_FEATURES_EDX_ARCH_LBR               = 1 << 19,\n    CPUID_FEATURES_EDX_CET_IBT                = 1 << 20,\n    CPUID_FEATURES_EDX_AMX_BF16               = 1 << 22,\n    CPUID_FEATURES_EDX_AVX512_FP16            = 1 << 23,\n    CPUID_FEATURES_EDX_AMX_TILE               = 1 << 24,\n    CPUID_FEATURES_EDX_AMX_INT8               = 1 << 25,\n    CPUID_FEATURES_EDX_SCA_IBRS_IBPB          = 1 << 26,\n    CPUID_FEATURES_EDX_SCA_STIBP              = 1 << 27,\n    CPUID_FEATURES_EDX_L1D_FLUSH              = 1 << 28,\n    CPUID_FEATURES_EDX_ARCH_CAPABILITIES_MSR  = 1 << 29,\n    CPUID_FEATURES_EDX_CORE_CAPABILITIES_MSR  = 1 << 30,\n    CPUID_FEATURES_EDX_SCA_SSBD               = 1 << 31\n} CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;\n\n/* CPUID STD7 features (0x00000007, subleaf 1) enumeration list */\ntypedef enum _CPUID_FEATURES_STANDARD7_LEAF1\n{\n    CPUID_FEATURES_EAX_SHA512                 = 1 << 0,\n    CPUID_FEATURES_EAX_SM3                    = 1 << 1,\n    CPUID_FEATURES_EAX_SM4                    = 1 << 2,\n    CPUID_FEATURES_EAX_RAO_INT                = 1 << 3,\n    CPUID_FEATURES_EAX_AVX_VNNI               = 1 << 4,\n    CPUID_FEATURES_EAX_AVX512_BF16            = 1 << 5,\n    CPUID_FEATURES_EAX_LASS                   = 1 << 6,\n    CPUID_FEATURES_EAX_CMPCCXADD              = 1 << 7,\n    CPUID_FEATURES_EAX_ARCH_PERFMON           = 1 << 8,\n    CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_MOVSB = 1 << 10,\n    CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_STOSB = 1 << 11,\n    CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_CMPSB = 1 << 12,\n    CPUID_FEATURES_EAX_FRED                   = 1 << 17,\n    CPUID_FEATURES_EAX_LKGS                   = 1 << 18,\n    CPUID_FEATURES_EAX_WRMSRNS                = 1 << 19,\n    CPUID_FEATURES_EAX_NMI_SOURCE_REPORTING   = 1 << 20,\n    CPUID_FEATURES_EAX_AMX_FP16               = 1 << 21,\n    CPUID_FEATURES_EAX_HRESET                 = 1 << 22,\n    CPUID_FEATURES_EAX_AVX_IFMA               = 1 << 23,\n    CPUID_FEATURES_EAX_LAM                    = 1 << 26,\n    CPUID_FEATURES_EAX_MSRLIST                = 1 << 27,\n    CPUID_FEATURES_EAX_INVD_DISABLE           = 1 << 30,\n    CPUID_FEATURES_EAX_MOVRS                  = 1 << 31,\n    CPUID_FEATURES_EBX_PPIN                   = 1 << 0,\n    CPUID_FEATURES_EBX_TSE                    = 1 << 1,\n    CPUID_FEATURES_EBX_CPUIDMAXVAL_LIM_RMV    = 1 << 3,\n    CPUID_FEATURES_ECX_MSR_IMM                = 1 << 5,\n    CPUID_FEATURES_EDX_AVX_VNNI_INT8          = 1 << 4,\n    CPUID_FEATURES_EDX_AVX_NE_CONVERT         = 1 << 5,\n    CPUID_FEATURES_EDX_AMX_COMPLEX            = 1 << 8,\n    CPUID_FEATURES_EDX_AVX_VNNI_INT16         = 1 << 10,\n    CPUID_FEATURES_EDX_USER_TIMER             = 1 << 13,\n    CPUID_FEATURES_EDX_PREFETCHI              = 1 << 14,\n    CPUID_FEATURES_EDX_USER_MSR               = 1 << 15,\n    CPUID_FEATURES_EDX_UIRET_UIF              = 1 << 17,\n    CPUID_FEATURES_EDX_CET_SSS                = 1 << 18,\n    CPUID_FEATURES_EDX_AVX10                  = 1 << 19,\n    CPUID_FEATURES_EDX_APX                    = 1 << 21,\n    CPUID_FEATURES_EDX_MWAIT_AND_LEAF5        = 1 << 23\n} CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;\n\n/* CPUID requests */\ntypedef enum _CPUID_REQUESTS\n{\n    CPUID_GET_VENDOR_STRING                   = 0x00000000,\n    CPUID_GET_STANDARD1_FEATURES              = 0x00000001,\n    CPUID_GET_TLB_CACHE                       = 0x00000002,\n    CPUID_GET_SERIAL                          = 0x00000003,\n    CPUID_GET_CACHE_TOPOLOGY                  = 0x00000004,\n    CPUID_GET_MONITOR_MWAIT                   = 0x00000005,\n    CPUID_GET_POWER_MANAGEMENT                = 0x00000006,\n    CPUID_GET_STANDARD7_FEATURES              = 0x00000007,\n    CPUID_GET_TSC_CRYSTAL_CLOCK               = 0x00000015,\n    CPUID_GET_EXTENDED_MAX                    = 0x80000000,\n    CPUID_GET_EXTENDED_FEATURES               = 0x80000001,\n    CPUID_GET_ADVANCED_POWER_MANAGEMENT       = 0x80000007\n} CPUID_REQUESTS, *PCPUID_REQUESTS;\n\n/* Interrupt handler */\ntypedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);\n\n/* Processor identification information */\ntypedef struct _CPU_IDENTIFICATION\n{\n    ULONGLONG ExtendedFeatureBits;\n    USHORT Family;\n    ULONGLONG FeatureBits;\n    USHORT Model;\n    USHORT Stepping;\n    CPU_VENDOR Vendor;\n    UCHAR VendorName[13];\n} CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;\n\n/* CPUID registers */\ntypedef struct _CPUID_REGISTERS\n{\n    UINT32 Leaf;\n    UINT32 SubLeaf;\n    UINT32 Eax;\n    UINT32 Ebx;\n    UINT32 Ecx;\n    UINT32 Edx;\n} CPUID_REGISTERS, *PCPUID_REGISTERS;\n\n/* CPU signature read from CPUID structure definition */\ntypedef struct _CPUID_SIGNATURE\n{\n    ULONG Stepping:4;\n    ULONG Model:4;\n    ULONG Family:4;\n    ULONG Unused1:4;\n    ULONG ExtendedModel:4;\n    ULONG ExtendedFamily:8;\n    ULONG Unused2:4;\n} CPU_SIGNATURE, *PCPU_SIGNATURE;\n\n/* Trampoline types */\ntypedef enum _TRAMPOLINE_TYPE\n{\n    TrampolineApStartup,\n    TrampolineEnableXpa\n} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_AMD64_ARTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/amd64/hlfuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/amd64/hlfuncs.h\n * DESCRIPTION:     XT hardware abstraction layer routines specific to AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_AMD64_HLFUNCS_H\n#define __XTDK_AMD64_HLFUNCS_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include <amd64/xtstruct.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Hardware layer routines forward references */\nXTCLINK\nXTCDECL\nUCHAR\nHlReadPort8(IN USHORT Port);\n\nXTCLINK\nXTCDECL\nUSHORT\nHlReadPort16(IN USHORT Port);\n\nXTCLINK\nXTCDECL\nULONG\nHlReadPort32(IN USHORT Port);\n\nXTCLINK\nXTCDECL\nVOID\nHlWritePort8(IN USHORT Port,\n             IN UCHAR Data);\n\nXTCLINK\nXTCDECL\nVOID\nHlWritePort16(IN USHORT Port,\n              IN USHORT Value);\n\nXTCLINK\nXTCDECL\nVOID\nHlWritePort32(IN USHORT Port,\n              IN ULONG Value);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_AMD64_HLFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/amd64/hltypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/amd64/hltypes.h\n * DESCRIPTION:     XT hardware abstraction layer structures definitions specific to AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_AMD64_HLTYPES_H\n#define __XTDK_AMD64_HLTYPES_H\n\n#include <xtbase.h>\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include ARCH_HEADER(xtstruct.h)\n\n\n/* APIC base addresses */\n#define APIC_BASE                                       0xFFFFFFFFFFFE0000\n#define APIC_LAPIC_MSR_BASE                             0x0000001B\n#define APIC_X2APIC_MSR_BASE                            0x00000800\n\n/* APIC vector definitions */\n#define APIC_VECTOR_ZERO                                0x00\n#define APIC_VECTOR_APC                                 0x1F\n#define APIC_VECTOR_DPC                                 0x2F\n#define APIC_VECTOR_CMCI                                0x35\n#define APIC_VECTOR_SPURIOUS                            0x3F\n#define APIC_VECTOR_REBOOT                              0x50\n#define APIC_VECTOR_GENERIC                             0xC1\n#define APIC_VECTOR_SYNC                                0xD1\n#define APIC_VECTOR_CLOCK                               0xD1\n#define APIC_VECTOR_CLOCK_IPI                           0xD2\n#define APIC_VECTOR_IPI                                 0xE1\n#define APIC_VECTOR_ERROR                               0xE3\n#define APIC_VECTOR_POWERFAIL                           0xEF\n#define APIC_VECTOR_PROFILE                             0xFD\n#define APIC_VECTOR_PERF                                0xFE\n#define APIC_VECTOR_NMI                                 0xFF\n\n/* APIC destination formats */\n#define APIC_DF_FLAT                                    0xFFFFFFFF\n#define APIC_DF_CLUSTER                                 0x0FFFFFFF\n\n/* APIC trigger modes */\n#define APIC_TGM_EDGE                                   0\n#define APIC_TGM_LEVEL                                  1\n\n/* APIC LDR (Logical Destination Register) shifts */\n#define APIC_X2APIC_LDR_SHIFT                           16\n#define APIC_XAPIC_LDR_SHIFT                            24\n\n/* Maximum number of I/O APICs */\n#define APIC_MAX_IOAPICS                                64\n\n/* I/O APIC base address */\n#define IOAPIC_DEFAULT_BASE                             0xFEC00000\n\n/* I/O APIC definitions */\n#define IOAPIC_MAX_CONTROLLERS                          128\n#define IOAPIC_MAX_OVERRIDES                            16\n#define IOAPIC_RTE_MASKED                               0x100FF\n#define IOAPIC_RTE_SIZE                                 2\n#define IOAPIC_VECTOR_FREE                              0xFF\n#define IOAPIC_VECTOR_RESERVED                          0xFE\n\n/* IOAPIC offsets */\n#define IOAPIC_IOREGSEL                                 0x00\n#define IOAPIC_IOWIN                                    0x10\n\n/* IOAPIC registers */\n#define IOAPIC_ID                                       0x00\n#define IOAPIC_VER                                      0x01\n#define IOAPIC_ARB                                      0x02\n#define IOAPIC_REDTBL                                   0x10\n\n/* 8259/ISP PIC ports definitions */\n#define PIC1_CONTROL_PORT                               0x20\n#define PIC1_DATA_PORT                                  0x21\n#define PIC2_CONTROL_PORT                               0xA0\n#define PIC2_DATA_PORT                                  0xA1\n\n/* PIC vector definitions */\n#define PIC1_VECTOR_SPURIOUS                            0x37\n\n/* HPET General Capabilities definitions */\n#define HPET_CAPABILITY_64BIT                           0x2000ULL\n#define HPET_CAPABILITY_LEGACY_REPLACEMENT              0x8000ULL\n\n/* HPET General Configuration definitions */\n#define HPET_CONFIG_ENABLE                              0x0001ULL\n#define HPET_CONFIG_LEGACY_REPLACEMENT                  0x0002ULL\n\n/* HPET Timer Configuration definitions */\n#define HPET_TIMER_CONFIG_LEVEL_TRIGGERED               0x0002ULL\n#define HPET_TIMER_CONFIG_ENABLED                       0x0004ULL\n#define HPET_TIMER_CONFIG_PERIODIC                      0x0008ULL\n#define HPET_TIMER_CONFIG_SUPPORTS_PERIODIC             0x0010ULL\n#define HPET_TIMER_CONFIG_SUPPORTS_64BIT                0x0020ULL\n#define HPET_TIMER_CONFIG_VALUE_ACCUMULATOR             0x0040ULL\n#define HPET_TIMER_CONFIG_FORCE_32BIT                   0x0100ULL\n#define HPET_TIMER_CONFIG_FSB_ENABLED                   0x4000ULL\n#define HPET_TIMER_CONFIG_SUPPORTS_FSB                  0x8000ULL\n\n/* PIT ports definitions */\n#define PIT_COMMAND_PORT                                0x43\n#define PIT_DATA_PORT0                                  0x40\n#define PIT_DATA_PORT1                                  0x41\n#define PIT_DATA_PORT2                                  0x42\n\n/* PIT related definitions */\n#define PIT_BASE_FREQUENCY                              1193182\n\n/* PIT Access Mode: Defines how the CPU reads or writes the counter value */\n#define PIT_CMD_ACCESS_LATCH                            0x00\n#define PIT_CMD_ACCESS_LOWBYTE_ONLY                     0x10\n#define PIT_CMD_ACCESS_HIGHBYTE_ONLY                    0x20\n#define PIT_CMD_ACCESS_LOWBYTE_HIGHBYTE                 0x30\n\n/* PIT Channel Selection: Specifies the physical timer channel to configure */\n#define PIT_CMD_CHANNEL0                                0x00\n#define PIT_CMD_CHANNEL1                                0x40\n#define PIT_CMD_CHANNEL2                                0x80\n\n/* PIT Operating Mode: Defines the hardware behavior and the generated waveform */\n#define PIT_MODE0_INT_ON_TERMINAL_COUNT                 0x00\n#define PIT_MODE1_ONESHOT                               0x02\n#define PIT_MODE2_RATE_GENERATOR                        0x04\n#define PIT_MODE3_SQUARE_WAVE_GEN                       0x06\n#define PIT_MODE4_SOFTWARE_STROBE                       0x08\n#define PIT_MODE5_HARDWARE_STROBE                       0x0A\n\n/* CMOS controller access ports */\n#define CMOS_SELECT_PORT                                0x70\n#define CMOS_DATA_PORT                                  0x71\n\n/* CMOD Select port definitions */\n#define CMOS_NMI_SELECT                                 0x80\n#define CMOS_REGISTER_SECOND                            0x00\n#define CMOS_REGISTER_MINUTE                            0x02\n#define CMOS_REGISTER_HOUR                              0x04\n#define CMOS_REGISTER_WEEKDAY                           0x06\n#define CMOS_REGISTER_DAY                               0x07\n#define CMOS_REGISTER_MONTH                             0x08\n#define CMOS_REGISTER_YEAR                              0x09\n#define CMOS_REGISTER_A                                 0x0A\n#define CMOS_REGISTER_B                                 0x0B\n#define CMOS_REGISTER_C                                 0x0C\n\n/* CMOS Register A definitions */\n#define CMOS_REGISTER_A_RATE_MASK                       0x0F\n#define CMOS_REGISTER_A_UPDATE_IN_PROGRESS              0x80\n\n/* CMOS Register B definitions */\n#define CMOS_REGISTER_B_24_HOUR                         0x02\n#define CMOS_REGISTER_B_BINARY                          0x04\n#define CMOS_REGISTER_B_PERIODIC                        0x40\n#define CMOS_REGISTER_B_SET_CLOCK                       0x80\n\n/* CMOS Register C definitions */\n#define CMOS_REGISTER_C_PERIODIC                        0x40\n#define CMOS_REGISTER_C_INTERRUPT                       0x80\n\n/* CMOS RTC 24-hour mode */\n#define CMOS_RTC_POST_MERIDIEM                          0x80\n\n/* Serial ports information */\n#define COMPORT_ADDRESS                                 {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}\n#define COMPORT_COUNT                                   8\n\n/* Initial stall factor */\n#define INITIAL_STALL_FACTOR                            100\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* APIC destination mode enumeration list */\ntypedef enum _APIC_DEST_MODE\n{\n    APIC_DM_Physical,\n    APIC_DM_Logical\n} APIC_DEST_MODE, *PAPIC_DEST_MODE;\n\n/* APIC delivery mode enumeration list */\ntypedef enum _APIC_DM\n{\n    APIC_DM_FIXED,\n    APIC_DM_LOWPRIO,\n    APIC_DM_SMI,\n    APIC_DM_REMOTE,\n    APIC_DM_NMI,\n    APIC_DM_INIT,\n    APIC_DM_STARTUP,\n    APIC_DM_EXTINT,\n} APIC_DM, *PAPIC_DM;\n\n/* APIC destination short-hand enumeration list */\ntypedef enum _APIC_DSH\n{\n    APIC_DSH_Destination,\n    APIC_DSH_Self,\n    APIC_DSH_AllIncludingSelf,\n    APIC_DSH_AllExclusingSelf\n} APIC_DSH, *PAPIC_DSH;\n\n/* APIC mode list */\ntypedef enum _APIC_MODE\n{\n    APIC_MODE_COMPAT,\n    APIC_MODE_X2APIC\n} APIC_MODE, *PAPIC_MODE;\n\n/* APIC Register Address Map */\ntypedef enum _APIC_REGISTER\n{\n    APIC_ID       = 0x02, /* APIC ID Register */\n    APIC_VER      = 0x03, /* APIC Version Register */\n    APIC_TPR      = 0x08, /* Task Priority Register */\n    APIC_APR      = 0x09, /* Arbitration Priority Register */\n    APIC_PPR      = 0x0A, /* Processor Priority Register (R) */\n    APIC_EOI      = 0x0B, /* EOI Register */\n    APIC_RRR      = 0x0C, /* Remote Read Register */\n    APIC_LDR      = 0x0D, /* Logical Destination Register */\n    APIC_DFR      = 0x0E, /* Destination Format Register (not available in extended mode) */\n    APIC_SIVR     = 0x0F, /* Spurious Interrupt Vector Register */\n    APIC_ISR      = 0x10, /* Interrupt Service Register*/\n    APIC_TMR      = 0x18, /* Trigger Mode Register */\n    APIC_IRR      = 0x20, /* Interrupt Request Register */\n    APIC_ESR      = 0x28, /* Error Status Register */\n    APIC_ICR0     = 0x30, /* Interrupt Command Register */\n    APIC_ICR1     = 0x31, /* Interrupt Command Register (not available in extended mode) */\n    APIC_TMRLVTR  = 0x32, /* Timer Local Vector Table */\n    APIC_THRMLVTR = 0x33, /* Thermal Local Vector Table */\n    APIC_PCLVTR   = 0x34, /* Performance Counter Local Vector Table */\n    APIC_LINT0    = 0x35, /* LINT0 Local Vector Table */\n    APIC_LINT1    = 0x36, /* LINT1 Local Vector Table */\n    APIC_ERRLVTR  = 0x37, /* Error Local Vector Table */\n    APIC_TICR     = 0x38, /* Initial Count Register for Timer */\n    APIC_TCCR     = 0x39, /* Current Count Register for Timer */\n    APIC_TDCR     = 0x3E, /* Timer Divide Configuration Register */\n    APIC_SIPI     = 0x3F, /* Self-IPI Register */\n    APIC_EAFR     = 0x40, /* extended APIC Feature register */\n    APIC_EACR     = 0x41, /* Extended APIC Control Register */\n    APIC_SEOI     = 0x42, /* Specific End Of Interrupt Register */\n    APIC_EXT0LVTR = 0x50, /* Extended Interrupt 0 Local Vector Table */\n    APIC_EXT1LVTR = 0x51, /* Extended Interrupt 1 Local Vector Table */\n    APIC_EXT2LVTR = 0x52, /* Extended Interrupt 2 Local Vector Table */\n    APIC_EXT3LVTR = 0x53  /* Extended Interrupt 3 Local Vector Table */\n} APIC_REGISTER, *PAPIC_REGISTER;\n\n/* APIC Timer Divide enumeration list */\ntypedef enum _APIC_TIMER_DIVISOR\n{\n    TIMER_DivideBy2   = 0,\n    TIMER_DivideBy4   = 1,\n    TIMER_DivideBy8   = 2,\n    TIMER_DivideBy16  = 3,\n    TIMER_DivideBy32  = 8,\n    TIMER_DivideBy64  = 9,\n    TIMER_DivideBy128 = 10,\n    TIMER_DivideBy1   = 11,\n} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;\n\n/* I8259 PIC interrupt mode enumeration list */\ntypedef enum _PIC_I8259_ICW1_INTERRUPT_MODE\n{\n    EdgeTriggered,\n    LevelTriggered\n} PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;\n\n/* I8259 PIC interval enumeration list */\ntypedef enum _PIC_I8259_ICW1_INTERVAL\n{\n    Interval8,\n    Interval4\n} PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;\n\n/* I8259 PIC operating mode enumeration list */\ntypedef enum _PIC_I8259_ICW1_OPERATING_MODE\n{\n    Cascade,\n    Single\n} PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_MODE;\n\n/* I8259 PIC buffered mode enumeration list */\ntypedef enum _PIC_I8259_ICW4_BUFFERED_MODE\n{\n    NonBuffered,\n    NonBuffered2,\n    BufferedSlave,\n    BufferedMaster\n} PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;\n\n/* I8259 PIC End Of Interrupt (EOI) mode enumeration list */\ntypedef enum _PIC_I8259_ICW4_EOI_MODE\n{\n    NormalEoi,\n    AutomaticEoi\n} PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;\n\n/* I8259 PIC system mode enumeration list */\ntypedef enum _PIC_I8259_ICW4_SYSTEM_MODE\n{\n    Mcs8085Mode,\n    New8086Mode\n} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;\n\n/* Supported hardware timer backends */\ntypedef enum _TIMER_TYPE\n{\n    TimerNone,\n    TimerAcpiPm,\n    TimerHpet,\n    TimerLapic,\n    TimerPit,\n    TimerTsc\n} TIMER_TYPE, *PTIMER_TYPE;\n\n/* APIC Base Register */\ntypedef union _APIC_BASE_REGISTER\n{\n    ULONGLONG LongLong;\n    struct\n    {\n        ULONGLONG Reserved1:8;\n        ULONGLONG BootStrapProcessor:1;\n        ULONGLONG Reserved2:1;\n        ULONGLONG ExtendedMode:1;\n        ULONGLONG Enable:1;\n        ULONGLONG BaseAddress:40;\n        ULONGLONG Reserved3:12;\n    };\n} APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;\n\n/* APIC Command Register */\ntypedef union _APIC_COMMAND_REGISTER\n{\n    ULONGLONG LongLong;\n    struct\n    {\n        ULONG Long0;\n        ULONG Long1;\n    };\n    struct\n    {\n        ULONGLONG Vector:8;\n        ULONGLONG DeliveryMode:3;\n        ULONGLONG DestinationMode:1;\n        ULONGLONG DeliveryStatus:1;\n        ULONGLONG ReservedMBZ:1;\n        ULONGLONG Level:1;\n        ULONGLONG TriggerMode:1;\n        ULONGLONG RemoteReadStatus:2;\n        ULONGLONG DestinationShortHand:2;\n        ULONGLONG Reserved2MBZ:36;\n        ULONGLONG Destination:8;\n    };\n} APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;\n\n/* APIC Local Vector Table (LVT) Register */\ntypedef union _APIC_LVT_REGISTER\n{\n    ULONG Long;\n    struct\n    {\n        ULONG Vector:8;\n        ULONG DeliveryMode:3;\n        ULONG Reserved1:1;\n        ULONG DeliveryStatus:1;\n        ULONG Reserved2:1;\n        ULONG RemoteIRR:1;\n        ULONG TriggerMode:1;\n        ULONG Mask:1;\n        ULONG TimerMode:1;\n        ULONG Reserved3:13;\n    };\n} APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;\n\n/* APIC Spurious Register */\ntypedef union _APIC_SPURIOUS_REGISTER\n{\n    ULONG Long;\n    struct\n    {\n        ULONG Vector:8;\n        ULONG SoftwareEnable:1;\n        ULONG CoreChecking:1;\n        ULONG Reserved:22;\n    };\n} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;\n\n/* I/O APIC Controller information */\ntypedef struct _IOAPIC_DATA\n{\n    ULONG GsiBase;\n    ULONG Identifier;\n    ULONG LineCount;\n    PHYSICAL_ADDRESS PhysicalAddress;\n    ULONG_PTR VirtualAddress;\n} IOAPIC_DATA, *PIOAPIC_DATA;\n\n/* I/O APIC Redirection Register */\ntypedef union _IOAPIC_REDIRECTION_REGISTER\n{\n    ULONGLONG LongLong;\n    struct\n    {\n        UINT Base;\n        UINT Extended;\n    };\n    struct\n    {\n        ULONGLONG Vector:8;\n        ULONGLONG DeliveryMode:3;\n        ULONGLONG DestinationMode:1;\n        ULONGLONG DeliveryStatus:1;\n        ULONGLONG PinPolarity:1;\n        ULONGLONG RemoteIRR:1;\n        ULONGLONG TriggerMode:1;\n        ULONGLONG Mask:1;\n        ULONGLONG Reserved:39;\n        ULONGLONG Destination:8;\n    };\n} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;\n\n/* I8259 PIC register structure */\ntypedef union _PIC_I8259_ICW1\n{\n    struct\n    {\n        UCHAR NeedIcw4:1;\n        UCHAR OperatingMode:1;\n        UCHAR Interval:1;\n        UCHAR InterruptMode:1;\n        UCHAR Init:1;\n        UCHAR InterruptVectorAddress:3;\n    };\n    UCHAR Bits;\n} PIC_I8259_ICW1, *PPIC_I8259_ICW1;\n\n/* I8259 PIC register structure */\ntypedef union _PIC_I8259_ICW2\n{\n    struct\n    {\n        UCHAR Sbz:3;\n        UCHAR InterruptVector:5;\n    };\n    UCHAR Bits;\n} PIC_I8259_ICW2, *PPIC_I8259_ICW2;\n\n/* I8259 PIC register structure */\ntypedef union _PIC_I8259_ICW3\n{\n    union\n    {\n        struct\n        {\n            UCHAR SlaveIrq0:1;\n            UCHAR SlaveIrq1:1;\n            UCHAR SlaveIrq2:1;\n            UCHAR SlaveIrq3:1;\n            UCHAR SlaveIrq4:1;\n            UCHAR SlaveIrq5:1;\n            UCHAR SlaveIrq6:1;\n            UCHAR SlaveIrq7:1;\n        };\n        struct\n        {\n            UCHAR SlaveId:3;\n            UCHAR Reserved:5;\n        };\n    };\n    UCHAR Bits;\n} PIC_I8259_ICW3, *PPIC_I8259_ICW3;\n\n/* I8259 PIC register structure */\ntypedef union _PIC_I8259_ICW4\n{\n    struct\n    {\n        UCHAR SystemMode:1;\n        UCHAR EoiMode:1;\n        UCHAR BufferedMode:2;\n        UCHAR SpecialFullyNestedMode:1;\n        UCHAR Reserved:3;\n    };\n    UCHAR Bits;\n} PIC_I8259_ICW4, *PPIC_I8259_ICW4;\n\n/* HPET Registers structure definition */\ntypedef struct _HPET_REGISTERS\n{\n    VOLATILE ULONGLONG GeneralCapabilities;\n    VOLATILE ULONGLONG Reserved0;\n    VOLATILE ULONGLONG GeneralConfiguration;\n    VOLATILE ULONGLONG Reserved1;\n    VOLATILE ULONGLONG GeneralInterruptStatus;\n    VOLATILE ULONGLONG Reserved2;\n    VOLATILE ULONGLONG Reserved3[2][12];\n    VOLATILE ULONGLONG MainCounterValue;\n    VOLATILE ULONGLONG Reserved4;\n    struct\n    {\n        VOLATILE ULONGLONG Configuration;\n        VOLATILE ULONGLONG Comparator;\n        VOLATILE ULONGLONG FsbInterruptRoute;\n        VOLATILE ULONGLONG Reserved;\n    } Timers[];\n} HPET_REGISTERS, *PHPET_REGISTERS;\n\n/* Hardware timer capabilities and CPU clock features */\ntypedef struct _TIMER_CAPABILITIES\n{\n    BOOLEAN Arat;\n    BOOLEAN Art;\n    BOOLEAN InvariantTsc;\n    BOOLEAN RDTSCP;\n    ULONG TimerFrequency;\n    BOOLEAN TscDeadline;\n    ULONG TscDenominator;\n    ULONG TscNumerator;\n} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_AMD64_HLTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/amd64/ketypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/amd64/ketypes.h\n * DESCRIPTION:     Kernel services related structures definitions specific to AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_AMD64_KETYPES_H\n#define __XTDK_AMD64_KETYPES_H\n\n#include <xtbase.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include <potypes.h>\n#include ARCH_HEADER(xtstruct.h)\n#include ARCH_HEADER(artypes.h)\n\n\n/* Selector masks */\n#define MODE_MASK                                 0x0001\n#define RPL_MASK                                  0x0003\n\n/* GDT selector names */\n#define KGDT_NULL                                 0x0000\n#define KGDT_R0_CMCODE                            0x0008\n#define KGDT_R0_CODE                              0x0010\n#define KGDT_R0_DATA                              0x0018\n#define KGDT_R3_CMCODE                            0x0020\n#define KGDT_R3_DATA                              0x0028\n#define KGDT_R3_CODE                              0x0030\n#define KGDT_SYS_TSS                              0x0040\n#define KGDT_R3_CMTEB                             0x0050\n#define KGDT_R0_LDT                               0x0060\n#define KGDT_ALIAS                                0x0070\n\n/* GDT descriptor privilege levels */\n#define KGDT_DPL_SYSTEM                           0\n#define KGDT_DPL_USER                             3\n\n/* GDT descriptor properties */\n#define KGDT_DESCRIPTOR_ACCESSED                  0x01\n#define KGDT_DESCRIPTOR_READ_WRITE                0x02\n#define KGDT_DESCRIPTOR_EXECUTE_READ              0x02\n#define KGDT_DESCRIPTOR_EXPAND_DOWN               0x04\n#define KGDT_DESCRIPTOR_CONFORMING                0x04\n#define KGDT_DESCRIPTOR_CODE                      0x08\n\n/* GDT descriptor type codes */\n#define KGDT_TYPE_NONE                            0x00\n#define KGDT_TYPE_CODE                            (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)\n#define KGDT_TYPE_DATA                            (0x10 | KGDT_DESCRIPTOR_READ_WRITE)\n\n/* IDT access levels */\n#define KIDT_ACCESS_RING0                         0x0\n#define KIDT_ACCESS_RING3                         0x3\n\n/* IDT Interrupt Stack Table entries */\n#define KIDT_IST_RESERVED                         0\n#define KIDT_IST_PANIC                            1\n#define KIDT_IST_MCA                              2\n#define KIDT_IST_NMI                              3\n\n/* AMD64 Segment Types */\n#define AMD64_TASK_GATE                           0x5\n#define AMD64_TSS                                 0x9\n#define AMD64_ACTIVE_TSS                          0xB\n#define AMD64_CALL_GATE                           0xC\n#define AMD64_INTERRUPT_GATE                      0xE\n#define AMD64_TRAP_GATE                           0xF\n\n/* Kernel CPU Standard Features */\n#define KCF_VME                           (1ULL << 0)  /* Virtual 8086 Mode Enhancements */\n#define KCF_LARGE_PAGE                    (1ULL << 1)  /* Page Size Extensions */\n#define KCF_RDTSC                         (1ULL << 2)  /* Time Stamp Counter */\n#define KCF_PAE                           (1ULL << 3)  /* Physical Address Extension */\n#define KCF_MCE                           (1ULL << 4)  /* Machine Check Exception */\n#define KCF_CMPXCHG8B                     (1ULL << 5)  /* CMPXCHG8B Instruction */\n#define KCF_APIC                          (1ULL << 6)  /* APIC On-Chip */\n#define KCF_FAST_SYSCALL                  (1ULL << 7)  /* SYSENTER/SYSEXIT Instructions */\n#define KCF_MTRR                          (1ULL << 8)  /* Memory Type Range Registers */\n#define KCF_GLOBAL_PAGE                   (1ULL << 9)  /* Page Global Enable */\n#define KCF_MCA                           (1ULL << 10) /* Machine Check Architecture */\n#define KCF_CMOV                          (1ULL << 11) /* Conditional Move Instructions */\n#define KCF_PAT                           (1ULL << 12) /* Page Attribute Table */\n#define KCF_PSE36                         (1ULL << 13) /* 36-bit Page Size Extension */\n#define KCF_CLFLUSH                       (1ULL << 14) /* CLFLUSH Instruction */\n#define KCF_FXSR                          (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */\n#define KCF_ACPI                          (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */\n#define KCF_MMX                           (1ULL << 17) /* MMX Technology */\n#define KCF_SSE                           (1ULL << 18) /* Streaming SIMD Extensions */\n#define KCF_SSE2                          (1ULL << 19) /* Streaming SIMD Extensions 2 */\n#define KCF_SMT                           (1ULL << 20) /* Hyper-Threading Technology */\n#define KCF_SSE3                          (1ULL << 21) /* Streaming SIMD Extensions 3 */\n#define KCF_VMX                           (1ULL << 22) /* Intel Virtual Machine Extensions */\n#define KCF_SSSE3                         (1ULL << 23) /* Supplemental SSE3 Instructions */\n#define KCF_SSE41                         (1ULL << 24) /* SSE4.1 Instructions */\n#define KCF_SSE42                         (1ULL << 25) /* SSE4.2 Instructions */\n#define KCF_X2APIC                        (1ULL << 26) /* x2APIC Support */\n#define KCF_POPCNT                        (1ULL << 27) /* POPCNT Instruction */\n#define KCF_TSC_DEADLINE                  (1ULL << 28) /* TSC Deadline Timer */\n#define KCF_AES                           (1ULL << 29) /* AES-NI Instruction Set */\n#define KCF_XSAVE                         (1ULL << 30) /* XSAVE/XRSTOR Instructions */\n#define KCF_AVX                           (1ULL << 31) /* Advanced Vector Extensions */\n#define KCF_RDRAND                        (1ULL << 32) /* RDRAND Instruction */\n#define KCF_FSGSBASE                      (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */\n#define KCF_AVX2                          (1ULL << 34) /* AVX2 Instructions */\n#define KCF_SMEP                          (1ULL << 35) /* Supervisor Mode Execution Prevention */\n#define KCF_RDSEED                        (1ULL << 36) /* RDSEED Instruction */\n#define KCF_SMAP                          (1ULL << 37) /* Supervisor Mode Access Prevention */\n#define KCF_SHA                           (1ULL << 38) /* SHA Extensions */\n#define KCF_LA57                          (1ULL << 39) /* 57-bit Linear Addresses */\n#define KCF_ARAT                          (1ULL << 40) /* Always Running APIC Timer */\n\n/* Kernel CPU Extended Features */\n#define KCF_SVM                           (1ULL << 0)  /* AMD Secure Virtual Machine */\n#define KCF_SSE4A                         (1ULL << 1)  /* SSE4A Instructions */\n#define KCF_FMA4                          (1ULL << 2)  /* FMA4 Instructions */\n#define KCF_TOPOEXT                       (1ULL << 3)  /* AMD Topology Extensions */\n#define KCF_SYSCALL                       (1ULL << 4)  /* SYSCALL/SYSRET Instructions */\n#define KCF_NX_BIT                        (1ULL << 5)  /* No-Execute Page Protection */\n#define KCF_RDTSCP                        (1ULL << 6)  /* RDTSCP Instruction */\n#define KCF_64BIT                         (1ULL << 7)  /* Long Mode Support */\n#define KCF_3DNOW_EXT                     (1ULL << 8)  /* 3DNow! Extensions */\n#define KCF_3DNOW                         (1ULL << 9)  /* 3DNow! Instructions */\n#define KCF_INVARIANT_TSC                 (1ULL << 10) /* Invariant Time Stamp Counter */\n\n/* Context control flags */\n#define CONTEXT_ARCHITECTURE                      0x00100000\n#define CONTEXT_CONTROL                           (CONTEXT_ARCHITECTURE | 0x01)\n#define CONTEXT_INTEGER                           (CONTEXT_ARCHITECTURE | 0x02)\n#define CONTEXT_SEGMENTS                          (CONTEXT_ARCHITECTURE | 0x04)\n#define CONTEXT_FLOATING_POINT                    (CONTEXT_ARCHITECTURE | 0x08)\n#define CONTEXT_DEBUG_REGISTERS                   (CONTEXT_ARCHITECTURE | 0x10)\n\n/* Interrupt request levels definitions */\n#define PASSIVE_LEVEL                             0\n#define LOW_LEVEL                                 0\n#define APC_LEVEL                                 1\n#define DISPATCH_LEVEL                            2\n#define CMC_LEVEL                                 5\n#define DEVICE1_LEVEL                             6\n#define DEVICE2_LEVEL                             7\n#define DEVICE3_LEVEL                             8\n#define DEVICE4_LEVEL                             9\n#define DEVICE5_LEVEL                             10\n#define DEVICE6_LEVEL                             11\n#define DEVICE7_LEVEL                             12\n#define SYNC_LEVEL                                12\n#define CLOCK_LEVEL                               13\n#define IPI_LEVEL                                 14\n#define DRS_LEVEL                                 14\n#define POWER_LEVEL                               14\n#define PROFILE_LEVEL                             15\n#define HIGH_LEVEL                                15\n\n/* Size of the exception area */\n#define EXCEPTION_AREA_SIZE               64\n\n/* IOPM Definitions */\n#define IO_ACCESS_MAP_NONE                0\n\n/* Size of the FNSAVE/FRSTOR save area */\n#define FLOATING_SAVE_AREA_SIZE           ((sizeof(FLOATING_SAVE_AREA) + 15) & ~15)\n\n/* Static Kernel-Mode address start */\n#define KSEG0_BASE                        0xFFFFF80000000000\n\n/* XTOS Kernel stack size */\n#define KERNEL_STACK_SIZE                 0x8000\n#define KERNEL_STACKS                     3\n\n/* XTOS Kernel stack guard pages */\n#define KERNEL_STACK_GUARD_PAGES          1\n\n/* Processor structures size */\n#define KPROCESSOR_STRUCTURES_SIZE        ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \\\n                                          sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)\n\n/* Kernel frames */\n#define KEXCEPTION_FRAME_SIZE             sizeof(KEXCEPTION_FRAME)\n#define KSWITCH_FRAME_SIZE                sizeof(KSWITCH_FRAME)\n#define KTRAP_FRAME_ALIGN                 0x10\n#define KTRAP_FRAME_SIZE                  sizeof(KTRAP_FRAME)\n\n/* Return address size pushed by 'call' instruction */\n#define KRETURN_ADDRESS_SIZE              0x8\n\n/* Size of legacy 387 registers */\n#define SIZE_OF_80387_REGISTERS           80\n\n/* NPX state definitions */\n#define NPX_STATE_UNUSED                  0x0\n#define NPX_STATE_SCRUB                   0x1\n#define NPX_STATE_SWITCH                  0x2\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Floating point state storing structure */\ntypedef struct _FLOATING_SAVE_AREA\n{\n    USHORT ControlWord;\n    USHORT StatusWord;\n    USHORT TagWord;\n    ULONG ErrorOffset;\n    USHORT ErrorSelector;\n    USHORT ErrorOpcode;\n    ULONG DataOffset;\n    USHORT DataSelector;\n    UCHAR RegisterArea[SIZE_OF_80387_REGISTERS];\n} FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;\n\n/* Context frame structure definition */\ntypedef struct _CONTEXT\n{\n    ULONG64 P1Home;\n    ULONG64 P2Home;\n    ULONG64 P3Home;\n    ULONG64 P4Home;\n    ULONG64 P5Home;\n    ULONG64 P6Home;\n    ULONG ContextFlags;\n    ULONG MxCsr;\n    USHORT SegCs;\n    USHORT SegDs;\n    USHORT SegEs;\n    USHORT SegFs;\n    USHORT SegGs;\n    USHORT SegSs;\n    ULONG EFlags;\n    ULONG64 Dr0;\n    ULONG64 Dr1;\n    ULONG64 Dr2;\n    ULONG64 Dr3;\n    ULONG64 Dr6;\n    ULONG64 Dr7;\n    ULONG64 Rax;\n    ULONG64 Rcx;\n    ULONG64 Rdx;\n    ULONG64 Rbx;\n    ULONG64 Rsp;\n    ULONG64 Rbp;\n    ULONG64 Rsi;\n    ULONG64 Rdi;\n    ULONG64 R8;\n    ULONG64 R9;\n    ULONG64 R10;\n    ULONG64 R11;\n    ULONG64 R12;\n    ULONG64 R13;\n    ULONG64 R14;\n    ULONG64 R15;\n    ULONG64 Rip;\n    union\n    {\n        FLOATING_SAVE_AREA FloatSave;\n        struct\n        {\n            M128 Header[2];\n            M128 Legacy[8];\n            M128 Xmm0;\n            M128 Xmm1;\n            M128 Xmm2;\n            M128 Xmm3;\n            M128 Xmm4;\n            M128 Xmm5;\n            M128 Xmm6;\n            M128 Xmm7;\n            M128 Xmm8;\n            M128 Xmm9;\n            M128 Xmm10;\n            M128 Xmm11;\n            M128 Xmm12;\n            M128 Xmm13;\n            M128 Xmm14;\n            M128 Xmm15;\n        };\n    };\n    M128 VectorRegister[26];\n    ULONG64 VectorControl;\n    ULONG64 DebugControl;\n    ULONG64 LastBranchToRip;\n    ULONG64 LastBranchFromRip;\n    ULONG64 LastExceptionToRip;\n    ULONG64 LastExceptionFromRip;\n} ALIGN(16) CONTEXT, *PCONTEXT;\n\n/* Pseudo 64-bit descriptor structure definition */\ntypedef struct _KDESCRIPTOR\n{\n    USHORT Pad[3];\n    USHORT Limit;\n    PVOID Base;\n} KDESCRIPTOR, *PKDESCRIPTOR;\n\n/* Global Descriptor Table (GDT) entry union definition */\ntypedef struct _KGDTENTRY\n{\n    USHORT LimitLow;\n    USHORT BaseLow;\n    union\n    {\n        struct\n        {\n            UCHAR BaseMiddle;\n            UCHAR Flags1;\n            UCHAR Flags2;\n            UCHAR BaseHigh;\n        } Bytes;\n        struct\n        {\n            ULONG BaseMiddle:8;\n            ULONG Type:5;\n            ULONG Dpl:2;\n            ULONG Present:1;\n            ULONG LimitHigh:4;\n            ULONG System:1;\n            ULONG LongMode:1;\n            ULONG DefaultBig:1;\n            ULONG Granularity:1;\n            ULONG BaseHigh:8;\n        } Bits;\n    };\n    ULONG BaseUpper;\n    ULONG MustBeZero;\n} KGDTENTRY, *PKGDTENTRY;\n\n/* Interrupt Descriptor Table (IDT) entry union definition */\ntypedef struct _KIDTENTRY\n{\n    USHORT OffsetLow;\n    USHORT Selector;\n    union\n    {\n        struct\n        {\n            USHORT IstIndex:3;\n            USHORT Reserved0:5;\n            USHORT Type:5;\n            USHORT Dpl:2;\n            USHORT Present:1;\n        };\n        USHORT Access;\n    };\n    USHORT OffsetMiddle;\n    ULONG OffsetHigh;\n    ULONG Reserved1;\n} KIDTENTRY, *PKIDTENTRY;\n\n/* Task State Segment (TSS) structure definition */\ntypedef struct _KTSS\n{\n    ULONG Reserved0;\n    ULONG64 Rsp0;\n    ULONG64 Rsp1;\n    ULONG64 Rsp2;\n    ULONG64 Ist[8];\n    ULONG64 Reserved1;\n    USHORT Reserved2;\n    USHORT IoMapBase;\n} PACKED KTSS, *PKTSS;\n\n/* Exception frame definition */\ntypedef struct _KEXCEPTION_FRAME\n{\n    ULONG64 P1Home;\n    ULONG64 P2Home;\n    ULONG64 P3Home;\n    ULONG64 P4Home;\n    ULONG64 P5;\n    ULONG64 InitialStack;\n    M128 Xmm6;\n    M128 Xmm7;\n    M128 Xmm8;\n    M128 Xmm9;\n    M128 Xmm10;\n    M128 Xmm11;\n    M128 Xmm12;\n    M128 Xmm13;\n    M128 Xmm14;\n    M128 Xmm15;\n    ULONG64 TrapFrame;\n    ULONG64 CallbackStack;\n    ULONG64 OutputBuffer;\n    ULONG64 OutputLength;\n    UCHAR ExceptionRecord[EXCEPTION_AREA_SIZE];\n    ULONG64 MxCsr;\n    ULONG64 Rbp;\n    ULONG64 Rbx;\n    ULONG64 Rdi;\n    ULONG64 Rsi;\n    ULONG64 R12;\n    ULONG64 R13;\n    ULONG64 R14;\n    ULONG64 R15;\n    ULONG64 Return;\n} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;\n\n/* Thread start frame definition */\ntypedef struct _KSTART_FRAME\n{\n    ULONG64 P1Home;\n    ULONG64 P2Home;\n    ULONG64 P3Home;\n    ULONG64 P4Home;\n    ULONG64 Reserved;\n    ULONG64 Return;\n} KSTART_FRAME, *PKSTART_FRAME;\n\n/* Switch frame definition */\ntypedef struct _KSWITCH_FRAME\n{\n    ULONG64 P1Home;\n    ULONG64 P2Home;\n    ULONG64 P3Home;\n    ULONG64 P4Home;\n    ULONG64 P5Home;\n    ULONG MxCsr;\n    KRUNLEVEL ApcBypass;\n    UCHAR Reserved[3];\n    ULONG64 Rbp;\n    ULONG64 Return;\n} KSWITCH_FRAME, *PKSWITCH_FRAME;\n\n/* Trap frame definition */\ntypedef struct _KTRAP_FRAME\n{\n    M128 Xmm0;\n    M128 Xmm1;\n    M128 Xmm2;\n    M128 Xmm3;\n    M128 Xmm4;\n    M128 Xmm5;\n    M128 Xmm6;\n    M128 Xmm7;\n    M128 Xmm8;\n    M128 Xmm9;\n    M128 Xmm10;\n    M128 Xmm11;\n    M128 Xmm12;\n    M128 Xmm13;\n    M128 Xmm14;\n    M128 Xmm15;\n    ULONG MxCsr;\n    ULONG PreviousMode;\n    ULONGLONG Cr2;\n    ULONGLONG Cr3;\n    ULONGLONG Dr0;\n    ULONGLONG Dr1;\n    ULONGLONG Dr2;\n    ULONGLONG Dr3;\n    ULONGLONG Dr6;\n    ULONGLONG Dr7;\n    USHORT SegDs;\n    USHORT SegEs;\n    USHORT SegFs;\n    USHORT SegGs;\n    ULONGLONG Rax;\n    ULONGLONG Rbx;\n    ULONGLONG Rcx;\n    ULONGLONG Rdx;\n    ULONGLONG R8;\n    ULONGLONG R9;\n    ULONGLONG R10;\n    ULONGLONG R11;\n    ULONGLONG R12;\n    ULONGLONG R13;\n    ULONGLONG R14;\n    ULONGLONG R15;\n    ULONGLONG Rsi;\n    ULONGLONG Rdi;\n    ULONGLONG Rbp;\n    ULONGLONG Vector;\n    union {\n        ULONGLONG ErrorCode;\n        ULONGLONG ExceptionFrame;\n    };\n    ULONGLONG Rip;\n    ULONGLONG SegCs;\n    ULONGLONG Flags;\n    ULONGLONG Rsp;\n    ULONGLONG SegSs;\n} KTRAP_FRAME, *PKTRAP_FRAME;\n\n/* Thread initialization frame definition */\ntypedef struct _KTHREAD_INIT_FRAME\n{\n    KSWITCH_FRAME SwitchFrame;\n    KSTART_FRAME StartFrame;\n    KEXCEPTION_FRAME ExceptionFrame;\n    KTRAP_FRAME TrapFrame;\n    FLOATING_SAVE_AREA NpxFrame;\n} KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME;\n\n/* Special kernel registers structure definition */\ntypedef struct _KSPECIAL_REGISTERS\n{\n    ULONG64 Cr0;\n    ULONG64 Cr2;\n    ULONG64 Cr3;\n    ULONG64 Cr4;\n    ULONG64 KernelDr0;\n    ULONG64 KernelDr1;\n    ULONG64 KernelDr2;\n    ULONG64 KernelDr3;\n    ULONG64 KernelDr6;\n    ULONG64 KernelDr7;\n    KDESCRIPTOR Gdtr;\n    KDESCRIPTOR Idtr;\n    USHORT Tr;\n    USHORT Ldtr;\n    ULONG MxCsr;\n    ULONG64 DebugControl;\n    ULONG64 LastBranchToRip;\n    ULONG64 LastBranchFromRip;\n    ULONG64 LastExceptionToRip;\n    ULONG64 LastExceptionFromRip;\n    ULONG64 Cr8;\n    ULONG64 MsrGsBase;\n    ULONG64 MsrGsSwap;\n    ULONG64 MsrStar;\n    ULONG64 MsrLStar;\n    ULONG64 MsrCStar;\n    ULONG64 MsrSyscallMask;\n} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;\n\n/* Processor start block structure definition */\ntypedef struct _PROCESSOR_START_BLOCK\n{\n    ULONG_PTR Cr3;\n    ULONG_PTR Cr4;\n    PVOID EntryPoint;\n    PVOID ProcessorStructures;\n    PVOID Stack;\n    BOOLEAN Started;\n} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;\n\n/* Processor state frame structure definition */\ntypedef struct _KPROCESSOR_STATE\n{\n    CONTEXT ContextFrame;\n    KSPECIAL_REGISTERS SpecialRegisters;\n} KPROCESSOR_STATE, *PKPROCESSOR_STATE;\n\n/* Processor Control Block (PRCB) structure definition */\ntypedef struct _KPROCESSOR_CONTROL_BLOCK\n{\n    ULONG MxCsr;\n    UCHAR CpuNumber;\n    PKTHREAD CurrentThread;\n    PKTHREAD IdleThread;\n    PKTHREAD NextThread;\n    ULONG64 RspBase;\n    ULONG_PTR SetMember;\n    CPU_IDENTIFICATION CpuId;\n    KPROCESSOR_STATE ProcessorState;\n    KSPIN_LOCK_QUEUE LockQueue[MaximumLock];\n    KDPC_DATA DpcData[2];\n    PVOID DpcStack;\n    VOLATILE BOOLEAN DpcRoutineActive;\n    VOLATILE ULONG_PTR TimerRequest;\n    ULONG_PTR MultiThreadProcessorSet;\n    SINGLE_LIST_ENTRY DeferredReadyListHead;\n    PROCESSOR_POWER_STATE PowerState;\n    ULONG ProfilingCountdown;\n} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;\n\n/* Processor Block structure definition */\ntypedef struct _KPROCESSOR_BLOCK\n{\n    union\n    {\n        THREAD_INFORMATION_BLOCK ThreadInformationBlock;\n        struct\n        {\n            PKGDTENTRY GdtBase;\n            PKTSS TssBase;\n            PKPROCESSOR_BLOCK Self;\n            PKPROCESSOR_CONTROL_BLOCK CurrentPrcb;\n        };\n    };\n    PKIDTENTRY IdtBase;\n    KRUNLEVEL RunLevel;\n    KPROCESSOR_CONTROL_BLOCK Prcb;\n    ULONG Irr;\n    ULONG IrrActive;\n    ULONG Idr;\n    ULONG ContextSwitches;\n    KAFFINITY SetMember;\n    ULONG StallScaleFactor;\n    UCHAR CpuNumber;\n    ULONG HardwareId;\n    VOLATILE BOOLEAN Started;\n    PINTERRUPT_HANDLER InterruptDispatchTable[256];\n} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;\n\n/* Thread Environment Block (TEB) structure definition */\ntypedef struct _THREAD_ENVIRONMENT_BLOCK\n{\n    THREAD_INFORMATION_BLOCK InformationBlock;\n} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_AMD64_KETYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/amd64/mmtypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/amd64/mmtypes.h\n * DESCRIPTION:     Memory management data structures for AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_AMD64_MMTYPES_H\n#define __XTDK_AMD64_MMTYPES_H\n\n#include <xtbase.h>\n#include <mmtypes.h>\n\n\n/* Pages related definitions */\n#define MM_PAGE_MASK                               (MM_PAGE_SIZE - 1)\n#define MM_PAGE_SHIFT                              12L\n#define MM_PAGE_SIZE                               4096\n\n/* Page directory and page base addresses for 4-level paging */\n#define MM_PTE_BASE                                0xFFFFF68000000000ULL\n#define MM_PDE_BASE                                0xFFFFF6FB40000000ULL\n#define MM_PPE_BASE                                0xFFFFF6FB7DA00000ULL\n#define MM_PXE_BASE                                0xFFFFF6FB7DBED000ULL\n\n/* Page directory and page base addresses for 5-level paging */\n#define MM_PTE_LA57_BASE                           0xFFED000000000000ULL\n#define MM_PDE_LA57_BASE                           0xFFEDF68000000000ULL\n#define MM_PPE_LA57_BASE                           0xFFEDF6FB40000000ULL\n#define MM_PXE_LA57_BASE                           0xFFEDF6FB7DA00000ULL\n#define MM_P5E_LA57_BASE                           0xFFEDF6FB7DBED000ULL\n\n/* PTE shift values */\n#define MM_PTE_SHIFT                               3\n#define MM_PTI_SHIFT                               12\n#define MM_PDI_SHIFT                               21\n#define MM_PPI_SHIFT                               30\n#define MM_PXI_SHIFT                               39\n#define MM_P5I_SHIFT                               48\n\n/* PTE state flags */\n#define MM_PTE_VALID                               0x0000000000000001ULL\n#define MM_PTE_ACCESSED                            0x0000000000000020ULL\n#define MM_PTE_DIRTY                               0x0000000000000040ULL\n\n/* PTE scope flags */\n#define MM_PTE_LARGE_PAGE                          0x0000000000000080ULL\n#define MM_PTE_GLOBAL                              0x0000000000000100ULL\n\n/* PTE access flags */\n#define MM_PTE_NOACCESS                            0x0000000000000000ULL\n#define MM_PTE_READONLY                            0x0000000000000000ULL\n#define MM_PTE_EXECUTE                             0x0000000000000000ULL\n#define MM_PTE_EXECUTE_READ                        0x0000000000000000ULL\n#define MM_PTE_READWRITE                           0x8000000000000002ULL\n#define MM_PTE_WRITECOPY                           0x8000000000000200ULL\n#define MM_PTE_EXECUTE_READWRITE                   0x0000000000000002ULL\n#define MM_PTE_EXECUTE_WRITECOPY                   0x0000000000000200ULL\n\n/* PTE protection flags */\n#define MM_PTE_NOEXECUTE                           0x8000000000000000ULL\n#define MM_PTE_GUARDED                             0x8000000000000018ULL\n#define MM_PTE_PROTECT                             0x8000000000000612ULL\n\n/* PTE cache flags */\n#define MM_PTE_CACHE_ENABLE                        0x0000000000000000ULL\n#define MM_PTE_CACHE_DISABLE                       0x0000000000000010ULL\n#define MM_PTE_CACHE_WRITECOMBINED                 0x0000000000000010ULL\n#define MM_PTE_CACHE_WRITETHROUGH                  0x0000000000000008ULL\n\n/* PTE software flags */\n#define MM_PTE_COPY_ON_WRITE                       0x0000000000000200ULL\n#define MM_PTE_PROTOTYPE                           0x0000000000000400ULL\n#define MM_PTE_TRANSITION                          0x0000000000000800ULL\n\n/* PTE frame bits */\n#define MM_PTE_FRAME_BITS                          57\n\n/* PTE protection bits */\n#define MM_PTE_PROTECTION_BITS                     5\n\n/* Base address of the system page table */\n#define MM_SYSTEM_PTE_BASE                         KSEG0_BASE\n\n/* Minimum number of physical pages needed by the system */\n#define MM_MINIMUM_PHYSICAL_PAGES                  2048\n\n/* Number of system PTEs */\n#define MM_DEFAULT_NUMBER_SYSTEM_PTES              22000\n\n/* Default number of secondary colors */\n#define MM_DEFAULT_SECONDARY_COLORS                64\n\n/* Number of HAL allocation descriptors */\n#define MM_HARDWARE_ALLOCATION_DESCRIPTORS         64\n\n/* Kernel HAL heap initial start address */\n#define MM_HARDWARE_HEAP_START_ADDRESS             ((PVOID)(((ULONG_PTR)MM_HARDWARE_VA_START) + 1024 * 1024))\n\n/* HAL memory pool virtual address start */\n#define MM_HARDWARE_VA_START                       0xFFFFFFFFFFC00000ULL\n\n/* Kernel shared data address */\n#define MM_KERNEL_SHARED_DATA_ADDRESS              0xFFFFFFFFFFDF0000ULL\n\n/* Maximum physical address used by HAL allocations */\n#define MM_MAXIMUM_PHYSICAL_ADDRESS                0x00000000FFFFFFFFULL\n\n/* Highest system address */\n#define MM_HIGHEST_SYSTEM_ADDRESS                  0xFFFFFFFFFFFFFFFFULL\n\n/* Trampoline code address */\n#define MM_TRAMPOLINE_ADDRESS                      0x80000\n\n/* Pool block size */\n#define MM_POOL_BLOCK_SIZE                         16\n\n/* Number of pool lists per page */\n#define MM_POOL_LISTS_PER_PAGE                     (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)\n\n/* Number of pool tracking tables */\n#define MM_POOL_TRACKING_TABLES                    64\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Page size enumeration list */\ntypedef enum _PAGE_SIZE\n{\n    Size4K,\n    Size2M,\n    Size1G\n} PAGE_SIZE, *PPAGE_SIZE;\n\n/* Page Table Entry structure definition */\ntypedef struct _HARDWARE_PTE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Writable:1;\n    ULONGLONG Owner:1;\n    ULONGLONG WriteThrough:1;\n    ULONGLONG CacheDisable:1;\n    ULONGLONG Accessed:1;\n    ULONGLONG Dirty:1;\n    ULONGLONG LargePage:1;\n    ULONGLONG Global:1;\n    ULONGLONG CopyOnWrite:1;\n    ULONGLONG Prototype:1;\n    ULONGLONG Reserved1:1;\n    ULONGLONG PageFrameNumber:36;\n    ULONGLONG Reserved2:4;\n    ULONGLONG SoftwareWsIndex:11;\n    ULONGLONG NoExecute:1;\n} HARDWARE_PTE, *PHARDWARE_PTE;\n\n/* Page map information structure definition */\ntypedef struct _MMPAGEMAP_INFO\n{\n    BOOLEAN Xpa;\n    ULONGLONG PteBase;\n    ULONGLONG PdeBase;\n    ULONGLONG PpeBase;\n    ULONGLONG PxeBase;\n    ULONGLONG P5eBase;\n    ULONG VaBits;\n} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;\n\n/* A Page Table Entry on AMD64 system */\ntypedef struct _MMPTE_HARDWARE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Writable:1;\n    ULONGLONG Owner:1;\n    ULONGLONG WriteThrough:1;\n    ULONGLONG CacheDisable:1;\n    ULONGLONG Accessed:1;\n    ULONGLONG Dirty:1;\n    ULONGLONG LargePage:1;\n    ULONGLONG Global:1;\n    ULONGLONG CopyOnWrite:1;\n    ULONGLONG Prototype:1;\n    ULONGLONG Write:1;\n    ULONGLONG PageFrameNumber:36;\n    ULONGLONG Reserved1:2;\n    ULONGLONG SoftwareWsIndex:11;\n    ULONGLONG NoExecute:1;\n} MMPTE_HARDWARE, *PMMPTE_HARDWARE;\n\n/* A Page Table Entry on AMD64 system with large pages */\ntypedef struct _MMPTE_HARDWARE_LARGEPAGE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Write:1;\n    ULONGLONG Owner:1;\n    ULONGLONG WriteThrough:1;\n    ULONGLONG CacheDisable:1;\n    ULONGLONG Accessed:1;\n    ULONGLONG Dirty:1;\n    ULONGLONG LargePage:1;\n    ULONGLONG Global:1;\n    ULONGLONG CopyOnWrite:1;\n    ULONGLONG Prototype:1;\n    ULONGLONG Reserved1:1;\n    ULONGLONG PAT:1;\n    ULONGLONG Reserved2:8;\n    ULONGLONG PageFrameNumber:19;\n    ULONGLONG Reserved3:24;\n} MMPTE_HARDWARE_LARGEPAGE, *PMMPTE_HARDWARE_LARGEPAGE;\n\n/* Page Table Entry list structure definition */\ntypedef struct _MMPTE_LIST\n{\n    ULONGLONG Valid:1;\n    ULONGLONG OneEntry:1;\n    ULONGLONG Reserved1:3;\n    ULONGLONG Protection:5;\n    ULONGLONG Prototype:1;\n    ULONGLONG Transition:1;\n    ULONGLONG Reserved2:20;\n    ULONGLONG NextEntry:32;\n} MMPTE_LIST, *PMMPTE_LIST;\n\n/* Page Table Entry prototype structure definition */\ntypedef struct _MMPTE_PROTOTYPE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Reserved1:7;\n    ULONGLONG ReadOnly:1;\n    ULONGLONG Reserved2:1;\n    ULONGLONG Prototype:1;\n    ULONGLONG Protection:5;\n    LONGLONG ProtoAddress:48;\n} MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE;\n\n/* Software Page Table Entry structure definition */\ntypedef struct _MMPTE_SOFTWARE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG PageFileLow:4;\n    ULONGLONG Protection:5;\n    ULONGLONG Prototype:1;\n    ULONGLONG Transition:1;\n    ULONGLONG UsedPageTableEntries:10;\n    ULONGLONG Reserved:10;\n    ULONGLONG PageFileHigh:32;\n} MMPTE_SOFTWARE, *PMMPTE_SOFTWARE;\n\n/* Page Table Entry subsection structure definition */\ntypedef struct _MMPTE_SUBSECTION\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Reserved1:4;\n    ULONGLONG Protection:5;\n    ULONGLONG Prototype:1;\n    ULONGLONG Reserved2:5;\n    LONGLONG SubsectionAddress:48;\n} MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;\n\n/* Page Table Entry transition structure definition */\ntypedef struct _MMPTE_TRANSITION\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Write:1;\n    ULONGLONG Owner:1;\n    ULONGLONG WriteThrough:1;\n    ULONGLONG CacheDisable:1;\n    ULONGLONG Protection:5;\n    ULONGLONG Prototype:1;\n    ULONGLONG Transition:1;\n    ULONGLONG PageFrameNumber:36;\n    ULONGLONG Unused:16;\n} MMPTE_TRANSITION, *PMMPTE_TRANSITION;\n\n/* Page Table Entry structure definition */\ntypedef union _MMPTE\n{\n    ULONGLONG Long;\n    HARDWARE_PTE Flush;\n    MMPTE_HARDWARE Hardware;\n    MMPTE_PROTOTYPE Prototype;\n    MMPTE_SOFTWARE Software;\n    MMPTE_TRANSITION Transition;\n    MMPTE_SUBSECTION Subsection;\n    MMPTE_LIST List;\n} MMPTE, *PMMPTE;\n\n/* Page Frame Number structure definition */\ntypedef struct _MMPFN\n{\n    union\n    {\n        PFN_NUMBER Flink;\n        ULONG WsIndex;\n        PKEVENT Event;\n        XTSTATUS ReadStatus;\n        SINGLE_LIST_ENTRY NextStackPfn;\n    } u1;\n    PMMPTE PteAddress;\n    union\n    {\n        PFN_NUMBER Blink;\n        ULONG_PTR ShareCount;\n    } u2;\n    union\n    {\n        MMPFNENTRY e1;\n        struct\n        {\n            USHORT ShortFlags;\n            USHORT ReferenceCount;\n        } e2;\n    } u3;\n    ULONG UsedPageTableEntries;\n    union\n    {\n        MMPTE OriginalPte;\n        LONG AweReferenceCount;\n    };\n    union\n    {\n        ULONG_PTR EntireFrame;\n        struct\n        {\n            ULONG_PTR PteFrame:57;\n            ULONG_PTR InPageError:1;\n            ULONG_PTR VerifierAllocation:1;\n            ULONG_PTR AweAllocation:1;\n            ULONG_PTR Priority:3;\n            ULONG_PTR MustBeCached:1;\n        };\n    } u4;\n} MMPFN, *PMMPFN;\n\n/* Pool descriptor structure definition */\ntypedef struct _POOL_DESCRIPTOR\n{\n    LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];\n    PVOID LockAddress;\n    ULONG PoolIndex;\n    LONG PendingFreeDepth;\n    PVOID PendingFrees;\n    MMPOOL_TYPE PoolType;\n    ULONG RunningFrees;\n    ULONG RunningAllocations;\n    ULONG Threshold;\n    ULONG TotalPages;\n    ULONG TotalBigAllocations;\n    SIZE_T TotalBytes;\n    SIZE_T Reserved;\n} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_AMD64_MMTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/amd64/xtstruct.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/amd64/xtstruct.h\n * DESCRIPTION:     XT structures forward references specific to AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_AMD64_XTSTRUCT_H\n#define __XTDK_AMD64_XTSTRUCT_H\n\n#include <xtdefs.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Architecture-specific enumeration lists forward references */\ntypedef enum _APIC_DEST_MODE APIC_DEST_MODE, *PAPIC_DEST_MODE;\ntypedef enum _APIC_DM APIC_DM, *PAPIC_DM;\ntypedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;\ntypedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;\ntypedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;\ntypedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;\ntypedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;\ntypedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;\ntypedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;\ntypedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;\ntypedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;\ntypedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;\ntypedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;\ntypedef enum _CPUID_REQUESTS CPUID_REQUESTS, *PCPUID_REQUESTS;\ntypedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE;\ntypedef enum _PIC_I8259_ICW1_INTERRUPT_MODE PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;\ntypedef enum _PIC_I8259_ICW1_INTERVAL PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;\ntypedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_MODE;\ntypedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;\ntypedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;\ntypedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;\ntypedef enum _TIMER_TYPE TIMER_TYPE, *PTIMER_TYPE;\ntypedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;\n\n/* Architecture-specific structures forward references */\ntypedef struct _CONTEXT CONTEXT, *PCONTEXT;\ntypedef struct _CPU_IDENTIFICATION CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;\ntypedef struct _CPUID_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS;\ntypedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;\ntypedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;\ntypedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;\ntypedef struct _HPET_REGISTERS HPET_REGISTERS, *PHPET_REGISTERS;\ntypedef struct _IOAPIC_DATA IOAPIC_DATA, *PIOAPIC_DATA;\ntypedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;\ntypedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;\ntypedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;\ntypedef struct _KIDTENTRY KIDTENTRY, *PKIDTENTRY;\ntypedef struct _KPROCESSOR_BLOCK KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;\ntypedef struct _KPROCESSOR_CONTROL_BLOCK KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;\ntypedef struct _KPROCESSOR_STATE KPROCESSOR_STATE, *PKPROCESSOR_STATE;\ntypedef struct _KSPECIAL_REGISTERS KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;\ntypedef struct _KSTART_FRAME KSTART_FRAME, *PKSTART_FRAME;\ntypedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME;\ntypedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME;\ntypedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME;\ntypedef struct _KTSS KTSS, *PKTSS;\ntypedef struct _MMPAGEMAP_INFO MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;\ntypedef struct _MMPFN MMPFN, *PMMPFN;\ntypedef struct _MMPTE_HARDWARE MMPTE_HARDWARE, *PMMPTE_HARDWARE;\ntypedef struct _MMPTE_HARDWARE_LARGEPAGE MMPTE_HARDWARE_LARGEPAGE, *PMMPTE_HARDWARE_LARGEPAGE;\ntypedef struct _MMPTE_LIST MMPTE_LIST, *PMMPTE_LIST;\ntypedef struct _MMPTE_PROTOTYPE MMPTE_PROTOTYPE, *PMMPTE_PROTOTYPE;\ntypedef struct _MMPTE_SOFTWARE MMPTE_SOFTWARE, *PMMPTE_SOFTWARE;\ntypedef struct _MMPTE_SUBSECTION MMPTE_SUBSECTION, *PMMPTE_SUBSECTION;\ntypedef struct _MMPTE_TRANSITION MMPTE_TRANSITION, *PMMPTE_TRANSITION;\ntypedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;\ntypedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;\ntypedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;\n\n/* Unions forward references */\ntypedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;\ntypedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;\ntypedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;\ntypedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;\ntypedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;\ntypedef union _MMPTE MMP5E, *PMMP5E;\ntypedef union _MMPTE MMPDE, *PMMPDE;\ntypedef union _MMPTE MMPPE, *PMMPPE;\ntypedef union _MMPTE MMPTE, *PMMPTE;\ntypedef union _MMPTE MMPXE, *PMMPXE;\ntypedef union _PIC_I8259_ICW1 PIC_I8259_ICW1, *PPIC_I8259_ICW1;\ntypedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;\ntypedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;\ntypedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_AMD64_XTSTRUCT_H */\n"
  },
  {
    "path": "sdk/xtdk/blfuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/blfuncs.h\n * DESCRIPTION:     XT Boot Manager routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_BLFUNCS_H\n#define __XTDK_BLFUNCS_H\n\n#include <xttypes.h>\n#include <xtuefi.h>\n\n\n/* C/C++ specific code */\n#ifndef D__XTOS_ASSEMBLER__\n\n/* XT BootLoader routines forward references */\nXTCLINK\nXTCDECL\nEFI_STATUS\nBlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,\n                   IN EFI_HANDLE ImageHandle,\n                   OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_BLFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/bltarget.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/bltarget.h\n * DESCRIPTION:     XT Boot Loader target architecture specific definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_BLTARGET_H\n#define __XTDK_BLTARGET_H\n\n#include <xttypes.h>\n\n\n/* Boot Loader module information macros */\n#define MODULE_AUTHOR(_author)                                      XTBL_MODULE_DATA(author, author, _author)\n#define MODULE_DEPENDENCY(_softdeps)                                XTBL_MODULE_DATA(softdeps, softdeps, _softdeps)\n#define MODULE_DESCRIPTION(_description)                            XTBL_MODULE_DATA(description, description, _description)\n#define MODULE_LICENSE(_license)                                    XTBL_MODULE_DATA(license, license, _license)\n#define MODULE_VERSION(_version)                                    XTBL_MODULE_DATA(version, version, _version)\n\n/* Boot Loader module information segment macro */\n#define XTBL_MODULE_DATA(Tag, Name, Data)                           STATIC CONST WCHAR UNIQUE(Name)[] \\\n                                                                    USED SEGMENT(\".modinfo\") ALIGN(1) \\\n                                                                    = STRINGIFY(Tag) \"=\" Data\n\n/* XTLDR directories */\n#define XTBL_LOADER_DIRECTORY_PATH                                  L\"\\\\EFI\\\\BOOT\\\\XTLDR\\\\\"\n#define XTBL_MODULES_DIRECTORY_PATH                                 L\"\\\\EFI\\\\BOOT\\\\XTLDR\\\\MODULES\\\\\"\n#define XTBL_THEMES_DIRECTORY_PATH                                  L\"\\\\EFI\\\\BOOT\\\\XTLDR\\\\THEMES\\\\\"\n\n/* Architecture specific definitions */\n#if defined(__i386__) || defined(__i686__)\n    #define XTBL_ARCH_LOADER_DIRECTORY_PATH                         L\"\\\\EFI\\\\BOOT\\\\XTLDR32\\\\\"\n    #define XTBL_ARCH_MODULES_DIRECTORY_PATH                        L\"\\\\EFI\\\\BOOT\\\\XTLDR32\\\\MODULES\\\\\"\n    #define XTBL_ARCH_THEMES_DIRECTORY_PATH                         L\"\\\\EFI\\\\BOOT\\\\XTLDR32\\\\THEMES\\\\\"\n#elif defined(__amd64__) || defined(__x86_64__)\n    #define XTBL_ARCH_LOADER_DIRECTORY_PATH                         L\"\\\\EFI\\\\BOOT\\\\XTLDR64\\\\\"\n    #define XTBL_ARCH_MODULES_DIRECTORY_PATH                        L\"\\\\EFI\\\\BOOT\\\\XTLDR64\\\\MODULES\\\\\"\n    #define XTBL_ARCH_THEMES_DIRECTORY_PATH                         L\"\\\\EFI\\\\BOOT\\\\XTLDR64\\\\THEMES\\\\\"\n#else\n    #error Unknown architecture\n#endif\n\n#endif /* __XTDK_BLTARGET_H */\n"
  },
  {
    "path": "sdk/xtdk/bltypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/bltypes.h\n * DESCRIPTION:     XT Boot Loader structures definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTDK_BLTYPES_H\n#define __XTDK_BLTYPES_H\n\n#include <xttypes.h>\n#include <xtstruct.h>\n#include <xtuefi.h>\n#include <hltypes.h>\n#include ARCH_HEADER(xtstruct.h)\n\n\n/* EFI XT boot devices */\n#define XTBL_BOOT_DEVICE_UNKNOWN                                    0x00\n#define XTBL_BOOT_DEVICE_ESP                                        0x01\n#define XTBL_BOOT_DEVICE_CDROM                                      0x02\n#define XTBL_BOOT_DEVICE_FLOPPY                                     0x04\n#define XTBL_BOOT_DEVICE_HARDDISK                                   0x08\n#define XTBL_BOOT_DEVICE_RAMDISK                                    0x10\n\n/* XTLDR Debug Port type definitions */\n#define XTBL_DEBUGPORT_SCREEN                                       1\n#define XTBL_DEBUGPORT_SERIAL                                       2\n\n/* XTLDR Shell definitions */\n#define XTBL_SH_MAX_LINE_LENGTH                                     256\n#define XTBL_SH_HISTORY_ENTRIES                                     20\n\n/* TUI dialog box attributes */\n#define XTBL_TUI_DIALOG_GENERIC_BOX                                 1\n#define XTBL_TUI_DIALOG_ERROR_BOX                                   2\n#define XTBL_TUI_DIALOG_ACTIVE_BUTTON                               4\n#define XTBL_TUI_DIALOG_INACTIVE_BUTTON                             8\n#define XTBL_TUI_DIALOG_ACTIVE_INPUT                                16\n#define XTBL_TUI_DIALOG_INACTIVE_INPUT                              32\n#define XTBL_TUI_DIALOG_PROGRESS_BAR                                64\n\n/* TUI dialog box maximum width */\n#define XTBL_TUI_MAX_DIALOG_WIDTH                                   100\n\n\n/* C/C++ specific code */\n#ifndef D__XTOS_ASSEMBLER__\n\n/* XTLDR Routine pointers */\ntypedef LOADER_MEMORY_TYPE (XTCDECL *PBL_GET_MEMTYPE_ROUTINE)(IN EFI_MEMORY_TYPE EfiMemoryType);\n\n/* Boot Loader protocol routine pointers */\ntypedef EFI_STATUS (XTCDECL *PBL_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE AllocationType, IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory);\ntypedef EFI_STATUS (XTCDECL *PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory);\ntypedef EFI_STATUS (XTCDECL *PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLength, OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId);\ntypedef BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);\ntypedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);\ntypedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);\ntypedef EFI_STATUS (XTCDECL *PBL_COMMIT_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap);\ntypedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);\ntypedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);\ntypedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers);\ntypedef ULONG_PTR (XTCDECL *PBL_CPU_READ_CONTROL_REGISTER)(IN USHORT ControlRegister);\ntypedef ULONGLONG (XTCDECL *PBL_CPU_READ_MODEL_SPECIFIC_REGISTER)(IN ULONG Register);\ntypedef VOID (XTCDECL *PBL_CPU_WRITE_CONTROL_REGISTER)(IN USHORT ControlRegister, IN UINT_PTR Value);\ntypedef EFI_STATUS (XTCDECL *PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid);\ntypedef BOOLEAN (XTCDECL *PBL_CONFIG_GET_BOOLEAN_VALUE)(IN PCWSTR ConfigName);\ntypedef EFI_STATUS (XTCDECL *PBL_CONFIG_GET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN PCWSTR OptionName, OUT PWCHAR *OptionValue);\ntypedef VOID (XTCDECL *PBL_CONFIG_GET_EDITABLE_OPTIONS)(OUT PCWSTR **OptionsArray, OUT PULONG OptionsCount);\ntypedef EFI_STATUS (XTCDECL *PBL_CONFIG_GET_VALUE)(IN PCWSTR ConfigName, OUT PWCHAR *ConfigValue);\ntypedef EFI_STATUS (XTCDECL *PBL_CONFIG_SET_BOOT_OPTION_VALUE)(IN PLIST_ENTRY Options, IN PCWSTR OptionName, IN PCWSTR OptionValue);\ntypedef VOID (XTCDECL *PBL_CONSOLE_CLEAR_SCREEN)();\ntypedef VOID (XTCDECL *PBL_CONSOLE_DISABLE_CURSOR)();\ntypedef VOID (XTCDECL *PBL_CONSOLE_ENABLE_CURSOR)();\ntypedef VOID (XTCDECL *PBL_CONSOLE_PRINT)(IN PCWSTR Format, IN ...);\ntypedef VOID (XTCDECL *PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);\ntypedef EFI_STATUS (XTCDECL *PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);\ntypedef VOID (XTCDECL *PBL_CONSOLE_RESET_INPUT_BUFFER)();\ntypedef VOID (XTCDECL *PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes);\ntypedef VOID (XTCDECL *PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY);\ntypedef VOID (XTCDECL *PBL_CONSOLE_WRITE)(IN PCWSTR String);\ntypedef SIZE_T (XTAPI *PBL_COMPARE_MEMORY)(IN PCVOID LeftBuffer, IN PCVOID RightBuffer, IN SIZE_T Length);\ntypedef SIZE_T (XTAPI *PBL_WIDESTRING_COMPARE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length);\ntypedef VOID (XTAPI *PBL_COPY_MEMORY)(OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);\ntypedef VOID (XTCDECL *PBL_DEBUG_PRINT)(IN PCWSTR Format, IN ...);\ntypedef EFI_STATUS (XTCDECL *PBL_ENTER_FIRMWARE_SETUP)();\ntypedef EFI_STATUS (XTCDECL *PBL_EXIT_BOOT_SERVICES)();\ntypedef EFI_STATUS (XTCDECL *PBL_FIND_BOOT_PROTOCOL)(IN PCWSTR SystemType, OUT PEFI_GUID BootProtocolGuid);\ntypedef EFI_STATUS (XTCDECL *PBL_FREE_PAGES)(IN ULONGLONG Size, IN EFI_PHYSICAL_ADDRESS Memory);\ntypedef EFI_STATUS (XTCDECL *PBL_FREE_POOL)(IN PVOID Memory);\ntypedef EFI_STATUS (XTCDECL *PBL_GET_CONFIGURATION_TABLE)(IN PEFI_GUID TableGuid, OUT PVOID *Table);\ntypedef EFI_STATUS (XTCDECL *PBL_GET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PCWSTR VariableName, OUT PVOID *VariableValue);\ntypedef VOID (XTCDECL *PBL_GET_MAPPINGS_COUNT)(IN PXTBL_PAGE_MAPPING PageMap, OUT PULONG NumberOfMappings);\ntypedef EFI_STATUS (XTCDECL *PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap);\ntypedef PLIST_ENTRY (XTCDECL *PBL_GET_MODULES_LIST)();\ntypedef ULONGLONG (XTCDECL *PBL_GET_RANDOM_VALUE)(IN OUT PULONGLONG RNGBuffer);\ntypedef INT_PTR (XTCDECL *PBL_GET_SECURE_BOOT_STATUS)();\ntypedef PVOID (XTCDECL *PBL_GET_VIRTUAL_ADDRESS)(IN PXTBL_PAGE_MAPPING PageMap, IN PVOID PhysicalAddress);\ntypedef EFI_STATUS (XTCDECL *PBL_INITIALIZE_ENTROPY)(PULONGLONG RNGBuffer);\ntypedef VOID (XTCDECL *PBL_INITIALIZE_PAGE_MAP)(OUT PXTBL_PAGE_MAPPING PageMap, IN SHORT PageMapLevel, IN PAGE_SIZE PageSize);\ntypedef EFI_STATUS (XTCDECL *PBL_INSTALL_XT_PROTOCOL)(IN PVOID Interface, IN PEFI_GUID Guid);\ntypedef EFI_STATUS (XTCDECL *PBL_INVOKE_BOOT_PROTOCOL)(IN PWCHAR ShortName, IN PLIST_ENTRY OptionsList);\ntypedef EFI_STATUS (XTCDECL *PBL_LOCATE_PROTOCOL_HANDLES)(OUT PEFI_HANDLE *Handles, OUT PUINT_PTR Count, IN PEFI_GUID ProtocolGuid);\ntypedef EFI_STATUS (XTCDECL *PBL_LOAD_EFI_IMAGE)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN PVOID ImageData, IN SIZE_T ImageSize, OUT PEFI_HANDLE ImageHandle);\ntypedef VOID (XTCDECL *PBL_LLIST_INITIALIZE_HEAD)(IN PLIST_ENTRY ListHead);\ntypedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);\ntypedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);\ntypedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry);\ntypedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *BaseAddress, IN BOOLEAN IdentityMapping, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);\ntypedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages);\ntypedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);\ntypedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);\ntypedef EFI_STATUS (XTCDECL *PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);\ntypedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);\ntypedef EFI_STATUS (XTCDECL *PBL_OPEN_PROTOCOL_HANDLE)(IN EFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);\ntypedef PVOID (XTCDECL *PBL_PHYSICAL_ADDRESS_TO_VIRTUAL)(IN PVOID PhysicalAddress, IN PVOID PhysicalBase, IN PVOID VirtualBase);\ntypedef UCHAR (XTCDECL *PBL_IOPORT_READ_8)(IN USHORT Port);\ntypedef USHORT (XTCDECL *PBL_IOPORT_READ_16)(IN USHORT Port);\ntypedef ULONG (XTCDECL *PBL_IOPORT_READ_32)(IN USHORT Port);\ntypedef VOID (XTCDECL *PBL_IOPORT_WRITE_8)(IN USHORT Port, IN UCHAR Value);\ntypedef VOID (XTCDECL *PBL_IOPORT_WRITE_16)(IN USHORT Port, IN USHORT Value);\ntypedef VOID (XTCDECL *PBL_IOPORT_WRITE_32)(IN USHORT Port, IN ULONG Value);\ntypedef EFI_STATUS (XTCDECL *PBL_PHYSICAL_LIST_TO_VIRTUAL)(IN PXTBL_PAGE_MAPPING PageMap, IN OUT PLIST_ENTRY ListHead, IN PVOID PhysicalBase, IN PVOID VirtualBase);\ntypedef EFI_STATUS (XTCDECL *PBL_POWER_SYSTEM)();\ntypedef EFI_STATUS (XTCDECL *PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN PCWSTR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize);\ntypedef EFI_STATUS (XTCDECL *PBL_REGISTER_BOOT_PROTOCOL)(IN PCWSTR SystemType, IN PEFI_GUID BootProtocolGuid);\ntypedef VOID (XTCDECL *PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine);\ntypedef EFI_STATUS (XTCDECL *PBL_SET_EFI_VARIABLE)(IN PEFI_GUID Vendor, IN PCWSTR VariableName, IN PVOID VariableValue, IN UINT_PTR Size);\ntypedef SIZE_T (XTAPI *PBL_STRING_COMPARE)(IN PCSTR String1, IN PCSTR String2, IN SIZE_T Length);\ntypedef SIZE_T (XTAPI *PBL_STRING_LENGTH)(IN PCSTR String, IN SIZE_T MaxLength);\ntypedef SIZE_T (XTAPI *PBL_STRING_TO_WIDESTRING)(OUT PWCHAR Destination, IN PCSTR *Source, IN SIZE_T Length);\ntypedef PCHAR (XTAPI *PBL_STRING_TRIM)(IN PCHAR String);\ntypedef VOID (XTAPI *PBL_SET_MEMORY)(OUT PVOID Destination, IN UCHAR Byte, IN SIZE_T Length);\ntypedef VOID (XTCDECL *PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds);\ntypedef EFI_STATUS (XTCDECL *PBL_START_EFI_IMAGE)(IN EFI_HANDLE ImageHandle);\ntypedef VOID (XTCDECL *PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message);\ntypedef VOID (XTCDECL *PBL_TUI_DISPLAY_INFO_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message);\ntypedef VOID (XTCDECL *PBL_TUI_DISPLAY_INPUT_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message, IN OUT PWCHAR *InputFieldText);\ntypedef XTBL_DIALOG_HANDLE (XTCDECL *PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PCWSTR Caption, IN PCWSTR Message, IN UCHAR Percentage);\ntypedef VOID (XTCDECL *PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PCWSTR Message, IN UCHAR Percentage);\ntypedef SIZE_T (XTAPI *PBL_WIDESTRING_COMPARE_INSENSITIVE)(IN PCWSTR String1, IN PCWSTR String2, IN SIZE_T Length);\ntypedef PWCHAR (XTAPI *PBL_WIDESTRING_CONCATENATE)(OUT PWCHAR Destination, IN PWCHAR Source, IN SIZE_T Count);\ntypedef XTSTATUS (XTAPI *PBL_WIDESTRING_FORMAT)(IN PRTL_PRINT_CONTEXT Context, IN PCWSTR Format, IN VA_LIST ArgumentList);\ntypedef SIZE_T (XTAPI *PBL_WIDESTRING_LENGTH)(IN PCWSTR String, IN SIZE_T MaxLength);\ntypedef PWCHAR (XTAPI *PBL_WIDESTRING_TOKENIZE)(IN PWCHAR String, IN PCWSTR Delimiter, IN OUT PWCHAR *SavePtr);\ntypedef EFI_STATUS (XTCDECL *PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index);\ntypedef VOID (XTCDECL *PBL_SHELL_COMMAND)(IN ULONG Argc, IN PWCHAR *Argv);\ntypedef EFI_STATUS (XTCDECL *PBL_REGISTER_SHELL_COMMAND)(IN PCWSTR Command, IN PCWSTR Description, IN PBL_SHELL_COMMAND Handler);\ntypedef VOID (XTCDECL *PBL_XT_BOOT_MENU)();\ntypedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length);\n\n/* Module protocols routine pointers */\ntypedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER)(OUT PVOID *AcpiTable);\ntypedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_ACPI_TABLE)(IN CONST UINT Signature, IN PVOID PreviousTable, OUT PVOID *AcpiTable);\ntypedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_APIC_BASE)(OUT PVOID *ApicBase);\ntypedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_RSDP_TABLE)(OUT PVOID *AcpiTable);\ntypedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_SMBIOS_TABLE)(OUT PVOID *SmBiosTable);\ntypedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_SMBIOS3_TABLE)(OUT PVOID *SmBiosTable);\ntypedef EFI_STATUS (XTCDECL *PBL_ACPI_GET_XSDP_TABLE)(OUT PVOID *AcpiTable);\ntypedef EFI_STATUS (XTCDECL *PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_ENTRY_POINT)(IN PVOID ImagePointer, OUT PVOID *EntryPoint);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_FILE_SIZE)(IN PVOID ImagePointer, OUT PULONGLONG FileSize);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_IMAGE_SIZE)(IN PVOID ImagePointer, OUT PUINT ImageSize);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_MACHINE_TYPE)(IN PVOID ImagePointer, OUT PUSHORT MachineType);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_SECTION)(IN PVOID ImagePointer, IN PCHAR SectionName, OUT PULONG *RawData);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_SUBSYSTEM)(IN PVOID ImagePointer, OUT PUSHORT SubSystem);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_GET_VERSION)(IN PVOID ImagePointer, OUT PUSHORT Version);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_LOAD_IMAGE)(IN PEFI_FILE_HANDLE FileHandle, IN LOADER_MEMORY_TYPE MemoryType, IN PVOID VirtualAddress, OUT PVOID *ImagePointer);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_RELOCATE_IMAGE)(IN PVOID ImagePointer, IN EFI_VIRTUAL_ADDRESS Address);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_UNLOAD_IMAGE)(IN PVOID ImagePointer);\ntypedef EFI_STATUS (XTCDECL *PBL_EXECIMAGE_VERIFY_IMAGE)(IN PVOID ImagePointer);\ntypedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PEFI_GRAPHICS_PROTOCOL Protocol);\ntypedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PEFI_PHYSICAL_ADDRESS FrameBufferBase, OUT PULONG_PTR FrameBufferSize, OUT PXTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo);\ntypedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_GET_PREFERRED_SCREEN_RESOLUTION)(OUT PUINT PreferredWidth, OUT PUINT PreferredHeight);\ntypedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_INITIALIZE)();\ntypedef EFI_STATUS (XTCDECL *PBL_FRAMEBUFFER_SET_SCREEN_RESOLUTION)(IN UINT Width, IN UINT Height);\n\n/* Boot parameters structure */\ntypedef struct _XTBL_BOOT_PARAMETERS\n{\n    PEFI_DEVICE_PATH_PROTOCOL DevicePath;\n    PWCHAR ArcName;\n    PWCHAR EfiPath;\n    PWCHAR SystemPath;\n    PWCHAR SystemType;\n    PWCHAR KernelFile;\n    PWCHAR InitrdFile;\n    PWCHAR HalFile;\n    PWCHAR Parameters;\n} XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS;\n\n/* Boot menu list structure */\ntypedef struct _XTBL_BOOTMENU_ITEM\n{\n    PWCHAR EntryName;\n    PWCHAR FullName;\n    PWCHAR ShortName;\n    PLIST_ENTRY Options;\n} XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM;\n\n/* XTLDR Configuration data */\ntypedef struct _XTBL_CONFIG_ENTRY\n{\n    LIST_ENTRY Flink;\n    PWCHAR Name;\n    PWCHAR Value;\n} XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY;\n\n/* XTLDR Configuration section */\ntypedef struct _XTBL_CONFIG_SECTION\n{\n    LIST_ENTRY Flink;\n    LIST_ENTRY Options;\n    PWCHAR SectionName;\n} XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION;\n\n/* XTLDR Dialog handle data */\ntypedef struct _XTBL_DIALOG_HANDLE\n{\n    UCHAR Attributes;\n    UCHAR DialogColor;\n    UCHAR TextColor;\n    UINT_PTR ResX;\n    UINT_PTR ResY;\n    UINT_PTR PosX;\n    UINT_PTR PosY;\n    UINT_PTR Width;\n    UINT_PTR Height;\n} XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE;\n\n/* Registered boot protocol structure */\ntypedef struct _XTBL_KNOWN_BOOT_PROTOCOL\n{\n    LIST_ENTRY Flink;\n    PWCHAR SystemType;\n    EFI_GUID Guid;\n} XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;\n\n/* XTLDR Shell command entry */\ntypedef struct _XTBL_SHELL_COMMAND\n{\n    LIST_ENTRY Flink;\n    PWCHAR Command;\n    PWCHAR Description;\n    PBL_SHELL_COMMAND Handler;\n} XTBL_SHELL_COMMAND, *PXTBL_SHELL_COMMAND;\n\n/* Boot Loader memory mapping information */\ntypedef struct _XTBL_MEMORY_MAPPING\n{\n    LIST_ENTRY ListEntry;\n    ULONGLONG VirtualAddress;\n    ULONGLONG PhysicalAddress;\n    ULONGLONG NumberOfPages;\n    LOADER_MEMORY_TYPE MemoryType;\n} XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;\n\n/* XTLDR Module dependencies data */\ntypedef struct _XTBL_MODULE_AUTHORS\n{\n    LIST_ENTRY Flink;\n    PWCHAR AuthorName;\n} XTBL_MODULE_AUTHORS, *PXTBL_MODULE_AUTHORS;\n\n/* XTLDR Module dependencies data */\ntypedef struct _XTBL_MODULE_DEPS\n{\n    LIST_ENTRY Flink;\n    PWCHAR ModuleName;\n} XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS;\n\n/* XTLDR Module information data */\ntypedef struct _XTBL_MODULE_INFO\n{\n    LIST_ENTRY Flink;\n    PWCHAR ModuleName;\n    PWCHAR ModuleDescription;\n    PWCHAR License;\n    PWCHAR Version;\n    LIST_ENTRY Authors;\n    LIST_ENTRY Dependencies;\n    PVOID ModuleBase;\n    ULONGLONG ModuleSize;\n    UINT Revision;\n    PEFI_IMAGE_UNLOAD UnloadModule;\n} XTBL_MODULE_INFO, *PXTBL_MODULE_INFO;\n\n/* Boot Loader page mapping information */\ntypedef struct _XTBL_PAGE_MAPPING\n{\n    LIST_ENTRY MemoryMap;\n    ULONG MapSize;\n    PVOID PtePointer;\n    SHORT PageMapLevel;\n    PAGE_SIZE PageSize;\n} XTBL_PAGE_MAPPING, *PXTBL_PAGE_MAPPING;\n\n/* XTLDR Status data */\ntypedef struct _XTBL_STATUS\n{\n    PVOID LoaderBase;\n    ULONGLONG LoaderSize;\n    BOOLEAN BootServices;\n    INT_PTR SecureBoot;\n} XTBL_STATUS, *PXTBL_STATUS;\n\n/* XT framebuffer video mode information structure definition */\ntypedef struct _XTBL_FRAMEBUFFER_MODE_INFORMATION\n{\n    UINT Width;\n    UINT Height;\n    UINT Depth;\n    UINT RefreshRate;\n    UINT BitsPerPixel;\n    UINT BytesPerPixel;\n    UINT PixelsPerScanLine;\n    UINT Pitch;\n    EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;\n    struct\n    {\n        USHORT BlueShift;\n        USHORT BlueSize;\n        USHORT GreenShift;\n        USHORT GreenSize;\n        USHORT RedShift;\n        USHORT RedSize;\n        USHORT ReservedShift;\n        USHORT ReservedSize;\n    } PixelInformation;\n} XTBL_FRAMEBUFFER_MODE_INFORMATION, *PXTBL_FRAMEBUFFER_MODE_INFORMATION;\n\n/* XT framebuffer information structure definition */\ntypedef struct _XTBL_FRAMEBUFFER_INFORMATION\n{\n    BOOLEAN Initialized;\n    EFI_GRAPHICS_PROTOCOL Protocol;\n    EFI_PHYSICAL_ADDRESS FrameBufferBase;\n    ULONG_PTR FrameBufferSize;\n    UINT DefaultMode;\n    EFI_HANDLE Handle;\n    union\n    {\n        PEFI_GRAPHICS_OUTPUT_PROTOCOL Gop;\n        PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL Uga;\n    } Driver;\n    XTBL_FRAMEBUFFER_MODE_INFORMATION ModeInfo;\n} XTBL_FRAMEBUFFER_INFORMATION, *PXTBL_FRAMEBUFFER_INFORMATION;\n\n/* XTLDR ACPI protocol structure */\ntypedef struct _XTBL_ACPI_PROTOCOL\n{\n    PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER GetAcpiDescriptionPointer;\n    PBL_ACPI_GET_ACPI_TABLE GetAcpiTable;\n    PBL_ACPI_GET_APIC_BASE GetApicBase;\n    PBL_ACPI_GET_RSDP_TABLE GetRsdpTable;\n    PBL_ACPI_GET_SMBIOS_TABLE GetSMBiosTable;\n    PBL_ACPI_GET_SMBIOS3_TABLE GetSMBios3Table;\n    PBL_ACPI_GET_XSDP_TABLE GetXsdpTable;\n} XTBL_ACPI_PROTOCOL, *PXTBL_ACPI_PROTOCOL;\n\n/* XTLDR Boot protocol structure */\ntypedef struct _XTBL_BOOT_PROTOCOL\n{\n    PBL_BOOTPROTO_BOOT_SYSTEM BootSystem;\n} XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL;\n\n/* XTLDR Executable image protocol structure */\ntypedef struct _XTBL_EXECUTABLE_IMAGE_PROTOCOL\n{\n    PBL_EXECIMAGE_GET_ENTRY_POINT GetEntryPoint;\n    PBL_EXECIMAGE_GET_FILE_SIZE GetFileSize;\n    PBL_EXECIMAGE_GET_IMAGE_SIZE GetImageSize;\n    PBL_EXECIMAGE_GET_MACHINE_TYPE GetMachineType;\n    PBL_EXECIMAGE_GET_SECTION GetSection;\n    PBL_EXECIMAGE_GET_SUBSYSTEM GetSubSystem;\n    PBL_EXECIMAGE_GET_VERSION GetVersion;\n    PBL_EXECIMAGE_LOAD_IMAGE LoadImage;\n    PBL_EXECIMAGE_RELOCATE_IMAGE RelocateImage;\n    PBL_EXECIMAGE_UNLOAD_IMAGE UnloadImage;\n    PBL_EXECIMAGE_VERIFY_IMAGE VerifyImage;\n} XTBL_EXECUTABLE_IMAGE_PROTOCOL, *PXTBL_EXECUTABLE_IMAGE_PROTOCOL;\n\n/* XT framebuffer support protocol structure */\ntypedef struct _XTBL_FRAMEBUFFER_PROTOCOL\n{\n    PBL_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver;\n    PBL_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation;\n    PBL_FRAMEBUFFER_GET_PREFERRED_SCREEN_RESOLUTION GetPreferredScreenResolution;\n    PBL_FRAMEBUFFER_INITIALIZE Initialize;\n    PBL_FRAMEBUFFER_SET_SCREEN_RESOLUTION SetScreenResolution;\n} XTBL_FRAMEBUFFER_PROTOCOL, *PXTBL_FRAMEBUFFER_PROTOCOL;\n\n/* XTLDR Loader protocol structure */\ntypedef struct _XTBL_LOADER_PROTOCOL\n{\n    struct\n    {\n        PBL_FIND_BOOT_PROTOCOL FindProtocol;\n        PBL_BOOTMENU_INITIALIZE_OS_LIST InitializeMenuList;\n        PBL_INVOKE_BOOT_PROTOCOL InvokeProtocol;\n        PBL_REGISTER_XT_BOOT_MENU RegisterMenu;\n        PBL_REGISTER_BOOT_PROTOCOL RegisterProtocol;\n    } Boot;\n    struct\n    {\n        PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER GetBooleanParameter;\n        PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION GetTrampolineInformation;\n    } BootUtils;\n    struct\n    {\n        PBL_CONFIG_GET_BOOLEAN_VALUE GetBooleanValue;\n        PBL_CONFIG_GET_BOOT_OPTION_VALUE GetBootOptionValue;\n        PBL_CONFIG_GET_EDITABLE_OPTIONS GetEditableOptions;\n        PBL_CONFIG_GET_VALUE GetValue;\n        PBL_CONFIG_SET_BOOT_OPTION_VALUE SetBootOptionValue;\n    } Config;\n    struct\n    {\n        PBL_CLEAR_CONSOLE_LINE ClearLine;\n        PBL_CONSOLE_CLEAR_SCREEN ClearScreen;\n        PBL_CONSOLE_DISABLE_CURSOR DisableCursor;\n        PBL_CONSOLE_ENABLE_CURSOR EnableCursor;\n        PBL_CONSOLE_PRINT Print;\n        PBL_CONSOLE_QUERY_MODE QueryMode;\n        PBL_CONSOLE_READ_KEY_STROKE ReadKeyStroke;\n        PBL_CONSOLE_RESET_INPUT_BUFFER ResetInputBuffer;\n        PBL_CONSOLE_SET_ATTRIBUTES SetAttributes;\n        PBL_CONSOLE_SET_CURSOR_POSITION SetCursorPosition;\n        PBL_CONSOLE_WRITE Write;\n    } Console;\n    struct\n    {\n        PBL_CPU_CPUID CpuId;\n        PBL_CPU_READ_CONTROL_REGISTER ReadControlRegister;\n        PBL_CPU_READ_MODEL_SPECIFIC_REGISTER ReadModelSpecificRegister;\n        PBL_CPU_WRITE_CONTROL_REGISTER WriteControlRegister;\n    } Cpu;\n    struct\n    {\n        PBL_DEBUG_PRINT Print;\n    } Debug;\n    struct\n    {\n        PBL_CLOSE_VOLUME CloseVolume;\n        PBL_OPEN_VOLUME OpenVolume;\n        PBL_READ_FILE ReadFile;\n    } Disk;\n    struct\n    {\n        PBL_IOPORT_READ_8 Read8;\n        PBL_IOPORT_READ_16 Read16;\n        PBL_IOPORT_READ_32 Read32;\n        PBL_IOPORT_WRITE_8 Write8;\n        PBL_IOPORT_WRITE_16 Write16;\n        PBL_IOPORT_WRITE_32 Write32;\n    } IoPort;\n    struct\n    {\n        PBL_LLIST_INITIALIZE_HEAD InitializeHead;\n        PBL_LLIST_INSERT_HEAD InsertHead;\n        PBL_LLIST_INSERT_TAIL InsertTail;\n        PBL_LLIST_REMOVE_ENTRY RemoveEntry;\n    } LinkedList;\n    struct\n    {\n        PBL_ALLOCATE_PAGES AllocatePages;\n        PBL_ALLOCATE_POOL AllocatePool;\n        PBL_BUILD_PAGE_MAP BuildPageMap;\n        PBL_COMMIT_PAGE_MAP CommitPageMap;\n        PBL_COMPARE_MEMORY CompareMemory;\n        PBL_COPY_MEMORY CopyMemory;\n        PBL_FREE_PAGES FreePages;\n        PBL_FREE_POOL FreePool;\n        PBL_GET_MAPPINGS_COUNT GetMappingsCount;\n        PBL_GET_MEMORY_MAP GetMemoryMap;\n        PBL_GET_VIRTUAL_ADDRESS GetVirtualAddress;\n        PBL_INITIALIZE_PAGE_MAP InitializePageMap;\n        PBL_MAP_EFI_MEMORY MapEfiMemory;\n        PBL_MAP_PAGE MapPage;\n        PBL_MAP_VIRTUAL_MEMORY MapVirtualMemory;\n        PBL_MOVE_MEMORY MoveMemory;\n        PBL_PHYSICAL_ADDRESS_TO_VIRTUAL PhysicalAddressToVirtual;\n        PBL_PHYSICAL_LIST_TO_VIRTUAL PhysicalListToVirtual;\n        PBL_SET_MEMORY SetMemory;\n        PBL_ZERO_MEMORY ZeroMemory;\n    } Memory;\n    struct\n    {\n        PBL_CLOSE_XT_PROTOCOL Close;\n        PBL_GET_MODULES_LIST GetModulesList;\n        PBL_INSTALL_XT_PROTOCOL Install;\n        PBL_LOCATE_PROTOCOL_HANDLES LocateHandles;\n        PBL_OPEN_PROTOCOL Open;\n        PBL_OPEN_PROTOCOL_HANDLE OpenHandle;\n    } Protocol;\n    struct\n    {\n        PBL_REGISTER_SHELL_COMMAND RegisterCommand;\n    } Shell;\n    struct\n    {\n        PBL_STRING_COMPARE Compare;\n        PBL_STRING_LENGTH Length;\n        PBL_STRING_TO_WIDESTRING ToWideString;\n        PBL_STRING_TRIM Trim;\n    } String;\n    struct\n    {\n        PBL_TUI_DISPLAY_ERROR_DIALOG DisplayErrorDialog;\n        PBL_TUI_DISPLAY_INFO_DIALOG DisplayInfoDialog;\n        PBL_TUI_DISPLAY_INPUT_DIALOG DisplayInputDialog;\n        PBL_TUI_DISPLAY_PROGRESS_DIALOG DisplayProgressDialog;\n        PBL_TUI_UPDATE_PROGRESS_BAR UpdateProgressBar;\n    } Tui;\n    struct\n    {\n        PBL_ENTER_FIRMWARE_SETUP EnterFirmwareSetup;\n        PBL_EXIT_BOOT_SERVICES ExitBootServices;\n        PBL_GET_CONFIGURATION_TABLE GetConfigurationTable;\n        PBL_GET_EFI_VARIABLE GetEfiVariable;\n        PBL_GET_RANDOM_VALUE GetRandomValue;\n        PBL_GET_SECURE_BOOT_STATUS GetSecureBootStatus;\n        PBL_INITIALIZE_ENTROPY InitializeEntropy;\n        PBL_LOAD_EFI_IMAGE LoadEfiImage;\n        PBL_POWER_SYSTEM RebootSystem;\n        PBL_SET_EFI_VARIABLE SetEfiVariable;\n        PBL_POWER_SYSTEM ShutdownSystem;\n        PBL_SLEEP_EXECUTION SleepExecution;\n        PBL_START_EFI_IMAGE StartEfiImage;\n        PBL_WAIT_FOR_EFI_EVENT WaitForEfiEvent;\n    } Utils;\n    struct\n    {\n        PBL_WIDESTRING_COMPARE Compare;\n        PBL_WIDESTRING_COMPARE_INSENSITIVE CompareInsensitive;\n        PBL_WIDESTRING_CONCATENATE Concatenate;\n        PBL_WIDESTRING_FORMAT Format;\n        PBL_WIDESTRING_LENGTH Length;\n        PBL_WIDESTRING_TOKENIZE Tokenize;\n    } WideString;\n} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_BLTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/exfuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/exfuncs.h\n * DESCRIPTION:     Kernel executive routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_EXFUNCS_H\n#define __XTDK_EXFUNCS_H\n\n#include <xtbase.h>\n#include <xttypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Kernel Executive routines forward references */\nXTCLINK\nXTFASTCALL\nBOOLEAN\nExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n\nXTCLINK\nXTFASTCALL\nVOID\nExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n\nXTCLINK\nXTFASTCALL\nVOID\nExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n\nXTCLINK\nXTFASTCALL\nVOID\nExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n\nXTCLINK\nXTFASTCALL\nVOID\nExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n\nXTCLINK\nXTFASTCALL\nVOID\nExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_EXFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/extypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/extypes.h\n * DESCRIPTION:     Kernel executive structures definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_EXTYPES_H\n#define __XTDK_EXTYPES_H\n\n#include <xtbase.h>\n#include <xttypes.h>\n#include <ketypes.h>\n\n\n/* Rundown protection flags */\n#define EX_RUNDOWN_ACTIVE                               0x1\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Executive rundown protection structure definition */\ntypedef struct _EX_RUNDOWN_REFERENCE\n{\n    union\n    {\n        ULONG_PTR Count;\n        PVOID Ptr;\n    };\n} EX_RUNDOWN_REFERENCE, *PEX_RUNDOWN_REFERENCE;\n\n/* Executive rundown wait block definition */\ntypedef struct _EX_RUNDOWN_WAIT_BLOCK\n{\n    ULONG_PTR Count;\n    KEVENT WakeEvent;\n} EX_RUNDOWN_WAIT_BLOCK, *PEX_RUNDOWN_WAIT_BLOCK;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_EXTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/hlfuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/hlfuncs.h\n * DESCRIPTION:     XT hardware abstraction layer routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_HLFUNCS_H\n#define __XTDK_HLFUNCS_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Hardware layer routines forward references */\nXTCLINK\nXTAPI\nLARGE_INTEGER\nHlQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency);\n\nXTCLINK\nXTAPI\nUCHAR\nHlReadRegister8(IN PVOID Register);\n\nXTCLINK\nXTAPI\nUSHORT\nHlReadRegister16(IN PVOID Register);\n\nXTCLINK\nXTAPI\nULONG\nHlReadRegister32(IN PVOID Register);\n\nXTCLINK\nXTAPI\nULONG\nHlSetClockRate(IN ULONG Rate);\n\nXTCLINK\nXTAPI\nVOID\nHlWriteRegister8(IN PVOID Register,\n                 IN UCHAR Value);\n\nXTCLINK\nXTAPI\nVOID\nHlWriteRegister16(IN PVOID Register,\n                  IN USHORT Value);\n\nXTCLINK\nXTAPI\nVOID\nHlWriteRegister32(IN PVOID Register,\n                  IN ULONG Value);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_HLFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/hltypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/hltypes.h\n * DESCRIPTION:     XT hardware abstraction layer structures definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_HLTYPES_H\n#define __XTDK_HLTYPES_H\n\n#include <xtbase.h>\n#include <xtdefs.h>\n#include <xttypes.h>\n#include ARCH_HEADER(hltypes.h)\n\n\n/* ACPI Root System Description Pointer (RSDP) signature */\n#define ACPI_RSDP_SIGNATURE                         0x2052545020445352\n\n/* ACPI table signatures */\n#define ACPI_BERT_SIGNATURE                         0x54524542 /* Boot Error Record Table */\n#define ACPI_BGRT_SIGNATURE                         0x54524742 /* Boot Graphics Record Table */\n#define ACPI_BOOT_SIGNATURE                         0x544F4F42 /* ACPI BOOT Table */\n#define ACPI_CPEP_SIGNATURE                         0x50455043 /* Corrected Platform Error Polling Table */\n#define ACPI_DBG2_SIGNATURE                         0x32474244 /* Debug Port Table v2 */\n#define ACPI_DBGP_SIGNATURE                         0x50474244 /* Debug Port Table */\n#define ACPI_DMAR_SIGNATURE                         0x52414D44 /* DMA Remapping Table */\n#define ACPI_DSDT_SIGNATURE                         0x54445344 /* Differentiated System Description Table */\n#define ACPI_ECDT_SIGNATURE                         0x54444345 /* Embedded Controller Description Table */\n#define ACPI_ERST_SIGNATURE                         0x54535245 /* Error Record Serialization Table */\n#define ACPI_FACS_SIGNATURE                         0x53434146 /* Firmware ACPI Control Structure */\n#define ACPI_FADT_SIGNATURE                         0x50434146 /* Fixed ACPI Description Table */\n#define ACPI_FBPT_SIGNATURE                         0x54504246 /* Firmware Boot Performance Table */\n#define ACPI_FPDT_SIGNATURE                         0x54445046 /* Firmware Performance Data Table */\n#define ACPI_GTDT_SIGNATURE                         0x54445447 /* Generic Timer Description Table */\n#define ACPI_HPET_SIGNATURE                         0x54455048 /* High Precision Event Timer */\n#define ACPI_IVRS_SIGNATURE                         0x53525649 /* AMD IOMMU Resource Table */\n#define ACPI_MADT_SIGNATURE                         0x43495041 /* MADT/APIC Description Table */\n#define ACPI_MCFG_SIGNATURE                         0x4746434D /* Memory Mapped Configuration Space Access Table */\n#define ACPI_MPST_SIGNATURE                         0x5453504D /* Memory Power State Table*/\n#define ACPI_MSCT_SIGNATURE                         0x5443534D /* Maximum System Characteristics Table */\n#define ACPI_NFIT_SIGNATURE                         0x5449464E /* NVDIMM Firmware Interface Table */\n#define ACPI_PMMT_SIGNATURE                         0x544D4D50 /* Platform Memory Topology Table */\n#define ACPI_PSDT_SIGNATURE                         0x54445350 /* Persistent System Description Table */\n#define ACPI_RAS2_SIGNATURE                         0x32534152 /* ACPI RAS2 Feature Table */\n#define ACPI_RASF_SIGNATURE                         0x46534152 /* ACPI RAS Feature Table */\n#define ACPI_RSDT_SIGNATURE                         0x54445352 /* Root System Description Table */\n#define ACPI_SBST_SIGNATURE                         0x54534253 /* Smart Battery Subsystem Table */\n#define ACPI_SDEV_SIGNATURE                         0x56454453 /* Secure Device Table */\n#define ACPI_SLIT_SIGNATURE                         0x54494C53 /* System Locality Distance Information Table */\n#define ACPI_SPCR_SIGNATURE                         0x52435053 /* Serial Port Console Redirection Table */\n#define ACPI_SRAT_SIGNATURE                         0x54415253 /* Static Resource Affinity Table */\n#define ACPI_SSDT_SIGNATURE                         0x54445353 /* Secondary System Descriptor Table */\n#define ACPI_TPM2_SIGNATURE                         0x324D5054 /* ACPI TPM 2.0 Table */\n#define ACPI_WAET_SIGNATURE                         0x54454157 /* Windows ACPI Enlightenment Table */\n#define ACPI_WDAT_SIGNATURE                         0x54414457 /* Watch Dog Action Table */\n#define ACPI_WDTT_SIGNATURE                         0x54524457 /* Watchdog Timer Resource Table */\n#define ACPI_WPBT_SIGNATURE                         0x54425057 /* Windows Platform Binary Table */\n#define ACPI_WSMT_SIGNATURE                         0x544D5357 /* Windows SMM Security Mitigation Table */\n#define ACPI_XSDT_SIGNATURE                         0x54445358 /* eXtended System Descriptor Table */\n\n/* ACPI FADT flags masks */\n#define ACPI_FADT_32BIT_TIMER                       (1<<8)\n\n/* ACPI Timer bit masks */\n#define ACPI_FADT_TIMER_32BIT                       0xFFFFFFFF\n#define ACPI_FADT_TIMER_24BIT                       0x00FFFFFF\n\n/* ACPI MADT subtable type definitions */\n#define ACPI_MADT_TYPE_LOCAL_APIC                   0\n#define ACPI_MADT_TYPE_IOAPIC                       1\n#define ACPI_MADT_TYPE_INT_OVERRIDE                 2\n#define ACPI_MADT_TYPE_NMI_SOURCE                   3\n#define ACPI_MADT_TYPE_LOCAL_APIC_NMI               4\n#define ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE          5\n#define ACPI_MADT_TYPE_IO_SAPIC                     6\n#define ACPI_MADT_TYPE_LOCAL_SAPIC                  7\n#define ACPI_MADT_TYPE_INTERRUPT_SOURCE             8\n#define ACPI_MADT_TYPE_LOCAL_X2APIC                 9\n#define ACPI_MADT_TYPE_LOCAL_X2APIC_NMI             10\n#define ACPI_MADT_TYPE_GENERIC_INTERRUPT            11\n#define ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR          12\n#define ACPI_MADT_TYPE_GENERIC_MSI_FRAME            13\n#define ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR        14\n#define ACPI_MADT_TYPE_GENERIC_TRANSLATOR           15\n#define ACPI_MADT_TYPE_MULTIPROC_WAKEUP             16\n#define ACPI_MADT_TYPE_CORE_PIC                     17\n#define ACPI_MADT_TYPE_LIO_PIC                      18\n#define ACPI_MADT_TYPE_HT_PIC                       19\n#define ACPI_MADT_TYPE_EIO_PIC                      20\n#define ACPI_MADT_TYPE_MSI_PIC                      21\n#define ACPI_MADT_TYPE_BIO_PIC                      22\n#define ACPI_MADT_TYPE_LPC_PIC                      23\n#define ACPI_MADT_TYPE_RINTC                        24\n#define ACPI_MADT_TYPE_IMSIC                        25\n#define ACPI_MADT_TYPE_APLIC                        26\n#define ACPI_MADT_TYPE_PLIC                         27\n\n/* ACPI MADT Processor Local APIC Flags */\n#define ACPI_MADT_PLACE_ENABLED                     0 /* Processor Local APIC CPU Enabled */\n#define ACPI_MADT_PLAOC_ENABLED                     1 /* Processor Local APIC Online Capable */\n\n/* ACPI Timer frequency */\n#define ACPI_PM_TIMER_FREQUENCY                     3579545\n\n/* ACPI address space definitions */\n#define ACPI_ADDRESS_SPACE_MEMORY                   0x00\n\n/* Maximum number of cached ACPI tables */\n#define ACPI_MAX_CACHED_TABLES                      32\n\n/* Default serial port settings */\n#define COMPORT_CLOCK_RATE                          0x1C200\n#define COMPORT_WAIT_TIMEOUT                        204800\n\n/* Serial port divisors */\n#define COMPORT_DIV_DLL                             0x00 /* Divisor Latch Least */\n#define COMPORT_DIV_DLM                             0x01 /* Divisor Latch Most */\n\n/* Serial port control flags */\n#define COMPORT_FLAG_INIT                           0x01 /* Port Initialized */\n#define COMPORT_FLAG_DBR                            0x02 /* Default Baud Rate */\n#define COMPORT_FLAG_MC                             0x04 /* Modem Control */\n\n/* Serial port Fifo Control Register (FCR) access masks */\n#define COMPORT_FCR_DISABLE                         0x00 /* Disable */\n#define COMPORT_FCR_ENABLE                          0x01 /* Enable */\n#define COMPORT_FCR_RCVR_RESET                      0x02 /* Receiver Reset */\n#define COMPORT_FCR_TXMT_RESET                      0x04 /* Transmitter Reset */\n\n/* Serial port Line Control Register (LCR) access masks */\n#define COMPORT_LCR_1STOP                           0x00 /* 1 Stop Bit */\n#define COMPORT_LCR_2STOP                           0x04 /* 2 Stop Bits */\n#define COMPORT_LCR_5DATA                           0x00 /* 5 Data Bits */\n#define COMPORT_LCR_6DATA                           0x01 /* 6 Data Bits */\n#define COMPORT_LCR_7DATA                           0x02 /* 7 Data Bits */\n#define COMPORT_LCR_8DATA                           0x03 /* 8 Data Bits */\n#define COMPORT_LCR_PARN                            0x00 /* None Parity */\n#define COMPORT_LCR_PARO                            0x08 /* Odd Parity */\n#define COMPORT_LCR_PARE                            0x18 /* Even Parity */\n#define COMPORT_LCR_PARM                            0x28 /* Mark Parity */\n#define COMPORT_LCR_PARS                            0x38 /* Space Parity */\n#define COMPORT_LCR_BREAK                           0x40 /* Break */\n#define COMPORT_LCR_DLAB                            0x80 /* Divisor Latch Access Bit */\n\n/* Serial port Line Status Register (LSR) access masks */\n#define COMPORT_LSR_DIS                             0x00 /* Disable */\n#define COMPORT_LSR_DR                              0x01 /* Data Ready */\n#define COMPORT_LSR_OE                              0x02 /* Overrun Error */\n#define COMPORT_LSR_PE                              0x04 /* Parity Error */\n#define COMPORT_LSR_FE                              0x08 /* Framing Error */\n#define COMPORT_LSR_BI                              0x10 /* Break Interrupt */\n#define COMPORT_LSR_THRE                            0x20 /* Transmit Holding Register Empty */\n#define COMPORT_LSR_TEMPTY                          0x40 /* Transmitter Empty */\n#define COMPORT_LSR_FIFOE                           0x80 /* FIFO Error */\n\n/* Serial port Modem Control Register (MCR) access masks */\n#define COMPORT_MCR_DTR                             0x01 /* Data Terminal Ready */\n#define COMPORT_MCR_RTS                             0x02 /* Ready To Send */\n#define COMPORT_MCR_OUT1                            0x04 /* Generic Output 1 */\n#define COMPORT_MCR_OUT2                            0x08 /* Generic Output 2 */\n#define COMPORT_MCR_NOM                             0x0F /* Normal Operation Mode */\n#define COMPORT_MCR_LOOP                            0x10 /* Loopback Testing Mode */\n\n/* Serial port Modem Status Register (MSR) access masks */\n#define COMPORT_MSR_DCTS                            0x01 /* Delta Clear To Send */\n#define COMPORT_MSR_DDSR                            0x02 /* Delta Data Set Ready */\n#define COMPORT_MSR_DTRRTS                          0x03 /* DTR and RTS */\n#define COMPORT_MSR_TERI                            0x04 /* Trailing Edge Ring Indicator */\n#define COMPORT_MSR_DDCD                            0x08 /* Delta Data Carrier Detect */\n#define COMPORT_MSR_CTS                             0x10 /* Clear To Send */\n#define COMPORT_MSR_DSR                             0x20 /* Data Set Ready */\n#define COMPORT_MSR_RI                              0x40 /* Ring Indicator */\n#define COMPORT_MSR_DCD                             0x80 /* Data Carrier Detect */\n#define COMPORT_MSR_DSRCTSCD                        0xB0 /* DSR, CTS and CD */\n#define COMPORT_MSR_TST                             0xAE /* Test Pattern */\n\n/* Serial port offsets of the various registers */\n#define COMPORT_REG_RBR                             0x00 /* Receive Buffer Register */\n#define COMPORT_REG_THR                             0x00 /* Transmit Holding Register */\n#define COMPORT_REG_IER                             0x01 /* Interrupt Enable Register */\n#define COMPORT_REG_IIR                             0x02 /* Interrupt Identity Register */\n#define COMPORT_REG_FCR                             0x02 /* FIFO Control Register */\n#define COMPORT_REG_LCR                             0x03 /* Line Control Register */\n#define COMPORT_REG_MCR                             0x04 /* Modem Control Register */\n#define COMPORT_REG_LSR                             0x05 /* Line Status Register */\n#define COMPORT_REG_MSR                             0x06 /* Modem Status Register */\n#define COMPORT_REG_SR                              0x07 /* Scratch Register */\n\n/* Standard system clock rates (in 100-nanosecond units)*/\n#define HL_CLOCK_RATE_1000HZ                        10000  /* 1 ms (1000 Hz) - Best Performance */\n#define HL_CLOCK_RATE_500HZ                         20000  /* 2 ms (500 Hz) - High Responsiveness */\n#define HL_CLOCK_RATE_300HZ                         33333  /* 3.33ms (300 Hz) - Multimedia Sync */\n#define HL_CLOCK_RATE_250HZ                         40000  /* 4 ms (250 Hz) - Optimal Balance */\n#define HL_CLOCK_RATE_100HZ                         100000 /* 10 ms (100 Hz) - Power Saving */\n#define HL_CLOCK_RATE_50HZ                          200000 /* 20 ms (50 Hz) - Deep Power Saving */\n\n/* Minimum and maximum system clock rate definitions */\n#define HL_MINIMUM_CLOCK_RATE                       HL_CLOCK_RATE_1000HZ\n#define HL_MAXIMUM_CLOCK_RATE                       HL_CLOCK_RATE_50HZ\n\n/* Minimum and maximum profile intervals */\n#define MIN_PROFILE_INTERVAL                        10000\n#define MAX_PROFILE_INTERVAL                        10000000\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Hardware Layer routine callbacks */\ntypedef XTSTATUS (XTAPI *PHALP_INITIALIZE_CLOCK)(VOID);\ntypedef ULONGLONG (XTAPI *PHALP_QUERY_PERF_COUNTER)(VOID);\ntypedef ULONG (XTAPI *PHALP_QUERY_TIME_DELTA)(VOID);\ntypedef ULONG (XTAPI *PHALP_SET_CLOCK_RATE)(IN ULONG Increment);\ntypedef VOID (XTAPI *PHALP_STALL_EXECUTION)(IN ULONG MicroSeconds);\n\n/* Generic Address structure */\ntypedef struct _GENERIC_ADDRESS\n{\n    UCHAR AddressSpaceID;\n    UCHAR BitWidth;\n    UCHAR BitOffset;\n    UCHAR Reserved;\n    PHYSICAL_ADDRESS Address;\n} PACKED GENERIC_ADDRESS, *PGENERIC_ADDRESS;\n\n/* Each ACPI table description header structure */\ntypedef struct _ACPI_DESCRIPTION_HEADER\n{\n    ULONG Signature;\n    ULONG Length;\n    UCHAR Revision;\n    UCHAR Checksum;\n    UCHAR OemId[6];\n    UCHAR OemTableID[8];\n    ULONG OemRevision;\n    UCHAR CreatorID[4];\n    ULONG CreatorRev;\n} PACKED ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER;\n\n/* Each ACPI subtable description header structure */\ntypedef struct _ACPI_SUBTABLE_HEADER\n{\n    UCHAR Type;\n    UCHAR Length;\n} PACKED ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;\n\n/* ACPI cache list structure */\ntypedef struct _ACPI_CACHE_LIST\n{\n    LIST_ENTRY ListEntry;\n    PACPI_DESCRIPTION_HEADER Table;\n} ACPI_CACHE_LIST, *PACPI_CACHE_LIST;\n\n/* ACPI Root System Description Table Pointer (RSDP) structure */\ntypedef struct _ACPI_RSDP\n{\n    ULONGLONG Signature;\n    UCHAR Checksum;\n    UCHAR OemId[6];\n    UCHAR Revision;\n    ULONG RsdtAddress;\n    ULONG Length;\n    ULONGLONG XsdtAddress;\n    UCHAR XChecksum;\n    UCHAR Reserved[3];\n} PACKED ACPI_RSDP, *PACPI_RSDP;\n\n/* ACPI Root System Description Table (RSDT) structure */\ntypedef struct _ACPI_RSDT\n{\n    ACPI_DESCRIPTION_HEADER Header;\n    ULONG Tables[];\n} PACKED ACPI_RSDT, *PACPI_RSDT;\n\n/* ACPI eXtended Root System Description Table (XSDT) structure */\ntypedef struct _ACPI_XSDT\n{\n    ACPI_DESCRIPTION_HEADER Header;\n    ULONGLONG Tables[];\n} PACKED ACPI_XSDT, *PACPI_XSDT;\n\n/* Fixed ACPI Description Table (FADT) structure */\ntypedef struct _ACPI_FADT\n{\n    ACPI_DESCRIPTION_HEADER Header;\n    ULONG FirmwareCtrl;\n    ULONG Dsdt;\n    UCHAR IntModel;\n    UCHAR PmProfile;\n    USHORT SciIntVector;\n    ULONG SmiCmdIoPort;\n    UCHAR AcpiOnValue;\n    UCHAR AcpiOffValue;\n    UCHAR S4BiosReq;\n    UCHAR PStateControl;\n    ULONG Pm1aEvtBlkIoPort;\n    ULONG Pm1bEvtBlkIoPort;\n    ULONG Pm1aCtrlBlkIoPort;\n    ULONG Pm1bCtrlBlkIoPort;\n    ULONG Pm2CtrlBlkIoPort;\n    ULONG PmTmrBlkIoPort;\n    ULONG Gp0BlkIoPort;\n    ULONG Gp1BlkIoPort;\n    UCHAR Pm1EvtLen;\n    UCHAR Pm1CtrlLen;\n    UCHAR Pm2CtrlLen;\n    UCHAR PmTmrLen;\n    UCHAR Gp0BlkLen;\n    UCHAR Gp1BlkLen;\n    UCHAR Gp1Base;\n    UCHAR CStateControl;\n    USHORT Lvl2Latency;\n    USHORT Lvl3Latency;\n    USHORT FlushSize;\n    USHORT FlushStride;\n    UCHAR DutyOffset;\n    UCHAR DutyWidth;\n    UCHAR DayAlarmIndex;\n    UCHAR MonthAlarmIndex;\n    UCHAR CenturyAlarmIndex;\n    USHORT BootArch;\n    UCHAR Reserved0;\n    ULONG Flags;\n    GENERIC_ADDRESS ResetReg;\n    UCHAR ResetVal;\n    USHORT ArmBootArch;\n    UCHAR Reserved1;\n    PHYSICAL_ADDRESS XFirmwareCtrl;\n    PHYSICAL_ADDRESS XDsdt;\n    GENERIC_ADDRESS XPm1aEvtBlk;\n    GENERIC_ADDRESS XPm1bEvtBlk;\n    GENERIC_ADDRESS XPm1aCtrlBlk;\n    GENERIC_ADDRESS XPm1bCtrlBlk;\n    GENERIC_ADDRESS XPm2CtrlBlk;\n    GENERIC_ADDRESS XPmTmrBlk;\n    GENERIC_ADDRESS XGp0Blk;\n    GENERIC_ADDRESS XGp1Blk;\n    GENERIC_ADDRESS SleepControlReg;\n    GENERIC_ADDRESS SleepStatusReg;\n} PACKED ACPI_FADT, *PACPI_FADT;\n\n/* ACPI High Precision Event Timer (HPET) table structure */\ntypedef struct _ACPI_HPET\n{\n    ACPI_DESCRIPTION_HEADER Header;\n    ULONG EventTimerBlockId;\n    GENERIC_ADDRESS BaseAddress;\n    UCHAR HpetNumber;\n    USHORT MinimumTick;\n    UCHAR PageProtectionAndOem;\n} PACKED ACPI_HPET, *PACPI_HPET;\n\n/* ACPI Multiple APIC Description Table (MADT) structure */\ntypedef struct _ACPI_MADT\n{\n    ACPI_DESCRIPTION_HEADER Header;\n    ULONG LocalApicAddress;\n    ULONG Flags;\n    ULONG ApicTables[];\n} PACKED ACPI_MADT, *PACPI_MADT;\n\n/* ACPI Interrupt Override MADT subtable structure */\ntypedef struct _ACPI_MADT_INTERRUPT_OVERRIDE\n{\n    ACPI_SUBTABLE_HEADER Header;\n    UCHAR Bus;\n    UCHAR SourceIrq;\n    ULONG GlobalSystemInterrupt;\n    USHORT Flags;\n} PACKED ACPI_MADT_INTERRUPT_OVERRIDE, *PACPI_MADT_INTERRUPT_OVERRIDE;\n\n/* ACPI IO APIC MADT subtable structure */\ntypedef struct _ACPI_MADT_IOAPIC\n{\n    ACPI_SUBTABLE_HEADER Header;\n    UCHAR IoApicId;\n    UCHAR Reserved;\n    ULONG IoApicAddress;\n    ULONG GlobalIrqBase;\n} PACKED ACPI_MADT_IOAPIC, *PACPI_MADT_IOAPIC;\n\n/* ACPI Local APIC MADT subtable structure */\ntypedef struct _ACPI_MADT_LOCAL_APIC\n{\n    ACPI_SUBTABLE_HEADER Header;\n    UCHAR AcpiId;\n    UCHAR ApicId;\n    ULONG Flags;\n} PACKED ACPI_MADT_LOCAL_APIC, *PACPI_MADT_LOCAL_APIC;\n\n/* ACPI Local X2APIC MADT subtable structure */\ntypedef struct _ACPI_MADT_LOCAL_X2APIC\n{\n    ACPI_SUBTABLE_HEADER Header;\n    USHORT Reserved;\n    ULONG ApicId;\n    ULONG Flags;\n    ULONG AcpiId;\n} PACKED ACPI_MADT_LOCAL_X2APIC, *PACPI_MADT_LOCAL_X2APIC;\n\n/* ACPI System Information structure */\ntypedef struct _ACPI_SYSTEM_INFO\n{\n    ULONG CpuCount;\n    ULONG RunningCpus;\n    ULONG BusCount;\n    ULONG IoApicCount;\n    ULONG IntiCount;\n    ULONG LintiCount;\n    BOOLEAN ImcrPresent;\n    ULONG ApicBase;\n    PPROCESSOR_IDENTITY CpuInfo;\n    ULONG IoApicPhysicalBase[APIC_MAX_IOAPICS];\n    ULONG IoApicVirtualBase[APIC_MAX_IOAPICS];\n    ULONG IoApicVectorBase[APIC_MAX_IOAPICS];\n} ACPI_SYSTEM_INFO, *PACPI_SYSTEM_INFO;\n\n/* ACPI Timer information structure */\ntypedef struct _ACPI_TIMER_INFO\n{\n    ULONG TimerPort;\n    ULONG MsbMask;\n} ACPI_TIMER_INFO, *PACPI_TIMER_INFO;\n\n/* Serial (COM) port state */\ntypedef struct _CPPORT\n{\n    PUCHAR Address;\n    ULONG Baud;\n    USHORT Flags;\n    UCHAR Ring;\n} CPPORT, *PCPPORT;\n\n/* Framebuffer data structure */\ntypedef struct _HL_FRAMEBUFFER_DATA\n{\n    BOOLEAN Initialized;\n    PVOID Address;\n    ULONG_PTR BufferSize;\n    UINT Width;\n    UINT Height;\n    UINT PixelsPerScanLine;\n    UINT BytesPerPixel;\n    UINT Pitch;\n    PVOID Font;\n    struct\n    {\n        USHORT BlueShift;\n        USHORT BlueSize;\n        USHORT GreenShift;\n        USHORT GreenSize;\n        USHORT RedShift;\n        USHORT RedSize;\n        USHORT ReservedShift;\n        USHORT ReservedSize;\n    } Pixels;\n} HL_FRAMEBUFFER_DATA, *PHL_FRAMEBUFFER_DATA;\n\n/* Scroll region data structure */\ntypedef struct _HL_SCROLL_REGION_DATA\n{\n    ULONG Left;\n    ULONG Top;\n    ULONG Right;\n    ULONG Bottom;\n    ULONG WidthInChars;\n    ULONG HeightInChars;\n    ULONG CursorX;\n    ULONG CursorY;\n    ULONG BackgroundColor;\n    ULONG TextColor;\n} HL_SCROLL_REGION_DATA, *PHL_SCROLL_REGION_DATA;\n\n/* Processor identity structure */\ntypedef struct _PROCESSOR_IDENTITY\n{\n    ULONG AcpiId;\n    ULONG ApicId;\n    USHORT CpuNumber;\n    BOOLEAN Bsp;\n    BOOLEAN Started;\n} PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;\n\n/* SMBIOS table header structure */\ntypedef struct _SMBIOS_TABLE_HEADER\n{\n    UCHAR Signature[4];\n    UCHAR Checksum;\n    UCHAR Length;\n    UCHAR MajorVersion;\n    UCHAR MinorVersion;\n    USHORT MaxStructureSize;\n    UCHAR EntryPointRevision;\n    UCHAR Reserved[5];\n    UCHAR Signature2[5];\n    UCHAR IntermediateChecksum;\n    USHORT TableLength;\n    ULONG TableAddress;\n    USHORT NumberOfStructures;\n    UCHAR BcdRevision;\n} SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER;\n\n/* SMBIOS3 table header structure */\ntypedef struct _SMBIOS3_TABLE_HEADER\n{\n    UCHAR Signature[5];\n    UCHAR Checksum;\n    UCHAR Length;\n    UCHAR MajorVersion;\n    UCHAR MinorVersion;\n    UCHAR DocRevision;\n    UCHAR EntryPointRevision;\n    UCHAR Reserved;\n    ULONG MaxStructureSize;\n    ULONGLONG TableAddress;\n} SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;\n\n/* Timer dispatch table */\ntypedef struct _TIMER_ROUTINES\n{\n    PHALP_INITIALIZE_CLOCK InitializeClock;\n    PHALP_QUERY_PERF_COUNTER QueryPerformanceCounter;\n    PHALP_QUERY_TIME_DELTA QueryTimeDelta;\n    PHALP_SET_CLOCK_RATE SetClockRate;\n    PHALP_STALL_EXECUTION StallExecution;\n} TIMER_ROUTINES, *PTIMER_ROUTINES;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_HLTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/i686/artypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/i686/artypes.h\n * DESCRIPTION:     I686 architecture library structure definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_I686_ARTYPES_H\n#define __XTDK_I686_ARTYPES_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include ARCH_HEADER(xtstruct.h)\n\n\n/* Control Register 0 constants */\n#define CR0_PE                                          0x00000001\n#define CR0_MP                                          0x00000002\n#define CR0_EM                                          0x00000004\n#define CR0_TS                                          0x00000008\n#define CR0_ET                                          0x00000010\n#define CR0_NE                                          0x00000020\n#define CR0_WP                                          0x00010000\n#define CR0_AM                                          0x00040000\n#define CR0_NW                                          0x20000000\n#define CR0_CD                                          0x40000000\n#define CR0_PG                                          0x80000000\n\n/* Control Register 4 constants */\n#define CR4_VME                                         0x00000001\n#define CR4_PVI                                         0x00000002\n#define CR4_TSD                                         0x00000004\n#define CR4_DE                                          0x00000008\n#define CR4_PSE                                         0x00000010\n#define CR4_PAE                                         0x00000020\n#define CR4_MCE                                         0x00000040\n#define CR4_PGE                                         0x00000080\n#define CR4_PCE                                         0x00000100\n#define CR4_FXSR                                        0x00000200\n#define CR4_XMMEXCPT                                    0x00000400\n#define CR4_UMIP                                        0x00000800\n#define CR4_LA57                                        0x00001000\n#define CR4_VMXE                                        0x00002000\n#define CR4_SMXE                                        0x00004000\n#define CR4_FSGSBASE                                    0x00010000\n#define CR4_PCIDE                                       0x00020000\n#define CR4_XSAVE                                       0x00040000\n#define CR4_KL                                          0x00080000\n#define CR4_SMEP                                        0x00100000\n#define CR4_SMAP                                        0x00200000\n#define CR4_PKE                                         0x00400000\n#define CR4_CET                                         0x00800000\n#define CR4_PKS                                         0x01000000\n#define CR4_UINTR                                       0x02000000\n#define CR4_LASS                                        0x08000000\n#define CR4_LAM_SUP                                     0x10000000\n\n/* Descriptors size */\n#define GDT_ENTRIES                                     128\n#define IDT_ENTRIES                                     256\n\n/* Initial MXCSR control */\n#define INITIAL_MXCSR                                   0x1F80\n\n/* Segment defintions */\n#define SEGMENT_CS                                      0x2E\n#define SEGMENT_DS                                      0x3E\n#define SEGMENT_ES                                      0x26\n#define SEGMENT_SS                                      0x36\n#define SEGMENT_FS                                      0x64\n#define SEGMENT_GS                                      0x65\n\n/* X86 EFLAG bit masks definitions */\n#define X86_EFLAGS_NF_MASK                              0x00000000 /* None */\n#define X86_EFLAGS_CF_MASK                              0x00000001 /* Carry */\n#define X86_EFLAGS_PF_MASK                              0x00000004 /* Parity */\n#define X86_EFALGS_AF_MASK                              0x00000010 /* Aux Carry */\n#define X86_EFLAGS_ZF_MASK                              0x00000040 /* Zero */\n#define X86_EFLAGS_SF_MASK                              0x00000080 /* Sign */\n#define X86_EFLAGS_TF_MASK                              0x00000100 /* Trap */\n#define X86_EFLAGS_IF_MASK                              0x00000200 /* Interrupt */\n#define X86_EFLAGS_DF_MASK                              0x00000400 /* Direction */\n#define X86_EFLAGS_OF_MASK                              0x00000800 /* Overflow */\n#define X86_EFLAGS_IOPL_MASK                            0x00003000 /* I/O Privilege */\n#define X86_EFLAGS_NT_MASK                              0x00004000 /* Nested Task */\n#define X86_EFLAGS_SIGN_MASK                            0x00008000 /* Sign */\n#define X86_EFLAGS_RF_MASK                              0x00010000 /* Resume */\n#define X86_EFLAGS_V86_MASK                             0x00020000 /* Virtual 8086 */\n#define X86_EFLAGS_AC_MASK                              0x00040000 /* Alignment Check */\n#define X86_EFLAGS_VIF_MASK                             0x00080000 /* Virtual Interrupt */\n#define X86_EFLAGS_VIP_MASK                             0x00100000 /* Virtual Interrupt Pending */\n#define X86_EFLAGS_ID_MASK                              0x00200000 /* Identification */\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* CPU vendor enumeration list */\ntypedef enum _CPU_VENDOR\n{\n    CPU_VENDOR_AMD = 0x68747541,\n    CPU_VENDOR_INTEL = 0x756e6547,\n    CPU_VENDOR_UNKNOWN = 0xFFFFFFFF\n} CPU_VENDOR, *PCPU_VENDOR;\n\n/* CPUID advanced power management features (0x80000007) enumeration list */\ntypedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT\n{\n    CPUID_FEATURES_EDX_TS                     = 1 << 0, /* Temperature Sensor */\n    CPUID_FEATURES_EDX_FIS                    = 1 << 1, /* Frequency ID Selection */\n    CPUID_FEATURES_EDX_VIS                    = 1 << 2, /* Voltage ID Selection */\n    CPUID_FEATURES_EDX_TTS                    = 1 << 3, /* ThermaTrip Support */\n    CPUID_FEATURES_EDX_HTC                    = 1 << 4, /* Hardware Thermal Throttling */\n    CPUID_FEATURES_EDX_STC                    = 1 << 5, /* Software Thermal Throttling */\n    CPUID_FEATURES_EDX_TSCI                   = 1 << 8 /* TSC Invariant */\n} CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;\n\n/* CPUID extended features (0x80000001) enumeration list */\ntypedef enum _CPUID_FEATURES_EXTENDED\n{\n    CPUID_FEATURES_ECX_LAHF_SAHF              = 1 << 0,\n    CPUID_FEATURES_ECX_CMP_LEGACY             = 1 << 1,\n    CPUID_FEATURES_ECX_SVM                    = 1 << 2,\n    CPUID_FEATURES_ECX_EXT_APIC_SPACE         = 1 << 3,\n    CPUID_FEATURES_ECX_ALT_MOV_CR8            = 1 << 4,\n    CPUID_FEATURES_ECX_LZCNT                  = 1 << 5,\n    CPUID_FEATURES_ECX_SSE4A                  = 1 << 6,\n    CPUID_FEATURES_ECX_MISALIGNED_SSE         = 1 << 7,\n    CPUID_FEATURES_ECX_PREFETCHW              = 1 << 8,\n    CPUID_FEATURES_ECX_OSVW                   = 1 << 9,\n    CPUID_FEATURES_ECX_IBS                    = 1 << 10,\n    CPUID_FEATURES_ECX_XOP                    = 1 << 11,\n    CPUID_FEATURES_ECX_SKINIT                 = 1 << 12,\n    CPUID_FEATURES_ECX_WDT                    = 1 << 13,\n    CPUID_FEATURES_ECX_LWP                    = 1 << 15,\n    CPUID_FEATURES_ECX_FMA4                   = 1 << 16,\n    CPUID_FEATURES_ECX_TCE                    = 1 << 17,\n    CPUID_FEATURES_ECX_NODEID                 = 1 << 19,\n    CPUID_FEATURES_ECX_TBM                    = 1 << 21,\n    CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS    = 1 << 22,\n    CPUID_FEATURES_ECX_PERFCTR_EXT_CORE       = 1 << 23,\n    CPUID_FEATURES_ECX_PERFCTR_EXT_NB         = 1 << 24,\n    CPUID_FEATURES_ECX_DATA_BREAKPOINT_EXT    = 1 << 26,\n    CPUID_FEATURES_ECX_PERF_TSC               = 1 << 27,\n    CPUID_FEATURES_ECX_PERFCTR_EXT_L2I        = 1 << 28,\n    CPUID_FEATURES_ECX_MONITORX_MWAITX        = 1 << 29,\n    CPUID_FEATURES_ECX_CODEBP_ADDRMASK_EXT    = 1 << 30,\n    CPUID_FEATURES_EDX_SYSCALL_SYSRET         = 1 << 11,\n    CPUID_FEATURES_EDX_NX                     = 1 << 20,\n    CPUID_FEATURES_EDX_AMD_MMX_EXT            = 1 << 22,\n    CPUID_FEATURES_EDX_FFXSR                  = 1 << 25,\n    CPUID_FEATURES_EDX_1G_PAGES               = 1 << 26,\n    CPUID_FEATURES_EDX_RDTSCP                 = 1 << 27,\n    CPUID_FEATURES_EDX_LONG_MODE              = 1 << 29,\n    CPUID_FEATURES_EDX_3DNOW_EXT              = 1 << 30,\n    CPUID_FEATURES_EDX_3DNOW                  = 1 << 31\n} CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;\n\n/* CPUID Thermal and Power Management features (0x00000006) enumeration list */\ntypedef enum _CPUID_FEATURES_POWER_MANAGEMENT\n{\n    CPUID_FEATURES_EAX_DTHERM                  = 1 << 0,\n    CPUID_FEATURES_EAX_IDA                     = 1 << 1,\n    CPUID_FEATURES_EAX_ARAT                    = 1 << 2,\n    CPUID_FEATURES_EAX_PLN                     = 1 << 4,\n    CPUID_FEATURES_EAX_PTS                     = 1 << 6,\n    CPUID_FEATURES_EAX_HWP                     = 1 << 7,\n    CPUID_FEATURES_EAX_HWP_NOTIFY              = 1 << 8,\n    CPUID_FEATURES_EAX_HWP_ACT_WINDOW          = 1 << 9,\n    CPUID_FEATURES_EAX_HWP_EPP                 = 1 << 10,\n    CPUID_FEATURES_EAX_HWP_PKG_REQ             = 1 << 11,\n    CPUID_FEATURES_EAX_HWP_HIGHEST_PERF_CHANGE = 1 << 15,\n    CPUID_FEATURES_EAX_HFI                     = 1 << 19\n} CPUID_FEATURES_LEAF6, *PCPUID_FEATURES_LEAF6;\n\n/* CPUID STD1 features (0x00000001) enumeration list */\ntypedef enum _CPUID_FEATURES_STANDARD1\n{\n    CPUID_FEATURES_ECX_SSE3                   = 1 << 0,\n    CPUID_FEATURES_ECX_PCLMUL                 = 1 << 1,\n    CPUID_FEATURES_ECX_DTES64                 = 1 << 2,\n    CPUID_FEATURES_ECX_MONITOR                = 1 << 3,\n    CPUID_FEATURES_ECX_DS_CPL                 = 1 << 4,\n    CPUID_FEATURES_ECX_VMX                    = 1 << 5,\n    CPUID_FEATURES_ECX_SMX                    = 1 << 6,\n    CPUID_FEATURES_ECX_EST                    = 1 << 7,\n    CPUID_FEATURES_ECX_TM2                    = 1 << 8,\n    CPUID_FEATURES_ECX_SSSE3                  = 1 << 9,\n    CPUID_FEATURES_ECX_CID                    = 1 << 10,\n    CPUID_FEATURES_ECX_SDBG                   = 1 << 11,\n    CPUID_FEATURES_ECX_FMA                    = 1 << 12,\n    CPUID_FEATURES_ECX_CX16                   = 1 << 13,\n    CPUID_FEATURES_ECX_XTPR                   = 1 << 14,\n    CPUID_FEATURES_ECX_PDCM                   = 1 << 15,\n    CPUID_FEATURES_ECX_PCID                   = 1 << 17,\n    CPUID_FEATURES_ECX_DCA                    = 1 << 18,\n    CPUID_FEATURES_ECX_SSE4_1                 = 1 << 19,\n    CPUID_FEATURES_ECX_SSE4_2                 = 1 << 20,\n    CPUID_FEATURES_ECX_X2APIC                 = 1 << 21,\n    CPUID_FEATURES_ECX_MOVBE                  = 1 << 22,\n    CPUID_FEATURES_ECX_POPCNT                 = 1 << 23,\n    CPUID_FEATURES_ECX_TSC_DEADLINE           = 1 << 24,\n    CPUID_FEATURES_ECX_AES                    = 1 << 25,\n    CPUID_FEATURES_ECX_XSAVE                  = 1 << 26,\n    CPUID_FEATURES_ECX_OSXSAVE                = 1 << 27,\n    CPUID_FEATURES_ECX_AVX                    = 1 << 28,\n    CPUID_FEATURES_ECX_F16C                   = 1 << 29,\n    CPUID_FEATURES_ECX_RDRAND                 = 1 << 30,\n    CPUID_FEATURES_ECX_HYPERVISOR             = 1 << 31,\n    CPUID_FEATURES_EDX_FPU                    = 1 << 0,\n    CPUID_FEATURES_EDX_VME                    = 1 << 1,\n    CPUID_FEATURES_EDX_DE                     = 1 << 2,\n    CPUID_FEATURES_EDX_PSE                    = 1 << 3,\n    CPUID_FEATURES_EDX_TSC                    = 1 << 4,\n    CPUID_FEATURES_EDX_MSR                    = 1 << 5,\n    CPUID_FEATURES_EDX_PAE                    = 1 << 6,\n    CPUID_FEATURES_EDX_MCE                    = 1 << 7,\n    CPUID_FEATURES_EDX_CX8                    = 1 << 8,\n    CPUID_FEATURES_EDX_APIC                   = 1 << 9,\n    CPUID_FEATURES_EDX_SEP                    = 1 << 11,\n    CPUID_FEATURES_EDX_MTRR                   = 1 << 12,\n    CPUID_FEATURES_EDX_PGE                    = 1 << 13,\n    CPUID_FEATURES_EDX_MCA                    = 1 << 14,\n    CPUID_FEATURES_EDX_CMOV                   = 1 << 15,\n    CPUID_FEATURES_EDX_PAT                    = 1 << 16,\n    CPUID_FEATURES_EDX_PSE36                  = 1 << 17,\n    CPUID_FEATURES_EDX_PSN                    = 1 << 18,\n    CPUID_FEATURES_EDX_CLFLUSH                = 1 << 19,\n    CPUID_FEATURES_EDX_DS                     = 1 << 21,\n    CPUID_FEATURES_EDX_ACPI                   = 1 << 22,\n    CPUID_FEATURES_EDX_MMX                    = 1 << 23,\n    CPUID_FEATURES_EDX_FXSR                   = 1 << 24,\n    CPUID_FEATURES_EDX_SSE                    = 1 << 25,\n    CPUID_FEATURES_EDX_SSE2                   = 1 << 26,\n    CPUID_FEATURES_EDX_SS                     = 1 << 27,\n    CPUID_FEATURES_EDX_HTT                    = 1 << 28,\n    CPUID_FEATURES_EDX_TM                     = 1 << 29,\n    CPUID_FEATURES_EDX_IA64                   = 1 << 30,\n    CPUID_FEATURES_EDX_PBE                    = 1 << 31\n} CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;\n\n/* CPUID STD7 features (0x00000007, subleaf 0) enumeration list */\ntypedef enum _CPUID_FEATURES_STANDARD7_LEAF0\n{\n    CPUID_FEATURES_EBX_FSGSBASE               = 1 << 0,\n    CPUID_FEATURES_EBX_TSC_ADJUST             = 1 << 1,\n    CPUID_FEATURES_EBX_SGX                    = 1 << 2,\n    CPUID_FEATURES_EBX_BMI1                   = 1 << 3,\n    CPUID_FEATURES_EBX_HLE                    = 1 << 4,\n    CPUID_FEATURES_EBX_AVX2                   = 1 << 5,\n    CPUID_FEATURES_EBX_FDP_DEPRECATION        = 1 << 6,\n    CPUID_FEATURES_EBX_SMEP                   = 1 << 7,\n    CPUID_FEATURES_EBX_BMI2                   = 1 << 8,\n    CPUID_FEATURES_EBX_ERMS                   = 1 << 9,\n    CPUID_FEATURES_EBX_INVPCID                = 1 << 10,\n    CPUID_FEATURES_EBX_RTM                    = 1 << 11,\n    CPUID_FEATURES_EBX_QOS_MONITORING         = 1 << 12,\n    CPUID_FEATURES_EBX_DEPRECATE_FCS_FDS      = 1 << 13,\n    CPUID_FEATURES_EBX_MPX                    = 1 << 14,\n    CPUID_FEATURES_EBX_QOS_ENFORCEMENT        = 1 << 15,\n    CPUID_FEATURES_EBX_AVX512F                = 1 << 16,\n    CPUID_FEATURES_EBX_AVX512DQ               = 1 << 17,\n    CPUID_FEATURES_EBX_RDSEED                 = 1 << 18,\n    CPUID_FEATURES_EBX_ADX                    = 1 << 19,\n    CPUID_FEATURES_EBX_SMAP                   = 1 << 20,\n    CPUID_FEATURES_EBX_AVX512IFMA52           = 1 << 21,\n    CPUID_FEATURES_EBX_CLFLUSHOPT             = 1 << 23,\n    CPUID_FEATURES_EBX_CLWB                   = 1 << 24,\n    CPUID_FEATURES_EBX_PROCESSOR_TRACE        = 1 << 25,\n    CPUID_FEATURES_EBX_AVX512PF               = 1 << 26,\n    CPUID_FEATURES_EBX_AVX512ER               = 1 << 27,\n    CPUID_FEATURES_EBX_AVX512CD               = 1 << 28,\n    CPUID_FEATURES_EBX_SHA                    = 1 << 29,\n    CPUID_FEATURES_EBX_AVX512BW               = 1 << 30,\n    CPUID_FEATURES_EBX_AVX512VL               = 1 << 31,\n    CPUID_FEATURES_ECX_PREFETCHWT1            = 1 << 0,\n    CPUID_FEATURES_ECX_AVX512_VBMI            = 1 << 1,\n    CPUID_FEATURES_ECX_UMIP                   = 1 << 2,\n    CPUID_FEATURES_ECX_PKU                    = 1 << 3,\n    CPUID_FEATURES_ECX_OSPKE                  = 1 << 4,\n    CPUID_FEATURES_ECX_WAITPKG                = 1 << 5,\n    CPUID_FEATURES_ECX_AVX512_VBMI2           = 1 << 6,\n    CPUID_FEATURES_ECX_CET_SS                 = 1 << 7,\n    CPUID_FEATURES_ECX_GFNI                   = 1 << 8,\n    CPUID_FEATURES_ECX_VAES                   = 1 << 9,\n    CPUID_FEATURES_ECX_VPCLMULQDQ             = 1 << 10,\n    CPUID_FEATURES_ECX_AVX512_VNNI            = 1 << 11,\n    CPUID_FEATURES_ECX_AVX512_BITALG          = 1 << 12,\n    CPUID_FEATURES_ECX_TME                    = 1 << 13,\n    CPUID_FEATURES_ECX_AVX512_VPOPCNTDQ       = 1 << 14,\n    CPUID_FEATURES_ECX_LA57                   = 1 << 16,\n    CPUID_FEATURES_ECX_RDPID                  = 1 << 22,\n    CPUID_FEATURES_ECX_KEYLOCKER              = 1 << 23,\n    CPUID_FEATURES_ECX_BUS_LOCK_DETECT        = 1 << 24,\n    CPUID_FEATURES_ECX_CLDEMOTE               = 1 << 25,\n    CPUID_FEATURES_ECX_MOVDIRI                = 1 << 27,\n    CPUID_FEATURES_ECX_MOVDIR64B              = 1 << 28,\n    CPUID_FEATURES_ECX_ENQCMD                 = 1 << 29,\n    CPUID_FEATURES_ECX_SGX_LAUNCH_CONFIG      = 1 << 30,\n    CPUID_FEATURES_ECX_PKS                    = 1 << 31,\n    CPUID_FEATURES_EDX_SGX_KEYS               = 1 << 1,\n    CPUID_FEATURES_EDX_AVX512_4VNNIW          = 1 << 2,\n    CPUID_FEATURES_EDX_AVX512_4FMAPS          = 1 << 3,\n    CPUID_FEATURES_EDX_FAST_SHORT_REP_MOV     = 1 << 4,\n    CPUID_FEATURES_EDX_UINTR                  = 1 << 5,\n    CPUID_FEATURES_EDX_AVX512_VPINTERSECT     = 1 << 8,\n    CPUID_FEATURES_EDX_SRBDS_CTRL             = 1 << 9,\n    CPUID_FEATURES_EDX_MD_CLEAR               = 1 << 10,\n    CPUID_FEATURES_EDX_RTM_ALWAYS_ABORT       = 1 << 11,\n    CPUID_FEATURES_EDX_RTM_FORCE_ABORT        = 1 << 13,\n    CPUID_FEATURES_EDX_SERIALIZE              = 1 << 14,\n    CPUID_FEATURES_EDX_HYBRID                 = 1 << 15,\n    CPUID_FEATURES_EDX_TSXLDTRK               = 1 << 16,\n    CPUID_FEATURES_EDX_PCONFIG                = 1 << 18,\n    CPUID_FEATURES_EDX_ARCH_LBR               = 1 << 19,\n    CPUID_FEATURES_EDX_CET_IBT                = 1 << 20,\n    CPUID_FEATURES_EDX_AMX_BF16               = 1 << 22,\n    CPUID_FEATURES_EDX_AVX512_FP16            = 1 << 23,\n    CPUID_FEATURES_EDX_AMX_TILE               = 1 << 24,\n    CPUID_FEATURES_EDX_AMX_INT8               = 1 << 25,\n    CPUID_FEATURES_EDX_SCA_IBRS_IBPB          = 1 << 26,\n    CPUID_FEATURES_EDX_SCA_STIBP              = 1 << 27,\n    CPUID_FEATURES_EDX_L1D_FLUSH              = 1 << 28,\n    CPUID_FEATURES_EDX_ARCH_CAPABILITIES_MSR  = 1 << 29,\n    CPUID_FEATURES_EDX_CORE_CAPABILITIES_MSR  = 1 << 30,\n    CPUID_FEATURES_EDX_SCA_SSBD               = 1 << 31\n} CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;\n\n/* CPUID STD7 features (0x00000007, subleaf 1) enumeration list */\ntypedef enum _CPUID_FEATURES_STANDARD7_LEAF1\n{\n    CPUID_FEATURES_EAX_SHA512                 = 1 << 0,\n    CPUID_FEATURES_EAX_SM3                    = 1 << 1,\n    CPUID_FEATURES_EAX_SM4                    = 1 << 2,\n    CPUID_FEATURES_EAX_RAO_INT                = 1 << 3,\n    CPUID_FEATURES_EAX_AVX_VNNI               = 1 << 4,\n    CPUID_FEATURES_EAX_AVX512_BF16            = 1 << 5,\n    CPUID_FEATURES_EAX_LASS                   = 1 << 6,\n    CPUID_FEATURES_EAX_CMPCCXADD              = 1 << 7,\n    CPUID_FEATURES_EAX_ARCH_PERFMON           = 1 << 8,\n    CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_MOVSB = 1 << 10,\n    CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_STOSB = 1 << 11,\n    CPUID_FEATURES_EAX_FAST_ZEROLEN_REP_CMPSB = 1 << 12,\n    CPUID_FEATURES_EAX_FRED                   = 1 << 17,\n    CPUID_FEATURES_EAX_LKGS                   = 1 << 18,\n    CPUID_FEATURES_EAX_WRMSRNS                = 1 << 19,\n    CPUID_FEATURES_EAX_NMI_SOURCE_REPORTING   = 1 << 20,\n    CPUID_FEATURES_EAX_AMX_FP16               = 1 << 21,\n    CPUID_FEATURES_EAX_HRESET                 = 1 << 22,\n    CPUID_FEATURES_EAX_AVX_IFMA               = 1 << 23,\n    CPUID_FEATURES_EAX_LAM                    = 1 << 26,\n    CPUID_FEATURES_EAX_MSRLIST                = 1 << 27,\n    CPUID_FEATURES_EAX_INVD_DISABLE           = 1 << 30,\n    CPUID_FEATURES_EAX_MOVRS                  = 1 << 31,\n    CPUID_FEATURES_EBX_PPIN                   = 1 << 0,\n    CPUID_FEATURES_EBX_TSE                    = 1 << 1,\n    CPUID_FEATURES_EBX_CPUIDMAXVAL_LIM_RMV    = 1 << 3,\n    CPUID_FEATURES_ECX_MSR_IMM                = 1 << 5,\n    CPUID_FEATURES_EDX_AVX_VNNI_INT8          = 1 << 4,\n    CPUID_FEATURES_EDX_AVX_NE_CONVERT         = 1 << 5,\n    CPUID_FEATURES_EDX_AMX_COMPLEX            = 1 << 8,\n    CPUID_FEATURES_EDX_AVX_VNNI_INT16         = 1 << 10,\n    CPUID_FEATURES_EDX_USER_TIMER             = 1 << 13,\n    CPUID_FEATURES_EDX_PREFETCHI              = 1 << 14,\n    CPUID_FEATURES_EDX_USER_MSR               = 1 << 15,\n    CPUID_FEATURES_EDX_UIRET_UIF              = 1 << 17,\n    CPUID_FEATURES_EDX_CET_SSS                = 1 << 18,\n    CPUID_FEATURES_EDX_AVX10                  = 1 << 19,\n    CPUID_FEATURES_EDX_APX                    = 1 << 21,\n    CPUID_FEATURES_EDX_MWAIT_AND_LEAF5        = 1 << 23\n} CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;\n\n/* CPUID requests */\ntypedef enum _CPUID_REQUESTS\n{\n    CPUID_GET_VENDOR_STRING                   = 0x00000000,\n    CPUID_GET_STANDARD1_FEATURES              = 0x00000001,\n    CPUID_GET_TLB_CACHE                       = 0x00000002,\n    CPUID_GET_SERIAL                          = 0x00000003,\n    CPUID_GET_CACHE_TOPOLOGY                  = 0x00000004,\n    CPUID_GET_MONITOR_MWAIT                   = 0x00000005,\n    CPUID_GET_POWER_MANAGEMENT                = 0x00000006,\n    CPUID_GET_STANDARD7_FEATURES              = 0x00000007,\n    CPUID_GET_TSC_CRYSTAL_CLOCK               = 0x00000015,\n    CPUID_GET_EXTENDED_MAX                    = 0x80000000,\n    CPUID_GET_EXTENDED_FEATURES               = 0x80000001,\n    CPUID_GET_ADVANCED_POWER_MANAGEMENT       = 0x80000007\n} CPUID_REQUESTS, *PCPUID_REQUESTS;\n\n/* Interrupt handler */\ntypedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);\n\n/* Processor identification information */\ntypedef struct _CPU_IDENTIFICATION\n{\n    ULONGLONG ExtendedFeatureBits;\n    USHORT Family;\n    ULONGLONG FeatureBits;\n    USHORT Model;\n    USHORT Stepping;\n    CPU_VENDOR Vendor;\n    UCHAR VendorName[13];\n} CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;\n\n/* CPUID registers */\ntypedef struct _CPUID_REGISTERS\n{\n    UINT32 Leaf;\n    UINT32 SubLeaf;\n    UINT32 Eax;\n    UINT32 Ebx;\n    UINT32 Ecx;\n    UINT32 Edx;\n} CPUID_REGISTERS, *PCPUID_REGISTERS;\n\n/* CPU signature read from CPUID structure definition */\ntypedef struct _CPUID_SIGNATURE\n{\n    ULONG Stepping:4;\n    ULONG Model:4;\n    ULONG Family:4;\n    ULONG Unused1:4;\n    ULONG ExtendedModel:4;\n    ULONG ExtendedFamily:8;\n    ULONG Unused2:4;\n} CPU_SIGNATURE, *PCPU_SIGNATURE;\n\n/* Trampoline types */\ntypedef enum _TRAMPOLINE_TYPE\n{\n    TrampolineApStartup\n} TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_I686_ARTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/i686/hlfuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/i686/hlfuncs.h\n * DESCRIPTION:     XT hardware abstraction layer routines specific to i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_I686_HLFUNCS_H\n#define __XTDK_I686_HLFUNCS_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include <i686/xtstruct.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Hardware layer routines forward references */\nXTCLINK\nXTCDECL\nUCHAR\nHlReadPort8(IN USHORT Port);\n\nXTCLINK\nXTCDECL\nUSHORT\nHlReadPort16(IN USHORT Port);\n\nXTCLINK\nXTCDECL\nULONG\nHlReadPort32(IN USHORT Port);\n\nXTCLINK\nXTCDECL\nVOID\nHlWritePort8(IN USHORT Port,\n             IN UCHAR Data);\n\nXTCLINK\nXTCDECL\nVOID\nHlWritePort16(IN USHORT Port,\n              IN USHORT Value);\n\nXTCLINK\nXTCDECL\nVOID\nHlWritePort32(IN USHORT Port,\n              IN ULONG Value);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_I686_HLFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/i686/hltypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/i686/hltypes.h\n * DESCRIPTION:     XT hardware abstraction layer structures definitions specific to i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_I686_HLTYPES_H\n#define __XTDK_I686_HLTYPES_H\n\n#include <xtbase.h>\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include ARCH_HEADER(xtstruct.h)\n\n\n/* APIC base addresses */\n#define APIC_BASE                                       0xFFFE0000\n#define APIC_LAPIC_MSR_BASE                             0x0000001B\n#define APIC_X2APIC_MSR_BASE                            0x00000800\n\n/* APIC vector definitions */\n#define APIC_VECTOR_ZERO                                0x00\n#define APIC_VECTOR_SPURIOUS                            0x1F\n#define APIC_VECTOR_APC                                 0x3D\n#define APIC_VECTOR_DPC                                 0x41\n#define APIC_VECTOR_REBOOT                              0x50\n#define APIC_VECTOR_DEVICE1                             0x51\n#define APIC_VECTOR_DEVICE2                             0x61\n#define APIC_VECTOR_DEVICE3                             0x71\n#define APIC_VECTOR_DEVICE4                             0x81\n#define APIC_VECTOR_DEVICE5                             0x91\n#define APIC_VECTOR_DEVICE6                             0xA1\n#define APIC_VECTOR_DEVICE7                             0xB1\n#define APIC_VECTOR_GENERIC                             0xC1\n#define APIC_VECTOR_SYNC                                0xC1\n#define APIC_VECTOR_CLOCK                               0xD1\n#define APIC_VECTOR_CLOCK_IPI                           0xD2\n#define APIC_VECTOR_IPI                                 0xE1\n#define APIC_VECTOR_ERROR                               0xE3\n#define APIC_VECTOR_POWERFAIL                           0xEF\n#define APIC_VECTOR_PROFILE                             0xFD\n#define APIC_VECTOR_PERF                                0xFE\n#define APIC_VECTOR_NMI                                 0xFF\n\n/* APIC destination formats */\n#define APIC_DF_FLAT                                    0xFFFFFFFF\n#define APIC_DF_CLUSTER                                 0x0FFFFFFF\n\n/* APIC trigger modes */\n#define APIC_TGM_EDGE                                   0\n#define APIC_TGM_LEVEL                                  1\n\n/* APIC LDR (Logical Destination Register) shifts */\n#define APIC_X2APIC_LDR_SHIFT                           16\n#define APIC_XAPIC_LDR_SHIFT                            24\n\n/* Maximum number of I/O APICs */\n#define APIC_MAX_IOAPICS                                64\n\n/* I/O APIC base address */\n#define IOAPIC_DEFAULT_BASE                             0xFEC00000\n\n/* I/O APIC definitions */\n#define IOAPIC_MAX_CONTROLLERS                          64\n#define IOAPIC_MAX_OVERRIDES                            16\n#define IOAPIC_RTE_MASKED                               0x100FF\n#define IOAPIC_RTE_SIZE                                 2\n#define IOAPIC_VECTOR_FREE                              0xFF\n#define IOAPIC_VECTOR_RESERVED                          0xFE\n\n/* IOAPIC offsets */\n#define IOAPIC_IOREGSEL                                 0x00\n#define IOAPIC_IOWIN                                    0x10\n\n/* IOAPIC registers */\n#define IOAPIC_ID                                       0x00\n#define IOAPIC_VER                                      0x01\n#define IOAPIC_ARB                                      0x02\n#define IOAPIC_REDTBL                                   0x10\n\n/* 8259/ISP PIC ports definitions */\n#define PIC1_CONTROL_PORT                               0x20\n#define PIC1_DATA_PORT                                  0x21\n#define PIC1_ELCR_PORT                                  0x04D0\n#define PIC2_CONTROL_PORT                               0xA0\n#define PIC2_DATA_PORT                                  0xA1\n#define PIC2_ELCR_PORT                                  0x04D1\n\n/* PIC vector definitions */\n#define PIC1_VECTOR_SPURIOUS                            0x37\n\n/* HPET General Capabilities definitions */\n#define HPET_CAPABILITY_64BIT                           0x2000ULL\n#define HPET_CAPABILITY_LEGACY_REPLACEMENT              0x8000ULL\n\n/* HPET General Configuration definitions */\n#define HPET_CONFIG_ENABLE                              0x0001ULL\n#define HPET_CONFIG_LEGACY_REPLACEMENT                  0x0002ULL\n\n/* HPET Timer Configuration definitions */\n#define HPET_TIMER_CONFIG_LEVEL_TRIGGERED               0x0002ULL\n#define HPET_TIMER_CONFIG_ENABLED                       0x0004ULL\n#define HPET_TIMER_CONFIG_PERIODIC                      0x0008ULL\n#define HPET_TIMER_CONFIG_SUPPORTS_PERIODIC             0x0010ULL\n#define HPET_TIMER_CONFIG_SUPPORTS_64BIT                0x0020ULL\n#define HPET_TIMER_CONFIG_VALUE_ACCUMULATOR             0x0040ULL\n#define HPET_TIMER_CONFIG_FORCE_32BIT                   0x0100ULL\n#define HPET_TIMER_CONFIG_FSB_ENABLED                   0x4000ULL\n#define HPET_TIMER_CONFIG_SUPPORTS_FSB                  0x8000ULL\n\n/* PIT ports definitions */\n#define PIT_COMMAND_PORT                                0x43\n#define PIT_DATA_PORT0                                  0x40\n#define PIT_DATA_PORT1                                  0x41\n#define PIT_DATA_PORT2                                  0x42\n\n/* PIT related definitions */\n#define PIT_BASE_FREQUENCY                              1193182\n\n/* PIT Access Mode: Defines how the CPU reads or writes the counter value */\n#define PIT_CMD_ACCESS_LATCH                            0x00\n#define PIT_CMD_ACCESS_LOWBYTE_ONLY                     0x10\n#define PIT_CMD_ACCESS_HIGHBYTE_ONLY                    0x20\n#define PIT_CMD_ACCESS_LOWBYTE_HIGHBYTE                 0x30\n\n/* PIT Channel Selection: Specifies the physical timer channel to configure */\n#define PIT_CMD_CHANNEL0                                0x00\n#define PIT_CMD_CHANNEL1                                0x40\n#define PIT_CMD_CHANNEL2                                0x80\n\n/* PIT Operating Mode: Defines the hardware behavior and the generated waveform */\n#define PIT_MODE0_INT_ON_TERMINAL_COUNT                 0x00\n#define PIT_MODE1_ONESHOT                               0x02\n#define PIT_MODE2_RATE_GENERATOR                        0x04\n#define PIT_MODE3_SQUARE_WAVE_GEN                       0x06\n#define PIT_MODE4_SOFTWARE_STROBE                       0x08\n#define PIT_MODE5_HARDWARE_STROBE                       0x0A\n\n/* CMOS controller access ports */\n#define CMOS_SELECT_PORT                                0x70\n#define CMOS_DATA_PORT                                  0x71\n\n/* CMOD Select port definitions */\n#define CMOS_NMI_SELECT                                 0x80\n#define CMOS_REGISTER_SECOND                            0x00\n#define CMOS_REGISTER_MINUTE                            0x02\n#define CMOS_REGISTER_HOUR                              0x04\n#define CMOS_REGISTER_WEEKDAY                           0x06\n#define CMOS_REGISTER_DAY                               0x07\n#define CMOS_REGISTER_MONTH                             0x08\n#define CMOS_REGISTER_YEAR                              0x09\n#define CMOS_REGISTER_A                                 0x0A\n#define CMOS_REGISTER_B                                 0x0B\n#define CMOS_REGISTER_C                                 0x0C\n\n/* CMOS Register A definitions */\n#define CMOS_REGISTER_A_RATE_MASK                       0x0F\n#define CMOS_REGISTER_A_UPDATE_IN_PROGRESS              0x80\n\n/* CMOS Register B definitions */\n#define CMOS_REGISTER_B_24_HOUR                         0x02\n#define CMOS_REGISTER_B_BINARY                          0x04\n#define CMOS_REGISTER_B_PERIODIC                        0x40\n#define CMOS_REGISTER_B_SET_CLOCK                       0x80\n\n/* CMOS Register C definitions */\n#define CMOS_REGISTER_C_PERIODIC                        0x40\n#define CMOS_REGISTER_C_INTERRUPT                       0x80\n\n/* CMOS RTC 24-hour mode */\n#define CMOS_RTC_POST_MERIDIEM                          0x80\n\n/* Serial ports information */\n#define COMPORT_ADDRESS                                 {0x3F8, 0x2F8, 0x3E8, 0x2E8, 0x5F8, 0x4F8, 0x5E8, 0x4E8}\n#define COMPORT_COUNT                                   8\n\n/* Initial stall factor */\n#define INITIAL_STALL_FACTOR                            100\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* APIC destination mode enumeration list */\ntypedef enum _APIC_DEST_MODE\n{\n    APIC_DM_Physical,\n    APIC_DM_Logical\n} APIC_DEST_MODE, *PAPIC_DEST_MODE;\n\n/* APIC delivery mode enumeration list */\ntypedef enum _APIC_DM\n{\n    APIC_DM_FIXED,\n    APIC_DM_LOWPRIO,\n    APIC_DM_SMI,\n    APIC_DM_REMOTE,\n    APIC_DM_NMI,\n    APIC_DM_INIT,\n    APIC_DM_STARTUP,\n    APIC_DM_EXTINT,\n} APIC_DM, *PAPIC_DM;\n\n/* APIC destination short-hand enumeration list */\ntypedef enum _APIC_DSH\n{\n    APIC_DSH_Destination,\n    APIC_DSH_Self,\n    APIC_DSH_AllIncludingSelf,\n    APIC_DSH_AllExclusingSelf\n} APIC_DSH, *PAPIC_DSH;\n\n/* APIC mode list */\ntypedef enum _APIC_MODE\n{\n    APIC_MODE_COMPAT,\n    APIC_MODE_X2APIC\n} APIC_MODE, *PAPIC_MODE;\n\n/* APIC Register Address Map */\ntypedef enum _APIC_REGISTER\n{\n    APIC_ID       = 0x02, /* APIC ID Register */\n    APIC_VER      = 0x03, /* APIC Version Register */\n    APIC_TPR      = 0x08, /* Task Priority Register */\n    APIC_APR      = 0x09, /* Arbitration Priority Register */\n    APIC_PPR      = 0x0A, /* Processor Priority Register (R) */\n    APIC_EOI      = 0x0B, /* EOI Register */\n    APIC_RRR      = 0x0C, /* Remote Read Register */\n    APIC_LDR      = 0x0D, /* Logical Destination Register */\n    APIC_DFR      = 0x0E, /* Destination Format Register (not available in extended mode) */\n    APIC_SIVR     = 0x0F, /* Spurious Interrupt Vector Register */\n    APIC_ISR      = 0x10, /* Interrupt Service Register*/\n    APIC_TMR      = 0x18, /* Trigger Mode Register */\n    APIC_IRR      = 0x20, /* Interrupt Request Register */\n    APIC_ESR      = 0x28, /* Error Status Register */\n    APIC_ICR0     = 0x30, /* Interrupt Command Register */\n    APIC_ICR1     = 0x31, /* Interrupt Command Register (not available in extended mode) */\n    APIC_TMRLVTR  = 0x32, /* Timer Local Vector Table */\n    APIC_THRMLVTR = 0x33, /* Thermal Local Vector Table */\n    APIC_PCLVTR   = 0x34, /* Performance Counter Local Vector Table */\n    APIC_LINT0    = 0x35, /* LINT0 Local Vector Table */\n    APIC_LINT1    = 0x36, /* LINT1 Local Vector Table */\n    APIC_ERRLVTR  = 0x37, /* Error Local Vector Table */\n    APIC_TICR     = 0x38, /* Initial Count Register for Timer */\n    APIC_TCCR     = 0x39, /* Current Count Register for Timer */\n    APIC_TDCR     = 0x3E, /* Timer Divide Configuration Register */\n    APIC_SIPI     = 0x3F, /* Self-IPI Register */\n    APIC_EAFR     = 0x40, /* extended APIC Feature register */\n    APIC_EACR     = 0x41, /* Extended APIC Control Register */\n    APIC_SEOI     = 0x42, /* Specific End Of Interrupt Register */\n    APIC_EXT0LVTR = 0x50, /* Extended Interrupt 0 Local Vector Table */\n    APIC_EXT1LVTR = 0x51, /* Extended Interrupt 1 Local Vector Table */\n    APIC_EXT2LVTR = 0x52, /* Extended Interrupt 2 Local Vector Table */\n    APIC_EXT3LVTR = 0x53  /* Extended Interrupt 3 Local Vector Table */\n} APIC_REGISTER, *PAPIC_REGISTER;\n\n/* APIC Timer Divide enumeration list */\ntypedef enum _APIC_TIMER_DIVISOR\n{\n    TIMER_DivideBy2   = 0,\n    TIMER_DivideBy4   = 1,\n    TIMER_DivideBy8   = 2,\n    TIMER_DivideBy16  = 3,\n    TIMER_DivideBy32  = 8,\n    TIMER_DivideBy64  = 9,\n    TIMER_DivideBy128 = 10,\n    TIMER_DivideBy1   = 11,\n} APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;\n\n/* I8259 PIC interrupt mode enumeration list */\ntypedef enum _PIC_I8259_ICW1_INTERRUPT_MODE\n{\n    EdgeTriggered,\n    LevelTriggered\n} PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;\n\n/* I8259 PIC interval enumeration list */\ntypedef enum _PIC_I8259_ICW1_INTERVAL\n{\n    Interval8,\n    Interval4\n} PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;\n\n/* I8259 PIC operating mode enumeration list */\ntypedef enum _PIC_I8259_ICW1_OPERATING_MODE\n{\n    Cascade,\n    Single\n} PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_MODE;\n\n/* I8259 PIC buffered mode enumeration list */\ntypedef enum _PIC_I8259_ICW4_BUFFERED_MODE\n{\n    NonBuffered,\n    NonBuffered2,\n    BufferedSlave,\n    BufferedMaster\n} PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;\n\n/* I8259 PIC End Of Interrupt (EOI) mode enumeration list */\ntypedef enum _PIC_I8259_ICW4_EOI_MODE\n{\n    NormalEoi,\n    AutomaticEoi\n} PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;\n\n/* I8259 PIC system mode enumeration list */\ntypedef enum _PIC_I8259_ICW4_SYSTEM_MODE\n{\n    Mcs8085Mode,\n    New8086Mode\n} PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;\n\n/* Supported hardware timer backends */\ntypedef enum _TIMER_TYPE\n{\n    TimerNone,\n    TimerAcpiPm,\n    TimerHpet,\n    TimerLapic,\n    TimerPit,\n    TimerTsc\n} TIMER_TYPE, *PTIMER_TYPE;\n\n/* APIC Base Register */\ntypedef union _APIC_BASE_REGISTER\n{\n    ULONGLONG LongLong;\n    struct\n    {\n        ULONGLONG Reserved1:8;\n        ULONGLONG BootStrapProcessor:1;\n        ULONGLONG Reserved2:1;\n        ULONGLONG ExtendedMode:1;\n        ULONGLONG Enable:1;\n        ULONGLONG BaseAddress:40;\n        ULONGLONG Reserved3:12;\n    };\n} APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;\n\n/* APIC Command Register */\ntypedef union _APIC_COMMAND_REGISTER\n{\n    ULONGLONG LongLong;\n    struct\n    {\n        ULONG Long0;\n        ULONG Long1;\n    };\n    struct\n    {\n        ULONGLONG Vector:8;\n        ULONGLONG DeliveryMode:3;\n        ULONGLONG DestinationMode:1;\n        ULONGLONG DeliveryStatus:1;\n        ULONGLONG ReservedMBZ:1;\n        ULONGLONG Level:1;\n        ULONGLONG TriggerMode:1;\n        ULONGLONG RemoteReadStatus:2;\n        ULONGLONG DestinationShortHand:2;\n        ULONGLONG Reserved2MBZ:36;\n        ULONGLONG Destination:8;\n    };\n} APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;\n\n/* APIC Local Vector Table (LVT) Register */\ntypedef union _APIC_LVT_REGISTER\n{\n    ULONG Long;\n    struct\n    {\n        ULONG Vector:8;\n        ULONG DeliveryMode:3;\n        ULONG Reserved1:1;\n        ULONG DeliveryStatus:1;\n        ULONG Reserved2:1;\n        ULONG RemoteIRR:1;\n        ULONG TriggerMode:1;\n        ULONG Mask:1;\n        ULONG TimerMode:1;\n        ULONG Reserved3:13;\n    };\n} APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;\n\n/* APIC Spurious Register */\ntypedef union _APIC_SPURIOUS_REGISTER\n{\n    ULONG Long;\n    struct\n    {\n        ULONG Vector:8;\n        ULONG SoftwareEnable:1;\n        ULONG CoreChecking:1;\n        ULONG Reserved:22;\n    };\n} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;\n\n/* I/O APIC Controller information */\ntypedef struct _IOAPIC_DATA\n{\n    ULONG GsiBase;\n    ULONG Identifier;\n    ULONG LineCount;\n    PHYSICAL_ADDRESS PhysicalAddress;\n    ULONG_PTR VirtualAddress;\n} IOAPIC_DATA, *PIOAPIC_DATA;\n\n/* I/O APIC Redirection Register */\ntypedef union _IOAPIC_REDIRECTION_REGISTER\n{\n    ULONGLONG LongLong;\n    struct\n    {\n        UINT Base;\n        UINT Extended;\n    };\n    struct\n    {\n        ULONGLONG Vector:8;\n        ULONGLONG DeliveryMode:3;\n        ULONGLONG DestinationMode:1;\n        ULONGLONG DeliveryStatus:1;\n        ULONGLONG PinPolarity:1;\n        ULONGLONG RemoteIRR:1;\n        ULONGLONG TriggerMode:1;\n        ULONGLONG Mask:1;\n        ULONGLONG Reserved:39;\n        ULONGLONG Destination:8;\n    };\n} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;\n\n/* I8259 PIC register structure */\ntypedef union _PIC_I8259_ICW1\n{\n    struct\n    {\n        UCHAR NeedIcw4:1;\n        UCHAR OperatingMode:1;\n        UCHAR Interval:1;\n        UCHAR InterruptMode:1;\n        UCHAR Init:1;\n        UCHAR InterruptVectorAddress:3;\n    };\n    UCHAR Bits;\n} PIC_I8259_ICW1, *PPIC_I8259_ICW1;\n\n/* I8259 PIC register structure */\ntypedef union _PIC_I8259_ICW2\n{\n    struct\n    {\n        UCHAR Sbz:3;\n        UCHAR InterruptVector:5;\n    };\n    UCHAR Bits;\n} PIC_I8259_ICW2, *PPIC_I8259_ICW2;\n\n/* I8259 PIC register structure */\ntypedef union _PIC_I8259_ICW3\n{\n    union\n    {\n        struct\n        {\n            UCHAR SlaveIrq0:1;\n            UCHAR SlaveIrq1:1;\n            UCHAR SlaveIrq2:1;\n            UCHAR SlaveIrq3:1;\n            UCHAR SlaveIrq4:1;\n            UCHAR SlaveIrq5:1;\n            UCHAR SlaveIrq6:1;\n            UCHAR SlaveIrq7:1;\n        };\n        struct\n        {\n            UCHAR SlaveId:3;\n            UCHAR Reserved:5;\n        };\n    };\n    UCHAR Bits;\n} PIC_I8259_ICW3, *PPIC_I8259_ICW3;\n\n/* I8259 PIC register structure */\ntypedef union _PIC_I8259_ICW4\n{\n    struct\n    {\n        UCHAR SystemMode:1;\n        UCHAR EoiMode:1;\n        UCHAR BufferedMode:2;\n        UCHAR SpecialFullyNestedMode:1;\n        UCHAR Reserved:3;\n    };\n    UCHAR Bits;\n} PIC_I8259_ICW4, *PPIC_I8259_ICW4;\n\n/* HPET Registers structure definition */\ntypedef struct _HPET_REGISTERS\n{\n    VOLATILE ULONGLONG GeneralCapabilities;\n    VOLATILE ULONGLONG Reserved0;\n    VOLATILE ULONGLONG GeneralConfiguration;\n    VOLATILE ULONGLONG Reserved1;\n    VOLATILE ULONGLONG GeneralInterruptStatus;\n    VOLATILE ULONGLONG Reserved2;\n    VOLATILE ULONGLONG Reserved3[2][12];\n    VOLATILE ULONGLONG MainCounterValue;\n    VOLATILE ULONGLONG Reserved4;\n    struct\n    {\n        VOLATILE ULONGLONG Configuration;\n        VOLATILE ULONGLONG Comparator;\n        VOLATILE ULONGLONG FsbInterruptRoute;\n        VOLATILE ULONGLONG Reserved;\n    } Timers[];\n} HPET_REGISTERS, *PHPET_REGISTERS;\n\n/* Hardware timer capabilities and CPU clock features */\ntypedef struct _TIMER_CAPABILITIES\n{\n    BOOLEAN Arat;\n    BOOLEAN Art;\n    BOOLEAN InvariantTsc;\n    BOOLEAN RDTSCP;\n    ULONG TimerFrequency;\n    BOOLEAN TscDeadline;\n    ULONG TscDenominator;\n    ULONG TscNumerator;\n} TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_I686_HLTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/i686/ketypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/i686/ketypes.h\n * DESCRIPTION:     Kernel services related structures definitions specific to i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_I686_KETYPES_H\n#define __XTDK_I686_KETYPES_H\n\n#include <xtbase.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include <potypes.h>\n#include ARCH_HEADER(xtstruct.h)\n#include ARCH_HEADER(artypes.h)\n\n\n/* Selector masks */\n#define MODE_MASK                         0x0001\n#define RPL_MASK                          0x0003\n\n/* GDT selector names */\n#define KGDT_NULL                         0x0000\n#define KGDT_R0_CODE                      0x0008\n#define KGDT_R0_DATA                      0x0010\n#define KGDT_R3_CODE                      0x0018\n#define KGDT_R3_DATA                      0x0020\n#define KGDT_SYS_TSS                      0x0028\n#define KGDT_R0_PB                        0x0030\n#define KGDT_R3_TEB                       0x0038\n#define KGDT_VDM_TILE                     0x0040\n#define KGDT_R0_LDT                       0x0048\n#define KGDT_DF_TSS                       0x0050\n#define KGDT_NMI_TSS                      0x0058\n#define KGDT_VDBS                         0x0068\n#define KGDT_ALIAS                        0x0070\n\n/* GDT descriptor privilege levels */\n#define KGDT_DPL_SYSTEM                   0\n#define KGDT_DPL_USER                     3\n\n/* GDT descriptor properties */\n#define KGDT_DESCRIPTOR_ACCESSED          0x01\n#define KGDT_DESCRIPTOR_READ_WRITE        0x02\n#define KGDT_DESCRIPTOR_EXECUTE_READ      0x02\n#define KGDT_DESCRIPTOR_EXPAND_DOWN       0x04\n#define KGDT_DESCRIPTOR_CONFORMING        0x04\n#define KGDT_DESCRIPTOR_CODE              0x08\n\n/* GDT descriptor type codes */\n#define KGDT_TYPE_NONE                    0x00\n#define KGDT_TYPE_CODE                    (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)\n#define KGDT_TYPE_DATA                    (0x10 | KGDT_DESCRIPTOR_READ_WRITE)\n\n/* IDT access levels */\n#define KIDT_ACCESS_RING0                 0x00\n#define KIDT_ACCESS_RING3                 0x60\n\n/* TSS Offsets */\n#define KTSS_ESP0                         0x04\n#define KTSS_CR3                          0x1C\n#define KTSS_EIP                          0x20\n#define KTSS_EFLAGS                       0x24\n#define KTSS_EAX                          0x28\n#define KTSS_ECX                          0x2C\n#define KTSS_EDX                          0x30\n#define KTSS_EBX                          0x34\n#define KTSS_ESP                          0x38\n#define KTSS_EBP                          0x3C\n#define KTSS_ESI                          0x40\n#define KTSS_EDI                          0x44\n#define KTSS_ES                           0x48\n#define KTSS_CS                           0x4C\n#define KTSS_SS                           0x50\n#define KTSS_DS                           0x54\n#define KTSS_FS                           0x58\n#define KTSS_GS                           0x5C\n#define KTSS_LDT                          0x60\n#define KTSS_IOMAPBASE                    0x66\n#define KTSS_IO_MAPS                      0x68\n\n/* I686 Segment Types */\n#define I686_LDT                          0x2\n#define I686_TASK_GATE                    0x5\n#define I686_TSS                          0x9\n#define I686_ACTIVE_TSS                   0xB\n#define I686_CALL_GATE                    0xC\n#define I686_INTERRUPT_GATE               0xE\n#define I686_TRAP_GATE                    0xF\n\n/* Kernel CPU Standard Features */\n#define KCF_VME                           (1ULL << 0)  /* Virtual 8086 Mode Enhancements */\n#define KCF_LARGE_PAGE                    (1ULL << 1)  /* Page Size Extensions */\n#define KCF_RDTSC                         (1ULL << 2)  /* Time Stamp Counter */\n#define KCF_PAE                           (1ULL << 3)  /* Physical Address Extension */\n#define KCF_MCE                           (1ULL << 4)  /* Machine Check Exception */\n#define KCF_CMPXCHG8B                     (1ULL << 5)  /* CMPXCHG8B Instruction */\n#define KCF_APIC                          (1ULL << 6)  /* APIC On-Chip */\n#define KCF_FAST_SYSCALL                  (1ULL << 7)  /* SYSENTER/SYSEXIT Instructions */\n#define KCF_MTRR                          (1ULL << 8)  /* Memory Type Range Registers */\n#define KCF_GLOBAL_PAGE                   (1ULL << 9)  /* Page Global Enable */\n#define KCF_MCA                           (1ULL << 10) /* Machine Check Architecture */\n#define KCF_CMOV                          (1ULL << 11) /* Conditional Move Instructions */\n#define KCF_PAT                           (1ULL << 12) /* Page Attribute Table */\n#define KCF_PSE36                         (1ULL << 13) /* 36-bit Page Size Extension */\n#define KCF_CLFLUSH                       (1ULL << 14) /* CLFLUSH Instruction */\n#define KCF_FXSR                          (1ULL << 15) /* FXSAVE/FXRSTOR Instructions */\n#define KCF_ACPI                          (1ULL << 16) /* Thermal Monitor and Software Controlled Clock */\n#define KCF_MMX                           (1ULL << 17) /* MMX Technology */\n#define KCF_SSE                           (1ULL << 18) /* Streaming SIMD Extensions */\n#define KCF_SSE2                          (1ULL << 19) /* Streaming SIMD Extensions 2 */\n#define KCF_SMT                           (1ULL << 20) /* Hyper-Threading Technology */\n#define KCF_SSE3                          (1ULL << 21) /* Streaming SIMD Extensions 3 */\n#define KCF_VMX                           (1ULL << 22) /* Intel Virtual Machine Extensions */\n#define KCF_SSSE3                         (1ULL << 23) /* Supplemental SSE3 Instructions */\n#define KCF_SSE41                         (1ULL << 24) /* SSE4.1 Instructions */\n#define KCF_SSE42                         (1ULL << 25) /* SSE4.2 Instructions */\n#define KCF_X2APIC                        (1ULL << 26) /* x2APIC Support */\n#define KCF_POPCNT                        (1ULL << 27) /* POPCNT Instruction */\n#define KCF_TSC_DEADLINE                  (1ULL << 28) /* TSC Deadline Timer */\n#define KCF_AES                           (1ULL << 29) /* AES-NI Instruction Set */\n#define KCF_XSAVE                         (1ULL << 30) /* XSAVE/XRSTOR Instructions */\n#define KCF_AVX                           (1ULL << 31) /* Advanced Vector Extensions */\n#define KCF_RDRAND                        (1ULL << 32) /* RDRAND Instruction */\n#define KCF_FSGSBASE                      (1ULL << 33) /* RDFSBASE/WRFSBASE Instructions */\n#define KCF_AVX2                          (1ULL << 34) /* AVX2 Instructions */\n#define KCF_SMEP                          (1ULL << 35) /* Supervisor Mode Execution Prevention */\n#define KCF_RDSEED                        (1ULL << 36) /* RDSEED Instruction */\n#define KCF_SMAP                          (1ULL << 37) /* Supervisor Mode Access Prevention */\n#define KCF_SHA                           (1ULL << 38) /* SHA Extensions */\n#define KCF_LA57                          (1ULL << 39) /* 57-bit Linear Addresses */\n#define KCF_ARAT                          (1ULL << 40) /* Always Running APIC Timer */\n\n/* Kernel CPU Extended Features */\n#define KCF_SVM                           (1ULL << 0)  /* AMD Secure Virtual Machine */\n#define KCF_SSE4A                         (1ULL << 1)  /* SSE4A Instructions */\n#define KCF_FMA4                          (1ULL << 2)  /* FMA4 Instructions */\n#define KCF_TOPOEXT                       (1ULL << 3)  /* AMD Topology Extensions */\n#define KCF_SYSCALL                       (1ULL << 4)  /* SYSCALL/SYSRET Instructions */\n#define KCF_NX_BIT                        (1ULL << 5)  /* No-Execute Page Protection */\n#define KCF_RDTSCP                        (1ULL << 6)  /* RDTSCP Instruction */\n#define KCF_64BIT                         (1ULL << 7)  /* Long Mode Support */\n#define KCF_3DNOW_EXT                     (1ULL << 8)  /* 3DNow! Extensions */\n#define KCF_3DNOW                         (1ULL << 9)  /* 3DNow! Instructions */\n#define KCF_INVARIANT_TSC                 (1ULL << 10) /* Invariant Time Stamp Counter */\n\n/* Context control flags */\n#define CONTEXT_ARCHITECTURE              0x00010000\n#define CONTEXT_CONTROL                   (CONTEXT_ARCHITECTURE | 0x01)\n#define CONTEXT_INTEGER                   (CONTEXT_ARCHITECTURE | 0x02)\n#define CONTEXT_SEGMENTS                  (CONTEXT_ARCHITECTURE | 0x04)\n#define CONTEXT_FLOATING_POINT            (CONTEXT_ARCHITECTURE | 0x08)\n#define CONTEXT_DEBUG_REGISTERS           (CONTEXT_ARCHITECTURE | 0x10)\n#define CONTEXT_EXTENDED_REGISTERS        (CONTEXT_ARCHITECTURE | 0x20)\n\n/* Interrupt request levels definitions */\n#define PASSIVE_LEVEL                     0\n#define LOW_LEVEL                         0\n#define APC_LEVEL                         1\n#define DISPATCH_LEVEL                    2\n#define CMCI_LEVEL                        5\n#define DEVICE1_LEVEL                     6\n#define DEVICE2_LEVEL                     7\n#define DEVICE3_LEVEL                     8\n#define DEVICE4_LEVEL                     9\n#define DEVICE5_LEVEL                     10\n#define DEVICE6_LEVEL                     11\n#define DEVICE7_LEVEL                     12\n#define PROFILE_LEVEL                     27\n#define SYNC_LEVEL                        27\n#define CLOCK_LEVEL                       28\n#define IPI_LEVEL                         29\n#define POWER_LEVEL                       30\n#define HIGH_LEVEL                        31\n\n/* IOPM Definitions */\n#define IOPM_COUNT                        1\n#define IOPM_SIZE                         8192\n#define IOPM_FULL_SIZE                    8196\n#define IOPM_ACCESS_MAP_NONE              0\n#define IOPM_DIRECTION_MAP_SIZE           32\n\n/* Static Kernel-Mode address start */\n#define KSEG0_BASE                        0x80000000\n\n/* XTOS Kernel stack size */\n#define KERNEL_STACK_SIZE                 0x4000\n#define KERNEL_STACKS                     3\n\n/* XTOS Kernel stack guard pages */\n#define KERNEL_STACK_GUARD_PAGES          1\n\n/* Processor structures size */\n#define KPROCESSOR_STRUCTURES_SIZE        ((KERNEL_STACKS * KERNEL_STACK_SIZE) + (GDT_ENTRIES * sizeof(KGDTENTRY)) + \\\n                                          sizeof(KTSS) + sizeof(KPROCESSOR_BLOCK) + MM_PAGE_SIZE)\n\n/* Kernel frames */\n#define KTRAP_FRAME_ALIGN                 0x08\n#define KTRAP_FRAME_SIZE                  sizeof(KTRAP_FRAME)\n#define NPX_FRAME_SIZE                    0x210\n\n/* Number of supported extensions */\n#define MAXIMUM_SUPPORTED_EXTENSION       512\n\n/* Return address size pushed by 'call' instruction */\n#define KRETURN_ADDRESS_SIZE              0x4\n\n/* Size of 387 registers */\n#define SIZE_OF_80387_REGISTERS           80\n#define SIZE_OF_FX_REGISTERS              128\n\n/* NPX state definitions */\n#define NPX_STATE_LOADED                  0x0\n#define NPX_STATE_UNLOADED                0xA\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Floating point state storing structure */\ntypedef struct _FN_SAVE_FORMAT\n{\n    ULONG ControlWord;\n    ULONG StatusWord;\n    ULONG TagWord;\n    ULONG ErrorOffset;\n    ULONG ErrorSelector;\n    ULONG DataOffset;\n    ULONG DataSelector;\n    UCHAR RegisterArea[SIZE_OF_80387_REGISTERS];\n    ULONG Cr0NpxState;\n} FN_SAVE_FORMAT, *PFN_SAVE_FORMAT;\n\n/* Data for FXSAVE/FXRSTOR instructions structure definition */\ntypedef struct _FX_SAVE_FORMAT\n{\n    USHORT ControlWord;\n    USHORT StatusWord;\n    USHORT TagWord;\n    USHORT ErrorOpcode;\n    ULONG ErrorOffset;\n    ULONG ErrorSelector;\n    ULONG DataOffset;\n    ULONG DataSelector;\n    ULONG MxCsr;\n    ULONG MxCsrMask;\n    UCHAR RegisterArea[SIZE_OF_FX_REGISTERS];\n    UCHAR Reserved3[SIZE_OF_FX_REGISTERS];\n    UCHAR Reserved4[224];\n    UCHAR Align16Byte[8];\n} FX_SAVE_FORMAT, *PFX_SAVE_FORMAT;\n\n/* Floating save area structure definition */\ntypedef struct _FX_SAVE_AREA\n{\n    union\n    {\n        FN_SAVE_FORMAT FnArea;\n        FX_SAVE_FORMAT FxArea;\n    };\n    ULONG NpxSavedCpu;\n    ULONG Cr0NpxState;\n} FX_SAVE_AREA, *PFX_SAVE_AREA;\n\n/* Context frame structure definition */\ntypedef struct _CONTEXT\n{\n    ULONG ContextFlags;\n    ULONG Dr0;\n    ULONG Dr1;\n    ULONG Dr2;\n    ULONG Dr3;\n    ULONG Dr6;\n    ULONG Dr7;\n    FN_SAVE_FORMAT FloatSave;\n    ULONG SegGs;\n    ULONG SegFs;\n    ULONG SegEs;\n    ULONG SegDs;\n    ULONG Edi;\n    ULONG Esi;\n    ULONG Ebx;\n    ULONG Edx;\n    ULONG Ecx;\n    ULONG Eax;\n    ULONG Ebp;\n    ULONG Eip;\n    ULONG SegCs;\n    ULONG EFlags;\n    ULONG Esp;\n    ULONG SegSs;\n    UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];\n} CONTEXT, *PCONTEXT;\n\n/* Pseudo descriptor structure definition */\ntypedef struct _KDESCRIPTOR\n{\n    USHORT Pad;\n    USHORT Limit;\n    PVOID Base;\n} KDESCRIPTOR, *PKDESCRIPTOR;\n\n/* Global Descriptor Table (GDT) entry structure definition */\ntypedef struct _KGDTENTRY\n{\n    USHORT LimitLow;\n    USHORT BaseLow;\n    union\n    {\n        struct\n        {\n            UCHAR BaseMiddle;\n            UCHAR Flags1;\n            UCHAR Flags2;\n            UCHAR BaseHigh;\n        } Bytes;\n        struct\n        {\n            ULONG BaseMiddle:8;\n            ULONG Type:5;\n            ULONG Dpl:2;\n            ULONG Present:1;\n            ULONG LimitHigh:4;\n            ULONG System:1;\n            ULONG Reserved0:1;\n            ULONG DefaultBig:1;\n            ULONG Granularity:1;\n            ULONG BaseHigh:8;\n        } Bits;\n    };\n} KGDTENTRY, *PKGDTENTRY;\n\n/* Interrupt Descriptor Table (IDT) entry structure definition */\ntypedef struct _KIDTENTRY\n{\n    USHORT Offset;\n    USHORT Selector;\n    union\n    {\n        struct\n        {\n            UCHAR Reserved;\n            UCHAR Type:4;\n            UCHAR Flag:1;\n            UCHAR Dpl:2;\n            UCHAR Present:1;\n        };\n        USHORT Access;\n    };\n    USHORT ExtendedOffset;\n} KIDTENTRY, *PKIDTENTRY;\n\n/* Interrupt direction access map structure definition */\ntypedef struct _KIIO_ACCESS_MAP\n{\n    UCHAR DirectionMap[IOPM_DIRECTION_MAP_SIZE];\n    UCHAR IoMap[IOPM_FULL_SIZE];\n} KIIO_ACCESS_MAP, *PKIIO_ACCESS_MAP;\n\n/* Task State Segment (TSS) structure definition */\ntypedef struct _KTSS\n{\n    USHORT Backlink;\n    USHORT Reserved0;\n    ULONG Esp0;\n    USHORT Ss0;\n    USHORT Reserved1;\n    ULONG NotUsed1[4];\n    ULONG CR3;\n    ULONG Eip;\n    ULONG EFlags;\n    ULONG Eax;\n    ULONG Ecx;\n    ULONG Edx;\n    ULONG Ebx;\n    ULONG Esp;\n    ULONG Ebp;\n    ULONG Esi;\n    ULONG Edi;\n    USHORT Es;\n    USHORT Reserved2;\n    USHORT Cs;\n    USHORT Reserved3;\n    USHORT Ss;\n    USHORT Reserved4;\n    USHORT Ds;\n    USHORT Reserved5;\n    USHORT Fs;\n    USHORT Reserved6;\n    USHORT Gs;\n    USHORT Reserved7;\n    USHORT LDT;\n    USHORT Reserved8;\n    USHORT Flags;\n    USHORT IoMapBase;\n    KIIO_ACCESS_MAP IoMaps[IOPM_COUNT];\n    UCHAR IntDirectionMap[IOPM_DIRECTION_MAP_SIZE];\n} KTSS, *PKTSS;\n\n/* Exception frame definition (not available on i686) */\ntypedef struct _KEXCEPTION_FRAME\n{\n    ULONG Ebp;\n    ULONG Ebx;\n    ULONG Edi;\n    ULONG Esi;\n    ULONG Return;\n} KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;\n\n/* Thread start frame definition */\ntypedef struct _KSTART_FRAME\n{\n    PKSYSTEM_ROUTINE SystemRoutine;\n    PKSTART_ROUTINE StartRoutine;\n    PVOID StartContext;\n    BOOLEAN UserMode;\n} KSTART_FRAME, *PKSTART_FRAME;\n\n/* Switch frame definition */\ntypedef struct _KSWITCH_FRAME\n{\n    PVOID ExceptionList;\n    BOOLEAN ApcBypassDisabled;\n    PVOID Return;\n} KSWITCH_FRAME, *PKSWITCH_FRAME;\n\n/* Trap frame definition */\ntypedef struct _KTRAP_FRAME\n{\n    ULONG PreviousMode;\n    ULONG Cr2;\n    ULONG Cr3;\n    ULONG Dr0;\n    ULONG Dr1;\n    ULONG Dr2;\n    ULONG Dr3;\n    ULONG Dr6;\n    ULONG Dr7;\n    USHORT SegDs;\n    USHORT SegEs;\n    USHORT SegFs;\n    USHORT SegGs;\n    ULONG Eax;\n    ULONG Ebx;\n    ULONG Ecx;\n    ULONG Edx;\n    ULONG Esi;\n    ULONG Edi;\n    ULONG Ebp;\n    ULONG Vector;\n    ULONG ErrorCode;\n    ULONG Eip;\n    ULONG SegCs;\n    ULONG Flags;\n    ULONG Esp;\n    ULONG SegSs;\n} KTRAP_FRAME, *PKTRAP_FRAME;\n\n/* Thread initialization frame definition */\ntypedef struct _KTHREAD_INIT_FRAME\n{\n    KSWITCH_FRAME SwitchFrame;\n    KSTART_FRAME StartFrame;\n    KTRAP_FRAME TrapFrame;\n    FX_SAVE_AREA NpxFrame;\n} KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME;\n\n/* Special kernel registers structure definition */\ntypedef struct _KSPECIAL_REGISTERS\n{\n    ULONG Cr0;\n    ULONG Cr2;\n    ULONG Cr3;\n    ULONG Cr4;\n    ULONG KernelDr0;\n    ULONG KernelDr1;\n    ULONG KernelDr2;\n    ULONG KernelDr3;\n    ULONG KernelDr6;\n    ULONG KernelDr7;\n    KDESCRIPTOR Gdtr;\n    KDESCRIPTOR Idtr;\n    USHORT Tr;\n    USHORT Ldtr;\n    ULONG Reserved[6];\n} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;\n\n/* Processor start block structure definition */\ntypedef struct _PROCESSOR_START_BLOCK\n{\n    ULONG_PTR Cr3;\n    ULONG_PTR Cr4;\n    PVOID EntryPoint;\n    PVOID ProcessorStructures;\n    PVOID Stack;\n    BOOLEAN Started;\n} PROCESSOR_START_BLOCK, *PPROCESSOR_START_BLOCK;\n\n/* Processor state frame structure definition */\ntypedef struct _KPROCESSOR_STATE\n{\n    CONTEXT ContextFrame;\n    KSPECIAL_REGISTERS SpecialRegisters;\n} KPROCESSOR_STATE, *PKPROCESSOR_STATE;\n\n/* Processor Control Block (PRCB) structure definition */\ntypedef struct _KPROCESSOR_CONTROL_BLOCK\n{\n    PKTHREAD CurrentThread;\n    PKTHREAD IdleThread;\n    PKTHREAD NextThread;\n    UCHAR CpuNumber;\n    ULONG_PTR SetMember;\n    CPU_IDENTIFICATION CpuId;\n    KPROCESSOR_STATE ProcessorState;\n    KSPIN_LOCK_QUEUE LockQueue[MaximumLock];\n    ULONG_PTR MultiThreadProcessorSet;\n    KDPC_DATA DpcData[2];\n    PVOID DpcStack;\n    VOLATILE BOOLEAN DpcRoutineActive;\n    VOLATILE ULONG_PTR TimerRequest;\n    SINGLE_LIST_ENTRY DeferredReadyListHead;\n    PROCESSOR_POWER_STATE PowerState;\n    ULONG ProfilingCountdown;\n} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;\n\n/* Processor Block structure definition */\ntypedef struct _KPROCESSOR_BLOCK\n{\n    union\n    {\n        THREAD_INFORMATION_BLOCK ThreadInformationBlock;\n        struct\n        {\n            PKGDTENTRY GdtBase;\n            PKTSS TssBase;\n            PKPROCESSOR_BLOCK Self;\n            PKPROCESSOR_CONTROL_BLOCK CurrentPrcb;\n        };\n    };\n    PKIDTENTRY IdtBase;\n    KRUNLEVEL RunLevel;\n    KPROCESSOR_CONTROL_BLOCK Prcb;\n    ULONG Irr;\n    ULONG IrrActive;\n    ULONG Idr;\n    ULONG ContextSwitches;\n    KAFFINITY SetMember;\n    ULONG StallScaleFactor;\n    UCHAR CpuNumber;\n    ULONG HardwareId;\n    VOLATILE BOOLEAN Started;\n    PINTERRUPT_HANDLER InterruptDispatchTable[256];\n} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;\n\n/* Thread Environment Block (TEB) structure definition */\ntypedef struct _THREAD_ENVIRONMENT_BLOCK\n{\n    THREAD_INFORMATION_BLOCK InformationBlock;\n} THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_I686_KETYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/i686/mmtypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/i686/mmtypes.h\n * DESCRIPTION:     Memory management data structures for i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_I686_MMTYPES_H\n#define __XTDK_I686_MMTYPES_H\n\n#include <xtbase.h>\n#include <mmtypes.h>\n\n\n/* Pages related definitions */\n#define MM_PAGE_MASK                               (MM_PAGE_SIZE - 1)\n#define MM_PAGE_SHIFT                              12\n#define MM_PAGE_SIZE                               4096\n\n/* Page directory and page base addresses */\n#define MM_PTE_BASE                                0xC0000000\n#define MM_PDE_BASE                                0xC0600000\n\n/* PTE shift values */\n#define MM_PTE_SHIFT                               3\n#define MM_PTI_SHIFT                               12\n#define MM_PDI_SHIFT                               21\n#define MM_PPI_SHIFT                               30\n\n/* Page directory and page base legacy address */\n#define MM_PDE_LEGACY_BASE                         0xC0300000\n\n/* PTE legacy shift values */\n#define MM_PTE_LEGACY_SHIFT                        2\n#define MM_PDI_LEGACY_SHIFT                        22\n\n/* PTE state flags */\n#define MM_PTE_VALID                               0x00000001\n#define MM_PTE_ACCESSED                            0x00000020\n#define MM_PTE_DIRTY                               0x00000040\n\n/* PTE scope flags */\n#define MM_PTE_LARGE_PAGE                          0x00000080\n#define MM_PTE_GLOBAL                              0x00000100\n\n/* PTE access flags */\n#define MM_PTE_NOACCESS                            0x00000000\n#define MM_PTE_READONLY                            0x00000000\n#define MM_PTE_EXECUTE                             0x00000000\n#define MM_PTE_EXECUTE_READ                        0x00000000\n#define MM_PTE_READWRITE                           0x00000002\n#define MM_PTE_WRITECOPY                           0x00000200\n#define MM_PTE_EXECUTE_READWRITE                   0x00000002\n#define MM_PTE_EXECUTE_WRITECOPY                   0x00000200\n\n/* PTE protection flags */\n#define MM_PTE_NOEXECUTE                           0x00000000\n#define MM_PTE_GUARDED                             0x00000018\n#define MM_PTE_PROTECT                             0x00000612\n\n/* PTE cache flags */\n#define MM_PTE_CACHE_ENABLE                        0x00000000\n#define MM_PTE_CACHE_DISABLE                       0x00000010\n#define MM_PTE_CACHE_WRITECOMBINED                 0x00000010\n#define MM_PTE_CACHE_WRITETHROUGH                  0x00000008\n\n/* PTE software flags */\n#define MM_PTE_COPY_ON_WRITE                       0x00000200\n#define MM_PTE_PROTOTYPE                           0x00000400\n#define MM_PTE_TRANSITION                          0x00000800\n\n/* PTE frame bits */\n#define MM_PTE_FRAME_BITS                          25\n\n/* PTE protection bits */\n#define MM_PTE_PROTECTION_BITS                     5\n\n/* Base address of the system page table */\n#define MM_SYSTEM_PTE_BASE                         NULLPTR\n\n/* Minimum number of physical pages needed by the system */\n#define MM_MINIMUM_PHYSICAL_PAGES                  1100\n\n/* Number of system PTEs */\n#define MM_MINIMUM_NUMBER_SYSTEM_PTES              7000\n#define MM_DEFAULT_NUMBER_SYSTEM_PTES              11000\n#define MM_MAXIMUM_NUMBER_SYSTEM_PTES              22000\n\n/* Default number of secondary colors */\n#define MM_DEFAULT_SECONDARY_COLORS                64\n\n/* Number of HAL allocation descriptors */\n#define MM_HARDWARE_ALLOCATION_DESCRIPTORS         64\n\n/* Kernel HAL heap initial start address */\n#define MM_HARDWARE_HEAP_START_ADDRESS             ((PVOID)(((ULONG_PTR)MM_HARDWARE_VA_START) + 1024 * 1024))\n\n/* HAL memory pool virtual address start */\n#define MM_HARDWARE_VA_START                       0xFFC00000\n\n/* Kernel shared data address */\n#define MM_KERNEL_SHARED_DATA_ADDRESS              0xFFDF0000\n\n/* Maximum physical address used by HAL allocations */\n#define MM_MAXIMUM_PHYSICAL_ADDRESS                0xFFFFFFFF\n\n/* Highest system address */\n#define MM_HIGHEST_SYSTEM_ADDRESS                  0xFFFFFFFF\n\n/* Trampoline code address */\n#define MM_TRAMPOLINE_ADDRESS                      0x80000\n\n/* Pool block size */\n#define MM_POOL_BLOCK_SIZE                         8\n\n/* Number of pool lists per page */\n#define MM_POOL_LISTS_PER_PAGE                     (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)\n\n/* Number of pool tracking tables */\n#define MM_POOL_TRACKING_TABLES                    32\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Page size enumeration list */\ntypedef enum _PAGE_SIZE\n{\n    Size4K,\n    Size2M,\n    Size4M\n} PAGE_SIZE, *PPAGE_SIZE;\n\n/* Legacy Page Table entry structure definition (PML2) */\ntypedef struct _HARDWARE_LEGACY_PTE\n{\n    ULONG Valid:1;\n    ULONG Writable:1;\n    ULONG Owner:1;\n    ULONG WriteThrough:1;\n    ULONG CacheDisable:1;\n    ULONG Accessed:1;\n    ULONG Dirty:1;\n    ULONG LargePage:1;\n    ULONG Global:1;\n    ULONG CopyOnWrite:1;\n    ULONG Prototype:1;\n    ULONG Reserved0:1;\n    ULONG PageFrameNumber:20;\n} HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;\n\n/* Page Table entry structure definition (PML3) */\ntypedef struct _HARDWARE_MODERN_PTE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Writable:1;\n    ULONGLONG Owner:1;\n    ULONGLONG WriteThrough:1;\n    ULONGLONG CacheDisable:1;\n    ULONGLONG Accessed:1;\n    ULONGLONG Dirty:1;\n    ULONGLONG LargePage:1;\n    ULONGLONG Global:1;\n    ULONGLONG CopyOnWrite:1;\n    ULONGLONG Prototype:1;\n    ULONGLONG Reserved0:1;\n    ULONGLONG PageFrameNumber:26;\n    ULONGLONG Reserved1:14;\n    ULONGLONG SoftwareWsIndex:11;\n    ULONGLONG NoExecute:1;\n} HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;\n\n/* Generic Page Table entry union to abstract PML2 and PML3 formats */\ntypedef union _HARDWARE_PTE\n{\n    HARDWARE_LEGACY_PTE Pml2;\n    HARDWARE_MODERN_PTE Pml3;\n} HARDWARE_PTE, *PHARDWARE_PTE;\n\n/* Page map information structure definition */\ntypedef struct _MMPAGEMAP_INFO\n{\n    BOOLEAN Xpa;\n    ULONG PteBase;\n    ULONG PdeBase;\n    ULONG PdiShift;\n    ULONG PteShift;\n} MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;\n\n/* Legacy Page Table Entry hardware structure definition (PML2) */\ntypedef struct _MMPML2_PTE_HARDWARE\n{\n    ULONG Valid:1;\n    ULONG Writable:1;\n    ULONG Owner:1;\n    ULONG WriteThrough:1;\n    ULONG CacheDisable:1;\n    ULONG Accessed:1;\n    ULONG Dirty:1;\n    ULONG LargePage:1;\n    ULONG Global:1;\n    ULONG CopyOnWrite:1;\n    ULONG Prototype:1;\n    ULONG Write:1;\n    ULONG PageFrameNumber:20;\n} MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE;\n\n/* Legacy Page Table Entry list structure definition (PML2) */\ntypedef struct _MMPML2_PTE_LIST\n{\n    ULONG Valid:1;\n    ULONG OneEntry:1;\n    ULONG Reserved0:8;\n    ULONG Prototype:1;\n    ULONG Reserved1:1;\n    ULONG NextEntry:20;\n} MMPML2_PTE_LIST, *PMMPML2_PTE_LIST;\n\n/* Legacy Page Table Entry subsection structure definition (PML2) */\ntypedef struct _MMPML2_PTE_PROTOTYPE\n{\n    ULONG Valid:1;\n    ULONG ProtoAddressLow:7;\n    ULONG ReadOnly:1;\n    ULONG WhichPool:1;\n    ULONG Prototype:1;\n    ULONG ProtoAddressHigh:21;\n} MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE;\n\n/* Legacy Page Table Entry software structure definition (PML2) */\ntypedef struct _MMPML2_PTE_SOFTWARE\n{\n    ULONG Valid:1;\n    ULONG PageFileLow:4;\n    ULONG Protection:5;\n    ULONG Prototype:1;\n    ULONG Transition:1;\n    ULONG PageFileHigh:20;\n} MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE;\n\n/* Legacy Page Table Entry subsection structure definition (PML2) */\ntypedef struct _MMPML2_PTE_SUBSECTION\n{\n    ULONG Valid:1;\n    ULONG SubsectionAddressLow:4;\n    ULONG Protection:5;\n    ULONG Prototype:1;\n    ULONG SubsectionAddressHigh:20;\n    ULONG WhichPool:1;\n} MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION;\n\n/* Legacy Page Table Entry transition structure definition (PML2) */\ntypedef struct _MMPML2_PTE_TRANSITION\n{\n    ULONG Valid:1;\n    ULONG Write:1;\n    ULONG Owner:1;\n    ULONG WriteThrough:1;\n    ULONG CacheDisable:1;\n    ULONG Protection:5;\n    ULONG Prototype:1;\n    ULONG Transition:1;\n    ULONG PageFrameNumber:20;\n} MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION;\n\n/* Legacy Page Table Entry union definition (PML2) */\ntypedef union _MMPML2_PTE\n{\n    ULONG Long;\n    HARDWARE_LEGACY_PTE Flush;\n    MMPML2_PTE_HARDWARE Hardware;\n    MMPML2_PTE_PROTOTYPE Prototype;\n    MMPML2_PTE_SOFTWARE Software;\n    MMPML2_PTE_TRANSITION Transition;\n    MMPML2_PTE_SUBSECTION Subsection;\n    MMPML2_PTE_LIST List;\n} MMPML2_PTE, *PMMPML2_PTE;\n\n/* Page Table Entry hardware structure definition (PML3) */\ntypedef struct _MMPML3_PTE_HARDWARE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Writable:1;\n    ULONGLONG Owner:1;\n    ULONGLONG WriteThrough:1;\n    ULONGLONG CacheDisable:1;\n    ULONGLONG Accessed:1;\n    ULONGLONG Dirty:1;\n    ULONGLONG LargePage:1;\n    ULONGLONG Global:1;\n    ULONGLONG CopyOnWrite:1;\n    ULONGLONG Prototype:1;\n    ULONGLONG Write:1;\n    ULONGLONG PageFrameNumber:26;\n    ULONGLONG Reserved0:25;\n    ULONGLONG NoExecute:1;\n} MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE;\n\n/* Page Table Entry list structure definition (PML3) */\ntypedef struct _MMPML3_PTE_LIST\n{\n    ULONGLONG Valid:1;\n    ULONGLONG OneEntry:1;\n    ULONGLONG Reserved0:8;\n    ULONGLONG Prototype:1;\n    ULONGLONG Reserved1:21;\n    ULONGLONG NextEntry:32;\n} MMPML3_PTE_LIST, *PMMPML3_PTE_LIST;\n\n/* Page Table Entry subsection structure definition (PML3) */\ntypedef struct _MMPML3_PTE_PROTOTYPE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Reserved0:7;\n    ULONGLONG ReadOnly:1;\n    ULONGLONG Reserved1:1;\n    ULONGLONG Prototype:1;\n    ULONGLONG Protection:5;\n    ULONGLONG Reserved2:16;\n    ULONGLONG ProtoAddress:32;\n} MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE;\n\n/* Page Table Entry software structure definition (PML3) */\ntypedef struct _MMPML3_PTE_SOFTWARE\n{\n    ULONGLONG Valid:1;\n    ULONGLONG PageFileLow:4;\n    ULONGLONG Protection:5;\n    ULONGLONG Prototype:1;\n    ULONGLONG Transition:1;\n    ULONGLONG Reserved0:20;\n    ULONGLONG PageFileHigh:32;\n} MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;\n\n/* Page Table Entry subsection structure definition (PML3) */\ntypedef struct _MMPML3_PTE_SUBSECTION\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Reserved0:4;\n    ULONGLONG Protection:5;\n    ULONGLONG Prototype:1;\n    ULONGLONG Reserved1:21;\n    ULONGLONG SubsectionAddress:32;\n} MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;\n\n/* Page Table Entry transition structure definition (PML3) */\ntypedef struct _MMPML3_PTE_TRANSITION\n{\n    ULONGLONG Valid:1;\n    ULONGLONG Write:1;\n    ULONGLONG Owner:1;\n    ULONGLONG WriteThrough:1;\n    ULONGLONG CacheDisable:1;\n    ULONGLONG Protection:5;\n    ULONGLONG Prototype:1;\n    ULONGLONG Transition:1;\n    ULONGLONG PageFrameNumber:26;\n    ULONGLONG Unused:26;\n} MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;\n\n/* Page Table Entry union definition (PML3) */\ntypedef union _MMPML3_PTE\n{\n    ULONGLONG Long;\n    HARDWARE_MODERN_PTE Flush;\n    MMPML3_PTE_HARDWARE Hardware;\n    MMPML3_PTE_PROTOTYPE Prototype;\n    MMPML3_PTE_SOFTWARE Software;\n    MMPML3_PTE_TRANSITION Transition;\n    MMPML3_PTE_SUBSECTION Subsection;\n    MMPML3_PTE_LIST List;\n} MMPML3_PTE, *PMMPML3_PTE;\n\n/* Generic Page Table Entry union to abstract PML2 and PML3 formats */\ntypedef union _MMPTE\n{\n    MMPML2_PTE Pml2;\n    MMPML3_PTE Pml3;\n} MMPTE, *PMMPTE;\n\n/* Page Frame Number structure definition */\ntypedef struct _MMPFN\n{\n    union\n    {\n        PFN_NUMBER Flink;\n        ULONG WsIndex;\n        PKEVENT Event;\n        XTSTATUS ReadStatus;\n        SINGLE_LIST_ENTRY NextStackPfn;\n    } u1;\n    PMMPTE PteAddress;\n    union\n    {\n        PFN_NUMBER Blink;\n        ULONG_PTR ShareCount;\n    } u2;\n    union\n    {\n        MMPFNENTRY e1;\n        struct\n        {\n            USHORT ShortFlags;\n            USHORT ReferenceCount;\n        } e2;\n    } u3;\n    ULONG UsedPageTableEntries;\n    union\n    {\n        MMPTE OriginalPte;\n        LONG AweReferenceCount;\n    };\n    union\n    {\n        ULONG_PTR EntireFrame;\n        struct\n        {\n            ULONG_PTR PteFrame:25;\n            ULONG_PTR InPageError:1;\n            ULONG_PTR VerifierAllocation:1;\n            ULONG_PTR AweAllocation:1;\n            ULONG_PTR Priority:3;\n            ULONG_PTR MustBeCached:1;\n        };\n    } u4;\n} MMPFN, *PMMPFN;\n\n/* Pool descriptor structure definition */\ntypedef struct _POOL_DESCRIPTOR\n{\n    LIST_ENTRY ListHeads[MM_POOL_LISTS_PER_PAGE];\n    PVOID LockAddress;\n    ULONG PoolIndex;\n    LONG PendingFreeDepth;\n    PVOID PendingFrees;\n    MMPOOL_TYPE PoolType;\n    ULONG RunningFrees;\n    ULONG RunningAllocations;\n    ULONG Threshold;\n    ULONG TotalPages;\n    ULONG TotalBigAllocations;\n    SIZE_T TotalBytes;\n    SIZE_T Reserved;\n} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_I686_MMTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/i686/xtstruct.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/i686/xtstruct.h\n * DESCRIPTION:     XT structures forward references specific to i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_I686_XTSTRUCT_H\n#define __XTDK_I686_XTSTRUCT_H\n\n#include <xtdefs.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Architecture-specific enumeration lists forward references */\ntypedef enum _APIC_DEST_MODE APIC_DEST_MODE, *PAPIC_DEST_MODE;\ntypedef enum _APIC_DM APIC_DM, *PAPIC_DM;\ntypedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;\ntypedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;\ntypedef enum _APIC_REGISTER APIC_REGISTER, *PAPIC_REGISTER;\ntypedef enum _APIC_TIMER_DIVISOR APIC_TIMER_DIVISOR, *PAPIC_TIMER_DIVISOR;\ntypedef enum _CPU_VENDOR CPU_VENDOR, *PCPU_VENDOR;\ntypedef enum _CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT CPUID_FEATURES_ADVANCED_POWER_MANAGEMENT, *PCPUID_FEATURES_ADVANCED_POWER_MANAGEMENT;\ntypedef enum _CPUID_FEATURES_EXTENDED CPUID_FEATURES_EXTENDED, *PCPUID_FEATURES_EXTENDED;\ntypedef enum _CPUID_FEATURES_POWER_MANAGEMENT CPUID_FEATURES_POWER_MANAGEMENT, *PCPUID_FEATURES_POWER_MANAGEMENT;\ntypedef enum _CPUID_FEATURES_STANDARD1 CPUID_FEATURES_STANDARD1, *PCPUID_FEATURES_STANDARD1;\ntypedef enum _CPUID_FEATURES_STANDARD7_LEAF0 CPUID_FEATURES_STANDARD7_LEAF0, *PCPUID_FEATURES_STANDARD7_LEAF0;\ntypedef enum _CPUID_FEATURES_STANDARD7_LEAF1 CPUID_FEATURES_STANDARD7_LEAF1, *PCPUID_FEATURES_STANDARD7_LEAF1;\ntypedef enum _CPUID_REQUESTS CPUID_REQUESTS, *PCPUID_REQUESTS;\ntypedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE;\ntypedef enum _PIC_I8259_ICW1_INTERRUPT_MODE PIC_I8259_ICW1_INTERRUPT_MODE, *PPIC_I8259_ICW1_INTERRUPT_MODE;\ntypedef enum _PIC_I8259_ICW1_INTERVAL PIC_I8259_ICW1_INTERVAL, *PPIC_I8259_ICW1_INTERVAL;\ntypedef enum _PIC_I8259_ICW1_OPERATING_MODE PIC_I8259_ICW1_OPERATING_MODE, *PPIC_I8259_ICW1_OPERATING_MODE;\ntypedef enum _PIC_I8259_ICW4_BUFFERED_MODE PIC_I8259_ICW4_BUFFERED_MODE, *PPIC_I8259_ICW4_BUFFERED_MODE;\ntypedef enum _PIC_I8259_ICW4_EOI_MODE PIC_I8259_ICW4_EOI_MODE, *PPIC_I8259_ICW4_EOI_MODE;\ntypedef enum _PIC_I8259_ICW4_SYSTEM_MODE PIC_I8259_ICW4_SYSTEM_MODE, *PPIC_I8259_ICW4_SYSTEM_MODE;\ntypedef enum _TIMER_TYPE TIMER_TYPE, *PTIMER_TYPE;\ntypedef enum _TRAMPOLINE_TYPE TRAMPOLINE_TYPE, *PTRAMPOLINE_TYPE;\n\n/* Architecture-specific structures forward references */\ntypedef struct _CONTEXT CONTEXT, *PCONTEXT;\ntypedef struct _CPU_IDENTIFICATION CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;\ntypedef struct _CPUID_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS;\ntypedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;\ntypedef struct _FN_SAVE_FORMAT FN_SAVE_FORMAT, *PFN_SAVE_FORMAT;\ntypedef struct _FX_SAVE_AREA FX_SAVE_AREA, *PFX_SAVE_AREA;\ntypedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT;\ntypedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;\ntypedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;\ntypedef struct _HPET_REGISTERS HPET_REGISTERS, *PHPET_REGISTERS;\ntypedef struct _IOAPIC_DATA IOAPIC_DATA, *PIOAPIC_DATA;\ntypedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;\ntypedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;\ntypedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;\ntypedef struct _KIDTENTRY KIDTENTRY, *PKIDTENTRY;\ntypedef struct _KIIO_ACCESS_MAP KIIO_ACCESS_MAP, *PKIIO_ACCESS_MAP;\ntypedef struct _KPROCESSOR_BLOCK KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;\ntypedef struct _KPROCESSOR_CONTROL_BLOCK KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK;\ntypedef struct _KPROCESSOR_STATE KPROCESSOR_STATE, *PKPROCESSOR_STATE;\ntypedef struct _KSPECIAL_REGISTERS KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;\ntypedef struct _KSTART_FRAME KSTART_FRAME, *PKSTART_FRAME;\ntypedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME;\ntypedef struct _KTHREAD_INIT_FRAME KTHREAD_INIT_FRAME, *PKTHREAD_INIT_FRAME;\ntypedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME;\ntypedef struct _KTSS KTSS, *PKTSS;\ntypedef struct _MMPAGEMAP_INFO MMPAGEMAP_INFO, *PMMPAGEMAP_INFO;\ntypedef struct _MMPFN MMPFN, *PMMPFN;\ntypedef struct _MMPML2_PTE_HARDWARE MMPML2_PTE_HARDWARE, *PMMPML2_PTE_HARDWARE;\ntypedef struct _MMPML2_PTE_LIST MMPML2_PTE_LIST, *PMMPML2_PTE_LIST;\ntypedef struct _MMPML2_PTE_PROTOTYPE MMPML2_PTE_PROTOTYPE, *PMMPML2_PTE_PROTOTYPE;\ntypedef struct _MMPML2_PTE_SOFTWARE MMPML2_PTE_SOFTWARE, *PMMPML2_PTE_SOFTWARE;\ntypedef struct _MMPML2_PTE_SUBSECTION MMPML2_PTE_SUBSECTION, *PMMPML2_PTE_SUBSECTION;\ntypedef struct _MMPML2_PTE_TRANSITION MMPML2_PTE_TRANSITION, *PMMPML2_PTE_TRANSITION;\ntypedef struct _MMPML3_PTE_HARDWARE MMPML3_PTE_HARDWARE, *PMMPML3_PTE_HARDWARE;\ntypedef struct _MMPML3_PTE_LIST MMPML3_PTE_LIST, *PMMPML3_PTE_LIST;\ntypedef struct _MMPML3_PTE_PROTOTYPE MMPML3_PTE_PROTOTYPE, *PMMPML3_PTE_PROTOTYPE;\ntypedef struct _MMPML3_PTE_SOFTWARE MMPML3_PTE_SOFTWARE, *PMMPML3_PTE_SOFTWARE;\ntypedef struct _MMPML3_PTE_SUBSECTION MMPML3_PTE_SUBSECTION, *PMMPML3_PTE_SUBSECTION;\ntypedef struct _MMPML3_PTE_TRANSITION MMPML3_PTE_TRANSITION, *PMMPML3_PTE_TRANSITION;\ntypedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;\ntypedef struct _THREAD_ENVIRONMENT_BLOCK THREAD_ENVIRONMENT_BLOCK, *PTHREAD_ENVIRONMENT_BLOCK;\ntypedef struct _TIMER_CAPABILITIES TIMER_CAPABILITIES, *PTIMER_CAPABILITIES;\n\n/* Unions forward references */\ntypedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;\ntypedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;\ntypedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;\ntypedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;\ntypedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;\ntypedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;\ntypedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE;\ntypedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;\ntypedef union _MMPTE MMPDE, *PMMPDE;\ntypedef union _MMPTE MMPPE, *PMMPPE;\ntypedef union _MMPTE MMPTE, *PMMPTE;\ntypedef union _PIC_I8259_ICW1 PIC_I8259_ICW1, *PPIC_I8259_ICW1;\ntypedef union _PIC_I8259_ICW2 PIC_I8259_ICW2, *PPIC_I8259_ICW2;\ntypedef union _PIC_I8259_ICW3 PIC_I8259_ICW3, *PPIC_I8259_ICW3;\ntypedef union _PIC_I8259_ICW4 PIC_I8259_ICW4, *PPIC_I8259_ICW4;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_I686_XTSTRUCT_H */\n"
  },
  {
    "path": "sdk/xtdk/iotypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/iotypes.h\n * DESCRIPTION:     I/O related type definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_IOTYPES_H\n#define __XTDK_IOTYPES_H\n\n#include <xttypes.h>\n\n\n/* Number of PCI base address registers */\n#define PCI_TYPE0_ADDRESSES                     6\n#define PCI_TYPE1_ADDRESSES                     2\n#define PCI_TYPE2_ADDRESSES                     5\n\n/* PCI maximum number of devices */\n#define PCI_MAX_BRIDGE_NUMBER                   255\n#define PCI_MAX_DEVICES                         32\n#define PCI_MAX_FUNCTION                        8\n\n/* Invalid PCI vendor ID */\n#define PCI_INVALID_VENDORID                    0xFFFF\n\n/* PCI common config header types */\n#define PCI_DEVICE_TYPE                         0x00\n#define PCI_BRIDGE_TYPE                         0x01\n#define PCI_CARDBUS_BRIDGE_TYPE                 0x02\n#define PCI_MULTIFUNCTION                       0x80\n\n/* PCI common config commands */\n#define PCI_ENABLE_IO_SPACE                     0x0001\n#define PCI_ENABLE_MEMORY_SPACE                 0x0002\n#define PCI_ENABLE_BUS_MASTER                   0x0004\n#define PCI_ENABLE_SPECIAL_CYCLES               0x0008\n#define PCI_ENABLE_WRITE_AND_INVALIDATE         0x0010\n#define PCI_ENABLE_VGA_COMPATIBLE_PALETTE       0x0020\n#define PCI_ENABLE_PARITY                       0x0040\n#define PCI_ENABLE_WAIT_CYCLE                   0x0080\n#define PCI_ENABLE_SERR                         0x0100\n#define PCI_ENABLE_FAST_BACK_TO_BACK            0x0200\n#define PCI_DISABLE_LEVEL_INTERRUPT             0x0400\n\n/* PCI common config statuses */\n#define PCI_STATUS_INTERRUPT_PENDING            0x0008\n#define PCI_STATUS_CAPABILITIES_LIST            0x0010\n#define PCI_STATUS_66MHZ_CAPABLE                0x0020\n#define PCI_STATUS_UDF_SUPPORTED                0x0040\n#define PCI_STATUS_FAST_BACK_TO_BACK            0x0080\n#define PCI_STATUS_DATA_PARITY_DETECTED         0x0100\n#define PCI_STATUS_DEVSEL                       0x0600\n#define PCI_STATUS_SIGNALED_TARGET_ABORT        0x0800\n#define PCI_STATUS_RECEIVED_TARGET_ABORT        0x1000\n#define PCI_STATUS_RECEIVED_MASTER_ABORT        0x2000\n#define PCI_STATUS_SIGNALED_SYSTEM_ERROR        0x4000\n#define PCI_STATUS_DETECTED_PARITY_ERROR        0x8000\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* PCI bridge control registers */\ntypedef struct _PCI_BRIDGE_CONTROL_REGISTER\n{\n    UINT Bar[2];\n    UCHAR PrimaryBus;\n    UCHAR SecondaryBus;\n    UCHAR SubordinateBus;\n    UCHAR SecondaryLatencyTimer;\n    UCHAR IoBase;\n    UCHAR IoLimit;\n    USHORT SecondaryStatus;\n    USHORT MemoryBase;\n    USHORT MemoryLimit;\n    USHORT PrefetchableMemoryBase;\n    USHORT PrefetchableMemoryLimit;\n    UINT PrefetchableBaseUpper32;\n    UINT PrefetchableLimitUpper32;\n    USHORT IoBaseUpper16;\n    USHORT IoLimitUpper16;\n    UINT Reserved;\n    UINT ExpansionRomBAR;\n    UCHAR InterruptLine;\n    UCHAR InterruptPin;\n    USHORT BridgeControl;\n} PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;\n\n/* PCI and PCI-E common header structure */\ntypedef struct _PCI_COMMON_HEADER\n{\n    USHORT VendorId;\n    USHORT DeviceId;\n    USHORT Command;\n    USHORT Status;\n    UCHAR RevisionId;\n    UCHAR ProgIf;\n    UCHAR SubClass;\n    UCHAR BaseClass;\n    UCHAR CacheLineSize;\n    UCHAR LatencyTimer;\n    UCHAR HeaderType;\n    UCHAR BIST;\n    union\n    {\n        struct _PCI_TYPE0_HEADER\n        {\n            ULONG BaseAddresses[PCI_TYPE0_ADDRESSES];\n            ULONG CIS;\n            USHORT SubVendorId;\n            USHORT SubSystemId;\n            ULONG ROMBaseAddress;\n            UCHAR CapabilitiesPtr;\n            UCHAR Reserved1[3];\n            ULONG Reserved2;\n            UCHAR InterruptLine;\n            UCHAR InterruptPin;\n            UCHAR MinimumGrant;\n            UCHAR MaximumLatency;\n        } type0;\n        struct _PCI_TYPE1_HEADER\n        {\n            ULONG BaseAddresses[PCI_TYPE1_ADDRESSES];\n            UCHAR PrimaryBus;\n            UCHAR SecondaryBus;\n            UCHAR SubordinateBus;\n            UCHAR SecondaryLatency;\n            UCHAR IOBase;\n            UCHAR IOLimit;\n            USHORT SecondaryStatus;\n            USHORT MemoryBase;\n            USHORT MemoryLimit;\n            USHORT PrefetchBase;\n            USHORT PrefetchLimit;\n            ULONG PrefetchBaseUpper32;\n            ULONG PrefetchLimitUpper32;\n            USHORT IOBaseUpper16;\n            USHORT IOLimitUpper16;\n            UCHAR CapabilitiesPtr;\n            UCHAR Reserved1[3];\n            ULONG ROMBaseAddress;\n            UCHAR InterruptLine;\n            UCHAR InterruptPin;\n            USHORT BridgeControl;\n        } type1;\n        struct _PCI_TYPE2_HEADER\n        {\n            ULONG SocketRegistersBaseAddress;\n            UCHAR CapabilitiesPtr;\n            UCHAR Reserved;\n            USHORT SecondaryStatus;\n            UCHAR PrimaryBus;\n            UCHAR SecondaryBus;\n            UCHAR SubordinateBus;\n            UCHAR SecondaryLatency;\n            struct\n            {\n                ULONG Base;\n                ULONG Limit;\n            } Range[PCI_TYPE2_ADDRESSES - 1];\n            UCHAR InterruptLine;\n            UCHAR InterruptPin;\n            USHORT BridgeControl;\n        } type2;\n    } u;\n} PCI_COMMON_HEADER, *PPCI_COMMON_HEADER;\n\n/* PCI and PCI-E common config structure */\ntypedef struct _PCI_COMMON_CONFIG\n{\n    PCI_COMMON_HEADER PciHeader;\n    UCHAR DeviceSpecific[192];\n} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;\n\n/* PCI device header type region structure */\ntypedef struct _PCI_DEVICE_HEADER_TYPE_REGION\n{\n    UINT Bar[6];\n    UINT CISPtr;\n    USHORT SubsystemVendorID;\n    USHORT SubsystemID;\n    UINT ExpansionRomBar;\n    UINT Reserved[2];\n    UCHAR InterruptLine;\n    UCHAR InterruptPin;\n    UCHAR MinGnt;\n    UCHAR MaxLat;\n} PCI_DEVICE_HEADER_TYPE_REGION, *PPCI_DEVICE_HEADER_TYPE_REGION;\n\n/* PCI device independent region structure */\ntypedef struct _PCI_DEVICE_INDEPENDENT_REGION\n{\n    USHORT VendorId;\n    USHORT DeviceId;\n    USHORT Command;\n    USHORT Status;\n    UCHAR RevisionID;\n    UCHAR ClassCode[3];\n    UCHAR CacheLineSize;\n    UCHAR LaytencyTimer;\n    UCHAR HeaderType;\n    UCHAR BIST;\n} PCI_DEVICE_INDEPENDENT_REGION, *PPCI_DEVICE_INDEPENDENT_REGION;\n\n/* PCI device type 0 structure */\ntypedef struct _PCI_TYPE0_DEVICE\n{\n    PCI_DEVICE_INDEPENDENT_REGION Hdr;\n    PCI_DEVICE_HEADER_TYPE_REGION Device;\n} PCI_TYPE0_DEVICE, *PPCI_TYPE0_DEVICE;\n\n/* PCI device type 1 structure */\ntypedef struct _PCI_TYPE1_DEVICE\n{\n    PCI_DEVICE_INDEPENDENT_REGION Hdr;\n    PCI_BRIDGE_CONTROL_REGISTER Bridge;\n} PCI_TYPE1_DEVICE, *PPCI_TYPE1_DEVICE;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_IOTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/kdfuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/kdfuncs.h\n * DESCRIPTION:     XTOS kernel debugger routine definitions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTDK_KDFUNCS_H\n#define __XTDK_KDFUNCS_H\n\n#include <xtdefs.h>\n#include <xttypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Kernel debugger routines forward references */\nXTCLINK\nXTCDECL\nVOID\nDbgPrint(PCWSTR Format,\n         ...);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_KDFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/kdtypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/kdtypes.h\n * DESCRIPTION:     Kernel Debugger data structures\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTDK_KDTYPES_H\n#define __XTDK_KDTYPES_H\n\n#include <xtbase.h>\n#include <xtstruct.h>\n#include <rtltypes.h>\n\n\n/* Number of debug providers */\n#define KDBG_PROVIDERS_COUNT                                2\n\n/* Debug providers bitmask definitions */\n#define DEBUG_PROVIDER_COMPORT                              0x00000001\n#define DEBUG_PROVIDER_FRAMEBUFFER                          0x00000002\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Kernel routine callbacks */\ntypedef XTSTATUS (XTAPI *PKD_INIT_ROUTINE)();\ntypedef VOID (*PKD_PRINT_ROUTINE)(IN PCWSTR Format, IN ...);\n\n/* Debug mode structure definition */\ntypedef struct _KD_DEBUG_MODE\n{\n    BOOLEAN Enabled;\n    ULONG Mode;\n    ULONG ComPortAddress;\n    ULONG ComPortNumber;\n    ULONG ComPortBaudRate;\n} KD_DEBUG_MODE, *PKD_DEBUG_MODE;\n\n/* Kernel debugger dispatch table structure definition */\ntypedef struct _KD_DISPATCH_TABLE\n{\n    LIST_ENTRY ListEntry;\n    RTL_PRINT_CONTEXT PrintContext;\n} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_KDTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/kefuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/kefuncs.h\n * DESCRIPTION:     XTOS kernel services routine definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_KEFUNCS_H\n#define __XTDK_KEFUNCS_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include <ketypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Kernel services routines forward references */\nXTCLINK\nXTFASTCALL\nVOID\nKeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);\n\nXTCLINK\nXTFASTCALL\nVOID\nKeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);\n\nXTCLINK\nXTAPI\nXTSTATUS\nKeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                        OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);\n\nXTCLINK\nXTAPI\nBOOLEAN\nKeCancelTimer(IN PKTIMER Timer);\n\nXTCLINK\nXTFASTCALL\nKRUNLEVEL\nKeGetCurrentRunLevel(VOID);\n\nXTCLINK\nXTAPI\nXTSTATUS\nKeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                    OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);\n\nXTCLINK\nXTAPI\nBOOLEAN\nKeGetTimerState(IN PKTIMER Timer);\n\nXTCLINK\nXTAPI\nVOID\nKeInitializeApc(IN PKAPC Apc,\n                IN PKTHREAD Thread,\n                IN KAPC_ENVIRONMENT Environment,\n                IN PKKERNEL_ROUTINE KernelRoutine,\n                IN PKRUNDOWN_ROUTINE RundownRoutine,\n                IN PKNORMAL_ROUTINE NormalRoutine,\n                IN KPROCESSOR_MODE ApcMode,\n                IN PVOID Context);\n\nXTCLINK\nXTAPI\nVOID\nKeInitializeDpc(IN PKDPC Dpc,\n                IN PKDEFERRED_ROUTINE DpcRoutine,\n                IN PVOID DpcContext);\n\nXTCLINK\nXTAPI\nVOID\nKeInitializeSemaphore(IN PKSEMAPHORE Semaphore,\n                      IN LONG Count,\n                      IN LONG Limit);\n\nXTCLINK\nXTAPI\nVOID\nKeInitializeSpinLock(IN PKSPIN_LOCK SpinLock);\n\nXTCLINK\nXTAPI\nVOID\nKeInitializeThreadedDpc(IN PKDPC Dpc,\n                        IN PKDEFERRED_ROUTINE DpcRoutine,\n                        IN PVOID DpcContext);\n\nXTCLINK\nXTAPI\nVOID\nKeInitializeTimer(OUT PKTIMER Timer,\n                  IN KTIMER_TYPE Type);\n\nXTCLINK\nXTFASTCALL\nVOID\nKeLowerRunLevel(IN KRUNLEVEL RunLevel);\n\nXTCLINK\nXTFASTCALL\nKRUNLEVEL\nKeRaiseRunLevel(IN KRUNLEVEL RunLevel);\n\nXTCLINK\nXTAPI\nLONG\nKeReadSemaphoreState(IN PKSEMAPHORE Semaphore);\n\nXTCLINK\nXTAPI\nLONG\nKeReleaseSemaphore(IN PKSEMAPHORE Semaphore,\n                   IN KPRIORITY Increment,\n                   IN LONG Adjustment,\n                   IN BOOLEAN Wait);\n\nXTCLINK\nXTFASTCALL\nVOID\nKeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);\n\nXTCLINK\nXTFASTCALL\nVOID\nKeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);\n\nXTCLINK\nXTAPI\nVOID\nKeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader);\n\nXTCLINK\nXTAPI\nVOID\nKeSetTargetProcessorDpc(IN PKDPC Dpc,\n                        IN CCHAR Number);\n\nXTCLINK\nXTAPI\nVOID\nKeSetTimeIncrement(IN ULONG MaxIncrement,\n                   IN ULONG MinIncrement);\n\nXTCLINK\nXTAPI\nVOID\nKeSetTimer(IN PKTIMER Timer,\n           IN LARGE_INTEGER DueTime,\n           IN LONG Period,\n           IN PKDPC Dpc);\n\nXTCLINK\nXTAPI\nVOID\nKeSignalCallDpcDone(IN PVOID SystemArgument);\n\nXTCLINK\nXTAPI\nBOOLEAN\nKeSignalCallDpcSynchronize(IN PVOID SystemArgument);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_KEFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/ketypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/ketypes.h\n * DESCRIPTION:     XT kernel core structures definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_KETYPES_H\n#define __XTDK_KETYPES_H\n\n#include <xtbase.h>\n#include <xtstruct.h>\n#include <xttarget.h>\n#include <xttypes.h>\n#include ARCH_HEADER(xtstruct.h)\n\n\n/* Exception types and handling mechanisms */\n#define EXCEPTION_CONTINUE_SEARCH                   0x00\n#define EXCEPTION_EXECUTE_HANDLER                   0x01\n#define EXCEPTION_CONTINUE_EXECUTION                0xFF\n\n/* Maximum number of exception parameters */\n#define EXCEPTION_MAXIMUM_PARAMETERS                15\n\n/* APC pending state length */\n#define KAPC_STATE_LENGTH                           (FIELD_OFFSET(KAPC_STATE, UserApcPending) + sizeof(BOOLEAN))\n\n/* Kernel service descriptor tables count */\n#define KSERVICE_TABLES_COUNT                       4\n\n/* Timer length */\n#define KTIMER_LENGTH                               (FIELD_OFFSET(KTIMER, Period) + sizeof(LONG))\n\n/* Kernel builtin wait blocks */\n#define EVENT_WAIT_BLOCK                            2\n#define KTHREAD_WAIT_BLOCK                          3\n#define KTIMER_WAIT_BLOCK                           3\n#define SEMAPHORE_WAIT_BLOCK                        2\n\n/* Quantum values */\n#define READY_SKIP_QUANTUM                          2\n#define THREAD_QUANTUM                              6\n\n/* Thread priority levels */\n#define THREAD_LOW_PRIORITY                         0\n#define THREAD_LOW_REALTIME_PRIORITY                16\n#define THREAD_HIGH_PRIORITY                        31\n#define THREAD_MAXIMUM_PRIORITY                     32\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Adjust reason */\ntypedef enum _ADJUST_REASON\n{\n    AdjustNone = 0,\n    AdjustUnwait = 1,\n    AdjustBoost = 2\n} ADJUST_REASON, *PADJUST_REASON;\n\n/* Exception disposition return values */\ntypedef enum _EXCEPTION_DISPOSITION\n{\n    ExceptionContinueExecution,\n    ExceptionContinueSearch,\n    ExceptionNestedException,\n    ExceptionCollidedUnwind,\n} EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION;\n\n/* APC environment types */\ntypedef enum _KAPC_ENVIRONMENT\n{\n    OriginalApcEnvironment,\n    AttachedApcEnvironment,\n    CurrentApcEnvironment,\n    InsertApcEnvironment\n} KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;\n\n/* DPC importance enumeration list */\ntypedef enum _KDPC_IMPORTANCE\n{\n    LowImportance,\n    MediumImportance,\n    HighImportance,\n    MediumHighImportance\n} KDPC_IMPORTANCE, *PKDPC_IMPORTANCE;\n\n/* Event types list */\ntypedef enum _KEVENT_TYPE\n{\n    NotificationEvent,\n    SynchronizationEvent\n} KEVENT_TYPE, *PKEVENT_TYPE;\n\n/* Kernel objects */\ntypedef enum _KOBJECTS\n{\n    EventNotificationObject = 0,\n    EventSynchronizationObject = 1,\n    MutantObject = 2,\n    ProcessObject = 3,\n    QueueObject = 4,\n    SemaphoreObject = 5,\n    ThreadObject = 6,\n    GateObject = 7,\n    TimerNotificationObject = 8,\n    TimerSynchronizationObject = 9,\n    Spare2Object = 10,\n    Spare3Object = 11,\n    Spare4Object = 12,\n    Spare5Object = 13,\n    Spare6Object = 14,\n    Spare7Object = 15,\n    Spare8Object = 16,\n    Spare9Object = 17,\n    ApcObject = 18,\n    DpcObject = 19,\n    DeviceQueueObject = 20,\n    EventPairObject = 21,\n    InterruptObject = 22,\n    ProfileObject = 23,\n    ThreadedDpcObject = 24,\n    MaximumKernelObject = 25\n} KOBJECTS, *PKOBJECTS;\n\n/* Process states */\ntypedef enum _KPROCESS_STATE\n{\n    ProcessInMemory,\n    ProcessOutOfMemory,\n    ProcessInTransition,\n    ProcessOutTransition,\n    ProcessInSwap,\n    ProcessOutSwap\n} KPROCESS_STATE, *PKPROCESS_STATE;\n\n/* Kernel profiling sources */\ntypedef enum _KPROFILE_SOURCE\n{\n    ProfileTime,\n    ProfileAlignmentFixup,\n    ProfileTotalIssues,\n    ProfilePipelineDry,\n    ProfileLoadInstructions,\n    ProfilePipelineFrozen,\n    ProfileBranchInstructions,\n    ProfileTotalNonissues,\n    ProfileDcacheMisses,\n    ProfileIcacheMisses,\n    ProfileCacheMisses,\n    ProfileBranchMispredictions,\n    ProfileStoreInstructions,\n    ProfileFpInstructions,\n    ProfileIntegerInstructions,\n    Profile2Issue,\n    Profile3Issue,\n    Profile4Issue,\n    ProfileSpecialInstructions,\n    ProfileTotalCycles,\n    ProfileIcacheIssues,\n    ProfileDcacheAccesses,\n    ProfileMemoryBarrierCycles,\n    ProfileLoadLinkedIssues,\n    ProfileXtKernel,\n    ProfileMaximum\n} KPROFILE_SOURCE, *PKPROFILE_SOURCE;\n\n/* Thread state */\ntypedef enum _KTHREAD_STATE\n{\n    Initialized,\n    Ready,\n    Running,\n    Standby,\n    Terminated,\n    Waiting,\n    Transition,\n    DeferredReady\n} KTHREAD_STATE, *PKTHREAD_STATE;\n\n/* Spin lock queue levels */\ntypedef enum _KSPIN_LOCK_QUEUE_LEVEL\n{\n    DispatcherLock,\n    ExpansionLock,\n    PfnLock,\n    SystemSpaceLock,\n    VacbLock,\n    MasterLock,\n    NonPagedAllocPoolLock,\n    IoCancelLock,\n    WorkQueueLock,\n    IoVpbLock,\n    IoDatabaseLock,\n    IoCompletionLock,\n    FileSystemLock,\n    AfdWorkQueueLock,\n    BcbLock,\n    NonPagedPoolLock,\n    ReservedSystemLock,\n    TimerTableLock,\n    MaximumLock\n} KSPIN_LOCK_QUEUE_LEVEL, *PKSPIN_LOCK_QUEUE_LEVEL;\n\n/* Timer type */\ntypedef enum _KTIMER_TYPE\n{\n    NotificationTimer,\n    SynchronizationTimer\n} KTIMER_TYPE, *PKTIMER_TYPE;\n\n/* APC Types */\ntypedef enum _MODE\n{\n    KernelMode,\n    UserMode,\n    MaximumMode\n} MODE, *PMODE;\n\n/* System resource types */\ntypedef enum _SYSTEM_RESOURCE_TYPE\n{\n    SystemResourceInvalid,\n    SystemResourceAcpi,\n    SystemResourceFrameBuffer\n} SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE;\n\n/* Wait type */\ntypedef enum _WAIT_TYPE\n{\n    WaitAll,\n    WaitAny\n} WAIT_TYPE, *PWAIT_TYPE;\n\n/* Kernel UBSAN data types enumeration list */\ntypedef enum _KUBSAN_DATA_TYPE\n{\n    DataTypeInt,\n    DataTypeFloat,\n    DataTypeUnknown = 0xFFFF\n} KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;\n\n/* Kernel routine callbacks */\ntypedef EXCEPTION_DISPOSITION (XTCDECL *PEXCEPTION_ROUTINE)(IN PEXCEPTION_RECORD ExceptionRecord, IN PVOID EstablisherFrame, IN OUT PCONTEXT ContextRecord, IN OUT PVOID DispatcherContext);\ntypedef VOID (XTAPI *PKDEFERRED_ROUTINE)(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);\ntypedef VOID (XTAPI *PKNORMAL_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);\ntypedef VOID (XTAPI *PKKERNEL_ROUTINE)(IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2);\ntypedef VOID (XTAPI *PKRUNDOWN_ROUTINE)(IN PKAPC Apc);\ntypedef VOID (XTCDECL *PKSTART_ROUTINE)(IN PVOID StartContext);\ntypedef VOID (XTCDECL *PKSYSTEM_ROUTINE)(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext);\n\n/* Exception record structure definition */\ntypedef struct _EXCEPTION_RECORD\n{\n    XTSTATUS ExceptionCode;\n    ULONG ExceptionFlags;\n    PEXCEPTION_RECORD ExceptionRecord;\n    PVOID ExceptionAddress;\n    ULONG NumberParameters;\n    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];\n} EXCEPTION_RECORD, *PEXCEPTION_RECORD;\n\n/* Asynchronous Procedure Call (APC) object structure definition */\ntypedef struct _KAPC\n{\n    UCHAR Type;\n    UCHAR SpareByte0;\n    UCHAR Size;\n    UCHAR SpareByte1;\n    ULONG SpareLong0;\n    PKTHREAD Thread;\n    LIST_ENTRY ApcListEntry;\n    PKKERNEL_ROUTINE KernelRoutine;\n    PKRUNDOWN_ROUTINE RundownRoutine;\n    PKNORMAL_ROUTINE NormalRoutine;\n    PVOID NormalContext;\n    PVOID SystemArgument1;\n    PVOID SystemArgument2;\n    CHAR ApcStateIndex;\n    KPROCESSOR_MODE ApcMode;\n    BOOLEAN Inserted;\n} KAPC, *PKAPC;\n\n/* Deferred Procedure Call (DPC) object structure definition */\ntypedef struct _KDPC\n{\n    UCHAR Type;\n    UCHAR Importance;\n    UCHAR Number;\n    UCHAR Expedite;\n    LIST_ENTRY DpcListEntry;\n    PKDEFERRED_ROUTINE DeferredRoutine;\n    PVOID DeferredContext;\n    PVOID SystemArgument1;\n    PVOID SystemArgument2;\n    PVOID DpcData;\n} KDPC, *PKDPC;\n\n/* DPC data structure definition */\ntypedef struct _KDPC_DATA\n{\n    LIST_ENTRY DpcListHead;\n    KSPIN_LOCK DpcLock;\n    VOLATILE ULONG DpcQueueDepth;\n    ULONG DpcCount;\n} KDPC_DATA, *PKDPC_DATA;\n\n/* Event object structure definition */\ntypedef struct _KEVENT\n{\n    DISPATCHER_HEADER Header;\n} KEVENT, *PKEVENT;\n\n/* Exception registration record  structure definition */\ntypedef struct _EXCEPTION_REGISTRATION_RECORD\n{\n    PEXCEPTION_REGISTRATION_RECORD Next;\n    PEXCEPTION_ROUTINE Handler;\n} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;\n\n/* APC state structure definition */\ntypedef struct _KAPC_STATE\n{\n    LIST_ENTRY ApcListHead[MaximumMode];\n    PKPROCESS Process;\n    BOOLEAN KernelApcInProgress;\n    BOOLEAN KernelApcPending;\n    BOOLEAN UserApcPending;\n} KAPC_STATE, *PKAPC_STATE;\n\n/* Event gate structure definition */\ntypedef struct _KGATE\n{\n    DISPATCHER_HEADER Header;\n} KGATE, *PKGATE;\n\n/* Semaphore object structure definition */\ntypedef struct _KSEMAPHORE\n{\n    DISPATCHER_HEADER Header;\n    LONG Limit;\n} KSEMAPHORE, *PKSEMAPHORE;\n\n/* Per processor lock queue structure definition */\ntypedef struct _KSPIN_LOCK_QUEUE\n{\n    PKSPIN_LOCK_QUEUE Next;\n    PKSPIN_LOCK Lock;\n} KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE;\n\n/* Per processor lock queue handle structure definition */\ntypedef struct _KLOCK_QUEUE_HANDLE\n{\n    KSPIN_LOCK_QUEUE LockQueue;\n    KRUNLEVEL OldRunLevel;\n} KLOCK_QUEUE_HANDLE, *PKLOCK_QUEUE_HANDLE;\n\n/* Queue object structure definition */\ntypedef struct _KQUEUE\n{\n    DISPATCHER_HEADER Header;\n    LIST_ENTRY EntryListHead;\n    ULONG CurrentCount;\n    ULONG MaximumCount;\n    LIST_ENTRY ThreadListHead;\n} KQUEUE, *PKQUEUE;\n\n/* Kernel service table descriptor */\ntypedef struct _KSERVICE_DESCRIPTOR_TABLE\n{\n    PULONG_PTR Base;\n    PULONG Count;\n    ULONG Limit;\n    PUCHAR Number;\n} KSERVICE_DESCRIPTOR_TABLE, *PKSERVICE_DESCRIPTOR_TABLE;\n\n/* Timer object structure definition */\ntypedef struct _KTIMER\n{\n    DISPATCHER_HEADER Header;\n    ULARGE_INTEGER DueTime;\n    LIST_ENTRY TimerListEntry;\n    PKDPC Dpc;\n    LONG Period;\n} KTIMER, *PKTIMER;\n\n/* Wait block structure definition */\ntypedef struct _KWAIT_BLOCK\n{\n    LIST_ENTRY WaitListEntry;\n    PKTHREAD Thread;\n    PVOID Object;\n    PKWAIT_BLOCK *NextWaitBlock;\n    USHORT WaitKey;\n    UCHAR WaitType;\n    UCHAR SpareByte;\n    LONG SpareLong;\n} KWAIT_BLOCK, *PKWAIT_BLOCK;\n\n/* XT Thread Information Block (TIB) definition */\ntypedef struct _THREAD_INFORMATION_BLOCK\n{\n    PEXCEPTION_REGISTRATION_RECORD ExceptionList;\n    PVOID StackBase;\n    PVOID StackLimit;\n    PVOID SubSystemTib;\n    PVOID ArbitraryUserPointer;\n    PTHREAD_INFORMATION_BLOCK Self;\n} THREAD_INFORMATION_BLOCK, *PTHREAD_INFORMATION_BLOCK;\n\n/* Process control block structure definition */\ntypedef struct _KPROCESS\n{\n    DISPATCHER_HEADER Header;\n    LIST_ENTRY ProfileListHead;\n    ULONG_PTR DirectoryTable[2];\n    USHORT IopmOffset;\n    UCHAR Iopl;\n    VOLATILE KAFFINITY ActiveProcessors;\n    ULONG KernelTime;\n    ULONG UserTime;\n    LIST_ENTRY ReadyListHead;\n    SINGLE_LIST_ENTRY SwapListEntry;\n    PVOID VdmTrapHandler;\n    LIST_ENTRY ThreadListHead;\n    KSPIN_LOCK ProcessLock;\n    KAFFINITY Affinity;\n    union\n    {\n        struct\n        {\n            BOOLEAN AutoAlignment;\n            BOOLEAN DisableBoost;\n            BOOLEAN DisableQuantum;\n            LONG ReservedFlags:29;\n        };\n        LONG ProcessFlags;\n    };\n    ULONG_PTR StackCount;\n    SCHAR BasePriority;\n    SCHAR Quantum;\n    UCHAR State;\n    UCHAR ThreadSeed;\n    UCHAR PowerState;\n    UCHAR IdealNode;\n    UCHAR Spare;\n} KPROCESS, *PKPROCESS;\n\n/* System Time structure definition */\ntypedef struct _KSYSTEM_TIME\n{\n    ULONG LowPart;\n    LONG High1Part;\n    LONG High2Part;\n} KSYSTEM_TIME, *PKSYSTEM_TIME;\n\n/* Kernel Shared Data (KSD) structure definition */\ntypedef struct _KSHARED_DATA\n{\n    VOLATILE KSYSTEM_TIME InterruptTime;\n    VOLATILE KSYSTEM_TIME SystemTime;\n    VOLATILE KSYSTEM_TIME TickCount;\n    ULONG XtMajorVersion;\n    ULONG XtMinorVersion;\n    WCHAR XtBuild[8];\n    WCHAR XtBuildHash[11];\n    WCHAR XtArchitecture[8];\n    WCHAR XtDate[9];\n    WCHAR XtFullDate[25];\n} KSHARED_DATA, *PKSHARED_DATA;\n\n/* Thread control block structure definition */\ntypedef struct _KTHREAD\n{\n    DISPATCHER_HEADER Header;\n    LIST_ENTRY MutantListHead;\n    PVOID InitialStack;\n    PVOID KernelStack;\n    PVOID StackBase;\n    PVOID StackLimit;\n    KSPIN_LOCK ThreadLock;\n\n    ULONG ContextSwitches;\n    VOLATILE UCHAR State;\n    UCHAR NpxState;\n    KRUNLEVEL WaitRunLevel;\n    KPROCESSOR_MODE WaitMode;\n    PTHREAD_ENVIRONMENT_BLOCK EnvironmentBlock;\n    union\n    {\n        KAPC_STATE ApcState;\n        struct\n        {\n            UCHAR ApcStateFill[KAPC_STATE_LENGTH];\n            BOOLEAN ApcQueueable;\n            VOLATILE UCHAR NextProcessor;\n            VOLATILE UCHAR DeferredProcessor;\n            UCHAR AdjustReason;\n            SCHAR AdjustIncrement;\n        };\n    };\n    KSPIN_LOCK ApcQueueLock;\n    LONG_PTR WaitStatus;\n    PKWAIT_BLOCK WaitBlockList;\n    BOOLEAN Alertable;\n    BOOLEAN WaitNext;\n    UCHAR WaitReason;\n    SCHAR Priority;\n    UCHAR StackSwap;\n    VOLATILE UCHAR SwapBusy;\n    BOOLEAN Alerted[MaximumMode];\n    union\n    {\n        LIST_ENTRY WaitListEntry;\n        SINGLE_LIST_ENTRY SwapListEntry;\n    };\n    PKQUEUE Queue;\n    ULONG WaitTime;\n    union\n    {\n        struct\n        {\n            SHORT KernelApcDisable;\n            SHORT SpecialApcDisable;\n        };\n        ULONG CombinedApcDisable;\n    };\n    KTIMER Timer;\n    KWAIT_BLOCK WaitBlock[KTHREAD_WAIT_BLOCK + 1];\n    LIST_ENTRY QueueListEntry;\n    UCHAR ApcStateIndex;\n    BOOLEAN Preempted;\n    BOOLEAN ProcessReadyQueue;\n    BOOLEAN KernelStackResident;\n    CHAR Saturation;\n    UCHAR IdealProcessor;\n    SCHAR BasePriority;\n    UCHAR Spare4;\n    SCHAR PriorityDecrement;\n    SCHAR Quantum;\n    BOOLEAN SystemAffinityActive;\n    CHAR PreviousMode;\n    UCHAR ResourceIndex;\n    UCHAR DisableBoost;\n    KAFFINITY UserAffinity;\n    PKPROCESS Process;\n    KAFFINITY Affinity;\n    PVOID ServiceTable;\n    PKAPC_STATE ApcStatePointer[2];\n    KAPC_STATE SavedApcState;\n    PVOID CallbackStack;\n    PVOID SubSystemThread;\n    PKTRAP_FRAME TrapFrame;\n    ULONG KernelTime;\n    ULONG UserTime;\n    KAPC SuspendApc;\n    KSEMAPHORE SuspendSemaphore;\n    PVOID TlsArray;\n    PVOID LegoData;\n    LIST_ENTRY ThreadListEntry;\n    UCHAR LargeStack;\n    UCHAR PowerState;\n    UCHAR NpxIrql;\n    UCHAR Spare5;\n    BOOLEAN AutoAlignment;\n    UCHAR Iopl;\n    CCHAR FreezeCount;\n    CCHAR SuspendCount;\n    UCHAR Spare0[1];\n    UCHAR UserIdealProcessor;\n    UCHAR Spare2[3];\n    ULONG KernelLimit;\n    BOOLEAN StackResident;\n} KTHREAD, *PKTHREAD;\n\n/* System resource common header structure definition */\ntypedef struct _SYSTEM_RESOURCE_HEADER\n{\n    LIST_ENTRY ListEntry;\n    SYSTEM_RESOURCE_TYPE ResourceType;\n    BOOLEAN ResourceLocked;\n    ULONG ResourceSize;\n    PVOID PhysicalAddress;\n    PVOID VirtualAddress;\n} SYSTEM_RESOURCE_HEADER, *PSYSTEM_RESOURCE_HEADER;\n\n/* ACPI system resource structure definition */\ntypedef struct _SYSTEM_RESOURCE_ACPI\n{\n    SYSTEM_RESOURCE_HEADER Header;\n    PVOID ApicBase;\n} SYSTEM_RESOURCE_ACPI, *PSYSTEM_RESOURCE_ACPI;\n\n/* FrameBuffer system resource structure definition */\ntypedef struct _SYSTEM_RESOURCE_FRAMEBUFFER\n{\n    SYSTEM_RESOURCE_HEADER Header;\n    ULONG_PTR BufferSize;\n    UINT Width;\n    UINT Height;\n    UINT Depth;\n    UINT PixelsPerScanLine;\n    UINT BitsPerPixel;\n    UINT Pitch;\n    PVOID Font;\n    struct\n    {\n        USHORT BlueShift;\n        USHORT BlueSize;\n        USHORT GreenShift;\n        USHORT GreenSize;\n        USHORT RedShift;\n        USHORT RedSize;\n        USHORT ReservedShift;\n        USHORT ReservedSize;\n    } Pixels;\n} SYSTEM_RESOURCE_FRAMEBUFFER, *PSYSTEM_RESOURCE_FRAMEBUFFER;\n\n/* Kernel UBSAN source location structure definition */\ntypedef struct _KUBSAN_SOURCE_LOCATION\n{\n    PCCHAR FileName;\n    union\n    {\n        ULONG Reported;\n        struct\n        {\n            UINT Line;\n            UINT Column;\n        };\n    };\n} KUBSAN_SOURCE_LOCATION, *PKUBSAN_SOURCE_LOCATION;\n\n/* Kernel UBSAN type descriptor structure definition */\ntypedef struct _KUBSAN_TYPE_DESCRIPTOR\n{\n    USHORT DataType;\n    USHORT TypeInfo;\n    CHAR TypeName[1];\n} KUBSAN_TYPE_DESCRIPTOR, *PKUBSAN_TYPE_DESCRIPTOR;\n\n/* Kernel UBSAN float cast overflow data structure definition */\ntypedef struct _KUBSAN_FLOAT_CAST_OVERFLOW_DATA\n{\n    KUBSAN_SOURCE_LOCATION Location;\n    PKUBSAN_TYPE_DESCRIPTOR LhsType;\n    PKUBSAN_TYPE_DESCRIPTOR RhsType;\n} KUBSAN_FLOAT_CAST_OVERFLOW_DATA, *PKUBSAN_FLOAT_CAST_OVERFLOW_DATA;\n\n/* Kernel UBSAN function type mismatch data structure definition */\ntypedef struct _KUBSAN_FUNCTION_TYPE_MISMATCH_DATA\n{\n    KUBSAN_SOURCE_LOCATION Location;\n    PKUBSAN_TYPE_DESCRIPTOR Type;\n} KUBSAN_FUNCTION_TYPE_MISMATCH_DATA, *PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA;\n\n/* Kernel UBSAN invalid builtin data structure definition */\ntypedef struct _KUBSAN_INVALID_BUILTIN_DATA\n{\n    KUBSAN_SOURCE_LOCATION Location;\n    UCHAR Kind;\n} KUBSAN_INVALID_BUILTIN_DATA, *PKUBSAN_INVALID_BUILTIN_DATA;\n\n/* Kernel UBSAN shift out of bounds data structure definition */\ntypedef struct _KUBSAN_SHIFT_OUT_OF_BOUNDS_DATA\n{\n    KUBSAN_SOURCE_LOCATION Location;\n    PKUBSAN_TYPE_DESCRIPTOR LhsType;\n    PKUBSAN_TYPE_DESCRIPTOR RhsType;\n} KUBSAN_SHIFT_OUT_OF_BOUNDS_DATA, *PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA;\n\n/* Kernel UBSAN out of bounds data structure definition */\ntypedef struct _KUBSAN_OUT_OF_BOUNDS_DATA\n{\n    KUBSAN_SOURCE_LOCATION Location;\n    PKUBSAN_TYPE_DESCRIPTOR ArrayType;\n    PKUBSAN_TYPE_DESCRIPTOR IndexType;\n} KUBSAN_OUT_OF_BOUNDS_DATA, *PKUBSAN_OUT_OF_BOUNDS_DATA;\n\n/* Kernel UBSAN overflow data structure definition */\ntypedef struct _KUBSAN_OVERFLOW_DATA\n{\n    KUBSAN_SOURCE_LOCATION Location;\n    PKUBSAN_TYPE_DESCRIPTOR Type;\n} KUBSAN_OVERFLOW_DATA, *PKUBSAN_OVERFLOW_DATA;\n\n/* Kernel UBSAN type mismatch data structure definition */\ntypedef struct _KUBSAN_TYPE_MISMATCH_DATA\n{\n    KUBSAN_SOURCE_LOCATION Location;\n    PKUBSAN_TYPE_DESCRIPTOR Type;\n    ULONG Alignment;\n    UCHAR TypeCheckKind;\n} KUBSAN_TYPE_MISMATCH_DATA, *PKUBSAN_TYPE_MISMATCH_DATA;\n\n/* Kernel UBSAN type mismatch data structure definition */\ntypedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1\n{\n    KUBSAN_SOURCE_LOCATION Location;\n    PKUBSAN_TYPE_DESCRIPTOR Type;\n    UCHAR LogAlignment;\n    UCHAR TypeCheckKind;\n} KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_KEFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/ldrtypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/ldrtypes.h\n * DESCRIPTION:     Loader structures definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_LDRTYPES_H\n#define __XTDK_LDRTYPES_H\n\n#include <xtbase.h>\n\n\n/* Loader Data Table Entry Flags */\n#define LDR_DTE_STATIC_LINK                        0x00000002\n#define LDR_DTE_IMAGE_DLL                          0x00000004\n#define LDR_DTE_SHIMENG_SUPPRESSED_ENTRY           0x00000008\n#define LDR_DTE_IMAGE_INTEGRITY_FORCED             0x00000020\n#define LDR_DTE_LOAD_IN_PROGRESS                   0x00001000\n#define LDR_DTE_UNLOAD_IN_PROGRESS                 0x00002000\n#define LDR_DTE_ENTRY_PROCESSED                    0x00004000\n#define LDR_DTE_ENTRY_INSERTED                     0x00008000\n#define LDR_DTE_CURRENT_LOAD                       0x00010000\n#define LDR_DTE_FAILED_BUILTIN_LOAD                0x00020000\n#define LDR_DTE_DONT_CALL_FOR_THREADS              0x00040000\n#define LDR_DTE_PROCESS_ATTACH_CALLED              0x00080000\n#define LDR_DTE_DEBUG_SYMBOLS_LOADED               0x00100000\n#define LDR_DTE_IMAGE_NOT_AT_BASE                  0x00200000\n#define LDR_DTE_COR_IMAGE                          0x00400000\n#define LDR_DTE_COR_OWNS_UNMAP                     0x00800000\n#define LDR_DTE_SYSTEM_MAPPED                      0x01000000\n#define LDR_DTE_IMAGE_VERIFYING                    0x02000000\n#define LDR_DTE_DRIVER_DEPENDENT_DLL               0x04000000\n#define LDR_DTE_ENTRY_NATIVE                       0x08000000\n#define LDR_DTE_REDIRECTED                         0x10000000\n#define LDR_DTE_NON_PAGED_DEBUG_INFO               0x20000000\n#define LDR_DTE_MM_LOADED                          0x40000000\n#define LDR_DTE_COMPAT_DATABASE_PROCESSED          0x80000000\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Loader data table entry */\ntypedef struct _LDR_DATA_TABLE_ENTRY\n{\n    LIST_ENTRY InLoadOrderLinks;\n    LIST_ENTRY InMemoryOrderLinks;\n    LIST_ENTRY InInitializationOrderLinks;\n    PVOID DllBase;\n    PVOID EntryPoint;\n    ULONG SizeOfImage;\n    UNICODE_STRING FullDllName;\n    UNICODE_STRING BaseDllName;\n    ULONG Flags;\n    USHORT LoadCount;\n    USHORT TlsIndex;\n    union\n    {\n        LIST_ENTRY HashLinks;\n        struct\n        {\n            PVOID SectionPointer;\n            ULONG CheckSum;\n        };\n    };\n    union\n    {\n        ULONG TimeDateStamp;\n        PVOID LoadedImports;\n    };\n    PVOID EntryPointActivationContext;\n    PVOID PatchInformation;\n} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_LDRTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/mmfuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/mmfuncs.h\n * DESCRIPTION:     XTOS memory manager routine definitions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTDK_MMFUNCS_H\n#define __XTDK_MMFUNCS_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Memory manager routines forward references */\nXTAPI\nXTSTATUS\nMmAllocatePool(IN MMPOOL_TYPE PoolType,\n               IN SIZE_T Bytes,\n               OUT PVOID *Memory);\n\nXTAPI\nXTSTATUS\nMmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,\n                      IN SIZE_T Bytes,\n                      OUT PVOID *Memory,\n                      IN ULONG Tag);\n\nXTAPI\nXTSTATUS\nMmFreePool(IN PVOID VirtualAddress);\n\nXTAPI\nXTSTATUS\nMmFreePoolWithTag(IN PVOID VirtualAddress,\n                  IN ULONG Tag);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_MMFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/mmtypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/mmtypes.h\n * DESCRIPTION:     Memory management data structures\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTDK_MMTYPES_H\n#define __XTDK_MMTYPES_H\n\n#include <xtbase.h>\n#include ARCH_HEADER(xtstruct.h)\n\n\n/* Number of hyper space pages */\n#define MM_HYPERSPACE_PAGE_COUNT                   255\n\n/* Number of free page list heads */\n#define MM_MAX_FREE_PAGE_LIST_HEADS                4\n\n/* Number of paging colors */\n#define MM_PAGING_COLORS                           64\n\n/* PTE frame mask definition */\n#define MM_PFN_PTE_FRAME                           (((ULONG_PTR)1 << MM_PTE_FRAME_BITS) - 1)\n\n/* Memory manager pool type mask definition */\n#define MM_POOL_TYPE_MASK                          1\n\n/* Bad pool caller reasons */\n#define MM_POOL_INVALID_ALLOC_RUNLEVEL             8\n#define MM_POOL_INVALID_FREE_RUNLEVEL              9\n\n/* Pool flags */\n#define MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE         0x1\n#define MM_POOL_PROTECTED                          0x80000000\n#define MM_POOL_RAISE_EXCEPTION                    0x10\n\n/* Number of reserved zeroed PTEs */\n#define MM_RESERVED_ZERO_PTES                      32\n\n/* Memory Manager Protection Bits */\n#define MM_ZERO_ACCESS                             0\n#define MM_READONLY                                1\n#define MM_EXECUTE                                 2\n#define MM_EXECUTE_READ                            3\n#define MM_READWRITE                               4\n#define MM_WRITECOPY                               5\n#define MM_EXECUTE_READWRITE                       6\n#define MM_EXECUTE_WRITECOPY                       7\n#define MM_PROTECT_ACCESS                          7\n\n/* Protection field shift */\n#define MM_PROTECT_FIELD_SHIFT                     5\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Memory manager page lists */\ntypedef enum _MMPAGELISTS\n{\n   ZeroedPageList = 0,\n   FreePageList = 1,\n   StandbyPageList = 2,\n   ModifiedPageList = 3,\n   ModifiedReadOnlyPageList = 4,\n   BadPageList = 5,\n   ActiveAndValid = 6,\n   TransitionPage = 7\n} MMPAGELISTS, *PMMPAGELISTS;\n\n/* Page cache attributes */\ntypedef enum _MMPFN_CACHE_ATTRIBUTE\n{\n    PfnNonCached,\n    PfnCached,\n    PfnWriteCombined,\n    PfnNotMapped\n} MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBUTE;\n\n/* Memory Manager pool types */\ntypedef enum _MMPOOL_TYPE\n{\n    NonPagedPool = 0,\n    PagedPool = 1,\n    NonPagedPoolMustSucceed = 2,\n    NonPagedPoolCacheAligned = 4,\n    PagedPoolCacheAligned = 5,\n    NonPagedPoolCacheAlignedMustSucceed = 6,\n    MaxPoolType = 7,\n    NonPagedPoolSession = 32,\n    PagedPoolSession = 33,\n    NonPagedPoolMustSucceedSession = 34,\n    NonPagedPoolCacheAlignedSession = 36,\n    PagedPoolCacheAlignedSession = 37,\n    NonPagedPoolCacheAlignedMustSucceedSession = 38\n} MMPOOL_TYPE, *PMMPOOL_TYPE;\n\n/* Page table pool types */\ntypedef enum _MMSYSTEM_PTE_POOL_TYPE\n{\n    SystemPteSpace,\n    NonPagedPoolExpansion,\n    MaximumPtePoolTypes\n} MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;\n\n/* Page map routines structure definition */\ntypedef CONST STRUCT _CMMPAGEMAP_ROUTINES\n{\n    VOID (XTAPI *ClearPte)(PHARDWARE_PTE PtePointer);\n    BOOLEAN (XTAPI *PteValid)(PHARDWARE_PTE PtePointer);\n    VOID (XTAPI *SetPteCaching)(PHARDWARE_PTE PtePointer, BOOLEAN CacheDisable, BOOLEAN WriteThrough);\n    VOID (XTAPI *SetPte)(PHARDWARE_PTE PtePointer, PFN_NUMBER PageFrameNumber, BOOLEAN Writable);\n} CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES;\n\n/* Color tables structure definition */\ntypedef struct _MMCOLOR_TABLES\n{\n    ULONG_PTR Flink;\n    PVOID Blink;\n    ULONG_PTR Count;\n} MMCOLOR_TABLES, *PMMCOLOR_TABLES;\n\n/* Free pool entry structure definition */\ntypedef struct _MMFREE_POOL_ENTRY\n{\n    LIST_ENTRY List;\n    PFN_COUNT Size;\n    PMMFREE_POOL_ENTRY Owner;\n} MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;\n\n/* Memory layout structure definition */\ntypedef struct _MMMEMORY_LAYOUT\n{\n    PMMPFN PfnDatabase;\n    PFN_NUMBER PfnDatabaseSize;\n    PVOID SelfMapAddress;\n    PVOID HardwarePoolStart;\n    PVOID HardwarePoolEnd;\n    PVOID HyperSpaceStart;\n    PVOID HyperSpaceEnd;\n    PVOID LoaderMappingsStart;\n    PVOID LoaderMappingsEnd;\n    PFN_NUMBER LoaderMappingsSize;\n    PVOID NonCanonicalStart;\n    PVOID NonCanonicalEnd;\n    PVOID NonPagedPoolStart;\n    PVOID NonPagedPoolEnd;\n    PFN_NUMBER NonPagedPoolSize;\n    PVOID NonPagedExpansionPoolStart;\n    PVOID NonPagedExpansionPoolEnd;\n    PFN_NUMBER NonPagedExpansionPoolSize;\n    PVOID NonPagedSystemPoolStart;\n    PVOID NonPagedSystemPoolEnd;\n    PFN_NUMBER NonPagedSystemPoolSize;\n    PVOID PagedPoolStart;\n    PVOID PagedPoolEnd;\n    PFN_NUMBER PagedPoolSize;\n    PVOID ReservedSystemPoolStart;\n    PVOID ReservedSystemPoolEnd;\n    PVOID SessionSpaceStart;\n    PVOID SessionSpaceEnd;\n    PFN_NUMBER SessionSpaceSize;\n    PVOID SharedSystemPageStart;\n    PVOID SharedSystemPageEnd;\n    PVOID SystemCacheStart;\n    PVOID SystemCacheEnd;\n    PVOID SystemWorkingSetStart;\n    PVOID SystemWorkingSetEnd;\n    PVOID UserSpaceStart;\n    PVOID UserSpaceEnd;\n    PVOID PteSpaceStart;\n    PVOID PteSpaceEnd;\n} MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;\n\n/* Page Frame Entry structure definition */\ntypedef struct _MMPFNENTRY\n{\n    USHORT Modified:1;\n    USHORT ReadInProgress:1;\n    USHORT WriteInProgress:1;\n    USHORT PrototypePte:1;\n    USHORT PageColor:4;\n    USHORT PageLocation:3;\n    USHORT RemovalRequested:1;\n    USHORT CacheAttribute:2;\n    USHORT Rom:1;\n    USHORT ParityError:1;\n} MMPFNENTRY, *PMMPFNENTRY;\n\n/* Page Frame List structure definition */\ntypedef struct _MMPFNLIST\n{\n    PFN_NUMBER Total;\n    MMPAGELISTS ListName;\n    PFN_NUMBER Flink;\n    PFN_NUMBER Blink;\n} MMPFNLIST, *PMMPFNLIST;\n\n/* Physical memory run structure definition */\ntypedef struct _PHYSICAL_MEMORY_RUN\n{\n    PFN_NUMBER BasePage;\n    PFN_NUMBER PageCount;\n} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;\n\n/* Physical memory descriptor structure definition */\ntypedef struct _PHYSICAL_MEMORY_DESCRIPTOR\n{\n    ULONG NumberOfRuns;\n    PFN_NUMBER NumberOfPages;\n    PHYSICAL_MEMORY_RUN Run[1];\n} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;\n\n/* Pool header structure definition */\ntypedef struct _POOL_HEADER\n{\n    union\n    {\n        struct\n        {\n            USHORT PreviousSize:9;\n            USHORT PoolIndex:7;\n            USHORT BlockSize:9;\n            USHORT PoolType:7;\n        };\n        ULONG Long;\n    };\n    union\n    {\n        ULONG PoolTag;\n        PEPROCESS ProcessBilled;\n        struct\n        {\n            USHORT AllocatorBackTraceIndex;\n            USHORT PoolTagHash;\n        };\n    };\n} POOL_HEADER, *PPOOL_HEADER;\n\n/* Pool descriptor structure definition */\ntypedef struct _POOL_TRACKING_BIG_ALLOCATIONS\n{\n    ULONG NumberOfPages;\n    PVOID QuotaObject;\n    ULONG Tag;\n    PVOID VirtualAddress;\n} POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;\n\n/* Pool tracking table structure definition */\ntypedef struct _POOL_TRACKING_TABLE\n{\n    LONG NonPagedAllocations;\n    SIZE_T NonPagedBytes;\n    LONG NonPagedFrees;\n    LONG PagedAllocations;\n    SIZE_T PagedBytes;\n    LONG PagedFrees;\n    ULONG Tag;\n} POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_MMTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/potypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/potypes.h\n * DESCRIPTION:     Power manager subsystem structures definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_POTYPES_H\n#define __XTDK_POTYPES_H\n\n#include <xttypes.h>\n#include <xtstruct.h>\n#include <ketypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Power Manager routine callbacks */\ntypedef VOID (XTFASTCALL *PPROCESSOR_IDLE_FUNCTION)(IN PPROCESSOR_POWER_STATE PowerState);\ntypedef XTSTATUS (XTFASTCALL *PSET_PROCESSOR_THROTTLE)(IN UCHAR Throttle);\n\n/* Processor IDLE times structure definition */\ntypedef struct _PROCESSOR_IDLE_TIMES\n{\n    ULONGLONG StartTime;\n    ULONGLONG EndTime;\n    ULONG IdleHandlerReserved[4];\n} PROCESSOR_IDLE_TIMES, *PPROCESSOR_IDLE_TIMES;\n\n/* Processor performance state structure definition */\ntypedef struct _PROCESSOR_PERF_STATE\n{\n    UCHAR PercentFrequency;\n    UCHAR MinCapacity;\n    USHORT Power;\n    UCHAR IncreaseLevel;\n    UCHAR DecreaseLevel;\n    USHORT Flags;\n    ULONG IncreaseTime;\n    ULONG DecreaseTime;\n    ULONG IncreaseCount;\n    ULONG DecreaseCount;\n    ULONGLONG PerformanceTime;\n} PROCESSOR_PERF_STATE, *PPROCESSOR_PERF_STATE;\n\n/* Processor power state structure definition */\ntypedef struct _PROCESSOR_POWER_STATE\n{\n    PPROCESSOR_IDLE_FUNCTION IdleFunction;\n    ULONG Idle0TimeLimit;\n    ULONG Idle0LastTime;\n    PVOID IdleHandlers;\n    PVOID IdleState;\n    ULONG IdleHandlersCount;\n    ULONGLONG LastCheck;\n    PROCESSOR_IDLE_TIMES IdleTimes;\n    ULONG IdleTime1;\n    ULONG PromotionCheck;\n    ULONG IdleTime2;\n    UCHAR CurrentThrottle;\n    UCHAR ThermalThrottleLimit;\n    UCHAR CurrentThrottleIndex;\n    UCHAR ThermalThrottleIndex;\n    ULONG PerfSystemTime;\n    ULONG PerfIdleTime;\n    ULONG LastSysTime;\n    ULONGLONG TotalIdleStateTime[3];\n    ULONG TotalIdleTransitions[3];\n    ULONGLONG PreviousC3StateTime;\n    UCHAR KneeThrottleIndex;\n    UCHAR ThrottleLimitIndex;\n    UCHAR PerfStatesCount;\n    UCHAR ProcessorMinThrottle;\n    UCHAR ProcessorMaxThrottle;\n    UCHAR LastBusyPercentage;\n    UCHAR LastC3Percentage;\n    UCHAR LastAdjustedBusyPercentage;\n    ULONG PromotionCount;\n    ULONG DemotionCount;\n    ULONG ErrorCount;\n    ULONG RetryCount;\n    ULONG Flags;\n    LARGE_INTEGER PerfCounterFrequency;\n    ULONG PerfTickCount;\n    KTIMER PerfTimer;\n    KDPC PerfDpc;\n    PPROCESSOR_PERF_STATE PerfStates;\n    PSET_PROCESSOR_THROTTLE PerfSetThrottle;\n    ULONG LastC3UserTime;\n} PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_POTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/pstypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/pstypes.h\n * DESCRIPTION:     Process-related data structure definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_PSTYPES_H\n#define __XTDK_PSTYPES_H\n\n#include <xttypes.h>\n#include <ketypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Kernel's representation of a process object */\ntypedef struct _EPROCESS\n{\n    KPROCESS ProcessControlBlock;\n    UINT Reserved0;\n} EPROCESS, *PEPROCESS;\n\n/* Kernel's representation of a thread object */\ntypedef struct _ETHREAD\n{\n    KTHREAD ThreadControlBlock;\n    UINT Reserved0;\n} ETHREAD, *PETHREAD;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_PSTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/rtlfuncs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/rtlfuncs.h\n * DESCRIPTION:     XT runtime library routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_RTLFUNCS_H\n#define __XTDK_RTLFUNCS_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n#include <rtltypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Runtime Library routines forward references */\nXTCLINK\nXTAPI\nVOID\nRtlClearAllBits(IN PRTL_BITMAP BitMap);\n\nXTCLINK\nXTAPI\nVOID\nRtlClearBit(IN PRTL_BITMAP BitMap,\n            IN ULONG_PTR Bit);\n\nXTCLINK\nXTAPI\nVOID\nRtlClearBits(IN PRTL_BITMAP BitMap,\n             IN ULONG_PTR StartingIndex,\n             IN ULONG_PTR Length);\n\nXTCLINK\nXTAPI\nULONG\nRtlClearSetBits(IN PRTL_BITMAP BitMap,\n                IN ULONG_PTR Length,\n                IN ULONG_PTR Index);\n\nXTCLINK\nXTAPI\nBOOLEAN\nRtlCompareGuids(IN PGUID Guid1,\n                IN PGUID Guid2);\n\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareMemory(IN PCVOID LeftBuffer,\n                 IN PCVOID RightBuffer,\n                 IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareString(IN PCSTR String1,\n                 IN PCSTR String2,\n                 IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareStringInsensitive(IN PCSTR String1,\n                            IN PCSTR String2,\n                            IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareWideString(IN PCWSTR String1,\n                     IN PCWSTR String2,\n                     IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareWideStringInsensitive(IN PCWSTR String1,\n                                IN PCWSTR String2,\n                                IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nPCHAR\nRtlConcatenateString(OUT PCHAR Destination,\n                     IN PCHAR Source,\n                     IN SIZE_T Count);\n\nXTCLINK\nXTAPI\nPWCHAR\nRtlConcatenateWideString(OUT PWCHAR Destination,\n                         IN PWCHAR Source,\n                         IN SIZE_T Count);\n\nXTCLINK\nXTAPI\nLARGE_INTEGER\nRtlConvertToLargeInteger32(IN LONG Value);\n\nXTCLINK\nXTAPI\nLARGE_INTEGER\nRtlConvertToLargeIntegerUnsigned32(IN ULONG Value);\n\nXTCLINK\nXTAPI\nVOID\nRtlCopyMemory(OUT PVOID Destination,\n              IN PCVOID Source,\n              IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nVOID\nRtlCopyString(IN PCHAR Destination,\n              IN PCSTR Source,\n              IN ULONG Length);\n\nXTCLINK\nXTAPI\nVOID\nRtlCopyWideString(IN PWCHAR Destination,\n                  IN PCWSTR Source,\n                  IN ULONG Length);\n\nXTCLINK\nXTAPI\nLARGE_INTEGER\nRtlDivideLargeInteger(IN LARGE_INTEGER Dividend,\n                      IN ULONG Divisor,\n                      OUT PULONG Remainder);\n\nXTCLINK\nXTAPI\nULONG_PTR\nRtlFindClearBits(IN PRTL_BITMAP BitMap,\n                 IN ULONG_PTR Length,\n                 IN ULONG_PTR Index);\n\nXTCLINK\nXTAPI\nULONG_PTR\nRtlFindSetBits(IN PRTL_BITMAP BitMap,\n               IN ULONG_PTR Length,\n               IN ULONG_PTR Index);\n\nXTCLINK\nXTAPI\nPCSTR\nRtlFindString(IN PCSTR Source,\n              IN PCSTR Search);\n\nXTCLINK\nXTAPI\nPCSTR\nRtlFindStringInsensitive(IN PCSTR Source,\n                         IN PCSTR Search);\n\nXTCLINK\nXTAPI\nPCWSTR\nRtlFindWideString(IN PCWSTR Source,\n                  IN PCWSTR Search);\n\nXTCLINK\nXTAPI\nPCWSTR\nRtlFindWideStringInsensitive(IN PCWSTR Source,\n                             IN PCWSTR Search);\n\nXTCLINK\nXTAPI\nVOID\nRtlInitializeBitMap(IN PRTL_BITMAP BitMap,\n                    IN PULONG_PTR Buffer,\n                    IN ULONG Size);\n\nXTCLINK\nXTCDECL\nVOID\nRtlInitializeListHead(IN PLIST_ENTRY ListHead);\n\nXTCLINK\nXTCDECL\nVOID\nRtlInsertHeadList(IN OUT PLIST_ENTRY ListHead,\n                  IN PLIST_ENTRY Entry);\n\nXTCLINK\nXTCDECL\nVOID\nRtlInsertTailList(IN OUT PLIST_ENTRY ListHead,\n                  IN PLIST_ENTRY Entry);\n\nXTCLINK\nXTCDECL\nBOOLEAN\nRtlListEmpty(IN PLIST_ENTRY ListHead);\n\nXTCLINK\nXTCDECL\nBOOLEAN\nRtlListLoop(IN PLIST_ENTRY ListHead);\n\nXTCLINK\nXTAPI\nVOID\nRtlMoveMemory(OUT PVOID Destination,\n              IN PCVOID Source,\n              IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nLARGE_INTEGER\nRtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand,\n                        IN LONG Multiplier);\n\nXTCLINK\nXTCDECL\nVOID\nRtlRemoveEntryList(IN PLIST_ENTRY Entry);\n\nXTCLINK\nXTAPI\nVOID\nRtlReverseString(IN OUT PCHAR String,\n                 IN ULONG Length);\n\nXTCLINK\nXTAPI\nVOID\nRtlReverseWideString(IN OUT PWCHAR String,\n                     IN ULONG Length);\n\nXTCLINK\nXTAPI\nBOOLEAN\nRtlSameMemory(IN PCVOID LeftBuffer,\n              IN PCVOID RightBuffer,\n              IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nVOID\nRtlSetAllBits(IN PRTL_BITMAP BitMap);\n\nXTCLINK\nXTAPI\nVOID\nRtlSetBit(IN PRTL_BITMAP BitMap,\n          IN ULONG_PTR Bit);\n\nXTCLINK\nXTAPI\nVOID\nRtlSetBits(IN PRTL_BITMAP BitMap,\n           IN ULONG_PTR StartingIndex,\n           IN ULONG_PTR Length);\n\nXTCLINK\nXTAPI\nULONG\nRtlSetClearBits(IN PRTL_BITMAP BitMap,\n                IN ULONG_PTR Length,\n                IN ULONG_PTR Index);\n\nXTCLINK\nXTAPI\nVOID\nRtlSetMemory(OUT PVOID Destination,\n             IN UCHAR Byte,\n             IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nSIZE_T\nRtlStringLength(IN PCSTR String,\n                IN SIZE_T MaxLength);\n\nXTCLINK\nXTAPI\nSIZE_T\nRtlStringToWideString(OUT PWCHAR Destination,\n                      IN PCSTR *Source,\n                      IN SIZE_T Length);\n\nXTCLINK\nXTAPI\nBOOLEAN\nRtlTestBit(IN PRTL_BITMAP BitMap,\n           IN ULONG_PTR Bit);\n\nXTCLINK\nXTAPI\nXTSTATUS\nRtlTimeFieldsToUnixEpoch(IN PTIME_FIELDS TimeFields,\n                         OUT PLONGLONG UnixTime);\n\nXTCLINK\nXTAPI\nXTSTATUS\nRtlTimeFieldsToXtEpoch(IN PTIME_FIELDS TimeFields,\n                       OUT PLARGE_INTEGER XtTime);\n\nXTCLINK\nXTAPI\nPCHAR\nRtlTokenizeString(IN PCHAR String,\n                  IN PCSTR Delimiter,\n                  IN OUT PCHAR *SavePtr);\n\nXTCLINK\nXTAPI\nPWCHAR\nRtlTokenizeWideString(IN PWCHAR String,\n                      IN PCWSTR Delimiter,\n                      IN OUT PWCHAR *SavePtr);\n\nXTCLINK\nXTAPI\nCHAR\nRtlToLowerCharacter(IN CHAR Character);\n\nXTCLINK\nXTAPI\nWCHAR\nRtlToLowerWideCharacter(IN WCHAR Character);\n\nXTCLINK\nXTAPI\nCHAR\nRtlToUpperCharacter(IN CHAR Character);\n\nXTCLINK\nXTAPI\nWCHAR\nRtlToUpperWideCharacter(IN WCHAR Character);\n\nXTCLINK\nXTAPI\nPCHAR\nRtlTrimLeftString(IN PCHAR String);\n\nXTCLINK\nXTAPI\nPWCHAR\nRtlTrimLeftWideString(IN PWCHAR String);\n\nXTCLINK\nXTAPI\nPCHAR\nRtlTrimRightString(IN PCHAR String);\n\nXTCLINK\nXTAPI\nPWCHAR\nRtlTrimRightWideString(IN PWCHAR String);\n\nXTCLINK\nXTAPI\nPCHAR\nRtlTrimString(IN PCHAR String);\n\nXTCLINK\nXTAPI\nPWCHAR\nRtlTrimWideString(IN PWCHAR String);\n\nXTCLINK\nXTAPI\nSIZE_T\nRtlWideStringLength(IN PCWSTR String,\n                    IN SIZE_T MaxLength);\n\nXTCLINK\nXTAPI\nVOID\nRtlZeroMemory(OUT PVOID Destination,\n              IN SIZE_T Length);\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_RTLFUNCS_H */\n"
  },
  {
    "path": "sdk/xtdk/rtltypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/rtltypes.h\n * DESCRIPTION:     Runtime library structures definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_RTLTYPES_H\n#define __XTDK_RTLTYPES_H\n\n#include <xtbase.h>\n#include <xttypes.h>\n\n\n/* UUID string lengths */\n#define GUID_STRING_LENGTH              38\n#define PARTUUID_STRING_LENGTH          13\n\n/* Maximum double/integer value string length */\n#define MAX_DOUBLE_STRING_SIZE          15\n#define MAX_INTEGER_STRING_SIZE         25\n\n/* Floating point definitions */\n#define DOUBLE_EXPONENT_MASK            0x7FF0000000000000ULL\n#define DOUBLE_EXPONENT_SHIFT           0x34\n#define DOUBLE_EXPONENT_BIAS            0x3FF\n#define DOUBLE_HIGH_VALUE_MASK          0x000FFFFF\n#define DOUBLE_HIGH_VALUE_SHIFT         0x20\n#define DOUBLE_PRECISION                6\n#define DOUBLE_HEX_PRECISION            13\n#define DOUBLE_SCIENTIFIC_PRECISION     -4\n#define DOUBLE_SIGN_BIT                 0x8000000000000000ULL\n\n/* Print flag definitions */\n#define PFL_ALWAYS_PRINT_SIGN           0x00000001\n#define PFL_SPACE_FOR_PLUS              0x00000002\n#define PFL_LEFT_JUSTIFIED              0x00000004\n#define PFL_LEADING_ZEROES              0x00000008\n#define PFL_LONG_INTEGER                0x00000010\n#define PFL_LONG_DOUBLE                 0x00000020\n#define PFL_WIDE_CHARACTER              0x00000040\n#define PFL_SHORT_VALUE                 0x00000080\n#define PFL_UNSIGNED                    0x00000100\n#define PFL_UPPERCASE                   0x00000200\n#define PFL_PRINT_RADIX                 0x00000400\n#define PFL_FLOAT_FORMAT                0x00000800\n#define PFL_SCI_FORMAT                  0x00001000\n#define PFL_DIGIT_PRECISION             0x00002000\n#define PFL_THOUSANDS_GROUPING          0x00004000\n\n/* Cryptographic related definitions */\n#define SHA1_BLOCK_SIZE                 64\n#define SHA1_DIGEST_SIZE                20\n\n/* Time related definitions */\n#define TIME_SECONDS_PER_MINUTE         60\n#define TIME_SECONDS_PER_HOUR           3600\n#define TIME_SECONDS_PER_DAY            86400\n#define TIME_TICKS_PER_SECOND           10000000\n#define TIME_TICKS_PER_MILLISECOND      10000\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Runtime Library routine callbacks */\ntypedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);\ntypedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);\n\n/* Variable types enumeration list */\ntypedef enum _RTL_VARIABLE_TYPE\n{\n    TypeUnknown,\n    TypeAnsiString,\n    TypeBoolean,\n    TypeChar,\n    TypeFloat,\n    TypeGuid,\n    TypeInteger,\n    TypeString,\n    TypeUnicodeString,\n    TypeWideChar,\n    TypeWideString\n} RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;\n\n/* Bit Map structure definition */\ntypedef struct _RTL_BITMAP\n{\n    ULONG Size;\n    PULONG_PTR Buffer;\n} RTL_BITMAP, *PRTL_BITMAP;\n\n/* Runtime Library print context structure definition */\ntypedef struct _RTL_PRINT_CONTEXT\n{\n    PWRITE_CHARACTER WriteCharacter;\n    PWRITE_WIDE_CHARACTER WriteWideCharacter;\n    ULONG CharactersWritten;\n} RTL_PRINT_CONTEXT, *PRTL_PRINT_CONTEXT;\n\n/* Runtime Library print format properties structure definition */\ntypedef struct _RTL_PRINT_FORMAT_PROPERTIES\n{\n    RTL_VARIABLE_TYPE VariableType;\n    ULONG Radix;\n    LONG FieldWidth;\n    LONG IntegerSize;\n    LONG Precision;\n    LONG Flags;\n} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;\n\n/* Runtime Library SHA-1 context structure definition */\ntypedef struct _RTL_SHA1_CONTEXT\n{\n    ULONG   State[5];\n    ULONG   Count[2];\n    UCHAR   Buffer[SHA1_BLOCK_SIZE];\n} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;\n\n/* Runtime time fields structure definition */\ntypedef struct _TIME_FIELDS\n{\n    SHORT Year;\n    SHORT Month;\n    SHORT Day;\n    SHORT Hour;\n    SHORT Minute;\n    SHORT Second;\n    SHORT Milliseconds;\n    SHORT Weekday;\n} TIME_FIELDS, *PTIME_FIELDS;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_RTLTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/xtbase.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtbase.h\n * DESCRIPTION:     Basic and common native XT structures\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTBASE_H\n#define __XTDK_XTBASE_H\n\n#include <xtdefs.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Kernel affinity */\ntypedef ULONG_PTR KAFFINITY, *PKAFFINITY;\n\n/* Kernel priority */\ntypedef LONG KPRIORITY, *PKPRIORITY;\n\n/* Processor modes */\ntypedef CHAR KPROCESSOR_MODE, *PKPROCESSOR_MODE;\n\n/* Interrupt Request Run Level (IRQL) */\ntypedef UCHAR KRUNLEVEL, *PKRUNLEVEL;\n\n/* Spin locks synchronization mechanism */\ntypedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;\n\n/* Page Frame Number count */\ntypedef ULONG PFN_COUNT;\n\n/* Page Frame Number */\ntypedef ULONG_PTR PFN_NUMBER, *PPFN_NUMBER;\n\n/* Physical address */\ntypedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;\n\n/* 128-bit buffer containing a unique identifier value */\ntypedef struct _GUID\n{\n    UINT Data1;\n    USHORT Data2;\n    USHORT Data3;\n    UCHAR Data4[8];\n} GUID, *PGUID;\n\n/* Double linked list structure definition */\ntypedef struct _LIST_ENTRY\n{\n    PLIST_ENTRY Flink;\n    PLIST_ENTRY Blink;\n} LIST_ENTRY, *PLIST_ENTRY;\n\n/* 32-bit double linked list structure definition */\ntypedef struct _LIST_ENTRY32\n{\n    ULONG Flink;\n    ULONG Blink;\n} LIST_ENTRY32, *PLIST_ENTRY32;\n\n/* 64-bit double linked list structure definition */\ntypedef struct _LIST_ENTRY64\n{\n    ULONGLONG Flink;\n    ULONGLONG Blink;\n} LIST_ENTRY64, *PLIST_ENTRY64;\n\n/* Single linked list structure definition */\ntypedef struct _SINGLE_LIST_ENTRY\n{\n    PSINGLE_LIST_ENTRY Next;\n} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;\n\n/* Header for a sequenced single linked list union definition */\ntypedef union _SINGLE_LIST_HEADER\n{\n    ULONGLONG Alignment;\n    struct\n    {\n        SINGLE_LIST_ENTRY Next;\n        USHORT Depth;\n        USHORT Sequence;\n    };\n} SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;\n\n/* 128-bit 16-byte aligned XMM register */\ntypedef struct _M128\n{\n    ULONGLONG Low;\n    LONGLONG High;\n} ALIGN(16) M128, *PM128;\n\n/* Dispatcher object header structure definition */\ntypedef struct _DISPATCHER_HEADER\n{\n    UCHAR Type;\n    union\n    {\n        UCHAR Absolute;\n        UCHAR NpxIrql;\n    };\n    UCHAR Inserted;\n    BOOLEAN DebugActive;\n    LONG SignalState;\n    LIST_ENTRY WaitListHead;\n} DISPATCHER_HEADER, *PDISPATCHER_HEADER;\n\n#endif /* __XTOS_ASSEMBLER_ */\n#endif /* __XTDK_XTBASE_H */\n"
  },
  {
    "path": "sdk/xtdk/xtblapi.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtblapi.h\n * DESCRIPTION:     Top level header for the XT Boot Loader API\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n/* Base XT headers */\n#include <xtcompat.h>\n#include <xtdefs.h>\n#include <xtstatus.h>\n#include <xttarget.h>\n#include <xttypes.h>\n\n/* XT forward references */\n#include <xtstruct.h>\n\n/* Architecture-specific XT forward references */\n#include ARCH_HEADER(xtstruct.h)\n\n/* Architecture-independent XT API */\n#include <xtbase.h>\n#include <xtfw.h>\n#include <xtimage.h>\n#include <xtuefi.h>\n#include <xtdebug.h>\n#include <xtguid.h>\n\n/* Architecture independent XT kernel data types */\n#include <hltypes.h>\n#include <iotypes.h>\n#include <rtltypes.h>\n\n/* Architecture dependent XT kernel data types */\n#include ARCH_HEADER(artypes.h)\n#include ARCH_HEADER(hltypes.h)\n#include ARCH_HEADER(ketypes.h)\n#include ARCH_HEADER(mmtypes.h)\n\n/* Boot Manager specific structures */\n#include <bltarget.h>\n#include <bltypes.h>\n#include <blfuncs.h>\n"
  },
  {
    "path": "sdk/xtdk/xtcompat.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtcompat.h\n * DESCRIPTION:     C/C++ compatibility macros\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTDK_XTCOMPAT_H\n#define __XTDK_XTCOMPAT_H\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n#ifdef __cplusplus\n    /* C++ definitions */\n    #define NULLPTR         nullptr\n    #define VIRTUAL         virtual\n    #define XTCLINK         extern \"C\"\n    #define XTSYMBOL(Name)  __asm__(Name)\n\n    /* C++ boolean type */\n    typedef bool BOOLEAN, *PBOOLEAN;\n    #define TRUE true\n    #define FALSE false\n\n    /* C++ widechar type */\n    typedef wchar_t wchar;\n#else\n    /* C definitions */\n    #define NULLPTR         ((void *)0)\n    #define VIRTUAL\n    #define XTCLINK\n    #define XTSYMBOL(Name)\n\n    /* C boolean type */\n    typedef enum _BOOLEAN\n    {\n        FALSE = 0,\n        TRUE = 1\n    } BOOLEAN, *PBOOLEAN;\n\n    /* C widechar type */\n    typedef unsigned short wchar;\n#endif\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_XTCOMPAT_H */\n"
  },
  {
    "path": "sdk/xtdk/xtdebug.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtdebug.h\n * DESCRIPTION:     XT debugging support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTDEBUG_H\n#define __XTDK_XTDEBUG_H\n\n\n/* Debugging macros */\n#define CHECKPOINT                      DebugPrint(L\"Checkpoint reached at %s:%d\\n\", __RELFILE__, __LINE__);\n#define DEPRECATED                      DebugPrint(L\"Called deprecated routine '%s()' at %s:%d\\n\", \\\n                                                   __FUNCTION__, __RELFILE__, __LINE__);\n#define UNIMPLEMENTED                   DebugPrint(L\"Called unimplemented routine '%s()' at %s:%d\\n\", \\\n                                                   __FUNCTION__, __RELFILE__, __LINE__);\n\n/* XTOS platform debugging macros */\n#ifdef DBG\n    #define DEBUG                       1\n    #define DebugPrint(Format, ...)     DbgPrint(Format, __VA_ARGS__);\n#else\n    #define DEBUG                       0\n    #define DebugPrint(Format, ...)     ((VOID)NULLPTR)\n#endif\n\n#endif /* __XTDK_XTDEBUG_H */\n"
  },
  {
    "path": "sdk/xtdk/xtdefs.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtdefs.h\n * DESCRIPTION:     XT definitions for basic types\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTDEFS_H\n#define __XTDK_XTDEFS_H\n\n\n/* Routines and arguments modifiers */\n#define IN\n#define OUT\n#define XTAPI                                  __stdcall\n#define XTCDECL                                __cdecl\n#define XTFASTCALL                             __fastcall\n#define XTVECTORCALL                           __vectorcall\n#define XTINLINE                               __inline\n#define XTASSEMBLY                             __attribute__((naked))\n#define XTINTERRUPT                            __attribute__((interrupt))\n\n/* Variable modifiers */\n#define CONST                                  const\n#define EXTERN                                 extern\n#define STRUCT                                 struct\n#define STATIC                                 static\n#define UNION                                  union\n#define VOLATILE                               volatile\n\n/* Type limits */\n#define MINCHAR                                0x80\n#define MAXCHAR                                0x7F\n#define MINSHORT                               0x8000\n#define MAXSHORT                               0x7FFF\n#define MINLONG                                0x80000000\n#define MAXLONG                                0x7FFFFFFF\n#define MAXULONG                               0xFFFFFFFF\n\n/* Pointer limits */\n#define MININT_PTR                             (~MAXINT_PTR)\n#define MAXINT_PTR                             ((INT_PTR)(MAXUINT_PTR >> 1))\n#define MAXUINT_PTR                            (~((UINT_PTR)0))\n#define MINLONG_PTR                            (~MAXLONG_PTR)\n#define MAXLONG_PTR                            ((LONG_PTR)(MAXULONG_PTR >> 1))\n#define MAXULONG_PTR                           (~((ULONG_PTR)0))\n\n/* Number of bits per byte */\n#define BITS_PER_BYTE                          8\n\n/* Preprocessor macros for defining an additional compiler attributes */\n#define ALIGN(Alignment)                       __attribute__((aligned(Alignment)))\n#define PACKED                                 __attribute__((packed))\n#define SEGMENT(Segment)                       __attribute__((section(Segment)))\n#define USED                                   __attribute__((__used__))\n\n/* Macro for calculating size of an array */\n#define ARRAY_SIZE(Array)                      (sizeof(Array) / sizeof(*Array))\n\n/* Macros for converting Binary Coded Decimal (BCD) into decimal and vice versa */\n#define BCD_TO_DECIMAL(Value)                  (((Value) & 0x0F) + (((Value) >> 4) * 10))\n#define DECIMAL_TO_BCD(Value)                  ((((Value) / 10) << 4) | ((Value) % 10))\n\n/* Macros for concatenating two strings */\n#define CONCAT_STRING(Str1, Str2)              Str1##Str2\n#define CONCATENATE(Str1, Str2)                CONCAT_STRING(Str1, Str2)\n\n/* Macro for accessing the base address of a structure from a structure member */\n#define CONTAIN_RECORD(Address, Type, Field)   ((Type *)((char *)(Address) - FIELD_OFFSET(Type, Field)))\n\n/* EFI size to pages conversion macro */\n#define EFI_SIZE_TO_PAGES(Size)                (((Size) >> EFI_PAGE_SHIFT) + (((Size) & EFI_PAGE_MASK) ? 1 : 0))\n\n/* Macro for calculating byte offset of a field in the structure */\n#define FIELD_OFFSET(Structure, Field)         __builtin_offsetof(Structure, Field)\n\n/* Macro for calculating size of a field in the structure */\n#define FIELD_SIZE(Structure, Field)           (sizeof(((Structure *)0)->Field))\n\n/* Macros for calculating minimum and maximum of two values */\n#define MIN(A, B)                              (((A) < (B)) ? (A) : (B))\n#define MAX(A, B)                              (((A) > (B)) ? (A) : (B))\n\n/* Macro that page-aligns a virtual address */\n#define PAGE_ALIGN(VirtualAddress)             ((PVOID)((ULONG_PTR)VirtualAddress & ~MM_PAGE_MASK))\n\n/* Macro that returns offset of the virtual address */\n#define PAGE_OFFSET(VirtualAddress)            ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))\n\n/* Macros for bitwise rotating */\n#define ROTATE_LEFT(Value, Count)              ((Value << Count) | (Value >> (32 - Count)))\n#define ROTATE_RIGHT(Value, Count)             ((Value >> Count) | (Value << (32 - Count)))\n\n/* Macro for rounding down */\n#define ROUND_DOWN(Value, Alignment)           ((Value) & ~((Alignment) - 1))\n\n/* Macro for rounding up */\n#define ROUND_UP(Value, Alignment)             ROUND_DOWN((Value) + (Alignment - 1), Alignment)\n\n/* Macros for defining signatures built from ASCII characters */\n#define SIGNATURE16(A, B)                      ((A) | (B << 8))\n#define SIGNATURE32(A, B, C, D)                (SIGNATURE16(A, B) | (SIGNATURE16(C, D) << 16))\n#define SIGNATURE64(A, B, C, D, E, F, G, H)    (SIGNATURE32(A, B, C, D) | ((UINT64)(SIGNATURE32(E, F, G, H)) << 32))\n\n/* XT size <-> pages conversion macro */\n#define PAGES_TO_SIZE(Pages)                   ((Pages) << MM_PAGE_SHIFT)\n#define SIZE_TO_PAGES(Size)                    (((Size) >> MM_PAGE_SHIFT) + (((Size) & (MM_PAGE_MASK)) ? 1 : 0))\n\n/* Macros for concatenating strings */\n#define STRINGIFY(String...)                   STRINGIZE(String)\n#define STRINGIZE(String...)                   #String\n\n/* Macro for generating unique identifiers */\n#define UNIQUE(Prefix)                         CONCATENATE(CONCATENATE(__UNIQUE_ID_, Prefix), __COUNTER__)\n\n/* Variadic ABI functions */\n#define VA_ARG(Marker, Type)                   ((sizeof(Type) < sizeof(UINT_PTR)) ? \\\n                                               (Type)(__builtin_va_arg(Marker, UINT_PTR)) : \\\n                                               (Type)(__builtin_va_arg(Marker, Type)))\n#define VA_COPY(Dest, Start)                   __builtin_va_copy(Dest, Start)\n#define VA_START(Marker, Parameter)            __builtin_va_start(Marker, Parameter)\n#define VA_END(Marker)                         __builtin_va_end(Marker)\n\n/* Data conversion macros */\n#define HandleToLong(Var)                      ((LONG)(LONG_PTR)Var)\n#define HandleToUlong(Var)                     ((ULONG)(ULONG_PTR)Var)\n#define IntToPtr(Var)                          ((PVOID)(INT_PTR)Var)\n#define LongToHandle(Var)                      ((HANDLE)(LONG_PTR)Var)\n#define LongToPtr(Var)                         ((PVOID)(LONG_PTR)Var)\n#define PtrToInt(Var)                          ((INT)(INT_PTR)Var)\n#define PtrToLong(Var)                         ((LONG)(LONG_PTR)Var)\n#define PtrToShort(Var)                        ((SHORT)(LONG_PTR)Var)\n#define PtrToUint(Var)                         ((UINT)(UINT_PTR)Var)\n#define PtrToUlong(Var)                        ((ULONG)(ULONG_PTR)Var)\n#define PtrToUshort(Var)                       ((USHORT)(ULONG_PTR)Var)\n#define UintToPtr(Var)                         ((PVOID)(UINT_PTR)Var)\n#define UlongToHandle(Var)                     ((HANDLE)(ULONG_PTR)Var)\n#define UlongToPtr(Var)                        ((PVOID)(ULONG_PTR)Var)\n\n#endif /* __XTDK_XTDEFS_H */\n"
  },
  {
    "path": "sdk/xtdk/xtfont.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtfont.h\n * DESCRIPTION:     XT framebuffer native font\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTFONT_H\n#define __XTDK_XTFONT_H\n\n#include <xttypes.h>\n#include <xtdefs.h>\n\n\n/* C/C++ specific code */\n#ifndef D__XTOS_ASSEMBLER__\n\n/* SSF2 font header */\ntypedef struct _SSFN_FONT_HEADER\n{\n    UCHAR Magic[4];\n    UINT Size;\n    UCHAR Type;\n    UCHAR Features;\n    UCHAR Width;\n    UCHAR Height;\n    UCHAR Baseline;\n    UCHAR Underline;\n    USHORT FragmentsOffset;\n    UINT CharactersOffset;\n    UINT LigatureOffset;\n    UINT KerningOffset;\n    UINT ColorMapOffset;\n} SSFN_FONT_HEADER, *PSSFN_FONT_HEADER;\n\n/* XTOS font (VGA Unicode by Dmitry Yu. Bolkhovityanov (C) 2000, https://www.inp.nsk.su/~bolkhov/files/fonts/univga/) */\nUCHAR XtFbDefaultFont[] = {0x78, 0x74, 0x66, 0x6E, 0x3B, 0xE7, 0x00, 0x00, 0x03, 0x00, 0x08, 0x10, 0x0C, 0x0D, 0x7D,\n                           0x00, 0x41, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n                           0x00, 0x00, 0x56, 0x67, 0x61, 0x20, 0x55, 0x6E, 0x69, 0x63, 0x6F, 0x64, 0x65, 0x00, 0x56,\n                           0x47, 0x41, 0x00, 0x4D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0x00, 0x00, 0x42, 0x6F, 0x6C, 0x6B,\n                           0x68, 0x6F, 0x76, 0x00, 0x43, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28,\n                           0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x30, 0x20, 0x44, 0x6D, 0x69, 0x74, 0x72, 0x79, 0x20,\n                           0x42, 0x6F, 0x6C, 0x6B, 0x68, 0x6F, 0x76, 0x69, 0x74, 0x79, 0x61, 0x6E, 0x6F, 0x76, 0x2C,\n                           0x20, 0x62, 0x6F, 0x6C, 0x6B, 0x68, 0x6F, 0x76, 0x40, 0x69, 0x6E, 0x70, 0x2E, 0x6E, 0x73,\n                           0x6B, 0x2E, 0x73, 0x75, 0x00, 0x80, 0x00, 0x10, 0x80, 0x00, 0x7F, 0x80, 0x01, 0x18, 0x18,\n                           0x80, 0x00, 0x28, 0x80, 0x00, 0x3E, 0x80, 0x01, 0x0C, 0x0C, 0x80, 0x01, 0x30, 0x18, 0x80,\n                           0x01, 0x36, 0x36, 0x80, 0x01, 0x6E, 0x3B, 0x80, 0x06, 0x1E, 0x30, 0x3E, 0x33, 0x33, 0x33,\n                           0x6E, 0x80, 0x06, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x00, 0x08, 0x80, 0x00,\n                           0x7E, 0x80, 0x00, 0xFF, 0x80, 0x00, 0x20, 0x80, 0x06, 0x3E, 0x63, 0x7F, 0x03, 0x03, 0x63,\n                           0x3E, 0x80, 0x01, 0x36, 0x1C, 0x80, 0x06, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80,\n                           0x00, 0x50, 0x80, 0x01, 0x06, 0x0C, 0x80, 0x02, 0x18, 0x18, 0x0C, 0x80, 0x06, 0x1C, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x01, 0x66, 0x66, 0x80, 0x03, 0x02, 0x81, 0x81, 0x7E,\n                           0x80, 0x02, 0x10, 0x10, 0xEF, 0x80, 0x09, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7E, 0x60,\n                           0x30, 0x1F, 0x80, 0x00, 0x18, 0x80, 0x02, 0x08, 0x1C, 0x36, 0x80, 0x03, 0x10, 0x20, 0x20,\n                           0x1F, 0x80, 0x02, 0x36, 0x1C, 0x08, 0x80, 0x01, 0x33, 0x66, 0x80, 0x04, 0x10, 0x20, 0x40,\n                           0x42, 0x3C, 0x80, 0x05, 0x20, 0x40, 0x40, 0x20, 0x18, 0x06, 0x80, 0x06, 0x30, 0x48, 0x70,\n                           0x40, 0x20, 0x18, 0x06, 0x80, 0x03, 0x08, 0x38, 0x28, 0x1C, 0x80, 0x01, 0x77, 0x77, 0x80,\n                           0x08, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x80, 0x08, 0x7F, 0x66, 0x46,\n                           0x16, 0x1E, 0x16, 0x46, 0x66, 0x7F, 0x80, 0x04, 0x36, 0x51, 0x32, 0x14, 0x13, 0x80, 0x01,\n                           0x7F, 0x7F, 0x80, 0x08, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x08,\n                           0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x06, 0x3B, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0x80, 0x06, 0x3B, 0x6E, 0x66, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x06, 0x3E,\n                           0x63, 0x06, 0x1C, 0x30, 0x63, 0x3E, 0x80, 0x00, 0x36, 0x80, 0x06, 0x6E, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x6E, 0x80, 0x04, 0x60, 0x92, 0xA1, 0xC1, 0x7E, 0x80, 0x09, 0x6E, 0x33, 0x33,\n                           0x33, 0x33, 0x33, 0x3E, 0x30, 0x33, 0x1E, 0x80, 0x08, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x3E, 0x80, 0x01, 0x1C, 0x36, 0x80, 0x03, 0x02, 0x01, 0x81, 0x7E, 0x80, 0x06,\n                           0x3E, 0x63, 0x03, 0x03, 0x03, 0x63, 0x3E, 0x80, 0x06, 0x63, 0x63, 0x6B, 0x6B, 0x6B, 0x7F,\n                           0x36, 0x80, 0x00, 0x3C, 0x80, 0x02, 0x1C, 0x36, 0x1C, 0x80, 0x01, 0x66, 0x33, 0x80, 0x05,\n                           0x82, 0x81, 0x81, 0x81, 0x42, 0x3C, 0x80, 0x06, 0xE0, 0x10, 0x11, 0x61, 0x81, 0x81, 0x7E,\n                           0x80, 0x00, 0x3F, 0x80, 0x09, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C,\n                           0x80, 0x09, 0x67, 0x66, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x66, 0x67, 0x80, 0x06, 0x7F,\n                           0x33, 0x18, 0x0C, 0x06, 0x63, 0x7F, 0x80, 0x01, 0x0C, 0x18, 0x80, 0x08, 0x66, 0x66, 0x66,\n                           0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x01, 0xC0, 0xC0, 0x80, 0x02, 0x18, 0x18, 0x18,\n                           0x80, 0x06, 0x60, 0x90, 0x8C, 0x79, 0x11, 0x11, 0x0E, 0x80, 0x03, 0x1C, 0xE2, 0x18, 0x07,\n                           0x80, 0x03, 0x0E, 0xF1, 0x4C, 0x83, 0x80, 0x06, 0x30, 0x48, 0xF0, 0x40, 0x20, 0x18, 0x06,\n                           0x80, 0x09, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x01, 0x60,\n                           0x60, 0x80, 0x07, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x00, 0x14, 0x80,\n                           0x08, 0x0E, 0xF1, 0x0C, 0x02, 0x01, 0x01, 0x01, 0x82, 0x7C, 0x80, 0x05, 0x80, 0xA8, 0x11,\n                           0x21, 0x21, 0x1E, 0x80, 0x01, 0x28, 0x10, 0x80, 0x04, 0x70, 0x1C, 0x07, 0x1C, 0x70, 0x80,\n                           0x04, 0x07, 0x1C, 0x70, 0x1C, 0x07, 0x80, 0x09, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63,\n                           0x63, 0x63, 0x63, 0x80, 0x09, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x3F,\n                           0x80, 0x09, 0x7F, 0x66, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x46, 0x66, 0x7F, 0x80, 0x09, 0x63,\n                           0x63, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x63, 0x80, 0x09, 0x0F, 0x06, 0x06, 0x06,\n                           0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x80, 0x09, 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x80, 0x09, 0x63, 0x67, 0x6F, 0x7F, 0x7B, 0x73, 0x63, 0x63, 0x63, 0x63,\n                           0x80, 0x09, 0x38, 0x30, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x09, 0x70,\n                           0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x3C, 0x80, 0x09, 0x1C, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x06, 0x37, 0x7F, 0x6B, 0x6B, 0x6B, 0x6B, 0x63,\n                           0x80, 0x06, 0x63, 0x36, 0x1C, 0x1C, 0x1C, 0x36, 0x63, 0x80, 0x01, 0x18, 0x0C, 0x80, 0x08,\n                           0x3F, 0x66, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x66, 0x67, 0x80, 0x06, 0x1C, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x70, 0x80, 0x06, 0x33, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x06, 0x63,\n                           0x73, 0x7B, 0x7F, 0x6F, 0x67, 0x63, 0x80, 0x01, 0x03, 0x03, 0x80, 0x04, 0x18, 0x24, 0x44,\n                           0x44, 0x38, 0x80, 0x09, 0x0E, 0x01, 0x31, 0x0E, 0x02, 0x01, 0x01, 0x01, 0x82, 0x7C, 0x80,\n                           0x00, 0x02, 0x80, 0x03, 0x08, 0x08, 0x08, 0x08, 0x80, 0x08, 0x20, 0x90, 0x48, 0x20, 0x10,\n                           0x22, 0x41, 0x41, 0x3E, 0x80, 0x02, 0x1C, 0x30, 0x18, 0x80, 0x04, 0x10, 0x10, 0x20, 0x62,\n                           0x9C, 0x80, 0x04, 0xE0, 0x11, 0xE1, 0x81, 0x7E, 0x80, 0x04, 0x18, 0x18, 0x7E, 0x18, 0x18,\n                           0x80, 0x09, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x80, 0x09, 0x3E,\n                           0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x3F, 0x66, 0x66, 0x66,\n                           0x3E, 0x36, 0x66, 0x66, 0x66, 0x67, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x06, 0x1C, 0x30, 0x60,\n                           0x63, 0x63, 0x3E, 0x80, 0x09, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E,\n                           0x80, 0x09, 0x63, 0x63, 0x36, 0x3E, 0x1C, 0x1C, 0x3E, 0x36, 0x63, 0x63, 0x80, 0x09, 0x66,\n                           0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x7F, 0x63, 0x61, 0x30,\n                           0x18, 0x0C, 0x06, 0x43, 0x63, 0x7F, 0x80, 0x02, 0x0C, 0x0C, 0x18, 0x80, 0x09, 0x07, 0x06,\n                           0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x67, 0x80, 0x09, 0x07, 0x06, 0x06, 0x66, 0x36,\n                           0x1E, 0x1E, 0x36, 0x66, 0x67, 0x80, 0x09, 0x3B, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x06,\n                           0x06, 0x0F, 0x80, 0x09, 0x08, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x80,\n                           0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x80, 0x03, 0x18, 0x18, 0x18, 0x18, 0x80,\n                           0x08, 0x63, 0x67, 0x6F, 0x7F, 0x7B, 0x73, 0x63, 0x63, 0x63, 0x80, 0x06, 0x33, 0x6E, 0x6C,\n                           0x7E, 0x1B, 0x1B, 0x76, 0x80, 0x08, 0x3C, 0x66, 0x43, 0x03, 0x7B, 0x63, 0x63, 0x66, 0x5C,\n                           0x80, 0x06, 0x67, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x67, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x63,\n                           0x7F, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x00, 0x33, 0x80, 0x06, 0x3E, 0x63, 0x60, 0x60,\n                           0x7F, 0x63, 0x3E, 0x80, 0x07, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x06,\n                           0x3E, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x3E, 0x80, 0x08, 0x63, 0x63, 0x63, 0x63, 0x7E, 0x60,\n                           0x60, 0x63, 0x3E, 0x80, 0x00, 0x04, 0x80, 0x08, 0x60, 0x90, 0x90, 0xE2, 0x81, 0x81, 0x81,\n                           0x42, 0x3C, 0x80, 0x06, 0x98, 0x84, 0x98, 0x84, 0x80, 0x81, 0x7E, 0x80, 0x03, 0x30, 0x0C,\n                           0x30, 0x0C, 0x80, 0x01, 0x30, 0x0C, 0x80, 0x01, 0x30, 0xC8, 0x80, 0x08, 0x63, 0x63, 0x63,\n                           0x6B, 0x6B, 0x6B, 0x7F, 0x77, 0x36, 0x80, 0x03, 0x70, 0xC8, 0x5C, 0x36, 0x80, 0x07, 0x63,\n                           0x63, 0x36, 0x36, 0x1C, 0x1C, 0x08, 0x08, 0x80, 0x02, 0x38, 0x38, 0x38, 0x80, 0x04, 0x30,\n                           0x48, 0x50, 0x60, 0x3F, 0x80, 0x04, 0x30, 0x48, 0x48, 0x30, 0xCF, 0x80, 0x04, 0x20, 0xE0,\n                           0x20, 0x18, 0x06, 0x80, 0x03, 0x60, 0x94, 0x8C, 0x7B, 0x80, 0x03, 0x18, 0x18, 0x18, 0x0C,\n                           0x80, 0x09, 0x3C, 0x66, 0x43, 0x03, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3C, 0x80, 0x09, 0x3F,\n                           0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x09, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x36, 0x1C, 0x08, 0x80, 0x09, 0x07, 0x06, 0x06, 0x1E, 0x36, 0x66, 0x66,\n                           0x66, 0x66, 0x3E, 0x80, 0x04, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x09, 0x1F, 0x36, 0x66,\n                           0x66, 0x6F, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x80, 0x09, 0x3E, 0x63, 0x03, 0x03, 0x03, 0x63,\n                           0x3E, 0x18, 0x30, 0x1C, 0x80, 0x01, 0x33, 0x33, 0x80, 0x02, 0x18, 0x0C, 0x0C, 0x80, 0x08,\n                           0x63, 0x63, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x80, 0x08, 0x3E, 0x63, 0x63, 0x06,\n                           0x1C, 0x30, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x3B, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60,\n                           0x60, 0x60, 0x80, 0x09, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x80,\n                           0x00, 0x0C, 0x80, 0x09, 0x7F, 0x60, 0x30, 0x18, 0x3C, 0x60, 0x60, 0x60, 0x63, 0x3E, 0x80,\n                           0x06, 0x3E, 0x63, 0x03, 0x1E, 0x03, 0x63, 0x3E, 0x80, 0x06, 0x3E, 0x63, 0x60, 0x3C, 0x60,\n                           0x63, 0x3E, 0x80, 0x06, 0x36, 0x63, 0x6B, 0x6B, 0x6B, 0x6B, 0x36, 0x80, 0x08, 0x63, 0x63,\n                           0x73, 0x7B, 0x7F, 0x6F, 0x67, 0x63, 0x63, 0x80, 0x06, 0x6B, 0x6B, 0x6B, 0x3E, 0x6B, 0x6B,\n                           0x6B, 0x80, 0x06, 0x36, 0x63, 0x6B, 0x6B, 0x6B, 0x7F, 0x36, 0x80, 0x01, 0x18, 0x66, 0x80,\n                           0x00, 0x66, 0x80, 0x01, 0x06, 0x06, 0x80, 0x04, 0x18, 0x24, 0x04, 0x78, 0x04, 0x80, 0x05,\n                           0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x80, 0x03, 0x18, 0x04, 0x38, 0x04, 0x80, 0x09, 0x40,\n                           0x40, 0x40, 0x40, 0x40, 0x42, 0x41, 0x41, 0x21, 0x1E, 0x80, 0x00, 0x24, 0x80, 0x02, 0x60,\n                           0x94, 0x7A, 0x80, 0x05, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x80, 0x08, 0x0E, 0xF1, 0x0C,\n                           0x02, 0x29, 0x01, 0x11, 0x82, 0x7C, 0x80, 0x08, 0x04, 0x1C, 0x14, 0x0E, 0x10, 0x20, 0x40,\n                           0x42, 0x3C, 0x80, 0x00, 0x40, 0x80, 0x03, 0x10, 0x10, 0x10, 0x10, 0x80, 0x01, 0x10, 0x28,\n                           0x80, 0x06, 0xE0, 0x10, 0x11, 0x61, 0x81, 0x41, 0x3E, 0x80, 0x03, 0x18, 0x3C, 0x3C, 0x18,\n                           0x80, 0x06, 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x80, 0x04, 0x57, 0x54, 0x72, 0x71,\n                           0x77, 0x80, 0x01, 0xDB, 0xDB, 0x80, 0x06, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80,\n                           0x07, 0x08, 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x63, 0x63, 0x80, 0x01, 0x3B, 0x6E, 0x80, 0x0F,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x80, 0x01, 0xFF, 0xFF, 0x80, 0x04, 0x60, 0x92, 0x91, 0x61, 0xBE, 0x80, 0x03, 0x38,\n                           0x04, 0x38, 0x04, 0x80, 0x06, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x80, 0x09, 0x3C,\n                           0x66, 0x43, 0x03, 0x03, 0x7B, 0x63, 0x63, 0x66, 0x5C, 0x80, 0x09, 0x78, 0x30, 0x30, 0x30,\n                           0x30, 0x30, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x09, 0x63, 0x63, 0x63, 0x63, 0x6B, 0x6B, 0x6B,\n                           0x7F, 0x77, 0x36, 0x80, 0x03, 0x08, 0x1C, 0x36, 0x63, 0x80, 0x06, 0x08, 0x1C, 0x36, 0x63,\n                           0x63, 0x63, 0x7F, 0x80, 0x03, 0x1C, 0x36, 0x36, 0x1C, 0x80, 0x05, 0x0E, 0x1B, 0x0C, 0x06,\n                           0x13, 0x1F, 0x80, 0x05, 0x0E, 0x1B, 0x0C, 0x18, 0x1B, 0x0E, 0x80, 0x09, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x33, 0x6F, 0x03, 0x03, 0x03, 0x80, 0x05, 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E,\n                           0x80, 0x0B, 0x08, 0x1C, 0x36, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x80,\n                           0x09, 0x7C, 0x36, 0x33, 0x33, 0x7F, 0x33, 0x33, 0x33, 0x33, 0x73, 0x80, 0x0C, 0x3C, 0x66,\n                           0x43, 0x03, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3C, 0x18, 0x30, 0x1C, 0x80, 0x0B, 0x08, 0x1C,\n                           0x22, 0x7F, 0x66, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x66, 0x7F, 0x80, 0x0B, 0x08, 0x1C, 0x22,\n                           0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x06, 0x5E, 0x23, 0x73, 0x6B,\n                           0x67, 0x62, 0x3D, 0x80, 0x08, 0x3C, 0x66, 0x43, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3C, 0x80,\n                           0x09, 0x30, 0x7C, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x09, 0x06, 0x1F,\n                           0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x67, 0x80, 0x01, 0x66, 0x3C, 0x80, 0x08, 0x0F,\n                           0x06, 0x06, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x80, 0x08, 0x1C, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x3C, 0x80, 0x00, 0x1E, 0x80, 0x08, 0x7F, 0x63, 0x31, 0x18, 0x0C, 0x06,\n                           0x43, 0x63, 0x7F, 0x80, 0x09, 0x1E, 0x33, 0x61, 0x60, 0x60, 0x60, 0x60, 0x61, 0x33, 0x1E,\n                           0x80, 0x09, 0x3E, 0x63, 0x60, 0x60, 0x60, 0x7F, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x3E,\n                           0x63, 0x43, 0x03, 0x1E, 0x03, 0x03, 0x43, 0x63, 0x3E, 0x80, 0x0B, 0xC0, 0xC0, 0x5E, 0x33,\n                           0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x09, 0xC0, 0xC0, 0x60, 0x1E, 0x33,\n                           0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x09, 0x7F, 0x63, 0x46, 0x0C, 0x18, 0x18, 0x0C, 0x46,\n                           0x63, 0x7F, 0x80, 0x0B, 0xC0, 0xC0, 0x73, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,\n                           0x1E, 0x80, 0x09, 0xC0, 0xC0, 0x60, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x09,\n                           0x77, 0x36, 0x36, 0x36, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0x7C, 0x36, 0x33, 0x33, 0x7F, 0x33,\n                           0x33, 0x33, 0x73, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x0C, 0x06, 0x1C,\n                           0x80, 0x09, 0x1C, 0x18, 0x18, 0xFE, 0x9B, 0x5B, 0x5B, 0x5B, 0x3B, 0xF6, 0x80, 0x01, 0x3C,\n                           0x66, 0x80, 0x09, 0x3E, 0x63, 0x7F, 0x03, 0x03, 0x63, 0x3E, 0x18, 0x30, 0x1C, 0x80, 0x09,\n                           0x4E, 0x39, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x63, 0x62, 0x36,\n                           0x34, 0x34, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0C, 0x08, 0x08, 0x08, 0x3E, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x3E, 0x08, 0x08, 0x08, 0x80, 0x06, 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66,\n                           0x3F, 0x80, 0x06, 0x63, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x80, 0x03, 0x7F, 0x63, 0x63,\n                           0x63, 0x80, 0x02, 0x18, 0x0C, 0x06, 0x80, 0x02, 0x18, 0x30, 0x18, 0x80, 0x02, 0x0E, 0x18,\n                           0x0C, 0x80, 0x09, 0x7F, 0x66, 0x46, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x09,\n                           0x08, 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x63, 0x63, 0x63, 0x7F, 0x80, 0x09, 0x7F, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x80, 0x09, 0x08, 0x3E, 0x6B, 0x6B, 0x6B, 0x6B,\n                           0x6B, 0x3E, 0x08, 0x08, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x36, 0x36,\n                           0x77, 0x80, 0x08, 0x67, 0x66, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x66, 0x67, 0x80, 0x06, 0x7F,\n                           0x66, 0x46, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x06, 0x63, 0x63, 0x63, 0x7E, 0x60, 0x60, 0x60,\n                           0x80, 0x06, 0xC3, 0xC3, 0xC3, 0xCF, 0xDB, 0xDB, 0xCF, 0x80, 0x06, 0x3E, 0x63, 0x60, 0x7C,\n                           0x60, 0x63, 0x3E, 0x80, 0x06, 0x43, 0x63, 0x26, 0x36, 0x1C, 0x1C, 0x08, 0x80, 0x02, 0x20,\n                           0x3E, 0x02, 0x80, 0x01, 0x3E, 0x2A, 0x80, 0x01, 0x66, 0x18, 0x80, 0x0B, 0x63, 0x63, 0x63,\n                           0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0xE3, 0xC0, 0x80, 0x80, 0x08, 0x63, 0x63, 0x63, 0x7F,\n                           0x63, 0x63, 0xE3, 0xC0, 0x80, 0x80, 0x02, 0x30, 0x30, 0x3C, 0x80, 0x02, 0x18, 0x0C, 0x18,\n                           0x80, 0x07, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0x40, 0x3C, 0x02,\n                           0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x80, 0x08, 0x18, 0x04, 0x38, 0x04, 0x10, 0x10, 0x10,\n                           0x10, 0x10, 0x80, 0x0A, 0x38, 0x04, 0x38, 0x04, 0x30, 0x48, 0x70, 0x40, 0x20, 0x18, 0x06,\n                           0x80, 0x04, 0x28, 0x02, 0x81, 0x81, 0x7E, 0x80, 0x08, 0x0E, 0xF1, 0x0C, 0x02, 0x01, 0x11,\n                           0x01, 0x82, 0x7C, 0x80, 0x06, 0x04, 0x04, 0x04, 0x34, 0x4C, 0x45, 0x3E, 0x80, 0x06, 0x24,\n                           0x04, 0x04, 0x34, 0x4C, 0x45, 0x3E, 0x80, 0x09, 0x30, 0x48, 0x48, 0x3C, 0x02, 0x02, 0x02,\n                           0x02, 0x02, 0x02, 0x80, 0x05, 0x02, 0x0C, 0x72, 0x92, 0x9C, 0x67, 0x80, 0x04, 0x30, 0x48,\n                           0x53, 0x34, 0x0E, 0x80, 0x04, 0x10, 0x28, 0x30, 0x10, 0x08, 0x80, 0x03, 0x50, 0x54, 0x34,\n                           0x08, 0x80, 0x02, 0x18, 0x24, 0x18, 0x80, 0x03, 0x30, 0x08, 0x30, 0x08, 0x80, 0x08, 0x04,\n                           0x0E, 0x0E, 0x1C, 0x18, 0x18, 0x10, 0x10, 0x10, 0x80, 0x08, 0x22, 0x3F, 0x1F, 0x06, 0x0C,\n                           0x0C, 0x08, 0x08, 0x08, 0x80, 0x08, 0x52, 0x7F, 0x2F, 0x06, 0x0C, 0x0C, 0x08, 0x08, 0x08,\n                           0x80, 0x08, 0x41, 0x63, 0x63, 0x36, 0x14, 0x1C, 0x08, 0x08, 0x08, 0x80, 0x08, 0x08, 0x08,\n                           0x08, 0x1C, 0x14, 0x36, 0x63, 0x63, 0x41, 0x80, 0x08, 0x0E, 0x1F, 0x11, 0x1F, 0x1E, 0x10,\n                           0x30, 0x70, 0x60, 0x80, 0x07, 0x08, 0x08, 0x1C, 0x7F, 0x3E, 0x1C, 0x36, 0x22, 0x80, 0x04,\n                           0x20, 0x20, 0x20, 0x20, 0x20, 0x80, 0x02, 0x60, 0x14, 0x7A, 0x80, 0x03, 0xC0, 0x20, 0xC0,\n                           0x20, 0x80, 0x0B, 0xC4, 0x2A, 0xCC, 0x24, 0x02, 0x30, 0x48, 0x70, 0x40, 0x20, 0x18, 0x06,\n                           0x80, 0x08, 0x0E, 0xF1, 0x0C, 0x02, 0x01, 0x29, 0x01, 0x82, 0x7C, 0x80, 0x08, 0x0E, 0xF1,\n                           0x0C, 0x02, 0x11, 0x01, 0x11, 0x82, 0x7C, 0x80, 0x08, 0x0E, 0xF1, 0x0C, 0x02, 0x29, 0x01,\n                           0x29, 0x82, 0x7C, 0x80, 0x05, 0x80, 0xA8, 0x11, 0x11, 0x09, 0xA6, 0x80, 0x00, 0x0A, 0x80,\n                           0x07, 0x80, 0x40, 0x20, 0x10, 0x22, 0x41, 0x41, 0x3E, 0x80, 0x06, 0x94, 0x80, 0x98, 0x84,\n                           0x98, 0x85, 0x7E, 0x80, 0x08, 0x25, 0x90, 0x48, 0x20, 0x10, 0x22, 0x41, 0x41, 0x3E, 0x80,\n                           0x08, 0x1C, 0x02, 0x1C, 0x02, 0x18, 0x24, 0x44, 0x44, 0x38, 0x80, 0x06, 0x30, 0x48, 0x70,\n                           0x40, 0x3C, 0x18, 0x06, 0x80, 0x0B, 0x08, 0x14, 0x18, 0x08, 0x04, 0x30, 0x48, 0x70, 0x40,\n                           0x20, 0x18, 0x06, 0x80, 0x04, 0x10, 0x28, 0x06, 0x01, 0x7F, 0x80, 0x03, 0xA8, 0x51, 0x09,\n                           0x06, 0x80, 0x04, 0x30, 0x30, 0x08, 0x08, 0x08, 0x80, 0x03, 0x08, 0x0C, 0x02, 0x7C, 0x80,\n                           0x04, 0x10, 0x28, 0x44, 0x28, 0x10, 0x80, 0x08, 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63,\n                           0x63, 0x63, 0x80, 0x03, 0x30, 0x18, 0x6E, 0x3B, 0x80, 0x08, 0x3F, 0x66, 0x66, 0x66, 0x3E,\n                           0x06, 0x06, 0x06, 0x0F, 0x80, 0x08, 0x63, 0x63, 0x36, 0x3E, 0x1C, 0x3E, 0x36, 0x63, 0x63,\n                           0x80, 0x03, 0xC0, 0x64, 0x0E, 0x1B, 0x80, 0x03, 0x03, 0x26, 0x70, 0xD8, 0x80, 0x03, 0x66,\n                           0x66, 0x66, 0x33, 0x80, 0x09, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18,\n                           0x80, 0x06, 0x49, 0x22, 0x14, 0x49, 0x14, 0x22, 0x49, 0x80, 0x05, 0x0E, 0x1B, 0x1B, 0x1B,\n                           0x1B, 0x0E, 0x80, 0x05, 0x18, 0x1C, 0x1E, 0x1B, 0x3F, 0x18, 0x80, 0x05, 0x1F, 0x03, 0x0F,\n                           0x18, 0x1B, 0x0E, 0x80, 0x05, 0x1E, 0x03, 0x0F, 0x1B, 0x1B, 0x0E, 0x80, 0x05, 0x1F, 0x1B,\n                           0x0C, 0x0C, 0x06, 0x06, 0x80, 0x05, 0x0E, 0x1B, 0x0E, 0x1B, 0x1B, 0x0E, 0x80, 0x05, 0x0E,\n                           0x1B, 0x1B, 0x1E, 0x18, 0x0F, 0x80, 0x04, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x80, 0x05, 0x0C,\n                           0x06, 0x06, 0x06, 0x06, 0x0C, 0x80, 0x05, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x06, 0x80, 0x04,\n                           0x0D, 0x1B, 0x1B, 0x1B, 0x1B, 0x80, 0x01, 0xA0, 0xA0, 0x80, 0x06, 0x0F, 0x07, 0x0D, 0x18,\n                           0x30, 0x60, 0xC0, 0x80, 0x02, 0x0C, 0x06, 0xFF, 0x80, 0x02, 0xFF, 0x06, 0x0C, 0x80, 0x02,\n                           0x30, 0x60, 0xFF, 0x80, 0x02, 0xFF, 0x60, 0x30, 0x80, 0x04, 0x0C, 0x06, 0x7F, 0x06, 0x0C,\n                           0x80, 0x04, 0x18, 0x30, 0x7F, 0x30, 0x18, 0x80, 0x03, 0x18, 0x24, 0x24, 0x18, 0x80, 0x06,\n                           0x40, 0x60, 0x38, 0x0F, 0x38, 0x60, 0x40, 0x80, 0x06, 0x01, 0x03, 0x0E, 0x78, 0x0E, 0x03,\n                           0x01, 0x80, 0x05, 0x7E, 0x03, 0x03, 0x03, 0x03, 0x7E, 0x80, 0x05, 0x3F, 0x60, 0x60, 0x60,\n                           0x60, 0x3F, 0x80, 0x05, 0x7F, 0x03, 0x03, 0x03, 0x03, 0x7F, 0x80, 0x05, 0x7F, 0x60, 0x60,\n                           0x60, 0x60, 0x7F, 0x80, 0x06, 0x60, 0x78, 0x6E, 0x63, 0x6E, 0x78, 0x60, 0x80, 0x06, 0x03,\n                           0x0F, 0x3B, 0x63, 0x3B, 0x0F, 0x03, 0x80, 0x01, 0x08, 0x08, 0x80, 0x0F, 0x0C, 0x0C, 0x0C,\n                           0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x80, 0x0F,\n                           0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,\n                           0x30, 0x80, 0x01, 0xFF, 0xC3, 0x80, 0x01, 0xC3, 0xFF, 0x80, 0x0F, 0x03, 0x03, 0x03, 0x03,\n                           0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x03, 0x38,\n                           0x38, 0x38, 0x38, 0x80, 0x06, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x07, 0xEF,\n                           0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x80, 0x06, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,\n                           0xEF, 0x80, 0x08, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x02, 0x54,\n                           0x7E, 0x55, 0x80, 0x05, 0x20, 0x20, 0x20, 0x20, 0x20, 0xC0, 0x80, 0x06, 0x60, 0x18, 0x04,\n                           0x08, 0x10, 0x10, 0x0F, 0x80, 0x06, 0x60, 0x18, 0x04, 0x04, 0x08, 0x10, 0xEF, 0x80, 0x08,\n                           0x20, 0x90, 0x48, 0x20, 0x10, 0x12, 0x21, 0x41, 0xBE, 0x80, 0x08, 0x30, 0x0C, 0x62, 0x18,\n                           0x04, 0x08, 0x10, 0x10, 0x0F, 0x80, 0x08, 0x30, 0x0C, 0x62, 0x18, 0x04, 0x04, 0x08, 0x10,\n                           0xEF, 0x80, 0x05, 0x80, 0x82, 0x81, 0x81, 0x42, 0x3C, 0x80, 0x06, 0x08, 0x1C, 0x32, 0x4A,\n                           0x4C, 0xBC, 0x02, 0x80, 0x03, 0xE0, 0x18, 0x04, 0xFC, 0x80, 0x01, 0x10, 0x08, 0x80, 0x02,\n                           0x60, 0x18, 0x06, 0x80, 0x03, 0x30, 0x08, 0x70, 0x08, 0x80, 0x05, 0x08, 0x08, 0x16, 0x11,\n                           0x2E, 0xC0, 0x80, 0x08, 0x0E, 0xF1, 0x4C, 0x82, 0x01, 0x01, 0x01, 0x02, 0x7C, 0x80, 0x02,\n                           0x80, 0xA8, 0x57, 0x80, 0x01, 0x54, 0xAB, 0x80, 0x09, 0x78, 0x44, 0x38, 0x44, 0x82, 0x01,\n                           0x01, 0x01, 0x82, 0x7C, 0x80, 0x03, 0x70, 0x08, 0x08, 0x7F, 0x80, 0x03, 0x78, 0x44, 0x38,\n                           0xC7, 0x80, 0x07, 0x42, 0x44, 0x48, 0x50, 0x20, 0x30, 0x48, 0x3C, 0x80, 0x06, 0x44, 0x48,\n                           0x48, 0x50, 0x50, 0x70, 0xBC, 0x80, 0x09, 0x5B, 0x40, 0x01, 0x41, 0x40, 0x01, 0x41, 0x40,\n                           0x01, 0x6D, 0x80, 0x03, 0x66, 0x66, 0x66, 0x24, 0x80, 0x08, 0x36, 0x36, 0x7F, 0x36, 0x36,\n                           0x36, 0x7F, 0x36, 0x36, 0x80, 0x0D, 0x18, 0x18, 0x3E, 0x63, 0x43, 0x03, 0x3E, 0x60, 0x60,\n                           0x61, 0x63, 0x3E, 0x18, 0x18, 0x80, 0x07, 0x43, 0x63, 0x30, 0x18, 0x0C, 0x06, 0x63, 0x61,\n                           0x80, 0x09, 0x1C, 0x36, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x03, 0x0C,\n                           0x0C, 0x0C, 0x04, 0x80, 0x09, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30,\n                           0x80, 0x09, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x80, 0x04, 0x66,\n                           0x3C, 0xFF, 0x3C, 0x66, 0x80, 0x07, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80,\n                           0x09, 0x1C, 0x36, 0x63, 0x63, 0x6B, 0x6B, 0x63, 0x63, 0x36, 0x1C, 0x80, 0x09, 0x18, 0x1C,\n                           0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x80, 0x09, 0x3E, 0x63, 0x60, 0x30, 0x18,\n                           0x0C, 0x06, 0x03, 0x63, 0x7F, 0x80, 0x09, 0x3E, 0x63, 0x60, 0x60, 0x3C, 0x60, 0x60, 0x60,\n                           0x63, 0x3E, 0x80, 0x09, 0x30, 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x30, 0x30, 0x78, 0x80,\n                           0x09, 0x7F, 0x03, 0x03, 0x03, 0x3F, 0x60, 0x60, 0x60, 0x63, 0x3E, 0x80, 0x09, 0x1C, 0x06,\n                           0x03, 0x03, 0x3F, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x7F, 0x63, 0x60, 0x60, 0x30,\n                           0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x63, 0x3E, 0x63, 0x63, 0x63,\n                           0x63, 0x3E, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x63, 0x7E, 0x60, 0x60, 0x60, 0x30, 0x1E, 0x80,\n                           0x08, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x80, 0x08, 0x06, 0x0C, 0x18,\n                           0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x80, 0x06, 0x3E, 0x63, 0x63, 0x30, 0x18, 0x18, 0x18,\n                           0x80, 0x08, 0x3E, 0x63, 0x63, 0x7B, 0x7B, 0x7B, 0x3B, 0x03, 0x3E, 0x80, 0x09, 0x7F, 0x66,\n                           0x46, 0x16, 0x1E, 0x16, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x0B, 0x3E, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x6B, 0x7B, 0x3E, 0x30, 0x70, 0x80, 0x09, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,\n                           0x0C, 0x0C, 0x0C, 0x3C, 0x80, 0x08, 0x01, 0x03, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0x60, 0x40,\n                           0x80, 0x09, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x80, 0x09, 0x1C,\n                           0x36, 0x26, 0x06, 0x0F, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x09, 0x6E, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x3E, 0x30, 0x30, 0x78, 0x80, 0x09, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18,\n                           0x18, 0x18, 0x70, 0x80, 0x09, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0E,\n                           0x80, 0x06, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x80, 0x0A, 0x18, 0x18, 0x3C, 0x66,\n                           0x06, 0x06, 0x06, 0x66, 0x3C, 0x18, 0x18, 0x80, 0x0A, 0x1C, 0x36, 0x26, 0x06, 0x0F, 0x06,\n                           0x06, 0x06, 0x06, 0x67, 0x3F, 0x80, 0x06, 0x66, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x66, 0x80,\n                           0x09, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x80, 0x0B, 0x3E, 0x63,\n                           0x06, 0x1C, 0x36, 0x63, 0x63, 0x36, 0x1C, 0x30, 0x63, 0x3E, 0x80, 0x09, 0x3C, 0x42, 0x99,\n                           0xA5, 0x85, 0x85, 0xA5, 0x99, 0x42, 0x3C, 0x80, 0x03, 0x3C, 0x36, 0x36, 0x7C, 0x80, 0x04,\n                           0x6C, 0x36, 0x1B, 0x36, 0x6C, 0x80, 0x04, 0x7F, 0x60, 0x60, 0x60, 0x60, 0x80, 0x06, 0x1C,\n                           0x22, 0x5D, 0x4D, 0x55, 0x22, 0x1C, 0x80, 0x09, 0xFE, 0xDB, 0xDB, 0xDB, 0xDE, 0xD8, 0xD8,\n                           0xD8, 0xD8, 0xD8, 0x80, 0x02, 0x18, 0x30, 0x1C, 0x80, 0x04, 0x1B, 0x36, 0x6C, 0x36, 0x1B,\n                           0x80, 0x0C, 0x03, 0x03, 0x43, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x73, 0x79, 0x7C, 0x60, 0x60,\n                           0x80, 0x0C, 0x03, 0x03, 0x43, 0x63, 0x33, 0x18, 0x0C, 0x06, 0x3B, 0x61, 0x30, 0x18, 0x7C,\n                           0x80, 0x0C, 0x07, 0x0C, 0x46, 0x6C, 0x37, 0x18, 0x0C, 0x66, 0x73, 0x79, 0x7C, 0x60, 0x60,\n                           0x80, 0x06, 0x0C, 0x0C, 0x06, 0x03, 0x63, 0x63, 0x3E, 0x80, 0x0B, 0x1C, 0x36, 0x1C, 0x08,\n                           0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x80, 0x0B, 0x18, 0x3C, 0x42, 0x3C, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x04, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x80,\n                           0x09, 0x5E, 0x23, 0x73, 0x73, 0x6B, 0x6B, 0x67, 0x67, 0x62, 0x3D, 0x80, 0x0B, 0x08, 0x1C,\n                           0x22, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x0F, 0x06, 0x3E,\n                           0x66, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x0F, 0x80, 0x09, 0x3C, 0x66, 0x66, 0x66, 0x36, 0x66,\n                           0x66, 0x66, 0x66, 0x37, 0x80, 0x09, 0x6E, 0x38, 0x3C, 0x60, 0x7E, 0x63, 0x63, 0x63, 0x63,\n                           0x3E, 0x80, 0x0C, 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x06,\n                           0x0F, 0x80, 0x0C, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x30, 0x18,\n                           0x70, 0x80, 0x09, 0x1E, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x6E, 0x30, 0x18, 0x70, 0x80, 0x0B,\n                           0x08, 0x1C, 0x22, 0x3C, 0x66, 0x43, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3C, 0x80, 0x0B, 0x36,\n                           0x1C, 0x08, 0x3C, 0x66, 0x43, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3C, 0x80, 0x0B, 0x36, 0x1C,\n                           0x08, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x80, 0x0B, 0x36, 0x1C, 0x08,\n                           0x30, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x0B, 0x7F, 0x66, 0x46, 0x16,\n                           0x1E, 0x16, 0x46, 0x66, 0x7F, 0x18, 0x0C, 0x38, 0x80, 0x09, 0x3E, 0x63, 0x7F, 0x03, 0x03,\n                           0x63, 0x3E, 0x0C, 0x06, 0x1C, 0x80, 0x0B, 0x36, 0x1C, 0x08, 0x7F, 0x66, 0x46, 0x16, 0x1E,\n                           0x16, 0x46, 0x66, 0x7F, 0x80, 0x0B, 0x08, 0x1C, 0x22, 0x3C, 0x66, 0x43, 0x03, 0x7B, 0x63,\n                           0x63, 0x66, 0x5C, 0x80, 0x01, 0x08, 0x1C, 0x80, 0x0B, 0x08, 0x1C, 0x22, 0x07, 0x06, 0x36,\n                           0x6E, 0x66, 0x66, 0x66, 0x66, 0x67, 0x80, 0x09, 0x66, 0xFF, 0x66, 0x66, 0x7E, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0x80, 0x0B, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x18,\n                           0x0C, 0x38, 0x80, 0x09, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x18, 0x0C, 0x38, 0x80,\n                           0x09, 0xEF, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xDE, 0xDE, 0x77, 0x80, 0x09, 0x77, 0x66,\n                           0x66, 0x66, 0x66, 0x66, 0x6F, 0x60, 0x66, 0x3C, 0x80, 0x0B, 0x10, 0x38, 0x44, 0x78, 0x30,\n                           0x30, 0x30, 0x30, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x02, 0x20, 0x70, 0xD8, 0x80, 0x0B, 0x36,\n                           0x1C, 0x08, 0x0F, 0x06, 0x06, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x80, 0x0B, 0x36, 0x1C,\n                           0x08, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x0F, 0x06, 0x06,\n                           0x06, 0x66, 0x66, 0x06, 0x46, 0x66, 0x7F, 0x80, 0x09, 0x0E, 0x0C, 0x0C, 0x0C, 0x6C, 0x6C,\n                           0x0C, 0x0C, 0x0C, 0x1E, 0x80, 0x09, 0x0F, 0x06, 0x06, 0x06, 0x1E, 0x07, 0x06, 0x46, 0x66,\n                           0x7F, 0x80, 0x09, 0x1C, 0x18, 0x18, 0x18, 0x78, 0x1E, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x0B,\n                           0x36, 0x1C, 0x08, 0x63, 0x67, 0x6F, 0x7F, 0x7B, 0x73, 0x63, 0x63, 0x63, 0x80, 0x02, 0x06,\n                           0x06, 0x03, 0x80, 0x0C, 0x63, 0x67, 0x6F, 0x7F, 0x7B, 0x73, 0x63, 0x63, 0x63, 0x63, 0x60,\n                           0x60, 0x38, 0x80, 0x09, 0x3B, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x38, 0x80,\n                           0x09, 0x76, 0x1B, 0x1B, 0x1B, 0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x76, 0x80, 0x06, 0x36, 0x6B,\n                           0x6B, 0x7B, 0x1B, 0x1B, 0x76, 0x80, 0x0B, 0x36, 0x1C, 0x08, 0x3F, 0x66, 0x66, 0x66, 0x3E,\n                           0x36, 0x66, 0x66, 0x67, 0x80, 0x0B, 0x08, 0x1C, 0x22, 0x3E, 0x63, 0x63, 0x06, 0x1C, 0x30,\n                           0x63, 0x63, 0x3E, 0x80, 0x0B, 0x3E, 0x63, 0x63, 0x06, 0x1C, 0x30, 0x63, 0x63, 0x3E, 0x18,\n                           0x30, 0x1C, 0x80, 0x09, 0x3E, 0x63, 0x06, 0x1C, 0x30, 0x63, 0x3E, 0x18, 0x30, 0x1C, 0x80,\n                           0x0B, 0x36, 0x1C, 0x08, 0x3E, 0x63, 0x63, 0x06, 0x1C, 0x30, 0x63, 0x63, 0x3E, 0x80, 0x0C,\n                           0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x18, 0x30, 0x1C, 0x80, 0x0C,\n                           0x08, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x18, 0x30, 0x1C, 0x80, 0x0B,\n                           0x36, 0x1C, 0x08, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x0B, 0x36,\n                           0x1C, 0x08, 0x08, 0x0C, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x80, 0x09, 0x7E, 0x7E,\n                           0x5A, 0x18, 0x18, 0x3C, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x08, 0x0C, 0x0C, 0x3F, 0x0C,\n                           0x3F, 0x0C, 0x0C, 0x6C, 0x38, 0x80, 0x01, 0x33, 0x1E, 0x80, 0x0B, 0x1C, 0x36, 0x1C, 0x63,\n                           0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x0B, 0x63, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x3E, 0x0C, 0x06, 0x1C, 0x80, 0x09, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,\n                           0x6E, 0x0C, 0x06, 0x1C, 0x80, 0x0B, 0x08, 0x1C, 0x22, 0x63, 0x63, 0x63, 0x6B, 0x6B, 0x6B,\n                           0x7F, 0x77, 0x36, 0x80, 0x0B, 0x08, 0x1C, 0x22, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18,\n                           0x18, 0x3C, 0x80, 0x0B, 0x36, 0x1C, 0x08, 0x7F, 0x63, 0x31, 0x18, 0x0C, 0x06, 0x43, 0x63,\n                           0x7F, 0x80, 0x09, 0x1C, 0x36, 0x26, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x09,\n                           0x06, 0x1F, 0x06, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x80, 0x09, 0x7E, 0xCD, 0xCD,\n                           0xCC, 0x7C, 0xCC, 0xCC, 0xCC, 0xCC, 0x7E, 0x80, 0x09, 0x3F, 0x26, 0x06, 0x06, 0x3E, 0x66,\n                           0x66, 0x66, 0x66, 0x3F, 0x80, 0x09, 0x7E, 0x46, 0x06, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66,\n                           0x3E, 0x80, 0x09, 0x3E, 0x67, 0x67, 0x66, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x3F, 0x80, 0x09,\n                           0x06, 0x07, 0x07, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x80, 0x0A, 0xC0, 0x7C, 0x66,\n                           0x43, 0x03, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3C, 0x80, 0x07, 0xC0, 0x7E, 0x63, 0x03, 0x03,\n                           0x03, 0x63, 0x3E, 0x80, 0x09, 0x3E, 0x6D, 0xCD, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x6C, 0x3E,\n                           0x80, 0x09, 0x7E, 0x32, 0x30, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x80, 0x09, 0x3E,\n                           0x32, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x63,\n                           0x63, 0x3E, 0x0C, 0x18, 0x33, 0x1E, 0x80, 0x09, 0x7F, 0x33, 0x31, 0x34, 0x3C, 0x34, 0x30,\n                           0x31, 0x33, 0x7F, 0x80, 0x0C, 0x7F, 0x66, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x06, 0x06, 0x06,\n                           0x06, 0x06, 0x03, 0x80, 0x0C, 0x38, 0x6C, 0x4C, 0x0C, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,\n                           0x0C, 0x0C, 0x07, 0x80, 0x0A, 0xC0, 0x7C, 0x66, 0x43, 0x03, 0x03, 0x7B, 0x63, 0x63, 0x66,\n                           0x5C, 0x80, 0x0B, 0x63, 0x63, 0x63, 0x36, 0x36, 0x36, 0x1C, 0x1C, 0x08, 0x1C, 0x36, 0x1C,\n                           0x80, 0x09, 0x03, 0x03, 0x03, 0xCF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x73, 0x80, 0x09, 0x0E,\n                           0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x80, 0x09, 0x3C, 0x18, 0x18, 0x18,\n                           0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x67, 0xB6, 0x36, 0x1E, 0x0E, 0x1E, 0x36,\n                           0x66, 0x66, 0x67, 0x80, 0x09, 0x1C, 0x36, 0x06, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x67,\n                           0x80, 0x09, 0x1C, 0x18, 0x18, 0x18, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x13,\n                           0x1C, 0x0E, 0x0B, 0x1C, 0x1C, 0x36, 0x26, 0x63, 0x43, 0x80, 0x09, 0x6B, 0x6B, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x6B, 0x7F, 0x37, 0x80, 0x0C, 0x66, 0x66, 0x6E, 0x7E, 0x7E, 0x76, 0x66,\n                           0x66, 0x66, 0x66, 0x06, 0x06, 0x03, 0x80, 0x0C, 0xCE, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,\n                           0xDB, 0xDB, 0xCE, 0xC0, 0xC0, 0xC0, 0x80, 0x09, 0xCE, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE,\n                           0xC0, 0xC0, 0xC0, 0x80, 0x09, 0x7E, 0xCD, 0xCD, 0xCC, 0x7C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E,\n                           0x80, 0x0C, 0x1C, 0x36, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F,\n                           0x80, 0x0A, 0x0F, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x1E, 0x36, 0x36, 0x67, 0x60, 0x80, 0x09,\n                           0x3E, 0x63, 0x63, 0x30, 0x1C, 0x06, 0x03, 0x63, 0x63, 0x3E, 0x80, 0x06, 0x3E, 0x63, 0x30,\n                           0x1C, 0x06, 0x63, 0x3E, 0x80, 0x0C, 0x0E, 0x1B, 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0xD8, 0x70, 0x80, 0x0C, 0x08, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C,\n                           0x38, 0x30, 0x36, 0x1C, 0x80, 0x09, 0x7E, 0x7F, 0x59, 0x1A, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x3C, 0x80, 0x09, 0x38, 0x6C, 0x0C, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x80, 0x0C,\n                           0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x70, 0x80, 0x09,\n                           0x33, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x33, 0x1E, 0x80, 0x09, 0xC6, 0xCD, 0xCD,\n                           0xCC, 0x78, 0x30, 0x30, 0x30, 0x30, 0x78, 0x80, 0x0B, 0x60, 0xB0, 0x33, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x3E, 0x30, 0x18, 0x0F, 0x80, 0x09, 0x7F, 0x63, 0x61, 0x30, 0x7E, 0x0C, 0x06,\n                           0x43, 0x63, 0x7F, 0x80, 0x06, 0x7F, 0x33, 0x18, 0x3F, 0x06, 0x63, 0x7F, 0x80, 0x0B, 0x7F,\n                           0x60, 0x30, 0x18, 0x0C, 0x3E, 0x60, 0x60, 0x60, 0x60, 0x63, 0x3E, 0x80, 0x0B, 0x7F, 0x03,\n                           0x06, 0x0C, 0x18, 0x3E, 0x03, 0x03, 0x03, 0x03, 0x63, 0x3E, 0x80, 0x09, 0x7F, 0x03, 0x06,\n                           0x0C, 0x1E, 0x03, 0x03, 0x03, 0x63, 0x3E, 0x80, 0x09, 0x7F, 0x60, 0x30, 0x18, 0x3C, 0x60,\n                           0x3E, 0x03, 0x63, 0x3E, 0x80, 0x09, 0x3E, 0x63, 0x60, 0x30, 0x7E, 0x0C, 0x06, 0x03, 0x63,\n                           0x7F, 0x80, 0x09, 0x7F, 0x06, 0x06, 0x1E, 0x30, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x80, 0x06,\n                           0x7F, 0x06, 0x1E, 0x30, 0x60, 0x66, 0x3C, 0x80, 0x09, 0x08, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C,\n                           0x18, 0x32, 0x36, 0x1C, 0x80, 0x09, 0x3B, 0x66, 0x66, 0x66, 0x36, 0x1E, 0x0E, 0x06, 0x06,\n                           0x0F, 0x80, 0x09, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0B,\n                           0xD8, 0x70, 0x20, 0xEF, 0x9B, 0x9B, 0x5B, 0x5B, 0x5B, 0x3B, 0x3B, 0xEF, 0x80, 0x09, 0xAF,\n                           0x5B, 0x1B, 0xFB, 0x9B, 0x5B, 0x5B, 0x5B, 0x3B, 0xEF, 0x80, 0x09, 0xBC, 0x58, 0x18, 0xFE,\n                           0x9B, 0x5B, 0x5B, 0x5B, 0x3B, 0xF6, 0x80, 0x09, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,\n                           0xC3, 0xD3, 0x6F, 0x80, 0x0C, 0xCF, 0xC6, 0x06, 0xE6, 0xC6, 0xC6, 0xC6, 0xE6, 0xF6, 0xFF,\n                           0xC0, 0xD8, 0x70, 0x80, 0x0C, 0xC7, 0xC6, 0x06, 0xE6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xCF,\n                           0xC0, 0xCC, 0x78, 0x80, 0x09, 0xDB, 0xDB, 0xDF, 0xDF, 0xDF, 0xDB, 0xDB, 0xDB, 0xDB, 0x7B,\n                           0x80, 0x0C, 0xDB, 0xDB, 0x1F, 0xFF, 0xDF, 0xDF, 0xDB, 0xDB, 0xDB, 0xDB, 0xC0, 0xCC, 0x78,\n                           0x80, 0x09, 0xED, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xC0, 0xCC, 0x78, 0x80, 0x0B, 0x36,\n                           0x1C, 0x08, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x80, 0x0B, 0x36, 0x1C,\n                           0x08, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x0B, 0x36, 0x1C, 0x08,\n                           0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x0B, 0x36, 0x1C, 0x08, 0x63,\n                           0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x02, 0x10, 0x08, 0x36, 0x80, 0x02,\n                           0x14, 0x08, 0x36, 0x80, 0x01, 0x1E, 0x0C, 0x80, 0x02, 0x04, 0x08, 0x36, 0x80, 0x09, 0x36,\n                           0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x80, 0x0B, 0x3E, 0x0C, 0x0C, 0x08,\n                           0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x80, 0x09, 0x3C, 0x66, 0x43, 0x03, 0x03,\n                           0x7B, 0x63, 0xFB, 0x66, 0x5C, 0x80, 0x09, 0x6E, 0x33, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x7C,\n                           0x33, 0x1E, 0x80, 0x0B, 0x36, 0x1C, 0x08, 0x3C, 0x66, 0x43, 0x03, 0x7B, 0x63, 0x63, 0x66,\n                           0x5C, 0x80, 0x0B, 0x36, 0x1C, 0x08, 0x67, 0x66, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x66, 0x67,\n                           0x80, 0x0B, 0x36, 0x1C, 0x08, 0x07, 0x06, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x67, 0x80,\n                           0x0C, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x0C, 0x06, 0x1C, 0x80,\n                           0x0B, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x0C, 0x06, 0x1C, 0x80, 0x0D,\n                           0x36, 0x1C, 0x08, 0x7F, 0x30, 0x18, 0x0C, 0x3E, 0x60, 0x60, 0x60, 0x60, 0x63, 0x3E, 0x80,\n                           0x02, 0xD8, 0x70, 0x20, 0x80, 0x09, 0xEF, 0x9B, 0x9B, 0x5B, 0x5B, 0x5B, 0x5B, 0x3B, 0x3B,\n                           0xEF, 0x80, 0x09, 0x0F, 0x1B, 0x1B, 0xFB, 0x9B, 0x5B, 0x5B, 0x5B, 0x3B, 0xEF, 0x80, 0x09,\n                           0x1B, 0x1B, 0x1B, 0xDB, 0xDF, 0xDB, 0xDB, 0xDB, 0xDB, 0x73, 0x80, 0x0C, 0x3F, 0x66, 0x66,\n                           0x66, 0x66, 0x36, 0x1E, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x07, 0x80, 0x0B, 0x30, 0x18, 0x1C,\n                           0x36, 0x1C, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x80, 0x0B, 0x30, 0x18, 0x1C, 0x36,\n                           0x1C, 0x1E, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x08, 0x5E, 0x23, 0x73, 0x73, 0x6B,\n                           0x67, 0x67, 0x62, 0x3D, 0x80, 0x01, 0x1E, 0x33, 0x80, 0x0B, 0x3E, 0x63, 0x61, 0x60, 0x38,\n                           0x2E, 0x60, 0x60, 0x60, 0x60, 0x38, 0x0F, 0x80, 0x08, 0x3E, 0x63, 0x60, 0x70, 0x3C, 0x60,\n                           0x60, 0x38, 0x0F, 0x80, 0x0B, 0x36, 0x1C, 0x08, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x63, 0x63,\n                           0x63, 0x63, 0x80, 0x0B, 0x36, 0x1C, 0x08, 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66,\n                           0x67, 0x80, 0x09, 0x36, 0x63, 0x63, 0x63, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x09,\n                           0x24, 0x66, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x80, 0x0B, 0x7F, 0x63, 0x61,\n                           0x30, 0x18, 0x0C, 0x06, 0x03, 0x03, 0x3F, 0x60, 0x30, 0x80, 0x08, 0x7F, 0x33, 0x18, 0x0C,\n                           0x06, 0x03, 0x3F, 0x60, 0x30, 0x80, 0x0C, 0x7F, 0x66, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x46,\n                           0x66, 0x7F, 0x18, 0x30, 0x1C, 0x80, 0x06, 0x3B, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C, 0x80,\n                           0x06, 0x2E, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x06, 0x3B, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x3A, 0x80, 0x09, 0x1C, 0x36, 0x06, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x80,\n                           0x06, 0x3E, 0x63, 0x60, 0x60, 0x60, 0x63, 0x3E, 0x80, 0x07, 0x3E, 0x63, 0x03, 0x03, 0x3B,\n                           0x67, 0x3E, 0x01, 0x80, 0x0C, 0x38, 0x30, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x3E,\n                           0x30, 0xB0, 0x60, 0x80, 0x09, 0x60, 0xB0, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6E,\n                           0x80, 0x06, 0x3E, 0x63, 0x7F, 0x60, 0x60, 0x63, 0x3E, 0x80, 0x06, 0xDC, 0x36, 0x71, 0x68,\n                           0x64, 0x36, 0x1C, 0x80, 0x06, 0x5E, 0xB3, 0xB0, 0x1C, 0x30, 0x33, 0x1E, 0x80, 0x06, 0x3E,\n                           0x63, 0x63, 0x3B, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x70, 0x60, 0x60, 0xF8, 0x60, 0x60, 0x60,\n                           0x66, 0x66, 0x3C, 0x80, 0x0B, 0x60, 0xB0, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3E, 0x30,\n                           0x33, 0x1E, 0x80, 0x06, 0x3E, 0x63, 0x03, 0x73, 0x63, 0x63, 0x5E, 0x80, 0x06, 0x43, 0x26,\n                           0x14, 0x1C, 0x1C, 0x36, 0x1C, 0x80, 0x09, 0x73, 0x33, 0x33, 0x33, 0x33, 0x3B, 0x36, 0x30,\n                           0x30, 0x70, 0x80, 0x09, 0x1C, 0x36, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x67, 0x80,\n                           0x0C, 0x1C, 0x36, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x67, 0x60, 0x60, 0x38, 0x80,\n                           0x06, 0x1C, 0x18, 0x18, 0x3C, 0x18, 0x18, 0x3C, 0x80, 0x06, 0x3C, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x3C, 0x80, 0x09, 0x1C, 0x18, 0x18, 0x18, 0xDE, 0x7B, 0x18, 0x18, 0x18, 0x3C, 0x80,\n                           0x09, 0x1C, 0x18, 0x18, 0x18, 0x1E, 0x1A, 0x7C, 0x18, 0x18, 0x3C, 0x80, 0x0C, 0x1C, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x80, 0x0C, 0x07, 0x06,\n                           0x06, 0xFE, 0xC6, 0x66, 0x36, 0x7E, 0xC6, 0xCF, 0xC0, 0xCC, 0x78, 0x80, 0x06, 0x63, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x7F, 0x76, 0x80, 0x09, 0x63, 0x6B, 0x6B, 0x6B, 0x6B, 0x7F, 0x76, 0x60,\n                           0x60, 0x60, 0x80, 0x09, 0x37, 0x7F, 0x6B, 0x6B, 0x6B, 0x6B, 0x63, 0x60, 0x60, 0x38, 0x80,\n                           0x09, 0x3B, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x03, 0x80, 0x09, 0x3B, 0x66,\n                           0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0xC0, 0x80, 0x06, 0x63, 0x67, 0x6F, 0x7F, 0x7B,\n                           0x73, 0x63, 0x80, 0x06, 0x76, 0x1B, 0x1B, 0x7B, 0x1B, 0x1B, 0x76, 0x80, 0x06, 0x78, 0x30,\n                           0x30, 0x30, 0x33, 0x3B, 0x6E, 0x80, 0x09, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33,\n                           0x3B, 0x6E, 0x80, 0x09, 0x78, 0x30, 0x30, 0x30, 0x33, 0x3B, 0x36, 0x30, 0xB0, 0x60, 0x80,\n                           0x09, 0x3B, 0x6E, 0x66, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x09, 0x3B, 0x6E,\n                           0x66, 0x06, 0x06, 0x06, 0x06, 0x06, 0x36, 0x1C, 0x80, 0x06, 0x3C, 0x66, 0x66, 0x06, 0x06,\n                           0x06, 0x0F, 0x80, 0x06, 0x1E, 0x33, 0x33, 0x30, 0x30, 0x30, 0x78, 0x80, 0x06, 0x3F, 0x66,\n                           0x66, 0x3E, 0x36, 0x66, 0x67, 0x80, 0x06, 0x67, 0x66, 0x36, 0x3E, 0x66, 0x66, 0x3F, 0x80,\n                           0x09, 0x3E, 0x63, 0x06, 0x1C, 0x30, 0x63, 0x3F, 0x03, 0x1B, 0x0E, 0x80, 0x0C, 0x70, 0xD8,\n                           0x98, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x1B, 0x0E, 0x80, 0x0C, 0x70, 0xD8,\n                           0x98, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x19, 0x1B, 0x0E, 0x80, 0x07, 0x0E, 0x1B,\n                           0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x80, 0x0A, 0x70, 0xD8, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x7E, 0x1B, 0x0E, 0x80, 0x09, 0x0E, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18,\n                           0x08, 0x80, 0x0C, 0x08, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C,\n                           0x38, 0x80, 0x06, 0x66, 0x66, 0x66, 0xFF, 0x66, 0x66, 0xDC, 0x80, 0x06, 0x77, 0x36, 0x36,\n                           0x63, 0x63, 0x63, 0x3E, 0x80, 0x06, 0x18, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x80, 0x06,\n                           0x36, 0x7F, 0x6B, 0x6B, 0x6B, 0x63, 0x63, 0x80, 0x09, 0x7C, 0x06, 0x03, 0x3F, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x63, 0x80, 0x06, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0x80, 0x09,\n                           0x7F, 0x33, 0x18, 0x0C, 0x06, 0x63, 0x7F, 0x60, 0x60, 0xC0, 0x80, 0x07, 0x7F, 0x33, 0x18,\n                           0x0C, 0x66, 0xD3, 0x7F, 0x08, 0x80, 0x09, 0x7F, 0x60, 0x30, 0x18, 0x3C, 0x60, 0x60, 0x7E,\n                           0xE3, 0x3E, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x60, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80,\n                           0x09, 0x3E, 0x63, 0x63, 0x03, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x80, 0x09, 0x3C, 0x18,\n                           0x18, 0x18, 0x18, 0x38, 0x60, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x3E, 0x63, 0x03, 0x03, 0x03,\n                           0x03, 0x03, 0x03, 0x63, 0x3E, 0x80, 0x09, 0x3C, 0x66, 0xC3, 0xC3, 0xDB, 0xDB, 0xC3, 0xC3,\n                           0x66, 0x3C, 0x80, 0x06, 0x3E, 0x63, 0x63, 0x6E, 0x63, 0x63, 0x3E, 0x80, 0x07, 0xC0, 0x7E,\n                           0x63, 0x03, 0x73, 0x63, 0x63, 0x5E, 0x80, 0x01, 0x30, 0x30, 0x80, 0x09, 0x38, 0x30, 0x30,\n                           0x30, 0x30, 0x30, 0x30, 0x7E, 0x33, 0x1E, 0x80, 0x09, 0x73, 0x33, 0x36, 0x3C, 0x3C, 0x36,\n                           0x33, 0x30, 0x30, 0x70, 0x80, 0x06, 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x80, 0x0B,\n                           0x60, 0xB0, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x30, 0x78, 0x80, 0x09, 0x3E,\n                           0x63, 0x63, 0x60, 0x38, 0x18, 0x7E, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x03,\n                           0x0E, 0x0C, 0x3F, 0x0C, 0x0C, 0x1E, 0x80, 0x0C, 0x1C, 0x18, 0x18, 0xFE, 0xDB, 0xDB, 0x7B,\n                           0x7B, 0xDB, 0xD6, 0xC0, 0xD8, 0x70, 0x80, 0x0A, 0x1C, 0x18, 0x18, 0xFE, 0x9B, 0x5B, 0x5B,\n                           0xDB, 0xBB, 0xF6, 0x20, 0x80, 0x09, 0x04, 0x06, 0x06, 0x6F, 0xB6, 0x36, 0x66, 0xC6, 0xD6,\n                           0x6C, 0x80, 0x0C, 0x64, 0xB6, 0x36, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3C, 0x30, 0x34,\n                           0x18, 0x80, 0x09, 0x04, 0x06, 0x06, 0x6F, 0xB6, 0x36, 0x36, 0x76, 0xB6, 0x6C, 0x80, 0x0C,\n                           0x0E, 0x1B, 0x03, 0x7F, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xC0, 0xC0, 0x70, 0x80, 0x09,\n                           0x07, 0x06, 0x06, 0x66, 0xB6, 0x36, 0x66, 0xC6, 0xD6, 0x6F, 0x80, 0x09, 0x07, 0x06, 0x06,\n                           0xF6, 0xD6, 0xC6, 0x66, 0x36, 0xB6, 0xFF, 0x80, 0x09, 0x63, 0x6B, 0x3E, 0x36, 0x14, 0x63,\n                           0x6B, 0x3E, 0x36, 0x14, 0x80, 0x05, 0x03, 0x03, 0x0F, 0x1B, 0x1B, 0x1B, 0x80, 0x05, 0x0E,\n                           0x03, 0x0F, 0x1B, 0x1B, 0x1B, 0x80, 0x04, 0x1C, 0x18, 0x18, 0x1B, 0x0E, 0x80, 0x03, 0x0D,\n                           0x1B, 0x03, 0x03, 0x80, 0x03, 0x18, 0x18, 0x1B, 0x16, 0x80, 0x04, 0x18, 0x18, 0x1B, 0x16,\n                           0x30, 0x80, 0x05, 0x1B, 0x1B, 0x0F, 0x1B, 0x1B, 0x0F, 0x80, 0x03, 0x63, 0x6B, 0x3E, 0x36,\n                           0x80, 0x04, 0x1B, 0x1B, 0x1E, 0x18, 0x0E, 0x80, 0x02, 0x6C, 0x36, 0x1B, 0x80, 0x02, 0x0C,\n                           0x06, 0x0C, 0x80, 0x04, 0x0E, 0x1B, 0x18, 0x0C, 0x0C, 0x80, 0x04, 0x0E, 0x1B, 0x03, 0x06,\n                           0x06, 0x80, 0x04, 0x18, 0x0E, 0x03, 0x0E, 0x18, 0x80, 0x04, 0x03, 0x0E, 0x18, 0x0E, 0x03,\n                           0x80, 0x05, 0x04, 0x04, 0x0E, 0x0E, 0x1B, 0x1B, 0x80, 0x05, 0x1B, 0x1B, 0x0E, 0x0E, 0x04,\n                           0x04, 0x80, 0x01, 0x18, 0x30, 0x80, 0x01, 0x0C, 0x06, 0x80, 0x02, 0x18, 0x0C, 0x38, 0x80,\n                           0x03, 0x36, 0x36, 0x36, 0x12, 0x80, 0x01, 0x2C, 0x1A, 0x80, 0x01, 0x03, 0x06, 0x80, 0x01,\n                           0xC0, 0x60, 0x80, 0x02, 0x0C, 0x04, 0x02, 0x80, 0x02, 0x08, 0x04, 0x06, 0x80, 0x02, 0x0C,\n                           0x2C, 0x18, 0x80, 0x01, 0x06, 0x03, 0x80, 0x0B, 0x06, 0x03, 0x08, 0x1C, 0x36, 0x63, 0x63,\n                           0x7F, 0x63, 0x63, 0x63, 0x63, 0x80, 0x0B, 0x06, 0x03, 0x7C, 0x4C, 0x0C, 0x2C, 0x3C, 0x2C,\n                           0x0C, 0x0C, 0x4C, 0x7C, 0x80, 0x0B, 0x06, 0x03, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC,\n                           0xCC, 0xCC, 0xCC, 0x80, 0x0B, 0x06, 0x03, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x3C, 0x80, 0x0B, 0x06, 0x03, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x3C, 0x80, 0x0B, 0x06, 0x03, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C,\n                           0x80, 0x0B, 0x06, 0x03, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x6C, 0x6C, 0x6C, 0xEE, 0x80,\n                           0x09, 0x08, 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x63, 0x63, 0x63, 0x63, 0x80, 0x05, 0x7F, 0x63,\n                           0x41, 0x22, 0x3E, 0x22, 0x80, 0x02, 0x41, 0x63, 0x7F, 0x80, 0x09, 0x08, 0x49, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x3E, 0x08, 0x08, 0x80, 0x0C, 0x3C, 0x66, 0x66, 0x66, 0x36, 0x66, 0x66,\n                           0x66, 0x66, 0x36, 0x06, 0x06, 0x06, 0x80, 0x09, 0x3C, 0x66, 0x0C, 0x18, 0x3E, 0x63, 0x63,\n                           0x63, 0x63, 0x3E, 0x80, 0x0C, 0x62, 0x3E, 0x18, 0x0C, 0x06, 0x06, 0x03, 0x03, 0x03, 0x3E,\n                           0x60, 0x60, 0x38, 0x80, 0x09, 0x3C, 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x3C,\n                           0x80, 0x09, 0x03, 0x04, 0x0C, 0x08, 0x1C, 0x1C, 0x36, 0x26, 0x63, 0x43, 0x80, 0x06, 0x63,\n                           0x63, 0x66, 0x36, 0x3C, 0x1C, 0x08, 0x80, 0x0C, 0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x06, 0x03,\n                           0x03, 0x03, 0x3E, 0x60, 0x60, 0x38, 0x80, 0x06, 0x7F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x66,\n                           0x80, 0x09, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x80, 0x08, 0x3E,\n                           0x63, 0x03, 0x03, 0x03, 0x3E, 0x60, 0x60, 0x38, 0x80, 0x06, 0x7E, 0x33, 0x33, 0x33, 0x33,\n                           0x33, 0x1E, 0x80, 0x06, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x70, 0x80, 0x09, 0x36, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x6B, 0x3E, 0x08, 0x08, 0x08, 0x80, 0x09, 0x61, 0x62, 0x34, 0x34, 0x18,\n                           0x0C, 0x16, 0x16, 0x23, 0x43, 0x80, 0x09, 0x49, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x3E, 0x08,\n                           0x08, 0x08, 0x80, 0x09, 0x3C, 0x66, 0x66, 0x36, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x80,\n                           0x09, 0x3C, 0x66, 0x66, 0x6C, 0x78, 0x63, 0x66, 0x66, 0x66, 0x3C, 0x80, 0x09, 0x43, 0xA6,\n                           0x24, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x0B, 0x06, 0x03, 0x84, 0x4C, 0x48,\n                           0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x80, 0x08, 0x43, 0xA6, 0x24, 0x1C, 0x18, 0x18,\n                           0x18, 0x18, 0x3C, 0x80, 0x06, 0x7F, 0x36, 0x63, 0x6B, 0x6B, 0x6B, 0x36, 0x80, 0x08, 0x62,\n                           0x65, 0x34, 0x1C, 0x16, 0x53, 0x23, 0x30, 0x18, 0x80, 0x0B, 0x3C, 0x66, 0x43, 0x03, 0x03,\n                           0x03, 0x03, 0x06, 0x3C, 0x60, 0x60, 0x38, 0x80, 0x09, 0x7E, 0x03, 0x03, 0x03, 0x03, 0x03,\n                           0x3E, 0x60, 0x60, 0x38, 0x80, 0x09, 0x7F, 0x66, 0x46, 0x06, 0x1E, 0x16, 0x06, 0x06, 0x06,\n                           0x0F, 0x80, 0x09, 0x7E, 0x4C, 0x0C, 0x0C, 0x3C, 0x2C, 0x0C, 0x0C, 0x0C, 0x0C, 0x80, 0x0A,\n                           0x06, 0x0C, 0x0C, 0x06, 0xC6, 0xFF, 0x63, 0x60, 0x30, 0x30, 0x60, 0x80, 0x09, 0x0C, 0x0C,\n                           0x06, 0x06, 0x7F, 0x7F, 0x30, 0x30, 0x18, 0x18, 0x80, 0x0C, 0x1E, 0x35, 0x64, 0x64, 0xD0,\n                           0xD0, 0xD8, 0xD8, 0xD8, 0xD8, 0xC0, 0x40, 0x20, 0x80, 0x0A, 0x03, 0x06, 0x0C, 0x18, 0x14,\n                           0x32, 0x28, 0x24, 0x60, 0x40, 0x40, 0x80, 0x0B, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,\n                           0xDB, 0xDB, 0xB6, 0xC0, 0x7C, 0x80, 0x08, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xB6, 0xC0,\n                           0x7E, 0x80, 0x09, 0x6E, 0x6B, 0x63, 0x63, 0x63, 0x7E, 0x60, 0x60, 0x60, 0x60, 0x80, 0x09,\n                           0x6C, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x60, 0x80, 0x0C, 0x03, 0x03, 0x03,\n                           0x03, 0x3F, 0x63, 0x63, 0x63, 0x63, 0x63, 0x60, 0x6E, 0x39, 0x80, 0x07, 0x10, 0x3E, 0x6B,\n                           0x66, 0x60, 0x60, 0x66, 0x3D, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x60, 0x3C, 0x06, 0x63, 0x63,\n                           0x63, 0x3E, 0x80, 0x09, 0x3C, 0x66, 0x66, 0x64, 0x38, 0x0E, 0x03, 0x43, 0x63, 0x3E, 0x80,\n                           0x09, 0x63, 0x16, 0x1C, 0x0C, 0x1C, 0x1C, 0x32, 0x32, 0x61, 0x7F, 0x80, 0x06, 0x26, 0x5D,\n                           0x0C, 0x1C, 0x14, 0x32, 0x3E, 0x80, 0x09, 0x7E, 0x03, 0x33, 0x6B, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x3E, 0x80, 0x06, 0x7E, 0x03, 0x3B, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x09, 0x3C, 0x18,\n                           0x7E, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x18, 0x38, 0x18, 0x7E, 0x1A,\n                           0x18, 0x18, 0x18, 0x1C, 0x18, 0x80, 0x06, 0x62, 0x65, 0x34, 0x1C, 0x16, 0x53, 0x23, 0x80,\n                           0x09, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x3F, 0x03, 0x06, 0x3C, 0x60, 0x80, 0x0B, 0x7F, 0x4D,\n                           0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xC0, 0x60, 0x80, 0x08, 0x7F, 0x66, 0x46,\n                           0x06, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x09, 0x3C, 0x66, 0x43, 0x03, 0x1F, 0x03, 0x03,\n                           0x43, 0x66, 0x3C, 0x80, 0x09, 0x1E, 0x1B, 0x1B, 0x1B, 0x7B, 0xDB, 0xDB, 0xDB, 0xDB, 0x7B,\n                           0x80, 0x09, 0x1B, 0x1B, 0x1B, 0x1B, 0x7F, 0xDB, 0xDB, 0xDB, 0xDB, 0x7B, 0x80, 0x09, 0x7F,\n                           0x4D, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x80, 0x0C, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x1C, 0x08, 0x08, 0x80, 0x09, 0x7F, 0x66, 0x46, 0x06,\n                           0x3E, 0x66, 0x66, 0x66, 0x66, 0x3F, 0x80, 0x0B, 0x3C, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,\n                           0x36, 0x36, 0x7F, 0x63, 0x41, 0x80, 0x09, 0x6B, 0x6B, 0x6B, 0x3E, 0x1C, 0x3E, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x80, 0x09, 0x3E, 0x63, 0x61, 0x60, 0x3C, 0x60, 0x60, 0x61, 0x63, 0x3E, 0x80,\n                           0x09, 0x63, 0x63, 0x63, 0x73, 0x7B, 0x7F, 0x6F, 0x67, 0x63, 0x63, 0x80, 0x0B, 0x36, 0x1C,\n                           0x63, 0x63, 0x63, 0x73, 0x7B, 0x7F, 0x6F, 0x67, 0x63, 0x63, 0x80, 0x09, 0x7C, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x63, 0x80, 0x09, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7E,\n                           0x60, 0x60, 0x63, 0x3E, 0x80, 0x0B, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,\n                           0x7F, 0x60, 0x40, 0x80, 0x09, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7E, 0x60, 0x60, 0x60, 0x60,\n                           0x80, 0x09, 0x63, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x7F, 0x80, 0x0B, 0x63,\n                           0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0xFF, 0xC0, 0x80, 0x80, 0x09, 0x1F, 0x0D,\n                           0x0D, 0x0C, 0x3C, 0x6C, 0x6C, 0x6C, 0x6C, 0x3E, 0x80, 0x09, 0xC3, 0xC3, 0xC3, 0xC3, 0xCF,\n                           0xDB, 0xDB, 0xDB, 0xDB, 0xCF, 0x80, 0x09, 0x0F, 0x06, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66,\n                           0x66, 0x3F, 0x80, 0x09, 0x1E, 0x33, 0x61, 0x60, 0x7C, 0x60, 0x60, 0x61, 0x33, 0x1E, 0x80,\n                           0x09, 0x39, 0x6D, 0x6D, 0x6D, 0x6F, 0x6D, 0x6D, 0x6D, 0x6D, 0x39, 0x80, 0x09, 0x7E, 0x33,\n                           0x33, 0x33, 0x3E, 0x36, 0x36, 0x36, 0x36, 0x73, 0x80, 0x09, 0x60, 0x3E, 0x03, 0x03, 0x3F,\n                           0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x08, 0x3C, 0x36, 0x36, 0x36, 0x36, 0x36, 0x7F, 0x63,\n                           0x41, 0x80, 0x06, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x63, 0x80, 0x06, 0x63, 0x77, 0x7F,\n                           0x7F, 0x6B, 0x63, 0x63, 0x80, 0x06, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x80, 0x06,\n                           0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x0A, 0x08, 0x3E, 0x6B, 0x6B, 0x6B, 0x6B,\n                           0x6B, 0x3E, 0x08, 0x08, 0x08, 0x80, 0x08, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x7F, 0x60,\n                           0x40, 0x80, 0x06, 0x63, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x7F, 0x80, 0x08, 0x63, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0xFF, 0xC0, 0x80, 0x80, 0x06, 0x1F, 0x0D, 0x0C, 0x3C, 0x6C, 0x6C, 0x3E,\n                           0x80, 0x06, 0x0F, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3F, 0x80, 0x06, 0x39, 0x6D, 0x6D, 0x6F,\n                           0x6D, 0x6D, 0x39, 0x80, 0x06, 0x7E, 0x33, 0x33, 0x3E, 0x36, 0x36, 0x73, 0x80, 0x0C, 0x06,\n                           0x1F, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x67, 0x60, 0x60, 0x38, 0x80, 0x06, 0x3E,\n                           0x63, 0x03, 0x1F, 0x03, 0x63, 0x3E, 0x80, 0x06, 0x1E, 0x1B, 0x1B, 0x7B, 0xDB, 0xDB, 0x7B,\n                           0x80, 0x06, 0x1B, 0x1B, 0x1B, 0x7F, 0xDB, 0xDB, 0x7B, 0x80, 0x09, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x7F, 0x1C, 0x08, 0x08, 0x80, 0x09, 0x36, 0x63, 0x63, 0x6B, 0x6B, 0x6B, 0x6B,\n                           0x6B, 0x7F, 0x36, 0x80, 0x09, 0x0C, 0x3F, 0x2D, 0x0C, 0x3C, 0x6C, 0x6C, 0x6C, 0x6C, 0x3E,\n                           0x80, 0x09, 0x0C, 0x0C, 0x0C, 0x3F, 0x2D, 0x0C, 0x3C, 0x6C, 0x6C, 0x3E, 0x80, 0x09, 0x73,\n                           0xDB, 0x9B, 0x1B, 0x7F, 0x1B, 0x1B, 0x9B, 0xDB, 0x73, 0x80, 0x06, 0x73, 0xDB, 0x1B, 0x7F,\n                           0x1B, 0xDB, 0x73, 0x80, 0x09, 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x36, 0x7F, 0x6B, 0x6B, 0x6B,\n                           0x80, 0x06, 0x08, 0x1C, 0x1C, 0x36, 0x3E, 0x6B, 0x6B, 0x80, 0x09, 0x11, 0x31, 0x39, 0x69,\n                           0x6F, 0x6D, 0xFD, 0xD5, 0xD7, 0xD7, 0x80, 0x06, 0x11, 0x31, 0x39, 0x6F, 0x7D, 0xD5, 0xD7,\n                           0x80, 0x09, 0x7F, 0x63, 0x36, 0x36, 0x1C, 0x3E, 0x6B, 0x6B, 0x6B, 0x6B, 0x80, 0x06, 0x7F,\n                           0x63, 0x36, 0x3E, 0x6B, 0x6B, 0x6B, 0x80, 0x09, 0xFF, 0xC5, 0x4D, 0x69, 0x3F, 0x39, 0x7D,\n                           0x55, 0xD5, 0xD7, 0x80, 0x06, 0xFD, 0xC5, 0x69, 0x7F, 0xD5, 0xD5, 0xD7, 0x80, 0x0D, 0x36,\n                           0x1C, 0x08, 0x3E, 0x63, 0x60, 0x60, 0x3E, 0x60, 0x60, 0x60, 0x3E, 0x03, 0x3E, 0x80, 0x08,\n                           0x3E, 0x61, 0x60, 0x3E, 0x60, 0x60, 0x3E, 0x03, 0x3E, 0x80, 0x09, 0x08, 0x69, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x3E, 0x08, 0x08, 0x80, 0x0C, 0x08, 0x08, 0x08, 0x69, 0x6B, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x3E, 0x08, 0x08, 0x08, 0x80, 0x09, 0x43, 0x63, 0x63, 0x23, 0x33, 0x36, 0x16,\n                           0x1E, 0x1C, 0x0C, 0x80, 0x08, 0x43, 0x63, 0x23, 0x23, 0x36, 0x16, 0x1E, 0x1C, 0x0C, 0x80,\n                           0x0C, 0x0E, 0x1B, 0x1B, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xF6, 0xC0, 0x60, 0x38, 0x80,\n                           0x09, 0xCE, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xF6, 0xC0, 0x60, 0x38, 0x80, 0x0B, 0x08, 0x3E,\n                           0x6B, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x6B, 0x3E, 0x08, 0x80, 0x08, 0x08, 0x3E, 0x6B,\n                           0x63, 0x63, 0x63, 0x6B, 0x3E, 0x08, 0x80, 0x0B, 0x20, 0x3E, 0x02, 0x36, 0x63, 0x63, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x7F, 0x36, 0x80, 0x08, 0x36, 0x63, 0x63, 0x6B, 0x6B, 0x6B, 0x6B, 0x7F,\n                           0x36, 0x80, 0x0C, 0x3C, 0x66, 0x43, 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x3C, 0x30, 0x30,\n                           0x30, 0x80, 0x08, 0x3E, 0x63, 0x03, 0x03, 0x03, 0x03, 0x1E, 0x18, 0x18, 0x80, 0x09, 0x60,\n                           0x60, 0x3C, 0xF0, 0x18, 0x18, 0x0F, 0x3C, 0x06, 0x06, 0x80, 0x02, 0x18, 0x24, 0x22, 0x80,\n                           0x02, 0x02, 0x3E, 0x02, 0x80, 0x02, 0x20, 0x3E, 0x20, 0x80, 0x00, 0xC3, 0x80, 0x02, 0x10,\n                           0x0A, 0x62, 0x80, 0x01, 0x41, 0x82, 0x80, 0x02, 0x46, 0x50, 0x08, 0x80, 0x0D, 0x36, 0x1C,\n                           0x63, 0x63, 0x63, 0x73, 0x7B, 0x7F, 0x6F, 0x67, 0x63, 0xE3, 0xC0, 0x80, 0x80, 0x08, 0x63,\n                           0x73, 0x7B, 0x7F, 0x6F, 0x67, 0xE3, 0xC0, 0x80, 0x80, 0x0A, 0x06, 0x0F, 0x06, 0x06, 0x06,\n                           0x3E, 0x66, 0x66, 0x66, 0x66, 0x3F, 0x80, 0x07, 0x06, 0x0F, 0x06, 0x06, 0x3E, 0x66, 0x66,\n                           0x3F, 0x80, 0x09, 0x3F, 0x66, 0x76, 0x26, 0x5E, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x09,\n                           0x3B, 0x66, 0x66, 0x66, 0x76, 0x26, 0x5E, 0x06, 0x06, 0x0F, 0x80, 0x0B, 0x40, 0x60, 0x7F,\n                           0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x08, 0x40, 0x60, 0x7F, 0x06,\n                           0x06, 0x06, 0x06, 0x06, 0x0F, 0x80, 0x09, 0x7F, 0x66, 0x46, 0x06, 0x1F, 0x06, 0x06, 0x06,\n                           0x06, 0x0F, 0x80, 0x06, 0x7F, 0x66, 0x46, 0x1F, 0x06, 0x06, 0x0F, 0x80, 0x0C, 0x7F, 0x66,\n                           0x46, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x6F, 0x60, 0x68, 0x30, 0x80, 0x09, 0x7F, 0x66,\n                           0x46, 0x1E, 0x36, 0x66, 0x6F, 0x60, 0x68, 0x30, 0x80, 0x0B, 0x6B, 0x6B, 0x6B, 0x3E, 0x1C,\n                           0x3E, 0x6B, 0x6B, 0x6B, 0xEB, 0xC0, 0x80, 0x80, 0x08, 0x6B, 0x6B, 0x6B, 0x3E, 0x6B, 0x6B,\n                           0xEB, 0xC0, 0x80, 0x80, 0x0C, 0x3E, 0x63, 0x61, 0x60, 0x3C, 0x60, 0x60, 0x61, 0x63, 0x3E,\n                           0x0C, 0x06, 0x1C, 0x80, 0x09, 0x3E, 0x63, 0x60, 0x3C, 0x60, 0x63, 0x3E, 0x0C, 0x06, 0x1C,\n                           0x80, 0x0B, 0x67, 0x66, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x66, 0xE7, 0xC0, 0x80, 0x80,\n                           0x08, 0x67, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0xE7, 0xC0, 0x80, 0x80, 0x09, 0x63, 0x6B, 0x6B,\n                           0x3B, 0x1F, 0x3B, 0x6B, 0x6B, 0x63, 0x63, 0x80, 0x06, 0x63, 0x6B, 0x3B, 0x1F, 0x3B, 0x6B,\n                           0x63, 0x80, 0x09, 0x67, 0x66, 0x6F, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x66, 0x67, 0x80, 0x09,\n                           0x07, 0x06, 0x0F, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x67, 0x80, 0x09, 0xCF, 0xCD, 0xCD,\n                           0x6C, 0x3C, 0x3C, 0x6C, 0xCC, 0xCC, 0xCE, 0x80, 0x06, 0xCF, 0x6D, 0x3D, 0x3C, 0x6C, 0xCC,\n                           0xCE, 0x80, 0x09, 0xFB, 0xDB, 0x9B, 0x1B, 0x1F, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x80, 0x06,\n                           0xFB, 0xDB, 0x9B, 0x1F, 0x1B, 0x1B, 0x1B, 0x80, 0x0C, 0x1F, 0x1B, 0x1B, 0x1B, 0x7B, 0xDB,\n                           0xDB, 0xDB, 0xDB, 0xDB, 0xC0, 0xD0, 0x60, 0x80, 0x09, 0x1B, 0x1B, 0x1B, 0x7F, 0xDB, 0xDB,\n                           0xDB, 0xC0, 0xD0, 0x60, 0x80, 0x09, 0x3E, 0x43, 0x33, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x33,\n                           0x5E, 0x80, 0x06, 0x3E, 0x43, 0x33, 0x6B, 0x6B, 0x33, 0x5E, 0x80, 0x0B, 0x7E, 0x7E, 0x5A,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x30, 0x20, 0x80, 0x08, 0x7E, 0x5A, 0x18, 0x18,\n                           0x18, 0x18, 0x3C, 0x30, 0x20, 0x80, 0x09, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18,\n                           0x18, 0x3C, 0x80, 0x09, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18, 0x3C, 0x80,\n                           0x09, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x3C, 0x80, 0x0B, 0x63, 0x63,\n                           0x36, 0x3E, 0x1C, 0x1C, 0x3E, 0x36, 0x63, 0xE3, 0xC0, 0x80, 0x80, 0x08, 0x63, 0x36, 0x1C,\n                           0x1C, 0x1C, 0x36, 0xE3, 0xC0, 0x80, 0x80, 0x0B, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0xFE, 0xC0, 0x80, 0x80, 0x08, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFE, 0xC0,\n                           0x80, 0x80, 0x0B, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7E, 0x60, 0x60, 0x60, 0xE0, 0xC0, 0x80,\n                           0x80, 0x08, 0x63, 0x63, 0x63, 0x7E, 0x60, 0x60, 0xE0, 0xC0, 0x80, 0x80, 0x09, 0x63, 0x63,\n                           0x63, 0x6B, 0x6B, 0x7E, 0x68, 0x68, 0x60, 0x60, 0x80, 0x06, 0x63, 0x6B, 0x6B, 0x7E, 0x68,\n                           0x68, 0x60, 0x80, 0x09, 0x03, 0x03, 0x03, 0x03, 0x3F, 0x63, 0x63, 0x63, 0x63, 0x63, 0x80,\n                           0x06, 0x03, 0x03, 0x03, 0x3F, 0x63, 0x63, 0x63, 0x80, 0x09, 0x78, 0xCC, 0xCD, 0xCD, 0xFE,\n                           0x0C, 0x0C, 0x0C, 0xCC, 0x78, 0x80, 0x06, 0x79, 0xCD, 0xFE, 0x0C, 0x0C, 0xCC, 0x78, 0x80,\n                           0x0C, 0x78, 0xCC, 0xCD, 0xCD, 0xFE, 0x0C, 0x0C, 0x0C, 0xCC, 0x78, 0x30, 0x18, 0x70, 0x80,\n                           0x09, 0x79, 0xCD, 0xFE, 0x0C, 0x0C, 0xCC, 0x78, 0x30, 0x18, 0x70, 0x80, 0x0B, 0x36, 0x1C,\n                           0x6B, 0x6B, 0x6B, 0x3E, 0x1C, 0x3E, 0x6B, 0x6B, 0x6B, 0x6B, 0x80, 0x0C, 0x67, 0x66, 0x66,\n                           0x36, 0x1E, 0x1E, 0x36, 0x66, 0x66, 0x67, 0x60, 0x68, 0x30, 0x80, 0x09, 0x67, 0x36, 0x1E,\n                           0x1E, 0x36, 0x66, 0x67, 0x60, 0x68, 0x30, 0x80, 0x0B, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0xE3, 0xC0, 0x80, 0x80, 0x08, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE3,\n                           0xC0, 0x80, 0x80, 0x0C, 0x63, 0x63, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x63, 0x60,\n                           0x68, 0x30, 0x80, 0x09, 0x63, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x60, 0x68, 0x30, 0x80,\n                           0x0B, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7E, 0x60, 0x60, 0x60, 0x70, 0x30, 0x10, 0x80, 0x08,\n                           0x63, 0x63, 0x63, 0x7E, 0x60, 0x60, 0x70, 0x30, 0x10, 0x80, 0x0B, 0x63, 0x77, 0x7F, 0x7F,\n                           0x6B, 0x63, 0x63, 0x63, 0x63, 0xE3, 0xC0, 0x80, 0x80, 0x08, 0x63, 0x77, 0x7F, 0x7F, 0x6B,\n                           0x63, 0xE3, 0xC0, 0x80, 0x80, 0x08, 0x3E, 0x63, 0x60, 0x60, 0x7F, 0x63, 0x63, 0x63, 0x3E,\n                           0x80, 0x08, 0x6B, 0x6B, 0x6B, 0x3E, 0x1C, 0x3E, 0x6B, 0x6B, 0x6B, 0x80, 0x08, 0x3E, 0x63,\n                           0x61, 0x60, 0x3C, 0x60, 0x61, 0x63, 0x3E, 0x80, 0x09, 0x7F, 0x60, 0x30, 0x18, 0x3C, 0x60,\n                           0x60, 0x61, 0x63, 0x3E, 0x80, 0x08, 0x3E, 0x63, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x3E,\n                           0x80, 0x08, 0x1E, 0x33, 0x61, 0x60, 0x7C, 0x60, 0x61, 0x33, 0x1E, 0x80, 0x08, 0x63, 0x63,\n                           0x63, 0x63, 0x7E, 0x60, 0x60, 0x60, 0x60, 0x80, 0x08, 0xC3, 0xC3, 0xC3, 0xCF, 0xDB, 0xDB,\n                           0xDB, 0xDB, 0xCF, 0x80, 0x09, 0x78, 0x30, 0x30, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E,\n                           0x80, 0x09, 0x78, 0x30, 0x30, 0x30, 0x3E, 0xB3, 0xB3, 0xB3, 0xB3, 0x6E, 0x80, 0x09, 0x38,\n                           0x30, 0x30, 0x3C, 0x36, 0x33, 0xB3, 0xB3, 0xB3, 0x6E, 0x80, 0x09, 0x1E, 0x33, 0x31, 0x30,\n                           0x1C, 0xB0, 0xB0, 0xB0, 0xB0, 0x60, 0x80, 0x06, 0x1E, 0x33, 0x30, 0x9C, 0xB0, 0xB0, 0x60,\n                           0x80, 0x0B, 0x3E, 0x63, 0x61, 0x60, 0x3C, 0x60, 0x60, 0x60, 0x60, 0xE0, 0xC0, 0x80, 0x80,\n                           0x08, 0x3E, 0x63, 0x60, 0x3C, 0x60, 0x60, 0xE0, 0xC0, 0x80, 0x80, 0x09, 0x3C, 0x36, 0x36,\n                           0x36, 0x36, 0xB6, 0xB6, 0xB6, 0xB6, 0x63, 0x80, 0x06, 0x3C, 0x36, 0x36, 0xB6, 0xB6, 0xB6,\n                           0x63, 0x80, 0x09, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xB3, 0xB3, 0xB3, 0xB3, 0x63, 0x80, 0x06,\n                           0x33, 0x33, 0x33, 0xBF, 0xB3, 0xB3, 0x63, 0x80, 0x09, 0x3C, 0x66, 0x43, 0x03, 0x03, 0x73,\n                           0x63, 0x63, 0x66, 0x3C, 0x80, 0x06, 0x3E, 0x63, 0x03, 0x73, 0x63, 0x63, 0x3E, 0x80, 0x09,\n                           0x7E, 0x7E, 0x5A, 0x18, 0x18, 0xD8, 0xD8, 0xD8, 0xD8, 0x70, 0x80, 0x06, 0x7E, 0x5A, 0x18,\n                           0xD8, 0xD8, 0xD8, 0x70, 0x80, 0x06, 0x18, 0x26, 0x29, 0x5D, 0x4A, 0x32, 0x0C, 0x80, 0x09,\n                           0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xF3, 0xDE, 0x80, 0x09, 0x3C, 0x66, 0x66,\n                           0x66, 0x66, 0x06, 0x06, 0x7E, 0x06, 0x06, 0x80, 0x09, 0x1E, 0x33, 0x33, 0x33, 0x33, 0xFE,\n                           0x30, 0x30, 0x30, 0x30, 0x80, 0x09, 0x1E, 0x33, 0x33, 0x33, 0x33, 0xF3, 0x30, 0x30, 0x30,\n                           0x30, 0x80, 0x09, 0x06, 0x7E, 0x06, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x80, 0x0A,\n                           0x3C, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x30, 0x1B, 0x7F, 0xC3, 0x80, 0x0A, 0x06, 0x06,\n                           0x7E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x60, 0x80, 0x09, 0x3C, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0x06, 0x06, 0x06, 0x7E, 0x80, 0x09, 0x3E, 0x63, 0xF3, 0x6B, 0x6B, 0x6B, 0x6B,\n                           0x33, 0x03, 0x03, 0x80, 0x09, 0x30, 0x30, 0x30, 0x30, 0xFE, 0x33, 0x33, 0x33, 0x33, 0x1E,\n                           0x80, 0x09, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x80, 0x0A, 0x06,\n                           0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x60, 0x80, 0x09, 0x03, 0x03, 0x6F,\n                           0x6B, 0x6B, 0x6B, 0x6B, 0x33, 0x03, 0x03, 0x80, 0x09, 0x03, 0xFE, 0x24, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0x3C, 0x80, 0x09, 0x06, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60,\n                           0x60, 0x80, 0x0A, 0x18, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x0F, 0x3C, 0x70, 0x20, 0x80,\n                           0x09, 0x3C, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x36, 0x1B, 0x76, 0x80, 0x09, 0x1E, 0x33,\n                           0x33, 0x33, 0x33, 0x33, 0x30, 0x30, 0x30, 0xF0, 0x80, 0x09, 0x78, 0x0C, 0x06, 0x1F, 0x36,\n                           0x66, 0x66, 0x66, 0x66, 0x7E, 0x80, 0x09, 0xF3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,\n                           0x33, 0x1E, 0x80, 0x09, 0x3C, 0x66, 0x60, 0x60, 0x3E, 0x60, 0x60, 0x66, 0x66, 0x3C, 0x80,\n                           0x09, 0x07, 0x06, 0x06, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x80, 0x09, 0x3C, 0x60,\n                           0x7C, 0x66, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x80, 0x09, 0x3C, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0x66, 0x66, 0x80, 0x09, 0x3C, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x36,\n                           0x1C, 0x70, 0x80, 0x09, 0x3E, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x68, 0x68, 0x60, 0x60, 0x80,\n                           0x0A, 0x3C, 0x66, 0x66, 0x66, 0x6E, 0x78, 0x70, 0x30, 0x1B, 0x7F, 0xC3, 0x80, 0x09, 0x1E,\n                           0x33, 0x33, 0x33, 0x33, 0xF3, 0x33, 0x33, 0x33, 0x33, 0x80, 0x09, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x80, 0x09, 0x30, 0x30, 0x33, 0x33, 0x33, 0x33, 0x3E,\n                           0x30, 0x30, 0xF0, 0x80, 0x09, 0x3E, 0x63, 0x63, 0x06, 0x0C, 0x18, 0x30, 0x63, 0x63, 0x3E,\n                           0x80, 0x09, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x06, 0x80, 0x09, 0x3C,\n                           0x66, 0x66, 0x66, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x80, 0x09, 0x06, 0x06, 0x3E, 0x66,\n                           0x66, 0x66, 0x66, 0xC6, 0x06, 0x06, 0x80, 0x09, 0x08, 0x3E, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B,\n                           0x6B, 0x3E, 0x08, 0x80, 0x09, 0x3C, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x7F, 0x06, 0x06,\n                           0x80, 0x09, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x80, 0x09, 0x0E,\n                           0x0B, 0x0B, 0x0B, 0x3E, 0x68, 0x68, 0x68, 0x6B, 0x3E, 0x80, 0x03, 0x18, 0x0C, 0x0C, 0x18,\n                           0x80, 0x03, 0x0C, 0x18, 0x18, 0x0C, 0x80, 0x02, 0x60, 0x3C, 0x06, 0x80, 0x02, 0x0C, 0x18,\n                           0x30, 0x80, 0x02, 0x38, 0x6C, 0x36, 0x80, 0x02, 0x0E, 0x06, 0x7C, 0x80, 0x06, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x6B, 0x56, 0x80, 0x09, 0x3E, 0x66, 0x66, 0x66, 0x06, 0x06, 0x7E, 0x06,\n                           0x06, 0x06, 0x80, 0x09, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x33, 0xFE, 0x30, 0x30, 0x30, 0x80,\n                           0x09, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x33, 0xF3, 0x30, 0x30, 0x30, 0x80, 0x09, 0x06, 0x06,\n                           0x7E, 0x06, 0x06, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x80, 0x09, 0x3E, 0x33, 0x33, 0x33, 0x33,\n                           0x33, 0x3E, 0x30, 0x30, 0xF0, 0x80, 0x0B, 0x06, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x06, 0x06,\n                           0x06, 0x1E, 0x30, 0x18, 0x80, 0x09, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06,\n                           0x7E, 0x80, 0x09, 0x3F, 0x63, 0x63, 0xF3, 0x6B, 0x6B, 0x33, 0x03, 0x03, 0x03, 0x80, 0x09,\n                           0x30, 0x30, 0x30, 0xFE, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3E, 0x80, 0x0C, 0x06, 0x06, 0x06,\n                           0x3E, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x80, 0x09, 0x0C, 0x0C, 0x0C,\n                           0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x7C, 0x80, 0x0C, 0x03, 0x03, 0x03, 0x6F, 0x6B, 0x6B,\n                           0x6B, 0x6B, 0x6B, 0x53, 0x03, 0x03, 0x03, 0x80, 0x09, 0x06, 0x1C, 0x30, 0xFE, 0x33, 0x33,\n                           0x33, 0x33, 0x33, 0x1E, 0x80, 0x0C, 0x06, 0x06, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x7C, 0x60, 0x60, 0x60, 0x80, 0x09, 0x06, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x80, 0x09, 0x0C, 0x38, 0x30, 0x18, 0x3C, 0x26, 0x66, 0x46, 0xC6, 0xBC, 0x80, 0x09,\n                           0x1F, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, 0x30, 0xF0, 0x80, 0x09, 0x70, 0x18, 0x0C,\n                           0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x80, 0x09, 0xF0, 0x30, 0x30, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x33, 0x3E, 0x80, 0x09, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36,\n                           0x1C, 0x80, 0x09, 0x07, 0x06, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x80, 0x09,\n                           0x3C, 0x66, 0x66, 0x66, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x7C, 0x80, 0x06, 0x3E, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0x66, 0x80, 0x09, 0x30, 0x18, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06,\n                           0x7C, 0x80, 0x09, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x7E, 0x60, 0x60, 0x60, 0x80, 0x09,\n                           0x3C, 0x66, 0x66, 0x66, 0x6E, 0x38, 0x18, 0x0C, 0x06, 0x7C, 0x80, 0x06, 0x1F, 0x33, 0x33,\n                           0x33, 0x33, 0x33, 0xF3, 0x80, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x80, 0x0C,\n                           0x30, 0x30, 0x30, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x30, 0xF0, 0x80, 0x06,\n                           0x3B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6E, 0x80, 0x09, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x06, 0x06, 0x06, 0x80, 0x09, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x66,\n                           0x3C, 0x80, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x7C, 0x80, 0x0C, 0x08, 0x08, 0x08,\n                           0x3B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6E, 0x08, 0x08, 0x08, 0x80, 0x09, 0x3E, 0x66, 0x66,\n                           0x66, 0x66, 0x3E, 0x06, 0x7F, 0x06, 0x06, 0x80, 0x06, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x3C, 0x80, 0x0C, 0x0E, 0x0B, 0x0B, 0x3E, 0x68, 0x68, 0x68, 0x68, 0x6B, 0x3E, 0x08, 0x08,\n                           0x08, 0x80, 0x09, 0x03, 0x03, 0x03, 0x03, 0x03, 0x33, 0x33, 0x33, 0x33, 0xEE, 0x80, 0x02,\n                           0x03, 0x63, 0x3E, 0x80, 0x03, 0x08, 0x08, 0x1C, 0x36, 0x80, 0x04, 0x10, 0x1C, 0x08, 0x1C,\n                           0x04, 0x80, 0x02, 0x36, 0x06, 0x36, 0x80, 0x02, 0x08, 0x18, 0x30, 0x80, 0x02, 0x08, 0x1C,\n                           0x08, 0x80, 0x02, 0x2E, 0x6B, 0x3A, 0x80, 0x02, 0x03, 0x06, 0x04, 0x80, 0x02, 0xC0, 0x60,\n                           0xC0, 0x80, 0x02, 0x14, 0x18, 0x0C, 0x80, 0x02, 0x30, 0x18, 0x08, 0x80, 0x02, 0xC0, 0x60,\n                           0x20, 0x80, 0x02, 0xD8, 0x6C, 0x24, 0x80, 0x03, 0x22, 0x55, 0x36, 0x14, 0x80, 0x03, 0x20,\n                           0x50, 0x30, 0x10, 0x80, 0x03, 0x02, 0x0A, 0x07, 0x01, 0x80, 0x02, 0x08, 0x0C, 0x06, 0x80,\n                           0x02, 0x24, 0x36, 0x1B, 0x80, 0x03, 0x18, 0x0C, 0x10, 0x0C, 0x80, 0x02, 0x06, 0x0C, 0x08,\n                           0x80, 0x03, 0x02, 0x05, 0x06, 0x04, 0x80, 0x03, 0x36, 0x1C, 0x08, 0x08, 0x80, 0x02, 0x20,\n                           0x60, 0xC0, 0x80, 0x02, 0x12, 0x15, 0x09, 0x80, 0x00, 0xDB, 0x80, 0x00, 0xCC, 0x80, 0x00,\n                           0x6F, 0x80, 0x00, 0x60, 0x80, 0x02, 0x6F, 0x06, 0x66, 0x80, 0x02, 0x7E, 0x18, 0x18, 0x80,\n                           0x02, 0x03, 0x18, 0xC0, 0x80, 0x01, 0x7E, 0x3F, 0x80, 0x07, 0x63, 0x63, 0x66, 0x6E, 0x3B,\n                           0x33, 0x63, 0x63, 0x80, 0x07, 0x1F, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x7F, 0x80, 0x07,\n                           0x1C, 0x30, 0x30, 0x30, 0x30, 0x38, 0x6C, 0x67, 0x80, 0x07, 0x7F, 0x30, 0x30, 0x30, 0x30,\n                           0x30, 0x30, 0x30, 0x80, 0x07, 0x3F, 0x60, 0x60, 0x60, 0x63, 0x63, 0x63, 0x63, 0x80, 0x07,\n                           0x0E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x07, 0x7E, 0x18, 0x18, 0x18, 0x30,\n                           0x30, 0x18, 0x0C, 0x80, 0x07, 0x3F, 0x66, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x80, 0x07,\n                           0x33, 0x6B, 0x6B, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x04, 0x0E, 0x18, 0x18, 0x18, 0x0C,\n                           0x80, 0x0A, 0x3F, 0x60, 0x60, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x70, 0x80, 0x07,\n                           0x3F, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x3F, 0x80, 0x09, 0x03, 0x03, 0x3F, 0x60, 0x60,\n                           0x60, 0x60, 0x30, 0x18, 0x18, 0x80, 0x07, 0x3F, 0x66, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7F,\n                           0x80, 0x07, 0x3B, 0x6E, 0x66, 0x63, 0x63, 0x63, 0x63, 0x7B, 0x80, 0x0A, 0x1C, 0x30, 0x30,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0x80, 0x07, 0x1C, 0x30, 0x30, 0x30, 0x30,\n                           0x30, 0x30, 0x3E, 0x80, 0x07, 0x3F, 0x66, 0x63, 0x63, 0x63, 0x63, 0x33, 0x1E, 0x80, 0x07,\n                           0x77, 0x66, 0x66, 0x66, 0x66, 0x66, 0x34, 0x1F, 0x80, 0x0A, 0x1F, 0x32, 0x33, 0x33, 0x37,\n                           0x30, 0x30, 0x30, 0x30, 0x30, 0x70, 0x80, 0x07, 0x3F, 0x62, 0x63, 0x63, 0x67, 0x60, 0x60,\n                           0x7F, 0x80, 0x0A, 0x77, 0x66, 0x66, 0x36, 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0E, 0x80,\n                           0x07, 0x77, 0x66, 0x66, 0x2C, 0x18, 0x30, 0x60, 0x7F, 0x80, 0x0A, 0x3F, 0x60, 0x60, 0x66,\n                           0x26, 0x36, 0x76, 0x06, 0x06, 0x06, 0x06, 0x80, 0x07, 0x3F, 0x60, 0x60, 0x60, 0x60, 0x60,\n                           0x60, 0x60, 0x80, 0x07, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6F, 0x63, 0x3E, 0x80, 0x07, 0x3F,\n                           0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x80, 0x07, 0x33, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0x80, 0x07, 0x33, 0x66, 0x66, 0x66, 0x63, 0x60, 0x60, 0x60, 0x80, 0x04, 0x33,\n                           0x66, 0x66, 0x66, 0x33, 0x80, 0x03, 0x10, 0x08, 0x18, 0x18, 0x80, 0x02, 0x30, 0x18, 0x18,\n                           0x80, 0x05, 0x38, 0x44, 0x04, 0x08, 0x10, 0x10, 0x80, 0x0A, 0x0C, 0x02, 0x1C, 0x02, 0xE0,\n                           0x10, 0x11, 0x61, 0x81, 0x41, 0x3E, 0x80, 0x02, 0x80, 0x7E, 0x01, 0x80, 0x02, 0x0C, 0x1E,\n                           0x0C, 0x80, 0x08, 0x08, 0x04, 0x02, 0x0C, 0x08, 0x04, 0x42, 0x3E, 0x1C, 0x80, 0x08, 0x08,\n                           0x1C, 0x34, 0x22, 0x42, 0x41, 0x41, 0x7F, 0x3E, 0x80, 0x08, 0x01, 0x1F, 0x1E, 0x10, 0x10,\n                           0x10, 0x30, 0x70, 0x60, 0x80, 0x09, 0x06, 0x89, 0x49, 0x26, 0x10, 0x08, 0x64, 0x92, 0x91,\n                           0x60, 0x80, 0x05, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x06, 0x80, 0x04, 0x08, 0x1C, 0x18, 0x08,\n                           0x04, 0x80, 0x03, 0xE0, 0x10, 0xE0, 0x10, 0x80, 0x08, 0xC0, 0x20, 0xC0, 0x28, 0x08, 0x08,\n                           0x08, 0x08, 0x08, 0x80, 0x07, 0x28, 0x02, 0x81, 0x81, 0x7E, 0x10, 0x28, 0x10, 0x80, 0x0C,\n                           0x60, 0x10, 0x60, 0x10, 0x0E, 0xF1, 0x0C, 0x02, 0x01, 0x01, 0x01, 0x82, 0x7C, 0x80, 0x07,\n                           0x10, 0x20, 0x40, 0x42, 0x3C, 0x10, 0x28, 0x10, 0x80, 0x06, 0x20, 0x40, 0x40, 0x20, 0x38,\n                           0x56, 0x20, 0x80, 0x05, 0x20, 0x40, 0x40, 0x20, 0x18, 0x46, 0x80, 0x05, 0x20, 0x40, 0x48,\n                           0x20, 0x18, 0x46, 0x80, 0x05, 0x80, 0xA8, 0x11, 0x11, 0x51, 0x0E, 0x80, 0x06, 0x60, 0x90,\n                           0x8C, 0x79, 0x11, 0x09, 0xA6, 0x80, 0x06, 0x54, 0x04, 0x04, 0x34, 0x4C, 0x45, 0x3E, 0x80,\n                           0x06, 0x18, 0x04, 0x02, 0x7C, 0x80, 0x81, 0x7E, 0x80, 0x07, 0x80, 0x40, 0xA0, 0xD0, 0x12,\n                           0x21, 0x41, 0x3E, 0x80, 0x08, 0x20, 0x90, 0x48, 0xA0, 0xD0, 0x12, 0x21, 0x41, 0x3E, 0x80,\n                           0x08, 0x22, 0x90, 0x45, 0x20, 0x10, 0x22, 0x41, 0x41, 0x3E, 0x80, 0x0A, 0x28, 0x10, 0x40,\n                           0x40, 0x40, 0x40, 0x42, 0x41, 0x41, 0x21, 0x1E, 0x80, 0x0A, 0x10, 0x40, 0x40, 0x40, 0x40,\n                           0x40, 0x42, 0x41, 0x41, 0x21, 0x1E, 0x80, 0x0A, 0x08, 0x40, 0x54, 0x40, 0x40, 0x40, 0x42,\n                           0x41, 0x41, 0x21, 0x1E, 0x80, 0x08, 0x82, 0x81, 0x81, 0x81, 0x42, 0x3C, 0x10, 0x28, 0x10,\n                           0x80, 0x06, 0x08, 0x1C, 0x32, 0x4A, 0x4C, 0x3C, 0x02, 0x80, 0x03, 0x1C, 0x02, 0x1C, 0x02,\n                           0x80, 0x06, 0x30, 0x48, 0x70, 0x48, 0x34, 0x18, 0x06, 0x80, 0x07, 0x04, 0xE2, 0x11, 0x10,\n                           0x61, 0x81, 0x81, 0x7E, 0x80, 0x08, 0x0A, 0x04, 0xE0, 0x10, 0x11, 0x61, 0x81, 0x81, 0x7E,\n                           0x80, 0x08, 0x06, 0x01, 0x06, 0x01, 0x10, 0x28, 0x06, 0x01, 0x7F, 0x80, 0x06, 0x02, 0x02,\n                           0xC2, 0xAA, 0x7E, 0x01, 0x3E, 0x80, 0x06, 0x54, 0x04, 0x64, 0x54, 0x3E, 0x01, 0x3E, 0x80,\n                           0x03, 0x30, 0x70, 0x38, 0x06, 0x80, 0x04, 0x28, 0x28, 0x10, 0x28, 0x18, 0x80, 0x05, 0x18,\n                           0x34, 0x08, 0x14, 0x44, 0x38, 0x80, 0x0D, 0x5A, 0xA5, 0x66, 0xDA, 0x81, 0x81, 0x81, 0x81,\n                           0x81, 0x81, 0x5A, 0x66, 0xA5, 0x5A, 0x80, 0x0B, 0x18, 0x66, 0x42, 0x42, 0x81, 0x99, 0x99,\n                           0x81, 0x42, 0x42, 0x66, 0x18, 0x80, 0x02, 0x10, 0x38, 0x10, 0x80, 0x03, 0x18, 0x64, 0x10,\n                           0x0E, 0x80, 0x01, 0x4C, 0x34, 0x80, 0x05, 0x10, 0x28, 0x30, 0x20, 0x10, 0x0C, 0x80, 0x03,\n                           0x10, 0x44, 0x44, 0x38, 0x80, 0x0D, 0x08, 0x14, 0x2A, 0x55, 0x49, 0x2A, 0x2A, 0x2A, 0x2A,\n                           0x2A, 0x2A, 0x2A, 0x41, 0x7F, 0x80, 0x03, 0x1C, 0x22, 0x22, 0x1C, 0x80, 0x08, 0x72, 0x0F,\n                           0x7F, 0x3E, 0x0C, 0x0C, 0x08, 0x08, 0x08, 0x80, 0x08, 0x0C, 0x1C, 0x34, 0x22, 0x42, 0x41,\n                           0x49, 0x7F, 0x36, 0x80, 0x08, 0x18, 0x3C, 0x06, 0x7E, 0x3C, 0x0C, 0x06, 0x02, 0x01, 0x80,\n                           0x05, 0x80, 0xA8, 0x11, 0x11, 0x11, 0x4E, 0x80, 0x06, 0x60, 0x90, 0x8C, 0x79, 0x11, 0x11,\n                           0x4E, 0x80, 0x09, 0x0E, 0x01, 0x31, 0x0E, 0x02, 0x01, 0x11, 0x01, 0x82, 0x7C, 0x80, 0x03,\n                           0x28, 0x28, 0x28, 0x28, 0x80, 0x09, 0x30, 0x48, 0x48, 0x3C, 0x02, 0x2A, 0x2A, 0x2A, 0x2A,\n                           0x02, 0x80, 0x09, 0x36, 0x49, 0x49, 0x49, 0x49, 0x49, 0x32, 0x0C, 0x32, 0x40, 0x80, 0x06,\n                           0x36, 0x49, 0x49, 0x49, 0x49, 0x49, 0x26, 0x80, 0x09, 0x2A, 0x55, 0x55, 0x55, 0x41, 0x41,\n                           0x02, 0x0C, 0x32, 0x40, 0x80, 0x06, 0x36, 0x49, 0x49, 0x49, 0x41, 0x41, 0x22, 0x80, 0x09,\n                           0x36, 0x49, 0x49, 0x49, 0x41, 0x41, 0x02, 0x0C, 0x32, 0x40, 0x80, 0x08, 0x3F, 0x66, 0x66,\n                           0x66, 0x3E, 0x66, 0x66, 0x66, 0x3F, 0x80, 0x0A, 0x30, 0x37, 0x06, 0x06, 0x1E, 0x36, 0x66,\n                           0x66, 0x66, 0x66, 0x3E, 0x80, 0x0B, 0x3C, 0x66, 0x43, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3C,\n                           0x18, 0x30, 0x1C, 0x80, 0x08, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x80,\n                           0x0B, 0x06, 0x06, 0x30, 0x30, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x0C,\n                           0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x0C, 0x18, 0x0E, 0x80, 0x0C,\n                           0x38, 0x30, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x0C, 0x18, 0x0E, 0x80, 0x0C,\n                           0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x08, 0x1C, 0x36, 0x80, 0x0C,\n                           0x38, 0x30, 0x30, 0x3C, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x08, 0x1C, 0x36, 0x80, 0x0C,\n                           0x7F, 0x66, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x46, 0x66, 0x7F, 0x08, 0x1C, 0x36, 0x80, 0x09,\n                           0x3E, 0x63, 0x7F, 0x03, 0x03, 0x63, 0x3E, 0x08, 0x1C, 0x36, 0x80, 0x0B, 0x7F, 0x66, 0x46,\n                           0x16, 0x1E, 0x16, 0x46, 0x66, 0x7F, 0x18, 0x30, 0x1C, 0x80, 0x08, 0x7F, 0x66, 0x46, 0x16,\n                           0x1E, 0x16, 0x06, 0x06, 0x0F, 0x80, 0x08, 0x1C, 0x36, 0x26, 0x0F, 0x06, 0x06, 0x06, 0x06,\n                           0x0F, 0x80, 0x0B, 0x30, 0x30, 0x07, 0x06, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x67,\n                           0x80, 0x08, 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x67, 0x80, 0x0C, 0x63, 0x63,\n                           0x63, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x63, 0x06, 0x0C, 0x07, 0x80, 0x0C, 0x07, 0x06,\n                           0x06, 0x36, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x67, 0x0C, 0x18, 0x0E, 0x80, 0x02, 0x30, 0x18,\n                           0x66, 0x80, 0x07, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x03, 0x30, 0x18,\n                           0x66, 0x66, 0x80, 0x0A, 0x30, 0x37, 0x06, 0x06, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x67,\n                           0x80, 0x0C, 0x0F, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x08, 0x1C, 0x36,\n                           0x80, 0x0C, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x08, 0x1C, 0x36,\n                           0x80, 0x0C, 0x63, 0x67, 0x6F, 0x7F, 0x7B, 0x73, 0x63, 0x63, 0x63, 0x63, 0x08, 0x1C, 0x36,\n                           0x80, 0x09, 0x3B, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x08, 0x1C, 0x36, 0x80, 0x0B, 0x30,\n                           0x18, 0x4E, 0x39, 0x3E, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x02, 0x06, 0x0C,\n                           0x3E, 0x80, 0x02, 0x30, 0x18, 0x3E, 0x80, 0x02, 0x06, 0x36, 0x18, 0x80, 0x07, 0x3E, 0x63,\n                           0x63, 0x0E, 0x38, 0x63, 0x63, 0x3E, 0x80, 0x03, 0x06, 0x06, 0x30, 0x18, 0x80, 0x0B, 0x0C,\n                           0x22, 0x1C, 0x08, 0x3E, 0x63, 0x63, 0x0E, 0x38, 0x63, 0x63, 0x3E, 0x80, 0x0B, 0x0C, 0x0C,\n                           0x22, 0x1C, 0x08, 0x3E, 0x63, 0x06, 0x1C, 0x30, 0x63, 0x3E, 0x80, 0x08, 0x7E, 0x7E, 0x5A,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x0A, 0x60, 0x68, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C,\n                           0x0C, 0x0C, 0x6C, 0x38, 0x80, 0x0C, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x3C, 0x08, 0x1C, 0x36, 0x80, 0x0C, 0x08, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C,\n                           0x38, 0x10, 0x38, 0x6C, 0x80, 0x0C, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,\n                           0x3E, 0x08, 0x1C, 0x36, 0x80, 0x09, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x08, 0x1C,\n                           0x36, 0x80, 0x03, 0x30, 0x18, 0x4E, 0x39, 0x80, 0x06, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,\n                           0x3E, 0x80, 0x08, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x08, 0x80, 0x0B, 0x08,\n                           0x1C, 0x22, 0x7F, 0x63, 0x31, 0x18, 0x0C, 0x06, 0x43, 0x63, 0x7F, 0x80, 0x08, 0x08, 0x0C,\n                           0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x80, 0x08, 0x1C, 0x36, 0x26, 0x06, 0x06, 0x06,\n                           0x06, 0x06, 0x0F, 0x80, 0x0B, 0x1C, 0x30, 0x18, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63,\n                           0x63, 0x63, 0x80, 0x0B, 0xC0, 0x68, 0x1C, 0x36, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63,\n                           0x63, 0x80, 0x03, 0xC0, 0x68, 0x1C, 0x36, 0x80, 0x0B, 0x03, 0x16, 0x38, 0x6C, 0x08, 0x1C,\n                           0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x80, 0x03, 0x03, 0x16, 0x38, 0x6C, 0x80, 0x0B, 0x70,\n                           0xC8, 0x5C, 0x36, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x80, 0x0B, 0x6E, 0x3B,\n                           0x08, 0x14, 0x2A, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x80, 0x0B, 0x6E, 0x3B, 0x08,\n                           0x1C, 0x22, 0x1E, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x0B, 0x30, 0x18, 0x22, 0x1C,\n                           0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x80, 0x03, 0x30, 0x18, 0x22, 0x1C, 0x80,\n                           0x0B, 0x06, 0x0C, 0x22, 0x1C, 0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x80, 0x03,\n                           0x06, 0x0C, 0x22, 0x1C, 0x80, 0x0B, 0x0C, 0x10, 0x2A, 0x1C, 0x08, 0x1C, 0x36, 0x63, 0x63,\n                           0x7F, 0x63, 0x63, 0x80, 0x03, 0x0C, 0x10, 0x2A, 0x1C, 0x80, 0x0B, 0x4E, 0x39, 0x22, 0x1C,\n                           0x08, 0x1C, 0x36, 0x63, 0x63, 0x7F, 0x63, 0x63, 0x80, 0x03, 0x4E, 0x39, 0x22, 0x1C, 0x80,\n                           0x0B, 0x1C, 0x30, 0x18, 0x7F, 0x66, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x66, 0x7F, 0x80, 0x0B,\n                           0xC4, 0x6E, 0x11, 0x7F, 0x66, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x66, 0x7F, 0x80, 0x0B, 0x23,\n                           0x76, 0x88, 0x7F, 0x66, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x66, 0x7F, 0x80, 0x0B, 0x6E, 0x3B,\n                           0x08, 0x1C, 0x22, 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x80, 0x0B, 0x6E, 0x3B, 0x08,\n                           0x1C, 0x22, 0x3E, 0x63, 0x7F, 0x03, 0x03, 0x63, 0x3E, 0x80, 0x0B, 0x1C, 0x30, 0x18, 0x3C,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x0B, 0x1C, 0x30, 0x18, 0x3E, 0x63,\n                           0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x0B, 0xC4, 0x6E, 0x11, 0x3E, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x0B, 0x23, 0x76, 0x88, 0x3E, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x63, 0x3E, 0x80, 0x0B, 0x70, 0xC8, 0x5C, 0x22, 0x3E, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x3E, 0x80, 0x0B, 0x6E, 0x3B, 0x08, 0x14, 0x22, 0x3E, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x3E, 0x80, 0x0B, 0x6E, 0x3B, 0x08, 0x1C, 0x22, 0x3E, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x3E, 0x80, 0x0B, 0x18, 0xCC, 0xC0, 0x5E, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,\n                           0x1E, 0x80, 0x09, 0xD8, 0xCC, 0x60, 0x1E, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x0B,\n                           0x06, 0xCC, 0xC0, 0x5E, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x09, 0xC6,\n                           0xCC, 0x60, 0x1E, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x0B, 0x0E, 0xD8, 0xCC, 0x5E,\n                           0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x0A, 0x0E, 0xD8, 0xCC, 0x60, 0x1E,\n                           0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x0B, 0x16, 0xCD, 0xC0, 0x5E, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x0A, 0x16, 0xCD, 0xC0, 0x60, 0x1E, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x1E, 0x80, 0x0B, 0x1C, 0x30, 0x18, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x3E, 0x80, 0x0B, 0x18, 0xCC, 0xC0, 0x73, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,\n                           0x1E, 0x80, 0x09, 0xD8, 0xCC, 0x60, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x0B,\n                           0x06, 0xCC, 0xC0, 0x73, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x09, 0xC6,\n                           0xCC, 0x60, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x0B, 0x0E, 0xD8, 0xCC, 0x73,\n                           0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x0A, 0x0E, 0xD8, 0xCC, 0x60, 0x33,\n                           0x33, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x80, 0x0B, 0x16, 0xCD, 0xC0, 0x73, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x0A, 0x16, 0xCD, 0xC0, 0x60, 0x33, 0x33, 0x33, 0x33,\n                           0x33, 0x33, 0x6E, 0x80, 0x09, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7E, 0x30, 0x18, 0x6F, 0x60,\n                           0x80, 0x0B, 0x1C, 0x30, 0x18, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x80,\n                           0x01, 0x5C, 0x3A, 0x80, 0x02, 0x06, 0x36, 0x63, 0x80, 0x02, 0x03, 0x33, 0x66, 0x80, 0x02,\n                           0x06, 0x66, 0x33, 0x80, 0x02, 0x03, 0x63, 0x36, 0x80, 0x03, 0x2C, 0x1A, 0x30, 0x18, 0x80,\n                           0x03, 0x2C, 0x1A, 0x0C, 0x18, 0x80, 0x04, 0x25, 0x55, 0x57, 0x57, 0x65, 0x80, 0x04, 0x25,\n                           0x57, 0x55, 0x55, 0x65, 0x80, 0x04, 0x57, 0x51, 0x73, 0x71, 0x57, 0x80, 0x04, 0x57, 0x71,\n                           0x53, 0x51, 0x57, 0x80, 0x04, 0x53, 0x74, 0x52, 0x54, 0x53, 0x80, 0x04, 0x55, 0x75, 0x57,\n                           0x54, 0x54, 0x80, 0x04, 0x56, 0x71, 0x53, 0x55, 0x52, 0x80, 0x04, 0x1C, 0x04, 0x0C, 0x04,\n                           0x04, 0x80, 0x04, 0x0C, 0x14, 0x0C, 0x04, 0x04, 0x80, 0x04, 0x57, 0x52, 0x72, 0x52, 0x52,\n                           0x80, 0x04, 0x14, 0x14, 0x1C, 0x14, 0x14, 0x80, 0x04, 0x45, 0x45, 0x47, 0x57, 0x25, 0x80,\n                           0x04, 0x10, 0x10, 0x10, 0x14, 0x08, 0x80, 0x0A, 0x01, 0x01, 0x01, 0x0F, 0x14, 0x0C, 0x14,\n                           0x50, 0x70, 0x70, 0x50, 0x80, 0x0A, 0x03, 0x05, 0x03, 0x05, 0x04, 0x04, 0x1C, 0x50, 0x70,\n                           0x70, 0x50, 0x80, 0x04, 0x39, 0x4B, 0x3D, 0x49, 0x39, 0x80, 0x03, 0x18, 0x0C, 0x0C, 0x0C,\n                           0x80, 0x03, 0x0C, 0x0C, 0x0C, 0x18, 0x80, 0x03, 0x66, 0x33, 0x33, 0x33, 0x80, 0x03, 0x33,\n                           0x33, 0x33, 0x66, 0x80, 0x09, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x80, 0x06, 0x04, 0x0C, 0x1C, 0x3C, 0x1C, 0x0C, 0x04, 0x80, 0x08, 0x03, 0x63, 0x30, 0x18,\n                           0x0C, 0x06, 0x03, 0x6C, 0x6C, 0x80, 0x08, 0x03, 0x63, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xD6,\n                           0xD6, 0x80, 0x02, 0x18, 0x18, 0x08, 0x80, 0x02, 0x36, 0x36, 0x12, 0x80, 0x02, 0xDB, 0xDB,\n                           0x49, 0x80, 0x02, 0x18, 0x18, 0x10, 0x80, 0x02, 0x36, 0x36, 0x24, 0x80, 0x02, 0xDB, 0xDB,\n                           0x92, 0x80, 0x06, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x80, 0x06, 0x06, 0x0C, 0x18,\n                           0x30, 0x18, 0x0C, 0x06, 0x80, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x80, 0x06,\n                           0x7E, 0xC3, 0xDB, 0xD8, 0x78, 0x38, 0x18, 0x80, 0x01, 0x41, 0x3E, 0x80, 0x01, 0x3E, 0x41,\n                           0x80, 0x04, 0x60, 0x30, 0x18, 0x1C, 0x36, 0x80, 0x02, 0x08, 0x1C, 0x14, 0x80, 0x02, 0x22,\n                           0x77, 0x55, 0x80, 0x01, 0x3C, 0x3C, 0x80, 0x09, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0C,\n                           0x0C, 0x06, 0x06, 0x80, 0x09, 0x3C, 0x0C, 0x0C, 0x0C, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,\n                           0x80, 0x09, 0x3C, 0x30, 0x30, 0x30, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x80, 0x06, 0xDE,\n                           0xF3, 0xF3, 0xD8, 0xCC, 0xCC, 0xCC, 0x80, 0x01, 0xCC, 0xCC, 0x80, 0x06, 0x7B, 0xCF, 0xCF,\n                           0x63, 0x33, 0x33, 0x33, 0x80, 0x05, 0x7E, 0x7E, 0x60, 0x60, 0x30, 0x30, 0x80, 0x09, 0x7F,\n                           0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x80, 0x06, 0x7C, 0x4E, 0x4F, 0x4F,\n                           0x4F, 0x4E, 0x7C, 0x80, 0x06, 0x1F, 0x39, 0x79, 0x79, 0x79, 0x39, 0x1F, 0x80, 0x09, 0x1E,\n                           0x33, 0x03, 0xF3, 0x33, 0x33, 0xFE, 0x30, 0x30, 0xF0, 0x80, 0x0D, 0x20, 0x20, 0x3E, 0x73,\n                           0x13, 0x13, 0x0B, 0x0B, 0x0B, 0x07, 0x67, 0x3E, 0x02, 0x02, 0x80, 0x09, 0x3E, 0x63, 0x03,\n                           0x03, 0x6B, 0x1B, 0x1B, 0x1B, 0x7B, 0x3E, 0x80, 0x09, 0x1F, 0x03, 0x03, 0x03, 0x0F, 0xB3,\n                           0x73, 0x33, 0x33, 0x33, 0x80, 0x09, 0x1C, 0x36, 0x06, 0x1F, 0x06, 0x1F, 0x06, 0x06, 0x67,\n                           0x3F, 0x80, 0x08, 0x40, 0x37, 0x6B, 0x7B, 0x6B, 0x6B, 0x6F, 0x6B, 0x02, 0x80, 0x09, 0x66,\n                           0x66, 0x6E, 0xFF, 0x6E, 0x76, 0xFF, 0x76, 0x66, 0x66, 0x80, 0x09, 0x3F, 0x66, 0x66, 0x3E,\n                           0x46, 0x66, 0xF6, 0x66, 0x66, 0xCF, 0x80, 0x09, 0x1F, 0x33, 0x33, 0x33, 0x1F, 0x07, 0xCF,\n                           0x6B, 0xDB, 0x73, 0x80, 0x09, 0x81, 0x81, 0x81, 0x5A, 0xFF, 0x5A, 0xFF, 0x24, 0x24, 0x24,\n                           0x80, 0x07, 0x4F, 0x51, 0x55, 0x55, 0x55, 0x55, 0x45, 0x3D, 0x80, 0x09, 0x38, 0x6C, 0x06,\n                           0x3F, 0x06, 0x1F, 0x06, 0x06, 0x6C, 0x38, 0x80, 0x09, 0x67, 0x66, 0x36, 0x1E, 0x7F, 0x1E,\n                           0x36, 0x66, 0x66, 0x67, 0x80, 0x09, 0x7E, 0x7E, 0x5A, 0x18, 0x78, 0x1E, 0x78, 0x1E, 0x18,\n                           0x3C, 0x80, 0x0A, 0x08, 0x3E, 0x6D, 0x6C, 0xCC, 0xCC, 0xCC, 0xC6, 0x66, 0x6F, 0x3B, 0x80,\n                           0x0B, 0x0E, 0x0B, 0x4B, 0x6B, 0x3E, 0x18, 0x0C, 0x76, 0x1B, 0x19, 0x18, 0x70, 0x80, 0x0B,\n                           0x0E, 0x0B, 0x4B, 0x6B, 0x3E, 0x18, 0x0C, 0x76, 0x1B, 0x31, 0x60, 0x38, 0x80, 0x09, 0x3C,\n                           0x46, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x46, 0x3C, 0x80, 0x09, 0x72, 0x9D, 0x1A, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x98, 0x70, 0x80, 0x09, 0x3C, 0x18, 0x3E, 0x5B, 0x1B, 0x1B, 0x5B,\n                           0x3E, 0x98, 0xFC, 0x80, 0x0B, 0x0E, 0x03, 0x43, 0x63, 0x3E, 0x18, 0x0C, 0x76, 0xDB, 0xD9,\n                           0xD8, 0x70, 0x80, 0x0B, 0x0E, 0x03, 0x43, 0x63, 0x3E, 0x18, 0x0C, 0xDE, 0xDB, 0xD9, 0xD8,\n                           0xB0, 0x80, 0x09, 0x1E, 0x33, 0x61, 0x64, 0x7C, 0x64, 0x60, 0x61, 0x33, 0x1E, 0x80, 0x09,\n                           0xFE, 0x9D, 0x1A, 0x58, 0x78, 0x58, 0x18, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x58, 0x66, 0x62,\n                           0xE1, 0x31, 0x31, 0x3E, 0x19, 0x19, 0x0E, 0x80, 0x09, 0x4A, 0xAD, 0xA8, 0x68, 0x34, 0x2C,\n                           0x16, 0x95, 0x55, 0x32, 0x80, 0x0C, 0x12, 0x0D, 0x01, 0x12, 0x3E, 0x66, 0x64, 0x64, 0x65,\n                           0x62, 0x60, 0x2C, 0x12, 0x80, 0x09, 0x47, 0x45, 0x45, 0x45, 0x7D, 0x45, 0x45, 0x45, 0x45,\n                           0x47, 0x80, 0x09, 0x1C, 0x18, 0x18, 0x6C, 0xDC, 0xDC, 0xCC, 0x66, 0x66, 0x67, 0x80, 0x09,\n                           0x1C, 0x78, 0x18, 0x6E, 0xDC, 0xDC, 0xCC, 0x66, 0x66, 0x67, 0x80, 0x09, 0xCC, 0x72, 0x60,\n                           0x60, 0x30, 0x30, 0xF8, 0x36, 0x11, 0x0E, 0x80, 0x09, 0x8E, 0x71, 0x20, 0x30, 0x60, 0xC0,\n                           0xC6, 0xC3, 0x42, 0x3C, 0x80, 0x09, 0x62, 0x92, 0x9C, 0x78, 0x18, 0x0C, 0x0E, 0x8D, 0x5D,\n                           0x36, 0x80, 0x09, 0x70, 0x98, 0x8C, 0x4C, 0x26, 0x16, 0x0E, 0x87, 0x66, 0x1C, 0x80, 0x09,\n                           0x1B, 0xFF, 0x1B, 0x7B, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7B, 0x80, 0x09, 0x47, 0x45, 0x4D,\n                           0x4D, 0x55, 0x55, 0x65, 0x65, 0x45, 0x47, 0x80, 0x09, 0x33, 0xF3, 0xB7, 0xFF, 0x3F, 0xFB,\n                           0x33, 0x33, 0x33, 0x33, 0x80, 0x09, 0x3C, 0x42, 0x9D, 0xA5, 0xA5, 0x9D, 0x85, 0x85, 0x42,\n                           0x3C, 0x80, 0x0A, 0x02, 0x71, 0xC9, 0xC5, 0xC6, 0xD2, 0x56, 0x25, 0x0D, 0x0D, 0x06, 0x80,\n                           0x09, 0x3F, 0x45, 0x45, 0x45, 0x45, 0x3D, 0x05, 0x05, 0x05, 0x07, 0x80, 0x0A, 0x3E, 0x45,\n                           0x45, 0x45, 0x45, 0x45, 0x45, 0x55, 0x65, 0x7E, 0x80, 0x80, 0x09, 0x7C, 0xB2, 0xB2, 0x98,\n                           0x78, 0x38, 0x2C, 0x2C, 0xAD, 0x46, 0x80, 0x09, 0x1A, 0x65, 0xC5, 0x36, 0x1D, 0x64, 0x64,\n                           0x64, 0xE5, 0x43, 0x80, 0x09, 0x3F, 0x45, 0x45, 0x45, 0x45, 0x3D, 0x0D, 0x15, 0x25, 0x47,\n                           0x80, 0x0A, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x36, 0xB6, 0xE6, 0x66, 0x77, 0x10, 0x80, 0x0C,\n                           0x0C, 0x30, 0x3F, 0x63, 0x63, 0x63, 0x3F, 0x1B, 0x3B, 0x3B, 0x67, 0x67, 0x04, 0x80, 0x03,\n                           0x8E, 0xDB, 0xAC, 0x8B, 0x80, 0x04, 0x7F, 0x4A, 0x5A, 0x4A, 0xFA, 0x80, 0x03, 0x8F, 0xDA,\n                           0xAA, 0x8A, 0x80, 0x0C, 0x06, 0x18, 0x73, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x67, 0x36, 0x1C,\n                           0x0A, 0x02, 0x80, 0x09, 0x7F, 0x50, 0x28, 0x28, 0x14, 0x14, 0x0A, 0x0A, 0x05, 0x7F, 0x80,\n                           0x0C, 0x7F, 0x39, 0x0C, 0x7F, 0x30, 0x18, 0x1C, 0x30, 0x60, 0x60, 0x63, 0x63, 0x3E, 0x80,\n                           0x09, 0x18, 0x64, 0xC0, 0xC8, 0x30, 0xC8, 0xC0, 0xC0, 0x66, 0x19, 0x80, 0x06, 0x0E, 0x18,\n                           0x18, 0x18, 0x18, 0x38, 0x18, 0x80, 0x0B, 0x1C, 0x36, 0x1C, 0x08, 0x1C, 0x1C, 0x36, 0x36,\n                           0x63, 0x7F, 0x63, 0x63, 0x80, 0x09, 0x78, 0xB4, 0xB4, 0x58, 0x78, 0xD8, 0x8C, 0x8C, 0x4D,\n                           0x36, 0x80, 0x09, 0x28, 0xD6, 0x13, 0x33, 0x63, 0x63, 0x33, 0x03, 0xC6, 0x38, 0x80, 0x06,\n                           0x3C, 0x66, 0xE7, 0xFF, 0x07, 0xE6, 0x7C, 0x80, 0x06, 0x38, 0x64, 0x22, 0x1F, 0x03, 0x13,\n                           0x0E, 0x80, 0x09, 0x32, 0x4A, 0x3C, 0x08, 0x3C, 0x06, 0x03, 0xC3, 0x33, 0x1E, 0x80, 0x09,\n                           0xCE, 0x73, 0x18, 0x5C, 0x3A, 0x18, 0x0C, 0x0C, 0x0D, 0x06, 0x80, 0x09, 0x78, 0x30, 0x30,\n                           0x30, 0x34, 0x3C, 0x34, 0x31, 0x33, 0x7F, 0x80, 0x09, 0x48, 0x48, 0x48, 0x68, 0x6C, 0x7C,\n                           0x5C, 0x5A, 0x4A, 0x89, 0x80, 0x06, 0x38, 0x64, 0x62, 0x63, 0x23, 0x13, 0x0E, 0x80, 0x09,\n                           0x42, 0x63, 0xE7, 0x5E, 0x1C, 0x3A, 0x73, 0xE7, 0xC6, 0x47, 0x80, 0x09, 0x01, 0x3F, 0x7E,\n                           0x60, 0x60, 0x60, 0x60, 0x30, 0x7E, 0x7F, 0x80, 0x09, 0x02, 0x1E, 0x3C, 0x30, 0x30, 0x30,\n                           0x30, 0x78, 0x7E, 0x4F, 0x80, 0x09, 0x01, 0x7F, 0x7E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38,\n                           0x18, 0x80, 0x01, 0x1C, 0x1C, 0x80, 0x06, 0x1E, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x3E, 0x80,\n                           0x06, 0xBE, 0xFF, 0xC1, 0x61, 0x41, 0x7F, 0x3E, 0x80, 0x0C, 0x03, 0x03, 0x43, 0x63, 0x33,\n                           0x18, 0x0C, 0x06, 0x3B, 0x61, 0x38, 0x60, 0x38, 0x80, 0x0C, 0x07, 0x0C, 0x46, 0x63, 0x3F,\n                           0x18, 0x0C, 0x06, 0x3B, 0x61, 0x38, 0x60, 0x38, 0x80, 0x0C, 0x03, 0x03, 0x43, 0x63, 0x33,\n                           0x18, 0x0C, 0x06, 0x7B, 0x19, 0x38, 0x60, 0x38, 0x80, 0x0C, 0x07, 0x0C, 0x46, 0x63, 0x3F,\n                           0x18, 0x0C, 0x06, 0x7B, 0x19, 0x38, 0x60, 0x38, 0x80, 0x0C, 0x07, 0x0C, 0x46, 0x6C, 0x37,\n                           0x18, 0x0C, 0x06, 0x7B, 0x19, 0x38, 0x60, 0x38, 0x80, 0x0C, 0x0C, 0x0E, 0x4D, 0x6F, 0x3C,\n                           0x18, 0x0C, 0x06, 0x7B, 0x19, 0x38, 0x60, 0x38, 0x80, 0x0C, 0x03, 0x03, 0x43, 0x63, 0x33,\n                           0x18, 0x0C, 0x06, 0x3B, 0x0D, 0x3C, 0x6C, 0x38, 0x80, 0x0C, 0x0F, 0x03, 0x47, 0x6C, 0x37,\n                           0x18, 0x0C, 0x06, 0x3B, 0x0D, 0x3C, 0x6C, 0x38, 0x80, 0x0C, 0x03, 0x03, 0x43, 0x63, 0x33,\n                           0x18, 0x0C, 0x06, 0x3B, 0x6D, 0x38, 0x6C, 0x38, 0x80, 0x0C, 0x07, 0x0C, 0x46, 0x6C, 0x37,\n                           0x18, 0x0C, 0x06, 0x3B, 0x6D, 0x38, 0x6C, 0x38, 0x80, 0x0C, 0x0F, 0x01, 0x47, 0x6C, 0x37,\n                           0x18, 0x0C, 0x06, 0x3B, 0x6D, 0x38, 0x6C, 0x38, 0x80, 0x0C, 0x0F, 0x0C, 0x46, 0x66, 0x36,\n                           0x18, 0x0C, 0x06, 0x3B, 0x6D, 0x38, 0x6C, 0x38, 0x80, 0x09, 0x03, 0x03, 0x43, 0x63, 0x33,\n                           0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0x09, 0x7F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,\n                           0x36, 0x7F, 0x80, 0x09, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x80,\n                           0x09, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x73, 0x73, 0x23, 0x80, 0x09, 0xDB, 0xDB,\n                           0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0xCE, 0xC4, 0x80, 0x09, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9,\n                           0xA9, 0xA9, 0xA6, 0xA6, 0xA6, 0x80, 0x09, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAA, 0xAA,\n                           0xAA, 0xAA, 0x80, 0x09, 0xDB, 0xDB, 0xDB, 0x73, 0x73, 0x73, 0xDB, 0xDB, 0xDB, 0xDB, 0x80,\n                           0x09, 0xDB, 0xDB, 0xDB, 0xCE, 0xCE, 0xCE, 0xDB, 0xDB, 0xDB, 0xDB, 0x80, 0x09, 0xA9, 0xA9,\n                           0xA9, 0xA6, 0xA6, 0xA6, 0xA9, 0xA9, 0xA9, 0xA9, 0x80, 0x06, 0x36, 0x36, 0x36, 0x36, 0x36,\n                           0x36, 0x36, 0x80, 0x06, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x80, 0x06, 0xDB, 0xDB,\n                           0xDB, 0xDB, 0xDB, 0x73, 0x23, 0x80, 0x06, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0xC4, 0x80,\n                           0x06, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA6, 0xA6, 0x80, 0x01, 0xA8, 0xA8, 0x80, 0x06, 0xAD,\n                           0xAD, 0xAD, 0xAD, 0xAA, 0xAA, 0xAA, 0x80, 0x06, 0xDB, 0xDB, 0x73, 0x73, 0x73, 0xDB, 0xDB,\n                           0x80, 0x06, 0xDB, 0xDB, 0xCE, 0xCE, 0xCE, 0xDB, 0xDB, 0x80, 0x06, 0xA9, 0xA9, 0xA6, 0xA6,\n                           0xA9, 0xA9, 0xA9, 0x80, 0x09, 0x3C, 0x5A, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x5A, 0x3C,\n                           0x80, 0x09, 0x1F, 0x33, 0x67, 0x6B, 0x6B, 0x6B, 0x6B, 0x67, 0x33, 0x1F, 0x80, 0x09, 0x3C,\n                           0x5A, 0x99, 0xBD, 0xDB, 0xDB, 0xBD, 0x99, 0x5A, 0x3C, 0x80, 0x04, 0x0C, 0x06, 0xFF, 0x06,\n                           0x0C, 0x80, 0x09, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x04,\n                           0x30, 0x60, 0xFF, 0x60, 0x30, 0x80, 0x09, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E,\n                           0x3C, 0x18, 0x80, 0x04, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x80, 0x08, 0x18, 0x3C, 0x7E, 0x18,\n                           0x18, 0x18, 0x7E, 0x3C, 0x18, 0x80, 0x06, 0xF0, 0xE0, 0xB0, 0x18, 0x0C, 0x06, 0x03, 0x80,\n                           0x06, 0x03, 0x06, 0x0C, 0x18, 0xB0, 0xE0, 0xF0, 0x80, 0x06, 0xC0, 0x60, 0x30, 0x18, 0x0D,\n                           0x07, 0x0F, 0x80, 0x04, 0x4C, 0x46, 0xFF, 0x26, 0x2C, 0x80, 0x04, 0x34, 0x64, 0xFF, 0x62,\n                           0x32, 0x80, 0x02, 0x07, 0x73, 0xDD, 0x80, 0x02, 0xE0, 0xCE, 0xBB, 0x80, 0x04, 0x6C, 0x36,\n                           0xFF, 0x36, 0x6C, 0x80, 0x09, 0x18, 0x3C, 0x7E, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18,\n                           0x80, 0x04, 0x36, 0x6C, 0xFF, 0x6C, 0x36, 0x80, 0x09, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C,\n                           0x18, 0x7E, 0x3C, 0x18, 0x80, 0x04, 0xCC, 0x66, 0x3F, 0x66, 0xCC, 0x80, 0x04, 0x33, 0x66,\n                           0xFC, 0x66, 0x33, 0x80, 0x04, 0xCC, 0xC6, 0xFF, 0xC6, 0xCC, 0x80, 0x09, 0x18, 0x3C, 0x7E,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x80, 0x04, 0x33, 0x63, 0xFF, 0x63, 0x33, 0x80,\n                           0x09, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x80, 0x09, 0x18, 0x3C,\n                           0x7E, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x80, 0x05, 0x60, 0xCC, 0xC6, 0x7F, 0x06,\n                           0x0C, 0x80, 0x05, 0x06, 0x33, 0x63, 0xFE, 0x60, 0x30, 0x80, 0x05, 0x60, 0xDC, 0xD6, 0x7F,\n                           0x16, 0x0C, 0x80, 0x05, 0x06, 0x3B, 0x6B, 0xFE, 0x68, 0x30, 0x80, 0x04, 0x24, 0x5A, 0xFF,\n                           0x66, 0x24, 0x80, 0x04, 0x34, 0x76, 0xFF, 0x6E, 0x2C, 0x80, 0x09, 0x0C, 0x0C, 0x06, 0xC6,\n                           0xFF, 0x63, 0x68, 0x38, 0x38, 0x78, 0x80, 0x08, 0x0C, 0x06, 0x7F, 0x66, 0x6C, 0x60, 0x60,\n                           0x60, 0x60, 0x80, 0x08, 0x18, 0x30, 0x7F, 0x33, 0x1B, 0x03, 0x03, 0x03, 0x03, 0x80, 0x08,\n                           0x60, 0x60, 0x60, 0x60, 0x6C, 0x66, 0x7F, 0x06, 0x0C, 0x80, 0x08, 0x03, 0x03, 0x03, 0x03,\n                           0x1B, 0x33, 0x7F, 0x30, 0x18, 0x80, 0x05, 0x3F, 0x30, 0x30, 0xFC, 0x78, 0x30, 0x80, 0x05,\n                           0x60, 0x6C, 0x66, 0x7F, 0x06, 0x0C, 0x80, 0x07, 0x78, 0xCC, 0xCC, 0xCC, 0x0C, 0x3F, 0x1E,\n                           0x0C, 0x80, 0x07, 0x1E, 0x33, 0x33, 0x33, 0x30, 0xFC, 0x78, 0x30, 0x80, 0x09, 0x19, 0x0D,\n                           0xFF, 0x0D, 0x19, 0x98, 0xB0, 0xFF, 0xB0, 0x98, 0x80, 0x08, 0x78, 0x38, 0x68, 0xC0, 0xC3,\n                           0xC3, 0xC3, 0x66, 0x3C, 0x80, 0x08, 0x1E, 0x1C, 0x16, 0x03, 0xC3, 0xC3, 0xC3, 0x66, 0x3C,\n                           0x80, 0x09, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x09, 0x18,\n                           0x1C, 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x09, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x78, 0x38, 0x18, 0x80, 0x09, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x1E, 0x1C, 0x18, 0x80, 0x09, 0x30, 0x60, 0xFF, 0x60, 0x30, 0x0C, 0x06, 0xFF, 0x06, 0x0C,\n                           0x80, 0x09, 0x24, 0x74, 0xFC, 0x24, 0x24, 0x24, 0x24, 0x3F, 0x2E, 0x24, 0x80, 0x09, 0x0C,\n                           0x06, 0xFF, 0x06, 0x0C, 0x30, 0x60, 0xFF, 0x60, 0x30, 0x80, 0x09, 0x24, 0x7E, 0xFF, 0x24,\n                           0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x80, 0x09, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,\n                           0xFF, 0x7E, 0x24, 0x80, 0x04, 0x44, 0xFE, 0x23, 0xFE, 0x24, 0x80, 0x04, 0x34, 0x7E, 0xD3,\n                           0x7E, 0x2C, 0x80, 0x04, 0x24, 0x7F, 0xC4, 0x7F, 0x22, 0x80, 0x04, 0x04, 0xFE, 0x03, 0xFE,\n                           0x04, 0x80, 0x09, 0x1C, 0x3E, 0x77, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x80, 0x04,\n                           0x20, 0x7F, 0xC0, 0x7F, 0x20, 0x80, 0x09, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x77,\n                           0x3E, 0x1C, 0x80, 0x04, 0x24, 0x7E, 0xC3, 0x7E, 0x24, 0x80, 0x09, 0x1C, 0x3E, 0x77, 0x36,\n                           0x36, 0x36, 0x36, 0x77, 0x3E, 0x1C, 0x80, 0x08, 0x0F, 0x07, 0x0D, 0x1B, 0x37, 0x6D, 0xD8,\n                           0x30, 0x20, 0x80, 0x08, 0xF0, 0xE0, 0xB0, 0xD8, 0xEC, 0xB6, 0x1B, 0x0C, 0x04, 0x80, 0x08,\n                           0x04, 0x0C, 0x1B, 0xB6, 0xEC, 0xD8, 0xB0, 0xE0, 0xF0, 0x80, 0x08, 0x20, 0x30, 0xD8, 0x6D,\n                           0x37, 0x1B, 0x0D, 0x07, 0x0F, 0x80, 0x06, 0x08, 0xFC, 0x06, 0xFF, 0x06, 0xFC, 0x08, 0x80,\n                           0x06, 0x10, 0x3F, 0x60, 0xFF, 0x60, 0x3F, 0x10, 0x80, 0x04, 0x0C, 0x56, 0xFF, 0xA6, 0x0C,\n                           0x80, 0x04, 0x30, 0x65, 0xFF, 0x6A, 0x30, 0x80, 0x09, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x3C,\n                           0x18, 0x3C, 0x18, 0x18, 0x80, 0x09, 0x18, 0x18, 0x3C, 0x18, 0x3C, 0x18, 0x18, 0x7E, 0x3C,\n                           0x18, 0x80, 0x04, 0x0C, 0x06, 0xAB, 0x06, 0x0C, 0x80, 0x03, 0x18, 0x3C, 0x66, 0x18, 0x80,\n                           0x04, 0x30, 0x60, 0xD5, 0x60, 0x30, 0x80, 0x03, 0x18, 0x66, 0x3C, 0x18, 0x80, 0x04, 0x19,\n                           0x0D, 0xFF, 0x0D, 0x19, 0x80, 0x04, 0x98, 0xB0, 0xFF, 0xB0, 0x98, 0x80, 0x06, 0x08, 0xFC,\n                           0x82, 0x81, 0x82, 0xFC, 0x08, 0x80, 0x09, 0x08, 0x14, 0x22, 0x63, 0x22, 0x22, 0x22, 0x22,\n                           0x22, 0x3E, 0x80, 0x06, 0x10, 0x3F, 0x41, 0x81, 0x41, 0x3F, 0x10, 0x80, 0x09, 0x3E, 0x22,\n                           0x22, 0x22, 0x22, 0x22, 0x63, 0x22, 0x14, 0x08, 0x80, 0x06, 0x08, 0x14, 0x22, 0x63, 0x22,\n                           0x22, 0x3E, 0x80, 0x02, 0x3E, 0x22, 0x3E, 0x80, 0x09, 0x08, 0x14, 0x22, 0x63, 0x22, 0x22,\n                           0x22, 0x63, 0x41, 0x7F, 0x80, 0x09, 0x08, 0x14, 0x3E, 0x63, 0x22, 0x22, 0x22, 0x63, 0x41,\n                           0x7F, 0x80, 0x09, 0x08, 0x1C, 0x2A, 0x6B, 0x2A, 0x2A, 0x2A, 0x6B, 0x49, 0x7F, 0x80, 0x0A,\n                           0x08, 0x14, 0x2A, 0x77, 0x22, 0x63, 0x22, 0x22, 0x22, 0x22, 0x3E, 0x80, 0x0A, 0x08, 0x14,\n                           0x2A, 0x77, 0x22, 0x63, 0x22, 0x22, 0x63, 0x41, 0x7F, 0x80, 0x06, 0x17, 0x3D, 0x41, 0x81,\n                           0x41, 0x3D, 0x17, 0x80, 0x08, 0xFF, 0x01, 0x3D, 0x1D, 0x35, 0x61, 0xC1, 0x81, 0x01, 0x80,\n                           0x08, 0x80, 0x81, 0x83, 0x86, 0xAC, 0xB8, 0xBC, 0x80, 0xFF, 0x80, 0x0A, 0x08, 0x14, 0x22,\n                           0x63, 0x22, 0x22, 0x22, 0x63, 0x22, 0x14, 0x08, 0x80, 0x09, 0x63, 0x63, 0x7F, 0x63, 0x36,\n                           0x36, 0x1C, 0x1C, 0x08, 0x08, 0x80, 0x08, 0x3C, 0x66, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66,\n                           0x3C, 0x80, 0x09, 0x1C, 0x36, 0x60, 0x60, 0x7C, 0x66, 0x63, 0x63, 0x33, 0x1E, 0x80, 0x09,\n                           0x7F, 0x60, 0x60, 0x60, 0x7E, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x80, 0x0B, 0x10, 0x7F, 0x68,\n                           0x68, 0x68, 0x7E, 0x68, 0x64, 0x64, 0x64, 0x7F, 0x02, 0x80, 0x09, 0xC0, 0x7C, 0x66, 0xF3,\n                           0xDB, 0xDB, 0xCF, 0x66, 0x3E, 0x03, 0x80, 0x09, 0x7F, 0x63, 0x63, 0x63, 0x36, 0x36, 0x1C,\n                           0x1C, 0x08, 0x08, 0x80, 0x08, 0x7C, 0x06, 0x03, 0x03, 0x7F, 0x03, 0x03, 0x06, 0x7C, 0x80,\n                           0x0A, 0x20, 0x7C, 0x26, 0x13, 0x13, 0x7F, 0x13, 0x0B, 0x0E, 0x7C, 0x04, 0x80, 0x06, 0x7C,\n                           0x06, 0x03, 0x7F, 0x03, 0x06, 0x7C, 0x80, 0x08, 0x1F, 0x30, 0x60, 0x60, 0x7F, 0x60, 0x60,\n                           0x30, 0x1F, 0x80, 0x0A, 0x10, 0x1F, 0x38, 0x68, 0x64, 0x7F, 0x64, 0x64, 0x32, 0x1F, 0x02,\n                           0x80, 0x06, 0x1F, 0x30, 0x60, 0x7F, 0x60, 0x30, 0x1F, 0x80, 0x06, 0x7E, 0x7E, 0x7E, 0x7E,\n                           0x7E, 0x7E, 0x7E, 0x80, 0x0B, 0xFF, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0xE7, 0x80, 0x0B, 0xE7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0xFF, 0x80, 0x0B, 0xFF, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x06, 0x83, 0xFF,\n                           0x80, 0x0B, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x06, 0x03, 0x03, 0x80,\n                           0x0B, 0x03, 0x03, 0x06, 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x80, 0x04,\n                           0x24, 0x18, 0x7E, 0x18, 0x24, 0x80, 0x09, 0xC0, 0xC0, 0x60, 0x60, 0x60, 0x30, 0x33, 0x36,\n                           0x1C, 0x18, 0x80, 0x09, 0xC7, 0xCC, 0x66, 0x6C, 0x67, 0x30, 0x33, 0x36, 0x1C, 0x18, 0x80,\n                           0x09, 0xCC, 0xCE, 0x6D, 0x6F, 0x6C, 0x30, 0x33, 0x36, 0x1C, 0x18, 0x80, 0x03, 0x6E, 0x1B,\n                           0x1B, 0x76, 0x80, 0x03, 0x6E, 0xDB, 0xDB, 0x76, 0x80, 0x05, 0x03, 0x03, 0x03, 0x03, 0x03,\n                           0x7F, 0x80, 0x06, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0xFF, 0x80, 0x07, 0x40, 0x68, 0x30,\n                           0x38, 0x2C, 0x46, 0xFF, 0x40, 0x80, 0x06, 0x08, 0x70, 0x1C, 0x17, 0x1C, 0x70, 0x08, 0x80,\n                           0x09, 0x18, 0x18, 0x18, 0x58, 0x38, 0x1C, 0x1A, 0x18, 0x18, 0x18, 0x80, 0x09, 0x36, 0x36,\n                           0x36, 0x76, 0x3E, 0x37, 0x36, 0x36, 0x36, 0x36, 0x80, 0x07, 0x3E, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x63, 0x63, 0x80, 0x0D, 0x30, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x1A, 0x0C, 0x80, 0x0D, 0xCC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x66, 0x66, 0x66, 0x33, 0x80, 0x0D, 0x54, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,\n                           0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x15, 0x80, 0x0D, 0x30, 0x58, 0x18, 0x18, 0x3C, 0x5A, 0x99,\n                           0x99, 0x5A, 0x3C, 0x18, 0x18, 0x1A, 0x0C, 0x80, 0x0D, 0xCC, 0x66, 0x66, 0x66, 0x7E, 0xE7,\n                           0xE7, 0xE7, 0xE7, 0x7E, 0x66, 0x66, 0x66, 0x33, 0x80, 0x0D, 0x54, 0x2A, 0x2A, 0x2A, 0x3E,\n                           0x6B, 0x6B, 0x6B, 0x6B, 0x3E, 0x2A, 0x2A, 0x2A, 0x15, 0x80, 0x0D, 0x18, 0x2C, 0x0C, 0x0C,\n                           0x1C, 0xAC, 0xCC, 0xEC, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x06, 0x80, 0x0D, 0x30, 0x58, 0x18,\n                           0x18, 0x3C, 0x5A, 0x5F, 0x5A, 0x5A, 0x3C, 0x18, 0x18, 0x1A, 0x0C, 0x80, 0x0D, 0x30, 0x58,\n                           0x18, 0x18, 0x3C, 0x5A, 0xFA, 0x5A, 0x5A, 0x3C, 0x18, 0x18, 0x1A, 0x0C, 0x80, 0x03, 0x4E,\n                           0xDB, 0xDB, 0x72, 0x80, 0x05, 0x0E, 0x1B, 0xDB, 0xDB, 0xD8, 0x70, 0x80, 0x08, 0x38, 0x0C,\n                           0x0C, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x1C, 0x80, 0x07, 0x10, 0x10, 0x08, 0x6E, 0x3B, 0x08,\n                           0x04, 0x04, 0x80, 0x07, 0x10, 0x10, 0x6E, 0x3B, 0x08, 0x7F, 0x04, 0x04, 0x80, 0x06, 0x6E,\n                           0x3B, 0x10, 0x7F, 0x08, 0x7F, 0x04, 0x80, 0x09, 0x10, 0x10, 0x6E, 0x3B, 0x08, 0x7F, 0x04,\n                           0x7F, 0x02, 0x02, 0x80, 0x08, 0x10, 0x10, 0x6E, 0x3B, 0x08, 0x6E, 0x3B, 0x04, 0x04, 0x80,\n                           0x01, 0x63, 0x3E, 0x80, 0x01, 0x3E, 0x63, 0x80, 0x01, 0x03, 0xFB, 0x80, 0x01, 0xFB, 0x03,\n                           0x80, 0x01, 0xC0, 0xDF, 0x80, 0x01, 0xDF, 0xC0, 0x80, 0x02, 0x7F, 0x14, 0x7F, 0x80, 0x02,\n                           0x08, 0x14, 0x08, 0x80, 0x01, 0x1C, 0x22, 0x80, 0x02, 0x08, 0x14, 0x22, 0x80, 0x02, 0x22,\n                           0x14, 0x08, 0x80, 0x03, 0x08, 0x08, 0x3E, 0x14, 0x80, 0x03, 0x08, 0x14, 0x22, 0x3E, 0x80,\n                           0x03, 0x64, 0x3E, 0x2D, 0x36, 0x80, 0x02, 0x16, 0x2A, 0x2A, 0x80, 0x02, 0x0C, 0x10, 0x08,\n                           0x80, 0x01, 0x08, 0x7F, 0x80, 0x07, 0x20, 0x10, 0x7E, 0x10, 0x08, 0x7E, 0x08, 0x04, 0x80,\n                           0x0A, 0x20, 0x10, 0x7F, 0x10, 0x08, 0x7F, 0x08, 0x04, 0x7F, 0x04, 0x02, 0x80, 0x09, 0x70,\n                           0x1C, 0x07, 0x1C, 0x70, 0x10, 0x7F, 0x08, 0x7F, 0x04, 0x80, 0x09, 0x07, 0x1C, 0x70, 0x1C,\n                           0x07, 0x10, 0x7F, 0x08, 0x7F, 0x04, 0x80, 0x06, 0xD8, 0x6C, 0x36, 0x1B, 0x36, 0x6C, 0xD8,\n                           0x80, 0x06, 0x1B, 0x36, 0x6C, 0xD8, 0x6C, 0x36, 0x1B, 0x80, 0x09, 0x66, 0x18, 0x3C, 0x66,\n                           0x66, 0x66, 0x66, 0x3C, 0x18, 0x66, 0x80, 0x06, 0x10, 0x73, 0x3E, 0x08, 0x3E, 0x67, 0x04,\n                           0x80, 0x08, 0x20, 0x20, 0x70, 0x1C, 0x17, 0x1C, 0x70, 0x08, 0x08, 0x80, 0x08, 0x08, 0x08,\n                           0x07, 0x1C, 0x74, 0x1C, 0x07, 0x02, 0x02, 0x80, 0x09, 0x20, 0x20, 0x70, 0x1C, 0x17, 0x1C,\n                           0x70, 0x08, 0x7F, 0x08, 0x80, 0x09, 0x08, 0x08, 0x07, 0x1C, 0x74, 0x1C, 0x07, 0x02, 0x7F,\n                           0x02, 0x80, 0x0B, 0x20, 0x20, 0x70, 0x1C, 0x17, 0x1C, 0x70, 0x08, 0x6E, 0x3B, 0x04, 0x04,\n                           0x80, 0x0A, 0x08, 0x08, 0x07, 0x1C, 0x74, 0x1C, 0x07, 0x02, 0x6E, 0x3B, 0x01, 0x80, 0x09,\n                           0x70, 0x1C, 0x07, 0x1C, 0x70, 0x07, 0x1C, 0x70, 0x1C, 0x07, 0x80, 0x09, 0x07, 0x1C, 0x70,\n                           0x1C, 0x07, 0x70, 0x1C, 0x07, 0x1C, 0x70, 0x80, 0x0B, 0x10, 0x70, 0x1C, 0x17, 0x1C, 0x78,\n                           0x0F, 0x1C, 0x74, 0x1C, 0x07, 0x04, 0x80, 0x0B, 0x10, 0x17, 0x1C, 0x70, 0x1C, 0x0F, 0x78,\n                           0x1C, 0x07, 0x1C, 0x74, 0x04, 0x80, 0x09, 0x40, 0x60, 0x38, 0x0F, 0x38, 0x60, 0x4F, 0x38,\n                           0x60, 0x40, 0x80, 0x09, 0x01, 0x03, 0x0E, 0x78, 0x0E, 0x03, 0x79, 0x0E, 0x03, 0x01, 0x80,\n                           0x08, 0x20, 0x60, 0x30, 0x1C, 0x17, 0x1C, 0x38, 0x68, 0x08, 0x80, 0x08, 0x08, 0x0B, 0x0E,\n                           0x1C, 0x74, 0x1C, 0x06, 0x03, 0x02, 0x80, 0x07, 0x20, 0x7E, 0x13, 0x13, 0x0B, 0x0B, 0x7E,\n                           0x04, 0x80, 0x07, 0x10, 0x3F, 0x68, 0x68, 0x64, 0x64, 0x3F, 0x02, 0x80, 0x09, 0x20, 0x7E,\n                           0x13, 0x13, 0x0B, 0x0B, 0x7E, 0x04, 0x7F, 0x02, 0x80, 0x09, 0x10, 0x3F, 0x68, 0x68, 0x64,\n                           0x64, 0x3F, 0x02, 0x7F, 0x01, 0x80, 0x08, 0x7E, 0x03, 0x03, 0x03, 0x03, 0x7E, 0x10, 0x7F,\n                           0x08, 0x80, 0x08, 0x3F, 0x60, 0x60, 0x60, 0x60, 0x3F, 0x08, 0x7F, 0x04, 0x80, 0x07, 0x41,\n                           0x49, 0x45, 0x5F, 0x45, 0x49, 0x22, 0x1C, 0x80, 0x07, 0x41, 0x41, 0x49, 0x5D, 0x5D, 0x49,\n                           0x22, 0x1C, 0x80, 0x07, 0x41, 0x41, 0x49, 0x5D, 0x49, 0x41, 0x22, 0x1C, 0x80, 0x07, 0x7F,\n                           0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x80, 0x07, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x7F, 0x80, 0x06, 0x1C, 0x2A, 0x49, 0x7F, 0x49, 0x2A, 0x1C, 0x80, 0x06, 0x1C, 0x22,\n                           0x41, 0x7F, 0x41, 0x22, 0x1C, 0x80, 0x06, 0x1C, 0x22, 0x55, 0x49, 0x55, 0x22, 0x1C, 0x80,\n                           0x06, 0x1C, 0x22, 0x51, 0x49, 0x45, 0x22, 0x1C, 0x80, 0x06, 0x1C, 0x22, 0x49, 0x5D, 0x49,\n                           0x22, 0x1C, 0x80, 0x06, 0x1C, 0x22, 0x49, 0x55, 0x49, 0x22, 0x1C, 0x80, 0x06, 0x1C, 0x2A,\n                           0x6B, 0x5D, 0x6B, 0x2A, 0x1C, 0x80, 0x06, 0x1C, 0x22, 0x5D, 0x41, 0x5D, 0x22, 0x1C, 0x80,\n                           0x06, 0x1C, 0x22, 0x41, 0x5D, 0x41, 0x22, 0x1C, 0x80, 0x06, 0x7F, 0x49, 0x49, 0x7F, 0x49,\n                           0x49, 0x7F, 0x80, 0x06, 0x7F, 0x41, 0x41, 0x7F, 0x41, 0x41, 0x7F, 0x80, 0x06, 0x7F, 0x63,\n                           0x55, 0x49, 0x55, 0x63, 0x7F, 0x80, 0x06, 0x7F, 0x41, 0x49, 0x5D, 0x49, 0x41, 0x7F, 0x80,\n                           0x08, 0x03, 0x03, 0x03, 0x03, 0xFF, 0x03, 0x03, 0x03, 0x03, 0x80, 0x08, 0xC0, 0xC0, 0xC0,\n                           0xC0, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x09, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x80, 0x09, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,\n                           0x80, 0x08, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x80, 0x08, 0x06, 0x06,\n                           0x06, 0x7E, 0x06, 0x7E, 0x06, 0x06, 0x06, 0x80, 0x08, 0x03, 0x03, 0x03, 0xFF, 0x03, 0xFF,\n                           0x03, 0x03, 0x03, 0x80, 0x08, 0x1B, 0x1B, 0x1B, 0x1B, 0xFB, 0x1B, 0x1B, 0x1B, 0x1B, 0x80,\n                           0x08, 0x15, 0x15, 0x15, 0x15, 0xF5, 0x15, 0x15, 0x15, 0x15, 0x80, 0x08, 0x1B, 0x1B, 0x1B,\n                           0xFB, 0x1B, 0xFB, 0x1B, 0x1B, 0x1B, 0x80, 0x08, 0x03, 0x43, 0x23, 0x23, 0xFF, 0x13, 0x13,\n                           0x0B, 0x03, 0x80, 0x08, 0x03, 0x23, 0x23, 0xFF, 0x13, 0xFF, 0x0B, 0x0B, 0x03, 0x80, 0x08,\n                           0x1B, 0x9B, 0x5B, 0x5B, 0xFB, 0x5B, 0x5B, 0x3B, 0x1B, 0x80, 0x08, 0x1B, 0x9B, 0x5B, 0xFB,\n                           0x5B, 0xFB, 0x5B, 0x3B, 0x1B, 0x80, 0x06, 0x30, 0x60, 0x38, 0x0F, 0x38, 0x60, 0x30, 0x80,\n                           0x06, 0x06, 0x03, 0x0E, 0x78, 0x0E, 0x03, 0x06, 0x80, 0x02, 0x42, 0xFD, 0x42, 0x80, 0x02,\n                           0x42, 0xBF, 0x42, 0x80, 0x02, 0x40, 0xBE, 0x40, 0x80, 0x00, 0x63, 0x80, 0x09, 0x7E, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x07, 0x03, 0x03, 0x03, 0x0F, 0x13,\n                           0x23, 0x23, 0xFF, 0x80, 0x07, 0xC0, 0xE0, 0xD0, 0xC8, 0xC4, 0xC2, 0xC1, 0xFF, 0x80, 0x07,\n                           0x1C, 0x36, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x80, 0x07, 0x63, 0x63, 0x63, 0x63, 0x63,\n                           0x63, 0x36, 0x1C, 0x80, 0x04, 0x08, 0x1C, 0x36, 0x1C, 0x08, 0x80, 0x04, 0x08, 0x08, 0x3E,\n                           0x1C, 0x14, 0x80, 0x06, 0x41, 0x63, 0x55, 0x49, 0x55, 0x63, 0x41, 0x80, 0x06, 0x41, 0x23,\n                           0x15, 0x09, 0x15, 0x23, 0x41, 0x80, 0x06, 0x41, 0x62, 0x54, 0x48, 0x54, 0x62, 0x41, 0x80,\n                           0x06, 0x01, 0x02, 0x04, 0x08, 0x14, 0x22, 0x41, 0x80, 0x06, 0x40, 0x20, 0x10, 0x08, 0x14,\n                           0x22, 0x41, 0x80, 0x07, 0x08, 0x08, 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x63, 0x80, 0x07, 0x63,\n                           0x36, 0x36, 0x1C, 0x1C, 0x08, 0x08, 0x08, 0x80, 0x07, 0x7C, 0x06, 0x73, 0x1B, 0x1B, 0x73,\n                           0x06, 0x7C, 0x80, 0x07, 0x1F, 0x30, 0x67, 0x6C, 0x6C, 0x67, 0x30, 0x1F, 0x80, 0x07, 0x1C,\n                           0x22, 0x49, 0x55, 0x55, 0x55, 0x55, 0x55, 0x80, 0x07, 0x55, 0x55, 0x55, 0x55, 0x55, 0x49,\n                           0x22, 0x1C, 0x80, 0x09, 0x08, 0x08, 0x1C, 0x2A, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x80,\n                           0x06, 0x18, 0x0C, 0x26, 0x73, 0x26, 0x0C, 0x18, 0x80, 0x06, 0x0C, 0x18, 0x32, 0x67, 0x32,\n                           0x18, 0x0C, 0x80, 0x06, 0xA8, 0x54, 0x2A, 0x15, 0x2A, 0x54, 0xA8, 0x80, 0x06, 0x15, 0x2A,\n                           0x54, 0xA8, 0x54, 0x2A, 0x15, 0x80, 0x09, 0x40, 0x60, 0x38, 0x4F, 0x60, 0x38, 0x0F, 0x38,\n                           0x60, 0x40, 0x80, 0x09, 0x01, 0x03, 0x0E, 0x79, 0x03, 0x0E, 0x78, 0x0E, 0x03, 0x01, 0x80,\n                           0x09, 0x50, 0x70, 0x38, 0x0F, 0x38, 0x68, 0x4F, 0x38, 0x64, 0x44, 0x80, 0x09, 0x11, 0x13,\n                           0x0E, 0x78, 0x0E, 0x0B, 0x79, 0x0E, 0x07, 0x05, 0x80, 0x09, 0x20, 0x7F, 0x13, 0x13, 0x0B,\n                           0x0B, 0x7F, 0x04, 0x7F, 0x02, 0x80, 0x09, 0x10, 0x7F, 0x68, 0x68, 0x64, 0x64, 0x7F, 0x02,\n                           0x7F, 0x01, 0x80, 0x08, 0x7F, 0x03, 0x03, 0x03, 0x03, 0x7F, 0x10, 0x7F, 0x08, 0x80, 0x08,\n                           0x7F, 0x60, 0x60, 0x60, 0x60, 0x7F, 0x08, 0x7F, 0x04, 0x80, 0x08, 0x70, 0x1C, 0x07, 0x1C,\n                           0x70, 0x08, 0x6E, 0x3B, 0x08, 0x80, 0x08, 0x07, 0x1C, 0x70, 0x1C, 0x07, 0x08, 0x6E, 0x3B,\n                           0x08, 0x80, 0x0A, 0x40, 0x60, 0x38, 0x0F, 0x38, 0x60, 0x40, 0x08, 0x6E, 0x3B, 0x08, 0x80,\n                           0x0A, 0x01, 0x03, 0x0E, 0x78, 0x0E, 0x03, 0x01, 0x08, 0x6E, 0x3B, 0x08, 0x80, 0x08, 0x10,\n                           0x70, 0x78, 0x6E, 0x6B, 0x6E, 0x78, 0x64, 0x04, 0x80, 0x08, 0x10, 0x13, 0x0F, 0x3B, 0x6B,\n                           0x3B, 0x0F, 0x07, 0x04, 0x80, 0x0A, 0x10, 0x70, 0x78, 0x6E, 0x6B, 0x6E, 0x78, 0x64, 0x04,\n                           0x7F, 0x02, 0x80, 0x0A, 0x10, 0x13, 0x0F, 0x3B, 0x6B, 0x3B, 0x0F, 0x07, 0x04, 0x7F, 0x02,\n                           0x80, 0x07, 0xBC, 0x66, 0xE3, 0xD3, 0xCB, 0xC7, 0x66, 0x3D, 0x80, 0x0D, 0x78, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0D, 0x1E, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0B, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x80, 0x0B, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x80, 0x04, 0x7F, 0x03, 0x03,\n                           0x03, 0x03, 0x80, 0x07, 0x42, 0xA5, 0x7E, 0x24, 0x24, 0x7E, 0xA5, 0x42, 0x80, 0x08, 0x1C,\n                           0x1C, 0x2A, 0x51, 0x6F, 0x41, 0x2A, 0x1C, 0x1C, 0x80, 0x0A, 0x7F, 0x7F, 0x22, 0x22, 0x14,\n                           0x08, 0x14, 0x22, 0x22, 0x7F, 0x7F, 0x80, 0x0D, 0x70, 0xD8, 0xD8, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x1B, 0x1B, 0x1B, 0x0E, 0x80, 0x0D, 0x30, 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x06,\n                           0x06, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x30, 0x80, 0x0D, 0x06, 0x06, 0x0C, 0x0C, 0x18, 0x18,\n                           0x30, 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x06, 0x80, 0x0E, 0xC0, 0x60, 0x30, 0x30, 0x18,\n                           0x18, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x80, 0x0D, 0x0C, 0x0C, 0x0C,\n                           0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x18, 0x18, 0x30, 0x30, 0x60, 0xC0, 0x80, 0x0E, 0x03, 0x06,\n                           0x0C, 0x0C, 0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x80, 0x0D,\n                           0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x03, 0x80,\n                           0x0E, 0xFC, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,\n                           0x0C, 0x80, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,\n                           0x0C, 0xFC, 0x80, 0x0E, 0x3F, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,\n                           0x30, 0x30, 0x30, 0x30, 0x80, 0x0D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,\n                           0x30, 0x30, 0x30, 0x30, 0x3F, 0x80, 0x0E, 0xE0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0C,\n                           0x07, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0D, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xE0, 0x80, 0x0E, 0x07, 0x0C,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xE0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x80, 0x0D, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x0C, 0x07, 0x80, 0x0F, 0xE0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x0C, 0x07, 0x80, 0x0F, 0x07, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xE0, 0x80, 0x0D, 0xFF, 0x83, 0x03, 0x06, 0x06,\n                           0x06, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x18, 0x18, 0x80, 0x0D, 0x18, 0x18, 0x18, 0x0C,\n                           0x0C, 0x0C, 0x0C, 0x06, 0x06, 0x06, 0x06, 0x03, 0x83, 0xFF, 0x80, 0x0D, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x1B, 0x1B, 0x1E, 0x1E, 0x1C, 0x1C, 0x18, 0x18, 0x80, 0x0F, 0xC0, 0xC0,\n                           0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80,\n                           0x09, 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA4, 0x9E, 0x43, 0x3E, 0x04, 0x80, 0x09, 0x1B, 0x1B,\n                           0x1F, 0x1B, 0x1B, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x80, 0x09, 0x03, 0x03, 0x03, 0x03, 0x0F,\n                           0xF0, 0x30, 0x70, 0x30, 0x30, 0x80, 0x09, 0x1B, 0x1B, 0x1F, 0x0E, 0x04, 0xF0, 0x60, 0x60,\n                           0x60, 0x60, 0x80, 0x09, 0x0F, 0x03, 0x07, 0x03, 0x03, 0xF0, 0x30, 0x70, 0x30, 0x30, 0x80,\n                           0x09, 0x0E, 0x03, 0x03, 0x03, 0x0E, 0x78, 0xD8, 0x78, 0xD8, 0xD8, 0x80, 0x01, 0x41, 0x7F,\n                           0x80, 0x09, 0x19, 0x1B, 0x1F, 0x1B, 0x1B, 0x30, 0x30, 0x30, 0x30, 0xF0, 0x80, 0x06, 0x3E,\n                           0x7F, 0x63, 0x63, 0x06, 0x0C, 0x0C, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x00, 0xB6, 0x80, 0x01, 0xB6,\n                           0xB6, 0x80, 0x04, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x00, 0x55, 0x80, 0x01, 0x55, 0x55,\n                           0x80, 0x08, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0xF8, 0xF8,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0xF8, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0x38, 0x80, 0x08, 0xF8, 0xF8, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80,\n                           0x08, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0x1F, 0x1F, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0x3F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0x80, 0x08, 0x3F, 0x3F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x07,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x80, 0x08, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0xF8, 0xF8, 0x80, 0x07, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xF8, 0x80,\n                           0x08, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xF8, 0xF8, 0x80, 0x07, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x1F, 0x80, 0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F,\n                           0x1F, 0x80, 0x07, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x80, 0x08, 0x38, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x3F, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0xF8, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xF8, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0xF8, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0xF8, 0xF8, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x0F,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xF8, 0xF8, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x1F,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x3F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x3F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x0F,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x3F, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3F, 0x3F,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x3F, 0x3F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x08, 0xFF, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0xFF, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x80, 0x08, 0xFF, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08,\n                           0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0xFF, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x08, 0xFF, 0x3F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x80, 0x08, 0xFF, 0xF8, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x08, 0xFF,\n                           0xFF, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x07, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0xFF, 0x80, 0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x1F, 0x80,\n                           0x08, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xF8, 0x80, 0x08, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x80, 0x07, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0xFF, 0x80, 0x08, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xFF, 0x3F, 0x80, 0x08, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xFF, 0xF8, 0x80, 0x08, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0xFF, 0xFF, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0xFF, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0xFF, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xFF, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0xFF, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x0F, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0xFF, 0x3F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xFF, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x3F, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xF8,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x0F,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xFF, 0x3F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,\n                           0x38, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xFF, 0xF8, 0x38, 0x38, 0x38,\n                           0x38, 0x38, 0x38, 0x38, 0x80, 0x0F, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0xFF, 0xFF,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x00, 0x77, 0x80, 0x0F, 0x6C, 0x6C, 0x6C,\n                           0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x80, 0x09,\n                           0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0xFC, 0x6C, 0x6C,\n                           0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x80, 0x09, 0xFC, 0x0C, 0xEC, 0x6C, 0x6C, 0x6C, 0x6C,\n                           0x6C, 0x6C, 0x6C, 0x80, 0x09, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x80, 0x08, 0x7F, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x80, 0x09, 0x7F, 0x60,\n                           0x6F, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x80, 0x08, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0xF8, 0x18, 0xF8, 0x80, 0x07, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0xFC, 0x80,\n                           0x08, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0xEC, 0x0C, 0xFC, 0x80, 0x08, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x80, 0x07, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,\n                           0x7F, 0x80, 0x08, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6F, 0x60, 0x7F, 0x80, 0x0F, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x80, 0x0F, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0xEC, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,\n                           0x6C, 0x6C, 0x6C, 0x80, 0x0F, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0xEC, 0x0C, 0xEC, 0x6C,\n                           0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F,\n                           0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F, 0x6C, 0x6C, 0x6C, 0x6C,\n                           0x6C, 0x6C, 0x6C, 0x6F, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x80, 0x0F, 0x6C,\n                           0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6F, 0x60, 0x6F, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,\n                           0x80, 0x07, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0xFF, 0x6C, 0x6C,\n                           0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x80, 0x06, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,\n                           0x80, 0x07, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0xFF, 0x80, 0x0F, 0x18, 0x18, 0x18,\n                           0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0F,\n                           0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0xFF, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,\n                           0x6C, 0x80, 0x08, 0xC0, 0x70, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0x03,\n                           0x0E, 0x0C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x07, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x0C, 0x0E, 0x03, 0x80, 0x07, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x70, 0xC0, 0x80, 0x0F,\n                           0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01,\n                           0x01, 0x80, 0x0F, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20,\n                           0x40, 0x40, 0x80, 0x80, 0x80, 0x0F, 0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18,\n                           0x18, 0x24, 0x24, 0x42, 0x42, 0x81, 0x81, 0x80, 0x00, 0x1F, 0x80, 0x00, 0xF8, 0x80, 0x08,\n                           0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x01, 0x3F, 0x3F, 0x80, 0x01,\n                           0xF8, 0xF8, 0x80, 0x01, 0xFF, 0xF8, 0x80, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x80, 0x01, 0xFF, 0x3F, 0x80, 0x0F,\n                           0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,\n                           0x18, 0x80, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF,\n                           0xFF, 0x80, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0xFF, 0xFF,\n                           0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n                           0xFF, 0x80, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n                           0x80, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n                           0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n                           0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,\n                           0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x80, 0x0F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,\n                           0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x80, 0x0F, 0x1F, 0x1F, 0x1F,\n                           0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x80, 0x0F,\n                           0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,\n                           0x0F, 0x80, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,\n                           0x07, 0x07, 0x07, 0x07, 0x80, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\n                           0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,\n                           0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x80, 0x0F, 0x88, 0x22, 0x88,\n                           0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x80, 0x0F,\n                           0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,\n                           0x55, 0x80, 0x0F, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE, 0xBB, 0xEE,\n                           0xBB, 0xEE, 0xBB, 0xEE, 0x80, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,\n                           0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x08, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,\n                           0x7F, 0x7F, 0x7F, 0x80, 0x08, 0x7F, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7F, 0x80,\n                           0x08, 0x3E, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x3E, 0x80, 0x08, 0x7F, 0x41, 0x5D,\n                           0x5D, 0x5D, 0x5D, 0x5D, 0x41, 0x7F, 0x80, 0x08, 0x7F, 0x41, 0x7F, 0x41, 0x7F, 0x41, 0x7F,\n                           0x41, 0x7F, 0x80, 0x08, 0x7F, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x7F, 0x80, 0x08,\n                           0x7F, 0x55, 0x7F, 0x55, 0x7F, 0x55, 0x7F, 0x55, 0x7F, 0x80, 0x08, 0x7F, 0x51, 0x63, 0x45,\n                           0x49, 0x51, 0x63, 0x45, 0x7F, 0x80, 0x08, 0x7F, 0x45, 0x63, 0x51, 0x49, 0x45, 0x63, 0x51,\n                           0x7F, 0x80, 0x08, 0x7F, 0x55, 0x63, 0x55, 0x49, 0x55, 0x63, 0x55, 0x7F, 0x80, 0x04, 0x3E,\n                           0x3E, 0x3E, 0x3E, 0x3E, 0x80, 0x04, 0x3E, 0x22, 0x22, 0x22, 0x3E, 0x80, 0x04, 0x7F, 0x7F,\n                           0x7F, 0x7F, 0x7F, 0x80, 0x04, 0x7F, 0x41, 0x41, 0x41, 0x7F, 0x80, 0x0B, 0x7F, 0x7F, 0x7F,\n                           0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x80, 0x0B, 0x7F, 0x41, 0x41, 0x41,\n                           0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7F, 0x80, 0x05, 0x7E, 0x7E, 0x7E, 0x3F, 0x3F,\n                           0x3F, 0x80, 0x05, 0x7E, 0x42, 0x42, 0x21, 0x21, 0x3F, 0x80, 0x06, 0x08, 0x1C, 0x1C, 0x3E,\n                           0x3E, 0x7F, 0x7F, 0x80, 0x06, 0x08, 0x14, 0x14, 0x22, 0x22, 0x41, 0x7F, 0x80, 0x03, 0x08,\n                           0x1C, 0x1C, 0x3E, 0x80, 0x03, 0x08, 0x14, 0x14, 0x3E, 0x80, 0x0A, 0x01, 0x03, 0x07, 0x0F,\n                           0x1F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x80, 0x0A, 0x01, 0x03, 0x05, 0x09, 0x11, 0x21,\n                           0x11, 0x09, 0x05, 0x03, 0x01, 0x80, 0x04, 0x02, 0x0E, 0x1E, 0x0E, 0x02, 0x80, 0x04, 0x02,\n                           0x0E, 0x12, 0x0E, 0x02, 0x80, 0x06, 0x01, 0x07, 0x1F, 0x7F, 0x1F, 0x07, 0x01, 0x80, 0x06,\n                           0x01, 0x07, 0x19, 0x61, 0x19, 0x07, 0x01, 0x80, 0x06, 0x7F, 0x7F, 0x3E, 0x3E, 0x1C, 0x1C,\n                           0x08, 0x80, 0x06, 0x7F, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08, 0x80, 0x03, 0x3E, 0x1C, 0x1C,\n                           0x08, 0x80, 0x03, 0x3E, 0x14, 0x14, 0x08, 0x80, 0x0A, 0x40, 0x60, 0x70, 0x78, 0x7C, 0x7E,\n                           0x7C, 0x78, 0x70, 0x60, 0x40, 0x80, 0x0A, 0x40, 0x60, 0x50, 0x48, 0x44, 0x42, 0x44, 0x48,\n                           0x50, 0x60, 0x40, 0x80, 0x04, 0x10, 0x1C, 0x1E, 0x1C, 0x10, 0x80, 0x04, 0x10, 0x1C, 0x12,\n                           0x1C, 0x10, 0x80, 0x06, 0x40, 0x70, 0x7C, 0x7F, 0x7C, 0x70, 0x40, 0x80, 0x06, 0x40, 0x70,\n                           0x4C, 0x43, 0x4C, 0x70, 0x40, 0x80, 0x09, 0x08, 0x1C, 0x3E, 0x3E, 0x7F, 0x7F, 0x3E, 0x3E,\n                           0x1C, 0x08, 0x80, 0x09, 0x08, 0x14, 0x22, 0x22, 0x41, 0x41, 0x22, 0x22, 0x14, 0x08, 0x80,\n                           0x09, 0x08, 0x14, 0x22, 0x2A, 0x5D, 0x5D, 0x2A, 0x22, 0x14, 0x08, 0x80, 0x09, 0x3C, 0x42,\n                           0x99, 0xBD, 0xBD, 0xBD, 0xBD, 0x99, 0x42, 0x3C, 0x80, 0x09, 0x08, 0x14, 0x14, 0x22, 0x41,\n                           0x41, 0x22, 0x14, 0x14, 0x08, 0x80, 0x09, 0x3C, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n                           0x42, 0x3C, 0x80, 0x09, 0x28, 0x02, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x40, 0x14, 0x80,\n                           0x09, 0x3C, 0x66, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0x66, 0x3C, 0x80, 0x09, 0x3C, 0x42,\n                           0x99, 0xA5, 0xA5, 0xA5, 0xA5, 0x99, 0x42, 0x3C, 0x80, 0x09, 0x3C, 0x7E, 0xFF, 0xFF, 0xFF,\n                           0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x80, 0x09, 0x3C, 0x4E, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,\n                           0x4E, 0x3C, 0x80, 0x09, 0x3C, 0x72, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0x72, 0x3C, 0x80,\n                           0x09, 0x3C, 0x42, 0x81, 0x81, 0x81, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C, 0x80, 0x09, 0x3C, 0x7E,\n                           0xFF, 0xFF, 0xFF, 0x81, 0x81, 0x81, 0x42, 0x3C, 0x80, 0x09, 0x3C, 0x72, 0xF1, 0xF1, 0xF1,\n                           0x81, 0x81, 0x81, 0x42, 0x3C, 0x80, 0x09, 0x3C, 0x72, 0xF1, 0xF1, 0xF1, 0xFF, 0xFF, 0xFF,\n                           0x7E, 0x3C, 0x80, 0x09, 0x0C, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x0C, 0x80,\n                           0x09, 0x30, 0x70, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x70, 0x30, 0x80, 0x0F, 0xFF, 0xFF,\n                           0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,\n                           0x0F, 0xFF, 0xFF, 0xC3, 0xBD, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0xBD, 0xC3, 0xFF, 0xFF,\n                           0xFF, 0xFF, 0x80, 0x06, 0xFF, 0xFF, 0xC3, 0xBD, 0x7E, 0x7E, 0x7E, 0x80, 0x08, 0x7E, 0x7E,\n                           0x7E, 0xBD, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x04, 0x0C, 0x02, 0x01, 0x01, 0x01, 0x80,\n                           0x04, 0x30, 0x40, 0x80, 0x80, 0x80, 0x80, 0x04, 0x80, 0x80, 0x80, 0x40, 0x30, 0x80, 0x04,\n                           0x01, 0x01, 0x01, 0x02, 0x0C, 0x80, 0x04, 0x3C, 0x42, 0x81, 0x81, 0x81, 0x80, 0x04, 0x81,\n                           0x81, 0x81, 0x42, 0x3C, 0x80, 0x0F, 0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8,\n                           0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0x80, 0x0F, 0x01, 0x01, 0x03, 0x03, 0x07, 0x07,\n                           0x0F, 0x0F, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0x7F,\n                           0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x01, 0x01, 0x80, 0x0F,\n                           0xFF, 0xFF, 0xFE, 0xFE, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80,\n                           0x80, 0x80, 0x05, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x80, 0x09, 0xFF, 0x8F, 0x8F, 0x8F,\n                           0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0xFF, 0x80, 0x09, 0xFF, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,\n                           0xF1, 0xF1, 0xFF, 0x80, 0x09, 0xFF, 0xFF, 0xBF, 0x9F, 0x8F, 0x8F, 0x87, 0x83, 0x81, 0xFF,\n                           0x80, 0x09, 0xFF, 0x81, 0xC1, 0xE1, 0xF1, 0xF1, 0xF9, 0xFD, 0xFF, 0xFF, 0x80, 0x09, 0xFF,\n                           0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xFF, 0x80, 0x08, 0x08, 0x08, 0x14, 0x14,\n                           0x22, 0x22, 0x49, 0x41, 0x7F, 0x80, 0x08, 0x08, 0x08, 0x1C, 0x1C, 0x2E, 0x2E, 0x4F, 0x4F,\n                           0x7F, 0x80, 0x08, 0x08, 0x08, 0x1C, 0x1C, 0x3A, 0x3A, 0x79, 0x79, 0x7F, 0x80, 0x0A, 0x3C,\n                           0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3C, 0x80, 0x08, 0x7F, 0x49, 0x49,\n                           0x49, 0x4F, 0x41, 0x41, 0x41, 0x7F, 0x80, 0x08, 0x7F, 0x41, 0x41, 0x41, 0x4F, 0x49, 0x49,\n                           0x49, 0x7F, 0x80, 0x08, 0x7F, 0x41, 0x41, 0x41, 0x79, 0x49, 0x49, 0x49, 0x7F, 0x80, 0x08,\n                           0x7F, 0x49, 0x49, 0x49, 0x79, 0x41, 0x41, 0x41, 0x7F, 0x80, 0x09, 0x3C, 0x52, 0x91, 0x91,\n                           0x91, 0x9F, 0x81, 0x81, 0x42, 0x3C, 0x80, 0x09, 0x3C, 0x42, 0x81, 0x81, 0x9F, 0x91, 0x91,\n                           0x91, 0x52, 0x3C, 0x80, 0x09, 0x3C, 0x42, 0x81, 0x81, 0xF9, 0x89, 0x89, 0x89, 0x4A, 0x3C,\n                           0x80, 0x09, 0x3C, 0x4A, 0x89, 0x89, 0x89, 0xF9, 0x81, 0x81, 0x42, 0x3C, 0x80, 0x08, 0x08,\n                           0x08, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08, 0x08, 0x80, 0x03, 0x0C, 0x3E, 0x7F, 0xFF, 0x80,\n                           0x08, 0x1C, 0x3E, 0x7F, 0x08, 0x08, 0x08, 0x08, 0x28, 0x10, 0x80, 0x07, 0x08, 0x08, 0x14,\n                           0x77, 0x22, 0x2A, 0x36, 0x22, 0x80, 0x08, 0x10, 0x18, 0x0C, 0x06, 0x03, 0x06, 0x2C, 0x38,\n                           0x3C, 0x80, 0x08, 0x7F, 0x63, 0x33, 0x1B, 0x0F, 0x1B, 0xB3, 0xE3, 0xF3, 0x80, 0x06, 0x1C,\n                           0x22, 0x41, 0x49, 0x41, 0x22, 0x1C, 0x80, 0x07, 0x18, 0x24, 0x42, 0x42, 0x42, 0xA5, 0xA5,\n                           0x42, 0x80, 0x07, 0x42, 0xA5, 0xA5, 0x42, 0x42, 0x42, 0x24, 0x18, 0x80, 0x06, 0x60, 0x30,\n                           0x1E, 0x33, 0x33, 0x33, 0x1E, 0x80, 0x09, 0x38, 0x6C, 0x6C, 0x38, 0x18, 0x0C, 0x0E, 0x1B,\n                           0x1B, 0x0E, 0x80, 0x07, 0x7F, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7F, 0x80, 0x07, 0x7F,\n                           0x41, 0x61, 0x51, 0x5D, 0x49, 0x41, 0x7F, 0x80, 0x07, 0x7F, 0x41, 0x77, 0x5D, 0x5D, 0x77,\n                           0x41, 0x7F, 0x80, 0x08, 0x41, 0x63, 0x36, 0x3E, 0x1C, 0x3E, 0x36, 0x63, 0x41, 0x80, 0x07,\n                           0x3E, 0x41, 0x55, 0x41, 0x22, 0x3E, 0x22, 0x1C, 0x80, 0x04, 0x22, 0x63, 0x1C, 0x63, 0x22,\n                           0x80, 0x07, 0x1C, 0x22, 0x77, 0x7F, 0x49, 0x5D, 0x3E, 0x1C, 0x80, 0x09, 0x18, 0x7E, 0x18,\n                           0x18, 0xFF, 0x18, 0x78, 0x1E, 0x18, 0x18, 0x80, 0x09, 0x18, 0x7E, 0x18, 0x18, 0xFF, 0x18,\n                           0x18, 0x18, 0x18, 0x18, 0x80, 0x08, 0x1C, 0x08, 0x08, 0x49, 0x7F, 0x49, 0x08, 0x08, 0x1C,\n                           0x80, 0x09, 0x3C, 0x4E, 0x07, 0x23, 0xFB, 0x73, 0x53, 0x07, 0x4E, 0x3C, 0x80, 0x08, 0x2A,\n                           0x14, 0x2A, 0x55, 0x55, 0x55, 0x55, 0x2A, 0x1C, 0x80, 0x09, 0x3C, 0x5A, 0x99, 0x99, 0x99,\n                           0xBD, 0xFF, 0xDB, 0x5A, 0x3C, 0x80, 0x09, 0x3C, 0x42, 0x81, 0xA1, 0x8D, 0x9F, 0xFF, 0xFB,\n                           0x7E, 0x3C, 0x80, 0x09, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0x81, 0x99, 0xA5, 0x81, 0x7E, 0x80,\n                           0x09, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xA5, 0x99, 0x81, 0x81, 0x7E, 0x80, 0x09, 0x7E, 0xFF,\n                           0xDB, 0xFF, 0xFF, 0xDB, 0xE7, 0xFF, 0xFF, 0x7E, 0x80, 0x08, 0x08, 0x08, 0x2A, 0x14, 0x63,\n                           0x14, 0x2A, 0x08, 0x08, 0x80, 0x09, 0x1E, 0x28, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x28,\n                           0x1E, 0x80, 0x09, 0x78, 0x14, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x14, 0x78, 0x80, 0x0B,\n                           0x66, 0x66, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18, 0x80, 0x09, 0x3C,\n                           0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18, 0x80, 0x09, 0x18, 0x18, 0x7E, 0x18,\n                           0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x80, 0x09, 0x78, 0x60, 0x70, 0x58, 0x1E, 0x33, 0x33,\n                           0x33, 0x33, 0x1E, 0x80, 0x0C, 0xC0, 0xC0, 0xDE, 0xF3, 0xF3, 0xF3, 0xF0, 0xD8, 0xCC, 0xFF,\n                           0xC0, 0xC0, 0xC0, 0x80, 0x09, 0x06, 0x0F, 0x06, 0x76, 0xCE, 0xC6, 0xC6, 0x66, 0x66, 0xC6,\n                           0x80, 0x0A, 0x6B, 0x2A, 0x2A, 0x3E, 0x2A, 0x2A, 0x6B, 0x1C, 0x22, 0x22, 0x1C, 0x80, 0x0B,\n                           0x18, 0x3C, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x3C, 0x18, 0x3C, 0x18, 0x18, 0x80, 0x0A, 0x1F,\n                           0x33, 0x33, 0x33, 0x33, 0x1F, 0x03, 0x03, 0x03, 0x03, 0x7F, 0x80, 0x0A, 0x42, 0xA5, 0xA5,\n                           0x3C, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x80, 0x0A, 0xC3, 0x66, 0x66, 0x66, 0x66,\n                           0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x80, 0x09, 0xC3, 0x7E, 0x66, 0x66, 0x66, 0x66, 0x66,\n                           0x66, 0x7E, 0xC3, 0x80, 0x03, 0x7E, 0xDB, 0x1B, 0x0E, 0x80, 0x03, 0x70, 0xD8, 0xDB, 0x7E,\n                           0x80, 0x0B, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xD8, 0xDE, 0xDB, 0xDB, 0xCE, 0xC0, 0x80, 0x80,\n                           0x0B, 0x29, 0x3E, 0xAA, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x60, 0xD0, 0x80, 0x06,\n                           0x3C, 0x66, 0x66, 0x66, 0x66, 0x24, 0xE7, 0x80, 0x0B, 0x29, 0x3E, 0x2A, 0x2A, 0x2A, 0x2A,\n                           0x2A, 0x2A, 0x2A, 0x2A, 0x20, 0xC0, 0x80, 0x07, 0xF8, 0xE0, 0xF1, 0xDB, 0xCE, 0x0E, 0x1B,\n                           0x11, 0x80, 0x0B, 0x09, 0x0A, 0x0E, 0x16, 0x12, 0x12, 0x72, 0x92, 0x90, 0x70, 0x08, 0x04,\n                           0x80, 0x0A, 0xC3, 0x66, 0x66, 0x66, 0x66, 0xFF, 0x66, 0x66, 0x66, 0x66, 0xC3, 0x80, 0x08,\n                           0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x18, 0x18, 0x3C, 0x80, 0x07, 0x36, 0x49, 0x41, 0x41,\n                           0x41, 0x22, 0x14, 0x08, 0x80, 0x06, 0x08, 0x14, 0x22, 0x41, 0x22, 0x14, 0x08, 0x80, 0x08,\n                           0x18, 0x3C, 0x3C, 0xE7, 0xE7, 0xE7, 0x18, 0x18, 0x3C, 0x80, 0x08, 0x18, 0x24, 0x42, 0x81,\n                           0x81, 0x66, 0x18, 0x18, 0x3C, 0x80, 0x07, 0x36, 0x7F, 0x7F, 0x7F, 0x7F, 0x3E, 0x1C, 0x08,\n                           0x80, 0x06, 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x80, 0x08, 0x18, 0x24, 0x3C, 0xE7,\n                           0xA5, 0xE7, 0x18, 0x18, 0x3C, 0x80, 0x09, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1C,\n                           0x1E, 0x0E, 0x80, 0x09, 0x0C, 0x3C, 0x7C, 0x4C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0F, 0x07, 0x80,\n                           0x0A, 0x0E, 0xFE, 0xF6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, 0xE7, 0xE3, 0x60, 0x80, 0x0A, 0xFE,\n                           0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xE7, 0xE7, 0x63, 0x80, 0x09, 0x03, 0x03, 0x03,\n                           0x03, 0x33, 0x7B, 0x67, 0x23, 0x1B, 0x07, 0x80, 0x0B, 0x02, 0x02, 0x22, 0x3A, 0x2E, 0x22,\n                           0x22, 0x3A, 0x2E, 0x22, 0x20, 0x20, 0x80, 0x0B, 0x20, 0x20, 0x62, 0x3A, 0x2E, 0x23, 0x62,\n                           0x3A, 0x2E, 0x23, 0x02, 0x02, 0x80, 0x09, 0xDC, 0x66, 0x66, 0x66, 0xFF, 0x66, 0x66, 0x66,\n                           0x66, 0xFF, 0x80, 0x09, 0x3C, 0x76, 0x66, 0x06, 0x7F, 0x66, 0x66, 0x66, 0x66, 0xFF, 0x80,\n                           0x09, 0x7C, 0x76, 0x66, 0x66, 0x7F, 0x66, 0x66, 0x66, 0x66, 0xFF, 0x80, 0x09, 0x76, 0xDB,\n                           0xDB, 0x1B, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x80, 0x09, 0xF6, 0xDB, 0xDB, 0xDB, 0xFF,\n                           0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x80, 0x09, 0x1C, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36,\n                           0xB6, 0x6F, 0x80, 0x08, 0x0E, 0xF1, 0x4C, 0x82, 0x11, 0x01, 0x11, 0x02, 0x7C, 0x80, 0x08,\n                           0x0E, 0xF1, 0x4C, 0x82, 0x01, 0x29, 0x01, 0x02, 0x7C, 0x80, 0x08, 0x0E, 0xF1, 0x4C, 0x82,\n                           0x29, 0x01, 0x11, 0x02, 0x7C, 0x80, 0x08, 0x0E, 0xF1, 0x4C, 0x82, 0x29, 0x01, 0x29, 0x02,\n                           0x7C, 0x80, 0x08, 0x04, 0x1C, 0x14, 0x0E, 0x10, 0x10, 0x20, 0x62, 0x9C, 0x80, 0x07, 0x80,\n                           0x40, 0x20, 0x10, 0x12, 0x21, 0x41, 0xBE, 0x80, 0x08, 0x25, 0x90, 0x48, 0x20, 0x10, 0x12,\n                           0x21, 0x41, 0xBE, 0x80, 0x08, 0x45, 0x30, 0xC8, 0x30, 0x08, 0x10, 0x20, 0x20, 0x1F, 0x80,\n                           0x08, 0x45, 0x30, 0xC8, 0x30, 0x08, 0x08, 0x10, 0x20, 0xDF, 0x80, 0x08, 0x0E, 0x01, 0x0E,\n                           0x01, 0x08, 0x16, 0x11, 0x2E, 0xC0, 0x80, 0x04, 0x08, 0x0F, 0x08, 0x28, 0x10, 0x80, 0x04,\n                           0x08, 0xEF, 0x10, 0x10, 0x10, 0x80, 0x05, 0x08, 0x1C, 0x32, 0x4A, 0x4C, 0x3F, 0x80, 0x05,\n                           0x08, 0x1C, 0x32, 0x4A, 0x4C, 0xBF, 0x80, 0x08, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x28, 0x06,\n                           0x01, 0x7F, 0x80, 0x06, 0x54, 0x40, 0x4C, 0x42, 0x4C, 0x63, 0x9E, 0x80, 0x06, 0xC5, 0x30,\n                           0x08, 0x10, 0x20, 0x20, 0x1F, 0x80, 0x06, 0xC5, 0x30, 0x08, 0x08, 0x10, 0x20, 0xDF, 0x80,\n                           0x04, 0x08, 0x14, 0x18, 0x08, 0x04, 0x80, 0x06, 0x30, 0x48, 0xF0, 0x40, 0x3C, 0x18, 0x06,\n                           0x80, 0x05, 0xE0, 0x11, 0xE1, 0x81, 0x7E, 0x08, 0x80, 0x08, 0x04, 0x04, 0x04, 0x04, 0x10,\n                           0x20, 0x40, 0x42, 0x3C, 0x80, 0x08, 0x18, 0x24, 0x19, 0x06, 0x43, 0x48, 0x49, 0x39, 0x06,\n                           0x80, 0x07, 0x40, 0x49, 0x39, 0x06, 0x70, 0x0E, 0x70, 0x0E, 0x80, 0x05, 0x18, 0x06, 0x20,\n                           0x2A, 0x1A, 0x04, 0x80, 0x07, 0x08, 0x14, 0x08, 0x06, 0x20, 0x2A, 0x1A, 0x04, 0x80, 0x05,\n                           0x20, 0x2A, 0x1A, 0x04, 0x30, 0x0C, 0x80, 0x05, 0x08, 0x08, 0x20, 0x2A, 0x1A, 0x04, 0x80,\n                           0x05, 0x70, 0x0F, 0x40, 0x49, 0x39, 0x06, 0x80, 0x08, 0x18, 0x24, 0x18, 0x06, 0x40, 0x49,\n                           0x39, 0x06, 0xFF, 0x80, 0x05, 0x40, 0x48, 0x39, 0x06, 0x70, 0x0E, 0x80, 0x08, 0x08, 0x14,\n                           0x0A, 0x14, 0x10, 0x10, 0x10, 0x10, 0xE0, 0x80, 0x08, 0x10, 0x28, 0x14, 0x28, 0x20, 0x20,\n                           0x20, 0x20, 0x20, 0x80, 0x08, 0x20, 0x10, 0x08, 0x2A, 0x1C, 0x2A, 0x08, 0x10, 0x20, 0x80,\n                           0x08, 0x04, 0x08, 0x10, 0x54, 0x38, 0x54, 0x10, 0x08, 0x04, 0x80, 0x01, 0x54, 0x28, 0x80,\n                           0x04, 0x84, 0x96, 0x95, 0x96, 0x68, 0x80, 0x01, 0x08, 0x10, 0x80, 0x03, 0x18, 0x24, 0x10,\n                           0x08, 0x80, 0x06, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x80, 0x06, 0x08, 0x10, 0x10,\n                           0x10, 0x10, 0x10, 0x08, 0x80, 0x06, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08, 0x18, 0x80, 0x06,\n                           0x18, 0x10, 0x10, 0x20, 0x10, 0x10, 0x18, 0x80, 0x06, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08,\n                           0x18, 0x80, 0x06, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x80, 0x04, 0x14, 0x3E, 0x14,\n                           0x3E, 0x14, 0x80, 0x06, 0x08, 0x14, 0x14, 0x08, 0x54, 0x24, 0x58, 0x80, 0x05, 0x08, 0x08,\n                           0x3E, 0x1C, 0x1C, 0x22, 0x80, 0x04, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x80, 0x04, 0x10, 0x08,\n                           0x04, 0x08, 0x10, 0x80, 0x04, 0x04, 0x08, 0x10, 0x08, 0x04, 0x80, 0x05, 0x04, 0x08, 0x08,\n                           0x10, 0x10, 0x20, 0x80, 0x07, 0x08, 0x1C, 0x2A, 0x0C, 0x18, 0x2A, 0x1C, 0x08, 0x80, 0x05,\n                           0x24, 0x10, 0x10, 0x08, 0x08, 0x24, 0x80, 0x05, 0x1C, 0x22, 0x2A, 0x1A, 0x02, 0x1C, 0x80,\n                           0x05, 0x60, 0x18, 0x06, 0x60, 0x18, 0x06, 0x80, 0x04, 0x18, 0x24, 0x28, 0x18, 0x06, 0x80,\n                           0x04, 0x40, 0x48, 0x49, 0x39, 0x06, 0x80, 0x08, 0x80, 0x7C, 0x02, 0x10, 0x10, 0x10, 0x10,\n                           0x10, 0xE0, 0x80, 0x08, 0x30, 0x08, 0x70, 0x08, 0x20, 0x20, 0x20, 0x20, 0xC0, 0x80, 0x0A,\n                           0x0C, 0x02, 0x1C, 0x02, 0xE0, 0x10, 0x11, 0x61, 0x81, 0x81, 0x7E, 0x80, 0x03, 0x0C, 0x02,\n                           0x1C, 0x02, 0x80, 0x07, 0x38, 0x04, 0x38, 0x04, 0x10, 0x20, 0x20, 0x1F, 0x80, 0x05, 0x10,\n                           0x10, 0x10, 0x10, 0x10, 0xE0, 0x80, 0x08, 0x0E, 0xF1, 0x4C, 0x82, 0x01, 0x11, 0x01, 0x02,\n                           0x7C, 0x80, 0x06, 0x04, 0x04, 0x04, 0x34, 0x4C, 0x45, 0xBE, 0x80, 0x06, 0x04, 0x04, 0x04,\n                           0x34, 0x4C, 0x44, 0x3F, 0x80, 0x06, 0x04, 0x04, 0x04, 0x34, 0x4C, 0x44, 0xBF, 0x80, 0x06,\n                           0x24, 0x04, 0x04, 0x34, 0x4C, 0x45, 0xBE, 0x80, 0x06, 0x24, 0x04, 0x04, 0x34, 0x4C, 0x44,\n                           0x3F, 0x80, 0x06, 0x24, 0x04, 0x04, 0x34, 0x4C, 0x44, 0xBF, 0x80, 0x07, 0x60, 0x90, 0x92,\n                           0xE1, 0x81, 0x81, 0x42, 0x3C, 0x80, 0x06, 0x4C, 0x42, 0x4C, 0x42, 0x40, 0x61, 0x9E, 0x80,\n                           0x0A, 0x40, 0x40, 0x40, 0x40, 0x40, 0xC0, 0x42, 0x41, 0x41, 0x21, 0x1E, 0x80, 0x06, 0x10,\n                           0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x80, 0x06, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xEF,\n                           0x80, 0x07, 0x10, 0x3C, 0xD2, 0x52, 0x22, 0x02, 0x02, 0x02, 0x80, 0x03, 0x30, 0x48, 0x4C,\n                           0x33, 0x80, 0x03, 0x30, 0x48, 0x4C, 0xB3, 0x80, 0x06, 0x10, 0x80, 0x82, 0x81, 0x81, 0x42,\n                           0x3C, 0x80, 0x07, 0x10, 0x28, 0x24, 0x14, 0xCF, 0x24, 0x18, 0x30, 0x80, 0x09, 0x16, 0x09,\n                           0x40, 0x44, 0x48, 0x50, 0x20, 0x30, 0x48, 0x3C, 0x80, 0x08, 0x16, 0x09, 0x40, 0x4C, 0x48,\n                           0x50, 0x50, 0x70, 0xBC, 0x80, 0x09, 0x06, 0x01, 0x4E, 0x45, 0x48, 0x50, 0x20, 0x30, 0x48,\n                           0x3C, 0x80, 0x08, 0x0C, 0x02, 0x5C, 0x4A, 0x48, 0x50, 0x50, 0x70, 0xBC, 0x80, 0x09, 0x8F,\n                           0xAC, 0xAA, 0x51, 0x07, 0x60, 0xA9, 0x6B, 0xAD, 0xE9, 0x80, 0x04, 0x77, 0x51, 0x77, 0x14,\n                           0x17, 0x80, 0x0B, 0x1C, 0x3E, 0x3E, 0x63, 0x49, 0x4F, 0x67, 0x7F, 0x67, 0x3E, 0x3E, 0x1C,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCB, 0x0C, 0x00, 0x9E, 0x00, 0x00, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x75, 0x06, 0x00, 0x00,\n                           0x0A, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD7, 0x0C, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xDD, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xE8, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0xF8, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x02, 0x0D, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0E, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x14, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x20,\n                           0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2C, 0x0D, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7D, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x09, 0xE6, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x80, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x33, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x3D, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x49, 0x0D, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x55, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x61, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x6D, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x79, 0x0D, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x85, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x91, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9D,\n                           0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA9, 0x0D, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x83, 0x00, 0x00, 0x00, 0x09, 0x83, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x83, 0x00, 0x00, 0x00, 0x09, 0xD8, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xB5, 0x0D, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xB2, 0x00, 0x00, 0x00, 0x08, 0xB2, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0xC0, 0x0D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xCB, 0x0D, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0xD4, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8B, 0x02,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x97, 0x02, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xEC, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x84, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA3, 0x02, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x0D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x7E, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xAF, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF2, 0x01, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8A, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xFE, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBB,\n                           0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC7, 0x02, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD3, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x90, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF8, 0x04,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xEB, 0x0D, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x9C, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xA8, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x49, 0x02, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB4, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x04, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x96, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC0, 0x03, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCC, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xD8, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF9,\n                           0x0D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x05, 0x0E, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x10, 0x0E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xA2, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0D, 0xB5, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xE4, 0x03, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x10, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC0, 0x01, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x1C, 0x0E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x9F, 0x01, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE9, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x55, 0x02, 0x00, 0x00, 0x05, 0xEB, 0x02, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xF5, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xF7, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x03, 0x03, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x71, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x01, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x28, 0x0E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x83, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0D,\n                           0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x19, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xC9, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x0C, 0x03,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x0A, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x34, 0x0E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x22, 0x04, 0x00,\n                           0x00, 0x07, 0x1C, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x40, 0x0E,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0xA8, 0x06, 0x00, 0x9F, 0x00, 0x00, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0x4C, 0x0E,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x55, 0x0E, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x62, 0x0E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x6F, 0x0E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x78, 0x0E, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x22, 0x04, 0x00, 0x00, 0x07, 0x1C, 0x05,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x84, 0x0E, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x92, 0x0E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x9E, 0x0E, 0x00,\n                           0x00, 0x06, 0xB2, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA4, 0x0E,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xAB, 0x0E, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x07, 0xD2, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xB2, 0x0E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xB1, 0x06, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x7D, 0x03, 0x00, 0x00, 0x0A, 0xB2, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0xB7, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0xBF, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC7, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xBB, 0x0E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08,\n                           0x01, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xC7, 0x0E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD3, 0x06, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0xB1, 0x06, 0x00, 0x00, 0x06, 0x8A, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xCC, 0x0E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0xD3, 0x0E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xE2, 0x0E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xF1, 0x0E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0F, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDB, 0x06, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x09, 0x0F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xE9, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF5, 0x06, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00, 0x03, 0x45, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x45, 0x01,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0x45, 0x01, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00, 0x03, 0x5B, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x5B, 0x01, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x17, 0x0F, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x03, 0x5B, 0x01, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x23, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x99, 0x00, 0x00, 0x00, 0x03, 0x28, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x03, 0x66, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x66, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x12, 0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x99, 0x00, 0x00, 0x00, 0x03, 0x66, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0x66, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x25, 0x0F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2C, 0x0F,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x03, 0xAB,\n                           0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03,\n                           0xAB, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x38, 0x0F, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0xAB, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x17, 0x02,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x46, 0x0F, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x52, 0x0F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xD4, 0x00, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x15, 0x03, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD5, 0x01, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x33, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x2F, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4,\n                           0x00, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x91, 0x00, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x13, 0x02, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE6, 0x00, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5E, 0x0F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x05, 0x71, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xD4, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00,\n                           0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x83, 0x00, 0x00, 0x00, 0x07, 0xB2,\n                           0x00, 0x00, 0x00, 0x09, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x20, 0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x00, 0x00, 0x00,\n                           0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x15, 0x03, 0x00,\n                           0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x04, 0x01,\n                           0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3B,\n                           0x05, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x91, 0x00, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x6A, 0x0F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00,\n                           0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00,\n                           0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A,\n                           0x00, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xC4, 0x00, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xC4, 0x00, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x79, 0x0F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x88, 0x0F,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x29,\n                           0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05,\n                           0xC0, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x94, 0x0F, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0xC0, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x03, 0x29, 0x07,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00, 0x05, 0xC0,\n                           0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xA2, 0x0F, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0xC0, 0x01, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB0, 0x0F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xBE, 0x0F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x23,\n                           0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x34, 0x07, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x45, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x03, 0x45, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x00, 0x00, 0x00, 0x05, 0xBB,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x03,\n                           0x45, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00,\n                           0x05, 0xBB, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xCC, 0x0F, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xDA, 0x0F, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xE6, 0x0F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x0F, 0x01, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xF4, 0x0F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00,\n                           0x00, 0x05, 0x9F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC4, 0x00,\n                           0x00, 0x00, 0x03, 0x3C, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4,\n                           0x00, 0x00, 0x00, 0x05, 0x9F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x83, 0x00, 0x00, 0x00, 0x03, 0x3C, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x8D, 0x00, 0x00, 0x00, 0x05, 0x9F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x7E, 0x06, 0x00, 0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x3F, 0x05, 0x00, 0x00, 0x05, 0x9F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x03, 0x44, 0x05, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x14, 0x10, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x40, 0x07, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x03, 0x5B, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x05, 0xDD,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xB2, 0x00, 0x00, 0x00, 0x03,\n                           0x5B, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xB2, 0x00, 0x00, 0x00,\n                           0x05, 0xDD, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x4C, 0x07, 0x00,\n                           0x00, 0x03, 0x5B, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x4C, 0x07,\n                           0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x20,\n                           0x10, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05,\n                           0x2E, 0x10, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00,\n                           0x03, 0x5B, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3A, 0x10, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xE6, 0x00, 0x00, 0x00, 0x05, 0x46, 0x10, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x52, 0x10, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x60, 0x10, 0x00, 0x00, 0x05, 0xEB, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xFE, 0x01, 0x00, 0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xF5, 0x03, 0x00, 0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x47, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x15, 0x03, 0x00, 0x00, 0x03, 0x50, 0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x5B, 0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xBB, 0x02, 0x00, 0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xF7, 0x02, 0x00, 0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x65, 0x10, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x73, 0x10, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x81, 0x10, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x10, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x99, 0x10, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA5,\n                           0x10, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03,\n                           0x28, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00,\n                           0x05, 0x71, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD3, 0x02, 0x00,\n                           0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x71, 0x01,\n                           0x00, 0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB1,\n                           0x10, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05,\n                           0x71, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xBF, 0x10, 0x00, 0x00,\n                           0x05, 0x71, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x10, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD3, 0x10, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x66, 0x01, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x03, 0x66, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDA, 0x01, 0x00, 0x00, 0x03, 0x66, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDA, 0x01, 0x00, 0x00, 0x05, 0xA6,\n                           0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x10, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xEB, 0x10, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x19, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x9C, 0x03, 0x00, 0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x0D, 0xD8, 0x00, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF4, 0x10, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x4F, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x83, 0x01, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x02, 0x11, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0x83, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x10, 0x11, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x1E, 0x11,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x2A, 0x11, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0x83, 0x01, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x38, 0x11, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x47, 0x11, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x56, 0x11,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x64, 0x11, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x72, 0x11, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x7E, 0x11, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00,\n                           0x00, 0x03, 0xAB, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x00,\n                           0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A,\n                           0x00, 0x00, 0x00, 0x03, 0xAB, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0x66, 0x07, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xC4, 0x00, 0x00, 0x00, 0x03, 0xAB, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x8A, 0x11, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x8E, 0x11, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD5,\n                           0x01, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xDA, 0x01, 0x00, 0x00, 0x03, 0xAB, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xDA, 0x01, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x9C, 0x11, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xAA, 0x11,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB6, 0x11, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0xC9, 0x01, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC4, 0x11, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x03, 0x17, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x69, 0x07, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x0A, 0x02, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x03, 0x69, 0x07, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0x0A, 0x02, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD2, 0x11, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0x0A, 0x02, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xE0, 0x11, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xEC, 0x11, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF8, 0x11, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x04, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x10, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x1C, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x28, 0x12, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x74, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x34, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x41,\n                           0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x23, 0x05, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x4B, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x57, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x63, 0x12,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x6F, 0x12, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x7B, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x80, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8C, 0x07, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x87, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x96, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0xA5, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB2, 0x12, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC0, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xCC, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD8,\n                           0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE4, 0x12, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF0, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xFC, 0x12, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x08, 0x13,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x14, 0x13, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x20, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x5A, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x50, 0x04, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x98, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xA6, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x2F, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3E, 0x13, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x4A, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x56, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x65,\n                           0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x72, 0x13, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7E, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xB2, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x87, 0x13,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x96, 0x13, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xA5, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xB1, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBD, 0x13, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBE, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xCC, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xD8, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCC, 0x13, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD8, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x03, 0xE4, 0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF2,\n                           0x13, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xFE, 0x13, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x07, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x15, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x23, 0x14,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2F, 0x14, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x3B, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x47, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x53, 0x14, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5C, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x68, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xE4, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x66, 0x05, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x74, 0x14, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x75, 0x06, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x8E, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9A, 0x14, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA6, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xB2, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC1,\n                           0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD0, 0x14, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDC, 0x14, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x22, 0x02, 0x00, 0x00, 0x05, 0xEB, 0x14, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xF7, 0x14, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0F,\n                           0x01, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x05, 0x15, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00,\n                           0x05, 0xDD, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x15, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0xA6, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x21, 0x15, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x8C, 0x01, 0x00, 0x00,\n                           0x04, 0x59, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x66, 0x07, 0x00,\n                           0x00, 0x03, 0x5C, 0x04, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x2F, 0x15, 0x00, 0x00, 0x04, 0x59, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x03, 0x5C, 0x04, 0x00, 0x00, 0x05, 0xC8,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x34, 0x15, 0x00, 0x00, 0x04,\n                           0x59, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x39, 0x15, 0x00, 0x00,\n                           0x03, 0x5C, 0x04, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x3D, 0x15, 0x00, 0x00, 0x04, 0x59, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x03, 0x5C, 0x04, 0x00, 0x00, 0x05, 0xC8, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x5F, 0x04, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x42, 0x15, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x01, 0x00, 0x00,\n                           0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x4E, 0x15, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x72, 0x05,\n                           0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A,\n                           0x00, 0x00, 0x00, 0x03, 0xF0, 0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0x8A, 0x00, 0x00, 0x00, 0x05, 0x33, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x5C, 0x15, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x68, 0x15, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x74, 0x15, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0x9F, 0x01, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x82, 0x15, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x90, 0x15, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9E, 0x15, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xFB, 0x07, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0xAD, 0x15, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0xFB, 0x07, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBB, 0x15, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0x75, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0xCB, 0x15, 0x00, 0x00, 0x05, 0xEB, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xD0, 0x15, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xDC, 0x15, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x07, 0x08, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x3C, 0x04, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x15, 0x03, 0x00, 0x00, 0x05, 0x9F, 0x01,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE8, 0x15, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xF4, 0x15, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xD4, 0x00, 0x00, 0x00, 0x03, 0x28, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x13, 0x02, 0x00, 0x00, 0x05, 0x71, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x03, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x11,\n                           0x16, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03,\n                           0xF0, 0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00,\n                           0x05, 0x33, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00,\n                           0x00, 0x03, 0x1F, 0x16, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00,\n                           0x00, 0x00, 0x05, 0x20, 0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x14,\n                           0x01, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x14, 0x01, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xB6, 0x01, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xB6, 0x01, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x03, 0x45, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x14, 0x01, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xB6, 0x01, 0x00, 0x00, 0x03, 0x45, 0x01, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB6, 0x01, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x03, 0x5B, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x14, 0x01, 0x00, 0x00, 0x05, 0xDD, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x08, 0x00, 0x00, 0x03, 0x5B,\n                           0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x13, 0x08, 0x00, 0x00, 0x05,\n                           0xDD, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00,\n                           0x03, 0x66, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x14, 0x01, 0x00,\n                           0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB6, 0x01,\n                           0x00, 0x00, 0x03, 0x66, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB6,\n                           0x01, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x14, 0x01, 0x00, 0x00, 0x03, 0x19, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x14, 0x01, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xB6, 0x01, 0x00, 0x00, 0x03, 0x19, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xB6, 0x01, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x03, 0xAB, 0x01, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x14, 0x01, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB6, 0x01, 0x00, 0x00, 0x03, 0xAB, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2A, 0x16, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA8, 0x03, 0x00, 0x00, 0x0D, 0xD8, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x83, 0x01, 0x00, 0x00, 0x0D, 0xD8,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x49, 0x02, 0x00, 0x00, 0x0D,\n                           0xD8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0D, 0x04, 0x00, 0x00,\n                           0x0D, 0xD8, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2E, 0x16, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3C, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x47, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x55, 0x16, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x63, 0x16, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6F, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x7B, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x89, 0x16, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00,\n                           0x03, 0x3A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x00, 0x00,\n                           0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x94, 0x16,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x17, 0x08, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x8C, 0x01, 0x00, 0x00, 0x04,\n                           0x68, 0x04, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00,\n                           0x03, 0x8C, 0x01, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x23, 0x08, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x66,\n                           0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00, 0x05,\n                           0xA6, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00,\n                           0x02, 0x72, 0x05, 0x00, 0x00, 0x04, 0x68, 0x04, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x72, 0x05, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD2, 0x01, 0x00, 0x00, 0x03, 0x17, 0x02,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0xF5,\n                           0x00, 0x00, 0x9B, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA3, 0x16, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xAC, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xB5, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBE,\n                           0x16, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xCA, 0x16, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD3, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xDD, 0x16, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xEC, 0x16,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xF8, 0x16, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x5F, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x01, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x81, 0x05, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x8A, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x0A, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x13, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x1C, 0x17, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x28, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x9F, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x36,\n                           0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2F, 0x08, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3F, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x48, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x54, 0x17,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x60, 0x17, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0x6F, 0x17, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x24, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x78, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x81, 0x17,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x17, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xA8, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB7, 0x17, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC0, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xCC, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0xD8, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE4, 0x17, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xF0, 0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x72, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xF9,\n                           0x17, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x93, 0x05, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3B, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x02, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0B, 0x18,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x17, 0x18, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x23, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x2F, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3B, 0x18, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x44, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x4D, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x56, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x5F, 0x18, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6B, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x7A, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x89,\n                           0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x93, 0x18, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA0, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xAC, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xBB, 0x18,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC4, 0x18, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x2D, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0xCD, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD6, 0x18, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xEB, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0xF4, 0x18, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x00, 0x19, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x75, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x0A, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x16,\n                           0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x22, 0x19, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2E, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x3A, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x46, 0x19,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x4A, 0x08, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x52, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x5B, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x53, 0x08, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x65, 0x19, 0x00, 0x00, 0x05, 0x69, 0x19,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x75, 0x19, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x81, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x8A, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x98, 0x19, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA4, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x07, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xB0, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBF, 0x19, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCC, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xD8, 0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE7,\n                           0x19, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF3, 0x19, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x02, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x0E, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x1A, 0x1A,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5C, 0x08, 0x00, 0x00, 0x08, 0x5C,\n                           0x08, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x26, 0x1A, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x2E, 0x1A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x03, 0x36, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x3D, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0x43, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x49, 0x1A, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x50, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x03, 0x58, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x5E,\n                           0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x62, 0x08, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x65, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x3F, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD8, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xE4, 0x03, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x67, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x6A, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6F, 0x1A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x76, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x7D, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x84, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8B, 0x1A, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x93, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0F,\n                           0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x26, 0x02, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x26, 0x02, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x0D, 0x9B, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0D, 0x9F, 0x1A, 0x00,\n                           0x87, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0xD5, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xA3, 0x1A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xDA, 0x01, 0x00, 0x8F, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0xA8, 0x1A, 0x00, 0x90, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x80, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAE, 0x1A, 0x00, 0x84, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x6C, 0x08, 0x00, 0x87, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x3F, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD8, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xE4, 0x03, 0x00, 0x8D, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x9B, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xB2, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB6, 0x1A, 0x00,\n                           0xB1, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xBA, 0x1A, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x0A, 0xBF, 0x1A, 0x00, 0x83, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x0C, 0xC4, 0x1A, 0x00, 0x82, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x83,\n                           0x00, 0x00, 0x00, 0x09, 0xD8, 0x00, 0x00, 0x84, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xC9, 0x1A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00,\n                           0x00, 0x03, 0x8C, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xCD, 0x1A,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xDB, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xE9, 0x1A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF7, 0x1A, 0x00,\n                           0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x05, 0x1B, 0x00, 0x80, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x21, 0x1B, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00,\n                           0x00, 0x00, 0x03, 0x8C, 0x01, 0x00, 0x00, 0x05, 0x24, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x8B, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x97, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x71, 0x08, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xA3, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD8,\n                           0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x02, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x50, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xF2, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE, 0x01,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2F, 0x1B, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xC7, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xD3, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3B, 0x1B, 0x00,\n                           0x00, 0x09, 0x43, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x90, 0x03,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x89, 0x08, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xF8, 0x04, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xB2, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x49, 0x02,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCC, 0x03, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xC0, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x48, 0x1B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA1, 0x08, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x03, 0x5B, 0x01, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x03, 0x17, 0x02, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x8F, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x81, 0x05, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x5A, 0x05,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x24,\n                           0x03, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03,\n                           0x8C, 0x01, 0x00, 0x00, 0x05, 0x2D, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x8F, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x54, 0x1B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2F, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x63, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x81, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6F, 0x1B, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x5A, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x7E, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x24,\n                           0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x47, 0x04, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8A, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xC7, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x96, 0x1B,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9F, 0x1B, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0xAE, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB7, 0x1B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC3, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xCE, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0xD7, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2D, 0x03, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE0, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xEC, 0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xF8,\n                           0x1B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x93, 0x05, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE6, 0x00, 0x00, 0x00, 0x05, 0x24, 0x03, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0x2D, 0x03, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x2D,\n                           0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05,\n                           0x93, 0x05, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x04, 0x1C, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x10, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x1C, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x28, 0x1C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00,\n                           0x03, 0x36, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3B, 0x08, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x41, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x4A, 0x1C, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x55, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x63, 0x1C, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6F, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x7B, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x87, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x94, 0x1C, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA0, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0xAF, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBC,\n                           0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xCA, 0x1C, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD5, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xE1, 0x1C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xED, 0x1C,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xFC, 0x1C, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x06, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x12, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x1E, 0x1D, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2A, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x33, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x3F, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x48, 0x1D, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x54, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x60, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x69,\n                           0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC0, 0x01, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x55, 0x02, 0x00, 0x00, 0x05, 0xEB, 0x02, 0x00, 0x8B,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00, 0x03, 0x45, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0x45,\n                           0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x75, 0x1D, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x83, 0x1D, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8E, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xA8, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF2,\n                           0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x03,\n                           0x5B, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8A, 0x06, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9A, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xA6, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB2,\n                           0x1D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03,\n                           0xAD, 0x08, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00,\n                           0x03, 0x9C, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00,\n                           0x00, 0x03, 0x7B, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBE, 0x1D,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8B, 0x02, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xCD, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x97, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x71, 0x08, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD9, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xA3, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xE7, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF3, 0x1D, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFF, 0x1D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x0B, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE,\n                           0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x19, 0x1E, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC7, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xAF, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x90, 0x03,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x89, 0x08, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xF8, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xEC, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x49, 0x02, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x25, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x95, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xC0, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x31, 0x1E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3F, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x4B, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x57,\n                           0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x65, 0x1E, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x71, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x7D, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x89, 0x1E,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x1E, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xA1, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAD, 0x1E, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x4A, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xB8, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0xB9, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA7, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x8A, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x36,\n                           0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x00, 0x00, 0x00, 0x05,\n                           0x36, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x47, 0x04, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC4, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xCD, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x53,\n                           0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD6, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x01, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC0, 0x01,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xDF, 0x1E, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0xE8, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x0C, 0x03, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xF5, 0x1E, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xC1, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x00, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x09, 0x1F, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x14, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xCA, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x1D,\n                           0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD3, 0x08, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x26, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x2F, 0x1F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x00,\n                           0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95,\n                           0x00, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x38, 0x1F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00,\n                           0x05, 0xB8, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x47, 0x1F, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x83, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xE6, 0x00, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x55, 0x02, 0x00, 0x00, 0x05, 0xEB, 0x02, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x50, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x59, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x40,\n                           0x07, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05,\n                           0x47, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x00, 0x00, 0x00,\n                           0x05, 0x36, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x00, 0x00,\n                           0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x62, 0x1F,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6E, 0x1F, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xB0, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x7A, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x86, 0x1F, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x92, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x9E, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xA7, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB3, 0x1F, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBC, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xC8, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD1,\n                           0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xDD, 0x1F, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE6, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xF2, 0x1F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xFB, 0x1F,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00, 0x05, 0x0B,\n                           0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x16, 0x20, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x22, 0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x50, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x72, 0x04,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x31, 0x20, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xDC, 0x08, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x14, 0x01, 0x00, 0x00, 0x03, 0x3D, 0x20, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x14, 0x01, 0x00, 0x00, 0x05, 0xDC, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x48, 0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x57,\n                           0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x63, 0x20, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x71, 0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x7C, 0x20, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xE5, 0x08,\n                           0x00, 0x00, 0x05, 0xB0, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xEA,\n                           0x08, 0x00, 0x00, 0x03, 0x8A, 0x20, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xEA, 0x08, 0x00, 0x00, 0x05, 0xB0, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x95, 0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA4, 0x20, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x20, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0xE5, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0xBB, 0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xC0, 0x20, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xC5, 0x20, 0x00, 0x80, 0x00, 0x03, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0xB9, 0x05, 0x00, 0x00, 0x06, 0xCA, 0x20, 0x00, 0x00, 0x08, 0xEE,\n                           0x08, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCD, 0x20, 0x00, 0x00, 0x06,\n                           0xD2, 0x20, 0x00, 0x00, 0x09, 0xD6, 0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xDB, 0x20, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x00, 0x00,\n                           0x00, 0x05, 0xEB, 0x20, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xF6, 0x20,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x03, 0x21, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x0D, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x19, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x25, 0x21, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x33, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x3E, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x4A, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x53, 0x21, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x62, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x6E, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7C,\n                           0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x87, 0x21, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x96, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xA2, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB0, 0x21,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBB, 0x21, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xC7, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xD0, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDC, 0x21, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE8, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xF4, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xF2, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFD, 0x21, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x09, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x12,\n                           0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x21, 0x22, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2D, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x39, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF5, 0x06,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2F, 0x05, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x42, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x50, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCC, 0x03, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x5B, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x67, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x73, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7F, 0x22, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x8D, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x98, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA6,\n                           0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB1, 0x22, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xBF, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xCA, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD6, 0x22,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x22, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xEB, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xF4, 0x22, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x00, 0x23, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x09, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x18, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xF2, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x24, 0x23, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x00, 0x00, 0x00, 0x05, 0xA7, 0x05, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x32, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x41, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x4D, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x5B, 0x23, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x66, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x75, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF2,\n                           0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x81, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x8F, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9A, 0x23,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA8, 0x23, 0x00, 0x80, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4, 0x00, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0x3A, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0x9D,\n                           0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE9, 0x06, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x33, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x03, 0x45, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xC4, 0x00, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x80, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x5F, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00,\n                           0x03, 0xB3, 0x23, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00,\n                           0x00, 0x05, 0x5F, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00,\n                           0x00, 0x00, 0x03, 0xBE, 0x23, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95,\n                           0x00, 0x00, 0x00, 0x05, 0xA7, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x95, 0x00, 0x00, 0x00, 0x03, 0xC9, 0x23, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0x8A, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xD4, 0x23, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x75, 0x05,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x9C,\n                           0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05,\n                           0x36, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00,\n                           0x03, 0x9C, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00,\n                           0x00, 0x05, 0x36, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00,\n                           0x00, 0x00, 0x03, 0x66, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95,\n                           0x00, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x50, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x72, 0x04, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x23, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0x72, 0x04,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0xEB,\n                           0x23, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05,\n                           0xD3, 0x08, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00,\n                           0x03, 0x7B, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00,\n                           0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00,\n                           0x00, 0x00, 0x03, 0x7B, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95,\n                           0x00, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xDA, 0x01, 0x00, 0x00, 0x03, 0x7B, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xDA, 0x01, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0xF6, 0x23, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0xC1, 0x08, 0x00, 0x81, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0x01, 0x24, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0xCA, 0x08, 0x00, 0x85,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0C, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xDF, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x18, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x24, 0x24, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x30, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x3C, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x45,\n                           0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x53, 0x24, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5E, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x6A, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x73, 0x24,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7F, 0x24, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x88, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x94, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9D, 0x24, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA9, 0x24, 0x00, 0x9F, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0xB2, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xBB, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC7, 0x24, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD3, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xDF, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xEB, 0x24, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF7, 0x24, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x04, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x11, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x1D,\n                           0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x29, 0x25, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x35, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x41, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x4E, 0x25,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5A, 0x25, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x66, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x72, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7F, 0x25, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8B, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x97, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xA3, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x25, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBB, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xC7, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD3,\n                           0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x25, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xEB, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xF7, 0x25, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x04, 0x26,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x10, 0x26, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x1C, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x28, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x34, 0x26, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x40, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x4C, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x58, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x64, 0x26, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x70, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x7C, 0x26, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x88, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8E, 0x26, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x62, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x94, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x99,\n                           0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x9E, 0x26, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xA3, 0x26, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xA8, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB1,\n                           0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xBD, 0x26, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC9, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xD5, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE1, 0x26,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xED, 0x26, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xFB, 0x26, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x07, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x13, 0x27, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x1F, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x2E, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x3A, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x49, 0x27, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x55, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x64, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x70,\n                           0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7C, 0x27, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x88, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x94, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA0, 0x27,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAC, 0x27, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xB8, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0xC4, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xCD, 0x27, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD9, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xE5, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0xF1, 0x27, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xFA, 0x27, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x03, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x12, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x1B,\n                           0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x27, 0x28, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x33, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x3C, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x4B, 0x28,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x57, 0x28, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x60, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x6F, 0x28, 0x00, 0x80, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x83, 0x00,\n                           0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7B,\n                           0x28, 0x00, 0x85, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x80, 0x28, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0xBD, 0x05, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x86, 0x28, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x0C, 0x92, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x97, 0x28, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x9C, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xA1, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C,\n                           0xA6, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xAB, 0x28, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB0, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xB5, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBA,\n                           0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBF, 0x28, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC5, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xCB, 0x28, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x0B,\n                           0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x10, 0x09, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xD1, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x0C, 0xD6, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xDB, 0x28,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xE1, 0x28, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xE6, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x0C, 0xEC, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x0C, 0xF2, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xF7, 0x28, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD5, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x01, 0x01, 0x00, 0x00, 0x0E, 0x01, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xFC, 0x28, 0x00, 0x00, 0x0E, 0xFF, 0x28,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x02, 0x29, 0x00, 0x00, 0x0E, 0x05,\n                           0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x08, 0x29, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x01, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x0C, 0xBD, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xBD, 0x05,\n                           0x00, 0x00, 0x0E, 0x01, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0D, 0xB2,\n                           0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0D, 0x0D, 0x29, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xC0, 0x05, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x0C, 0x12, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x83,\n                           0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0D, 0x26, 0x02, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x17, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x8A, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x15, 0x09,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x55, 0x02, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x3F, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x83, 0x00, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x83, 0x00, 0x00, 0x8A, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x1B,\n                           0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x25, 0x29, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x2F, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0x39, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x43, 0x29,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x4D, 0x29, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x57, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x61, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x6B, 0x29, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x75, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x7C, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x89, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x93, 0x29, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x9F, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0xA9, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xB3,\n                           0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xC0, 0x29, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xCA, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0xD4, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xDE, 0x29,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xEB, 0x29, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0xF5, 0x29, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x02, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x0C, 0x2A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x19, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x23, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x2D, 0x2A, 0x00, 0x84, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x37, 0x2A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x41, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x4B, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x91, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDA, 0x01, 0x00, 0x96,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x52, 0x2A, 0x00, 0x8D, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x58, 0x2A, 0x00, 0x00, 0x08, 0x83, 0x00, 0x00, 0x82, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5D, 0x2A, 0x00, 0x00, 0x09, 0x7D, 0x00, 0x00,\n                           0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xC4, 0x05, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x1F, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x2A, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x35, 0x09, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xCB, 0x05, 0x00, 0x00, 0x0A, 0xD3, 0x05,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x65, 0x2A, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0xCB, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0xEA, 0x00, 0x00, 0x00, 0x0B, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x63, 0x02, 0x00, 0x00, 0x04, 0x43, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x42, 0x09, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D,\n                           0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x49, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x66, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x86, 0x04, 0x00,\n                           0x00, 0x04, 0x66, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x18, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x00, 0x00, 0x00, 0x04, 0x18,\n                           0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x1F, 0x01, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x00, 0x00, 0x00, 0x05, 0x1F, 0x01, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x71, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0x71, 0x02,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x2B, 0x02, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x2B, 0x02, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x54, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x5D, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x4A, 0x03,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x56, 0x03, 0x00, 0x00, 0x04, 0x4A,\n                           0x03, 0x00, 0x84, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0xB5, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x98, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x00, 0x00, 0x04, 0x89, 0x04,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x94, 0x04, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0xD9, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x66, 0x09, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x00, 0x00,\n                           0x00, 0x05, 0xDE, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x72, 0x09,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xE6, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0xE6, 0x01, 0x00, 0x00, 0x0E, 0xE5, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x9D, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7A, 0x09,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0A, 0x9D, 0x04, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xA3, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x81, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xA3, 0x04, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x8E, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x72, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x93, 0x09, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x93, 0x09, 0x00, 0x89, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x06, 0x77, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x99, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA4, 0x09, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x7C, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x87,\n                           0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x92, 0x2A, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBA, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xC5, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD0, 0x09,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9D, 0x2A, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x08, 0xA9, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0xB1, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xDB, 0x09, 0x00,\n                           0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x59, 0x03, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xE8, 0x05, 0x00, 0x00, 0x04, 0xE5, 0x09, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xEC, 0x09, 0x00, 0x00, 0x04, 0xE5, 0x09, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xED, 0x05, 0x00, 0x00, 0x0A, 0xEC, 0x09, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xB8, 0x2A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xBE, 0x2A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xF1, 0x09, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xF7, 0x09, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF1, 0x09, 0x00,\n                           0x00, 0x05, 0xE6, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01,\n                           0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D,\n                           0x00, 0x00, 0x00, 0x03, 0x7D, 0x00, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C,\n                           0x7D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xC9, 0x2A, 0x00, 0x00,\n                           0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x03, 0x7D, 0x00, 0x00,\n                           0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xEA, 0x00,\n                           0x00, 0x00, 0x0B, 0x87, 0x00, 0x00, 0x00, 0x0D, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0xEA,\n                           0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x0B,\n                           0x87, 0x00, 0x00, 0x00, 0x0D, 0x87, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xD3, 0x2A, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00,\n                           0x00, 0x02, 0x7D, 0x00, 0x00, 0x00, 0x04, 0x66, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x05, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x10,\n                           0x0A, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x02,\n                           0x87, 0x00, 0x00, 0x00, 0x04, 0x66, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0xF5, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x1B, 0x0A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0xE2, 0x2A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x18, 0x01, 0x00, 0x00, 0x0B, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x00, 0x06, 0x00, 0x00, 0x0B, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00, 0x0B, 0x87, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x04, 0x18,\n                           0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x02,\n                           0x7D, 0x00, 0x00, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x87, 0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x05, 0x1F, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x79, 0x02, 0x00, 0x00, 0x05, 0x1F, 0x01,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xEC, 0x2A, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xF5, 0x2A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x1F, 0x01, 0x00, 0x00, 0x0C, 0x79, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xFD, 0x2A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x87, 0x00,\n                           0x00, 0x00, 0x05, 0x1F, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7D,\n                           0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x05, 0x1F, 0x01, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x05,\n                           0x1F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xB8, 0x00, 0x00, 0x00,\n                           0x05, 0x05, 0x2B, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x26, 0x0A, 0x00,\n                           0x00, 0x0C, 0x0B, 0x06, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xB8, 0x00,\n                           0x00, 0x00, 0x03, 0xD1, 0x00, 0x00, 0x00, 0x05, 0x26, 0x0A, 0x00, 0x00, 0x0C, 0x0B, 0x06,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x0D, 0x2B, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x00, 0x00, 0x04,\n                           0x2B, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00,\n                           0x02, 0x16, 0x2B, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x86, 0x04, 0x00,\n                           0x00, 0x02, 0x2E, 0x0A, 0x00, 0x00, 0x04, 0x4A, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x98, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x98,\n                           0x01, 0x00, 0x00, 0x0A, 0x0B, 0x06, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xB8, 0x00, 0x00, 0x00, 0x04, 0x98, 0x01, 0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x00, 0x00,\n                           0x04, 0x98, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x98, 0x01, 0x00,\n                           0x00, 0x0A, 0xD1, 0x00, 0x00, 0x00, 0x0C, 0xB8, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xD1, 0x00, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x00, 0x00, 0x04, 0x98, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x89,\n                           0x04, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x02,\n                           0xD1, 0x00, 0x00, 0x00, 0x04, 0x89, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x31, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x1F, 0x2B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x28, 0x2B, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x02, 0x94, 0x04, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00, 0x02, 0x3B, 0x0A, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x94, 0x04, 0x00, 0x00, 0x0A, 0x87, 0x00, 0x00, 0x00,\n                           0x0C, 0x7D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x5F, 0x03, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x32, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x44, 0x0A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x5F, 0x03, 0x00, 0x00, 0x0A, 0x87, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x5F, 0x03, 0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x3D, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x48, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x55,\n                           0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x62, 0x2B, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD9, 0x05, 0x00, 0x00, 0x0C, 0x87, 0x00, 0x00, 0x00,\n                           0x0E, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00,\n                           0x00, 0x05, 0xDE, 0x01, 0x00, 0x00, 0x0D, 0xB8, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xDE, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30,\n                           0x01, 0x00, 0x00, 0x05, 0xDE, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x7D, 0x00, 0x00, 0x00, 0x05, 0x6F, 0x2B, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x05, 0xDE, 0x01, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x7A, 0x2B, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xAF, 0x00, 0x00, 0x00, 0x04, 0xF5, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x4F, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07,\n                           0xA7, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x2B, 0x00, 0x00,\n                           0x07, 0xA7, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00,\n                           0x00, 0x07, 0xA7, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x89, 0x2B,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x5A, 0x0A, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x79, 0x02, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x63, 0x0A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x0E, 0x06, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x14, 0x06, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x05,\n                           0x27, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE6, 0x01, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x92, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x03, 0x9C, 0x2B, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D,\n                           0x00, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x18, 0x06, 0x00, 0x00, 0x0D, 0x7D, 0x00, 0x00, 0x00, 0x0F, 0x7D, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x18, 0x06, 0x00, 0x00, 0x0D, 0x87, 0x00, 0x00, 0x00,\n                           0x0F, 0x7D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x71, 0x0A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA7, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x07, 0xD2, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x43, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB2, 0x2B, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBB, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xC4, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xCA,\n                           0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD1, 0x2B, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x78, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0xD9, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE9,\n                           0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF7, 0x2B, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xFC, 0x2B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7E, 0x0A,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x78, 0x0A, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x06, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x85, 0x0A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x85, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x0E, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x14, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0B, 0x8B, 0x0A, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8B, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x21, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0B, 0x7E,\n                           0x0A, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x24, 0x2C, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xA4, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF,\n                           0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2A, 0x2C, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x35, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x40, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBA, 0x09,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC5, 0x09, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xD0, 0x09, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0x4B, 0x2C, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x53, 0x2C, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x56, 0x03, 0x00, 0x00, 0x04, 0x5C, 0x2C,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xC4, 0x05, 0x00, 0x00, 0x0A, 0x68,\n                           0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x6E, 0x2C, 0x00, 0xC9, 0xD3,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7A, 0x2C, 0x00, 0x82, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x86, 0x2C, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x8F, 0x2C, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x9B,\n                           0x2C, 0x00, 0x87, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA4, 0x2C, 0x00, 0xCD,\n                           0x18, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8B, 0x02, 0x00, 0x00, 0x0D, 0xD5,\n                           0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x0D,\n                           0xD5, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00,\n                           0x03, 0xB0, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xBB, 0x2C, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x97, 0x02, 0x00, 0x00, 0x0D, 0x83, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x10, 0x05, 0x00, 0x00, 0x0D, 0x83,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x97, 0x02, 0x00, 0x00, 0x0D,\n                           0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x10, 0x05, 0x00, 0x00,\n                           0x0D, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00,\n                           0x00, 0x03, 0xC8, 0x2C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00,\n                           0x00, 0x00, 0x05, 0x2F, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8D,\n                           0x00, 0x00, 0x00, 0x03, 0xD6, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xE1, 0x2C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x84, 0x03, 0x00, 0x00,\n                           0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x02, 0x00,\n                           0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x84, 0x03,\n                           0x00, 0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF,\n                           0x02, 0x00, 0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xEF, 0x2C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE, 0x2C, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0D, 0x2D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x1C, 0x2D, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD4,\n                           0x00, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0x27, 0x06, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05,\n                           0xBB, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00,\n                           0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0x27, 0x06, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2B, 0x2D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x3A, 0x2D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xA3, 0x02, 0x00, 0x00, 0x0D, 0x99, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0xBB, 0x00, 0x00, 0x00, 0x0D, 0x99, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x03, 0x46, 0x2D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xC4, 0x00, 0x00, 0x00, 0x05, 0x17, 0x08, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x03, 0x54, 0x2D, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x5F, 0x2D, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x3C, 0x04, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0x9F, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x44, 0x05,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x6A, 0x2D, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x02, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE9, 0x03, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0x44, 0x05, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0x78, 0x2D,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x2D, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x92, 0x2D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xAF, 0x02, 0x00, 0x00, 0x0D, 0xC4, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xE9, 0x03, 0x00, 0x00, 0x0D, 0xC4, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xF2, 0x01, 0x00, 0x00, 0x0D, 0x99, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x0D, 0x99,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xA1, 0x2D, 0x00, 0x00, 0x04,\n                           0xA6, 0x2D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB0, 0x2D, 0x00, 0x00,\n                           0x05, 0xDD, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00,\n                           0x00, 0x03, 0xAD, 0x08, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xB6, 0x2D,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE, 0x01, 0x00, 0x00, 0x0D, 0x83,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF5, 0x03, 0x00, 0x00, 0x0D,\n                           0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE, 0x01, 0x00, 0x00,\n                           0x0D, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF5, 0x03, 0x00,\n                           0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBB, 0x02,\n                           0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF7,\n                           0x02, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x8A, 0x00, 0x00, 0x00, 0x03, 0x50, 0x07, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x5B, 0x07, 0x00, 0x00,\n                           0x0D, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBB, 0x02, 0x00,\n                           0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF7, 0x02,\n                           0x00, 0x00, 0x0D, 0xB2, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC3,\n                           0x2D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD2, 0x2D, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x92, 0x0A, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05, 0x03, 0x03, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x92, 0x0A,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00, 0x05, 0x03,\n                           0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC7, 0x02, 0x00, 0x00, 0x0D,\n                           0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x03, 0x03, 0x00, 0x00,\n                           0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00,\n                           0x00, 0x03, 0x28, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x00,\n                           0x00, 0x00, 0x05, 0x71, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD3,\n                           0x02, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x71, 0x01, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xD3, 0x02, 0x00, 0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x71, 0x01, 0x00, 0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xE1, 0x2D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xF0,\n                           0x2D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xFC, 0x2D, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x9D, 0x0A, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x02, 0x23, 0x08, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x02, 0x99, 0x00,\n                           0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0A,\n                           0x2E, 0x00, 0x00, 0x04, 0x68, 0x04, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xD4, 0x00, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0F, 0x2E, 0x00, 0x00, 0x04, 0x68, 0x04, 0x00, 0x00,\n                           0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00,\n                           0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00,\n                           0x00, 0x00, 0x03, 0xA3, 0x0A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91,\n                           0x00, 0x00, 0x00, 0x05, 0x01, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x83, 0x00, 0x00, 0x00, 0x03, 0xA3, 0x0A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0x01, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x03, 0x19, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x9C, 0x03, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x03, 0x19, 0x03, 0x00, 0x00,\n                           0x0D, 0x83, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x00, 0x00,\n                           0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x9C, 0x03, 0x00, 0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x7A, 0x01, 0x00, 0x00, 0x0D, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x4F, 0x05, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00, 0x05, 0x83, 0x01, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA8, 0x03, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x83, 0x01, 0x00, 0x00, 0x0D, 0x8D, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x14, 0x2E, 0x00, 0x00, 0x04, 0x19,\n                           0x2E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x23, 0x2E, 0x00, 0x00, 0x05,\n                           0x83, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x29, 0x2E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x37, 0x2E, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x4F, 0x05, 0x00, 0x00, 0x0D, 0x8D, 0x00,\n                           0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00, 0x05, 0x83,\n                           0x01, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x83, 0x00, 0x00, 0x00, 0x03, 0x45, 0x2E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x50, 0x2E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x49, 0x02, 0x00,\n                           0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0D, 0x04,\n                           0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x49,\n                           0x02, 0x00, 0x00, 0x0D, 0xB2, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x0D, 0x04, 0x00, 0x00, 0x0D, 0xB2, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x5D, 0x2E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6C, 0x2E, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB4, 0x03, 0x00, 0x00, 0x0D, 0x95, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x0D, 0x95,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB4, 0x03, 0x00, 0x00, 0x0D,\n                           0x99, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00,\n                           0x0D, 0x99, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7B, 0x2E, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x8A, 0x2E, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x96, 0x2E, 0x00, 0x00, 0x05, 0x9C, 0x2E, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x9D, 0x0A, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x02, 0x8A, 0x00, 0x00, 0x00,\n                           0x04, 0x59, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x3B, 0x05, 0x00,\n                           0x00, 0x03, 0xEF, 0x01, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x03, 0xA5, 0x2E, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x05, 0x19, 0x04, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x04, 0x05, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x19, 0x04, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0x00, 0x03, 0xAB, 0x04, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x00, 0x00, 0x00, 0x05, 0xC9, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x03, 0xAB,\n                           0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x91, 0x00, 0x00, 0x00, 0x05,\n                           0xC9, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00,\n                           0x03, 0xAB, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00,\n                           0x00, 0x05, 0xC9, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8D, 0x00,\n                           0x00, 0x00, 0x03, 0xAB, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D,\n                           0x00, 0x00, 0x00, 0x05, 0xC9, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x96, 0x06, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0xC9, 0x01, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x03, 0xAE, 0x0A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00, 0x05, 0x0C, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03, 0xAE, 0x0A, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00, 0x00, 0x00, 0x05, 0x0C, 0x03, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x03, 0x17, 0x02, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x00, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB0, 0x2E, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0x0A, 0x02, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xD8, 0x03, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x0A, 0x02, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD8, 0x03, 0x00, 0x00, 0x0D, 0x8A, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x0A, 0x02, 0x00, 0x00, 0x0D, 0x8A, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE9, 0x03, 0x00, 0x00, 0x0D, 0x8A,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x03,\n                           0xBE, 0x2E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD5, 0x01, 0x00, 0x00,\n                           0x05, 0xC9, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD5, 0x01, 0x00,\n                           0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x67, 0x08,\n                           0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x8D,\n                           0x00, 0x00, 0x00, 0x03, 0xC9, 0x2E, 0x00, 0x83, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x8B, 0x02, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xD4, 0x2E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x6A,\n                           0x03, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xE2, 0x2E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF0, 0x2E, 0x00, 0x00,\n                           0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF6, 0x2E, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x04, 0x2F, 0x00, 0x00, 0x05, 0x9D, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0A, 0x2F, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xB6, 0x04, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x18, 0x2F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x26, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDB, 0x06,\n                           0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x04,\n                           0x01, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x34, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x42, 0x2F, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x48, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x56, 0x2F,\n                           0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x5C,\n                           0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x6A, 0x2F, 0x00, 0x00, 0x05,\n                           0x9D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x70, 0x2F, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7E, 0x2F, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x03, 0x3A, 0x01,\n                           0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC4,\n                           0x00, 0x00, 0x00, 0x05, 0x9D, 0x00, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xA3, 0x02, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x84, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x6A, 0x03, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x03, 0x45, 0x01, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x92, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xB9, 0x0A, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xA0, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBF,\n                           0x0A, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xB6, 0x04, 0x00, 0x00, 0x05, 0x27, 0x06, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xB6, 0x04, 0x00, 0x00, 0x05, 0xBB, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xAE, 0x2F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBC, 0x2F,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x04, 0x07, 0x00, 0x00, 0x0D, 0x83,\n                           0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05,\n                           0xBB, 0x00, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xCA, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x6A, 0x03, 0x00,\n                           0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF2, 0x01,\n                           0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83,\n                           0x00, 0x00, 0x00, 0x05, 0xDD, 0x00, 0x00, 0x00, 0x0D, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x90, 0x03, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x6A, 0x03, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xE6, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xB9, 0x0A, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xF4, 0x2F, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBF, 0x0A, 0x00,\n                           0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x02, 0x30,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB6, 0x04, 0x00, 0x00, 0x05, 0xA6,\n                           0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x10, 0x30, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x1E, 0x30, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x12, 0x07, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05, 0xA6, 0x00, 0x00, 0x00, 0x0D, 0x8D, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x2C, 0x30, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x3A, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x46, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x54, 0x30, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x6E, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x7B, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x89, 0x30, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x98, 0x07, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA6, 0x07, 0x00, 0x00, 0x0D, 0x8D, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB4, 0x03, 0x00, 0x00, 0x0D, 0x8D,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00, 0x00, 0x0D,\n                           0x8D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x96, 0x30, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x6C, 0x08, 0x00, 0x00, 0x05, 0xC8, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xA4, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xB2, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xBE, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCC, 0x30, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0xE6, 0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF3,\n                           0x30, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x01, 0x31, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBE, 0x07, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCC, 0x07, 0x00, 0x00, 0x0D, 0x8D, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00, 0x03, 0x17, 0x02,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x00, 0x00, 0x00, 0x05, 0xF5,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCC, 0x03, 0x00, 0x00, 0x0D,\n                           0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x0E, 0x31, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x31, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x6A, 0x03, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x28, 0x31, 0x00, 0x00, 0x03, 0x17, 0x02, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x00, 0x00, 0x00, 0x05, 0xF5, 0x00, 0x00, 0x85, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD8, 0x00, 0x00, 0x00, 0x05, 0x8F, 0x01, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xE4, 0x03, 0x00, 0x00, 0x05, 0x8F, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x2C, 0x31, 0x00, 0x00, 0x05, 0x8F,\n                           0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x31, 0x31, 0x00, 0x00, 0x05,\n                           0x8F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x36, 0x31, 0x00, 0x00,\n                           0x05, 0x8F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x3B, 0x31, 0x00,\n                           0x00, 0x05, 0x8F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x40, 0x31,\n                           0x00, 0x00, 0x05, 0x8F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x46,\n                           0x31, 0x00, 0x00, 0x05, 0x8F, 0x01, 0x00, 0xC0, 0xF7, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x4C, 0x31, 0x00, 0x00, 0x08, 0x50, 0x01, 0x00,\n                           0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00,\n                           0x00, 0x00, 0x02, 0x53, 0x31, 0x00, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0x0E, 0x80, 0x00,\n                           0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x5A,\n                           0x31, 0x00, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x04, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x61, 0x31, 0x00, 0x00, 0x08,\n                           0x50, 0x01, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x68, 0x31, 0x00, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00,\n                           0x0E, 0x80, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,\n                           0x00, 0x02, 0x6F, 0x31, 0x00, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00,\n                           0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x76, 0x31,\n                           0x00, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x7D, 0x31, 0x00, 0x00, 0x08, 0x50,\n                           0x01, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x80, 0x00, 0x00, 0x00, 0x02, 0x84, 0x31, 0x00, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0x0E,\n                           0x80, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,\n                           0x02, 0x8B, 0x31, 0x00, 0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00,\n                           0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x92, 0x31, 0x00,\n                           0x00, 0x08, 0x50, 0x01, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x30, 0x06, 0x00, 0x00, 0x08, 0x50, 0x01,\n                           0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80,\n                           0x00, 0x00, 0x00, 0x02, 0x30, 0x06, 0x00, 0x00, 0x08, 0x99, 0x31, 0x00, 0x00, 0x0E, 0x80,\n                           0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02,\n                           0x30, 0x06, 0x00, 0x00, 0x08, 0xA0, 0x31, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0xA7, 0x31, 0x00, 0x00,\n                           0x0E, 0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,\n                           0x00, 0x02, 0xB4, 0x31, 0x00, 0x00, 0x0E, 0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x07, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xC1,\n                           0x31, 0x00, 0x00, 0x07, 0xD2, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07,\n                           0xB2, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xB2, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x66,\n                           0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x80, 0x00, 0x00, 0x00, 0x0E,\n                           0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xC8, 0x31, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xE6, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x0A, 0xE6, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xCE,\n                           0x31, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD4, 0x31, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xC5, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x0A, 0xC5, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xDA, 0x31,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE0, 0x31, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xCB, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x06, 0x21, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xEC, 0x31, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x0A, 0xE6, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0A,\n                           0x37, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x83, 0x00, 0x00, 0x87,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xF5, 0x31, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x00, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x0B, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x10, 0x32, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x15, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x1A, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x1F,\n                           0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x24, 0x32, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x0B, 0xA2, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0x29, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x32, 0x32,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xD7, 0x0A, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x3B, 0x32, 0x00, 0x00, 0x0A, 0xE6, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x44, 0x32, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x0C, 0x4D, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x51,\n                           0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0A, 0x55, 0x32, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x5C, 0x32, 0x00, 0x00, 0x08, 0x61, 0x32, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x66, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x6A, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x76,\n                           0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x82, 0x32, 0x00, 0x80, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8E, 0x32, 0x00, 0x00, 0x0A, 0x97, 0x32, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9B, 0x32, 0x00, 0x00, 0x0A, 0x3B, 0x05,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xA4, 0x32, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xAC, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0xB8, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xC1, 0x32, 0x00,\n                           0xA1, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xE0, 0x0A, 0x00, 0x82, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xE8, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0xF0, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xF8, 0x0A,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x08, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x10, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x18, 0x0B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xEF, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xEF, 0x01, 0x00, 0x00, 0x04, 0xEF, 0x01, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x1F, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x27, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2F, 0x0B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xE0, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x07, 0xD3, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07,\n                           0xB7, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xBF, 0x06, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xE8, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x07, 0xF0, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xF8,\n                           0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x00, 0x0B, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x08, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x07, 0x10, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x18, 0x0B,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x09, 0xEF, 0x01, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x08, 0xEF, 0x01, 0x00, 0x00, 0x0A, 0xEF, 0x01, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x1F, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x07, 0x27, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0x2F, 0x0B,\n                           0x00, 0x8F, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCA, 0x32, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD6, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xE6, 0x32, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF2, 0x32,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE, 0x32, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x0A, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x15, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x21, 0x33, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2D, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x39, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x45, 0x33, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x34, 0x07, 0x00, 0x00,\n                           0x0D, 0x8A, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x4F, 0x33, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5B, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x67, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x73, 0x33, 0x00, 0xC0, 0x4F, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x80, 0x33,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8E, 0x33, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x9C, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xA8, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB4, 0x33, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xC0, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0xCE, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x8C, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDC, 0x33, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE8, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xF4, 0x33, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x00,\n                           0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0C, 0x34, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x1B, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x27, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x33, 0x34,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3F, 0x34, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x4B, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x57, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x63, 0x34, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6F, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x7B, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x87, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x93, 0x34, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x9F, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xAC, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB8,\n                           0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC5, 0x34, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD1, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xDD, 0x34, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE9, 0x34,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF6, 0x34, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x05, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x07, 0x0B, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x12, 0x35, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x18, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x27, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x33, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA1, 0x08, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD8, 0x07, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x42, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x4E,\n                           0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE, 0x01, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x57, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x65, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x71, 0x35,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x7D, 0x35, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x86, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x8F, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9B, 0x35, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA7, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xB3, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0xBF, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC8, 0x35, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xE0, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xEC,\n                           0x35, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF8, 0x35, 0x00, 0x00, 0x05,\n                           0xFC, 0x35, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x05, 0x36, 0x00, 0x97,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x0E, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x1D, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x2C, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x3B, 0x36, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x4A, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x59, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x68,\n                           0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x77, 0x36, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x86, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x95, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xA4, 0x36,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xB3, 0x36, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0xC2, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xF2, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCE, 0x36, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDA, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xE6, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x04, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF2, 0x36, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE, 0x36, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x0A, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x16,\n                           0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC0, 0x03, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x22, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x2E, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBB, 0x02,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xEC, 0x04, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x84, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xC7, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00,\n                           0x00, 0x05, 0x3B, 0x06, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x95, 0x00,\n                           0x00, 0x00, 0x05, 0x3A, 0x37, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x37,\n                           0x06, 0x00, 0x00, 0x05, 0x43, 0x37, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x3F, 0x03, 0x00, 0x00, 0x05, 0x4C, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x19, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x22, 0x02, 0x00,\n                           0x00, 0x05, 0x55, 0x37, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x36, 0x0B,\n                           0x00, 0x00, 0x05, 0x5E, 0x37, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x67,\n                           0x37, 0x00, 0x00, 0x05, 0x6B, 0x37, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x3F, 0x03, 0x00, 0x00, 0x05, 0x74, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x0C, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x22, 0x02, 0x00,\n                           0x00, 0x05, 0x7D, 0x37, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x36, 0x0B,\n                           0x00, 0x00, 0x05, 0x86, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF7,\n                           0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC0, 0x01, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x03, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8F, 0x37,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9B, 0x37, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xA7, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x74, 0x07, 0x00, 0x8B, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB3, 0x37,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBA, 0x37, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xC6, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xCD, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD9, 0x37, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE0, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x3A, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0xEB, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xF4, 0x37, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xFD, 0x37, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x06, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x0D,\n                           0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x14, 0x38, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x19, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x1E, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x25, 0x38,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x31, 0x38, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x38, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x44, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x4B, 0x38, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x52, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x59, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x65, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6C, 0x38, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x78, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x84, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x8C,\n                           0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x94, 0x38, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x9C, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xA4, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xAB, 0x38,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB2, 0x38, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0xBE, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0xC9, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xD4, 0x38, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xDF, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x07, 0xEA, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06,\n                           0xF2, 0x38, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xFA, 0x38, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x04, 0x39, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xB5, 0x00, 0x00, 0x00, 0x04, 0x3A, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x0E, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0x1A, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x25, 0x39, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x43, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x07, 0x48, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x30,\n                           0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3C, 0x39, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x4D, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x07, 0x52, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x48, 0x39,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x54, 0x39, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x60, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x6C, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x78, 0x39, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x57, 0x0B, 0x00, 0x00, 0x08, 0x57, 0x0B,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x84, 0x39, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x5E, 0x0B, 0x00, 0x00, 0x08, 0x5E, 0x0B, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x90, 0x39, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0x43, 0x0B, 0x00, 0x00, 0x08, 0x52, 0x0B, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x4D, 0x0B, 0x00, 0x00, 0x08, 0x48, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x9C, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0xA3, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xAA, 0x39, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB1, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xB8, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC4,\n                           0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCB, 0x39, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD7, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xDE, 0x39, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xEA, 0x39,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xF5, 0x39, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0x00, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x0B, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x16, 0x3A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x1F, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x28, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x2F, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x36, 0x3A, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x42, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x4E, 0x3A, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x55,\n                           0x3A, 0x00, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0x09, 0x01, 0x01, 0x00, 0x00, 0x0B, 0x01,\n                           0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x5B, 0x3A, 0x00, 0x00, 0x04,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x00, 0x04, 0x01, 0x01, 0x00, 0x00,\n                           0x06, 0x01, 0x01, 0x00, 0x00, 0x08, 0x62, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x68, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x6F, 0x3A,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x76, 0x3A, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x7F, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x8B, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x94, 0x3A, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA0, 0x3A, 0x00, 0x00, 0x0A, 0xA9, 0x3A,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAE, 0x3A, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xBA, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xC6, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD2, 0x3A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xDF, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0xEC, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xF5, 0x3A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x00, 0x3B, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0B, 0x3B, 0x00, 0x8B, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x18, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x24, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2F, 0x3B, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3B, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0x47, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x55,\n                           0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x08, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x61, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x6D, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x78, 0x3B,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x85, 0x3B, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0x8E, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x99, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xA6, 0x3B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xAF, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0xB8, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xC6, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD4, 0x3B, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xB2, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0xB2, 0x00, 0x00, 0x00, 0x06, 0x7D, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x83, 0x00, 0x00, 0x00, 0x06, 0x7D, 0x03, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0xE2, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0xF0, 0x3B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xFE, 0x3B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x65, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x21, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x05, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x11, 0x3C, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x1D, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x29, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2F,\n                           0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x35, 0x3C, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3D, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x46, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x50, 0x3C,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE4, 0x07, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x59, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x66, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x65, 0x3C, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x44, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0xBC, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x71, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x59, 0x02, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7B, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x8B, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x9B,\n                           0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xAB, 0x3C, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBB, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xCB, 0x3C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDB, 0x3C,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xEB, 0x3C, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xFB, 0x3C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x83, 0x00, 0x00, 0x00, 0x0A, 0xE6, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xE6, 0x00, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x83, 0x00, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xE6, 0x00, 0x00, 0x00, 0x0A, 0xE6, 0x00, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x83, 0x00, 0x00, 0x00, 0x07, 0xB2, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x22, 0x02, 0x00, 0x00, 0x07, 0xEF, 0x01, 0x00, 0x00,\n                           0x09, 0x22, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xE6, 0x00, 0x00,\n                           0x00, 0x07, 0xB2, 0x00, 0x00, 0x00, 0x09, 0xE6, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x03, 0x83, 0x00, 0x00, 0x00, 0x06, 0x99, 0x00, 0x00, 0x00, 0x09, 0x8D, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x99, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x06, 0x4E, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x0B, 0x3D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x11, 0x3D, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x19, 0x3D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x24, 0x3D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x80, 0x00, 0x00, 0x00, 0x07, 0x99, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x99, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x2E, 0x3D, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x99, 0x00,\n                           0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x09, 0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x38, 0x3D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x41, 0x3D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x99, 0x00, 0x00, 0x00,\n                           0x08, 0x99, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x4D, 0x3D, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x99, 0x00, 0x00, 0x00, 0x07, 0x99, 0x00,\n                           0x00, 0x00, 0x0A, 0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x99,\n                           0x00, 0x00, 0x00, 0x06, 0x99, 0x00, 0x00, 0x00, 0x09, 0x99, 0x00, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x4E, 0x06, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x09,\n                           0x80, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x58, 0x3D, 0x00, 0x00,\n                           0x08, 0x5C, 0x3D, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xB9, 0x05, 0x00,\n                           0x00, 0x08, 0xEE, 0x08, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xB9, 0x05,\n                           0x00, 0x00, 0x08, 0xB2, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83,\n                           0x00, 0x00, 0x00, 0x05, 0xB2, 0x00, 0x00, 0x00, 0x08, 0xB2, 0x00, 0x00, 0x00, 0x04, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x05, 0xB2, 0x00, 0x00, 0x00, 0x08,\n                           0xB2, 0x00, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xC0, 0x05, 0x00, 0x00, 0x05, 0xB2, 0x00, 0x00, 0x00, 0x08, 0xB2, 0x00, 0x00, 0x00,\n                           0x0A, 0x55, 0x02, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x55, 0x02, 0x00,\n                           0x00, 0x05, 0xB2, 0x00, 0x00, 0x00, 0x08, 0xB2, 0x00, 0x00, 0x00, 0x0A, 0xC0, 0x05, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x60, 0x3D, 0x00, 0x00, 0x08, 0x64, 0x3D,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x68, 0x3D, 0x00, 0x00, 0x08, 0x6C,\n                           0x3D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x70, 0x3D, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x75, 0x3D, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0x00,\n                           0x08, 0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x7A, 0x3D, 0x00,\n                           0x00, 0x06, 0x80, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x7E, 0x3D, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00,\n                           0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83, 0x3D, 0x00, 0x00, 0x06, 0x80,\n                           0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x88, 0x3D, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x8E, 0x3D, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0x00,\n                           0x08, 0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x94, 0x3D, 0x00,\n                           0x00, 0x06, 0x80, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x9A, 0x3D, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00,\n                           0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x9F, 0x3D, 0x00, 0x00, 0x05, 0xA4,\n                           0x3D, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0xA8, 0x3D, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00,\n                           0x07, 0x80, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xB2, 0x3D, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x80, 0x00,\n                           0x00, 0x00, 0x05, 0x80, 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x0B, 0x80, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x7D, 0x02, 0x00, 0x00, 0x0A, 0x80,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x84, 0x02, 0x00, 0x00, 0x0A,\n                           0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x7D, 0x02, 0x00, 0x00,\n                           0x09, 0x80, 0x00, 0x00, 0x00, 0x0B, 0x80, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x84, 0x02, 0x00, 0x00, 0x09, 0x80, 0x00, 0x00, 0x00, 0x0B, 0x80, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xBF, 0x3D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0xCB, 0x3D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0xD7, 0x3D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xE0, 0x3D, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xE9, 0x3D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0xF5, 0x3D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xFE,\n                           0x3D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x09, 0x3E, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x14, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x20, 0x3E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x7D, 0x02,\n                           0x00, 0x00, 0x0A, 0x99, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x84,\n                           0x02, 0x00, 0x00, 0x0A, 0x99, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x2C, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3A, 0x3E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x47, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x53, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x5F,\n                           0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x6D, 0x3E, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x6B, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x74, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7B, 0x3E,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x87, 0x3E, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x6B, 0x0B, 0x00, 0x00, 0x0A, 0x99, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x74, 0x0B, 0x00, 0x00, 0x0A, 0x99, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x93, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x9E, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x7D,\n                           0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x85, 0x0B, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xA9, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0xB3, 0x3E, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x7D, 0x0B,\n                           0x00, 0x00, 0x0A, 0x80, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x85,\n                           0x0B, 0x00, 0x00, 0x0A, 0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xBD, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC9, 0x3E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xD5, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x03, 0xE0, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xEB,\n                           0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xF5, 0x3E, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xFF, 0x3E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0x8D, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x95, 0x0B,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8D, 0x0B, 0x00, 0x00, 0x0A, 0x80,\n                           0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x95, 0x0B, 0x00, 0x00, 0x0A,\n                           0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x09, 0x3F, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x13, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x1D, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x26,\n                           0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x2F, 0x3F, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x38, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0x41, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x4A, 0x3F,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x53, 0x3F, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x5C, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0x65, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x6E, 0x3F, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x77, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x80, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x89, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x92, 0x3F, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x9D, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xA8, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB4,\n                           0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xC0, 0x3F, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xCB, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0xD6, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xE1, 0x3F,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xEC, 0x3F, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0xF7, 0x3F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x02, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x0D, 0x40, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x18, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x23, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0x2E, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x37, 0x40, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x9D, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x03, 0xA6, 0x0B, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9D,\n                           0x0B, 0x00, 0x00, 0x0A, 0x80, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xA6, 0x0B, 0x00, 0x00, 0x0A, 0x80, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x06, 0x40, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x45, 0x40, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x4A, 0x40, 0x00, 0x00, 0x03, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0xAF, 0x0B, 0x00, 0x00, 0x07, 0x4F, 0x40, 0x00, 0x00, 0x09, 0xAF,\n                           0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x52, 0x40, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBC, 0x04, 0x00, 0x00, 0x0B, 0x80, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x04, 0x44, 0x06, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x04, 0xBC, 0x04,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x5E, 0x40, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x68, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x44, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xBC, 0x04, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x72, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x7C, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x86, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x83, 0x00, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x8D, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0xD7, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x94,\n                           0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x9D, 0x40, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xA6, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0xAF, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xB8, 0x40,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x4E, 0x06, 0x00, 0x00, 0x08, 0x80,\n                           0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xC1, 0x40, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xCB, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0xD5, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xDF, 0x40,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xE9, 0x40, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0xF3, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xFD, 0x40, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCB, 0x0A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x09, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x12, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x1B, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x24, 0x41, 0x00, 0x00,\n                           0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x02, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,\n                           0x00, 0x09, 0x84, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x84, 0x02,\n                           0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x09, 0x7D, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x06, 0x7D, 0x02, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x06, 0x84, 0x02, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2D, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x39, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x45, 0x41,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x51, 0x41, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x5D, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x69, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x75, 0x41, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x80, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x8B, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x96, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA1, 0x41, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAE, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xBB, 0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC6,\n                           0x41, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xD1, 0x41, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xDE, 0x41, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x83, 0x00, 0x00, 0x00, 0x06, 0x83, 0x00, 0x00, 0x00, 0x0A, 0x83, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x37, 0x06, 0x00, 0x00, 0x03, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x22, 0x02, 0x00, 0x00, 0x06, 0x83, 0x00, 0x00, 0x00, 0x0A, 0x3F,\n                           0x03, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3F, 0x03, 0x00, 0x00, 0x06,\n                           0x83, 0x00, 0x00, 0x00, 0x0A, 0x22, 0x02, 0x00, 0x8D, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0xEB, 0x41, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xA8,\n                           0x06, 0x00, 0x84, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF5, 0x41, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x05, 0x42, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x15, 0x42, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x23,\n                           0x42, 0x00, 0x83, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x31, 0x42, 0x00, 0x86,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x38, 0x42, 0x00, 0x80, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0x42, 0x42, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x4D, 0x42, 0x00, 0x83, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5A, 0x42,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x6A, 0x42, 0x00, 0x86, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x78, 0x42, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x88, 0x42, 0x00, 0xC0, 0x6F, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x98, 0x42, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB3, 0x0B, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xA9, 0x42, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x01, 0xB9, 0x42, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC5,\n                           0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xCA, 0x42, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xDA, 0x42, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xB3, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xEB, 0x42,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xFB, 0x42, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xC5, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x0C, 0x43, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x1C, 0x43, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x2D, 0x43, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x3F, 0x43, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x52, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x4F, 0x43, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x60, 0x43, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x72, 0x43, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x52,\n                           0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x82, 0x43, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x94, 0x43, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA6, 0x43,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB6, 0x43, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xD7, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x0A, 0xDB, 0x0B, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xDB, 0x0B, 0x00,\n                           0x00, 0x08, 0xD7, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC6, 0x43,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDF, 0x0B, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xD6, 0x43, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB5, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x09, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x0B, 0xB5, 0x00, 0x00, 0x8F, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xE8, 0x43, 0x00, 0xB9, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF4, 0x43,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x0C, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x18, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x24, 0x44, 0x00,\n                           0x94, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0A, 0x30, 0x44, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x34, 0x44, 0x00, 0x80, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x40, 0x44, 0x00, 0x00, 0x0A, 0x8D, 0x00, 0x00, 0xC0, 0xD8, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x07, 0x64, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x52, 0x06, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x49, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x07, 0x5B, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07,\n                           0x5E, 0x44, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x22, 0x04, 0x00, 0x00,\n                           0x05, 0x1C, 0x05, 0x00, 0x00, 0x0B, 0x22, 0x04, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xF1, 0x0B, 0x00, 0x00, 0x05, 0x62, 0x44, 0x00, 0x00, 0x0B, 0xF1, 0x0B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x69, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x07, 0x6C, 0x44, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x26, 0x02, 0x00, 0x00, 0x04, 0x26, 0x02, 0x00, 0x00, 0x08, 0x26, 0x02, 0x00, 0x00, 0x0C,\n                           0x26, 0x02, 0x00, 0x00, 0x04, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC6, 0x04, 0x00, 0x00,\n                           0x04, 0xC6, 0x04, 0x00, 0x00, 0x08, 0xC6, 0x04, 0x00, 0x00, 0x0C, 0xC6, 0x04, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x70, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x07, 0x7B, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x86,\n                           0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x91, 0x44, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x9C, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x07, 0xA7, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xB2, 0x44,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xBD, 0x44, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xC8, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xD2, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDD, 0x44, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xE7, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xF2, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xFC, 0x44, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x07, 0x45, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x11, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x1C, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x2E,\n                           0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x40, 0x45, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x52, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x64, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x76, 0x45,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x88, 0x45, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x9A, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xAC, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBE, 0x45, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD0, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xE2, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xF4, 0x45, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x06, 0x46, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x18, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x2A, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x3C,\n                           0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x47, 0x46, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x52, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x07, 0x5D, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x68, 0x46,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x73, 0x46, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x07, 0x7E, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x07, 0x89, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x94, 0x46, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x9E, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xA9, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xB4, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xBF, 0x46, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC9, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xD4, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDF,\n                           0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xEA, 0x46, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xFC, 0x46, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x0E, 0x47, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x20, 0x47,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x32, 0x47, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x44, 0x47, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x56, 0x47, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x68, 0x47, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7A, 0x47, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x8C, 0x47, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x9E, 0x47, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB0, 0x47, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC2, 0x47, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xD4, 0x47, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xE6,\n                           0x47, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF8, 0x47, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x0A, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x07, 0x36, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x3B, 0x06,\n                           0x00, 0x00, 0x08, 0x3B, 0x06, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF7,\n                           0x0B, 0x00, 0x00, 0x08, 0xF7, 0x0B, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06,\n                           0xB5, 0x00, 0x00, 0x00, 0x08, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x0D, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x1F, 0x48, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x2B, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x06, 0x36, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06,\n                           0x42, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x4E, 0x48, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x59, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x65, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x70,\n                           0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7A, 0x48, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x85, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x90, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x9A, 0x48,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xA5, 0x48, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0xB7, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xC9, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDB, 0x48, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xED, 0x48, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xFF, 0x48, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06,\n                           0xB5, 0x00, 0x00, 0x00, 0x08, 0x11, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x07, 0x1B, 0x49, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xB5, 0x00, 0x00,\n                           0x00, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x26, 0x49,\n                           0x00, 0x00, 0x08, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x2F,\n                           0x49, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0A, 0x0C, 0x00, 0x00, 0x08,\n                           0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x39, 0x49, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x4B, 0x49, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x0A, 0x0C, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x07, 0x5D, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07,\n                           0x68, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x73, 0x49, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7D, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x87, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x99,\n                           0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xAB, 0x49, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xBD, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x15, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xC0, 0x49,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xC3, 0x49, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x07, 0xCE, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x13, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xD2, 0x49, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x13, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x07, 0xD6, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xDA, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xEC, 0x49, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF0, 0x49, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x02, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0E, 0x64,\n                           0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0x0B, 0x4A, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x0A, 0x11, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x08, 0x19, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x23, 0x4A,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x2F, 0x4A, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x3D, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x4D, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x5F, 0x4A, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x71, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x83, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x95, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xA7, 0x4A, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDF, 0x0B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xB9, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xCB,\n                           0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xDD, 0x4A, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xEF, 0x4A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x01, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x64, 0x06,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x13, 0x4B, 0x00, 0x89, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x25, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x30, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x3B, 0x4B,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x46, 0x4B, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0x51, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x5C, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x67, 0x4B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x72, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x7D, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0x88, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x93, 0x4B, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x9A, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x07, 0xA1, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xA8,\n                           0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x4B, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBD, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x06, 0xCB, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xD3, 0x4B,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xDB, 0x4B, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0xE4, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x08, 0xED, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0xF3, 0x4B, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xF9, 0x4B, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x06, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07,\n                           0x13, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x1A, 0x4C, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x21, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x2A, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x33,\n                           0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x3C, 0x4C, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0x45, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x08, 0x4B, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x51, 0x4C,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x5E, 0x4C, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x07, 0x6B, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x07, 0x72, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x79, 0x4C, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x82, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x8B, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x97, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA3, 0x4C, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xBB, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC7,\n                           0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD3, 0x4C, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xEB, 0x4C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF7, 0x4C,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x03, 0x4D, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x0F, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x1B, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x27, 0x4D, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x33, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x3F, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x4B, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x57, 0x4D, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x63, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x75, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x87,\n                           0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x90, 0x4D, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9B, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xA2, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xA9, 0x4D,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xB0, 0x4D, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xB7, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x07, 0xBE, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xC5, 0x4D, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD7, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0xE9, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xFB, 0x4D, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x0D, 0x4E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x15, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x21, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2D,\n                           0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x39, 0x4E, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x45, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x51, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x5C, 0x4E,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x67, 0x4E, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x72, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x7F, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x8A, 0x4E, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x95, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0xA0, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xAB, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB7, 0x4E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC3, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xCF, 0x4E, 0x00, 0x87, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0xDB, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xE6, 0x4E, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xEC, 0x4E, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0xDB, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0xF7, 0x4E, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x01, 0x4F, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0C, 0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x17, 0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x20,\n                           0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x2A, 0x4F, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x34, 0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x3D, 0x4F, 0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x49,\n                           0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x53, 0x4F, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x5D, 0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x67, 0x4F, 0x00, 0x8B, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x72,\n                           0x4F, 0x00, 0x00, 0x0A, 0x7C, 0x4F, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x83, 0x4F, 0x00, 0x82, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8D, 0x4F,\n                           0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x99, 0x4F, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xA5, 0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xB0, 0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xBC, 0x4F,\n                           0x00, 0x81, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC7, 0x4F, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD3, 0x4F, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x57, 0x01, 0x00, 0x00, 0x06, 0x57, 0x01, 0x00, 0x00, 0x0A, 0x57, 0x01, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x36, 0x01, 0x00, 0x00, 0x06, 0x57, 0x01,\n                           0x00, 0x00, 0x0A, 0x57, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x57,\n                           0x01, 0x00, 0x00, 0x06, 0x36, 0x01, 0x00, 0x00, 0x0A, 0x57, 0x01, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x36, 0x01, 0x00, 0x00, 0x06, 0x36, 0x01, 0x00, 0x00, 0x0A,\n                           0x57, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x57, 0x01, 0x00, 0x00,\n                           0x06, 0x57, 0x01, 0x00, 0x00, 0x0A, 0x36, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x36, 0x01, 0x00, 0x00, 0x06, 0x57, 0x01, 0x00, 0x00, 0x0A, 0x36, 0x01, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x57, 0x01, 0x00, 0x00, 0x06, 0x36, 0x01,\n                           0x00, 0x00, 0x0A, 0x36, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x36,\n                           0x01, 0x00, 0x00, 0x06, 0x36, 0x01, 0x00, 0x00, 0x0A, 0x36, 0x01, 0x00, 0x80, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDF, 0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xEB, 0x4F, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xF7, 0x4F,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x03, 0x50, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x0E, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x1A, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x26, 0x50, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x34, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x40, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x4C, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x58, 0x50, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x67, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x73, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x80,\n                           0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8E, 0x50, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9B, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0xA8, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB5, 0x50,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC1, 0x50, 0x00, 0x00, 0x08, 0xC7,\n                           0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xCD, 0x50, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDB, 0x50, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xE9, 0x50, 0x00, 0x00, 0x0A, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xF2, 0x50, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x00,\n                           0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0A, 0x51, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x1E, 0x0C, 0x00, 0x00, 0x08, 0x1E, 0x0C, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x18, 0x51, 0x00, 0x8B, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x25, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x30, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x3A, 0x51, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x43, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x03, 0x4E, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x59,\n                           0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x63, 0x51, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x6C, 0x51, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x77, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x83,\n                           0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8F, 0x51, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x9C, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0xA9, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB5, 0x51,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC3, 0x51, 0x00, 0xFE, 0xFF, 0xFE,\n                           0xFF, 0xFE, 0xFF, 0xD7, 0x8F, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD1, 0x51,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xDD, 0x51, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xE9, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xF5, 0x51, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x01, 0x52, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x0D, 0x52, 0x00, 0xC0, 0x49, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xE8, 0x05, 0x00, 0x00, 0x04, 0xED, 0x05, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xE8, 0x05, 0x00, 0x00, 0x04, 0x23, 0x0C, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x0A, 0x7D, 0x00,\n                           0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xBA,\n                           0x01, 0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C,\n                           0x7D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00, 0x00,\n                           0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x0A, 0x87, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xBA, 0x01, 0x00, 0x00, 0x0A, 0x87, 0x00,\n                           0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x09,\n                           0x01, 0x00, 0x00, 0x0A, 0x87, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00, 0x00, 0x0A, 0x87, 0x00, 0x00, 0x00, 0x0C,\n                           0x7D, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x00,\n                           0x0A, 0x87, 0x00, 0x00, 0x00, 0x0C, 0x87, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xBA, 0x01, 0x00, 0x00, 0x0A, 0x87, 0x00, 0x00, 0x00, 0x0C, 0x87, 0x00, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00, 0x00, 0x0A, 0x87, 0x00,\n                           0x00, 0x00, 0x0C, 0x87, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xF0,\n                           0x00, 0x00, 0x00, 0x0A, 0x87, 0x00, 0x00, 0x00, 0x0C, 0x87, 0x00, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x7D, 0x00, 0x00, 0x00, 0x05,\n                           0xEA, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00,\n                           0x03, 0x7D, 0x00, 0x00, 0x00, 0x05, 0xBA, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x7D, 0x00, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x7D, 0x00,\n                           0x00, 0x00, 0x06, 0xF0, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x87,\n                           0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x05,\n                           0xBA, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x87, 0x00, 0x00, 0x00,\n                           0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x87, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x05, 0xEA, 0x00,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x05, 0xBA,\n                           0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x05,\n                           0x09, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00,\n                           0x06, 0xF0, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00,\n                           0x00, 0x02, 0xD1, 0x00, 0x00, 0x00, 0x04, 0x98, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x00, 0x00, 0x04, 0x68, 0x06,\n                           0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x87,\n                           0x00, 0x00, 0x00, 0x04, 0xCB, 0x04, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x7D, 0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x04, 0xD2, 0x04, 0x00, 0x00, 0x03,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD1, 0x00, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x00, 0x00,\n                           0x04, 0x98, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xD1, 0x00, 0x00,\n                           0x00, 0x02, 0xD1, 0x00, 0x00, 0x00, 0x04, 0x68, 0x06, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x04, 0xCB, 0x04,\n                           0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x02, 0x87,\n                           0x00, 0x00, 0x00, 0x04, 0xD2, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0x10, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x19, 0x52, 0x00, 0x00,\n                           0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x34, 0x02, 0x00, 0x00, 0x0A, 0xB8, 0x00, 0x00,\n                           0x00, 0x0C, 0xB8, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3A, 0x02,\n                           0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x05, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x24, 0x52, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x34, 0x02, 0x00, 0x00,\n                           0x0B, 0xD1, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3A, 0x02, 0x00,\n                           0x00, 0x0B, 0x87, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xF5, 0x05,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x2F, 0x52, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x05, 0x34, 0x02, 0x00, 0x00, 0x0A, 0xD1, 0x00, 0x00, 0x00, 0x0C,\n                           0xB8, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3A, 0x02, 0x00, 0x00,\n                           0x0A, 0x87, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0x1B, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3A, 0x52,\n                           0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x34, 0x02, 0x00, 0x00, 0x0A, 0xD1,\n                           0x00, 0x00, 0x00, 0x0C, 0xD1, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x3A, 0x02, 0x00, 0x00, 0x0A, 0x87, 0x00, 0x00, 0x00, 0x0C, 0x87, 0x00, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00, 0x0B, 0x87, 0x00, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x6F, 0x03, 0x00, 0x00, 0x0B, 0x87, 0x00, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x63, 0x02, 0x00, 0x00, 0x04, 0x18, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x63, 0x02, 0x00, 0x00, 0x04, 0x6F,\n                           0x03, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00, 0x02,\n                           0x63, 0x02, 0x00, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0xAF, 0x00, 0x00, 0x00, 0x02, 0x63, 0x02, 0x00, 0x00, 0x04, 0x6F, 0x03, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x00, 0x45, 0x52, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7D,\n                           0x00, 0x00, 0x00, 0x02, 0x87, 0x00, 0x00, 0x00, 0x05, 0x1F, 0x01, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x00, 0x00, 0x00, 0x04, 0x87, 0x00, 0x00, 0x00, 0x07,\n                           0xD9, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00,\n                           0x05, 0x1F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00,\n                           0x00, 0x07, 0xD9, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x31, 0x0A,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x50, 0x52, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x2B, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x34, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x5F, 0x03, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x3D, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x48, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x53, 0x0C, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x5F, 0x03, 0x00, 0x00,\n                           0x0A, 0xAF, 0x00, 0x00, 0x00, 0x0C, 0xAF, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x3D, 0x0C, 0x00, 0x00, 0x0A, 0xAF, 0x00, 0x00, 0x00, 0x0C, 0xAF, 0x00, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x48, 0x0C, 0x00, 0x00, 0x0A, 0xAF, 0x00,\n                           0x00, 0x00, 0x0C, 0xAF, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x53,\n                           0x0C, 0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x44, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x5A, 0x52, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x65, 0x52, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x70, 0x52, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0xDE, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07,\n                           0x5E, 0x0C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00,\n                           0x05, 0xDE, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00,\n                           0x00, 0x07, 0x5E, 0x0C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30, 0x01,\n                           0x00, 0x00, 0x05, 0x09, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x30,\n                           0x01, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0x4F, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7B, 0x52, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x43, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x07, 0xA7, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x86,\n                           0x52, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x8D, 0x52, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x66, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x03, 0x66, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x94, 0x52,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x9C, 0x52, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x06, 0x71, 0x0A, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x08, 0x6F, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA4, 0x52, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6F, 0x06, 0x00, 0x00, 0x08, 0x6F, 0x0C,\n                           0x00, 0xA0, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00, 0x02,\n                           0x3B, 0x0A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xAF, 0x00, 0x00, 0x00,\n                           0x02, 0xAF, 0x52, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x56, 0x03, 0x00,\n                           0x00, 0x02, 0xB8, 0x52, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x56, 0x03,\n                           0x00, 0x00, 0x02, 0xC1, 0x52, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x63,\n                           0x0A, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xCA, 0x52, 0x00, 0x00, 0x06,\n                           0x40, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x79, 0x02, 0x00, 0x00,\n                           0x05, 0x27, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x79, 0x02, 0x00,\n                           0x00, 0x06, 0x40, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0E, 0x06,\n                           0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0E,\n                           0x06, 0x00, 0x00, 0x06, 0x40, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xF7, 0x09, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00,\n                           0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x7D, 0x00, 0x00, 0x00, 0x04, 0x87, 0x00, 0x00, 0x00, 0x06, 0x40, 0x02, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x5A, 0x0A, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x79, 0x02, 0x00, 0x00, 0x06, 0xD1, 0x52, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x14, 0x06, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x14, 0x06, 0x00, 0x00, 0x06, 0x40, 0x02, 0x00, 0x00,\n                           0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE6, 0x01, 0x00, 0x00, 0x0D, 0xAF, 0x00, 0x00,\n                           0x00, 0x0F, 0xAF, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0xDA, 0x52,\n                           0x00, 0x00, 0x0F, 0xAF, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x09,\n                           0x01, 0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00, 0x00, 0x0A, 0x7D, 0x00, 0x00, 0x00, 0x0C,\n                           0x7D, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00, 0x91, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x18, 0x06, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08,\n                           0x76, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00, 0x00,\n                           0x0B, 0x87, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00,\n                           0x00, 0x0B, 0x87, 0x00, 0x00, 0xC0, 0x5A, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00,\n                           0xE2, 0x52, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x59, 0x03, 0x00, 0x00,\n                           0x05, 0x1F, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x59, 0x03, 0x00,\n                           0x00, 0x05, 0xE6, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xED, 0x52,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF8, 0x52, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x02, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x0A, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x14, 0x53, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x1C, 0x53, 0x00, 0xAB, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x59, 0x03, 0x00, 0x00, 0x08, 0x76, 0x03, 0x00, 0xC0, 0x60,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x24, 0x53, 0x00, 0x00, 0x08, 0xB5, 0x00,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x37, 0x53, 0x00, 0x00, 0x08, 0xB5, 0x00, 0x00, 0xC0, 0x46,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x3F, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x4A, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0x55, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x60, 0x53, 0x00, 0xC0,\n                           0xB1, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x6B, 0x53, 0x00, 0x00, 0x04, 0x6F,\n                           0x53, 0x00, 0xC0, 0x5C, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x09, 0x75, 0x0C, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x09, 0x76, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x09, 0xAF, 0x00, 0x00, 0x80, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x06, 0x7D, 0x00, 0x00, 0x00, 0x09, 0x75, 0x0C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x06, 0xAF, 0x00, 0x00, 0x00, 0x09, 0xAF, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x7A, 0x53, 0x00, 0x00, 0x0A, 0xAF, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x59, 0x03, 0x00, 0x00, 0x0A, 0xAF, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x08, 0xD2, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x80, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x89, 0x53, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x92, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x9B, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0xA4, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xAD, 0x53, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xB6, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xBD, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xC6,\n                           0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xCE, 0x53, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0xD2, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x06, 0xD5, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xDC, 0x53,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xD2, 0x01, 0x00, 0x00, 0x09, 0xD2,\n                           0x01, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE3, 0x53, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0xEB, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xF5, 0x53, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xFD,\n                           0x53, 0x00, 0x83, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x9D, 0x04, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x05, 0x54, 0x00, 0x00, 0x08, 0xB5, 0x00, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x7A, 0x09, 0x00, 0x80, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x0A, 0x9D, 0x04, 0x00, 0x80, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0xA3, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x79, 0x0C,\n                           0x00, 0x00, 0x08, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x81,\n                           0x09, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x54, 0x00, 0x00, 0x08,\n                           0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x0C, 0xA3, 0x04, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0xB5, 0x00, 0x00, 0x00, 0x0B, 0x79, 0x0C, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x00, 0x14, 0x54, 0x00, 0x00, 0x08, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x8E, 0x09, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x65, 0x0B, 0x00, 0x00, 0x08, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x04, 0xC4, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x1F, 0x09,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x1B, 0x54, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x00, 0x2A, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x00, 0x26, 0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x35, 0x09, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x6F, 0x06, 0x00, 0x00, 0x06, 0x40, 0x02,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xED, 0x05, 0x00, 0x00, 0x0A, 0x7E,\n                           0x0C, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x23, 0x0C, 0x00, 0x00, 0x0A,\n                           0x7E, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x31, 0x54, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x3E, 0x54, 0x00, 0x00, 0x08, 0x76, 0x03, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x44, 0x54, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x6F, 0x06, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x03, 0xCB, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x4E, 0x54, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00,\n                           0x00, 0x0B, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xBA, 0x01,\n                           0x00, 0x00, 0x0B, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x09,\n                           0x01, 0x00, 0x00, 0x0B, 0xAF, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06,\n                           0xF0, 0x00, 0x00, 0x00, 0x0B, 0x7D, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x01, 0x63, 0x02, 0x00, 0x00, 0x04, 0x43, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x2E, 0x0A, 0x00, 0x00, 0x03, 0x84, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x04, 0x42, 0x09, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x87,\n                           0x00, 0x00, 0x00, 0x05, 0xBA, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03,\n                           0x87, 0x00, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x03, 0x87, 0x00, 0x00, 0x00, 0x06, 0xF0, 0x00, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00,\n                           0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00,\n                           0x00, 0x00, 0x05, 0xBA, 0x01, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D,\n                           0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00, 0x00, 0x03, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x06,\n                           0xF0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x49, 0x09, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x56, 0x54, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0x34, 0x02, 0x00, 0x00, 0x0B, 0xAF, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x05, 0x3A, 0x02, 0x00, 0x00, 0x0B, 0x7D, 0x00, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x66, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x05, 0x8C, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x34, 0x02, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x3A, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x86, 0x04, 0x00, 0x00, 0x04, 0x66, 0x02, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0x86, 0x04, 0x00, 0x00, 0x05, 0x8C, 0x0C, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xAF, 0x00, 0x00, 0x00, 0x05, 0x34, 0x02, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x00, 0x00, 0x00, 0x05, 0x3A, 0x02, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x6F, 0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xAF, 0x00, 0x00, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0xAF, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0x1F, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0xD9, 0x04,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x00, 0x00, 0x00, 0x05, 0x1F,\n                           0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x7D, 0x00, 0x00, 0x00, 0x07,\n                           0xD9, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x71, 0x02, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x71, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x06, 0x97, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x07, 0x9C,\n                           0x0C, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x03,\n                           0x87, 0x00, 0x00, 0x00, 0x05, 0x71, 0x02, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x7D, 0x00, 0x00, 0x00, 0x04, 0x87, 0x00, 0x00, 0x00, 0x06, 0x71, 0x02, 0x00, 0x00,\n                           0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0xB8, 0x00, 0x00, 0x00, 0x03, 0xD1, 0x00, 0x00,\n                           0x00, 0x06, 0x97, 0x0C, 0x00, 0x00, 0x03, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00,\n                           0x00, 0x00, 0x03, 0x87, 0x00, 0x00, 0x00, 0x07, 0x9C, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x04, 0x2B, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05,\n                           0x2B, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE0, 0x04, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE0, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x2B, 0x02, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0xB8, 0x00, 0x00, 0x00, 0x05, 0x2B, 0x02, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x05, 0xE0, 0x04, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x05, 0xE0, 0x04, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x54, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0x61, 0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x6A,\n                           0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x73, 0x54, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x5D, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x02, 0x7C, 0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x85, 0x54,\n                           0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x8E, 0x54, 0x00, 0x00, 0x01, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x04, 0x4A, 0x03, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x04, 0xA0, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xAC, 0x0C, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xB2, 0x0C, 0x00, 0x00, 0x02, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x01, 0x56, 0x03, 0x00, 0x00, 0x04, 0x4A, 0x03, 0x00, 0x00, 0x02, 0x08,\n                           0x10, 0x08, 0x00, 0x00, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x04, 0xA0, 0x0C, 0x00, 0x00, 0x02,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xAF, 0x00, 0x00, 0x00, 0x05, 0xAC, 0x0C, 0x00, 0x00,\n                           0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x00, 0x00, 0x00, 0x05, 0xB2, 0x0C, 0x00,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x98, 0x01,\n                           0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x00, 0x00, 0x00, 0x04, 0x68,\n                           0x06, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x00, 0x00, 0x00, 0x04,\n                           0xCB, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x00, 0x00, 0x00,\n                           0x04, 0xD2, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD1, 0x00, 0x00,\n                           0x00, 0x04, 0x89, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xD1, 0x00,\n                           0x00, 0x00, 0x05, 0x97, 0x54, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x87,\n                           0x00, 0x00, 0x00, 0x04, 0xCB, 0x04, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0x87, 0x00, 0x00, 0x00, 0x04, 0xD2, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00,\n                           0x02, 0x94, 0x04, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xA1, 0x54, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x2B, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x02, 0x34, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01,\n                           0xD9, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xAA, 0x54, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB7, 0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x02, 0xC0, 0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x66,\n                           0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xC9, 0x54, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xD3, 0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x05, 0xD9, 0x54, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0x7D, 0x00,\n                           0x00, 0x00, 0x05, 0xDE, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xDF,\n                           0x54, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0xAF, 0x00, 0x00, 0x00, 0x05,\n                           0x09, 0x01, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x7D, 0x00, 0x00, 0x00,\n                           0x06, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04, 0x43, 0x03, 0x00,\n                           0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x03, 0x84, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10,\n                           0x08, 0x00, 0x00, 0x03, 0x72, 0x09, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x04,\n                           0xE8, 0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x27, 0x01, 0x00, 0x00,\n                           0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0x40, 0x02, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08,\n                           0x00, 0x00, 0x05, 0xE6, 0x01, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0x76,\n                           0x03, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0xE6, 0x01, 0x00, 0x00, 0x0E,\n                           0xE5, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x08, 0x76, 0x03, 0x00, 0x00,\n                           0x0E, 0xE5, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x05, 0x09, 0x01, 0x00,\n                           0x00, 0x0B, 0x87, 0x00, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x06, 0xF0, 0x00,\n                           0x00, 0x00, 0x0B, 0x87, 0x00, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xF2,\n                           0x54, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0xFE, 0x54, 0x00, 0x00, 0x01,\n                           0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x09, 0x55, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00,\n                           0x00, 0x00, 0x15, 0x55, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xB8, 0x0C,\n                           0x00, 0x00, 0x0B, 0xD3, 0x05, 0x00, 0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC2,\n                           0x0C, 0x00, 0x00, 0x0B, 0xD3, 0x05, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02,\n                           0xB8, 0x0C, 0x00, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x02, 0xC2, 0x0C, 0x00, 0x81,\n                           0x00, 0x02, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00, 0x20, 0x55, 0x00, 0x00, 0x0B, 0x2C, 0x55,\n                           0x00, 0xC0, 0xFC, 0x00, 0x01, 0x08, 0x10, 0x08, 0x00, 0x00, 0x01, 0x33, 0x55, 0x00, 0xFF,\n                           0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n                           0x82, 0x32, 0x4E, 0x46, 0x53};\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_XTFONT_H */\n"
  },
  {
    "path": "sdk/xtdk/xtfw.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtfw.h\n * DESCRIPTION:     EFI-dependent XT structures\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTFW_H\n#define __XTDK_XTFW_H\n\n#include <xtbase.h>\n#include <xttypes.h>\n\n\n/* Version number of the current kernel initialization block */\n#define INITIALIZATION_BLOCK_VERSION                            1\n\n/* Version number of the current XTOS loader protocol */\n#define BOOT_PROTOCOL_VERSION                                   1\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Memory allocation structures */\ntypedef enum _LOADER_MEMORY_TYPE\n{\n    LoaderExceptionBlock,\n    LoaderSystemBlock,\n    LoaderFree,\n    LoaderBad,\n    LoaderLoadedProgram,\n    LoaderFirmwareTemporary,\n    LoaderFirmwarePermanent,\n    LoaderOsloaderHeap,\n    LoaderOsloaderStack,\n    LoaderSystemCode,\n    LoaderHalCode,\n    LoaderBootDriver,\n    LoaderConsoleInDriver,\n    LoaderConsoleOutDriver,\n    LoaderStartupDpcStack,\n    LoaderStartupKernelStack,\n    LoaderStartupPanicStack,\n    LoaderStartupPcrPage,\n    LoaderStartupPdrPage,\n    LoaderRegistryData,\n    LoaderMemoryData,\n    LoaderNlsData,\n    LoaderSpecialMemory,\n    LoaderBBTMemory,\n    LoaderReserve,\n    LoaderXIPRom,\n    LoaderHardwareCachedMemory,\n    LoaderMaximum\n} LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;\n\n/* Firmware types enumeration list */\ntypedef enum _SYSTEM_FIRMWARE_TYPE\n{\n    SystemFirmwareInvalid,\n    SystemFirmwareUnknown,\n    SystemFirmwareEfi,\n    SystemFirmwarePcat\n} SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;\n\n/* PCAT Firmware information block */\ntypedef struct _PCAT_FIRMWARE_INFORMATION\n{\n    ULONG PlaceHolder;\n} PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;\n\n/* UEFI Firmware information block */\ntypedef struct _UEFI_FIRMWARE_INFORMATION\n{\n    ULONG EfiVersion;\n    PEFI_RUNTIME_SERVICES EfiRuntimeServices;\n} UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRMWARE_INFORMATION;\n\n/* Firmware information block */\ntypedef struct _FIRMWARE_INFORMATION_BLOCK\n{\n    SYSTEM_FIRMWARE_TYPE FirmwareType;\n    union\n    {\n        UEFI_FIRMWARE_INFORMATION EfiFirmware;\n        PCAT_FIRMWARE_INFORMATION PcatFirmware;\n    };\n} FIRMWARE_INFORMATION_BLOCK, *PFIRMWARE_INFORMATION_BLOCK;\n\n/* Boot Loader information block */\ntypedef struct _LOADER_INFORMATION_BLOCK\n{\n    PVOID DbgPrint;\n} LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK;\n\n/* Boot Loader memory mapping information */\ntypedef struct _LOADER_MEMORY_DESCRIPTOR\n{\n    LIST_ENTRY ListEntry;\n    LOADER_MEMORY_TYPE MemoryType;\n    ULONG BasePage;\n    ULONG PageCount;\n} LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;\n\n/* Loader provided information needed by the kernel to initialize */\ntypedef struct _KERNEL_INITIALIZATION_BLOCK\n{\n    ULONG BlockSize;\n    ULONG BlockVersion;\n    ULONG ProtocolVersion;\n    PWCHAR KernelParameters;\n    PFN_NUMBER BootImageSize;\n    LIST_ENTRY LoadOrderListHead;\n    LIST_ENTRY MemoryDescriptorListHead;\n    LIST_ENTRY BootDriverListHead;\n    LIST_ENTRY SystemResourcesListHead;\n    LOADER_INFORMATION_BLOCK LoaderInformation;\n    FIRMWARE_INFORMATION_BLOCK FirmwareInformation;\n} KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;\n\n#endif /* __XTOS_ASSEMBLER_ */\n#endif /* __XTDK_XTFW_H */\n"
  },
  {
    "path": "sdk/xtdk/xtglyph.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtglyph.h\n * DESCRIPTION:     XT ASCII glyphs\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTGLYPH_H\n#define __XTDK_XTGLYPH_H\n\n#include <xttypes.h>\n\n\n/* C/C++ specific code */\n#ifndef D__XTOS_ASSEMBLER__\n\nCHAR XTGLYPH_EXECTOS_LOGO[] =\n{\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x23,\n  0x23, 0x2f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x25, 0x25,\n  0x25, 0x25, 0x25, 0x25, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x0d, 0x0a, 0x20, 0x20,\n  0x20, 0x20, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x23, 0x23,\n  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x28, 0x28, 0x28, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x2f,\n  0x2f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x25, 0x25, 0x25, 0x25, 0x25, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,\n  0x23, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,\n  0x2f, 0x2f, 0x2f, 0x2f, 0x0d, 0x0a, 0x20, 0x20, 0x25, 0x25, 0x20, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x2c, 0x2c, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x2f, 0x23, 0x23, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,\n  0x28, 0x28, 0x28, 0x2f, 0x2f, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x20, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x23, 0x23, 0x23, 0x23,\n  0x23, 0x23, 0x23, 0x2c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28,\n  0x28, 0x28, 0x28, 0x28, 0x28, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f,\n  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,\n  0x25, 0x25, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,\n  0x28, 0x28, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x2f, 0x2f, 0x2f, 0x2f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x25, 0x25,\n  0x25, 0x25, 0x25, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23,\n  0x23, 0x23, 0x23, 0x23, 0x23, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,\n  0x28, 0x28, 0x28, 0x28, 0x2f, 0x2f, 0x2f, 0x2f, 0x0d, 0x0a, 0x20, 0x20,\n  0x25, 0x25, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x28, 0x28, 0x28, 0x28,\n  0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2f, 0x2f, 0x2a, 0x0d, 0x0a,\n  0x20, 0x2c, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x25, 0x25, 0x25, 0x25, 0x25,\n  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x20, 0x20, 0x20,\n  0x20, 0x20, 0x2f, 0x2f, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x23, 0x25,\n  0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,\n  0x23, 0x23, 0x23, 0x23, 0x28, 0x28, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x2f, 0x2f, 0x0d, 0x0a, 0x20,\n  0x20, 0x20, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x20, 0x20, 0x20, 0x20,\n  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x28, 0x28, 0x28,\n  0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2f, 0x2f, 0x2f, 0x2f,\n  0x0d, 0x0a, 0x20, 0x20, 0x25, 0x25, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23,\n  0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2f,\n  0x2f, 0x2f, 0x0d, 0x0a, 0x20, 0x26, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n  0x20, 0x20, 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,\n  0x28, 0x0d, 0x0a\n};\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_XTGLYPH_H */\n"
  },
  {
    "path": "sdk/xtdk/xtguid.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtguid.h\n * DESCRIPTION:     XTOS Globally Unique Identifiers\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTGUID_H\n#define __XTDK_XTGUID_H\n\n\n/* EFI XT protocols GUIDs */\n#define XT_ACPI_PROTOCOL_GUID                {0x58544F53, 0x5854, 0x4357, {0x00, 0x00, 0x41, 0x43, 0x50, 0x49, 0x50, 0x54}}\n#define XT_BOOT_LOADER_PROTOCOL_GUID         {0x58544F53, 0x5854, 0x4357, {0x00, 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x50, 0x54}}\n#define XT_ELF_IMAGE_PROTOCOL_GUID           {0x58544F53, 0x5854, 0x4357, {0x45, 0x4C, 0x46, 0x49, 0x4D, 0x47, 0x50, 0x54}}\n#define XT_FRAMEBUFFER_PROTOCOL_GUID         {0x58544F53, 0x5854, 0x4357, {0x00, 0x00, 0x46, 0x42, 0x55, 0x46, 0x50, 0x54}}\n#define XT_HIVE_IMAGE_PROTOCOL_GUID          {0x58544F53, 0x5854, 0x4357, {0x48, 0x49, 0x56, 0x49, 0x4D, 0x47, 0x50, 0x54}}\n#define XT_PECOFF_IMAGE_PROTOCOL_GUID        {0x58544F53, 0x5854, 0x4357, {0x00, 0x50, 0x45, 0x49, 0x4D, 0x47, 0x50, 0x54}}\n\n/* EFI XT boot protocols GUIDs */\n#define XT_CHAIN_BOOT_PROTOCOL_GUID          {0x58544F53, 0x5854, 0x4357, {0x00, 0x43, 0x48, 0x41, 0x49, 0x4E, 0x50, 0x54}}\n#define XT_DUMMY_BOOT_PROTOCOL_GUID          {0x58544F53, 0x5854, 0x4357, {0x00, 0x44, 0x55, 0x4D, 0x4D, 0x59, 0x50, 0x54}}\n#define XT_LINUX_BOOT_PROTOCOL_GUID          {0x58544F53, 0x5854, 0x4357, {0x00, 0x4C, 0x49, 0x4E, 0x55, 0x58, 0x50, 0x54}}\n#define XT_WINNT_BOOT_PROTOCOL_GUID          {0x58544F53, 0x5854, 0x4357, {0x00, 0x57, 0x49, 0x4E, 0x4E, 0x54, 0x50, 0x54}}\n#define XT_XTOS_BOOT_PROTOCOL_GUID           {0x58544F53, 0x5854, 0x4357, {0x00, 0x00, 0x58, 0x54, 0x4F, 0x53, 0x50, 0x54}}\n\n/* XTOS GUIDs */\n#define XTOS_EXECTOS_GUID                    {0x58544F53, 0x5854, 0x4357, {0x00, 0x45, 0x58, 0x45, 0x43, 0x54, 0x4F, 0x53}}\n#define XTOS_XTLDR_LOADER_GUID               {0x58544F53, 0x5854, 0x4357, {0x00, 0x00, 0x00, 0x58, 0x54, 0x4C, 0x44, 0x52}}\n\n#endif /* __XTDK_XTGUID_H */\n"
  },
  {
    "path": "sdk/xtdk/xtimage.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtimage.h\n * DESCRIPTION:     Executable image structures definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTIMAGE_H\n#define __XTDK_XTIMAGE_H\n\n#include <xtdefs.h>\n#include <xtfw.h>\n#include <xtstruct.h>\n#include <xttypes.h>\n\n\n/* PE/COFF file image signatures */\n#define PECOFF_IMAGE_DOS_SIGNATURE                         0x5A4D /* MZ */\n#define PECOFF_IMAGE_OS2_SIGNATURE                         0x454E /* NE */\n#define PECOFF_IMAGE_OS2LE_SIGNATURE                       0x454C /* LE */\n#define PECOFF_IMAGE_VXD_SIGNATURE                         0x454C /* LE */\n#define PECOFF_IMAGE_EDOS_SIGNATURE                        0x44454550 /* PEED */\n#define PECOFF_IMAGE_NT_SIGNATURE                          0x00004550 /* PE00 */\n#define PECOFF_IMAGE_XT_SIGNATURE                          0x54584550 /* PEXT */\n\n/* PE/COFF image subsystems */\n#define PECOFF_IMAGE_SUBSYSTEM_UNKNOWN                     0\n#define PECOFF_IMAGE_SUBSYSTEM_NATIVE                      1\n#define PECOFF_IMAGE_SUBSYSTEM_WINDOWS_GUI                 2\n#define PECOFF_IMAGE_SUBSYSTEM_WINDOWS_CUI                 3\n#define PECOFF_IMAGE_SUBSYSTEM_WINDOWS_CE_OLD              4\n#define PECOFF_IMAGE_SUBSYSTEM_OS2_CUI                     5\n#define PECOFF_IMAGE_SUBSYSTEM_POSIX_CUI                   7\n#define PECOFF_IMAGE_SUBSYSTEM_NATIVE_WINDOWS              8\n#define PECOFF_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI              9\n#define PECOFF_IMAGE_SUBSYSTEM_EFI_APPLICATION             10\n#define PECOFF_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER     11\n#define PECOFF_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER          12\n#define PECOFF_IMAGE_SUBSYSTEM_EFI_ROM                     13\n#define PECOFF_IMAGE_SUBSYSTEM_XBOX                        14\n#define PECOFF_IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION    16\n#define PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL            20\n#define PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION       21\n#define PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER            22\n#define PECOFF_IMAGE_SUBSYSTEM_XT_DYNAMIC_LIBRARY          23\n#define PECOFF_IMAGE_SUBSYSTEM_XT_APPLICATION_CLI          24\n#define PECOFF_IMAGE_SUBSYSTEM_XT_APPLICATION_GDI          25\n\n/* PE/COFF file image architecture */\n#define PECOFF_IMAGE_FILE_MACHINE_UNKNOWN                  0x0000\n#define PECOFF_IMAGE_FILE_MACHINE_I386                     0x014C\n#define PECOFF_IMAGE_FILE_MACHINE_R4000                    0x0166\n#define PECOFF_IMAGE_FILE_MACHINE_R3000                    0x0162\n#define PECOFF_IMAGE_FILE_MACHINE_R10000                   0x0168\n#define PECOFF_IMAGE_FILE_MACHINE_WCEMIPSV2                0x0169\n#define PECOFF_IMAGE_FILE_MACHINE_ALPHA                    0x0184\n#define PECOFF_IMAGE_FILE_MACHINE_SH3                      0x01A2\n#define PECOFF_IMAGE_FILE_MACHINE_SH3DSP                   0x01A3\n#define PECOFF_IMAGE_FILE_MACHINE_SH3E                     0x01A4\n#define PECOFF_IMAGE_FILE_MACHINE_SH4                      0x01A6\n#define PECOFF_IMAGE_FILE_MACHINE_SH5                      0x01A8\n#define PECOFF_IMAGE_FILE_MACHINE_ARM                      0x01C0\n#define PECOFF_IMAGE_FILE_MACHINE_THUMB                    0x01C2\n#define PECOFF_IMAGE_FILE_MACHINE_AM33                     0x01D3\n#define PECOFF_IMAGE_FILE_MACHINE_POWERPC                  0x01F0\n#define PECOFF_IMAGE_FILE_MACHINE_POWERPCFP                0x01F1\n#define PECOFF_IMAGE_FILE_MACHINE_IA64                     0x0200\n#define PECOFF_IMAGE_FILE_MACHINE_MIPS16                   0x0266\n#define PECOFF_IMAGE_FILE_MACHINE_ALPHA64                  0x0284\n#define PECOFF_IMAGE_FILE_MACHINE_MIPSFPU                  0x0366\n#define PECOFF_IMAGE_FILE_MACHINE_MIPSFPU16                0x0466\n#define PECOFF_IMAGE_FILE_MACHINE_AXP64                    0x0284\n#define PECOFF_IMAGE_FILE_MACHINE_TRICORE                  0x0520\n#define PECOFF_IMAGE_FILE_MACHINE_CEF                      0x0CEF\n#define PECOFF_IMAGE_FILE_MACHINE_EBC                      0x0EBC\n#define PECOFF_IMAGE_FILE_MACHINE_AMD64                    0x8664\n#define PECOFF_IMAGE_FILE_MACHINE_M32R                     0x9041\n#define PECOFF_IMAGE_FILE_MACHINE_CEE                      0xC0EE\n\n/* PE/COFF image characteristic attributes */\n#define PECOFF_IMAGE_FILE_RELOCS_STRIPPED                  0x0001\n#define PECOFF_IMAGE_FILE_EXECUTABLE_IMAGE                 0x0002\n#define PECOFF_IMAGE_FILE_LINE_NUMS_STRIPPED               0x0004\n#define PECOFF_IMAGE_FILE_LOCAL_SYMS_STRIPPED              0x0008\n#define PECOFF_IMAGE_FILE_AGGRESIVE_WS_TRIM                0x0010\n#define PECOFF_IMAGE_FILE_LARGE_ADDRESS_AWARE              0x0020\n#define PECOFF_IMAGE_FILE_BYTES_REVERSED_LO                0x0080\n#define PECOFF_IMAGE_FILE_32BIT_MACHINE                    0x0100\n#define PECOFF_IMAGE_FILE_DEBUG_STRIPPED                   0x0200\n#define PECOFF_IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP          0x0400\n#define PECOFF_IMAGE_FILE_NET_RUN_FROM_SWAP                0x0800\n#define PECOFF_IMAGE_FILE_SYSTEM                           0x1000\n#define PECOFF_IMAGE_FILE_DLL                              0x2000\n#define PECOFF_IMAGE_FILE_UP_SYSTEM_ONLY                   0x4000\n#define PECOFF_IMAGE_FILE_BYTES_REVERSED_HI                0x8000\n\n/* PE/COFF directory entries count */\n#define PECOFF_IMAGE_NUMBEROF_DIRECTORY_ENTRIES            16\n\n/* PE/COFF image HDR magic */\n#define PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC               0x10B\n#define PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC               0x20B\n#define PECOFF_IMAGE_ROM_OPTIONAL_HDR_MAGIC                0x107\n\n/* PE/COFF image characteristics */\n#define PECOFF_IMAGE_CHARACTERISTICS_HIGH_ENTROPY_VA       0x0020\n#define PECOFF_IMAGE_CHARACTERISTICS_DYNAMIC_BASE          0x0040\n#define PECOFF_IMAGE_CHARACTERISTICS_FORCE_INTEGRITY       0x0080\n#define PECOFF_IMAGE_CHARACTERISTICS_NX_COMPAT             0x0100\n#define PECOFF_IMAGE_CHARACTERISTICS_NO_ISOLATION          0x0200\n#define PECOFF_IMAGE_CHARACTERISTICS_NO_SEH                0x0400\n#define PECOFF_IMAGE_CHARACTERISTICS_NO_BIND               0x0800\n#define PECOFF_IMAGE_CHARACTERISTICS_APPCONTAINER          0x1000\n#define PECOFF_IMAGE_CHARACTERISTICS_WDM_DRIVER            0x2000\n#define PECOFF_IMAGE_CHARACTERISTICS_GUARD_CF              0x4000\n#define PECOFF_IMAGE_CHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000\n\n/* PE/COFF directory entries */\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_EXPORT                0x0\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_IMPORT                0x1\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_RESOURCE              0x2\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_EXCEPTION             0x3\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_SECURITY              0x4\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_BASERELOC             0x5\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_DEBUG                 0x6\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_ARCHITECTURE          0x7\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_GLOBALPTR             0x8\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_TLS                   0x9\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG           0xA\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT          0xB\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_IAT                   0xC\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT          0xD\n#define PECOFF_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR        0xE\n\n/* PE/COFF image relocation types */\n#define PECOFF_IMAGE_REL_BASED_ABSOLUTE                    0x0\n#define PECOFF_IMAGE_REL_BASED_HIGH                        0x1\n#define PECOFF_IMAGE_REL_BASED_LOW                         0x2\n#define PECOFF_IMAGE_REL_BASED_HIGHLOW                     0x3\n#define PECOFF_IMAGE_REL_BASED_HIGHADJ                     0x4\n#define PECOFF_IMAGE_REL_BASED_MIPS_JMPADDR                0x5\n#define PECOFF_IMAGE_REL_BASED_SECTION                     0x6\n#define PECOFF_IMAGE_REL_BASED_REL32                       0x7\n#define PECOFF_IMAGE_REL_BASED_VXD_RELATIVE                0x8\n#define PECOFF_IMAGE_REL_BASED_MIPS_JMPADDR16              0x9\n#define PECOFF_IMAGE_REL_BASED_IA64_IMM64                  0x9\n#define PECOFF_IMAGE_REL_BASED_DIR64                       0xA\n\n/* PE/COFF related sizes */\n#define PECOFF_IMAGE_SIZEOF_SHORT_NAME                     8\n#define PECOFF_IMAGE_SIZEOF_BASE_RELOCATION                8\n#define PECOFF_IMAGE_SIZEOF_SECTION_HEADER                 40\n#define PECOFF_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER            56\n#define PECOFF_IMAGE_SIZEOF_STD_OPTIONAL_HEADER            28\n#define PECOFF_IMAGE_SIZEOF_PE_OPTIONAL32_HEADER           224\n#define PECOFF_IMAGE_SIZEOF_PE_OPTIONAL64_HEADER           240\n\n/* PE/COFF image section characteristics */\n#define PECOFF_IMAGE_SCN_TYPE_REG                          0x00000000\n#define PECOFF_IMAGE_SCN_TYPE_DSECT                        0x00000001\n#define PECOFF_IMAGE_SCN_TYPE_NOLOAD                       0x00000002\n#define PECOFF_IMAGE_SCN_TYPE_GROUP                        0x00000004\n#define PECOFF_IMAGE_SCN_TYPE_NO_PAD                       0x00000008\n#define PECOFF_IMAGE_SCN_TYPE_COPY                         0x00000010\n#define PECOFF_IMAGE_SCN_CNT_CODE                          0x00000020\n#define PECOFF_IMAGE_SCN_CNT_INITIALIZED_DATA              0x00000040\n#define PECOFF_IMAGE_SCN_CNT_UNINITIALIZED_DATA            0x00000080\n#define PECOFF_IMAGE_SCN_LNK_OTHER                         0x00000100\n#define PECOFF_IMAGE_SCN_LNK_INFO                          0x00000200\n#define PECOFF_IMAGE_SCN_TYPE_OVER                         0x00000400\n#define PECOFF_IMAGE_SCN_LNK_REMOVE                        0x00000800\n#define PECOFF_IMAGE_SCN_LNK_COMDAT                        0x00001000\n#define PECOFF_IMAGE_SCN_NO_DEFER_SPEC_EXC                 0x00004000\n#define PECOFF_IMAGE_SCN_GPREL                             0x00008000\n#define PECOFF_IMAGE_SCN_MEM_FARDATA                       0x00008000\n#define PECOFF_IMAGE_SCN_MEM_PURGEABLE                     0x00020000\n#define PECOFF_IMAGE_SCN_MEM_16BIT                         0x00020000\n#define PECOFF_IMAGE_SCN_MEM_LOCKED                        0x00040000\n#define PECOFF_IMAGE_SCN_MEM_PRELOAD                       0x00080000\n#define PECOFF_IMAGE_SCN_ALIGN_1BYTES                      0x00100000\n#define PECOFF_IMAGE_SCN_ALIGN_2BYTES                      0x00200000\n#define PECOFF_IMAGE_SCN_ALIGN_4BYTES                      0x00300000\n#define PECOFF_IMAGE_SCN_ALIGN_8BYTES                      0x00400000\n#define PECOFF_IMAGE_SCN_ALIGN_16BYTES                     0x00500000\n#define PECOFF_IMAGE_SCN_ALIGN_32BYTES                     0x00600000\n#define PECOFF_IMAGE_SCN_ALIGN_64BYTES                     0x00700000\n#define PECOFF_IMAGE_SCN_ALIGN_128BYTES                    0x00800000\n#define PECOFF_IMAGE_SCN_ALIGN_256BYTES                    0x00900000\n#define PECOFF_IMAGE_SCN_ALIGN_512BYTES                    0x00A00000\n#define PECOFF_IMAGE_SCN_ALIGN_1024BYTES                   0x00B00000\n#define PECOFF_IMAGE_SCN_ALIGN_2048BYTES                   0x00C00000\n#define PECOFF_IMAGE_SCN_ALIGN_4096BYTES                   0x00D00000\n#define PECOFF_IMAGE_SCN_ALIGN_8192BYTES                   0x00E00000\n#define PECOFF_IMAGE_SCN_ALIGN_MASK                        0x00F00000\n#define PECOFF_IMAGE_SCN_LNK_NRELOC_OVFL                   0x01000000\n#define PECOFF_IMAGE_SCN_MEM_DISCARDABLE                   0x02000000\n#define PECOFF_IMAGE_SCN_MEM_NOT_CACHED                    0x04000000\n#define PECOFF_IMAGE_SCN_MEM_NOT_PAGED                     0x08000000\n#define PECOFF_IMAGE_SCN_MEM_SHARED                        0x10000000\n#define PECOFF_IMAGE_SCN_MEM_EXECUTE                       0x20000000\n#define PECOFF_IMAGE_SCN_MEM_READ                          0x40000000\n#define PECOFF_IMAGE_SCN_MEM_WRITE                         0x80000000\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* PE/COFF image representation structure */\ntypedef struct _PECOFF_IMAGE_CONTEXT\n{\n    PPECOFF_IMAGE_DOS_HEADER DosHeader;\n    PPECOFF_IMAGE_PE_HEADER PeHeader;\n    PVOID Data;\n    UINT64 FileSize;\n    UINT ImagePages;\n    UINT ImageSize;\n    LOADER_MEMORY_TYPE MemoryType;\n    PVOID PhysicalAddress;\n    PVOID VirtualAddress;\n} PECOFF_IMAGE_CONTEXT, *PPECOFF_IMAGE_CONTEXT;\n\n/* PE/COFF directory format */\ntypedef struct _PECOFF_IMAGE_DATA_DIRECTORY\n{\n    ULONG VirtualAddress;\n    ULONG Size;\n} PECOFF_IMAGE_DATA_DIRECTORY, *PPECOFF_IMAGE_DATA_DIRECTORY;\n\n/* PE file image header */\ntypedef struct _PECOFF_IMAGE_FILE_HEADER\n{\n    USHORT Machine;\n    USHORT NumberOfSections;\n    ULONG TimeDateStamp;\n    ULONG PointerToSymbolTable;\n    ULONG NumberOfSymbols;\n    USHORT SizeOfOptionalHeader;\n    USHORT Characteristics;\n} PECOFF_IMAGE_FILE_HEADER, *PPECOFF_IMAGE_FILE_HEADER;\n\n/* DOS PE image header */\ntypedef struct _PECOFF_IMAGE_DOS_HEADER\n{\n    USHORT Magic;\n    USHORT LastPageBytes;\n    USHORT ImagePages;\n    USHORT Relocations;\n    USHORT HeaderParagraphs;\n    USHORT MinExtraParagraphs;\n    USHORT MaxExtraParagraphs;\n    USHORT InitialSS;\n    USHORT InitialSP;\n    USHORT Checksum;\n    USHORT InitialIP;\n    USHORT InitialCS;\n    USHORT RelocationTableOffset;\n    USHORT OverlayNumber;\n    USHORT Reserved1[4];\n    USHORT OemIdentification;\n    USHORT OemInformation;\n    USHORT Reserved2[10];\n    LONG PeHeaderOffset;\n} PECOFF_IMAGE_DOS_HEADER, *PPECOFF_IMAGE_DOS_HEADER;\n\n/* OS/2 PE image header */\ntypedef struct _PECOFF_IMAGE_OS2_HEADER\n{\n    USHORT Magic;\n    CHAR MajorVersion;\n    CHAR MinorVersion;\n    USHORT EntryTableOffset;\n    USHORT EntryTableLength;\n    LONG FileLoadCRC;\n    UCHAR ProgFlags;\n    UCHAR ApplFlags;\n    USHORT AutoDataSegIndex;\n    USHORT InitHeapSize;\n    USHORT InitStackSize;\n    LONG EntryPoint;\n    LONG InitStack;\n    USHORT SegCount;\n    USHORT ModRefs;\n    USHORT NoResNamesTabSiz;\n    USHORT SegTableOffset;\n    USHORT ResTableOffset;\n    USHORT ResidNamTable;\n    USHORT ModRefTable;\n    USHORT ImportNameTable;\n    LONG NonResTabableOffset;\n    USHORT MovEntryCount;\n    USHORT ImageAlignment;\n    USHORT ResTableEntries;\n    UCHAR ImageType;\n    UCHAR ImageFlags;\n    USHORT ReturnThunkOffset;\n    USHORT ReferenceThunksOffset;\n    USHORT SwapArea;\n    USHORT WindowsVersion;\n} PECOFF_IMAGE_OS2_HEADER, *PPECOFF_IMAGE_OS2_HEADER;\n\n/* Windows VXD PE image header */\ntypedef struct _PECOFF_IMAGE_VXD_HEADER\n{\n    USHORT Magic;\n    UCHAR BytesOrder;\n    UCHAR WordsOrder;\n    ULONG FormatLevel;\n    USHORT CpuType;\n    USHORT OSType;\n    ULONG ModuleVersion;\n    ULONG ModuleFlags;\n    ULONG ModulePages;\n    ULONG EntryPoint;\n    ULONG Eip;\n    ULONG Stack;\n    ULONG Esp;\n    ULONG PageSize;\n    ULONG LastPageSize;\n    ULONG FixupSectionSize;\n    ULONG FixupSectionChecksum;\n    ULONG LoaderSectionSize;\n    ULONG LoaderSectionChecksum;\n    ULONG ObjectTableOffset;\n    ULONG NumberOfObjects;\n    ULONG ObjectPageMapOffset;\n    ULONG ObjectIterMapOffset;\n    ULONG ResTableOffset;\n    ULONG NumberOfResources;\n    ULONG ResidentTableOffset;\n    ULONG EntryTableOffset;\n    ULONG DirectiveTableOffset;\n    ULONG NumberOfDirectives;\n    ULONG FixupPageTableOffset;\n    ULONG FixupRecordTableOffset;\n    ULONG ImportTableOffset;\n    ULONG NumberOfImports;\n    ULONG ImportProcTableOffset;\n    ULONG PageChecksumTableOffset;\n    ULONG DataPagesOffset;\n    ULONG NumberOfPreloadPages;\n    ULONG NonResidentTableOffset;\n    ULONG NonResidentTableSize;\n    ULONG NonResidentTableChecksum;\n    ULONG AutoDataObject;\n    ULONG DebugInfoOffset;\n    ULONG DebugInfoLength;\n    ULONG PreLoadSectionPages;\n    ULONG DemandLoadSectionPages;\n    ULONG HeapSize;\n    UCHAR Reserved[12];\n    ULONG WinResOffset;\n    ULONG WinResLength;\n    USHORT DeviceId;\n    USHORT DDKVersion;\n} PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER;\n\n/* PE/COFF section header */\ntypedef struct _PECOFF_IMAGE_SECTION_HEADER\n{\n    UCHAR Name[PECOFF_IMAGE_SIZEOF_SHORT_NAME];\n    union\n    {\n            ULONG PhysicalAddress;\n            ULONG VirtualSize;\n    } Misc;\n    ULONG VirtualAddress;\n    ULONG SizeOfRawData;\n    ULONG PointerToRawData;\n    ULONG PointerToRelocations;\n    ULONG PointerToLinenumbers;\n    USHORT NumberOfRelocations;\n    USHORT NumberOfLinenumbers;\n    ULONG Characteristics;\n} PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER;\n\n/* PE/COFF image 32bit optional header */\ntypedef struct _PECOFF_IMAGE_OPTIONAL_HEADER32\n{\n    USHORT Magic;\n    UCHAR MajorLinkerVersion;\n    UCHAR MinorLinkerVersion;\n    ULONG SizeOfCode;\n    ULONG SizeOfInitializedData;\n    ULONG SizeOfUninitializedData;\n    ULONG AddressOfEntryPoint;\n    ULONG BaseOfCode;\n    ULONG BaseOfData;\n    ULONG ImageBase;\n    ULONG SectionAlignment;\n    ULONG FileAlignment;\n    USHORT MajorOperatingSystemVersion;\n    USHORT MinorOperatingSystemVersion;\n    USHORT MajorImageVersion;\n    USHORT MinorImageVersion;\n    USHORT MajorSubsystemVersion;\n    USHORT MinorSubsystemVersion;\n    ULONG Win32VersionValue;\n    ULONG SizeOfImage;\n    ULONG SizeOfHeaders;\n    ULONG CheckSum;\n    USHORT Subsystem;\n    USHORT DllCharacteristics;\n    ULONG SizeOfStackReserve;\n    ULONG SizeOfStackCommit;\n    ULONG SizeOfHeapReserve;\n    ULONG SizeOfHeapCommit;\n    ULONG LoaderFlags;\n    ULONG NumberOfRvaAndSizes;\n    PECOFF_IMAGE_DATA_DIRECTORY DataDirectory[PECOFF_IMAGE_NUMBEROF_DIRECTORY_ENTRIES];\n} PECOFF_IMAGE_OPTIONAL_HEADER32, *PPECOFF_IMAGE_OPTIONAL_HEADER32;\n\n/* PE/COFF image 32bit optional header */\ntypedef struct _PECOFF_IMAGE_OPTIONAL_HEADER64\n{\n    USHORT Magic;\n    UCHAR MajorLinkerVersion;\n    UCHAR MinorLinkerVersion;\n    ULONG SizeOfCode;\n    ULONG SizeOfInitializedData;\n    ULONG SizeOfUninitializedData;\n    ULONG AddressOfEntryPoint;\n    ULONG BaseOfCode;\n    ULONGLONG ImageBase;\n    ULONG SectionAlignment;\n    ULONG FileAlignment;\n    USHORT MajorOperatingSystemVersion;\n    USHORT MinorOperatingSystemVersion;\n    USHORT MajorImageVersion;\n    USHORT MinorImageVersion;\n    USHORT MajorSubsystemVersion;\n    USHORT MinorSubsystemVersion;\n    ULONG Win32VersionValue;\n    ULONG SizeOfImage;\n    ULONG SizeOfHeaders;\n    ULONG CheckSum;\n    USHORT Subsystem;\n    USHORT DllCharacteristics;\n    ULONGLONG SizeOfStackReserve;\n    ULONGLONG SizeOfStackCommit;\n    ULONGLONG SizeOfHeapReserve;\n    ULONGLONG SizeOfHeapCommit;\n    ULONG LoaderFlags;\n    ULONG NumberOfRvaAndSizes;\n    PECOFF_IMAGE_DATA_DIRECTORY DataDirectory[PECOFF_IMAGE_NUMBEROF_DIRECTORY_ENTRIES];\n} PECOFF_IMAGE_OPTIONAL_HEADER64, *PPECOFF_IMAGE_OPTIONAL_HEADER64;\n\n/* PE/COFF ROM optional header */\ntypedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER\n{\n    USHORT Magic;\n    UCHAR MajorLinkerVersion;\n    UCHAR MinorLinkerVersion;\n    ULONG SizeOfCode;\n    ULONG SizeOfInitializedData;\n    ULONG SizeOfUninitializedData;\n    ULONG AddressOfEntryPoint;\n    ULONG BaseOfCode;\n    ULONG BaseOfData;\n    ULONG BaseOfBss;\n    ULONG GprMask;\n    ULONG CprMask[4];\n    ULONG GpValue;\n} PECOFF_IMAGE_ROM_OPTIONAL_HEADER, *PPECOFF_IMAGE_ROM_OPTIONAL_HEADER;\n\n/* PE/COFF PE image header */\ntypedef struct _PECOFF_IMAGE_PE_HEADER\n{\n    ULONG Signature;\n    PECOFF_IMAGE_FILE_HEADER FileHeader;\n    union\n    {\n        PECOFF_IMAGE_OPTIONAL_HEADER32 OptionalHeader32;\n        PECOFF_IMAGE_OPTIONAL_HEADER64 OptionalHeader64;\n    };\n} PECOFF_IMAGE_PE_HEADER, *PPECOFF_IMAGE_PE_HEADER;\n\n/* PE/COFF ROM image header */\ntypedef struct _PECOFF_IMAGE_ROM_HEADER {\n    PECOFF_IMAGE_FILE_HEADER FileHeader;\n    PECOFF_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;\n} PECOFF_IMAGE_ROM_HEADER, *PPECOFF_IMAGE_ROM_HEADER;\n\n/* PE/COFF based relocation format */\ntypedef struct _PECOFF_IMAGE_BASE_RELOCATION\n{\n    ULONG VirtualAddress;\n    ULONG SizeOfBlock;\n} PECOFF_IMAGE_BASE_RELOCATION, *PPECOFF_IMAGE_BASE_RELOCATION;\n\n/* PE/COFF image load config code integrity */\ntypedef struct _PECOFF_IMAGE_LOAD_CONFIG_CODE_INTEGRITY\n{\n    USHORT Flags;\n    USHORT Catalog;\n    ULONG CatalogOffset;\n    ULONG Reserved;\n} PECOFF_IMAGE_LOAD_CONFIG_CODE_INTEGRITY, *PPECOFF_IMAGE_LOAD_CONFIG_CODE_INTEGRITY;\n\n/* 32-bit load configuration directory */\ntypedef struct _PECOFF_IMAGE_LOAD_CONFIG_DIRECTORY32\n{\n    ULONG Size;\n    ULONG TimeDateStamp;\n    USHORT MajorVersion;\n    USHORT MinorVersion;\n    ULONG GlobalFlagsClear;\n    ULONG GlobalFlagsSet;\n    ULONG CriticalSectionDefaultTimeout;\n    ULONG DeCommitFreeBlockThreshold;\n    ULONG DeCommitTotalFreeThreshold;\n    ULONG LockPrefixTable;\n    ULONG MaximumAllocationSize;\n    ULONG VirtualMemoryThreshold;\n    ULONG ProcessHeapFlags;\n    ULONG ProcessAffinityMask;\n    USHORT CSDVersion;\n    USHORT Reserved1;\n    ULONG EditList;\n    ULONG SecurityCookie;\n    ULONG SEHandlerTable;\n    ULONG SEHandlerCount;\n} PECOFF_IMAGE_LOAD_CONFIG_DIRECTORY32, *PPECOFF_IMAGE_LOAD_CONFIG_DIRECTORY32;\n\n/* 64-bit load configuration directory */\ntypedef struct _PECOFF_IMAGE_LOAD_CONFIG_DIRECTORY64\n{\n    ULONG Size;\n    ULONG TimeDateStamp;\n    USHORT MajorVersion;\n    USHORT MinorVersion;\n    ULONG GlobalFlagsClear;\n    ULONG GlobalFlagsSet;\n    ULONG CriticalSectionDefaultTimeout;\n    ULONGLONG DeCommitFreeBlockThreshold;\n    ULONGLONG DeCommitTotalFreeThreshold;\n    ULONGLONG LockPrefixTable;\n    ULONGLONG MaximumAllocationSize;\n    ULONGLONG VirtualMemoryThreshold;\n    ULONGLONG ProcessAffinityMask;\n    ULONG ProcessHeapFlags;\n    USHORT CSDVersion;\n    USHORT DependentLoadFlags;\n    ULONGLONG EditList;\n    ULONGLONG SecurityCookie;\n    ULONGLONG SEHandlerTable;\n    ULONGLONG SEHandlerCount;\n    ULONGLONG GuardCFCheckFunctionPointer;\n    ULONGLONG GuardCFDispatchFunctionPointer;\n    ULONGLONG GuardCFFunctionTable;\n    ULONGLONG GuardCFFunctionCount;\n    ULONG GuardFlags;\n    PECOFF_IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;\n    ULONGLONG GuardAddressTakenIatEntryTable;\n    ULONGLONG GuardAddressTakenIatEntryCount;\n    ULONGLONG GuardLongJumpTargetTable;\n    ULONGLONG GuardLongJumpTargetCount;\n    ULONGLONG DynamicValueRelocTable;\n    ULONGLONG CHPEMetadataPointer;\n    ULONGLONG GuardRFFailureRoutine;\n    ULONGLONG GuardRFFailureRoutineFunctionPointer;\n    ULONG DynamicValueRelocTableOffset;\n    USHORT DynamicValueRelocTableSection;\n    USHORT Reserved2;\n    ULONGLONG GuardRFVerifyStackPointerFunctionPointer;\n    ULONG HotPatchTableOffset;\n    ULONG Reserved3;\n    ULONGLONG EnclaveConfigurationPointer;\n    ULONGLONG VolatileMetadataPointer;\n} PECOFF_IMAGE_LOAD_CONFIG_DIRECTORY64, *PPECOFF_IMAGE_LOAD_CONFIG_DIRECTORY64;\n\n/* PE/COFF image import descriptor */\ntypedef struct _PECOFF_IMAGE_IMPORT_DESCRIPTOR\n{\n    union\n    {\n        ULONG Characteristics;\n        ULONG OriginalFirstThunk;\n    };\n    ULONG TimeDateStamp;\n    ULONG ForwarderChain;\n    ULONG Name;\n    ULONG FirstThunk;\n} PECOFF_IMAGE_IMPORT_DESCRIPTOR, *PPECOFF_IMAGE_IMPORT_DESCRIPTOR;\n\n/* PE/COFF image export directory */\ntypedef struct _PECOFF_IMAGE_EXPORT_DIRECTORY\n{\n    ULONG Characteristics;\n    ULONG TimeDateStamp;\n    USHORT MajorVersion;\n    USHORT MinorVersion;\n    ULONG Name;\n    ULONG Base;\n    ULONG NumberOfFunctions;\n    ULONG NumberOfNames;\n    ULONG AddressOfFunctions;\n    ULONG AddressOfNames;\n    ULONG AddressOfNameOrdinals;\n} PECOFF_IMAGE_EXPORT_DIRECTORY, *PPECOFF_IMAGE_EXPORT_DIRECTORY;\n\n/* PE/COFF image resource directory */\ntypedef struct _PECOFF_IMAGE_RESOURCE_DIRECTORY\n{\n    ULONG Characteristics;\n    ULONG TimeDateStamp;\n    USHORT MajorVersion;\n    USHORT MinorVersion;\n    USHORT NumberOfNamedEntries;\n    USHORT NumberOfIdEntries;\n} PECOFF_IMAGE_RESOURCE_DIRECTORY, *PPECOFF_IMAGE_RESOURCE_DIRECTORY;\n\n/* PE/COFF image resource directory entry */\ntypedef struct _PECOFF_IMAGE_RESOURCE_DIRECTORY_ENTRY\n{\n    union\n    {\n        struct\n        {\n            ULONG NameOffset:31;\n            ULONG NameIsString:1;\n        };\n        ULONG Name;\n        USHORT Id;\n    };\n    union\n    {\n        ULONG OffsetToData;\n        struct {\n            ULONG OffsetToDirectory:31;\n            ULONG DataIsDirectory:1;\n        };\n    };\n} PECOFF_IMAGE_RESOURCE_DIRECTORY_ENTRY, *PPECOFF_IMAGE_RESOURCE_DIRECTORY_ENTRY;\n\n/* PE/COFF image resource data entry */\ntypedef struct _PECOFF_IMAGE_RESOURCE_DATA_ENTRY\n{\n    ULONG OffsetToData;\n    ULONG Size;\n    ULONG CodePage;\n    ULONG Reserved;\n} PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_XTIMAGE_H */\n"
  },
  {
    "path": "sdk/xtdk/xtkmapi.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtkmapi.h\n * DESCRIPTION:     Top level header for the kernel-mode XT API\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n/* Base XT headers */\n#include <xtcompat.h>\n#include <xtdefs.h>\n#include <xtstatus.h>\n#include <xttarget.h>\n#include <xttypes.h>\n\n/* XT forward references */\n#include <xtstruct.h>\n\n/* Architecture-specific XT forward references */\n#include ARCH_HEADER(xtstruct.h)\n\n/* Architecture-independent XT API */\n#include <xtbase.h>\n#include <xtdebug.h>\n#include <xtguid.h>\n#include <xtfw.h>\n#include <xtimage.h>\n#include <xtuefi.h>\n\n/* Low level data types headers */\n#include <extypes.h>\n#include <hltypes.h>\n#include <iotypes.h>\n#include <kdtypes.h>\n#include <ketypes.h>\n#include <ldrtypes.h>\n#include <mmtypes.h>\n#include <potypes.h>\n#include <pstypes.h>\n#include <rtltypes.h>\n\n/* Architecture-specific low level data types headers */\n#include ARCH_HEADER(artypes.h)\n#include ARCH_HEADER(hltypes.h)\n#include ARCH_HEADER(ketypes.h)\n#include ARCH_HEADER(mmtypes.h)\n\n/* XT routines */\n#include <exfuncs.h>\n#include <hlfuncs.h>\n#include <kdfuncs.h>\n#include <kefuncs.h>\n#include <mmfuncs.h>\n#include <rtlfuncs.h>\n\n/* Architecture specific XT routines */\n#include ARCH_HEADER(hlfuncs.h)\n"
  },
  {
    "path": "sdk/xtdk/xtstatus.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtstatus.h\n * DESCRIPTION:     Status code definitions for the XT API\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTSTATUS_H\n#define __XTDK_XTSTATUS_H\n\n\n/* EFI status code definitions */\n#define STATUS_EFI_SUCCESS                                                 (EFI_ERROR_MASK & 0x00)\n#define STATUS_EFI_LOAD_ERROR                                              (EFI_ERROR_MASK | 0x01)\n#define STATUS_EFI_INVALID_PARAMETER                                       (EFI_ERROR_MASK | 0x02)\n#define STATUS_EFI_UNSUPPORTED                                             (EFI_ERROR_MASK | 0x03)\n#define STATUS_EFI_BAD_BUFFER_SIZE                                         (EFI_ERROR_MASK | 0x04)\n#define STATUS_EFI_BUFFER_TOO_SMALL                                        (EFI_ERROR_MASK | 0x05)\n#define STATUS_EFI_NOT_READY                                               (EFI_ERROR_MASK | 0x06)\n#define STATUS_EFI_DEVICE_ERROR                                            (EFI_ERROR_MASK | 0x07)\n#define STATUS_EFI_WRITE_PROTECTED                                         (EFI_ERROR_MASK | 0x08)\n#define STATUS_EFI_OUT_OF_RESOURCES                                        (EFI_ERROR_MASK | 0x09)\n#define STATUS_EFI_VOLUME_CORRUPTED                                        (EFI_ERROR_MASK | 0x0A)\n#define STATUS_EFI_VOLUME_FULL                                             (EFI_ERROR_MASK | 0x0B)\n#define STATUS_EFI_NO_MEDIA                                                (EFI_ERROR_MASK | 0x0C)\n#define STATUS_EFI_MEDIA_CHANGED                                           (EFI_ERROR_MASK | 0x0D)\n#define STATUS_EFI_NOT_FOUND                                               (EFI_ERROR_MASK | 0x0E)\n#define STATUS_EFI_ACCESS_DENIED                                           (EFI_ERROR_MASK | 0x0F)\n#define STATUS_EFI_NO_RESPONSE                                             (EFI_ERROR_MASK | 0x10)\n#define STATUS_EFI_NO_MAPPING                                              (EFI_ERROR_MASK | 0x11)\n#define STATUS_EFI_TIMEOUT                                                 (EFI_ERROR_MASK | 0x12)\n#define STATUS_EFI_NOT_STARTED                                             (EFI_ERROR_MASK | 0x13)\n#define STATUS_EFI_ALREADY_STARTED                                         (EFI_ERROR_MASK | 0x14)\n#define STATUS_EFI_ABORTED                                                 (EFI_ERROR_MASK | 0x15)\n#define STATUS_EFI_ICMP_ERROR                                              (EFI_ERROR_MASK | 0x16)\n#define STATUS_EFI_TFTP_ERROR                                              (EFI_ERROR_MASK | 0x17)\n#define STATUS_EFI_PROTOCOL_ERROR                                          (EFI_ERROR_MASK | 0x18)\n#define STATUS_EFI_INCOMPATIBLE_VERSION                                    (EFI_ERROR_MASK | 0x19)\n#define STATUS_EFI_SECURITY_VIOLATION                                      (EFI_ERROR_MASK | 0x1A)\n#define STATUS_EFI_CRC_ERROR                                               (EFI_ERROR_MASK | 0x1B)\n#define STATUS_EFI_END_OF_MEDIA                                            (EFI_ERROR_MASK | 0x1C)\n#define STATUS_EFI_END_OF_FILE                                             (EFI_ERROR_MASK | 0x1F)\n#define STATUS_EFI_INVALID_LANGUAGE                                        (EFI_ERROR_MASK | 0x20)\n#define STATUS_EFI_COMPROMISED_DATA                                        (EFI_ERROR_MASK | 0x21)\n#define STATUS_EFI_IP_ADDRESS_CONFLICT                                     (EFI_ERROR_MASK | 0x22)\n#define STATUS_EFI_HTTP_ERROR                                              (EFI_ERROR_MASK | 0x23)\n\n/* XT status code definitions */\n#define STATUS_SUCCESS                                                     ((XTSTATUS) 0x00000000L)\n#define STATUS_END_OF_MEDIA                                                ((XTSTATUS) 0x8000001EL)\n#define STATUS_RESOURCE_LOCKED                                             ((XTSTATUS) 0xC0000000L)\n#define STATUS_UNSUCCESSFUL                                                ((XTSTATUS) 0xC0000001L)\n#define STATUS_NOT_IMPLEMENTED                                             ((XTSTATUS) 0xC0000002L)\n#define STATUS_ACCESS_VIOLATION                                            ((XTSTATUS) 0xC0000005L)\n#define STATUS_IN_PAGE_ERROR                                               ((XTSTATUS) 0xC0000006L)\n#define STATUS_INVALID_HANDLE                                              ((XTSTATUS) 0xC0000008L)\n#define STATUS_BAD_INITIAL_STACK                                           ((XTSTATUS) 0xC0000009L)\n#define STATUS_INVALID_PARAMETER                                           ((XTSTATUS) 0xC000000DL)\n#define STATUS_END_OF_FILE                                                 ((XTSTATUS) 0xC0000011L)\n#define STATUS_NO_MEMORY                                                   ((XTSTATUS) 0xC0000017L)\n#define STATUS_PORT_DISCONNECTED                                           ((XTSTATUS) 0xC0000037L)\n#define STATUS_CRC_ERROR                                                   ((XTSTATUS) 0xC000003FL)\n#define STATUS_FLOAT_OVERFLOW                                              ((XTSTATUS) 0xC0000091L)\n#define STATUS_INTEGER_OVERFLOW                                            ((XTSTATUS) 0xC0000095L)\n#define STATUS_INSUFFICIENT_RESOURCES                                      ((XTSTATUS) 0xC000009AL)\n#define STATUS_DEVICE_NOT_READY                                            ((XTSTATUS) 0xC00000A3L)\n#define STATUS_NOT_SUPPORTED                                               ((XTSTATUS) 0xC00000BBL)\n#define STATUS_TIMEOUT                                                     ((XTSTATUS) 0x00000102L)\n#define STATUS_IO_DEVICE_ERROR                                             ((XTSTATUS) 0xC0000185L)\n#define STATUS_NOT_FOUND                                                   ((XTSTATUS) 0xC0000225L)\n\n#endif /* __XTDK_XTSTATUS_H */\n"
  },
  {
    "path": "sdk/xtdk/xtstruct.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtstruct.h\n * DESCRIPTION:     XT structures forward references\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTSTRUCT_H\n#define __XTDK_XTSTRUCT_H\n\n#include <xtdefs.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Enumeration lists forward references */\ntypedef enum _ADJUST_REASON ADJUST_REASON, *PADJUST_REASON;\ntypedef enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION, *PEXCEPTION_DISPOSITION;\ntypedef enum _EFI_ALLOCATE_TYPE EFI_ALLOCATE_TYPE, *PEFI_ALLOCATE_TYPE;\ntypedef enum _EFI_FRAMEWORK_CPU_DESIGNATION EFI_FRAMEWORK_CPU_DESIGNATION, *PEFI_FRAMEWORK_CPU_DESIGNATION;\ntypedef enum _EFI_GRAPHICS_OUTPUT_BLT_OPERATION EFI_GRAPHICS_OUTPUT_BLT_OPERATION, *PEFI_GRAPHICS_OUTPUT_BLT_OPERATION;\ntypedef enum _EFI_GRAPHICS_PIXEL_FORMAT EFI_GRAPHICS_PIXEL_FORMAT, *PEFI_GRAPHICS_PIXEL_FORMAT;\ntypedef enum _EFI_GRAPHICS_PROTOCOL EFI_GRAPHICS_PROTOCOL, *PEFI_GRAPHICS_PROTOCOL;\ntypedef enum _EFI_INTERFACE_TYPE EFI_INTERFACE_TYPE, *PEFI_INTERFACE_TYPE;\ntypedef enum _EFI_IO_OPERATION_TYPE EFI_IO_OPERATION_TYPE, *PEFI_IO_OPERATION_TYPE;\ntypedef enum _EFI_IO_WIDTH EFI_IO_WIDTH, *PEFI_IO_WIDTH;\ntypedef enum _EFI_LOCATE_SEARCH_TYPE EFI_LOCATE_SEARCH_TYPE, *PEFI_LOCATE_SEARCH_TYPE;\ntypedef enum _EFI_MEMORY_TYPE EFI_MEMORY_TYPE, *PEFI_MEMORY_TYPE;\ntypedef enum _EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION, *PEFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION;\ntypedef enum _EFI_PCI_IO_PROTOCOL_OPERATION EFI_PCI_IO_PROTOCOL_OPERATION, *PEFI_PCI_IO_PROTOCOL_OPERATION;\ntypedef enum _EFI_PCI_IO_PROTOCOL_WIDTH EFI_PCI_IO_PROTOCOL_WIDTH, *PEFI_PCI_IO_PROTOCOL_WIDTH;\ntypedef enum _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION, *PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION;\ntypedef enum _EFI_PXE_BASE_CODE_CALLBACK_STATUS EFI_PXE_BASE_CODE_CALLBACK_STATUS, *PEFI_PXE_BASE_CODE_CALLBACK_STATUS;\ntypedef enum _EFI_PXE_BASE_CODE_FUNCTION EFI_PXE_BASE_CODE_FUNCTION, *PEFI_PXE_BASE_CODE_FUNCTION;\ntypedef enum _EFI_PXE_BASE_CODE_TFTP_OPCODE EFI_PXE_BASE_CODE_TFTP_OPCODE, *PEFI_PXE_BASE_CODE_TFTP_OPCODE;\ntypedef enum _EFI_RESET_TYPE EFI_RESET_TYPE, *PEFI_RESET_TYPE;\ntypedef enum _EFI_SIMPLE_NETWORK_STATE EFI_SIMPLE_NETWORK_STATE, *PEFI_SIMPLE_NETWORK_STATE;\ntypedef enum _EFI_TIMER_DELAY EFI_TIMER_DELAY, *PEFI_TIMER_DELAY;\ntypedef enum _EFI_UART_PARITY_TYPE EFI_UART_PARITY_TYPE, *PEFI_UART_PARITY_TYPE;\ntypedef enum _EFI_UART_STOP_BITS_TYPE EFI_UART_STOP_BITS_TYPE, *PEFI_UART_STOP_BITS_TYPE;\ntypedef enum _EFI_UNIVERSA_GRAPHICS_BLT_OPERATION EFI_UNIVERSA_GRAPHICS_BLT_OPERATION, *PEFI_UNIVERSA_GRAPHICS_BLT_OPERATION;\ntypedef enum _HAL_APIC_MODE HAL_APIC_MODE, *PHAL_APIC_MODE;\ntypedef enum _KAPC_ENVIRONMENT KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;\ntypedef enum _KDPC_IMPORTANCE KDPC_IMPORTANCE, *PKDPC_IMPORTANCE;\ntypedef enum _KEVENT_TYPE KEVENT_TYPE, *PKEVENT_TYPE;\ntypedef enum _KOBJECTS KOBJECTS, *PKOBJECTS;\ntypedef enum _KPROCESS_STATE KPROCESS_STATE, *PKPROCESS_STATE;\ntypedef enum _KPROFILE_SOURCE KPROFILE_SOURCE, *PKPROFILE_SOURCE;\ntypedef enum _KTHREAD_STATE KTHREAD_STATE, *PKTHREAD_STATE;\ntypedef enum _KTIMER_TYPE KTIMER_TYPE, *PKTIMER_TYPE;\ntypedef enum _KUBSAN_DATA_TYPE KUBSAN_DATA_TYPE, *PKUBSAN_DATA_TYPE;\ntypedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;\ntypedef enum _MMPAGELISTS MMPAGELISTS, *PMMPAGELISTS;\ntypedef enum _MMPFN_CACHE_ATTRIBUTE MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBUTE;\ntypedef enum _MMPOOL_TYPE MMPOOL_TYPE, *PMMPOOL_TYPE;\ntypedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;\ntypedef enum _MODE MODE, *PMODE;\ntypedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;\ntypedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;\ntypedef enum _SYSTEM_RESOURCE_TYPE SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE;\ntypedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;\n\n/* Structures forward references */\ntypedef struct _ACPI_CACHE_LIST ACPI_CACHE_LIST, *PACPI_CACHE_LIST;\ntypedef struct _ACPI_DESCRIPTION_HEADER ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER;\ntypedef struct _ACPI_FADT ACPI_FADT, *PACPI_FADT;\ntypedef struct _ACPI_HPET ACPI_HPET, *PACPI_HPET;\ntypedef struct _ACPI_MADT ACPI_MADT, *PACPI_MADT;\ntypedef struct _ACPI_MADT_INTERRUPT_OVERRIDE ACPI_MADT_INTERRUPT_OVERRIDE, *PACPI_MADT_INTERRUPT_OVERRIDE;\ntypedef struct _ACPI_MADT_IOAPIC ACPI_MADT_IOAPIC, *PACPI_MADT_IOAPIC;\ntypedef struct _ACPI_MADT_LOCAL_APIC ACPI_MADT_LOCAL_APIC, *PACPI_MADT_LOCAL_APIC;\ntypedef struct _ACPI_MADT_LOCAL_X2APIC ACPI_MADT_LOCAL_X2APIC, *PACPI_MADT_LOCAL_X2APIC;\ntypedef struct _ACPI_RSDP ACPI_RSDP, *PACPI_RSDP;\ntypedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT;\ntypedef struct _ACPI_SUBTABLE_HEADER ACPI_SUBTABLE_HEADER, *PACPI_SUBTABLE_HEADER;\ntypedef struct _ACPI_SYSTEM_INFO ACPI_SYSTEM_INFO, *PACPI_SYSTEM_INFO;\ntypedef struct _ACPI_TIMER_INFO ACPI_TIMER_INFO, *PACPI_TIMER_INFO;\ntypedef struct _ACPI_XSDT ACPI_XSDT, *PACPI_XSDT;\ntypedef struct _ANSI_STRING ANSI_STRING, *PANSI_STRING;\ntypedef struct _ANSI_STRING32 ANSI_STRING32, *PANSI_STRING32;\ntypedef struct _ANSI_STRING64 ANSI_STRING64, *PANSI_STRING64;\ntypedef struct _CPPORT CPPORT, *PCPPORT;\ntypedef const struct _CMMPAGEMAP_ROUTINES CMMPAGEMAP_ROUTINES, *PCMMPAGEMAP_ROUTINES;\ntypedef struct _CSTRING CSTRING, *PCSTRING;\ntypedef struct _EFI_1394_DEVICE_PATH EFI_1394_DEVICE_PATH, *PEFI_1394_DEVICE_PATH;\ntypedef struct _EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR, *PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR;\ntypedef struct _EFI_ACPI_ADR_DEVICE_PATH EFI_ACPI_ADR_DEVICE_PATH, *PEFI_ACPI_ADR_DEVICE_PATH;\ntypedef struct _EFI_ACPI_HID_DEVICE_PATH EFI_ACPI_HID_DEVICE_PATH, *PEFI_ACPI_HID_DEVICE_PATH;\ntypedef struct _EFI_ATAPI_DEVICE_PATH EFI_ATAPI_DEVICE_PATH, *PEFI_ATAPI_DEVICE_PATH;\ntypedef struct _EFI_ATAPI_IDENTIFY EFI_ATAPI_IDENTIFY, *PEFI_ATAPI_IDENTIFY;\ntypedef struct _EFI_BBS_BBS_DEVICE_PATH EFI_BBS_BBS_DEVICE_PATH, *PEFI_BBS_BBS_DEVICE_PATH;\ntypedef struct _EFI_BBS_STATUS_FLAGS EFI_BBS_STATUS_FLAGS, *PEFI_BBS_STATUS_FLAGS;\ntypedef struct _EFI_BBS_TABLE EFI_BBS_TABLE, *PEFI_BBS_TABLE;\ntypedef struct _EFI_BLOCK_DEVICE EFI_BLOCK_DEVICE, *PEFI_BLOCK_DEVICE;\ntypedef struct _EFI_BLOCK_DEVICE_DATA EFI_BLOCK_DEVICE_DATA, *PEFI_BLOCK_DEVICE_DATA;\ntypedef struct _EFI_BLOCK_IO_MEDIA EFI_BLOCK_IO_MEDIA, *PEFI_BLOCK_IO_MEDIA;\ntypedef struct _EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO_PROTOCOL, *PEFI_BLOCK_IO_PROTOCOL;\ntypedef struct _EFI_BLOCK_IO2_PROTOCOL EFI_BLOCK_IO2_PROTOCOL, *PEFI_BLOCK_IO2_PROTOCOL;\ntypedef struct _EFI_BLOCK_IO2_TOKEN EFI_BLOCK_IO2_TOKEN, *PEFI_BLOCK_IO2_TOKEN;\ntypedef struct _EFI_BOOT_SERVICES EFI_BOOT_SERVICES, *PEFI_BOOT_SERVICES;\ntypedef struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL, *PEFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL;\ntypedef struct _EFI_BYTE_REGS EFI_BYTE_REGS, *PEFI_BYTE_REGS;\ntypedef struct _EFI_CAPSULE_BLOCK_DESCRIPTOR EFI_CAPSULE_BLOCK_DESCRIPTOR, *PEFI_CAPSULE_BLOCK_DESCRIPTOR;\ntypedef struct _EFI_CAPSULE_HEADER EFI_CAPSULE_HEADER, *PEFI_CAPSULE_HEADER;\ntypedef struct _EFI_CDROM_DEVICE_PATH EFI_CDROM_DEVICE_PATH, *PEFI_CDROM_DEVICE_PATH;\ntypedef struct _EFI_COMPONENT_NAME_PROTOCOL EFI_COMPONENT_NAME_PROTOCOL, *PEFI_COMPONENT_NAME_PROTOCOL;\ntypedef struct _EFI_COMPONENT_NAME2_PROTOCOL EFI_COMPONENT_NAME2_PROTOCOL, *PEFI_COMPONENT_NAME2_PROTOCOL;\ntypedef struct _EFI_CONFIGURATION_TABLE EFI_CONFIGURATION_TABLE, *PEFI_CONFIGURATION_TABLE;\ntypedef struct _EFI_CONTROLLER_DEVICE_PATH EFI_CONTROLLER_DEVICE_PATH, *PEFI_CONTROLLER_DEVICE_PATH;\ntypedef struct _EFI_DEVICE_IO_PROTOCOL EFI_DEVICE_IO_PROTOCOL, *PEFI_DEVICE_IO_PROTOCOL;\ntypedef struct _EFI_DEVICE_LOGICAL_UNIT_DEVICE_PATH EFI_DEVICE_LOGICAL_UNIT_DEVICE_PATH, *PEFI_DEVICE_LOGICAL_UNIT_DEVICE_PATH;\ntypedef struct _EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL, *PEFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;\ntypedef struct _EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL, *PEFI_DEVICE_PATH_PROTOCOL;\ntypedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL EFI_DEVICE_PATH_TO_TEXT_PROTOCOL, *PEFI_DEVICE_PATH_TO_TEXT_PROTOCOL;\ntypedef struct _EFI_DEVICE_PATH_UTILITIES_PROTOCOL EFI_DEVICE_PATH_UTILITIES_PROTOCOL, *PEFI_DEVICE_PATH_UTILITIES_PROTOCOL;\ntypedef struct _EFI_DISK_IO_PROTOCOL EFI_DISK_IO_PROTOCOL, *PEFI_DISK_IO_PROTOCOL;\ntypedef struct _EFI_DISK_IO2_PROTOCOL EFI_DISK_IO2_PROTOCOL, *PEFI_DISK_IO2_PROTOCOL;\ntypedef struct _EFI_DISK_IO2_TOKEN EFI_DISK_IO2_TOKEN, *PEFI_DISK_IO2_TOKEN;\ntypedef struct _EFI_DRIVER_BINDING_PROTOCOL EFI_DRIVER_BINDING_PROTOCOL, *PEFI_DRIVER_BINDING_PROTOCOL;\ntypedef struct _EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL, *PEFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL;\ntypedef struct _EFI_DWORD_REGS EFI_DWORD_REGS, *PEFI_DWORD_REGS;\ntypedef struct _EFI_EBC_PROTOCOL EFI_EBC_PROTOCOL, *PEFI_EBC_PROTOCOL;\ntypedef struct _EFI_EDID_ACTIVE_PROTOCOL EFI_EDID_ACTIVE_PROTOCOL, *PEFI_EDID_ACTIVE_PROTOCOL;\ntypedef struct _EFI_EDID_DISCOVERED_PROTOCOL EFI_EDID_DISCOVERED_PROTOCOL, *PEFI_EDID_DISCOVERED_PROTOCOL;\ntypedef struct _EFI_EDID_OVERRIDE_PROTOCOL EFI_EDID_OVERRIDE_PROTOCOL, *PEFI_EDID_OVERRIDE_PROTOCOL;\ntypedef struct _EFI_EFLAGS_REG EFLAGS_REG, *PEFI_EFLAGS_REG;\ntypedef struct _EFI_EXPANDED_ACPI_HID_DEVICE_PATH EFI_EXPANDED_ACPI_HID_DEVICE_PATH, *PEFI_EXPANDED_ACPI_HID_DEVICE_PATH;\ntypedef struct _EFI_FIBRECHANNEL_DEVICE_PATH EFI_FIBRECHANNEL_DEVICE_PATH, *PEFI_FIBRECHANNEL_DEVICE_PATH;\ntypedef struct _EFI_FIBRECHANNELEX_DEVICE_PATH EFI_FIBRECHANNELEX_DEVICE_PATH, *PEFI_FIBRECHANNELEX_DEVICE_PATH;\ntypedef struct _EFI_FILE_HANDLE EFI_FILE_HANDLE, *PEFI_FILE_HANDLE;\ntypedef struct _EFI_FILE_HEADER EFI_FILE_HEADER, *PEFI_FILE_HEADER;\ntypedef struct _EFI_FILE_INFO EFI_FILE_INFO, *PEFI_FILE_INFO;\ntypedef struct _EFI_FILE_IO_TOKEN EFI_FILE_IO_TOKEN, *PEFI_FILE_IO_TOKEN;\ntypedef struct _EFI_FILE_SYSTEM_INFO EFI_FILE_SYSTEM_INFO, *PEFI_FILE_SYSTEM_INFO;\ntypedef struct _EFI_FILE_SYSTEM_VOLUME_LABEL EFI_FILE_SYSTEM_VOLUME_LABEL, *PEFI_FILE_SYSTEM_VOLUME_LABEL;\ntypedef struct _EFI_FILEPATH_DEVICE_PATH EFI_FILEPATH_DEVICE_PATH, *PEFI_FILEPATH_DEVICE_PATH;\ntypedef struct _EFI_FLAGS_REG EFI_FLAGS_REG, *PEFI_FLAGS_REG;\ntypedef struct _EFI_FRAMEWORK_MP_HEALTH EFI_FRAMEWORK_MP_HEALTH, *PEFI_FRAMEWORK_MP_HEALTH;\ntypedef struct _EFI_FRAMEWORK_MP_PROCESSOR_CONTEXT EFI_FRAMEWORK_MP_PROCESSOR_CONTEXT, *PEFI_FRAMEWORK_MP_PROCESSOR_CONTEXT;\ntypedef struct _EFI_FRAMEWORK_MP_SERVICES_PROTOCOL EFI_FRAMEWORK_MP_SERVICES_PROTOCOL, *PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL;\ntypedef struct _EFI_GPT_PARTITION_TABLE_HEADER EFI_GPT_PARTITION_TABLE_HEADER, *PEFI_GPT_PARTITION_TABLE_HEADER;\ntypedef struct _EFI_GPT_PARTITION_ENTRY EFI_GPT_PARTITION_ENTRY, *PEFI_GPT_PARTITION_ENTRY;\ntypedef struct _EFI_GRAPHICS_OUTPUT_BLT_PIXEL EFI_GRAPHICS_OUTPUT_BLT_PIXEL, *PEFI_GRAPHICS_OUTPUT_BLT_PIXEL;\ntypedef struct _EFI_GRAPHICS_OUTPUT_MODE_INFORMATION EFI_GRAPHICS_OUTPUT_MODE_INFORMATION, *PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION;\ntypedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL, *PEFI_GRAPHICS_OUTPUT_PROTOCOL;\ntypedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE, *PEFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;\ntypedef struct _EFI_GUID EFI_GUID, *PEFI_GUID;\ntypedef struct _EFI_HARDDRIVE_DEVICE_PATH EFI_HARDDRIVE_DEVICE_PATH, *PEFI_HARDDRIVE_DEVICE_PATH;\ntypedef struct _EFI_HASH_PROTOCOL EFI_HASH_PROTOCOL, *PEFI_HASH_PROTOCOL;\ntypedef struct _EFI_HDD_INFO EFI_HDD_INFO, *PEFI_HDD_INFO;\ntypedef struct _EFI_I2O_DEVICE_PATH EFI_I2O_DEVICE_PATH, *PEFI_I2O_DEVICE_PATH;\ntypedef struct _EFI_INFINIBAND_DEVICE_PATH EFI_INFINIBAND_DEVICE_PATH, *PEFI_INFINIBAND_DEVICE_PATH;\ntypedef struct _EFI_INPUT_KEY EFI_INPUT_KEY, *PEFI_INPUT_KEY;\ntypedef struct _EFI_IO_ACCESS EFI_IO_ACCESS, *PEFI_IO_ACCESS;\ntypedef struct _EFI_IPv4_ADDRESS EFI_IPv4_ADDRESS, *PEFI_IPv4_ADDRESS;\ntypedef struct _EFI_IPv4_DEVICE_PATH EFI_IPv4_DEVICE_PATH, *PEFI_IPv4_DEVICE_PATH;\ntypedef struct _EFI_IPv6_ADDRESS EFI_IPv6_ADDRESS, *PEFI_IPv6_ADDRESS;\ntypedef struct _EFI_IPv6_DEVICE_PATH EFI_IPv6_DEVICE_PATH, *PEFI_IPv6_DEVICE_PATH;\ntypedef struct _EFI_KEY_DATA EFI_KEY_DATA, *PEFI_KEY_DATA;\ntypedef struct _EFI_KEY_STATE EFI_KEY_STATE, *PEFI_KEY_STATE;\ntypedef struct _EFI_LBAL EFI_LBAL, *PEFI_LBAL;\ntypedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL, *PEFI_LEGACY_BIOS_PROTOCOL;\ntypedef struct _EFI_LOAD_FILE_PROTOCOL EFI_LOAD_FILE_PROTOCOL, *PEFI_LOAD_FILE_PROTOCOL;\ntypedef struct _EFI_LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE_PROTOCOL, *PEFI_LOADED_IMAGE_PROTOCOL;\ntypedef struct _EFI_MAC_ADDR_DEVICE_PATH EFI_MAC_ADDR_DEVICE_PATH, *PEFI_MAC_ADDR_DEVICE_PATH;\ntypedef struct _EFI_MAC_ADDRESS EFI_MAC_ADDRESS, *PEFI_MAC_ADDRESS;\ntypedef struct _EFI_MANAGED_NETWORK_CONFIG_DATA EFI_MANAGED_NETWORK_CONFIG_DATA, *PEFI_MANAGED_NETWORK_CONFIG_DATA;\ntypedef struct _EFI_MASTER_BOOT_RECORD EFI_MASTER_BOOT_RECORD, *PEFI_MASTER_BOOT_RECORD;\ntypedef struct _EFI_MBR_PARTITION_RECORD EFI_MBR_PARTITION_RECORD, *PEFI_MBR_PARTITION_RECORD;\ntypedef struct _EFI_MEDIA_FW_VOL_DEVICE_PATH EFI_MEDIA_FW_VOL_DEVICE_PATH, *PEFI_MEDIA_FW_VOL_DEVICE_PATH;\ntypedef struct _EFI_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH EFI_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH, *PEFI_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;\ntypedef struct _EFI_MEDIA_PROTOCOL_DEVICE_PATH EFI_MEDIA_PROTOCOL_DEVICE_PATH, *PEFI_MEDIA_PROTOCOL_DEVICE_PATH;\ntypedef struct _EFI_MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH EFI_MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH, *PEFI_MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;\ntypedef struct _EFI_MEMMAP_DEVICE_PATH EFI_MEMMAP_DEVICE_PATH, *PEFI_MEMMAP_DEVICE_PATH;\ntypedef struct _EFI_MEMORY_DESCRIPTOR EFI_MEMORY_DESCRIPTOR, *PEFI_MEMORY_DESCRIPTOR;\ntypedef struct _EFI_MEMORY_MAP EFI_MEMORY_MAP, *PEFI_MEMORY_MAP;\ntypedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL, *PEFI_MP_SERVICES_PROTOCOL;\ntypedef struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL, *PEFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE;\ntypedef struct _EFI_NETWORK_STATISTICS EFI_NETWORK_STATISTICS, *PEFI_NETWORK_STATISTICS;\ntypedef struct _EFI_OPEN_PROTOCOL_INFORMATION_ENTRY EFI_OPEN_PROTOCOL_INFORMATION_ENTRY, *PEFI_OPEN_PROTOCOL_INFORMATION_ENTRY;\ntypedef struct _EFI_PARTITION_HEADER EFI_PARTITION_HEADER, *PEFI_PARTITION_HEADER;\ntypedef struct _EFI_PCCARD_DEVICE_PATH EFI_PCCARD_DEVICE_PATH, *PEFI_PCCARD_DEVICE_PATH;\ntypedef struct _EFI_PCI_DEVICE_PATH EFI_PCI_DEVICE_PATH, *PEFI_PCI_DEVICE_PATH;\ntypedef struct _EFI_PCI_IO_PROTOCOL EFI_PCI_IO_PROTOCOL, *PEFI_PCI_IO_PROTOCOL;\ntypedef struct _EFI_PCI_IO_PROTOCOL_ACCESS EFI_PCI_IO_PROTOCOL_ACCESS, *PEFI_PCI_IO_PROTOCOL_ACCESS;\ntypedef struct _EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS, *PEFI_PCI_IO_PROTOCOL_CONFIG_ACCESS;\ntypedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL, *PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL;\ntypedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS, *PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS;\ntypedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS, *PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS;\ntypedef struct _EFI_PIXEL_BITMASK EFI_PIXEL_BITMASK, *PEFI_PIXEL_BITMASK;\ntypedef struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL, *PEFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL;\ntypedef struct _EFI_PROCESSOR_INFORMATION EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION;\ntypedef struct _EFI_PROCESSOR_PHYSICAL_LOCATION EFI_PROCESSOR_PHYSICAL_LOCATION, *PEFI_PROCESSOR_PHYSICAL_LOCATION;\ntypedef struct _EFI_PXE_BASE_CODE_ARP_ENTRY EFI_PXE_BASE_CODE_ARP_ENTRY, *PEFI_PXE_BASE_CODE_ARP_ENTRY;\ntypedef struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL, *PEFI_PXE_BASE_CODE_CALLBACK_PROTOCOL;\ntypedef struct _EFI_PXE_BASE_CODE_DHCPV4_PACKET EFI_PXE_BASE_CODE_DHCPV4_PACKET, *PEFI_PXE_BASE_CODE_DHCPV4_PACKET;\ntypedef struct _EFI_PXE_BASE_CODE_DHCPV6_PACKET EFI_PXE_BASE_CODE_DHCPV6_PACKET, *PEFI_PXE_BASE_CODE_DHCPV6_PACKET;\ntypedef struct _EFI_PXE_BASE_CODE_DISCOVER_INFO EFI_PXE_BASE_CODE_DISCOVER_INFO, *PEFI_PXE_BASE_CODE_DISCOVER_INFO;\ntypedef struct _EFI_PXE_BASE_CODE_ICMP_ERROR EFI_PXE_BASE_CODE_ICMP_ERROR, *PEFI_PXE_BASE_CODE_ICMP_ERROR;\ntypedef struct _EFI_PXE_BASE_CODE_IP_FILTER EFI_PXE_BASE_CODE_IP_FILTER, *PEFI_PXE_BASE_CODE_IP_FILTER;\ntypedef struct _EFI_PXE_BASE_CODE_MODE EFI_PXE_BASE_CODE_MODE, *PEFI_PXE_BASE_CODE_MODE;\ntypedef struct _EFI_PXE_BASE_CODE_MTFTP_INFO EFI_PXE_BASE_CODE_MTFTP_INFO, *PEFI_PXE_BASE_CODE_MTFTP_INFO;\ntypedef struct _EFI_PXE_BASE_CODE_PROTOCOL EFI_PXE_BASE_CODE_PROTOCOL, *PEFI_PXE_BASE_CODE_PROTOCOL;\ntypedef struct _EFI_PXE_BASE_CODE_ROUTE_ENTRY EFI_PXE_BASE_CODE_ROUTE_ENTRY, *PEFI_PXE_BASE_CODE_ROUTE_ENTRY;\ntypedef struct _EFI_PXE_BASE_CODE_SRVLIST EFI_PXE_BASE_CODE_SRVLIST, *PEFI_PXE_BASE_CODE_SRVLIST;\ntypedef struct _EFI_PXE_BASE_CODE_TFTP_ERROR EFI_PXE_BASE_CODE_TFTP_ERROR, *PEFI_PXE_BASE_CODE_TFTP_ERROR;\ntypedef struct _EFI_RL EFI_RL, *PEFI_RL;\ntypedef struct _EFI_RNG_PROTOCOL EFI_RNG_PROTOCOL, *PEFI_RNG_PROTOCOL;\ntypedef struct _EFI_RUNTIME_SERVICES EFI_RUNTIME_SERVICES, *PEFI_RUNTIME_SERVICES;\ntypedef struct _EFI_SATA_DEVICE_PATH EFI_SATA_DEVICE_PATH, *PEFI_SATA_DEVICE_PATH;\ntypedef struct _EFI_SCSI_DEVICE_PATH EFI_SCSI_DEVICE_PATH, *PEFI_SCSI_DEVICE_PATH;\ntypedef struct _EFI_SERVICE_BINDING EFI_SERVICE_BINDING, *PEFI_SERVICE_BINDING;\ntypedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, *PEFI_SIMPLE_FILE_SYSTEM_PROTOCOL;\ntypedef struct _EFI_SIMPLE_NETWORK_MODE EFI_SIMPLE_NETWORK_MODE, *PEFI_SIMPLE_NETWORK_MODE;\ntypedef struct _EFI_SIMPLE_NETWORK_PROTOCOL EFI_SIMPLE_NETWORK_PROTOCOL, *PEFI_SIMPLE_NETWORK_PROTOCOL;\ntypedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL, *PEFI_SIMPLE_TEXT_INPUT_PROTOCOL;\ntypedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL, *PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;\ntypedef struct _EFI_SIMPLE_TEXT_OUTPUT_MODE EFI_SIMPLE_TEXT_OUTPUT_MODE, *PEFI_SIMPLE_TEXT_OUTPUT_MODE;\ntypedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL, *PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;\ntypedef struct _EFI_SYSTEM_TABLE EFI_SYSTEM_TABLE, *PEFI_SYSTEM_TABLE;\ntypedef struct _EFI_TABLE_HEADER EFI_TABLE_HEADER, *PEFI_TABLE_HEADER;\ntypedef struct _EFI_TIME EFI_TIME, *PEFI_TIME;\ntypedef struct _EFI_TIME_CAPABILITIES EFI_TIME_CAPABILITIES, *PEFI_TIME_CAPABILITIES;\ntypedef struct _EFI_UART_DEVICE_PATH EFI_UART_DEVICE_PATH, *PEFI_UART_DEVICE_PATH;\ntypedef struct _EFI_UART_IO_MODE EFI_UART_IO_MODE, *PEFI_UART_IO_MODE;\ntypedef struct _EFI_UART_IO_PROTOCOL EFI_UART_IO_PROTOCOL, *PEFI_UART_IO_PROTOCOL;\ntypedef struct _EFI_UDC_ATTRIBUTES EFI_UDC_ATTRIBUTES, *PEFI_UDC_ATTRIBUTES;\ntypedef struct _EFI_UKNOWN_DEVICE_VENDOR_DEVICE_PATH EFI_UNKNOWN_DEVICE_VENDOR_DEVICE_PATH, *PEFI_UNKNOWN_DEVICE_VENDOR_DEVICE_PATH;\ntypedef struct _EFI_UNICODE_COLLATION_PROTOCOL EFI_UNICODE_COLLATION_PROTOCOL, *PEFI_UNICODE_COLLATION_PROTOCOL;\ntypedef struct _EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL, *PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL;\ntypedef struct _EFI_UNIVERSAL_GRAPHICS_BLT_PIXEL EFI_UNIVERSAL_GRAPHICS_BLT_PIXEL, *PEFI_UNIVERSAL_GRAPHICS_BLT_PIXEL;\ntypedef struct _EFI_URI_DEVICE_PATH EFI_URI_DEVICE_PATH, *PEFI_URI_DEVICE_PATH;\ntypedef struct _EFI_USB_CLASS_DEVICE_PATH EFI_USB_CLASS_DEVICE_PATH, *PEFI_USB_CLASS_DEVICE_PATH;\ntypedef struct _EFI_USB_DEVICE_PATH EFI_USB_DEVICE_PATH, *PEFI_USB_DEVICE_PATH;\ntypedef struct _EFI_USB_WWID_DEVICE_PATH EFI_USB_WWID_DEVICE_PATH, *PEFI_USB_WWID_DEVICE_PATH;\ntypedef struct _EFI_VENDOR_DEVICE_PATH EFI_VENDOR_DEVICE_PATH, *PEFI_VENDOR_DEVICE_PATH;\ntypedef struct _EFI_VLAN_DEVICE_PATH EFI_VLAN_DEVICE_PATH, *PEFI_VLAN_DEVICE_PATH;\ntypedef struct _EFI_WORD_REGS EFI_WORD_REGS, *PEFI_WORD_REGS;\ntypedef struct _EPROCESS EPROCESS, *PEPROCESS;\ntypedef struct _ETHREAD ETHREAD, *PETHREAD;\ntypedef struct _EX_RUNDOWN_REFERENCE EX_RUNDOWN_REFERENCE, *PEX_RUNDOWN_REFERENCE;\ntypedef struct _EXCEPTION_RECORD EXCEPTION_RECORD, *PEXCEPTION_RECORD;\ntypedef struct _EXCEPTION_REGISTRATION_RECORD EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;\ntypedef struct _FIRMWARE_INFORMATION_BLOCK FIRMWARE_INFORMATION_BLOCK, *PFIRMWARE_INFORMATION_BLOCK;\ntypedef struct _FLOAT128 FLOAT128, *PFLOAT128;\ntypedef struct _GENERIC_ADDRESS GENERIC_ADDRESS, *PGENERIC_ADDRESS;\ntypedef struct _GUID GUID, *PGUID;\ntypedef struct _HL_FRAMEBUFFER_DATA HL_FRAMEBUFFER_DATA, *PHL_FRAMEBUFFER_DATA;\ntypedef struct _HL_SCROLL_REGION_DATA HL_SCROLL_REGION_DATA, *PHL_SCROLL_REGION_DATA;\ntypedef struct _KAPC KAPC, *PKAPC;\ntypedef struct _KAPC_STATE KAPC_STATE, *PKAPC_STATE;\ntypedef struct _KD_DEBUG_MODE KD_DEBUG_MODE, *PKD_DEBUG_MODE;\ntypedef struct _KD_DISPATCH_TABLE KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;\ntypedef struct _KDPC KDPC, *PKDPC;\ntypedef struct _KDPC_DATA KDPC_DATA, *PKDPC_DATA;\ntypedef struct _KERNEL_INITIALIZATION_BLOCK KERNEL_INITIALIZATION_BLOCK, *PKERNEL_INITIALIZATION_BLOCK;\ntypedef struct _KEVENT KEVENT, *PKEVENT;\ntypedef struct _KGATE KGATE, *PKGATE;\ntypedef struct _KLOCK_QUEUE_HANDLE KLOCK_QUEUE_HANDLE, *PKLOCK_QUEUE_HANDLE;\ntypedef struct _KPROCESS KPROCESS, *PKPROCESS;\ntypedef struct _KQUEUE KQUEUE, *PKQUEUE;\ntypedef struct _KSEMAPHORE KSEMAPHORE, *PKSEMAPHORE;\ntypedef struct _KSERVICE_DESCRIPTOR_TABLE KSERVICE_DESCRIPTOR_TABLE, *PKSERVICE_DESCRIPTOR_TABLE;\ntypedef struct _KSHARED_DATA KSHARED_DATA, *PKSHARED_DATA;\ntypedef struct _KSPIN_LOCK_QUEUE KSPIN_LOCK_QUEUE, *PKSPIN_LOCK_QUEUE;\ntypedef struct _KSYSTEM_TIME KSYSTEM_TIME, *PKSYSTEM_TIME;\ntypedef struct _KTHREAD KTHREAD, *PKTHREAD;\ntypedef struct _KTIMER KTIMER, *PKTIMER;\ntypedef struct _KUBSAN_FLOAT_CAST_OVERFLOW_DATA KUBSAN_FLOAT_CAST_OVERFLOW_DATA, *PKUBSAN_FLOAT_CAST_OVERFLOW_DATA;\ntypedef struct _KUBSAN_FUNCTION_TYPE_MISMATCH_DATA KUBSAN_FUNCTION_TYPE_MISMATCH_DATA, *PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA;\ntypedef struct _KUBSAN_INVALID_BUILTIN_DATA KUBSAN_INVALID_BUILTIN_DATA, *PKUBSAN_INVALID_BUILTIN_DATA;\ntypedef struct _KUBSAN_OUT_OF_BOUNDS_DATA KUBSAN_OUT_OF_BOUNDS_DATA, *PKUBSAN_OUT_OF_BOUNDS_DATA;\ntypedef struct _KUBSAN_OVERFLOW_DATA KUBSAN_OVERFLOW_DATA, *PKUBSAN_OVERFLOW_DATA;\ntypedef struct _KUBSAN_SHIFT_OUT_OF_BOUNDS_DATA KUBSAN_SHIFT_OUT_OF_BOUNDS_DATA, *PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA;\ntypedef struct _KUBSAN_SOURCE_LOCATION KUBSAN_SOURCE_LOCATION, *PKUBSAN_SOURCE_LOCATION;\ntypedef struct _KUBSAN_TYPE_DESCRIPTOR KUBSAN_TYPE_DESCRIPTOR, *PKUBSAN_TYPE_DESCRIPTOR;\ntypedef struct _KUBSAN_TYPE_MISMATCH_DATA KUBSAN_TYPE_MISMATCH_DATA, *PKUBSAN_TYPE_MISMATCH_DATA;\ntypedef struct _KUBSAN_TYPE_MISMATCH_DATA_V1 KUBSAN_TYPE_MISMATCH_DATA_V1, *PKUBSAN_TYPE_MISMATCH_DATA_V1;\ntypedef struct _KWAIT_BLOCK KWAIT_BLOCK, *PKWAIT_BLOCK;\ntypedef struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;\ntypedef struct _LIST_ENTRY LIST_ENTRY, *PLIST_ENTRY;\ntypedef struct _LIST_ENTRY32 LIST_ENTRY32, *PLIST_ENTRY32;\ntypedef struct _LIST_ENTRY64 LIST_ENTRY64, *PLIST_ENTRY64;\ntypedef struct _LOADER_GRAPHICS_INFORMATION_BLOCK LOADER_GRAPHICS_INFORMATION_BLOCK, *PLOADER_GRAPHICS_INFORMATION_BLOCK;\ntypedef struct _LOADER_INFORMATION_BLOCK LOADER_INFORMATION_BLOCK, *PLOADER_INFORMATION_BLOCK;\ntypedef struct _LOADER_MEMORY_DESCRIPTOR LOADER_MEMORY_DESCRIPTOR, *PLOADER_MEMORY_DESCRIPTOR;\ntypedef struct _M128 M128, *PM128;\ntypedef struct _MMCOLOR_TABLES MMCOLOR_TABLES, *PMMCOLOR_TABLES;\ntypedef struct _MMFREE_POOL_ENTRY MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;\ntypedef struct _MMMEMORY_LAYOUT MMMEMORY_LAYOUT, *PMMMEMORY_LAYOUT;\ntypedef struct _MMPFNENTRY MMPFNENTRY, *PMMPFNENTRY;\ntypedef struct _MMPFNLIST MMPFNLIST, *PMMPFNLIST;\ntypedef struct _PCAT_FIRMWARE_INFORMATION PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;\ntypedef struct _PCI_BRIDGE_CONTROL_REGISTER PCI_BRIDGE_CONTROL_REGISTER, *PPCI_BRIDGE_CONTROL_REGISTER;\ntypedef struct _PCI_COMMON_CONFIG PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;\ntypedef struct _PCI_COMMON_HEADER PCI_COMMON_HEADER, *PPCI_COMMON_HEADER;\ntypedef struct _PCI_DEVICE_HEADER_TYPE_REGION PCI_DEVICE_HEADER_TYPE_REGION, *PPCI_DEVICE_HEADER_TYPE_REGION;\ntypedef struct _PCI_DEVICE_INDEPENDENT_REGION PCI_DEVICE_INDEPENDENT_REGION, *PPCI_DEVICE_INDEPENDENT_REGION;\ntypedef struct _PCI_TYPE0_DEVICE PCI_TYPE0_DEVICE, *PPCI_TYPE0_DEVICE;\ntypedef struct _PCI_TYPE1_DEVICE PCI_TYPE1_DEVICE, *PPCI_TYPE1_DEVICE;\ntypedef struct _PECOFF_IMAGE_BASE_RELOCATION PECOFF_IMAGE_BASE_RELOCATION, *PPECOFF_IMAGE_BASE_RELOCATION;\ntypedef struct _PECOFF_IMAGE_DATA PECOFF_IMAGE_DATA, *PPECOFF_IMAGE_DATA;\ntypedef struct _PECOFF_IMAGE_DATA_DIRECTORY PECOFF_IMAGE_DATA_DIRECTORY, *PPECOFF_IMAGE_DATA_DIRECTORY;\ntypedef struct _PECOFF_IMAGE_DOS_HEADER PECOFF_IMAGE_DOS_HEADER, *PPECOFF_IMAGE_DOS_HEADER;\ntypedef struct _PECOFF_IMAGE_EXPORT_DIRECTORY PECOFF_IMAGE_EXPORT_DIRECTORY, *PPECOFF_IMAGE_EXPORT_DIRECTORY;\ntypedef struct _PECOFF_IMAGE_FILE_HEADER PECOFF_IMAGE_FILE_HEADER, *PPECOFF_IMAGE_FILE_HEADER;\ntypedef struct _PECOFF_IMAGE_IMPORT_DESCRIPTOR PECOFF_IMAGE_IMPORT_DESCRIPTOR, *PPECOFF_IMAGE_IMPORT_DESCRIPTOR;\ntypedef struct _PECOFF_IMAGE_LOAD_CONFIG_CODE_INTEGRITY PECOFF_IMAGE_LOAD_CONFIG_CODE_INTEGRITY, *PPECOFF_IMAGE_LOAD_CONFIG_CODE_INTEGRITY;\ntypedef struct _PECOFF_IMAGE_LOAD_CONFIG_DIRECTORY32 PECOFF_IMAGE_LOAD_CONFIG_DIRECTORY32, *PPECOFF_IMAGE_LOAD_CONFIG_DIRECTORY32;\ntypedef struct _PECOFF_IMAGE_LOAD_CONFIG_DIRECTORY64 PECOFF_IMAGE_LOAD_CONFIG_DIRECTORY64, *PPECOFF_IMAGE_LOAD_CONFIG_DIRECTORY64;\ntypedef struct _PECOFF_IMAGE_OPTIONAL_HEADER PECOFF_IMAGE_OPTIONAL_HEADER, *PPECOFF_IMAGE_OPTIONAL_HEADER;\ntypedef struct _PECOFF_IMAGE_OS2_HEADER PECOFF_IMAGE_OS2_HEADER, *PPECOFF_IMAGE_OS2_HEADER;\ntypedef struct _PECOFF_IMAGE_PE_HEADER PECOFF_IMAGE_PE_HEADER, *PPECOFF_IMAGE_PE_HEADER;\ntypedef struct _PECOFF_IMAGE_RESOURCE_DATA_ENTRY PECOFF_IMAGE_RESOURCE_DATA_ENTRY, *PPECOFF_IMAGE_RESOURCE_DATA_ENTRY;\ntypedef struct _PECOFF_IMAGE_RESOURCE_DIRECTORY PECOFF_IMAGE_RESOURCE_DIRECTORY, *PPECOFF_IMAGE_RESOURCE_DIRECTORY;\ntypedef struct _PECOFF_IMAGE_RESOURCE_DIRECTORY_ENTRY PECOFF_IMAGE_RESOURCE_DIRECTORY_ENTRY, *PPECOFF_IMAGE_RESOURCE_DIRECTORY_ENTRY;\ntypedef struct _PECOFF_IMAGE_ROM_HEADER PECOFF_IMAGE_ROM_HEADER, *PPECOFF_IMAGE_ROM_HEADER;\ntypedef struct _PECOFF_IMAGE_ROM_OPTIONAL_HEADER PECOFF_IMAGE_ROM_OPTIONAL_HEADER, *PPECOFF_IMAGE_ROM_OPTIONAL_HEADER;\ntypedef struct _PECOFF_IMAGE_SECTION_HEADER PECOFF_IMAGE_SECTION_HEADER, *PPECOFF_IMAGE_SECTION_HEADER;\ntypedef struct _PECOFF_IMAGE_VXD_HEADER PECOFF_IMAGE_VXD_HEADER, *PPECOFF_IMAGE_VXD_HEADER;\ntypedef struct _PHYSICAL_MEMORY_DESCRIPTOR PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;\ntypedef struct _PHYSICAL_MEMORY_RUN PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;\ntypedef struct _POOL_HEADER POOL_HEADER, *PPOOL_HEADER;\ntypedef struct _POOL_TRACKING_BIG_ALLOCATIONS POOL_TRACKING_BIG_ALLOCATIONS, *PPOOL_TRACKING_BIG_ALLOCATIONS;\ntypedef struct _POOL_TRACKING_TABLE POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;\ntypedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;\ntypedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;\ntypedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;\ntypedef struct _RTL_PRINT_CONTEXT RTL_PRINT_CONTEXT, *PRTL_PRINT_CONTEXT;\ntypedef struct _RTL_PRINT_FORMAT_PROPERTIES RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;\ntypedef struct _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;\ntypedef struct _SMBIOS_TABLE_HEADER SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER;\ntypedef struct _SMBIOS3_TABLE_HEADER SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;\ntypedef struct _STRING STRING, *PSTRING;\ntypedef struct _STRING32 STRING32, *PSTRING32;\ntypedef struct _STRING64 STRING64, *PSTRING64;\ntypedef struct _THREAD_INFORMATION_BLOCK THREAD_INFORMATION_BLOCK, *PTHREAD_INFORMATION_BLOCK;\ntypedef struct _TIME_FIELDS TIME_FIELDS, *PTIME_FIELDS;\ntypedef struct _TIMER_ROUTINES TIMER_ROUTINES, *PTIMER_ROUTINES;\ntypedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRMWARE_INFORMATION;\ntypedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;\ntypedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32;\ntypedef struct _UNICODE_STRING64 UNICODE_STRING64, *PUNICODE_STRING64;\ntypedef struct _XTBL_BOOT_PARAMETERS XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS;\ntypedef struct _XTBL_BOOT_PROTOCOL XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL;\ntypedef struct _XTBL_BOOTMENU_ITEM XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM;\ntypedef struct _XTBL_CONFIG_ENTRY XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY;\ntypedef struct _XTBL_CONFIG_SECTION XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION;\ntypedef struct _XTBL_DIALOG_HANDLE XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE;\ntypedef struct _XTBL_EXECUTABLE_IMAGE_PROTOCOL XTBL_EXECUTABLE_IMAGE_PROTOCOL, *PXTBL_EXECUTABLE_IMAGE_PROTOCOL;\ntypedef struct _XTBL_FRAMEBUFFER_INFORMATION XTBL_FRAMEBUFFER_INFORMATION, *PXTBL_FRAMEBUFFER_INFORMATION;\ntypedef struct _XTBL_FRAMEBUFFER_MODE_INFORMATION XTBL_FRAMEBUFFER_MODE_INFORMATION, *PXTBL_FRAMEBUFFER_MODE_INFORMATION;\ntypedef struct _XTBL_FRAMEBUFFER_PROTOCOL XTBL_FRAMEBUFFER_PROTOCOL, *PXTBL_FRAMEBUFFER_PROTOCOL;\ntypedef struct _XTBL_KNOWN_BOOT_PROTOCOL XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;\ntypedef struct _XTBL_LOADER_PROTOCOL XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;\ntypedef struct _XTBL_MEMORY_MAPPING XTBL_MEMORY_MAPPING, *PXTBL_MEMORY_MAPPING;\ntypedef struct _XTBL_MODULE_AUTHORS XTBL_MODULE_AUTHORS, *PXTBL_MODULE_AUTHORS;\ntypedef struct _XTBL_MODULE_DEPS XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS;\ntypedef struct _XTBL_MODULE_INFO XTBL_MODULE_INFO, *PXTBL_MODULE_INFO;\ntypedef struct _XTBL_PAGE_MAPPING XTBL_PAGE_MAPPING, *PXTBL_PAGE_MAPPING;\ntypedef struct _XTBL_STATUS XTBL_STATUS, *PXTBL_STATUS;\n\n/* Unions forward references */\ntypedef union _EFI_DEV_PATH EFI_DEV_PATH, *PEFI_DEV_PATH;\ntypedef union _EFI_DEV_PATH_PTR EFI_DEV_PATH_PTR, *PEFI_DEV_PATH_PTR;\ntypedef union _EFI_FRAMEWORK_MP_HEALTH_FLAGS EFI_FRAMEWORK_MP_HEALTH_FLAGS, *PEFI_FRAMEWORK_MP_HEALTH_FLAGS;\ntypedef union _EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION, *PEFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION;\ntypedef union _EFI_HASH_OUTPUT EFI_HASH_OUTPUT, *PEFI_HASH_OUTPUT;\ntypedef union _EFI_IA32_REGISTER_SET EFI_IA32_REGISTER_SET, *PEFI_IA32_REGISTER_SET;\ntypedef union _EFI_IP_ADDRESS EFI_IP_ADDRESS, *PEFI_IP_ADDRESS;\ntypedef union _EFI_PXE_BASE_CODE_PACKET EFI_PXE_BASE_CODE_PACKET, *PEFI_PXE_BASE_CODE_PACKET;\ntypedef union _LARGE_INTEGER LARGE_INTEGER, *PLARGE_INTEGER;\ntypedef union _SINGLE_LIST_HEADER SINGLE_LIST_HEADER, *PSINGLE_LIST_HEADER;\ntypedef union _ULARGE_INTEGER ULARGE_INTEGER, *PULARGE_INTEGER;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_XTSTRUCT_H */\n"
  },
  {
    "path": "sdk/xtdk/xttarget.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xttarget.h\n * DESCRIPTION:     XT target architecture specific definitions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTTARGET_H\n#define __XTDK_XTTARGET_H\n\n\n/* Preprocessor macros for including arch-specific headers */\n#define ARCH_COMMON(header)                         STRINGIFY(../_ARCH_COMMON/header)\n#define ARCH_HEADER(header)                         STRINGIFY(_ARCH/header)\n\n/* Architecture specific definitions */\n#if defined(__i386__) || defined(__i686__)\n    #define _ARCH                                   i686\n    #define _ARCH_I686                              1\n    #define _ARCH_COMMON                            x86\n    #define _ARCH_NAME                              \"32-bit x86\"\n    #define _ARCH_IMAGE_MACHINE_TYPE                0x014C\n    #define _XT32                                   1\n    #define BITS_PER_LONG                           32\n    #define CACHE_ALIGNMENT                         64\n    #define EFI_ERROR_MASK                          0x80000000\n    #define MAXIMUM_PROCESSORS                      32\n    #define MEMORY_ALIGNMENT                        8\n    #define MM_USERPAGE_TABLES                      1536\n    #define MM_VIRTUAL_PAGESIZE                     20\n    #define STACK_ALIGNMENT                         4\n#elif defined(__amd64__) || defined(__x86_64__)\n    #define _ARCH                                   amd64\n    #define _ARCH_AMD64                             1\n    #define _ARCH_COMMON                            x86\n    #define _ARCH_NAME                              \"64-bit x86\"\n    #define _ARCH_IMAGE_MACHINE_TYPE                0x8664\n    #define _XT64                                   1\n    #define BITS_PER_LONG                           64\n    #define CACHE_ALIGNMENT                         64\n    #define EFI_ERROR_MASK                          0x8000000000000000\n    #define MAXIMUM_PROCESSORS                      256\n    #define MEMORY_ALIGNMENT                        16\n    #define MM_USERPAGE_TABLES                      4194304\n    #define MM_VIRTUAL_PAGESIZE                     52\n    #define STACK_ALIGNMENT                         16\n#else\n    #error Unknown architecture\n#endif\n\n#endif /* __XTDK_XTTARGET_H */\n"
  },
  {
    "path": "sdk/xtdk/xttypes.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xttypes.h\n * DESCRIPTION:     Definitions of basic data types defined by XT\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTTYPES_H\n#define __XTDK_XTTYPES_H\n\n#include <xttarget.h>\n#include <xtcompat.h>\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Standard C types */\ntypedef unsigned char BYTE, *PBYTE, *LPBYTE;\ntypedef char CHAR, *PCHAR, *LPCHAR;\ntypedef double DOUBLE, *PDOUBLE, *LPDOUBLE;\ntypedef unsigned long DWORD, *PDWORD, *LPDWORD;\ntypedef float FLOAT, *PFLOAT, *LPFLOAT;\ntypedef int INT, *PINT, *LPINT;\ntypedef long LONG, *PLONG, *LPLONG;\ntypedef signed char SCHAR, *PSCHAR;\ntypedef signed long SLONG, *PSLONG;\ntypedef short SHORT, *PSHORT, *LPSHORT;\ntypedef unsigned char UCHAR, *PUCHAR;\ntypedef unsigned int UINT, *PUINT;\ntypedef unsigned long ULONG, *PULONG, LPULONG;\ntypedef unsigned short USHORT, *PUSHORT;\ntypedef unsigned short WORD, *PWORD, *LPWORD;\ntypedef void VOID, *PVOID, *LPVOID;\n\n/* Constant C types */\ntypedef const BYTE CBYTE, *PCBYTE, *LPCBYTE;\ntypedef const CHAR CCHAR, *PCCHAR, *LPCCHAR;\ntypedef const DOUBLE CDOUBLE, *PCDOUBLE, *LPCDOUBLE;\ntypedef const DWORD CDWORD, *PCDWORD, *LPCDWORD;\ntypedef const FLOAT CFLOAT, *PCFLOAT, *LPCFLOAT;\ntypedef const INT CINT, *PCINT, *LPCINT;\ntypedef const LONG CLONG, *PCLONG, *LPCLONG;\ntypedef const SCHAR CSCHAR, *PCSCHAR, *LPCSCHAR;\ntypedef const SHORT CSHORT, *PCSHORT, *LPCSHORT;\ntypedef const UCHAR CUCHAR, *PCUCHAR, *LPCUCHAR;\ntypedef const UINT CUINT, *PCUINT, *LPCUINT;\ntypedef const ULONG CULONG, *PCULONG, *LPCULONG;\ntypedef const USHORT CUSHORT, *PCUSHORT, *LPCUSHORT;\ntypedef const VOID CVOID, *PCVOID, *LPCVOID;\ntypedef const WORD CWORD, *PCWORD, *LPCWORD;\n\n/* Integer types */\ntypedef signed char INT8, *PINT8;\ntypedef unsigned char UINT8, *PUINT8;\ntypedef signed short INT16, *PINT16;\ntypedef unsigned short UINT16, *PUINT16;\ntypedef signed int INT32, *PINT32;\ntypedef unsigned int UINT32, *PUINT32;\ntypedef signed long long INT64, *PINT64;\ntypedef unsigned long long UINT64, *PUINT64;\n\n/* 64-bit types */\ntypedef long double DOUBLE64, *PDOUBLE64;\ntypedef long double LDOUBLE, *PLDOUBLE;\ntypedef long long LONG64, *PLONG64;\ntypedef long long LONGLONG, *PLONGLONG;\ntypedef unsigned long long ULONGLONG, *PULONGLONG;\n\n/* Signed 32-bit wide types */\ntypedef signed int LONG32, *PLONG32;\n\n/* Unsigned 32-bit wide types */\ntypedef unsigned int DWORD32, *PDWORD32;\ntypedef unsigned int ULONG32, *PULONG32;\n\n/* Unsigned 64-bit wide types */\ntypedef unsigned long long DWORD64, *PDWORD64;\ntypedef unsigned long long ULONG64, *PULONG64;\n\n/* Pointer size guaranteed types */\n#if defined(_XT64)\n    typedef long long INT_PTR, *PINT_PTR;\n    typedef unsigned long long UINT_PTR, *PUINT_PTR;\n    typedef long long LONG_PTR, *PLONG_PTR;\n    typedef unsigned long long ULONG_PTR, *PULONG_PTR;\n    typedef unsigned long long POINTER_64_INT;\n#else\n    typedef int INT_PTR, *PINT_PTR;\n    typedef unsigned int UINT_PTR, *PUINT_PTR;\n    typedef long LONG_PTR, *PLONG_PTR;\n    typedef unsigned long ULONG_PTR, *PULONG_PTR;\n    typedef unsigned long POINTER_64_INT;\n#endif\n\n/* Flag (bitfield) types */\ntypedef BYTE FCHAR;\ntypedef DWORD FLONG;\ntypedef WORD FSHORT;\n\n/* SIZE_T types */\ntypedef ULONG_PTR SIZE_T, *PSIZE_T;\ntypedef LONG_PTR SSIZE_T, *PSSIZE_T;\n\n/* Pointer to PVOID */\ntypedef PVOID *PPVOID;\n\n/* Polymorphic values types */\ntypedef SLONG HPARAM, HRESULT;\ntypedef LONG_PTR LPARAM, LRESULT;\ntypedef UINT_PTR WPARAM, WRESULT;\n\n/* Handle types */\ntypedef VOID *HANDLE, **PHANDLE;\ntypedef HANDLE *SPHANDLE, *LPHANDLE;\n\n/* XT status types */\ntypedef LONG XTSTATUS, *PXTSTATUS;\n\n/* ANSI character types */\ntypedef CHAR *PCH, *LPCH;\ntypedef CHAR *PCCH, *LPCCH;\ntypedef CHAR *PSTR, *LPSTR, *NPSTR;\ntypedef PSTR *PZPSTR;\ntypedef const PSTR *PCZPSTR;\ntypedef const CHAR *PCSTR, *LPCSTR;\ntypedef PCSTR *PZPCSTR;\n\n/* ASCIIZ character types */\ntypedef CHAR SZ, *PSZ;\ntypedef const CHAR CSZ, *PCSZ;\n\n/* UNICODE character types */\ntypedef wchar WCHAR, *PWCHAR;\ntypedef WCHAR *PWCH, *LPWCH;\ntypedef const WCHAR *PCWCH, *LPCWCH;\ntypedef WCHAR *PWSTR, *LPWSTR, *NWPSTR;\ntypedef PWSTR *PZPWSTR;\ntypedef const PWSTR *PCZPWSTR;\ntypedef WCHAR *PUWSTR, *LPUWSTR;\ntypedef const WCHAR *PCWSTR, *LPCWSTR;\ntypedef PCWSTR *PZPCWSTR;\ntypedef const WCHAR *PCUWSTR, *LPCUWSTR;\n\n/* Neutral character types */\ntypedef WCHAR TBYTE, *PTBYTE;\ntypedef WCHAR TCHAR, *PTCHAR;\ntypedef LPWSTR LP;\ntypedef LPWSTR PTCH, LPTCH;\ntypedef LPWSTR PTSTR, LPTSTR;\ntypedef LPCWSTR PCTSTR, LPCTSTR;\ntypedef LPUWSTR PUTSTR, LPUTSTR;\ntypedef LPCUWSTR PCUTSTR, LPCUTSTR;\n\n/* Variadic ABI types */\ntypedef __builtin_va_list VA_LIST, *PVA_LIST;\n\n/* 128-bit floats structure */\ntypedef struct _FLOAT128\n{\n    LONGLONG LowPart;\n    LONGLONG HighPart;\n} FLOAT128, *PFLOAT128;\n\n/* 64-bit floating point union */\ntypedef union _LARGE_DOUBLE\n{\n    struct\n    {\n        ULONG LowPart;\n        ULONG HighPart;\n    } u;\n    DOUBLE DoublePart;\n    ULONGLONG QuadPart;\n} LARGE_DOUBLE, *PLARGE_DOUBLE;\n\n/* 64-bit signed integer union */\ntypedef union _LARGE_INTEGER\n{\n    struct\n    {\n        ULONG LowPart;\n        LONG HighPart;\n    };\n    struct\n    {\n        ULONG LowPart;\n        LONG HighPart;\n    } u;\n    LONGLONG QuadPart;\n} LARGE_INTEGER, *PLARGE_INTEGER;\n\n/* 64-bit unsigned integer union */\ntypedef union _ULARGE_INTEGER\n{\n    struct\n    {\n        ULONG LowPart;\n        ULONG HighPart;\n    };\n    struct\n    {\n        ULONG LowPart;\n        ULONG HighPart;\n    } u;\n    ULONGLONG QuadPart;\n} ULARGE_INTEGER, *PULARGE_INTEGER;\n\n/* Counted string structure */\ntypedef struct _STRING\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    PCHAR Buffer;\n} STRING, *PSTRING;\n\n/* 32-bit counted string structure */\ntypedef struct _STRING32\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    ULONG Buffer;\n} STRING32, *PSTRING32;\n\n/* 64-bit counted string structure */\ntypedef struct _STRING64\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    ULONGLONG Buffer;\n} STRING64, *PSTRING64;\n\n/* Constant counted string structure */\ntypedef struct _CSTRING\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    PCCHAR Buffer;\n} CSTRING, *PCSTRING;\n\n/* ANSI string structure */\ntypedef struct _ANSI_STRING\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    PSTR Buffer;\n} ANSI_STRING, *PANSI_STRING;\ntypedef const ANSI_STRING *PCANSI_STRING;\n\n/* 32-bit ANSI string structure */\ntypedef struct _ANSI_STRING32\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    ULONG Buffer;\n} ANSI_STRING32, *PANSI_STRING32;\ntypedef const ANSI_STRING32 *PCANSI_STRING32;\n\n/* 64-bit ANSI string structure */\ntypedef struct _ANSI_STRING64\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    ULONGLONG Buffer;\n} ANSI_STRING64, *PANSI_STRING64;\ntypedef const ANSI_STRING64 *PCANSI_STRING64;\n\n/* UNICODE string structure */\ntypedef struct _UNICODE_STRING\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    PWSTR Buffer;\n} UNICODE_STRING, *PUNICODE_STRING;\ntypedef const UNICODE_STRING *PCUNICODE_STRING;\n\n/* 32-bit UNICODE string structure */\ntypedef struct _UNICODE_STRING32\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    ULONG Buffer;\n} UNICODE_STRING32, *PUNICODE_STRING32;\ntypedef const UNICODE_STRING32 *PCUNICODE_STRING32;\n\n/* 64-bit UNICODE string structure */\ntypedef struct _UNICODE_STRING64\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    ULONGLONG Buffer;\n} UNICODE_STRING64, *PUNICODE_STRING64;\ntypedef const UNICODE_STRING64 *PCUNICODE_STRING64;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_XTTYPES_H */\n"
  },
  {
    "path": "sdk/xtdk/xtuefi.h",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            sdk/xtdk/xtuefi.h\n * DESCRIPTION:     XT UEFI support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTDK_XTUEFI_H\n#define __XTDK_XTUEFI_H\n\n#include <xtbase.h>\n#include <xtdefs.h>\n#include <xttypes.h>\n#include <xtstruct.h>\n\n\n/* EFI ACPI Small Item Descriptor Name */\n#define EFI_ACPI_SMALL_IRQ_DESCRIPTOR_NAME                          0x04\n#define EFI_ACPI_SMALL_DMA_DESCRIPTOR_NAME                          0x05\n#define EFI_ACPI_SMALL_START_DEPENDENT_DESCRIPTOR_NAME              0x06\n#define EFI_ACPI_SMALL_END_DEPENDENT_DESCRIPTOR_NAME                0x07\n#define EFI_ACPI_SMALL_IO_PORT_DESCRIPTOR_NAME                      0x08\n#define EFI_ACPI_SMALL_FIXED_IO_PORT_DESCRIPTOR_NAME                0x09\n#define EFI_ACPI_SMALL_VENDOR_DEFINED_DESCRIPTOR_NAME               0x0E\n#define EFI_ACPI_SMALL_END_TAG_DESCRIPTOR_NAME                      0x0F\n\n/* EFI ACPI Large Item Descriptor Name */\n#define EFI_ACPI_LARGE_24_BIT_MEMORY_RANGE_DESCRIPTOR_NAME          0x01\n#define EFI_ACPI_LARGE_VENDOR_DEFINED_DESCRIPTOR_NAME               0x04\n#define EFI_ACPI_LARGE_32_BIT_MEMORY_RANGE_DESCRIPTOR_NAME          0x05\n#define EFI_ACPI_LARGE_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR_NAME    0x06\n#define EFI_ACPI_LARGE_DWORD_ADDRESS_SPACE_DESCRIPTOR_NAME          0x07\n#define EFI_ACPI_LARGE_WORD_ADDRESS_SPACE_DESCRIPTOR_NAME           0x08\n#define EFI_ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME                 0x09\n#define EFI_ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME          0x0A\n\n/* EFI ACPI Small Item Descriptor Values */\n#define EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR                              0x22\n#define EFI_ACPI_IRQ_DESCRIPTOR                                     0x23\n#define EFI_ACPI_DMA_DESCRIPTOR                                     0x2A\n#define EFI_ACPI_START_DEPENDENT_DESCRIPTOR                         0x30\n#define EFI_ACPI_START_DEPENDENT_EX_DESCRIPTOR                      0x31\n#define EFI_ACPI_END_DEPENDENT_DESCRIPTOR                           0x38\n#define EFI_ACPI_IO_PORT_DESCRIPTOR                                 0x47\n#define EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR                  0x4B\n#define EFI_ACPI_END_TAG_DESCRIPTOR                                 0x79\n\n/* EFI ACPI Large Item Descriptor Values */\n#define EFI_ACPI_24_BIT_MEMORY_RANGE_DESCRIPTOR                     0x81\n#define EFI_ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR                     0x85\n#define EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR               0x86\n#define EFI_ACPI_ADDRESS32_SPACE_DESCRIPTOR                         0x87\n#define EFI_ACPI_ADDRESS16_SPACE_DESCRIPTOR                         0x88\n#define EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR                      0x89\n#define EFI_ACPI_ADDRESS64_SPACE_DESCRIPTOR                         0x8A\n\n/* EFI ACPI Resource Types */\n#define EFI_ACPI_ADDRESS_SPACE_TYPE_MEMORY                          0x00\n#define EFI_ACPI_ADDRESS_SPACE_TYPE_IO                              0x01\n#define EFI_ACPI_ADDRESS_SPACE_TYPE_BUS_NUMBER                      0x02\n\n/* EFI service signatures */\n#define EFI_BOOT_SERVICES_SIGNATURE                                 0x56524553544f4f42\n#define EFI_RUNTIME_SERVICES_SIGNATURE                              0x56524553544e5552\n#define EFI_SYSTEM_TABLE_SIGNATURE                                  0x5453595320494249\n\n/* Caching types for the memory range */\n#define EFI_MEMORY_UC                                               0x0000000000000001\n#define EFI_MEMORY_WC                                               0x0000000000000002\n#define EFI_MEMORY_WT                                               0x0000000000000004\n#define EFI_MEMORY_WB                                               0x0000000000000008\n#define EFI_MEMORY_UCE                                              0x0000000000000010\n\n/* Physical memory protection on range */\n#define EFI_MEMORY_WP                                               0x0000000000001000\n#define EFI_MEMORY_RP                                               0x0000000000002000\n#define EFI_MEMORY_XP                                               0x0000000000004000\n#define EFI_MEMORY_RO                                               0x0000000000020000\n\n/* Physical memory persistence attribute */\n#define EFI_MEMORY_NV                                               0x0000000000008000\n\n/* Memory region provides higher reliability relative to other memory in the system */\n#define EFI_MEMORY_MORE_RELIABLE                                    0x0000000000010000\n\n/* Specific-purpose memory (SPM) */\n#define EFI_MEMORY_SP                                               0x0000000000040000\n\n/* Memory region capable of being protected with the CPU's cryptography */\n#define EFI_MEMORY_CPU_CRYPTO                                       0x0000000000080000\n\n/* EFI Runtime memory attribute */\n#define EFI_MEMORY_RUNTIME                                          0x8000000000000000\n\n/* EFI Pages related definitions */\n#define EFI_PAGE_SIZE                                               4096\n#define EFI_PAGE_MASK                                               0xFFF\n#define EFI_PAGE_SHIFT                                              12\n\n/* EFI open protocol */\n#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL                        0x00000001\n#define EFI_OPEN_PROTOCOL_GET_PROTOCOL                              0x00000002\n#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL                             0x00000004\n#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER                       0x00000008\n#define EFI_OPEN_PROTOCOL_BY_DRIVER                                 0x00000010\n#define EFI_OPEN_PROTOCOL_EXCLUSIVE                                 0x00000020\n\n/* EFI capsule flags */\n#define EFI_CAPSULE_FLAGS_PERSIST_ACROSS_RESET                      0x00010000\n#define EFI_CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE                     0x00020000\n#define EFI_CAPSULE_FLAGS_INITIATE_RESET                            0x00040000\n\n/* EFI variables related definitions */\n#define EFI_VARIABLE_NON_VOLATILE                                   0x00000001\n#define EFI_VARIABLE_BOOTSERVICE_ACCESS                             0x00000002\n#define EFI_VARIABLE_RUNTIME_ACCESS                                 0x00000004\n#define EFI_VARIABLE_HARDWARE_ERROR_RECORD                          0x00000008\n#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS                     0x00000010\n#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS          0x00000020\n#define EFI_VARIABLE_APPEND_WRITE                                   0x00000040\n\n/* Maximum EFI variable size */\n#define EFI_MAXIMUM_VARIABLE_SIZE                                   1024\n\n/* EFI event types */\n#define EFI_EVENT_EFI_SIGNAL_MASK                                   0x000000FF\n#define EFI_EVENT_NOTIFY_WAIT                                       0x00000100\n#define EFI_EVENT_NOTIFY_SIGNAL                                     0x00000200\n#define EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES                         0x00000201\n#define EFI_EVENT_RUNTIME_CONTEXT                                   0x20000000\n#define EFI_EVENT_RUNTIME                                           0x40000000\n#define EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE                     0x60000202\n#define EFI_EVENT_TIMER                                             0x80000000\n\n/* EFI disk signature type */\n#define EFI_DISK_SIGNATURE_TYPE_MBR                                 0x01\n#define EFI_DISK_SIGNATURE_TYPE_GPT                                 0x02\n\n/* EFI device path types */\n#define EFI_HARDWARE_DEVICE_PATH                                    0x01\n#define EFI_ACPI_DEVICE_PATH                                        0x02\n#define EFI_MESSAGING_DEVICE_PATH                                   0x03\n#define EFI_MEDIA_DEVICE_PATH                                       0x04\n#define EFI_BBS_DEVICE_PATH                                         0x05\n#define EFI_END_DEVICE_PATH                                         0x7F\n\n/* EFI hardware device path subtypes */\n#define EFI_HARDWARE_PCI_DP                                         0x01\n#define EFI_HARDWARE_PCCARD_DP                                      0x02\n#define EFI_HARDWARE_MEMMAP_DP                                      0x03\n#define EFI_HARDWARE_VENDOR_DP                                      0x04\n#define EFI_HARDWARE_CONTROLLER_DP                                  0x05\n\n/* EFI ACPI device path subtypes */\n#define EFI_ACPI_DP                                                 0x01\n#define EFI_ACPI_EXPANDED_DP                                        0x02\n\n/* EFI messaging device path subtypes */\n#define EFI_MESSAGING_ATAPI_DP                                      0x01\n#define EFI_MESSAGING_SCSI_DP                                       0x02\n#define EFI_MESSAGING_FIBRECHANNEL_DP                               0x03\n#define EFI_MESSAGING_1394_DP                                       0x04\n#define EFI_MESSAGING_USB_DP                                        0x05\n#define EFI_MESSAGING_I2O_DP                                        0x06\n#define EFI_MESSAGING_INFINIBAND_DP                                 0x09\n#define EFI_MESSAGING_VENDOR_DP                                     0x0A\n#define EFI_MESSAGING_MAC_ADDR_DP                                   0x0B\n#define EFI_MESSAGING_IPv4_DP                                       0x0C\n#define EFI_MESSAGING_IPv6_DP                                       0x0D\n#define EFI_MESSAGING_UART_DP                                       0x0E\n#define EFI_MESSAGING_USB_CLASS_DP                                  0x0F\n#define EFI_MESSAGING_USB_WWID_DP                                   0x10\n#define EFI_MESSAGING_DEVICE_LOGICAL_UNIT_DP                        0x11\n#define EFI_MESSAGING_SATA_DP                                       0x12\n#define EFI_MESSAGING_VLAN_DP                                       0x14\n#define EFI_MESSAGING_FIBRECHANNELEX_DP                             0x15\n#define EFI_MESSAGING_URI_DP                                        0x18\n\n/* EFI media device path subtypes */\n#define EFI_MEDIA_HARDDRIVE_DP                                      0x01\n#define EFI_MEDIA_CDROM_DP                                          0x02\n#define EFI_MEDIA_VENDOR_DP                                         0x03\n#define EFI_MEDIA_FILEPATH_DP                                       0x04\n#define EFI_MEDIA_PROTOCOL_DP                                       0x05\n#define EFI_MEDIA_PIWG_FW_FILE_DP                                   0x06\n#define EFI_MEDIA_PIWG_FW_VOL_DP                                    0x07\n#define EFI_MEDIA_RELATIVE_OFFSET_RANGE_DP                          0x08\n#define EFI_MEDIA_RAMDISK_DP                                        0x09\n\n/* DeviceType definitions according to BBS specification */\n#define EFI_BBS_TYPE_FLOPPY                                         0x01\n#define EFI_BBS_TYPE_HARDDRIVE                                      0x02\n#define EFI_BBS_TYPE_CDROM                                          0x03\n#define EFI_BBS_TYPE_PCMCIA                                         0x04\n#define EFI_BBS_TYPE_USB                                            0x05\n#define EFI_BBS_TYPE_EMBEDDED_NETWORK                               0x06\n#define EFI_BBS_TYPE_DEV                                            0x80\n#define EFI_BBS_TYPE_UNKNOWN                                        0xFF\n\n/* EFI end device path subtypes */\n#define EFI_END_INSTANCE_DP                                         0x01\n#define EFI_END_UNPACKED_DP                                         0x7F\n#define EFI_END_ENTIRE_DP                                           0xFF\n\n/* EFI file open modes */\n#define EFI_FILE_MODE_READ                                          0x0000000000000001\n#define EFI_FILE_MODE_WRITE                                         0x0000000000000002\n#define EFI_FILE_MODE_CREATE                                        0x8000000000000000\n\n/* EFI file attributes */\n#define EFI_FILE_READ_ONLY                                          0x0000000000000001\n#define EFI_FILE_HIDDEN                                             0x0000000000000002\n#define EFI_FILE_SYSTEM                                             0x0000000000000004\n#define EFI_FILE_RESERVIED                                          0x0000000000000008\n#define EFI_FILE_DIRECTORY                                          0x0000000000000010\n#define EFI_FILE_ARCHIVE                                            0x0000000000000020\n#define EFI_FILE_VALID_ATTR                                         0x0000000000000037\n\n/* EFI PCI attributes */\n#define EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO                        0x00001\n#define EFI_PCI_ATTRIBUTE_ISA_IO                                    0x00002\n#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO                            0x00004\n#define EFI_PCI_ATTRIBUTE_VGA_MEMORY                                0x00008\n#define EFI_PCI_ATTRIBUTE_VGA_IO                                    0x00010\n#define EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO                            0x00020\n#define EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO                          0x00040\n#define EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE                      0x00080\n#define EFI_PCI_ATTRIBUTE_IO                                        0x00100\n#define EFI_PCI_ATTRIBUTE_MEMORY                                    0x00200\n#define EFI_PCI_ATTRIBUTE_BUS_MASTER                                0x00400\n#define EFI_PCI_ATTRIBUTE_MEMORY_CACHED                             0x00800\n#define EFI_PCI_ATTRIBUTE_MEMORY_DISABLE                            0x01000\n#define EFI_PCI_ATTRIBUTE_EMBEDDED_DEVICE                           0x02000\n#define EFI_PCI_ATTRIBUTE_EMBEDDED_ROM                              0x04000\n#define EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE                        0x08000\n#define EFI_PCI_ATTRIBUTE_ISA_IO_16                                 0x10000\n#define EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16                         0x20000\n#define EFI_PCI_ATTRIBUTE_VGA_IO_16                                 0x40000\n\n/* EFI UART attributes */\n#define EFI_UART_CLEAR_TO_SEND                                      0x0010\n#define EFI_UART_DATA_SET_READY                                     0x0020\n#define EFI_UART_RING_INDICATE                                      0x0040\n#define EFI_UART_CARRIER_DETECT                                     0x0080\n#define EFI_UART_REQUEST_TO_SEND                                    0x0002\n#define EFI_UART_DATA_TERMINAL_READY                                0x0001\n#define EFI_UART_INPUT_BUFFER_EMPTY                                 0x0100\n#define EFI_UART_OUTPUT_BUFFER_EMPTY                                0x0200\n#define EFI_UART_HARDWARE_LOOPBACK_ENABLE                           0x1000\n#define EFI_UART_SOFTWARE_LOOPBACK_ENABLE                           0x2000\n#define EFI_UART_HARDWARE_FLOW_CONTROL_ENABLE                       0x4000\n\n/* EFI Simple Network protocol */\n#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST                          0x01\n#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST                        0x02\n#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST                        0x04\n#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS                      0x08\n#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST            0x10\n\n/* EFI task priority levels */\n#define EFI_TPL_APPLICATION                                         4\n#define EFI_TPL_CALLBACK                                            8\n#define EFI_TPL_NOTIFY                                              16\n#define EFI_TPL_HIGH_LEVEL                                          31\n\n/* EFI Processor StatusFlag bits */\n#define EFI_PROCESSOR_AS_BSP_BIT                                    0x00000001\n#define EFI_PROCESSOR_ENABLED_BIT                                   0x00000002\n#define EFI_PROCESSOR_HEALTH_STATUS_BIT                             0x00000004\n\n/* EFI list of failed CPUs termination */\n#define EFI_PROCESSOR_END_OF_LIST                                   0xFFFFFFFF\n\n/* EFI text background color definitions */\n#define EFI_TEXT_BGCOLOR_BLACK                                      0x00\n#define EFI_TEXT_BGCOLOR_BLUE                                       0x10\n#define EFI_TEXT_BGCOLOR_GREEN                                      0x20\n#define EFI_TEXT_BGCOLOR_CYAN                                       0x30\n#define EFI_TEXT_BGCOLOR_RED                                        0x40\n#define EFI_TEXT_BGCOLOR_MAGENTA                                    0x50\n#define EFI_TEXT_BGCOLOR_BROWN                                      0x60\n#define EFI_TEXT_BGCOLOR_LIGHTGRAY                                  0x70\n\n/* EFI text foreground color definitions */\n#define EFI_TEXT_FGCOLOR_BLACK                                      0x00\n#define EFI_TEXT_FGCOLOR_BLUE                                       0x01\n#define EFI_TEXT_FGCOLOR_GREEN                                      0x02\n#define EFI_TEXT_FGCOLOR_CYAN                                       0x03\n#define EFI_TEXT_FGCOLOR_RED                                        0x04\n#define EFI_TEXT_FGCOLOR_MAGENTA                                    0x05\n#define EFI_TEXT_FGCOLOR_BROWN                                      0x06\n#define EFI_TEXT_FGCOLOR_LIGHTGRAY                                  0x07\n#define EFI_TEXT_FGCOLOR_DARKGRAY                                   0x08\n#define EFI_TEXT_FGCOLOR_LIGHTBLUE                                  0x09\n#define EFI_TEXT_FGCOLOR_LIGHTGREEN                                 0x0A\n#define EFI_TEXT_FGCOLOR_LIGHTCYAN                                  0x0B\n#define EFI_TEXT_FGCOLOR_LIGHTRED                                   0x0C\n#define EFI_TEXT_FGCOLOR_LIGHTMAGENTA                               0x0D\n#define EFI_TEXT_FGCOLOR_YELLOW                                     0x0E\n#define EFI_TEXT_FGCOLOR_WHITE                                      0x0F\n\n/* EFI text box character definitions */\n#define EFI_TEXT_BOX_HORIZONTAL                                     0x2500\n#define EFI_TEXT_BOX_VERTICAL                                       0x2502\n#define EFI_TEXT_BOX_DOWN_RIGHT                                     0x250C\n#define EFI_TEXT_BOX_DOWN_LEFT                                      0x2510\n#define EFI_TEXT_BOX_UP_RIGHT                                       0x2518\n#define EFI_TEXT_BOX_UP_LEFT                                        0x2514\n#define EFI_TEXT_BOX_VERTICAL_RIGHT                                 0x251C\n#define EFI_TEXT_BOX_VERTICAL_LEFT                                  0x2524\n#define EFI_TEXT_BOX_FULL_BLOCK                                     0x2588\n#define EFI_TEXT_BOX_LIGHT_BLOCK                                    0x2591\n\n/* EFI OS indication bits */\n#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI                            0x0000000000000001ULL\n\n/* EFI protocols GUIDs */\n#define EFI_BLOCK_IO_PROTOCOL_GUID                         {0x964E5B21, 0x6459, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_BLOCK_IO2_PROTOCOL_GUID                        {0xA77B2472, 0xE282, 0x4E9F, {0xA2, 0x45, 0xC2, 0xC0, 0xE2, 0x7B, 0xBC, 0xC1}}\n#define EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID     {0x3BC1B285, 0x8A15, 0x4A82, {0xAA, 0xBF, 0x4D, 0x7D, 0x13, 0xFB, 0x32, 0x65}}\n#define EFI_COMPONENT_NAME_PROTOCOL_GUID                   {0x107A772C, 0xD5E1, 0x11D4, {0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_COMPONENT_NAME2_PROTOCOL_GUID                  {0x6A7A5CFF, 0xE8D9, 0x4F70, {0xBA, 0xDA, 0x75, 0xAB, 0x30, 0x25, 0xCE, 0x14}}\n#define EFI_DEBUG_IMAGE_INFO_TABLE_GUID                    {0x49152E77, 0x1ADA, 0x4764, {0xB7, 0xA2, 0x7A, 0xFE, 0xFE, 0xD9, 0x5E, 0x8B}}\n#define EFI_DEBUG_SUPPORT_PROTOCOL_GUID                    {0x2755590C, 0x6F3C, 0x42FA, {0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25}}\n#define EFI_DEVICE_IO_PROTOCOL_GUID                        {0xAF6AC311, 0x84C3, 0x11D2, {0x8E, 0x3C, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_DEVICE_PATH_PROTOCOL_GUID                      {0x09576E91, 0x6D3F, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID            {0x05C99A21, 0xC70F, 0x4AD2, {0x8A, 0x5F, 0x35, 0xDF, 0x33, 0x43, 0xF5, 0x1E}}\n#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID              {0x8B843E20, 0x8132, 0x4852, {0x90, 0xCC, 0x55, 0x1A, 0x4E, 0x4A, 0x7F, 0x1C}}\n#define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID            {0x0379BE4E, 0xD706, 0x437D, {0xB0, 0x37, 0xED, 0xB8, 0x2F, 0xB7, 0x72, 0xA4}}\n#define EFI_DISK_IO_PROTOCOL_GUID                          {0xCE345171, 0xBA0B, 0x11D2, {0x8E, 0x4F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_DISK_IO2_PROTOCOL_GUID                         {0x151C8EAE, 0x7F2C, 0x472C, {0x9E, 0x54, 0x98, 0x28, 0x19, 0x4F, 0x6A, 0x88}}\n#define EFI_DRIVER_BINDING_PROTOCOL_GUID                   {0x18A031AB, 0xB443, 0x4D1A, {0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71}}\n#define EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL_GUID           {0xB1EE129E, 0xDA36, 0x4181, {0x91, 0xF8, 0x04, 0xA4, 0x92, 0x37, 0x66, 0xA7}}\n#define EFI_EBC_INTERPRETER_PROTOCOL_GUID                  {0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7}}\n#define EFI_EDID_ACTIVE_PROTOCOL_GUID                      {0xBD8C1056, 0x9F36, 0x44EC, {0x92, 0xA8, 0xA6, 0x33, 0x7F, 0x81, 0x79, 0x86}}\n#define EFI_EDID_DISCOVERED_PROTOCOL_GUID                  {0x1C0C34F6, 0xD380, 0x41FA, {0xA0, 0x49, 0x8a, 0xD0, 0x6C, 0x1A, 0x66, 0xAA}}\n#define EFI_EDID_OVERRIDE_PROTOCOL_GUID                    {0x48ECB431, 0xFB72, 0x45C0, {0xA9, 0x22, 0xF4, 0x58, 0xFE, 0x04, 0x0B, 0xD5}}\n#define EFI_FILE_INFO_PROTOCOL_GUID                        {0x09576E92, 0x6D3F, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_FPSWA_PROTOCOL_GUID                            {0xC41B6531, 0x97B9, 0x11D3, {0x9A, 0x29, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_FRAMEWORK_MP_SERVICES_PROTOCOL_GUID            {0xF33261E7, 0x23CB, 0x11D5, {0xBD, 0x5C, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}}\n#define EFI_GLOBAL_VARIABLE_GUID                           {0x8BE4DF61, 0x93CA, 0x11D2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C}}\n#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID                  {0x9042A9DE, 0x23DC, 0x4A38, {0x96, 0xFB, 0x7A, 0xDE, 0xD0, 0x80, 0x51, 0x6A}}\n#define EFI_HASH_PROTOCOL_GUID                             {0xC5184932, 0xDBA5, 0x46DB, {0xA5, 0xBA, 0xCC, 0x0B, 0xDA, 0x9C, 0x14, 0x35}}\n#define EFI_LEGACY_BIOS_PROTOCOL_GUID                      {0xDB9A1E3D, 0x45CB, 0x4ABB, {0x85, 0x3B, 0xE5, 0x38, 0x7F, 0xDB, 0x2E, 0x2D}}\n#define EFI_LOAD_FILE_PROTOCOL_GUID                        {0x56EC3091, 0x954C, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_LOADED_IMAGE_PROTOCOL_GUID                     {0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID         {0xBC62157E, 0x3E33, 0x4FEC, {0x99, 0x20, 0x2D, 0x3B, 0x36, 0xD7, 0x50, 0xDF}}\n#define EFI_MP_SERVICES_PROTOCOL_GUID                      {0x3FDDA605, 0xA76E, 0x4F46, {0xAD, 0x29, 0x12, 0xF4, 0x53, 0x1B, 0x3D, 0x08}}\n#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID     {0xE18541CD, 0xF755, 0x4f73, {0x92, 0x8D, 0x64, 0x3C, 0x8A, 0x79, 0xB2, 0x29}}\n#define EFI_PCI_IO_PROTOCOL_GUID                           {0x4CF5B200, 0x68B8, 0x4CA5, {0x9E, 0xEC, 0xB2, 0x3E, 0x3F, 0x50, 0x02, 0x9A}}\n#define EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID               {0x2F707EBB, 0x4A1A, 0x11d4, {0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL_GUID         {0x6B30C738, 0xA391, 0x11D4, {0x9A, 0x3B, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_PXE_BASE_CODE_PROTOCOL_GUID                    {0x03C4E603, 0xAC28, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3D, 0xC1, 0x4D}}\n#define EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_GUID           {0x245DCA21, 0xFB7F, 0x11D3, {0x8F, 0x01, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_RNG_PROTOCOL_GUID                              {0x3152BCA5, 0xEADE, 0x433D, {0x86, 0x2E, 0xC0, 0x1C, 0xDC, 0x29, 0x1F, 0x44}}\n#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID               {0x964E5B22, 0x6459, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID                   {0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_SIMPLE_POINTER_PROTOCOL_GUID                   {0x31878C87, 0x0B75, 0x11D5, {0x9A, 0x4F, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID                {0x387477C1, 0x69C7, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID             {0xDD9E7534, 0x7762, 0x4698, {0x8C, 0x14, 0xF5, 0x85, 0x17, 0xA6, 0x25, 0xAA}}\n#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID               {0x387477C2, 0x69C7, 0x11D2, {0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}}\n#define EFI_UART_IO_PROTOCOL_GUID                          {0xBB25CF6F, 0xF1D4, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0xFD}}\n#define EFI_UNICODE_COLLATION_PROTOCOL_GUID                {0x1D85CD7F, 0xF43D, 0x11D2, {0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID       {0x982C298B, 0xF4FA, 0x41CB, {0xB8, 0x38, 0x77, 0xAA, 0x68, 0x8F, 0xB8, 0x39}}\n\n/* EFI Configuration Tables GUIDs */\n#define EFI_CONFIG_TABLE_ACPI_TABLE_GUID                   {0xEB9D2D30, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_CONFIG_TABLE_ACPI20_TABLE_GUID                 {0x8868E871, 0xE4F1, 0x11D3, {0xBC, 0x22, 0x00, 0x80, 0xC7, 0x3C, 0x88, 0x81}}\n#define EFI_CONFIG_TABLE_DTB_TABLE_GUID                    {0xB1B621D5, 0xF19C, 0x41A5, {0x83, 0x0B, 0xD9, 0x15, 0x2C, 0x69, 0xAA, 0xE0}}\n#define EFI_CONFIG_TABLE_MPS_TABLE_GUID                    {0xEB9D2D2F, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_CONFIG_TABLE_SAL_SYSTEM_TABLE_GUID             {0xED9D2D32, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_CONFIG_TABLE_SMBIOS_TABLE_GUID                 {0xEB9D2D31, 0x2D88, 0x11D3, {0x9A, 0x16, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}}\n#define EFI_CONFIG_TABLE_SMBIOS3_TABLE_GUID                {0xF2FD1544, 0x9794, 0x4A2C, {0x99, 0x2E, 0xE5, 0xBB, 0xCf, 0x20, 0xE3, 0x94}}\n\n\n/* C/C++ specific code */\n#ifndef __XTOS_ASSEMBLER__\n\n/* Basic UEFI types */\ntypedef PVOID EFI_EVENT, *PEFI_EVENT;\ntypedef PVOID EFI_HANDLE, *PEFI_HANDLE;\ntypedef UINT64 EFI_LBA, *PEFI_LBA;\ntypedef UINT64 EFI_PHYSICAL_ADDRESS, *PEFI_PHYSICAL_ADDRESS;\ntypedef UINT_PTR EFI_STATUS, *PEFI_STATUS;\ntypedef UINT_PTR EFI_TPL, *PEFI_TPL;\ntypedef UINT64 EFI_VIRTUAL_ADDRESS, *PEFI_VIRTUAL_ADDRESS;\n\n/* Enumeration list of EFI memory allocation types */\ntypedef enum _EFI_ALLOCATE_TYPE\n{\n    AllocateAnyPages,\n    AllocateMaxAddress,\n    AllocateAddress,\n    MaxAllocateType\n} EFI_ALLOCATE_TYPE, *PEFI_ALLOCATE_TYPE;\n\n/* Enumeration list of reset types */\ntypedef enum _EFI_RESET_TYPE\n{\n    EfiResetCold,\n    EfiResetWarm,\n    EfiResetShutdown\n} EFI_RESET_TYPE, *PEFI_RESET_TYPE;\n\n/* Enumeration list of timer delay types */\ntypedef enum _EFI_TIMER_DELAY\n{\n    TimerCancel,\n    TimerPeriodic,\n    TimerRelative,\n    TimerTypeMax\n} EFI_TIMER_DELAY, *PEFI_TIMER_DELAY;\n\n/* Enumeration list of EFI Locate Search Types */\ntypedef enum _EFI_LOCATE_SEARCH_TYPE\n{\n    AllHandles,\n    ByRegisterNotify,\n    ByProtocol\n} EFI_LOCATE_SEARCH_TYPE, *PEFI_LOCATE_SEARCH_TYPE;\n\n/* Enumeration list of EFI Interface Types */\ntypedef enum _EFI_INTERFACE_TYPE\n{\n    EFI_NATIVE_INTERFACE,\n    EFI_PCODE_INTERFACE\n} EFI_INTERFACE_TYPE, *PEFI_INTERFACE_TYPE;\n\n/* Enumeration of memory types introduced in UEFI */\ntypedef enum _EFI_MEMORY_TYPE\n{\n    EfiReservedMemoryType,\n    EfiLoaderCode,\n    EfiLoaderData,\n    EfiBootServicesCode,\n    EfiBootServicesData,\n    EfiRuntimeServicesCode,\n    EfiRuntimeServicesData,\n    EfiConventionalMemory,\n    EfiUnusableMemory,\n    EfiACPIReclaimMemory,\n    EfiACPIMemoryNVS,\n    EfiMemoryMappedIO,\n    EfiMemoryMappedIOPortSpace,\n    EfiPalCode,\n    EfiMaxMemoryType\n} EFI_MEMORY_TYPE, *PEFI_MEMORY_TYPE;\n\n/* Enumeration of PCI I/O protocol widths */\ntypedef enum _EFI_PCI_IO_PROTOCOL_WIDTH\n{\n    EfiPciIoWidthUint8,\n    EfiPciIoWidthUint16,\n    EfiPciIoWidthUint32,\n    EfiPciIoWidthUint64,\n    EfiPciIoWidthFifoUint8,\n    EfiPciIoWidthFifoUint16,\n    EfiPciIoWidthFifoUint32,\n    EfiPciIoWidthFifoUint64,\n    EfiPciIoWidthFillUint8,\n    EfiPciIoWidthFillUint16,\n    EfiPciIoWidthFillUint32,\n    EfiPciIoWidthFillUint64,\n    EfiPciIoWidthMaximum\n} EFI_PCI_IO_PROTOCOL_WIDTH, *PEFI_PCI_IO_PROTOCOL_WIDTH;\n\n/* Enumeration of EFI PCI I/O protocol operations */\ntypedef enum _EFI_PCI_IO_PROTOCOL_OPERATION\n{\n    EfiPciIoOperationBusMasterRead,\n    EfiPciIoOperationBusMasterWrite,\n    EfiPciIoOperationBusMasterCommonBuffer,\n    EfiPciIoOperationMaximum\n} EFI_PCI_IO_PROTOCOL_OPERATION, *PEFI_PCI_IO_PROTOCOL_OPERATION;\n\n/* Enumeration of EFI PCI Root Bridge I/O protocol operations */\ntypedef enum _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION\n{\n    EfiPciOperationBusMasterRead,\n    EfiPciOperationBusMasterWrite,\n    EfiPciOperationBusMasterCommonBuffer,\n    EfiPciOperationBusMasterRead64,\n    EfiPciOperationBusMasterWrite64,\n    EfiPciOperationBusMasterCommonBuffer64,\n    EfiPciOperationMaximum\n} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION, *PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION;\n\n/* Enumeration of EFI PCI I/O protocol attribute operations */\ntypedef enum _EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION\n{\n    EfiPciIoAttributeOperationGet,\n    EfiPciIoAttributeOperationSet,\n    EfiPciIoAttributeOperationEnable,\n    EfiPciIoAttributeOperationDisable,\n    EfiPciIoAttributeOperationSupported,\n    EfiPciIoAttributeOperationMaximum\n} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION, *PEFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION;\n\n/* Enumeration of EFI I/O widths */\ntypedef enum _EFI_IO_WIDTH\n{\n    IO_UINT8,\n    IO_UINT16,\n    IO_UINT32,\n    IO_UINT64,\n    MMIO_COPY_UINT8,\n    MMIO_COPY_UINT16,\n    MMIO_COPY_UINT32,\n    MMIO_COPY_UINT64\n} EFI_IO_WIDTH, *PEFI_IO_WIDTH;\n\n/* Enumeration of EFI I/O operation types */\ntypedef enum _EFI_IO_OPERATION_TYPE\n{\n    EfiBusMasterRead,\n    EfiBusMasterWrite,\n    EfiBusMasterCommonBuffer\n} EFI_IO_OPERATION_TYPE, *PEFI_IO_OPERATION_TYPE;\n\n/* Enumeration of EFI GOP output BLT operations */\ntypedef enum _EFI_GRAPHICS_OUTPUT_BLT_OPERATION\n{\n    EfiBltVideoFill,\n    EfiBltVideoToBltBuffer,\n    EfiBltBufferToVideo,\n    EfiBltVideoToVideo,\n    EfiGraphicsOutputBltOperationMax\n} EFI_GRAPHICS_OUTPUT_BLT_OPERATION, *PEFI_GRAPHICS_OUTPUT_BLT_OPERATION;\n\n/* Enumeration of EFI GOP pixel formats */\ntypedef enum _EFI_GRAPHICS_PIXEL_FORMAT\n{\n    PixelRedGreenBlueReserved8BitPerColor,\n    PixelBlueGreenRedReserved8BitPerColor,\n    PixelBitMask,\n    PixelBltOnly,\n    PixelFormatMax\n} EFI_GRAPHICS_PIXEL_FORMAT, *PEFI_GRAPHICS_PIXEL_FORMAT;\n\n/* Enumeration of EGI graphics protocols */\ntypedef enum _EFI_GRAPHICS_PROTOCOL\n{\n    NONE,\n    GOP,\n    UGA\n} EFI_GRAPHICS_PROTOCOL, *PEFI_GRAPHICS_PROTOCOL;\n\n/* Enumeration of EFI UGA output BLT operations */\ntypedef enum _EFI_UNIVERSA_GRAPHICS_BLT_OPERATION\n{\n    EfiUgaVideoFill,\n    EfiUgaVideoToBltBuffer,\n    EfiUgaBltBufferToVideo,\n    EfiUgaVideoToVideo,\n    EfiUgaBltMax\n} EFI_UNIVERSA_GRAPHICS_BLT_OPERATION, *PEFI_UNIVERSA_GRAPHICS_BLT_OPERATION;\n\n/* Enumeration of UART parity types */\ntypedef enum _EFI_UART_PARITY_TYPE\n{\n    DefaultParity,\n    NoParity,\n    EvenParity,\n    OddParity,\n    MarkParity,\n    SpaceParity\n} EFI_UART_PARITY_TYPE, *PEFI_UART_PARITY_TYPE;\n\n/* Enumeration of UART stop bit types */\ntypedef enum _EFI_UART_STOP_BITS_TYPE\n{\n    DefaultStopBits,\n    OneStopBit,\n    OneFiveStopBits,\n    TwoStopBits\n} EFI_UART_STOP_BITS_TYPE, *PEFI_UART_STOP_BITS_TYPE;\n\n/* Enumeration of CPU designations */\ntypedef enum _EFI_FRAMEWORK_CPU_DESIGNATION\n{\n    EfiCpuAP,\n    EfiCpuBSP,\n    EfiCpuDesignationMaximum\n} EFI_FRAMEWORK_CPU_DESIGNATION, *PEFI_FRAMEWORK_CPU_DESIGNATION;\n\n/* Enumeration of network state */\ntypedef enum _EFI_SIMPLE_NETWORK_STATE\n{\n    EfiSimpleNetworkStopped,\n    EfiSimpleNetworkStarted,\n    EfiSimpleNetworkInitialized,\n    EfiSimpleNetworkMaxState\n} EFI_SIMPLE_NETWORK_STATE, *PEFI_SIMPLE_NETWORK_STATE;\n\n/* Enumeration of PXE TFTP opcodes */\ntypedef enum _EFI_PXE_BASE_CODE_TFTP_OPCODE\n{\n    EFI_PXE_BASE_CODE_TFTP_FIRST,\n    EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,\n    EFI_PXE_BASE_CODE_TFTP_READ_FILE,\n    EFI_PXE_BASE_CODE_TFTP_WRITE_FILE,\n    EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY,\n    EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE,\n    EFI_PXE_BASE_CODE_MTFTP_READ_FILE,\n    EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY,\n    EFI_PXE_BASE_CODE_MTFTP_LAST\n} EFI_PXE_BASE_CODE_TFTP_OPCODE, *PEFI_PXE_BASE_CODE_TFTP_OPCODE;\n\n/* Enumeration of PXE functions */\ntypedef enum _EFI_PXE_BASE_CODE_FUNCTION\n{\n    EFI_PXE_BASE_CODE_FUNCTION_FIRST,\n    EFI_PXE_BASE_CODE_FUNCTION_DHCP,\n    EFI_PXE_BASE_CODE_FUNCTION_DISCOVER,\n    EFI_PXE_BASE_CODE_FUNCTION_MTFTP,\n    EFI_PXE_BASE_CODE_FUNCTION_UDP_WRITE,\n    EFI_PXE_BASE_CODE_FUNCTION_UDP_READ,\n    EFI_PXE_BASE_CODE_FUNCTION_ARP,\n    EFI_PXE_BASE_CODE_FUNCTION_IGMP,\n    EFI_PXE_BASE_CODE_PXE_FUNCTION_LAST\n} EFI_PXE_BASE_CODE_FUNCTION, *PEFI_PXE_BASE_CODE_FUNCTION;\n\n/* Enumeration of PXE callback statuses */\ntypedef enum _EFI_PXE_BASE_CODE_CALLBACK_STATUS\n{\n    EFI_PXE_BASE_CODE_CALLBACK_STATUS_FIRST,\n    EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE,\n    EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT,\n    EFI_PXE_BASE_CODE_CALLBACK_STATUS_LAST\n} EFI_PXE_BASE_CODE_CALLBACK_STATUS, *PEFI_PXE_BASE_CODE_CALLBACK_STATUS;\n\n/* EFI routine callbacks */\ntypedef EFI_STATUS (*PEFI_CONVERT_POINTER)(IN UINT_PTR DebugDisposition, IN OUT PVOID *Address);\ntypedef EFI_STATUS (*PEFI_ALLOCATE_PAGES)(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINT_PTR NoPages, OUT PEFI_PHYSICAL_ADDRESS Memory);\ntypedef EFI_STATUS (*PEFI_ALLOCATE_POOL)(IN EFI_MEMORY_TYPE PoolType, IN UINT_PTR Size, OUT PVOID *Buffer);\ntypedef EFI_STATUS (*PEFI_FREE_PAGES)(IN EFI_PHYSICAL_ADDRESS Memory, IN UINT_PTR NoPages);\ntypedef EFI_STATUS (*PEFI_FREE_POOL)(IN PVOID Buffer);\ntypedef VOID (*PEFI_EVENT_NOTIFY)(IN EFI_EVENT Event, IN PVOID Context);\ntypedef EFI_STATUS (*PEFI_CREATE_EVENT)(IN UINT32 Type, IN EFI_TPL NotifyTpl, IN PEFI_EVENT_NOTIFY NotifyFunction, IN PVOID NotifyContext, OUT PEFI_EVENT Event);\ntypedef EFI_STATUS (*PEFI_GET_MEMORY_MAP)(IN OUT PUINT_PTR MemoryMapSize, IN OUT PEFI_MEMORY_DESCRIPTOR MemoryMap, OUT PUINT_PTR MapKey, OUT PUINT_PTR DescriptorSize, OUT PUINT32 DescriptorVersion);\ntypedef EFI_STATUS (*PEFI_GET_VARIABLE)(IN PWCHAR VariableName, IN PEFI_GUID VendorGuid, OUT PUINT32 Attributes, IN OUT PUINT_PTR DataSize, OUT PVOID Data);\ntypedef EFI_STATUS (*PEFI_GET_NEXT_HIGH_MONO_COUNT)(OUT PUINT32 HighCount);\ntypedef EFI_STATUS (*PEFI_GET_NEXT_VARIABLE_NAME)(IN OUT PUINT_PTR VariableNameSize, IN OUT PWCHAR VariableName, IN OUT PEFI_GUID VendorGuid);\ntypedef EFI_STATUS (*PEFI_GET_TIME)(OUT PEFI_TIME Time, OUT PEFI_TIME_CAPABILITIES Capabilities);\ntypedef EFI_STATUS (*PEFI_SET_TIME)(IN PEFI_TIME Time);\ntypedef EFI_STATUS (*PEFI_SET_TIMER)(IN EFI_EVENT Event, IN EFI_TIMER_DELAY Type, IN UINT64 TriggerTime);\ntypedef EFI_STATUS (*PEFI_SIGNAL_EVENT)(IN EFI_EVENT Event);\ntypedef EFI_STATUS (*PEFI_CLOSE_EVENT)(IN EFI_EVENT Event);\ntypedef EFI_STATUS (*PEFI_CHECK_EVENT)(IN EFI_EVENT Event);\ntypedef EFI_STATUS (*PEFI_CREATE_EVENT_EX)(IN UINT32 Type, IN EFI_TPL NotifyTpl, IN PEFI_EVENT_NOTIFY NotifyFunction, IN CONST PVOID NotifyContext, IN CONST PEFI_GUID EventGroup, OUT PEFI_EVENT Event);\ntypedef EFI_STATUS (*PEFI_WAIT_FOR_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index);\ntypedef EFI_STATUS (*PEFI_QUERY_CAPSULE_CAPABILITIES)(IN PEFI_CAPSULE_HEADER *CapsuleHeaderArray, IN UINT_PTR CapsuleCount, OUT PUINT64 MaximumCapsuleSize, OUT PEFI_RESET_TYPE ResetType);\ntypedef EFI_STATUS (*PEFI_QUERY_VARIABLE_INFO)(IN UINT32 Attributes, OUT PUINT64 MaximumVariableStorageSize, OUT PUINT64 RemainingVariableStorageSize, OUT PUINT64 MaximumVariableSize);\ntypedef EFI_STATUS (*PEFI_RAISE_TPL)(IN EFI_TPL NewTpl);\ntypedef EFI_STATUS (*PEFI_RESET_SYSTEM)(IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINT_PTR DataSize, IN PWCHAR ResetData);\ntypedef EFI_STATUS (*PEFI_RESTORE_TPL)(IN EFI_TPL OldTpl);\ntypedef EFI_STATUS (*PEFI_UPDATE_CAPSULE)(IN PEFI_CAPSULE_HEADER *CapsuleHeaderArray, IN UINT_PTR CapsuleCount, IN EFI_PHYSICAL_ADDRESS ScatterGatherList);\ntypedef EFI_STATUS (*PEFI_SET_VARIABLE)(IN PWCHAR VariableName, IN PEFI_GUID VendorGuid, IN UINT32 Attributes, IN UINT_PTR DataSize, IN PVOID Data);\ntypedef EFI_STATUS (*PEFI_SET_VIRTUAL_ADDRESS_MAP)(IN UINT_PTR MemoryMapSize, IN UINT_PTR DescriptorSize, IN UINT32 DescriptorVersion, IN PEFI_MEMORY_DESCRIPTOR VirtualMap);\ntypedef EFI_STATUS (*PEFI_GET_WAKEUP_TIME)(OUT BOOLEAN Enabled, OUT BOOLEAN Pending, OUT PEFI_TIME Time);\ntypedef EFI_STATUS (*PEFI_SET_WAKEUP_TIME)(IN BOOLEAN Enable, IN PEFI_TIME Time);\ntypedef EFI_STATUS (*PEFI_INSTALL_PROTOCOL_INTERFACE)(IN OUT PEFI_HANDLE Handle, IN PEFI_GUID Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN PVOID Interface);\ntypedef EFI_STATUS (*PEFI_REINSTALL_PROTOCOL_INTERFACE)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, IN PVOID OldInterface, IN PVOID NewInterface);\ntypedef EFI_STATUS (*PEFI_UNINSTALL_PROTOCOL_INTERFACE)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, IN PVOID Interface);\ntypedef EFI_STATUS (*PEFI_HANDLE_PROTOCOL)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, OUT PVOID *Interface);\ntypedef EFI_STATUS (*PEFI_REGISTER_PROTOCOL_NOTIFY)(IN PEFI_GUID Protocol, IN EFI_EVENT Event, OUT PVOID *Registration);\ntypedef EFI_STATUS (*PEFI_LOCATE_HANDLE)(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN PEFI_GUID Protocol, IN PVOID SearchKey, IN OUT PUINT_PTR BufferSize, OUT PEFI_HANDLE Buffer);\ntypedef EFI_STATUS (*PEFI_LOCATE_DEVICE_PATH)(IN PEFI_GUID Protocol, IN OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT PEFI_HANDLE Device);\ntypedef EFI_STATUS (*PEFI_LOCATE_HANDLE_BUFFER)(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN PEFI_GUID Protocol, IN PVOID SearchKey, IN OUT PUINT_PTR NoHandles, OUT PEFI_HANDLE *Buffer);\ntypedef EFI_STATUS (*PEFI_LOCATE_PROTOCOL)(IN PEFI_GUID Protocol, IN PVOID Registration, OUT PVOID *Interface);\ntypedef EFI_STATUS (*PEFI_INSTALL_CONFIGURATION_TABLE)(IN PEFI_GUID Guid, IN PVOID Table);\ntypedef EFI_STATUS (*PEFI_IMAGE_LOAD)(IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN PVOID SourceBuffer, IN UINT_PTR SourceSize, OUT PEFI_HANDLE ImageHandle);\ntypedef EFI_STATUS (*PEFI_IMAGE_UNLOAD)(IN EFI_HANDLE ImageHandle);\ntypedef EFI_STATUS (*PEFI_IMAGE_START)(IN EFI_HANDLE ImageHandle, OUT PUINT_PTR ExitDataSize, OUT PWCHAR *ExitData);\ntypedef EFI_STATUS (*PEFI_EXIT)(IN EFI_HANDLE ImageHandle, IN EFI_STATUS ExitStatus, IN UINT_PTR ExitDataSize, IN PWCHAR ExitData);\ntypedef EFI_STATUS (*PEFI_EXIT_BOOT_SERVICES)(IN EFI_HANDLE ImageHandle, IN UINT_PTR MapKey);\ntypedef EFI_STATUS (*PEFI_GET_NEXT_MONOTONIC_COUNT)(OUT PUINT64 Count);\ntypedef EFI_STATUS (*PEFI_STALL)(IN UINT_PTR Microseconds);\ntypedef EFI_STATUS (*PEFI_SET_WATCHDOG_TIMER)(IN UINT_PTR Timeout, IN UINT64 WatchdogCode, IN UINT_PTR DataSize, IN PWCHAR WatchdogData);\ntypedef EFI_STATUS (*PEFI_CONNECT_CONTROLLER)(IN EFI_HANDLE ControllerHandle, IN PEFI_HANDLE DriverImageHandle, IN PEFI_DEVICE_PATH_PROTOCOL RemainingDevicePath, IN BOOLEAN Recursive);\ntypedef EFI_STATUS (*PEFI_DISCONNECT_CONTROLLER)(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE DriverImageHandle, IN EFI_HANDLE ChildHandle);\ntypedef EFI_STATUS (*PEFI_OPEN_PROTOCOL)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, OUT PVOID *Interface, IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle, IN UINT32 Attributes);\ntypedef EFI_STATUS (*PEFI_CLOSE_PROTOCOL)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle);\ntypedef EFI_STATUS (*PEFI_OPEN_PROTOCOL_INFORMATION)(IN EFI_HANDLE Handle, IN PEFI_GUID Protocol, OUT PEFI_OPEN_PROTOCOL_INFORMATION_ENTRY *EntryBuffer, OUT PUINT_PTR EntryCount);\ntypedef EFI_STATUS (*PEFI_PROTOCOLS_PER_HANDLE)(IN EFI_HANDLE Handle, OUT PEFI_GUID **ProtocolBuffer, OUT PUINT_PTR ProtocolBufferCount);\ntypedef EFI_STATUS (*PEFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)(IN OUT PEFI_HANDLE Handle, ...);\ntypedef EFI_STATUS (*PEFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)(IN OUT PEFI_HANDLE Handle, ...);\ntypedef EFI_STATUS (*PEFI_CALCULATE_CRC32)(IN PVOID Data, IN UINT_PTR DataSize, OUT PUINT32 Crc32);\ntypedef EFI_STATUS (*PEFI_COPY_MEM)(IN OUT PVOID Destination, IN PVOID Source, IN UINT_PTR Length);\ntypedef EFI_STATUS (*PEFI_SET_MEM)(IN OUT PVOID Buffer, IN UINT_PTR Size, IN UINT8 Value);\ntypedef EFI_STATUS (*PEFI_INPUT_RESET)(IN PEFI_SIMPLE_TEXT_INPUT_PROTOCOL This, IN BOOLEAN ExtendedVerification);\ntypedef EFI_STATUS (*PEFI_INPUT_READ_KEY)(IN PEFI_SIMPLE_TEXT_INPUT_PROTOCOL This, OUT PEFI_INPUT_KEY Key);\ntypedef EFI_STATUS (*PEFI_TEXT_RESET)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN BOOLEAN ExtendedVerification);\ntypedef EFI_STATUS (*PEFI_TEXT_OUTPUT_STRING)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN PWCHAR String);\ntypedef EFI_STATUS (*PEFI_TEXT_TEST_STRING)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN PWCHAR String);\ntypedef EFI_STATUS (*PEFI_TEXT_QUERY_MODE)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UINT_PTR ModeNumber, OUT PUINT_PTR Columns, OUT PUINT_PTR Rows);\ntypedef EFI_STATUS (*PEFI_TEXT_SET_MODE)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UINT_PTR ModeNumber);\ntypedef EFI_STATUS (*PEFI_TEXT_SET_ATTRIBUTE)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UINT_PTR Attribute);\ntypedef EFI_STATUS (*PEFI_TEXT_CLEAR_SCREEN)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_TEXT_SET_CURSOR_POSITION)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN UINT_PTR Column, IN UINT_PTR Row);\ntypedef EFI_STATUS (*PEFI_TEXT_ENABLE_CURSOR)(IN PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL This, IN BOOLEAN Enable);\ntypedef EFI_STATUS (*PEFI_INPUT_RESET_EX)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, IN BOOLEAN ExtendedVerification);\ntypedef EFI_STATUS (*PEFI_INPUT_READ_KEY_EX)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, OUT PEFI_KEY_DATA KeyData);\ntypedef EFI_STATUS (*PEFI_SET_STATE)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, IN PUINT8 KeyToggleState);\ntypedef EFI_STATUS (*PEFI_KEY_NOTIFY_FUNCTION)(IN PEFI_KEY_DATA KeyData);\ntypedef EFI_STATUS (*PEFI_REGISTER_KEYSTROKE_NOTIFY)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, IN PEFI_KEY_DATA KeyData, IN PEFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, OUT PVOID *NotifyHandle);\ntypedef EFI_STATUS (*PEFI_UNREGISTER_KEYSTROKE_NOTIFY)(IN PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL This, IN PVOID NotificationHandle);\ntypedef PUINT16 (*PEFI_DEVICE_PATH_TO_TEXT_NODE)(IN CONST PEFI_DEVICE_PATH_PROTOCOL DeviceNode, IN UCHAR DisplayOnly, IN UCHAR AllowShortcuts);\ntypedef PUINT16 (*PEFI_DEVICE_PATH_TO_TEXT_PATH)(IN CONST PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN UCHAR DisplayOnly, IN UCHAR AllowShortcuts);\ntypedef PEFI_DEVICE_PATH_PROTOCOL (*PEFI_DEVICE_PATH_FROM_TEXT_NODE)(IN CONST PUINT16 TextDeviceNode);\ntypedef PEFI_DEVICE_PATH_PROTOCOL (*PEFI_DEVICE_PATH_FROM_TEXT_PATH)(IN CONST PUINT16 TextDevicePath);\ntypedef UINT_PTR (*PEFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)(IN CONST PEFI_DEVICE_PATH_PROTOCOL DevicePath);\ntypedef PEFI_DEVICE_PATH_PROTOCOL (*PEFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)(IN CONST PEFI_DEVICE_PATH_PROTOCOL DevicePath);\ntypedef PEFI_DEVICE_PATH_PROTOCOL (*PEFI_DEVICE_PATH_UTILS_APPEND_PATH)(IN CONST PEFI_DEVICE_PATH_PROTOCOL Src1, IN CONST PEFI_DEVICE_PATH_PROTOCOL Src2);\ntypedef PEFI_DEVICE_PATH_PROTOCOL (*PEFI_DEVICE_PATH_UTILS_APPEND_NODE)(IN CONST PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN CONST PEFI_DEVICE_PATH_PROTOCOL DeviceNode);\ntypedef PEFI_DEVICE_PATH_PROTOCOL (*PEFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)(IN CONST PEFI_DEVICE_PATH_PROTOCOL DevicePath, IN CONST PEFI_DEVICE_PATH_PROTOCOL DevicePathInstance);\ntypedef PEFI_DEVICE_PATH_PROTOCOL (*PEFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)(IN OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePathInstance, OUT PUINT_PTR DevicePathInstanceSize);\ntypedef PEFI_DEVICE_PATH_PROTOCOL (*PEFI_DEVICE_PATH_UTILS_CREATE_NODE)(IN UINT8 NodeType, IN UINT8 NodeSubType, IN UINT16 NodeLength);\ntypedef UCHAR (*PEFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)(IN CONST PEFI_DEVICE_PATH_PROTOCOL DevicePath);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_POLL_IO_MEM)(IN PEFI_PCI_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT PUINT64 Result);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT PUINT64 Result);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_IO_MEM)(IN PEFI_PCI_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINT_PTR Count, IN OUT PVOID Buffer);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINT_PTR Count, IN OUT PVOID Buffer);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_CONFIG)(IN PEFI_PCI_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT32 Offset, IN UINT_PTR Count, IN OUT PVOID Buffer);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, OUT PVOID *Resources);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_COPY_MEM)(IN PEFI_PCI_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 DestBarIndex, IN UINT64 DestOffset, IN UINT8 SrcBarIndex, IN UINT64 SrcOffset, IN UINT_PTR Count);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT64 DestAddress, IN UINT64 SrcAddress, IN UINT_PTR Count);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_MAP)(IN PEFI_PCI_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_OPERATION Operation, IN PVOID HostAddress, IN OUT PUINT_PTR NumberOfBytes, OUT PEFI_PHYSICAL_ADDRESS DeviceAddress, OUT PVOID *Mapping);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation, IN PVOID HostAddress, IN OUT PUINT_PTR NumberOfBytes, OUT PEFI_PHYSICAL_ADDRESS DeviceAddress, OUT PVOID *Mapping);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_UNMAP)(IN PEFI_PCI_IO_PROTOCOL This, IN PVOID Mapping);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN PVOID Mapping);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER)(IN PEFI_PCI_IO_PROTOCOL This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINT_PTR Pages, OUT PVOID *HostAddress, IN UINT64 Attributes);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINT_PTR Pages, IN OUT PVOID *HostAddress, IN UINT64 Attributes);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_FREE_BUFFER)(IN PEFI_PCI_IO_PROTOCOL This, IN UINT_PTR Pages, IN PVOID HostAddress);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN UINT_PTR Pages, IN PVOID HostAddress);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_FLUSH)(IN PEFI_PCI_IO_PROTOCOL This);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_GET_LOCATION)(IN PEFI_PCI_IO_PROTOCOL This, OUT PUINT_PTR SegmentNumber, OUT PUINT_PTR BusNumber, OUT PUINT_PTR DeviceNumber, OUT PUINT_PTR FunctionNumber);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_ATTRIBUTES)(IN PEFI_PCI_IO_PROTOCOL This, IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation, IN UINT64 Attributes, OUT PUINT64 Result);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES)(IN PEFI_PCI_IO_PROTOCOL This, IN UINT8 BarIndex, OUT PUINT64 Supports, OUT PVOID *Resources);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, OUT PUINT64 Supports, OUT PUINT64 Attributes);\ntypedef EFI_STATUS (*EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES)(IN PEFI_PCI_IO_PROTOCOL This, IN UINT64 Attributes, IN UINT8 BarIndex, IN OUT PUINT64 Offset, IN OUT PUINT64 Length);\ntypedef EFI_STATUS (*EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES)(IN PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL This, IN UINT64 Attributes, IN OUT PUINT64 ResourceBase, IN OUT PUINT64 ResourceLength);\ntypedef EFI_STATUS (*PEFI_BLOCK_RESET)(IN PEFI_BLOCK_IO_PROTOCOL This, IN BOOLEAN ExtendedVerification);\ntypedef EFI_STATUS (*PEFI_BLOCK_READ)(IN PEFI_BLOCK_IO_PROTOCOL This, IN UINT32 MediaId, IN EFI_LBA LBA, IN UINT_PTR BufferSize, OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_BLOCK_WRITE)(IN PEFI_BLOCK_IO_PROTOCOL This, IN UINT32 MediaId, IN EFI_LBA LBA, IN UINT_PTR BufferSize, IN PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_BLOCK_FLUSH)(IN PEFI_BLOCK_IO_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_BLOCK_RESET_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN BOOLEAN ExtendedVerification);\ntypedef EFI_STATUS (*PEFI_BLOCK_READ_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN UINT32 MediaId, IN EFI_LBA LBA, IN OUT PEFI_BLOCK_IO2_TOKEN Token, IN UINT_PTR BufferSize, OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_BLOCK_WRITE_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN UINT32 MediaId, IN EFI_LBA LBA, IN OUT PEFI_BLOCK_IO2_TOKEN Token, IN UINT_PTR BufferSize, IN PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_BLOCK_FLUSH_EX)(IN PEFI_BLOCK_IO2_PROTOCOL This, IN OUT PEFI_BLOCK_IO2_TOKEN Token);\ntypedef EFI_STATUS (*PEFI_DISK_READ)(IN PEFI_DISK_IO_PROTOCOL This, IN UINT32 MediaId, IN UINT64 Offset, IN UINT_PTR BufferSize, OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_DISK_WRITE)(IN PEFI_DISK_IO_PROTOCOL This, IN UINT32 MediaId, IN UINT64 Offset, IN UINT_PTR BufferSize, IN PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_DISK_CANCEL_EX)(IN PEFI_DISK_IO2_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_DISK_READ_EX)(IN PEFI_DISK_IO2_PROTOCOL This, IN UINT32 MediaId, IN UINT64 Offset, IN OUT PEFI_DISK_IO2_TOKEN Token, IN UINT_PTR BufferSize, OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_DISK_WRITE_EX)(IN PEFI_DISK_IO2_PROTOCOL This, IN UINT32 MediaId, IN UINT64 Offset, IN OUT PEFI_DISK_IO2_TOKEN Token, IN UINT_PTR BufferSize, IN PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_DISK_FLUSH_EX)(IN PEFI_DISK_IO2_PROTOCOL This, IN OUT PEFI_DISK_IO2_TOKEN Token);\ntypedef EFI_STATUS (*PEFI_VOLUME_OPEN)(IN PEFI_SIMPLE_FILE_SYSTEM_PROTOCOL This, OUT PEFI_FILE_HANDLE *Root);\ntypedef EFI_STATUS (*PEFI_FILE_OPEN)(IN PEFI_FILE_HANDLE File, OUT PEFI_FILE_HANDLE *NewHandle, IN PWCHAR FileName, IN UINT64 OpenMode, IN UINT64 Attributes);\ntypedef EFI_STATUS (*PEFI_FILE_CLOSE)(IN PEFI_FILE_HANDLE File);\ntypedef EFI_STATUS (*PEFI_FILE_DELETE)(IN PEFI_FILE_HANDLE File);\ntypedef EFI_STATUS (*PEFI_FILE_READ)(IN PEFI_FILE_HANDLE File, IN OUT PUINT_PTR BufferSize, OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_FILE_WRITE)(IN PEFI_FILE_HANDLE File, IN OUT PUINT_PTR BufferSize, IN PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_FILE_SET_POSITION)(IN PEFI_FILE_HANDLE File, IN UINT64 Position);\ntypedef EFI_STATUS (*PEFI_FILE_GET_POSITION)(IN PEFI_FILE_HANDLE File, OUT PUINT64 Position);\ntypedef EFI_STATUS (*PEFI_FILE_GET_INFO)(IN PEFI_FILE_HANDLE File, IN PEFI_GUID InformationType, IN OUT PUINT_PTR BufferSize, OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_FILE_SET_INFO)(IN PEFI_FILE_HANDLE File, IN PEFI_GUID InformationType, IN UINT_PTR BufferSize, IN PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_FILE_FLUSH)(IN PEFI_FILE_HANDLE File);\ntypedef EFI_STATUS (*PEFI_FILE_OPEN_EX)(IN PEFI_FILE_HANDLE File, OUT PEFI_FILE_HANDLE *NewHandle, IN PWCHAR FileName, IN UINT64 OpenMode, IN UINT64 Attributes, IN OUT PEFI_FILE_IO_TOKEN Token);\ntypedef EFI_STATUS (*PEFI_FILE_READ_EX)(IN PEFI_FILE_HANDLE File, IN OUT PEFI_FILE_IO_TOKEN Token);\ntypedef EFI_STATUS (*PEFI_FILE_WRITE_EX)(IN PEFI_FILE_HANDLE File, IN OUT PEFI_FILE_IO_TOKEN Token);\ntypedef EFI_STATUS (*PEFI_FILE_FLUSH_EX)(IN PEFI_FILE_HANDLE File, IN OUT PEFI_FILE_IO_TOKEN Token);\ntypedef EFI_STATUS (*PEFI_LOAD_FILE)(IN PEFI_LOAD_FILE_PROTOCOL This, IN PEFI_DEVICE_PATH_PROTOCOL FilePath, IN UCHAR BootPolicy, IN OUT PUINT_PTR BufferSize, IN PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_DEVICE_IO)(IN PEFI_DEVICE_IO_PROTOCOL This, IN EFI_IO_WIDTH Width, IN UINT64 Address, IN UINT_PTR Count, IN OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_PCIDEV_DEVICE_PATH)(IN PEFI_DEVICE_IO_PROTOCOL This, IN UINT64 Address, IN OUT PEFI_DEVICE_PATH_PROTOCOL *PciDevicePath);\ntypedef EFI_STATUS (*PEFI_IO_MAP)(IN PEFI_DEVICE_IO_PROTOCOL This, IN EFI_IO_OPERATION_TYPE Operation, IN PEFI_PHYSICAL_ADDRESS HostAddress, IN OUT PUINT_PTR NumberOfBytes, OUT PEFI_PHYSICAL_ADDRESS DeviceAddress, OUT PVOID *Mapping);\ntypedef EFI_STATUS (*PEFI_IO_UNMAP)(IN PEFI_DEVICE_IO_PROTOCOL This, IN PVOID Mapping);\ntypedef EFI_STATUS (*PEFI_IO_ALLOCATE_BUFFER)(IN PEFI_DEVICE_IO_PROTOCOL This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINT_PTR Pages, IN OUT PEFI_PHYSICAL_ADDRESS HostAddress);\ntypedef EFI_STATUS (*PEFI_IO_FLUSH)(IN PEFI_DEVICE_IO_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_IO_FREE_BUFFER)(IN PEFI_DEVICE_IO_PROTOCOL This, IN UINT_PTR Pages, IN EFI_PHYSICAL_ADDRESS HostAddress);\ntypedef INT_PTR (*PEFI_UNICODE_STRICOLL)(IN PEFI_UNICODE_COLLATION_PROTOCOL This, IN PUINT16 s1, IN PUINT16 s2);\ntypedef UCHAR (*PEFI_UNICODE_METAIMATCH)(IN PEFI_UNICODE_COLLATION_PROTOCOL This, IN PUINT16 String, IN PUINT16 Pattern);\ntypedef VOID (*PEFI_UNICODE_STRLWR)(IN PEFI_UNICODE_COLLATION_PROTOCOL This, IN OUT PUINT16 Str);\ntypedef VOID (*PEFI_UNICODE_STRUPR)(IN PEFI_UNICODE_COLLATION_PROTOCOL This, IN OUT PUINT16 Str);\ntypedef VOID (*PEFI_UNICODE_FATTOSTR)(IN PEFI_UNICODE_COLLATION_PROTOCOL This, IN UINT_PTR FatSize, IN PUINT8 Fat, OUT PUINT16 String);\ntypedef UCHAR (*PEFI_UNICODE_STRTOFAT)(IN PEFI_UNICODE_COLLATION_PROTOCOL This, IN PUINT16 String, IN UINT_PTR FatSize, OUT PUINT8 Fat);\ntypedef EFI_STATUS (*PEFI_HASH_GET_HASH_SIZE)(IN CONST PEFI_HASH_PROTOCOL This, IN CONST PEFI_GUID HashAlgorithm, OUT PUINT_PTR HashSize);\ntypedef EFI_STATUS (*PEFI_HASH_HASH)(IN CONST PEFI_HASH_PROTOCOL This, IN CONST PEFI_GUID HashAlgorithm, IN UCHAR Extend, IN CONST PUINT8 Message, IN UINT64 MessageSize, IN OUT PEFI_HASH_OUTPUT Hash);\ntypedef EFI_STATUS (*PEFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE)(IN PEFI_GRAPHICS_OUTPUT_PROTOCOL This, IN UINT32 ModeNumber, OUT PUINT_PTR SizeOfInfo, OUT PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info);\ntypedef EFI_STATUS (*PEFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE)(IN PEFI_GRAPHICS_OUTPUT_PROTOCOL This, IN UINT32 ModeNumber);\ntypedef EFI_STATUS (*PEFI_GRAPHICS_OUTPUT_PROTOCOL_BLT)(IN PEFI_GRAPHICS_OUTPUT_PROTOCOL This, IN PEFI_GRAPHICS_OUTPUT_BLT_PIXEL BltBuffer, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINT_PTR SourceX, IN UINT_PTR SourceY, IN UINT_PTR DestinationX, IN UINT_PTR DestinationY, IN UINT_PTR Width, IN UINT_PTR Height, IN UINT_PTR Delta);\ntypedef EFI_STATUS (*PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GET_MODE)(IN PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL This, OUT PUINT32 HorizontalResolution, OUT PUINT32 VerticalResolution, OUT PUINT32 ColorDepth, OUT PUINT32 RefreshRate);\ntypedef EFI_STATUS (*PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_SET_MODE)(IN PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL This, IN UINT32 HorizontalResolution, IN UINT32 VerticalResolution, IN UINT32 ColorDepth, IN UINT32 RefreshRate);\ntypedef EFI_STATUS (*PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_BLT)(IN PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL This, IN PEFI_UNIVERSAL_GRAPHICS_BLT_PIXEL BltBuffer, IN EFI_UNIVERSA_GRAPHICS_BLT_OPERATION BltOperation, IN UINT_PTR SourceX, IN UINT_PTR SourceY, IN UINT_PTR DestinationX, IN UINT_PTR DestinationY, IN UINT_PTR Width, IN UINT_PTR Height, IN UINT_PTR Delta);\ntypedef EFI_STATUS (*PEFI_EDID_OVERRIDE_PROTOCOL_GET_EDID)(IN PEFI_EDID_OVERRIDE_PROTOCOL This, IN PEFI_HANDLE ChildHandle, OUT PUINT32 Attributes, IN OUT PUINT_PTR EdidSize, IN OUT PUINT8 *Edid);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_BOOT)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN PEFI_BBS_BBS_DEVICE_PATH BootOption, IN UINT32 LoadOptionsSize, IN PVOID LoadOptions);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN EFI_UDC_ATTRIBUTES Attributes, IN UINT_PTR BbsEntry, IN PVOID BeerData, IN PVOID ServiceAreaData);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_CHECK_ROM)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN EFI_HANDLE PciHandle, OUT PVOID *RomImage, OUT PUINT_PTR RomSize, OUT PUINT_PTR Flags);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_COPY_LEGACY_REGION)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN UINT_PTR LegacyMemorySize, IN VOID *LegacyMemoryAddress, IN VOID *LegacyMemorySourceAddress);\ntypedef BOOLEAN (*PEFI_LEGACY_BIOS_FARCALL86)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN UINT16 Segment, IN UINT16 Offset, IN PEFI_IA32_REGISTER_SET Regs, IN PVOID Stack, IN UINT_PTR StackSize);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_GET_BBS_INFO)(IN PEFI_LEGACY_BIOS_PROTOCOL This, OUT PUINT16 HddCount, OUT PEFI_HDD_INFO *HddInfo, OUT PUINT16 BbsCount, IN OUT PEFI_BBS_TABLE *BbsTable);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_GET_LEGACY_REGION)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN UINT_PTR LegacyMemorySize, IN UINT_PTR Region, IN UINT_PTR Alignment, OUT PVOID *LegacyMemoryAddress);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_INSTALL_ROM)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN EFI_HANDLE PciHandle, IN PVOID *RomImage, OUT PUINT_PTR Flags, OUT PUINT8 DiskStart, OUT PUINT8 DiskEnd, OUT PVOID *RomShadowAddress, OUT PUINT32 ShadowedRomSize);\ntypedef BOOLEAN (*PEFI_LEGACY_BIOS_INT86)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN UINT8 BiosInt, IN OUT PEFI_IA32_REGISTER_SET Regs);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI)(IN PEFI_LEGACY_BIOS_PROTOCOL This, OUT PUINT16 BbsCount, OUT PEFI_BBS_TABLE *BbsTable);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS)(IN PEFI_LEGACY_BIOS_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS)(IN PEFI_LEGACY_BIOS_PROTOCOL This, IN UINT8 Leds);\ntypedef EFI_STATUS (*PEFI_SERVICE_BINDING_CREATE_CHILD)(IN PEFI_SERVICE_BINDING This, IN PEFI_HANDLE ChildHandle);\ntypedef EFI_STATUS (*PEFI_SERVICE_BINDING_DESTROY_CHILD)(IN PEFI_SERVICE_BINDING This, IN EFI_HANDLE ChildHandle);\ntypedef EFI_STATUS (*PEFI_DRIVER_BINDING_PROTOCOL_SUPPORTED)(IN PEFI_DRIVER_BINDING_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN PEFI_DEVICE_PATH_PROTOCOL RemainingDevicePath);\ntypedef EFI_STATUS (*PEFI_DRIVER_BINDING_PROTOCOL_START)(IN PEFI_DRIVER_BINDING_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN PEFI_DEVICE_PATH_PROTOCOL RemainingDevicePath);\ntypedef EFI_STATUS (*PEFI_DRIVER_BINDING_PROTOCOL_STOP)(IN PEFI_DRIVER_BINDING_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN UINT_PTR NumberOfChildren, IN PEFI_HANDLE ChildHandleBuffer);\ntypedef EFI_STATUS (*PEFI_COMPONENT_NAME_GET_DRIVER_NAME)(IN PEFI_COMPONENT_NAME_PROTOCOL This, IN PUINT8 Language, OUT PWCHAR *DriverName);\ntypedef EFI_STATUS (*PEFI_COMPONENT_NAME_GET_CONTROLLER_NAME)(IN PEFI_COMPONENT_NAME_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle, IN PUINT8 Language, OUT PWCHAR *ControllerName);\ntypedef EFI_STATUS (*PEFI_COMPONENT_NAME2_GET_DRIVER_NAME)(IN PEFI_COMPONENT_NAME2_PROTOCOL This, IN PUINT8 Language, OUT PWCHAR *DriverName);\ntypedef EFI_STATUS (*PEFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)(IN PEFI_COMPONENT_NAME2_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle, IN PUINT8 Language, OUT PWCHAR *ControllerName);\ntypedef EFI_STATUS (*PEFI_RNG_GET_INFO)(IN PEFI_RNG_PROTOCOL This, IN OUT PUINT_PTR RNGAlgorithmListSize, OUT PEFI_GUID RNGAlgorithmList);\ntypedef EFI_STATUS (*PEFI_RNG_GET_RNG)(IN PEFI_RNG_PROTOCOL This, IN PEFI_GUID RNGAlgorithm, IN UINT_PTR RNGValueLength, OUT PUINT8 RNGValue);\ntypedef EFI_STATUS (*PEFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER)(IN PEFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN OUT PEFI_HANDLE DriverImageHandle);\ntypedef EFI_STATUS (*PEFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER_PATH)(IN PEFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN OUT PEFI_DEVICE_PATH_PROTOCOL *DriverImagePath);\ntypedef EFI_STATUS (*PEFI_PLATFORM_DRIVER_OVERRIDE_DRIVER_LOADED)(IN PEFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL This, IN EFI_HANDLE ControllerHandle, IN PEFI_DEVICE_PATH_PROTOCOL DriverImagePath, IN EFI_HANDLE DriverImageHandle);\ntypedef EFI_STATUS (*PEFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER)(IN PEFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL This, IN OUT PEFI_HANDLE DriverImageHandle);\ntypedef UINT32 (*PEFI_DRIVER_FAMILY_OVERRIDE_GET_VERSION)(IN PEFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_EBC_CREATE_THUNK)(IN PEFI_EBC_PROTOCOL This, IN EFI_HANDLE ImageHandle, IN PVOID EbcEntryPoint, OUT PVOID *Thunk);\ntypedef EFI_STATUS (*PEFI_EBC_UNLOAD_IMAGE)(IN PEFI_EBC_PROTOCOL This, IN EFI_HANDLE ImageHandle);\ntypedef EFI_STATUS (*PEFI_EBC_ICACHE_FLUSH)(IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 Length);\ntypedef EFI_STATUS (*PEFI_EBC_REGISTER_ICACHE_FLUSH)(IN PEFI_EBC_PROTOCOL This, IN PEFI_EBC_ICACHE_FLUSH Flush);\ntypedef EFI_STATUS (*PEFI_EBC_GET_VERSION)(IN PEFI_EBC_PROTOCOL This, IN OUT PUINT64 Version);\ntypedef EFI_STATUS (*PEFI_UART_RESET)(IN PEFI_UART_IO_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_UART_SET_ATTRIBUTES)(IN PEFI_UART_IO_PROTOCOL This, IN UINT64 BaudRate, IN UINT32 ReceiveFifoDepth, IN UINT32 Timeout, IN EFI_UART_PARITY_TYPE Parity, IN UINT8 DataBits, IN EFI_UART_STOP_BITS_TYPE StopBits);\ntypedef EFI_STATUS (*PEFI_UART_SET_CONTROL_BITS)(IN PEFI_UART_IO_PROTOCOL This, IN UINT32 Control);\ntypedef EFI_STATUS (*PEFI_UART_GET_CONTROL_BITS)(IN PEFI_UART_IO_PROTOCOL This, OUT PUINT32 Control);\ntypedef EFI_STATUS (*PEFI_UART_WRITE)(IN PEFI_UART_IO_PROTOCOL This, IN OUT PUINT_PTR BufferSize, IN PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_UART_READ)(IN PEFI_UART_IO_PROTOCOL This, IN OUT PUINT_PTR BufferSize, OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_START)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_STOP)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_INITIALIZE)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, IN UINT_PTR ExtraRxBufferSize, IN UINT_PTR ExtraTxBufferSize);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_RESET)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, IN UCHAR ExtendedVerification);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_SHUTDOWN)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_RECEIVE_FILTERS)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, IN UINT32 Enable, IN UINT32 Disable, IN UCHAR ResetMCastFilter, IN UINT_PTR MCastFilterCnt, IN PEFI_MAC_ADDRESS MCastFilter);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_STATION_ADDRESS)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, IN UCHAR Reset, IN PEFI_MAC_ADDRESS New);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_STATISTICS)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, IN UCHAR Reset, IN OUT PUINT_PTR StatisticsSize, OUT PEFI_NETWORK_STATISTICS StatisticsTable);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, IN UCHAR IPv6, IN PEFI_IP_ADDRESS IP, OUT PEFI_MAC_ADDRESS MAC);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_NVDATA)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, IN UCHAR ReadWrite, IN UINT_PTR Offset, IN UINT_PTR BufferSize, IN OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_GET_STATUS)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, OUT PUINT32 InterruptStatus, OUT PVOID *TxBuf);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_TRANSMIT)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, IN UINT_PTR HeaderSize, IN UINT_PTR BufferSize, IN PVOID Buffer, IN PEFI_MAC_ADDRESS SrcAddr, IN PEFI_MAC_ADDRESS DestAddr, IN PUINT16 Protocol);\ntypedef EFI_STATUS (*PEFI_SIMPLE_NETWORK_RECEIVE)(IN PEFI_SIMPLE_NETWORK_PROTOCOL This, OUT PUINT_PTR HeaderSize, IN OUT PUINT_PTR BufferSize, OUT PVOID Buffer, OUT PEFI_MAC_ADDRESS SrcAddr, OUT PEFI_MAC_ADDRESS DestAddr, OUT PUINT16 Protocol);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_START)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UCHAR UseIpv6);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_STOP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_DHCP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UCHAR SortOffers);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_DISCOVER)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UINT16 Type, IN PUINT16 Layer, IN UCHAR UseBis, IN OUT PEFI_PXE_BASE_CODE_DISCOVER_INFO Info);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_MTFTP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation, IN OUT PVOID *BufferPtr, IN UCHAR Overwrite, IN OUT PUINT64 BufferSize, IN PUINT_PTR BlockSize, IN PEFI_IP_ADDRESS ServerIp, IN PWCHAR Filename, IN PEFI_PXE_BASE_CODE_MTFTP_INFO Info, IN UCHAR DontUseBuffer);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_UDP_WRITE)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UINT16 OpFlags, IN PEFI_IP_ADDRESS DestIp, IN PUINT16 DestPort, IN PEFI_IP_ADDRESS GatewayIp, IN PEFI_IP_ADDRESS SrcIp, IN OUT PUINT16 SrcPort, IN PUINT_PTR HeaderSize, IN PVOID HeaderPtr, IN PUINT_PTR BufferSize, IN PVOID BufferPtr);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_UDP_READ)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN UINT16 OpFlags, IN OUT PEFI_IP_ADDRESS DestIp, IN OUT PUINT16 DestPort, IN OUT PEFI_IP_ADDRESS SrcIp, IN OUT PUINT16 SrcPort, IN PUINT_PTR HeaderSize, IN PVOID HeaderPtr, IN OUT PUINT_PTR BufferSize, IN PVOID BufferPtr);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_SET_IP_FILTER)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN PEFI_PXE_BASE_CODE_IP_FILTER NewFilter);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_ARP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN PEFI_IP_ADDRESS IpAddr, IN PEFI_MAC_ADDRESS MacAddr);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_SET_PARAMETERS)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN PUCHAR NewAutoArp, IN PUCHAR NewSendGUID, IN PUINT8 NewTTL, IN PUINT8 NewToS, IN PUCHAR NewMakeCallback);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_SET_STATION_IP)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, IN PEFI_IP_ADDRESS NewStationIp, IN PEFI_IP_ADDRESS NewSubnetMask);\ntypedef EFI_STATUS (*PEFI_PXE_BASE_CODE_SET_PACKETS)(IN PEFI_PXE_BASE_CODE_PROTOCOL This, PUCHAR NewDhcpDiscoverValid, PUCHAR NewDhcpAckReceived, PUCHAR NewProxyOfferReceived, PUCHAR NewPxeDiscoverValid, PUCHAR NewPxeReplyReceived, PUCHAR NewPxeBisReplyReceived, IN PEFI_PXE_BASE_CODE_PACKET NewDhcpDiscover, IN PEFI_PXE_BASE_CODE_PACKET NewDhcpAck, IN PEFI_PXE_BASE_CODE_PACKET NewProxyOffer, IN PEFI_PXE_BASE_CODE_PACKET NewPxeDiscover, IN PEFI_PXE_BASE_CODE_PACKET NewPxeReply, IN PEFI_PXE_BASE_CODE_PACKET NewPxeBisReply);\ntypedef EFI_PXE_BASE_CODE_CALLBACK_STATUS (*PEFI_PXE_CALLBACK)(IN PEFI_PXE_BASE_CODE_CALLBACK_PROTOCOL This, IN EFI_PXE_BASE_CODE_FUNCTION Function, IN UCHAR Received, IN UINT32 PacketLen, IN PEFI_PXE_BASE_CODE_PACKET Packet);\ntypedef VOID (*PEFI_AP_PROCEDURE)(IN OUT PVOID Buffer);\ntypedef EFI_STATUS (*PEFI_FRAMEWORK_MP_SERVICES_GET_GENERAL_MP_INFO)(IN PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL This, OUT PUINT_PTR NumberOfCPUs, OUT PUINT_PTR MaximumNumberOfCPUs, OUT PUINT_PTR NumberOfEnabledCPUs, OUT PUINT_PTR RendezvousIntNumber, OUT PUINT_PTR RendezvousProcLength);\ntypedef EFI_STATUS (*PEFI_FRAMEWORK_MP_SERVICES_GET_PROCESSOR_CONTEXT)(IN PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL This, IN UINT_PTR ProcessorNumber, IN OUT PUINT_PTR BufferLength, IN OUT PEFI_FRAMEWORK_MP_PROCESSOR_CONTEXT ProcessorContextBuffer);\ntypedef EFI_STATUS (*PEFI_FRAMEWORK_MP_SERVICES_STARTUP_ALL_APS)(IN PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL This, IN PEFI_AP_PROCEDURE Procedure, IN BOOLEAN SingleThread, IN EFI_EVENT WaitEvent, IN UINT_PTR TimeoutInMicroSecs, IN OUT PVOID ProcArguments, OUT PUINT_PTR FailedCPUList);\ntypedef EFI_STATUS (*PEFI_FRAMEWORK_MP_SERVICES_STARTUP_THIS_AP)(IN PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL This, IN PEFI_AP_PROCEDURE Procedure, IN UINT_PTR ProcessorNumber, IN EFI_EVENT WaitEvent, IN UINT_PTR TimeoutInMicroSecs, IN OUT PVOID ProcArguments);\ntypedef EFI_STATUS (*PEFI_FRAMEWORK_MP_SERVICES_SWITCH_BSP)(IN PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL This, IN UINT_PTR ProcessorNumber, IN BOOLEAN EnableOldBSP);\ntypedef EFI_STATUS (*PEFI_FRAMEWORK_MP_SERVICES_SEND_IPI)(IN PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL This, IN UINT_PTR ProcessorNumber, IN UINT_PTR VectorNumber, IN UINT_PTR DeliveryMode);\ntypedef EFI_STATUS (*PEFI_FRAMEWORK_MP_SERVICES_ENABLEDISABLEAP)(IN PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL This, IN UINT_PTR ProcessorNumber, IN BOOLEAN NewAPState, IN PEFI_FRAMEWORK_MP_HEALTH HealthState);\ntypedef EFI_STATUS (*PEFI_FRAMEWORK_MP_SERVICES_WHOAMI)(IN PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL This, OUT PUINT_PTR ProcessorNumber);\ntypedef EFI_STATUS (*PEFI_MP_SERVICES_ENABLEDISABLEAP)(IN PEFI_MP_SERVICES_PROTOCOL This, IN UINT_PTR ProcessorNumber, IN BOOLEAN EnableAP, IN PUINT32 HealthFlag);\ntypedef EFI_STATUS (*PEFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)(IN PEFI_MP_SERVICES_PROTOCOL This, OUT PUINT_PTR NumberOfProcessors, OUT PUINT_PTR NumberOfEnabledProcessors);\ntypedef EFI_STATUS (*PEFI_MP_SERVICES_GET_PROCESSOR_INFO)(IN PEFI_MP_SERVICES_PROTOCOL This, IN UINT_PTR ProcessorNumber, OUT PEFI_PROCESSOR_INFORMATION ProcessorInfoBuffer);\ntypedef EFI_STATUS (*PEFI_MP_SERVICES_STARTUP_ALL_APS)(IN PEFI_MP_SERVICES_PROTOCOL This, IN PEFI_AP_PROCEDURE Procedure, IN BOOLEAN SingleThread, IN EFI_EVENT WaitEvent, IN UINT_PTR TimeoutInMicroSeconds, IN PVOID ProcedureArgument, OUT PUINT_PTR *FailedCpuList);\ntypedef EFI_STATUS (*PEFI_MP_SERVICES_STARTUP_THIS_AP)(IN PEFI_MP_SERVICES_PROTOCOL This, IN PEFI_AP_PROCEDURE Procedure, IN UINT_PTR ProcessorNumber, IN EFI_EVENT WaitEvent, IN UINT_PTR TimeoutInMicroseconds, IN PVOID ProcedureArgument, OUT PBOOLEAN Finished);\ntypedef EFI_STATUS (*PEFI_MP_SERVICES_SWITCH_BSP)(IN PEFI_MP_SERVICES_PROTOCOL This, IN UINT_PTR ProcessorNumber, IN BOOLEAN EnableOldBSP);\ntypedef EFI_STATUS (*PEFI_MP_SERVICES_WHOAMI)(IN PEFI_MP_SERVICES_PROTOCOL This, OUT PUINT_PTR ProcessorNumber);\n\n/* 128-bit buffer containing a unique identifier value */\ntypedef struct _EFI_GUID\n{\n    UINT32 Data1;\n    UINT16 Data2;\n    UINT16 Data3;\n    UINT8 Data4[8];\n} EFI_GUID, *PEFI_GUID;\n\n/* EFI Capsule Header */\ntypedef struct _EFI_CAPSULE_HEADER\n{\n    EFI_GUID CapsuleGuid;\n    UINT32 HeaderSize;\n    UINT32 Flags;\n    UINT32 CapsuleImageSize;\n} EFI_CAPSULE_HEADER, *PEFI_CAPSULE_HEADER;\n\n/* EFI Capsule Block Descriptor */\ntypedef struct _EFI_CAPSULE_BLOCK_DESCRIPTOR\n{\n    UINT64 Length;\n    union\n    {\n        EFI_PHYSICAL_ADDRESS DataBlock;\n        EFI_PHYSICAL_ADDRESS ContinuationPointer;\n    } Union;\n} EFI_CAPSULE_BLOCK_DESCRIPTOR, *PEFI_CAPSULE_BLOCK_DESCRIPTOR;\n\n/* Definition of an EFI memory descriptor */\ntypedef struct _EFI_MEMORY_DESCRIPTOR\n{\n    UINT32 Type;\n    UINT32 Pad;\n    EFI_PHYSICAL_ADDRESS PhysicalStart;\n    EFI_VIRTUAL_ADDRESS VirtualStart;\n    UINT64 NumberOfPages;\n    UINT64 Attribute;\n} EFI_MEMORY_DESCRIPTOR, *PEFI_MEMORY_DESCRIPTOR;\n\n/* Definition of an EFI memory map */\ntypedef struct _EFI_MEMORY_MAP\n{\n  PEFI_MEMORY_DESCRIPTOR Map;\n  UINT_PTR MapSize;\n  UINT_PTR MapKey;\n  UINT_PTR DescriptorSize;\n  UINT32 DescriptorVersion;\n} EFI_MEMORY_MAP, *PEFI_MEMORY_MAP;\n\n/* Data structure that precedes all of the standard EFI table types */\ntypedef struct _EFI_TABLE_HEADER\n{\n    UINT64 Signature;\n    UINT32 Revision;\n    UINT32 HeaderSize;\n    UINT32 CRC32;\n    UINT32 Reserved;\n} EFI_TABLE_HEADER, *PEFI_TABLE_HEADER;\n\n/* EFI Time Abstraction */\ntypedef struct _EFI_TIME\n{\n    UINT16 Year;\n    UINT8 Month;\n    UINT8 Day;\n    UINT8 Hour;\n    UINT8 Minute;\n    UINT8 Second;\n    UINT8 Pad1;\n    UINT32 Nanosecond;\n    INT16 TimeZone;\n    UINT8 Daylight;\n    UINT8 PAD2;\n} EFI_TIME, *PEFI_TIME;\n\n/* Provides the capabilities of the RTC device as exposed through the EFI interfaces */\ntypedef struct _EFI_TIME_CAPABILITIES\n{\n    UINT32 Resolution;\n    UINT32 Accuracy;\n    BOOLEAN SetsToZero;\n} EFI_TIME_CAPABILITIES, *PEFI_TIME_CAPABILITIES;\n\n/* EFI Open Protocol Information Entry */\ntypedef struct _EFI_OPEN_PROTOCOL_INFORMATION_ENTRY\n{\n    EFI_HANDLE AgentHandle;\n    EFI_HANDLE ControllerHandle;\n    UINT32 Attributes;\n    UINT32 OpenCount;\n} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY, *PEFI_OPEN_PROTOCOL_INFORMATION_ENTRY;\n\n/* EFI Boot Services Table */\ntypedef struct _EFI_BOOT_SERVICES\n{\n    EFI_TABLE_HEADER Hdr;\n    PEFI_RAISE_TPL RaiseTPL;\n    PEFI_RESTORE_TPL RestoreTPL;\n    PEFI_ALLOCATE_PAGES AllocatePages;\n    PEFI_FREE_PAGES FreePages;\n    PEFI_GET_MEMORY_MAP GetMemoryMap;\n    PEFI_ALLOCATE_POOL AllocatePool;\n    PEFI_FREE_POOL FreePool;\n    PEFI_CREATE_EVENT CreateEvent;\n    PEFI_SET_TIMER SetTimer;\n    PEFI_WAIT_FOR_EVENT WaitForEvent;\n    PEFI_SIGNAL_EVENT SignalEvent;\n    PEFI_CLOSE_EVENT CloseEvent;\n    PEFI_CHECK_EVENT CheckEvent;\n    PEFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;\n    PEFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;\n    PEFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;\n    PEFI_HANDLE_PROTOCOL HandleProtocol;\n    PVOID Reserved;\n    PEFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;\n    PEFI_LOCATE_HANDLE LocateHandle;\n    PEFI_LOCATE_DEVICE_PATH LocateDevicePath;\n    PEFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;\n    PEFI_IMAGE_LOAD LoadImage;\n    PEFI_IMAGE_START StartImage;\n    PEFI_EXIT Exit;\n    PEFI_IMAGE_UNLOAD UnloadImage;\n    PEFI_EXIT_BOOT_SERVICES ExitBootServices;\n    PEFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;\n    PEFI_STALL Stall;\n    PEFI_SET_WATCHDOG_TIMER SetWatchdogTimer;\n    PEFI_CONNECT_CONTROLLER ConnectController;\n    PEFI_DISCONNECT_CONTROLLER DisconnectController;\n    PEFI_OPEN_PROTOCOL OpenProtocol;\n    PEFI_CLOSE_PROTOCOL CloseProtocol;\n    PEFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation;\n    PEFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle;\n    PEFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;\n    PEFI_LOCATE_PROTOCOL LocateProtocol;\n    PEFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces;\n    PEFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces;\n    PEFI_CALCULATE_CRC32 CalculateCrc32;\n    PEFI_COPY_MEM CopyMem;\n    PEFI_SET_MEM SetMem;\n    PEFI_CREATE_EVENT_EX CreateEventEx;\n} EFI_BOOT_SERVICES, *PEFI_BOOT_SERVICES;\n\n/* EFI Runtime Services Table */\ntypedef struct _EFI_RUNTIME_SERVICES\n{\n    EFI_TABLE_HEADER Hdr;\n    PEFI_GET_TIME GetTime;\n    PEFI_SET_TIME SetTime;\n    PEFI_GET_WAKEUP_TIME GetWakeupTime;\n    PEFI_SET_WAKEUP_TIME SetWakeupTime;\n    PEFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;\n    PEFI_CONVERT_POINTER ConvertPointer;\n    PEFI_GET_VARIABLE GetVariable;\n    PEFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;\n    PEFI_SET_VARIABLE SetVariable;\n    PEFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount;\n    PEFI_RESET_SYSTEM ResetSystem;\n    PEFI_UPDATE_CAPSULE UpdateCapsule;\n    PEFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities;\n    PEFI_QUERY_VARIABLE_INFO QueryVariableInfo;\n} EFI_RUNTIME_SERVICES, *PEFI_RUNTIME_SERVICES;\n\n/* Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the EFI System Table */\ntypedef struct _EFI_CONFIGURATION_TABLE\n{\n    EFI_GUID VendorGuid;\n    PVOID VendorTable;\n} EFI_CONFIGURATION_TABLE, *PEFI_CONFIGURATION_TABLE;\n\n/* Simple Text Input protocol from the UEFI 2.0 specification */\ntypedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL\n{\n    PEFI_INPUT_RESET Reset;\n    PEFI_INPUT_READ_KEY ReadKeyStroke;\n    EFI_EVENT WaitForKey;\n} EFI_SIMPLE_TEXT_INPUT_PROTOCOL, *PEFI_SIMPLE_TEXT_INPUT_PROTOCOL;\n\n/* Simple Text Output protocol from the UEFI 2.0 specification */\ntypedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL\n{\n    PEFI_TEXT_RESET Reset;\n    PEFI_TEXT_OUTPUT_STRING OutputString;\n    PEFI_TEXT_TEST_STRING TestString;\n    PEFI_TEXT_QUERY_MODE QueryMode;\n    PEFI_TEXT_SET_MODE SetMode;\n    PEFI_TEXT_SET_ATTRIBUTE SetAttribute;\n    PEFI_TEXT_CLEAR_SCREEN ClearScreen;\n    PEFI_TEXT_SET_CURSOR_POSITION SetCursorPosition;\n    PEFI_TEXT_ENABLE_CURSOR EnableCursor;\n    PEFI_SIMPLE_TEXT_OUTPUT_MODE Mode;\n} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL, *PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;\n\n/* Mode Structure pointed to by Simple Text Out protocol */\ntypedef struct _EFI_SIMPLE_TEXT_OUTPUT_MODE\n{\n    INT32 MaxMode;\n    INT32 Mode;\n    INT32 Attribute;\n    INT32 CursorColumn;\n    INT32 CursorRow;\n    BOOLEAN CursorVisible;\n} EFI_SIMPLE_TEXT_OUTPUT_MODE, *PEFI_SIMPLE_TEXT_OUTPUT_MODE;\n\n/* The keystroke information for the key that was pressed */\ntypedef struct _EFI_INPUT_KEY\n{\n    UINT16 ScanCode;\n    WCHAR UnicodeChar;\n} EFI_INPUT_KEY, *PEFI_INPUT_KEY;\n\n/* EFI Key State information */\ntypedef struct _EFI_KEY_STATE\n{\n    UINT32 KeyShiftState;\n    UINT8 KeyToggleState;\n} EFI_KEY_STATE, *PEFI_KEY_STATE;\n\n/* EFI Key Data information */\ntypedef struct _EFI_KEY_DATA\n{\n    EFI_INPUT_KEY Key;\n    EFI_KEY_STATE KeyState;\n} EFI_KEY_DATA, *PEFI_KEY_DATA;\n\n/* EFI Simple Text Input Ex protocol */\ntypedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL\n{\n    PEFI_INPUT_RESET_EX Reset;\n    PEFI_INPUT_READ_KEY_EX ReadKeyStrokeEx;\n    EFI_EVENT WaitForKeyEx;\n    PEFI_SET_STATE SetState;\n    PEFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify;\n    PEFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify;\n} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL, *PEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;\n\n/* EFI System Table */\ntypedef struct _EFI_SYSTEM_TABLE\n{\n    EFI_TABLE_HEADER Hdr;\n    PWCHAR FirmwareVendor;\n    UINT32 FirmwareRevision;\n    EFI_HANDLE ConsoleInHandle;\n    PEFI_SIMPLE_TEXT_INPUT_PROTOCOL ConIn;\n    EFI_HANDLE ConsoleOutHandle;\n    PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL ConOut;\n    EFI_HANDLE StandardErrorHandle;\n    PEFI_SIMPLE_TEXT_OUTPUT_PROTOCOL StdErr;\n    PEFI_RUNTIME_SERVICES RuntimeServices;\n    PEFI_BOOT_SERVICES BootServices;\n    UINT_PTR NumberOfTableEntries;\n    PEFI_CONFIGURATION_TABLE ConfigurationTable;\n} EFI_SYSTEM_TABLE, *PEFI_SYSTEM_TABLE;\n\n/* EFI IPv4 network protocol */\ntypedef struct _EFI_IPv4_ADDRESS\n{\n    UINT8 Addr[4];\n} EFI_IPv4_ADDRESS, *PEFI_IPv4_ADDRESS;\n\n/* EFI IPv6 network protocol */\ntypedef struct _EFI_IPv6_ADDRESS\n{\n    UINT8 Addr[16];\n} EFI_IPv6_ADDRESS, *PEFI_IPv6_ADDRESS;\n\n/* EFI MAC address definition */\ntypedef struct _EFI_MAC_ADDRESS\n{\n    UINT8 Addr[32];\n} EFI_MAC_ADDRESS, *PEFI_MAC_ADDRESS;\n\n/* EFI network interface identifier protocol */\ntypedef struct _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL\n{\n    UINT64 Revision;\n    UINT64 ID;\n    UINT64 ImageAddr;\n    UINT32 ImageSize;\n    UINT8 StringId[4];\n    UINT8 Type;\n    UINT8 MajorVer;\n    UINT8 MinorVer;\n    UCHAR Ipv6Supported;\n    UINT8 IfNum;\n} EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL, *PEFI_NETWORK_INTERFACE_IDENTIFIER_INTERFACE;\n\n/* EFI network configuration data structure */\ntypedef struct _EFI_MANAGED_NETWORK_CONFIG_DATA\n{\n    UINT32 ReceivedQueueTimeoutValue;\n    UINT32 TransmitQueueTimeoutValue;\n    UINT16 ProtocolTypeFilter;\n    UCHAR EnableUnicastReceive;\n    UCHAR EnableMulticastReceive;\n    UCHAR EnableBroadcastReceive;\n    UCHAR EnablePromiscuousReceive;\n    UCHAR FlushQueuesOnReset;\n    UCHAR EnableReceiveTimestamps;\n    UCHAR DisableBackgroundPolling;\n} EFI_MANAGED_NETWORK_CONFIG_DATA, *PEFI_MANAGED_NETWORK_CONFIG_DATA;\n\n/* Describes the location of the device the handle is for */\ntypedef struct _EFI_DEVICE_PATH_PROTOCOL\n{\n    UINT8 Type;\n    UINT8 SubType;\n    UINT8 Length[2];\n} EFI_DEVICE_PATH_PROTOCOL, *PEFI_DEVICE_PATH_PROTOCOL;\n\n/* PCI device path node */\ntypedef struct _EFI_PCI_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT8 Function;\n    UINT8 Device;\n} EFI_PCI_DEVICE_PATH, *PEFI_PCI_DEVICE_PATH;\n\n/* PCCARD device path node */\ntypedef struct _EFI_PCCARD_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT8 FunctionNumber;\n} EFI_PCCARD_DEVICE_PATH, *PEFI_PCCARD_DEVICE_PATH;\n\n/* MemMap device path node */\ntypedef struct _EFI_MEMMAP_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 MemoryType;\n    EFI_PHYSICAL_ADDRESS StartingAddress;\n    EFI_PHYSICAL_ADDRESS EndingAddress;\n} EFI_MEMMAP_DEVICE_PATH, *PEFI_MEMMAP_DEVICE_PATH;\n\n/* Vendor device path node */\ntypedef struct _EFI_VENDOR_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    EFI_GUID Guid;\n} EFI_VENDOR_DEVICE_PATH, *PEFI_VENDOR_DEVICE_PATH;\n\n/* Unknown Device Vendor device path node */\ntypedef struct _EFI_UKNOWN_DEVICE_VENDOR_DEVICE_PATH\n{\n    EFI_VENDOR_DEVICE_PATH DevicePath;\n    UINT8 LegacyDriveLetter;\n} EFI_UNKNOWN_DEVICE_VENDOR_DEVICE_PATH, *PEFI_UNKNOWN_DEVICE_VENDOR_DEVICE_PATH;\n\n/* Controller device path node */\ntypedef struct _EFI_CONTROLLER_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 Controller;\n} EFI_CONTROLLER_DEVICE_PATH, *PEFI_CONTROLLER_DEVICE_PATH;\n\n/* ACPI address space descriptor */\ntypedef struct _EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR\n{\n    UCHAR SpaceDescriptor;\n    USHORT Length;\n    UCHAR ResourceType;\n    UCHAR GeneralFlags;\n    UCHAR TypeSpecificFlag;\n    ULONGLONG Granularity;\n    ULONGLONG AddressRangeMin;\n    ULONGLONG AddressRangeMax;\n    ULONGLONG TranslationOffset;\n    ULONGLONG AddressLength;\n} EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR, *PEFI_ACPI_ADDRESS_SPACE_DESCRIPTOR;\n\n/* ACPI device path node */\ntypedef struct _EFI_ACPI_HID_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 HID;\n    UINT32 UID;\n} EFI_ACPI_HID_DEVICE_PATH, *PEFI_ACPI_HID_DEVICE_PATH;\n\n/* Expanded ACPI device path node */\ntypedef struct _EFI_EXPANDED_ACPI_HID_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 HID;\n    UINT32 UID;\n    UINT32 CID;\n    UINT8 HidStr[1];\n} EFI_EXPANDED_ACPI_HID_DEVICE_PATH, *PEFI_EXPANDED_ACPI_HID_DEVICE_PATH;\n\n/* ACPI ADR device path node */\ntypedef struct _EFI_ACPI_ADR_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 ADR;\n} EFI_ACPI_ADR_DEVICE_PATH, *PEFI_ACPI_ADR_DEVICE_PATH;\n\n/* ATAPI device path node */\ntypedef struct _EFI_ATAPI_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT8 PrimarySecondary;\n    UINT8 SlaveMaster;\n    UINT16 Lun;\n} EFI_ATAPI_DEVICE_PATH, *PEFI_ATAPI_DEVICE_PATH;\n\n/* SCSI device path node */\ntypedef struct _EFI_SCSI_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT16 Pun;\n    UINT16 Lun;\n} EFI_SCSI_DEVICE_PATH, *PEFI_SCSI_DEVICE_PATH;\n\n/* Fibre Channel device path node */\ntypedef struct _EFI_FIBRECHANNEL_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 Reserved;\n    UINT64 WWN;\n    UINT64 Lun;\n} EFI_FIBRECHANNEL_DEVICE_PATH, *PEFI_FIBRECHANNEL_DEVICE_PATH;\n\n/* Fibre Channerl EX subtype device path node */\ntypedef struct _EFI_FIBRECHANNELEX_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header ;\n    UINT32 Reserved;\n    UINT8 WWN[8];\n    UINT8 Lun[8];\n} EFI_FIBRECHANNELEX_DEVICE_PATH, *PEFI_FIBRECHANNELEX_DEVICE_PATH;\n\n/* 1394 device path node */\ntypedef struct _EFI_1394_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 Reserved;\n    UINT64 Guid;\n} EFI_1394_DEVICE_PATH, *PEFI_1394_DEVICE_PATH;\n\n/* USB device path node */\ntypedef struct _EFI_USB_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT8 Port;\n    UINT8 Endpoint;\n} EFI_USB_DEVICE_PATH, *PEFI_USB_DEVICE_PATH;\n\n/* USB WWID device path node */\ntypedef struct _EFI_USB_WWID_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT16 InterfaceNumber;\n    UINT16 VendorId;\n    UINT16 ProductId;\n    UINT16 SerialNumber[1];\n} EFI_USB_WWID_DEVICE_PATH, *PEFI_USB_WWID_DEVICE_PATH;\n\n/* USB Class device path node */\ntypedef struct _EFI_USB_CLASS_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT16 VendorId;\n    UINT16 ProductId;\n    UINT8 DeviceClass;\n    UINT8 DeviceSubclass;\n    UINT8 DeviceProtocol;\n} EFI_USB_CLASS_DEVICE_PATH, *PEFI_USB_CLASS_DEVICE_PATH;\n\n/* SATA device path node */\ntypedef struct _EFI_SATA_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT16 HBAPortNumber;\n    UINT16 PortMultiplierPortNumber;\n    UINT16 Lun;\n} EFI_SATA_DEVICE_PATH, *PEFI_SATA_DEVICE_PATH;\n\n/* Device Logical Unit device path node */\ntypedef struct _EFI_DEVICE_LOGICAL_UNIT_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT8 Lun;\n} EFI_DEVICE_LOGICAL_UNIT_DEVICE_PATH, *PEFI_DEVICE_LOGICAL_UNIT_DEVICE_PATH;\n\n/* I2O device path node */\ntypedef struct _EFI_I2O_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 Tid;\n} EFI_I2O_DEVICE_PATH, *PEFI_I2O_DEVICE_PATH;\n\n/* MAC Address device path node */\ntypedef struct _EFI_MAC_ADDR_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    EFI_MAC_ADDRESS MacAddress;\n    UINT8 IfType;\n} EFI_MAC_ADDR_DEVICE_PATH, *PEFI_MAC_ADDR_DEVICE_PATH;\n\n/* IPv4 device path node */\ntypedef struct _EFI_IPv4_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    EFI_IPv4_ADDRESS LocalIpAddress;\n    EFI_IPv4_ADDRESS RemoteIpAddress;\n    UINT16 LocalPort;\n    UINT16 RemotePort;\n    UINT16 Protocol;\n    UCHAR StaticIpAddress;\n    EFI_IPv4_ADDRESS GatewayIpAddress;\n    EFI_IPv4_ADDRESS SubnetMask;\n} EFI_IPv4_DEVICE_PATH, *PEFI_IPv4_DEVICE_PATH;\n\n/* IPv6 device path node */\ntypedef struct _EFI_IPv6_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    EFI_IPv6_ADDRESS LocalIpAddress;\n    EFI_IPv6_ADDRESS RemoteIpAddress;\n    UINT16 LocalPort;\n    UINT16 RemotePort;\n    UINT16 Protocol;\n    UCHAR IPAddressOrigin;\n    UINT8 PrefixLength;\n    EFI_IPv6_ADDRESS GatewayIpAddress;\n} EFI_IPv6_DEVICE_PATH, *PEFI_IPv6_DEVICE_PATH;\n\n/* Uniform Resource Identifiers SubType device path node */\ntypedef struct _EFI_URI_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT8 Uri[1];\n} EFI_URI_DEVICE_PATH, *PEFI_URI_DEVICE_PATH;\n\n/* VLAN device path node */\ntypedef struct _EFI_VLAN_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT16 VlanId;\n} EFI_VLAN_DEVICE_PATH, *PEFI_VLAN_DEVICE_PATH;\n\n/* InfiniBand device path node */\ntypedef struct _EFI_INFINIBAND_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 ResourceFlags;\n    UINT8 PortGid[16];\n    UINT64 ServiceId;\n    UINT64 TargetPortId;\n    UINT64 DeviceId;\n} EFI_INFINIBAND_DEVICE_PATH, *PEFI_INFINIBAND_DEVICE_PATH;\n\n/* UART device path node */\ntypedef struct _EFI_UART_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 Reserved;\n    UINT64 BaudRate;\n    UINT8 DataBits;\n    UINT8 Parity;\n    UINT8 StopBits;\n} EFI_UART_DEVICE_PATH, *PEFI_UART_DEVICE_PATH;\n\n/* Hard Drive device path node */\ntypedef struct _EFI_HARDDRIVE_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 PartitionNumber;\n    UINT64 PartitionStart;\n    UINT64 PartitionSize;\n    UINT8 Signature[16];\n    UINT8 MBRType;\n    UINT8 SignatureType;\n} EFI_HARDDRIVE_DEVICE_PATH, *PEFI_HARDDRIVE_DEVICE_PATH;\n\n/* CDROM device path node */\ntypedef struct _EFI_CDROM_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 BootEntry;\n    UINT64 PartitionStart;\n    UINT64 PartitionSize;\n} EFI_CDROM_DEVICE_PATH, *PEFI_CDROM_DEVICE_PATH;\n\n/* File Path device path node */\ntypedef struct _EFI_FILEPATH_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    WCHAR PathName[1];\n} EFI_FILEPATH_DEVICE_PATH, *PEFI_FILEPATH_DEVICE_PATH;\n\n/* Media Protocol device path node */\ntypedef struct _EFI_MEDIA_PROTOCOL_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    EFI_GUID Protocol;\n} EFI_MEDIA_PROTOCOL_DEVICE_PATH, *PEFI_MEDIA_PROTOCOL_DEVICE_PATH;\n\n/* Media Firmware File SubType device path node */\ntypedef struct _EFI_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    EFI_GUID FvFileName;\n} EFI_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH, *PEFI_MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;\n\n/* Media Firmware Volume SubType device path node */\ntypedef struct _EFI_MEDIA_FW_VOL_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    EFI_GUID FvName;\n} EFI_MEDIA_FW_VOL_DEVICE_PATH, *PEFI_MEDIA_FW_VOL_DEVICE_PATH;\n\n/* Media relative offset range device path node */\ntypedef struct _EFI_MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT32 Reserved;\n    UINT64 StartingOffset;\n    UINT64 EndingOffset;\n} EFI_MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH, *PEFI_MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH;\n\n/* BIOS Boot Specification (BBS) device path node */\ntypedef struct _EFI_BBS_BBS_DEVICE_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL Header;\n    UINT16 DeviceType;\n    UINT16 StatusFlag;\n    UINT8 String[1];\n} EFI_BBS_BBS_DEVICE_PATH, *PEFI_BBS_BBS_DEVICE_PATH;\n\n/* EFI device path nodes union */\ntypedef union _EFI_DEV_PATH\n{\n    EFI_DEVICE_PATH_PROTOCOL DevPath;\n    EFI_PCI_DEVICE_PATH Pci;\n    EFI_PCCARD_DEVICE_PATH PcCard;\n    EFI_MEMMAP_DEVICE_PATH MemMap;\n    EFI_VENDOR_DEVICE_PATH Vendor;\n    EFI_UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor;\n    EFI_CONTROLLER_DEVICE_PATH Controller;\n    EFI_ACPI_HID_DEVICE_PATH Acpi;\n    EFI_ATAPI_DEVICE_PATH Atapi;\n    EFI_SCSI_DEVICE_PATH Scsi;\n    EFI_FIBRECHANNEL_DEVICE_PATH FibreChannel;\n    EFI_1394_DEVICE_PATH F1394;\n    EFI_USB_DEVICE_PATH Usb;\n    EFI_USB_CLASS_DEVICE_PATH UsbClass;\n    EFI_I2O_DEVICE_PATH I2O;\n    EFI_MAC_ADDR_DEVICE_PATH MacAddr;\n    EFI_IPv4_DEVICE_PATH Ipv4;\n    EFI_IPv6_DEVICE_PATH Ipv6;\n    EFI_URI_DEVICE_PATH Uri;\n    EFI_INFINIBAND_DEVICE_PATH InfiniBand;\n    EFI_UART_DEVICE_PATH Uart;\n    EFI_HARDDRIVE_DEVICE_PATH HardDrive;\n    EFI_CDROM_DEVICE_PATH CD;\n    EFI_FILEPATH_DEVICE_PATH FilePath;\n    EFI_MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;\n    EFI_BBS_BBS_DEVICE_PATH Bbs;\n} EFI_DEV_PATH, *PEFI_DEV_PATH;\n\n/* EFI device path node pointers union */\ntypedef union _EFI_DEV_PATH_PTR\n{\n    PEFI_DEVICE_PATH_PROTOCOL DevPath;\n    PEFI_PCI_DEVICE_PATH Pci;\n    PEFI_PCCARD_DEVICE_PATH PcCard;\n    PEFI_MEMMAP_DEVICE_PATH MemMap;\n    PEFI_VENDOR_DEVICE_PATH Vendor;\n    PEFI_UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor;\n    PEFI_CONTROLLER_DEVICE_PATH Controller;\n    PEFI_ACPI_HID_DEVICE_PATH Acpi;\n    PEFI_ATAPI_DEVICE_PATH Atapi;\n    PEFI_SCSI_DEVICE_PATH Scsi;\n    PEFI_FIBRECHANNEL_DEVICE_PATH FibreChannel;\n    PEFI_1394_DEVICE_PATH F1394;\n    PEFI_USB_DEVICE_PATH Usb;\n    PEFI_USB_CLASS_DEVICE_PATH UsbClass;\n    PEFI_I2O_DEVICE_PATH I2O;\n    PEFI_MAC_ADDR_DEVICE_PATH MacAddr;\n    PEFI_IPv4_DEVICE_PATH Ipv4;\n    PEFI_IPv6_DEVICE_PATH Ipv6;\n    PEFI_URI_DEVICE_PATH Uri;\n    PEFI_INFINIBAND_DEVICE_PATH InfiniBand;\n    PEFI_UART_DEVICE_PATH Uart;\n    PEFI_HARDDRIVE_DEVICE_PATH HardDrive;\n    PEFI_FILEPATH_DEVICE_PATH FilePath;\n    PEFI_MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;\n    PEFI_CDROM_DEVICE_PATH CD;\n    PEFI_BBS_BBS_DEVICE_PATH Bbs;\n} EFI_DEV_PATH_PTR, *PEFI_DEV_PATH_PTR;\n\n/* EFI device path to text protocol */\ntypedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL\n{\n    PEFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText;\n    PEFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText;\n} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL, *PEFI_DEVICE_PATH_TO_TEXT_PROTOCOL;\n\n/* EFI device path from text protocol */\ntypedef struct _EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL\n{\n    PEFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode;\n    PEFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath;\n} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL, *PEFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;\n\n/* EFI device path utility protocol */\ntypedef struct _EFI_DEVICE_PATH_UTILITIES_PROTOCOL\n{\n    PEFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;\n    PEFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath;\n    PEFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath;\n    PEFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode;\n    PEFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance;\n    PEFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance;\n    PEFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance;\n    PEFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode;\n} EFI_DEVICE_PATH_UTILITIES_PROTOCOL, *PEFI_DEVICE_PATH_UTILITIES_PROTOCOL;\n\n/* PCI I/O protocol access registers */\ntypedef struct _EFI_PCI_IO_PROTOCOL_ACCESS\n{\n    EFI_PCI_IO_PROTOCOL_IO_MEM Read;\n    EFI_PCI_IO_PROTOCOL_IO_MEM Write;\n} EFI_PCI_IO_PROTOCOL_ACCESS, *PEFI_PCI_IO_PROTOCOL_ACCESS;\n\n/* PCI Root Bridge I/O protocol access registers */\ntypedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS\n{\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Read;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Write;\n} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS, *PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS;\n\n/* PCI I/O protocol configuration access registers */\ntypedef struct _EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS\n{\n    EFI_PCI_IO_PROTOCOL_CONFIG Read;\n    EFI_PCI_IO_PROTOCOL_CONFIG Write;\n} EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS, *PEFI_PCI_IO_PROTOCOL_CONFIG_ACCESS;\n\n/* PCI Root Bridge I/O protocol address */\ntypedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS\n{\n    UINT8 Register;\n    UINT8 Function;\n    UINT8 Device;\n    UINT8 Bus;\n    UINT32 ExtendedRegister;\n} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS, *PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS;\n\n/* EFI PCI I/O protocol */\ntypedef struct _EFI_PCI_IO_PROTOCOL\n{\n    EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollMem;\n    EFI_PCI_IO_PROTOCOL_POLL_IO_MEM PollIo;\n    EFI_PCI_IO_PROTOCOL_ACCESS Mem;\n    EFI_PCI_IO_PROTOCOL_ACCESS Io;\n    EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS Pci;\n    EFI_PCI_IO_PROTOCOL_COPY_MEM CopyMem;\n    EFI_PCI_IO_PROTOCOL_MAP Map;\n    EFI_PCI_IO_PROTOCOL_UNMAP Unmap;\n    EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;\n    EFI_PCI_IO_PROTOCOL_FREE_BUFFER FreeBuffer;\n    EFI_PCI_IO_PROTOCOL_FLUSH Flush;\n    EFI_PCI_IO_PROTOCOL_GET_LOCATION GetLocation;\n    EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes;\n    EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes;\n    EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES SetBarAttributes;\n    UINT64 RomSize;\n    PVOID RomImage;\n} EFI_PCI_IO_PROTOCOL, *PEFI_PCI_IO_PROTOCOL;\n\n/* EFI PCI Root Bridge I/O protocol */\ntypedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\n{\n    EFI_HANDLE ParentHandle;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollMem;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollIo;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM CopyMem;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP Map;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP Unmap;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER FreeBuffer;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH Flush;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES GetAttributes;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES SetAttributes;\n    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION Configuration;\n    UINT32 SegmentNumber;\n} EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL, *PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL;\n\n/* Describes block device */\ntypedef struct _EFI_BLOCK_DEVICE\n{\n    LIST_ENTRY ListEntry;\n    EFI_GUID Guid;\n    USHORT DriveType;\n    ULONG DriveNumber;\n    ULONG PartitionNumber;\n    PEFI_GUID PartitionGuid;\n    PEFI_DEVICE_PATH_PROTOCOL DevicePath;\n} EFI_BLOCK_DEVICE, *PEFI_BLOCK_DEVICE;\n\n/* Describes block device I/O and DP protocols */\ntypedef struct _EFI_BLOCK_DEVICE_DATA\n{\n    LIST_ENTRY ListEntry;\n    PEFI_DEVICE_PATH_PROTOCOL DevicePath;\n    PEFI_BLOCK_IO_PROTOCOL BlockIo;\n} EFI_BLOCK_DEVICE_DATA, *PEFI_BLOCK_DEVICE_DATA;\n\n/* Block I/O media structure */\ntypedef struct _EFI_BLOCK_IO_MEDIA\n{\n    UINT32 MediaId;\n    BOOLEAN RemovableMedia;\n    BOOLEAN MediaPresent;\n    BOOLEAN LogicalPartition;\n    BOOLEAN ReadOnly;\n    BOOLEAN WriteCaching;\n    UINT32 BlockSize;\n    UINT32 IoAlign;\n    EFI_LBA LastBlock;\n    EFI_LBA LowestAlignedLba;\n    UINT32 LogicalBlocksPerPhysicalBlock;\n    UINT32 OptimalTransferLengthGranularity;\n} EFI_BLOCK_IO_MEDIA, *PEFI_BLOCK_IO_MEDIA;\n\n/* EFI Block I/O protocol */\ntypedef struct _EFI_BLOCK_IO_PROTOCOL\n{\n    UINT64 Revision;\n    PEFI_BLOCK_IO_MEDIA Media;\n    PEFI_BLOCK_RESET Reset;\n    PEFI_BLOCK_READ ReadBlocks;\n    PEFI_BLOCK_WRITE WriteBlocks;\n    PEFI_BLOCK_FLUSH FlushBlocks;\n} EFI_BLOCK_IO_PROTOCOL, *PEFI_BLOCK_IO_PROTOCOL;\n\n/* EFI Block IO2 protocol */\ntypedef struct _EFI_BLOCK_IO2_PROTOCOL\n{\n    PEFI_BLOCK_IO_MEDIA Media;\n    PEFI_BLOCK_RESET_EX Reset;\n    PEFI_BLOCK_READ_EX ReadBlocksEx;\n    PEFI_BLOCK_WRITE_EX WriteBlocksEx;\n    PEFI_BLOCK_FLUSH_EX FlushBlocksEx;\n} EFI_BLOCK_IO2_PROTOCOL, *PEFI_BLOCK_IO2_PROTOCOL;\n\n/* EFI Block IO2 token */\ntypedef struct _EFI_BLOCK_IO2_TOKEN\n{\n    EFI_EVENT Event;\n    EFI_STATUS TransactionStatus;\n} EFI_BLOCK_IO2_TOKEN, *PEFI_BLOCK_IO2_TOKEN;\n\n/* EFI Disk IO protocol */\ntypedef struct _EFI_DISK_IO_PROTOCOL\n{\n    UINT64 Revision;\n    PEFI_DISK_READ ReadDisk;\n    PEFI_DISK_WRITE WriteDisk;\n} EFI_DISK_IO_PROTOCOL, *PEFI_DISK_IO_PROTOCOL;\n\n/* EFI Disk IO2 token */\ntypedef struct _EFI_DISK_IO2_TOKEN\n{\n    EFI_EVENT Event;\n    EFI_STATUS TransactionStatus;\n} EFI_DISK_IO2_TOKEN, *PEFI_DISK_IO2_TOKEN;\n\n/* EFI Disk IO2 protocol */\ntypedef struct _EFI_DISK_IO2_PROTOCOL\n{\n    UINT64 Revision;\n    PEFI_DISK_CANCEL_EX Cancel;\n    PEFI_DISK_READ_EX ReadDiskEx;\n    PEFI_DISK_WRITE_EX WriteDiskEx;\n    PEFI_DISK_FLUSH_EX FlushDiskEx;\n} EFI_DISK_IO2_PROTOCOL, *PEFI_DISK_IO2_PROTOCOL;\n\n/* EFI Simple File System (SFS) protocol */\ntypedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL\n{\n    UINT64 Revision;\n    PEFI_VOLUME_OPEN OpenVolume;\n} EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, *PEFI_SIMPLE_FILE_SYSTEM_PROTOCOL;\n\n/* EFI File I/O token */\ntypedef struct _EFI_FILE_IO_TOKEN\n{\n    EFI_EVENT Event;\n    EFI_STATUS Status;\n    UINT_PTR BufferSize;\n    PVOID Buffer;\n} EFI_FILE_IO_TOKEN, *PEFI_FILE_IO_TOKEN;\n\n/* EFI File Handle */\ntypedef struct _EFI_FILE_HANDLE\n{\n    UINT64 Revision;\n    PEFI_FILE_OPEN Open;\n    PEFI_FILE_CLOSE Close;\n    PEFI_FILE_DELETE Delete;\n    PEFI_FILE_READ Read;\n    PEFI_FILE_WRITE Write;\n    PEFI_FILE_GET_POSITION GetPosition;\n    PEFI_FILE_SET_POSITION SetPosition;\n    PEFI_FILE_GET_INFO GetInfo;\n    PEFI_FILE_SET_INFO SetInfo;\n    PEFI_FILE_FLUSH Flush;\n    PEFI_FILE_OPEN_EX OpenEx;\n    PEFI_FILE_READ_EX ReadEx;\n    PEFI_FILE_WRITE_EX WriteEx;\n    PEFI_FILE_FLUSH_EX FlushEx;\n} EFI_FILE_HANDLE, *PEFI_FILE_HANDLE;\n\n/* EFI File Info structure */\ntypedef struct _EFI_FILE_INFO\n{\n    UINT64 Size;\n    UINT64 FileSize;\n    UINT64 PhysicalSize;\n    EFI_TIME CreateTime;\n    EFI_TIME LastAccessTime;\n    EFI_TIME ModificationTime;\n    UINT64 Attribute;\n    WCHAR FileName[1];\n} EFI_FILE_INFO, *PEFI_FILE_INFO;\n\n/* EFI File System Info structure */\ntypedef struct _EFI_FILE_SYSTEM_INFO\n{\n    UINT64 Size;\n    UCHAR ReadOnly;\n    UINT64 VolumeSize;\n    UINT64 FreeSpace;\n    UINT32 BlockSize;\n    UINT16 VolumeLabel[1];\n} EFI_FILE_SYSTEM_INFO, *PEFI_FILE_SYSTEM_INFO;\n\n/* EFI File System Volume Label */\ntypedef struct _EFI_FILE_SYSTEM_VOLUME_LABEL\n{\n    UINT16 VolumeLabel[1];\n} EFI_FILE_SYSTEM_VOLUME_LABEL, *PEFI_FILE_SYSTEM_VOLUME_LABEL;\n\n/* Load file protocol */\ntypedef struct _EFI_LOAD_FILE_PROTOCOL\n{\n    PEFI_LOAD_FILE LoadFile;\n} EFI_LOAD_FILE_PROTOCOL, *PEFI_LOAD_FILE_PROTOCOL;\n\n/* EFI I/O access structure */\ntypedef struct _EFI_IO_ACCESS\n{\n    PEFI_DEVICE_IO Read;\n    PEFI_DEVICE_IO Write;\n} EFI_IO_ACCESS, *PEFI_IO_ACCESS;\n\n/* EFI Device I/O protocol */\ntypedef struct _EFI_DEVICE_IO_PROTOCOL\n{\n    EFI_IO_ACCESS Mem;\n    EFI_IO_ACCESS Io;\n    EFI_IO_ACCESS Pci;\n    PEFI_IO_MAP Map;\n    PEFI_PCIDEV_DEVICE_PATH PciDevicePath;\n    PEFI_IO_UNMAP Unmap;\n    PEFI_IO_ALLOCATE_BUFFER AllocateBuffer;\n    PEFI_IO_FLUSH Flush;\n    PEFI_IO_FREE_BUFFER FreeBuffer;\n} EFI_DEVICE_IO_PROTOCOL, *PEFI_DEVICE_IO_PROTOCOL;\n\n/* EFI Hash Output union */\ntypedef union _EFI_HASH_OUTPUT\n{\n    PUINT8 Md5Hash;\n    PUINT8 Sha1Hash;\n    PUINT8 Sha224Hash;\n    PUINT8 Sha256Hash;\n    PUINT8 Sha384Hash;\n    PUINT8 Sha512Hash;\n} EFI_HASH_OUTPUT, *PEFI_HASH_OUTPUT;\n\n/* EFI Hash protocol */\ntypedef struct _EFI_HASH_PROTOCOL\n{\n    PEFI_HASH_GET_HASH_SIZE GetHashSize;\n    PEFI_HASH_HASH Hash;\n} EFI_HASH_PROTOCOL, *PEFI_HASH_PROTOCOL;\n\n/* EFI Unicode Collation protocol */\ntypedef struct _EFI_UNICODE_COLLATION_PROTOCOL\n{\n    PEFI_UNICODE_STRICOLL StriColl;\n    PEFI_UNICODE_METAIMATCH MetaiMatch;\n    PEFI_UNICODE_STRLWR StrLwr;\n    PEFI_UNICODE_STRUPR StrUpr;\n    PEFI_UNICODE_FATTOSTR FatToStr;\n    PEFI_UNICODE_STRTOFAT StrToFat;\n    PUINT8 SupportedLanguages;\n} EFI_UNICODE_COLLATION_PROTOCOL, *PEFI_UNICODE_COLLATION_PROTOCOL;\n\n/* EFI Pixel bitmask */\ntypedef struct _EFI_PIXEL_BITMASK\n{\n    UINT32 RedMask;\n    UINT32 GreenMask;\n    UINT32 BlueMask;\n    UINT32 ReservedMask;\n} EFI_PIXEL_BITMASK, *PEFI_PIXEL_BITMASK;\n\n/* EFI GOP output mode information */\ntypedef struct _EFI_GRAPHICS_OUTPUT_MODE_INFORMATION\n{\n    UINT32 Version;\n    UINT32 HorizontalResolution;\n    UINT32 VerticalResolution;\n    EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;\n    EFI_PIXEL_BITMASK PixelInformation;\n    UINT32 PixelsPerScanLine;\n} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION, *PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION;\n\n/* EFI GOP output blt pixel */\ntypedef struct _EFI_GRAPHICS_OUTPUT_BLT_PIXEL\n{\n    UINT8 Blue;\n    UINT8 Green;\n    UINT8 Red;\n    UINT8 Reserved;\n} EFI_GRAPHICS_OUTPUT_BLT_PIXEL, *PEFI_GRAPHICS_OUTPUT_BLT_PIXEL;\n\n/* EFI GOP output blt pixel */\ntypedef union _EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION\n{\n    EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel;\n    UINT32 Raw;\n} EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION, *PEFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION;\n\n/* EFI GOP output protocol mode */\ntypedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE\n{\n    UINT32 MaxMode;\n    UINT32 Mode;\n    PEFI_GRAPHICS_OUTPUT_MODE_INFORMATION Info;\n    UINT_PTR SizeOfInfo;\n    EFI_PHYSICAL_ADDRESS FrameBufferBase;\n    UINT_PTR FrameBufferSize;\n} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE, *PEFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;\n\n/* EFI GOP output protocol */\ntypedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL\n{\n    PEFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;\n    PEFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;\n    PEFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;\n    PEFI_GRAPHICS_OUTPUT_PROTOCOL_MODE Mode;\n} EFI_GRAPHICS_OUTPUT_PROTOCOL, *PEFI_GRAPHICS_OUTPUT_PROTOCOL;\n\n/* EFI UGA adapter protocol */\ntypedef struct _EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL\n{\n    PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GET_MODE GetMode;\n    PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_SET_MODE SetMode;\n    PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_BLT Blt;\n} EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL, *PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL;\n\n/* EFI UGA PIXEL */\ntypedef struct _EFI_UNIVERSAL_GRAPHICS_BLT_PIXEL\n{\n    UINT8 Blue;\n    UINT8 Green;\n    UINT8 Red;\n    UINT8 Reserved;\n} EFI_UNIVERSAL_GRAPHICS_BLT_PIXEL, *PEFI_UNIVERSAL_GRAPHICS_BLT_PIXEL;\n\n/* EFI EDID discover protocol */\ntypedef struct _EFI_EDID_DISCOVERED_PROTOCOL\n{\n    UINT32 SizeOfEdid;\n    PUINT8 Edid;\n} EFI_EDID_DISCOVERED_PROTOCOL, *PEFI_EDID_DISCOVERED_PROTOCOL;\n\n/* EFI EDID active protocol */\ntypedef struct _EFI_EDID_ACTIVE_PROTOCOL\n{\n    UINT32 SizeOfEdid;\n    PUINT8 Edid;\n} EFI_EDID_ACTIVE_PROTOCOL, *PEFI_EDID_ACTIVE_PROTOCOL;\n\n/* EFI EDID override protocol */\ntypedef struct _EFI_EDID_OVERRIDE_PROTOCOL\n{\n    PEFI_EDID_OVERRIDE_PROTOCOL_GET_EDID GetEdid;\n} EFI_EDID_OVERRIDE_PROTOCOL, *PEFI_EDID_OVERRIDE_PROTOCOL;\n\n/* EFI BBS status flags */\ntypedef struct _EFI_BBS_STATUS_FLAGS\n{\n    UINT16 OldPosition:4;\n    UINT16 Reserved1:4;\n    UINT16 Enabled:1;\n    UINT16 Failed:1;\n    UINT16 MediaPresent:2;\n    UINT16 Reserved2:4;\n} EFI_BBS_STATUS_FLAGS, *PEFI_BBS_STATUS_FLAGS;\n\n/* EFI BBS table */\ntypedef struct _EFI_BBS_TABLE\n{\n    UINT16 BootPriority;\n    UINT32 Bus;\n    UINT32 Device;\n    UINT32 Function;\n    UINT8 Class;\n    UINT8 SubClass;\n    UINT16 MfgStringOffset;\n    UINT16 MfgStringSegment;\n    UINT16 DeviceType;\n    EFI_BBS_STATUS_FLAGS StatusFlags;\n    UINT16 BootHandlerOffset;\n    UINT16 BootHandlerSegment;\n    UINT16 DescStringOffset;\n    UINT16 DescStringSegment;\n    UINT32 InitPerReserved;\n    UINT32 AdditionalIrq13Handler;\n    UINT32 AdditionalIrq18Handler;\n    UINT32 AdditionalIrq19Handler;\n    UINT32 AdditionalIrq40Handler;\n    UINT8 AssignedDriveNumber;\n    UINT32 AdditionalIrq41Handler;\n    UINT32 AdditionalIrq46Handler;\n    UINT32 IBV1;\n    UINT32 IBV2;\n} EFI_BBS_TABLE, *PEFI_BBS_TABLE;\n\n/* EFI ATAPI identify data */\ntypedef struct _EFI_ATAPI_IDENTIFY\n{\n    UINT16 Raw[256];\n} EFI_ATAPI_IDENTIFY, *PEFI_ATAPI_IDENTIFY;\n\n/* EFI HDD info structure */\ntypedef struct _EFI_HDD_INFO\n{\n    UINT16 Status;\n    UINT32 Bus;\n    UINT32 Device;\n    UINT32 Function;\n    UINT16 CommandBaseAddress;\n    UINT16 ControlBaseAddress;\n    UINT16 BusMasterAddress;\n    UINT8 HddIrq;\n    EFI_ATAPI_IDENTIFY IdentifyDrive[2];\n} EFI_HDD_INFO, *PEFI_HDD_INFO;\n\n/* EFI x86 EFLAGS register set */\ntypedef struct _EFI_EFLAGS_REG\n{\n    UINT32 CF:1;\n    UINT32 Reserved1:1;\n    UINT32 PF:1;\n    UINT32 Reserved2:1;\n    UINT32 AF:1;\n    UINT32 Reserved3:1;\n    UINT32 ZF:1;\n    UINT32 SF:1;\n    UINT32 TF:1;\n    UINT32 IF:1;\n    UINT32 DF:1;\n    UINT32 OF:1;\n    UINT32 IOPL:2;\n    UINT32 NT:1;\n    UINT32 Reserved4:2;\n    UINT32 VM:1;\n    UINT32 Reserved5:14;\n} EFI_EFLAGS_REG, *PEFI_EFLAGS_REG;\n\n/* EFI x86 FLAGS register set */\ntypedef struct _EFI_FLAGS_REG\n{\n    UINT16 CF:1;\n    UINT16 Reserved1:1;\n    UINT16 PF:1;\n    UINT16 Reserved2:1;\n    UINT16 AF:1;\n    UINT16 Reserved3:1;\n    UINT16 ZF:1;\n    UINT16 SF:1;\n    UINT16 TF:1;\n    UINT16 IF:1;\n    UINT16 DF:1;\n    UINT16 OF:1;\n    UINT16 IOPL:2;\n    UINT16 NT:1;\n    UINT16 Reserved4:1;\n} EFI_FLAGS_REG, *PEFI_FLAGS_REG;\n\n/* EFI x86 BYTE register set */\ntypedef struct _EFI_BYTE_REGS\n{\n    UINT8 AL;\n    UINT8 AH;\n    UINT16 ReservedAX;\n    UINT8 BL;\n    UINT8 BH;\n    UINT16 ReservedBX;\n    UINT8 CL;\n    UINT8 CH;\n    UINT16 ReservedCX;\n    UINT8 DL;\n    UINT8 DH;\n    UINT16 ReservedDX;\n} EFI_BYTE_REGS, *PEFI_BYTE_REGS;\n\n/* EFI x86 DWORD register set */\ntypedef struct _EFI_DWORD_REGS\n{\n    UINT32 EAX;\n    UINT32 EBX;\n    UINT32 ECX;\n    UINT32 EDX;\n    UINT32 ESI;\n    UINT32 EDI;\n    EFI_EFLAGS_REG EFlags;\n    UINT16 ES;\n    UINT16 CS;\n    UINT16 SS;\n    UINT16 DS;\n    UINT16 FS;\n    UINT16 GS;\n    UINT32 EBP;\n    UINT32 ESP;\n} EFI_DWORD_REGS, *PEFI_DWORD_REGS;\n\n/* EFI x86 WORD register set */\ntypedef struct _EFI_WORD_REGS\n{\n    UINT16 AX;\n    UINT16 ReservedAX;\n    UINT16 BX;\n    UINT16 ReservedBX;\n    UINT16 CX;\n    UINT16 ReservedCX;\n    UINT16 DX;\n    UINT16 ReservedDX;\n    UINT16 SI;\n    UINT16 ReservedSI;\n    UINT16 DI;\n    UINT16 ReservedDI;\n    EFI_FLAGS_REG Flags;\n    UINT16 ReservedFlags;\n    UINT16 ES;\n    UINT16 CS;\n    UINT16 SS;\n    UINT16 DS;\n    UINT16 FS;\n    UINT16 GS;\n    UINT16 BP;\n    UINT16 ReservedBP;\n    UINT16 SP;\n    UINT16 ReservedSP;\n} EFI_WORD_REGS, *PEFI_WORD_REGS;\n\n/* EFI x86 register set union */\ntypedef union _EFI_IA32_REGISTER_SET\n{\n    EFI_DWORD_REGS E;\n    EFI_WORD_REGS X;\n    EFI_BYTE_REGS H;\n} EFI_IA32_REGISTER_SET, *PEFI_IA32_REGISTER_SET;\n\n/* EFI legacy BIOS (CSM) support protocol */\ntypedef struct _EFI_LEGACY_BIOS_PROTOCOL\n{\n    PEFI_LEGACY_BIOS_INT86 Int86;\n    PEFI_LEGACY_BIOS_FARCALL86 FarCall86;\n    PEFI_LEGACY_BIOS_CHECK_ROM CheckPciRom;\n    PEFI_LEGACY_BIOS_INSTALL_ROM InstallPciRom;\n    PEFI_LEGACY_BIOS_BOOT LegacyBoot;\n    PEFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS UpdateKeyboardLedStatus;\n    PEFI_LEGACY_BIOS_GET_BBS_INFO GetBbsInfo;\n    PEFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS ShadowAllLegacyOproms;\n    PEFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI PrepareToBootEfi;\n    PEFI_LEGACY_BIOS_GET_LEGACY_REGION GetLegacyRegion;\n    PEFI_LEGACY_BIOS_COPY_LEGACY_REGION CopyLegacyRegion;\n    PEFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE BootUnconventionalDevice;\n} EFI_LEGACY_BIOS_PROTOCOL, *PEFI_LEGACY_BIOS_PROTOCOL;\n\n/* EFI UDC attributes */\ntypedef struct _EFI_UDC_ATTRIBUTES\n{\n    UINT8 DirectoryServiceValidity:1;\n    UINT8 RabcaUsedFlag:1;\n    UINT8 ExecuteHddDiagnosticsFlag:1;\n    UINT8 Reserved:5;\n} EFI_UDC_ATTRIBUTES, *PEFI_UDC_ATTRIBUTES;\n\n/* EFI Service binding */\ntypedef struct _EFI_SERVICE_BINDING\n{\n    PEFI_SERVICE_BINDING_CREATE_CHILD CreateChild;\n    PEFI_SERVICE_BINDING_DESTROY_CHILD DestroyChild;\n} EFI_SERVICE_BINDING, *PEFI_SERVICE_BINDING;\n\n/* EFI driver binding protocol */\ntypedef struct _EFI_DRIVER_BINDING_PROTOCOL\n{\n    PEFI_DRIVER_BINDING_PROTOCOL_SUPPORTED Supported;\n    PEFI_DRIVER_BINDING_PROTOCOL_START Start;\n    PEFI_DRIVER_BINDING_PROTOCOL_STOP Stop;\n    UINT32 Version;\n    EFI_HANDLE ImageHandle;\n    EFI_HANDLE DriverBindingHandle;\n} EFI_DRIVER_BINDING_PROTOCOL, *PEFI_DRIVER_BINDING_PROTOCOL;\n\n/* EFI component name protocol */\ntypedef struct _EFI_COMPONENT_NAME_PROTOCOL\n{\n    PEFI_COMPONENT_NAME_GET_DRIVER_NAME GetDriverName;\n    PEFI_COMPONENT_NAME_GET_CONTROLLER_NAME GetControllerName;\n    PUINT8 SupportedLanguages;\n} EFI_COMPONENT_NAME_PROTOCOL, *PEFI_COMPONENT_NAME_PROTOCOL;\n\n/* EFI component name2 protocol */\ntypedef struct _EFI_COMPONENT_NAME2_PROTOCOL\n{\n    PEFI_COMPONENT_NAME2_GET_DRIVER_NAME GetDriverName;\n    PEFI_COMPONENT_NAME2_GET_CONTROLLER_NAME GetControllerName;\n    PUINT8 SupportedLanguages;\n} EFI_COMPONENT_NAME2_PROTOCOL, *PEFI_COMPONENT_NAME2_PROTOCOL;\n\n/* EFI loaded image protocol */\ntypedef struct _EFI_LOADED_IMAGE_PROTOCOL\n{\n    UINT32 Revision;\n    EFI_HANDLE ParentHandle;\n    PEFI_SYSTEM_TABLE SystemTable;\n    EFI_HANDLE DeviceHandle;\n    PEFI_DEVICE_PATH_PROTOCOL FilePath;\n    PVOID Reserved;\n    UINT32 LoadOptionsSize;\n    PVOID LoadOptions;\n    PVOID ImageBase;\n    UINT64 ImageSize;\n    EFI_MEMORY_TYPE ImageCodeType;\n    EFI_MEMORY_TYPE ImageDataType;\n    PEFI_IMAGE_UNLOAD Unload;\n} EFI_LOADED_IMAGE_PROTOCOL, *PEFI_LOADED_IMAGE_PROTOCOL;\n\n/* EFI RNG protocol */\ntypedef struct _EFI_RNG_PROTOCOL\n{\n    PEFI_RNG_GET_INFO GetInfo;\n    PEFI_RNG_GET_RNG GetRNG;\n} EFI_RNG_PROTOCOL, *PEFI_RNG_PROTOCOL;\n\n/* EFI platform driver override protocol */\ntypedef struct _EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL\n{\n    PEFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER GetDriver;\n    PEFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER_PATH GetDriverPath;\n    PEFI_PLATFORM_DRIVER_OVERRIDE_DRIVER_LOADED DriverLoaded;\n} EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL, *PEFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL;\n\n/* EFI bus specific driver override protocol */\ntypedef struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL\n{\n    PEFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER GetDriver;\n} EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL, *PEFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL;\n\n/* EFI driver family override protocol */\ntypedef struct _EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL\n{\n    PEFI_DRIVER_FAMILY_OVERRIDE_GET_VERSION GetVersion;\n} EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL, *PEFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL;\n\n/* EFI EBC protocol */\ntypedef struct _EFI_EBC_PROTOCOL\n{\n    PEFI_EBC_CREATE_THUNK CreateThunk;\n    PEFI_EBC_UNLOAD_IMAGE UnloadImage;\n    PEFI_EBC_REGISTER_ICACHE_FLUSH RegisterICacheFlush;\n    PEFI_EBC_GET_VERSION GetVersion;\n} EFI_EBC_PROTOCOL, *PEFI_EBC_PROTOCOL;\n\n/* EFI partition header */\ntypedef struct _EFI_PARTITION_HEADER\n{\n    EFI_TABLE_HEADER Hdr;\n    UINT32 DirectoryAllocationNumber;\n    UINT32 BlockSize;\n    EFI_LBA FirstUsableLba;\n    EFI_LBA LastUsableLba;\n    EFI_LBA UnusableSpace;\n    EFI_LBA FreeSpace;\n    EFI_LBA RootFile;\n    EFI_LBA SecutiryFile;\n} EFI_PARTITION_HEADER, *PEFI_PARTITION_HEADER;\n\n/* MBR partition information */\ntypedef struct _EFI_MBR_PARTITION_RECORD\n{\n    UINT8 BootIndicator;\n    UINT8 StartHead;\n    UINT8 StartSector;\n    UINT8 StartTrack;\n    UINT8 OSIndicator;\n    UINT8 EndHead;\n    UINT8 EndSector;\n    UINT8 EndTrack;\n    UINT8 StartingLBA[4];\n    UINT8 SizeInLBA[4];\n} EFI_MBR_PARTITION_RECORD, *PEFI_MBR_PARTITION_RECORD;\n\n/* Master Boot Record (MBR) information */\ntypedef struct _EFI_MASTER_BOOT_RECORD\n{\n    UINT8 BootStrapCode[440];\n    UINT8 UniqueMbrSignature[4];\n    UINT8 Unknown[2];\n    EFI_MBR_PARTITION_RECORD Partition[4];\n    UINT16 Signature;\n} EFI_MASTER_BOOT_RECORD, *PEFI_MASTER_BOOT_RECORD;\n\n/* GUID Partition Table (GPT) header */\ntypedef struct _EFI_GPT_PARTITION_TABLE_HEADER\n{\n    EFI_TABLE_HEADER Header;\n    EFI_LBA MyLBA;\n    EFI_LBA AlternateLBA;\n    EFI_LBA FirstUsableLBA;\n    EFI_LBA LastUsableLBA;\n    EFI_GUID DiskGUID;\n    EFI_LBA PartitionEntryLBA;\n    UINT32 NumberOfPartitionEntries;\n    UINT32 SizeOfPartitionEntry;\n    UINT32 PartitionEntryArrayCRC32;\n} EFI_GPT_PARTITION_TABLE_HEADER, *PEFI_GPT_PARTITION_TABLE_HEADER;\n\n/* GUID Partition Table (GPT) partition entry */\ntypedef struct _EFI_GPT_PARTITION_ENTRY\n{\n    EFI_GUID PartitionTypeGUID;\n    EFI_GUID UniquePartitionGUID;\n    EFI_LBA StartingLBA;\n    EFI_LBA EndingLBA;\n    UINT64 Attributes;\n    WCHAR PartitionName[36];\n} EFI_GPT_PARTITION_ENTRY, *PEFI_GPT_PARTITION_ENTRY;\n\n/* EFI file header */\ntypedef struct _EFI_FILE_HEADER\n{\n    EFI_TABLE_HEADER Hdr;\n    UINT32 Class;\n    UINT32 LBALOffset;\n    EFI_LBA Parent;\n    UINT64 FileSize;\n    UINT64 FileAttributes;\n    EFI_TIME FileCreateTime;\n    EFI_TIME FileModificationTime;\n    EFI_GUID VendorGuid;\n    UINT16 FileString[260];\n} EFI_FILE_HEADER, *PEFI_FILE_HEADER;\n\n/* Logical Block Address List (LBA List) */\ntypedef struct _EFI_LBAL\n{\n    EFI_TABLE_HEADER Hdr;\n    UINT32 Class;\n    EFI_LBA Parent;\n    EFI_LBA Next;\n    UINT32 ArraySize;\n    UINT32 ArrayCount;\n} EFI_LBAL, *PEFI_LBAL;\n\n/* Logical Block run-length */\ntypedef struct _EFI_RL\n{\n    EFI_LBA     Start;\n    UINT64      Length;\n} EFI_RL, *PEFI_RL;\n\n/* EFI UART I/O mode */\ntypedef struct _EFI_UART_IO_MODE\n{\n    UINT32 ControlMask;\n    UINT32 Timeout;\n    UINT64 BaudRate;\n    UINT32 ReceiveFifoDepth;\n    UINT32 DataBits;\n    UINT32 Parity;\n    UINT32 StopBits;\n} EFI_UART_IO_MODE, *PEFI_UART_IO_MODE;\n\n/* EFI UART I/O protocol */\ntypedef struct _EFI_UART_IO_PROTOCOL {\n    UINT32 Revision;\n    PEFI_UART_RESET Reset;\n    PEFI_UART_SET_ATTRIBUTES SetAttributes;\n    PEFI_UART_SET_CONTROL_BITS SetControl;\n    PEFI_UART_GET_CONTROL_BITS GetControl;\n    PEFI_UART_WRITE Write;\n    PEFI_UART_READ Read;\n    PEFI_UART_IO_MODE Mode;\n} EFI_UART_IO_PROTOCOL, *PEFI_UART_IO_PROTOCOL;\n\n/* EFI IP address definition */\ntypedef union _EFI_IP_ADDRESS\n{\n    UINT32 Addr[4];\n    EFI_IPv4_ADDRESS v4;\n    EFI_IPv6_ADDRESS v6;\n} EFI_IP_ADDRESS, *PEFI_IP_ADDRESS;\n\n/* EFI DHCPv4 packet definition */\ntypedef struct _EFI_PXE_BASE_CODE_DHCPV4_PACKET\n{\n    UINT8 BootpOpcode;\n    UINT8 BootpHwType;\n    UINT8 BootpHwAddrLen;\n    UINT8 BootpGateHops;\n    UINT32 BootpIdent;\n    UINT16 BootpSeconds;\n    UINT16 BootpFlags;\n    UINT8 BootpCiAddr[4];\n    UINT8 BootpYiAddr[4];\n    UINT8 BootpSiAddr[4];\n    UINT8 BootpGiAddr[4];\n    UINT8 BootpHwAddr[16];\n    UINT8 BootpSrvName[64];\n    UINT8 BootpBootFile[128];\n    UINT32 DhcpMagik;\n    UINT8 DhcpOptions[56];\n} EFI_PXE_BASE_CODE_DHCPV4_PACKET, *PEFI_PXE_BASE_CODE_DHCPV4_PACKET;\n\n/* EFI DHCPv6 packet definition */\ntypedef struct _EFI_PXE_BASE_CODE_DHCPV6_PACKET\n{\n    UINT32 MessageType:8;\n    UINT32 TransactionId:24;\n    UINT8 DhcpOptions[1024];\n} EFI_PXE_BASE_CODE_DHCPV6_PACKET, *PEFI_PXE_BASE_CODE_DHCPV6_PACKET;\n\n/* EFI packet definition */\ntypedef union _EFI_PXE_BASE_CODE_PACKET\n{\n    UINT8 Raw[1472];\n    EFI_PXE_BASE_CODE_DHCPV4_PACKET Dhcpv4;\n    EFI_PXE_BASE_CODE_DHCPV6_PACKET Dhcpv6;\n} EFI_PXE_BASE_CODE_PACKET, *PEFI_PXE_BASE_CODE_PACKET;\n\n/* EFI ICMP error definition */\ntypedef struct _EFI_PXE_BASE_CODE_ICMP_ERROR\n{\n    UINT8 Type;\n    UINT8 Code;\n    UINT16 Checksum;\n    union\n    {\n        UINT32 reserved;\n        UINT32 Mtu;\n        UINT32 Pointer;\n        struct\n        {\n            UINT16 Identifier;\n            UINT16 Sequence;\n        } Echo;\n    } u;\n    UINT8 Data[494];\n} EFI_PXE_BASE_CODE_ICMP_ERROR, *PEFI_PXE_BASE_CODE_ICMP_ERROR;\n\n/* EFI TFTP error definition */\ntypedef struct _EFI_PXE_BASE_CODE_TFTP_ERROR\n{\n    UINT8 ErrorCode;\n    UINT8 ErrorString[127];\n} EFI_PXE_BASE_CODE_TFTP_ERROR, *PEFI_PXE_BASE_CODE_TFTP_ERROR;\n\n/* EFI IP filter */\ntypedef struct _EFI_PXE_BASE_CODE_IP_FILTER\n{\n    UINT8 Filters;\n    UINT8 IpCnt;\n    UINT16 reserved;\n    EFI_IP_ADDRESS IpList[8];\n} EFI_PXE_BASE_CODE_IP_FILTER, *PEFI_PXE_BASE_CODE_IP_FILTER;\n\n/* EFI ARP cache entry */\ntypedef struct _EFI_PXE_BASE_CODE_ARP_ENTRY\n{\n    EFI_IP_ADDRESS IpAddr;\n    EFI_MAC_ADDRESS MacAddr;\n} EFI_PXE_BASE_CODE_ARP_ENTRY, *PEFI_PXE_BASE_CODE_ARP_ENTRY;\n\n/* EFI route cache entry */\ntypedef struct _EFI_PXE_BASE_CODE_ROUTE_ENTRY\n{\n    EFI_IP_ADDRESS IpAddr;\n    EFI_IP_ADDRESS SubnetMask;\n    EFI_IP_ADDRESS GwAddr;\n} EFI_PXE_BASE_CODE_ROUTE_ENTRY, *PEFI_PXE_BASE_CODE_ROUTE_ENTRY;\n\n/* EFI service list */\ntypedef struct _EFI_PXE_BASE_CODE_SRVLIST\n{\n    UINT16 Type;\n    UCHAR AcceptAnyResponse;\n    UINT8 Reserved;\n    EFI_IP_ADDRESS IpAddr;\n} EFI_PXE_BASE_CODE_SRVLIST, *PEFI_PXE_BASE_CODE_SRVLIST;\n\n/* EFI network discovery info */\ntypedef struct _EFI_PXE_BASE_CODE_DISCOVER_INFO\n{\n    UCHAR UseMCast;\n    UCHAR UseBCast;\n    UCHAR UseUCast;\n    UCHAR MustUseList;\n    EFI_IP_ADDRESS ServerMCastIp;\n    UINT16 IpCnt;\n    EFI_PXE_BASE_CODE_SRVLIST SrvList[1];\n} EFI_PXE_BASE_CODE_DISCOVER_INFO, *PEFI_PXE_BASE_CODE_DISCOVER_INFO;\n\n/* EFI TFTP info */\ntypedef struct _EFI_PXE_BASE_CODE_MTFTP_INFO\n{\n    EFI_IP_ADDRESS MCastIp;\n    UINT16 CPort;\n    UINT16 SPort;\n    UINT16 ListenTimeout;\n    UINT16 TransmitTimeout;\n} EFI_PXE_BASE_CODE_MTFTP_INFO, *PEFI_PXE_BASE_CODE_MTFTP_INFO;\n\n/* EFI PXE base code mode structure */\ntypedef struct _EFI_PXE_BASE_CODE_MODE\n{\n    UCHAR Started;\n    UCHAR Ipv6Available;\n    UCHAR Ipv6Supported;\n    UCHAR UsingIpv6;\n    UCHAR BisSupported;\n    UCHAR BisDetected;\n    UCHAR AutoArp;\n    UCHAR SendGUID;\n    UCHAR DhcpDiscoverValid;\n    UCHAR DhcpAckReceived;\n    UCHAR ProxyOfferReceived;\n    UCHAR PxeDiscoverValid;\n    UCHAR PxeReplyReceived;\n    UCHAR PxeBisReplyReceived;\n    UCHAR IcmpErrorReceived;\n    UCHAR TftpErrorReceived;\n    UCHAR MakeCallbacks;\n    UINT8 TTL;\n    UINT8 ToS;\n    EFI_IP_ADDRESS StationIp;\n    EFI_IP_ADDRESS SubnetMask;\n    EFI_PXE_BASE_CODE_PACKET DhcpDiscover;\n    EFI_PXE_BASE_CODE_PACKET DhcpAck;\n    EFI_PXE_BASE_CODE_PACKET ProxyOffer;\n    EFI_PXE_BASE_CODE_PACKET PxeDiscover;\n    EFI_PXE_BASE_CODE_PACKET PxeReply;\n    EFI_PXE_BASE_CODE_PACKET PxeBisReply;\n    EFI_PXE_BASE_CODE_IP_FILTER IpFilter;\n    UINT32 ArpCacheEntries;\n    EFI_PXE_BASE_CODE_ARP_ENTRY ArpCache[8];\n    UINT32 RouteTableEntries;\n    EFI_PXE_BASE_CODE_ROUTE_ENTRY RouteTable[8];\n    EFI_PXE_BASE_CODE_ICMP_ERROR IcmpError;\n    EFI_PXE_BASE_CODE_TFTP_ERROR TftpError;\n} EFI_PXE_BASE_CODE_MODE, *PEFI_PXE_BASE_CODE_MODE;\n\n/* EFI PXE base code protocol */\ntypedef struct _EFI_PXE_BASE_CODE_PROTOCOL {\n    UINT64 Revision;\n    PEFI_PXE_BASE_CODE_START Start;\n    PEFI_PXE_BASE_CODE_STOP Stop;\n    PEFI_PXE_BASE_CODE_DHCP Dhcp;\n    PEFI_PXE_BASE_CODE_DISCOVER Discover;\n    PEFI_PXE_BASE_CODE_MTFTP Mtftp;\n    PEFI_PXE_BASE_CODE_UDP_WRITE UdpWrite;\n    PEFI_PXE_BASE_CODE_UDP_READ UdpRead;\n    PEFI_PXE_BASE_CODE_SET_IP_FILTER SetIpFilter;\n    PEFI_PXE_BASE_CODE_ARP Arp;\n    PEFI_PXE_BASE_CODE_SET_PARAMETERS SetParameters;\n    PEFI_PXE_BASE_CODE_SET_STATION_IP SetStationIp;\n    PEFI_PXE_BASE_CODE_SET_PACKETS SetPackets;\n    PEFI_PXE_BASE_CODE_MODE Mode;\n} EFI_PXE_BASE_CODE_PROTOCOL, *PEFI_PXE_BASE_CODE_PROTOCOL;\n\n/* EFI PXE base code callback protocol */\ntypedef struct _EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL {\n    UINT64 Revision;\n    PEFI_PXE_CALLBACK Callback;\n} EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL, *PEFI_PXE_BASE_CODE_CALLBACK_PROTOCOL;\n\n/* EFI network statistics structure */\ntypedef struct _EFI_NETWORK_STATISTICS\n{\n    UINT64 RxTotalFrames;\n    UINT64 RxGoodFrames;\n    UINT64 RxUndersizeFrames;\n    UINT64 RxOversizeFrames;\n    UINT64 RxDroppedFrames;\n    UINT64 RxUnicastFrames;\n    UINT64 RxBroadcastFrames;\n    UINT64 RxMulticastFrames;\n    UINT64 RxCrcErrorFrames;\n    UINT64 RxTotalBytes;\n    UINT64 TxTotalFrames;\n    UINT64 TxGoodFrames;\n    UINT64 TxUndersizeFrames;\n    UINT64 TxOversizeFrames;\n    UINT64 TxDroppedFrames;\n    UINT64 TxUnicastFrames;\n    UINT64 TxBroadcastFrames;\n    UINT64 TxMulticastFrames;\n    UINT64 TxCrcErrorFrames;\n    UINT64 TxTotalBytes;\n    UINT64 Collisions;\n    UINT64 UnsupportedProtocol;\n} EFI_NETWORK_STATISTICS, *PEFI_NETWORK_STATISTICS;\n\n/* EFI network mode structure */\ntypedef struct _EFI_SIMPLE_NETWORK_MODE\n{\n    UINT32 State;\n    UINT32 HwAddressSize;\n    UINT32 MediaHeaderSize;\n    UINT32 MaxPacketSize;\n    UINT32 NvRamSize;\n    UINT32 NvRamAccessSize;\n    UINT32 ReceiveFilterMask;\n    UINT32 ReceiveFilterSetting;\n    UINT32 MaxMCastFilterCount;\n    UINT32 MCastFilterCount;\n    EFI_MAC_ADDRESS MCastFilter[16];\n    EFI_MAC_ADDRESS CurrentAddress;\n    EFI_MAC_ADDRESS BroadcastAddress;\n    EFI_MAC_ADDRESS PermanentAddress;\n    UINT8 IfType;\n    UCHAR MacAddressChangeable;\n    UCHAR MultipleTxSupported;\n    UCHAR MediaPresentSupported;\n    UCHAR MediaPresent;\n} EFI_SIMPLE_NETWORK_MODE, *PEFI_SIMPLE_NETWORK_MODE;\n\n/* EFI network protocol structure */\ntypedef struct _EFI_SIMPLE_NETWORK_PROTOCOL\n{\n    UINT64 Revision;\n    PEFI_SIMPLE_NETWORK_START Start;\n    PEFI_SIMPLE_NETWORK_STOP Stop;\n    PEFI_SIMPLE_NETWORK_INITIALIZE Initialize;\n    PEFI_SIMPLE_NETWORK_RESET Reset;\n    PEFI_SIMPLE_NETWORK_SHUTDOWN Shutdown;\n    PEFI_SIMPLE_NETWORK_RECEIVE_FILTERS ReceiveFilters;\n    PEFI_SIMPLE_NETWORK_STATION_ADDRESS StationAddress;\n    PEFI_SIMPLE_NETWORK_STATISTICS Statistics;\n    PEFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC MCastIpToMac;\n    PEFI_SIMPLE_NETWORK_NVDATA NvData;\n    PEFI_SIMPLE_NETWORK_GET_STATUS GetStatus;\n    PEFI_SIMPLE_NETWORK_TRANSMIT Transmit;\n    PEFI_SIMPLE_NETWORK_RECEIVE Receive;\n    EFI_EVENT WaitForPacket;\n    PEFI_SIMPLE_NETWORK_MODE Mode;\n} EFI_SIMPLE_NETWORK_PROTOCOL, *PEFI_SIMPLE_NETWORK_PROTOCOL;\n\n/* EFI Framework MP (Multiprocessor) services protocol */\ntypedef struct _EFI_FRAMEWORK_MP_SERVICES_PROTOCOL\n{\n    PEFI_FRAMEWORK_MP_SERVICES_GET_GENERAL_MP_INFO GetGeneralMPInfo;\n    PEFI_FRAMEWORK_MP_SERVICES_GET_PROCESSOR_CONTEXT GetProcessorContext;\n    PEFI_FRAMEWORK_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs;\n    PEFI_FRAMEWORK_MP_SERVICES_STARTUP_THIS_AP StartupThisAP;\n    PEFI_FRAMEWORK_MP_SERVICES_SWITCH_BSP SwitchBSP;\n    PEFI_FRAMEWORK_MP_SERVICES_SEND_IPI SendIPI;\n    PEFI_FRAMEWORK_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP;\n    PEFI_FRAMEWORK_MP_SERVICES_WHOAMI WhoAmI;\n} EFI_FRAMEWORK_MP_SERVICES_PROTOCOL, *PEFI_FRAMEWORK_MP_SERVICES_PROTOCOL;\n\n/* EFI Framework MP (Multiprocessor) health flags union */\ntypedef union _EFI_FRAMEWORK_MP_HEALTH_FLAGS\n{\n    struct\n    {\n        UINT Status:2;\n        UINT Tested:1;\n        UINT Reserved1:13;\n        UINT VirtualMemoryUnavailable:1;\n        UINT Ia32ExecutionUnavailable:1;\n        UINT FloatingPointUnavailable:1;\n        UINT MiscFeaturesUnavailable:1;\n        UINT Reserved2:12;\n    } Bits;\n    UINT Uint32;\n} EFI_FRAMEWORK_MP_HEALTH_FLAGS, *PEFI_FRAMEWORK_MP_HEALTH_FLAGS;\n\n/* EFI Framework MP (Multiprocessor) health structure */\ntypedef struct _EFI_FRAMEWORK_MP_HEALTH\n{\n    EFI_FRAMEWORK_MP_HEALTH_FLAGS Flags;\n    UINT TestStatus;\n} EFI_FRAMEWORK_MP_HEALTH, *PEFI_FRAMEWORK_MP_HEALTH;\n\n/* EFI Framework processor context structure */\ntypedef struct _EFI_FRAMEWORK_MP_PROCESSOR_CONTEXT\n{\n    UINT ApicID;\n    BOOLEAN Enabled;\n    EFI_FRAMEWORK_CPU_DESIGNATION Designation;\n    EFI_FRAMEWORK_MP_HEALTH Health;\n    UINT_PTR PackageNumber;\n    UINT_PTR NumberOfCores;\n    UINT_PTR NumberOfThreads;\n    ULONGLONG ProcessorPALCompatibilityFlags;\n    ULONGLONG ProcessorTestMask;\n} EFI_FRAMEWORK_MP_PROCESSOR_CONTEXT, *PEFI_FRAMEWORK_MP_PROCESSOR_CONTEXT;\n\n/* EFI MP (Multiprocessor) services protocol */\ntypedef struct _EFI_MP_SERVICES_PROTOCOL\n{\n    PEFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors;\n    PEFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo;\n    PEFI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs;\n    PEFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP;\n    PEFI_MP_SERVICES_SWITCH_BSP SwitchBSP;\n    PEFI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP;\n    PEFI_MP_SERVICES_WHOAMI WhoAmI;\n} EFI_MP_SERVICES_PROTOCOL, *PEFI_MP_SERVICES_PROTOCOL;\n\n/* EFI processor physical location structure */\ntypedef struct _EFI_PROCESSOR_PHYSICAL_LOCATION\n{\n    UINT32 Package;\n    UINT32 Core;\n    UINT32 Thread;\n} EFI_PROCESSOR_PHYSICAL_LOCATION, *PEFI_PROCESSOR_PHYSICAL_LOCATION;\n\n/* EFI processor information structure */\ntypedef struct _EFI_PROCESSOR_INFORMATION\n{\n    UINT64 ProcessorId;\n    UINT32 StatusFlag;\n    EFI_PROCESSOR_PHYSICAL_LOCATION Location;\n} EFI_PROCESSOR_INFORMATION, *PEFI_PROCESSOR_INFORMATION;\n\n#endif /* __XTOS_ASSEMBLER__ */\n#endif /* __XTDK_XTUEFI_H */\n"
  },
  {
    "path": "xtoskrnl/CMakeLists.txt",
    "content": "# XT Kernel and library\nPROJECT(LIBXTOS)\nPROJECT(XTOSKRNL)\n\n# Specify include directories\ninclude_directories(\n    ${EXECTOS_SOURCE_DIR}/sdk/xtdk\n    ${XTOSKRNL_SOURCE_DIR}/includes)\n\n# Specify list of kernel source code files\nlist(APPEND XTOSKRNL_SOURCE\n    ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S\n    ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc\n    ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc\n    ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc\n    ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.cc\n    ${XTOSKRNL_SOURCE_DIR}/ex/exports.cc\n    ${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/firmware.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/irq.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/rtc.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/timer.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/cport.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/data.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/exports.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/fbdev.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/init.cc\n    ${XTOSKRNL_SOURCE_DIR}/hl/ioreg.cc\n    ${XTOSKRNL_SOURCE_DIR}/kd/data.cc\n    ${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc\n    ${XTOSKRNL_SOURCE_DIR}/kd/exports.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/dispatch.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/apc.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/crash.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/data.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/dispatch.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/event.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/exports.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/kprocess.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/kthread.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/shdata.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/systime.cc\n    ${XTOSKRNL_SOURCE_DIR}/ke/timer.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/mmgr.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pagemap.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/paging.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfault.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pfn.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pool.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/${ARCH}/pte.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/alloc.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/colors.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/data.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/exports.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/kpool.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/mmgr.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/paging.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/pfn.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/pool.cc\n    ${XTOSKRNL_SOURCE_DIR}/mm/pte.cc\n    ${XTOSKRNL_SOURCE_DIR}/po/idle.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/dispatch.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/exsup.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/${ARCH}/intrin.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/atomic.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/bitmap.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/data.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/endian.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/exports.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/guid.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/math.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/string.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/time.cc\n    ${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)\n\n# Set module definition SPEC file\nset_specfile(xtoskrnl.spec xtoskrnl.exe)\n\n# Link static XTOS library\nadd_library(libxtos ${XTOSKRNL_SOURCE})\ntarget_link_libraries(libxtos PRIVATE xtadk)\n\n# Link kernel executable\nadd_executable(xtoskrnl ${CMAKE_CURRENT_BINARY_DIR}/xtoskrnl.def)\n\n# Add linker libraries\ntarget_link_libraries(xtoskrnl PRIVATE libxtos)\n\n# Set proper binary name and install target\nset_target_properties(xtoskrnl PROPERTIES SUFFIX .exe)\nset_install_target(xtoskrnl \"exectos/boot\")\n\n# Set kernel entrypoint, imagebase address, ordinals and subsystem\nset_entrypoint(xtoskrnl \"KeStartXtSystem\")\nset_imagebase(xtoskrnl ${BASEADDRESS_XTOSKRNL})\nset_linker_map(xtoskrnl TRUE)\nset_ordinals(xtoskrnl TRUE)\nset_subsystem(xtoskrnl native xt_native_kernel)\n"
  },
  {
    "path": "xtoskrnl/README.md",
    "content": "## XTOSKRNL\nXTOSKRNL is the core kernel executable for ExectOS, providing the fundamental kernel and executive layers that operate\nwithin the XTOS kernel space. It is responsible for various core services, such as hardware abstraction, memory\nmanagement, and process scheduling. The kernel contains the scheduler (sometimes referred to as the Dispatcher), the\ncache, object, and memory managers, the security manager, and other executive components described below.\n\n\n## Kernel Parameters\nKernel parameters are XTOS boot-time options used to ensure proper initialization and handling of hardware peripherals.\nThese parameters can be configured either temporarily by editing the boot entry in the bootloader’s selection menu, or\npermanently by modifying the XTLDR configuration file.\n\nThe following is a consolidated list of available kernel parameters:\n * **CLOCK**: Specifies the primary hardware source used to drive the periodic system clock interrupts and the thread\n   scheduler tick. Valid values include `LAPIC` (Local APIC Timer), `HPET` (High Precision Event Timer), and `PIT`\n   (Legacy Programmable Interval Timer). If this parameter is omitted, the kernel will autonomously probe the hardware\n   and select the most optimal clock source for the current CPU topology, (defaulting to the Local APIC on modern systems.\n * **MAXCPUS**: Specifies the maximum number of logical processors the kernel is allowed to initialize and schedule.\n   Setting `MAXCPUS=1` explicitly disables Symmetric Multiprocessing (SMP), restricting execution exclusively to the Boot\n   Strap Processor (BSP) and ignoring all Application Processors (APs).\n * **NOX2APIC**: Explicitly disables x2APIC support. When specified, the kernel bypasses hardware feature detection for\n   x2APIC and forces the use of the classic, memory-mapped (MMIO) xAPIC mode. This parameter is particularly useful for\n   troubleshooting interrupt routing issues or ensuring compatibility with specific hypervisors and legacy emulators.\n * **NOXPA**: Disables PAE or LA57 support, depending on the CPU architecture. This parameter is handled by the\n   bootloader, which configures paging and selects the appropriate Page Map Level (PML) before transferring control to\n   the kernel.\n * **TIMER**: Designates the hardware counter used for high-resolution performance tracking (Query Performance Counter)\n   and microsecond execution stalls. Valid values include `TSC` (Invariant Time Stamp Counter), `HPET`, `ACPI` (or `PM`)\n   for the ACPI Power Management Timer, and `PIT`. If not specified, the kernel evaluates hardware capabilities and\n   defaults to the most precise and reliable counter available (e.g., Invariant TSC).\n\n## Source Code\nThe source code of the kernel is organized into subsystem-specific directories. Each directory name also defines the\ncorresponding C++ namespace in which the subsystem's classes and routines reside. These subsystems include:\n\n * Ar - Architecture-specific Library\n * Ex - Kernel Executive\n * Hl - Hardware Layer\n * Kd - Kernel Debugger\n * Ke - Core Kernel Library\n * Mm - Memory Manager\n * Po - Plug&Play and Power Manager\n * Rtl - Runtime library\n\n### AR: Architecture Library\nThis module contains functions specific to the processor architecture. These include routines for enabling and disabling\ninterrupts, retrieving the faulting address on a page fault, querying CPUID information, and performing very early\nprocessor initialization. This module contains only CPU architecture-specific code, with no manufacturer or\nboard-specific implementations.\n\n### EX: Kernel Executive\nThe Kernel Executive provides services for allocating system memory from paged and non-paged pools. It also supplies\nsynchronization primitives such as pushlocks and fast mutexes, routines for interlocked memory access, and support for\nworker threads.\n\n### HL: Hardware Layer\nThe Hardware Layer is an abstraction layer between the physical hardware and the rest of the operating system. It is\ndesigned to abstract away hardware differences, providing a consistent platform on which the kernel and applications\ncan run.\n\n### KD: Kernel Debugger\nThe Kernel Debugger (KD) subsystem provides debugging support for the kernel. The KD is initialized early in the boot\nprocess to facilitate debugging from the very beginning of the kernel's execution.\n\n### KE: Kernel Library\nThe Core Kernel Library implements the core functionality upon which the rest of the system depends. This includes\nfundamental low-level operations, such as routing hardware interrupts and managing dispatcher objects.\n\n### MM: Memory Manager\nThe Memory Manager is one of the core subsystems. It manages virtual memory, controls memory protection, and\nhandles paging memory between physical RAM and secondary storage. It also implements a general-purpose allocator for\nphysical memory.\n\n### PO: Plug&Play and Power Manager\nThis subsystem handles power management events, such as shutdown or standby. It also manages Plug and Play (PnP),\nsupporting device detection and installation at boot time. Furthermore, it is responsible for starting and stopping\ndevices on demand.\n\n### RTL: Runtime Library\nThe Runtime Library provides a kernel-mode implementation of common C library functions. It includes many utility\nroutines, for use by other kernel components.\n\n## Function Naming Convention\nAll kernel functions adhere to a strict naming convention to enhance code readability and maintainability. The structure\nof all public interfaces exposed by the kernel are generally composed of three parts:\n&lt;Prefix&gt;&lt;Operation&gt;&lt;Object&gt;\n\nThe prefix identifies the component to which the function belongs. For example, consider the **KeInitializeThread()**\nroutine:\n * **Ke** - The prefix indicates a routine belonging to the Core Kernel Library (Ke).\n * **Initialize** - The operation performed by the function.\n * **Thread** - The object on which the operation is performed.\n\nFor all C++ code inside the kernel the naming model has evolved. Consider the **KE::KThread::InitializeThread()**\nroutine:\n * **KE** - The namespace replaces the prefix and indicates the subsystem. Namespaces are written in uppercase and no\n   longer use the trailing p for private routines, because classes use C++ visibility to control access.\n * **KThread** - Within each namespace, related functionality is grouped into classes, which encapsulate variables and\n   methods.\n * **InitializeThread** - Method names follow the `<Operation><Object>` pattern.\n "
  },
  {
    "path": "xtoskrnl/ar/amd64/archsup.S",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/amd64/archsup.S\n * DESCRIPTION:     Provides AMD64 architecture features not implementable in C\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtkmapi.h>\n#include <xtadk.h>\n\n.altmacro\n.text\n\n\n/**\n * Creates a trap or interrupt handler for the specified vector.\n *\n * @param Vector\n *        Supplies a trap/interrupt vector number.\n *\n * @param Type\n *        Specifies whether the handler is designed to handle an interrupt or a trap.\n *\n * @return This macro does not return any value.\n *\n * @since XT 1.0\n */\n.macro ArCreateHandler Vector Type\n.global Ar\\Type\\Vector\nAr\\Type\\Vector:\n    /* Check handler type */\n    .ifc \\Type,Trap\n        /* Push fake error code for non-error vector traps */\n        .if \\Vector != 8 && \\Vector != 10 && \\Vector != 11 && \\Vector != 12 && \\Vector != 13 && \\Vector != 14 && \\Vector != 17 && \\Vector != 30\n            push $0\n        .endif\n    .else\n        /* Push fake error code for interrupts */\n        push $0\n    .endif\n\n    /* Push vector number */\n    push $\\Vector\n\n    /* Push General Purpose Registers */\n    push %rbp\n    push %rdi\n    push %rsi\n    push %r15\n    push %r14\n    push %r13\n    push %r12\n    push %r11\n    push %r10\n    push %r9\n    push %r8\n    push %rdx\n    push %rcx\n    push %rbx\n    push %rax\n\n    /* Reserve space for other registers and point RBP to the trap frame */\n    sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp\n    lea (%rsp), %rbp\n\n    /* Store segment selectors */\n    mov %gs, KTRAP_FRAME_SegGs(%rbp)\n    mov %fs, KTRAP_FRAME_SegFs(%rbp)\n    mov %es, KTRAP_FRAME_SegEs(%rbp)\n    mov %ds, KTRAP_FRAME_SegDs(%rbp)\n\n    /* Store debug registers */\n    mov %dr7, %rax\n    mov %rax, KTRAP_FRAME_Dr7(%rbp)\n    mov %dr6, %rax\n    mov %rax, KTRAP_FRAME_Dr6(%rbp)\n    mov %dr3, %rax\n    mov %rax, KTRAP_FRAME_Dr3(%rbp)\n    mov %dr2, %rax\n    mov %rax, KTRAP_FRAME_Dr2(%rbp)\n    mov %dr1, %rax\n    mov %rax, KTRAP_FRAME_Dr1(%rbp)\n    mov %dr0, %rax\n    mov %rax, KTRAP_FRAME_Dr0(%rbp)\n\n    /* Store CR2 and CR3 */\n    mov %cr3, %rax\n    mov %rax, KTRAP_FRAME_Cr3(%rbp)\n    mov %cr2, %rax\n    mov %rax, KTRAP_FRAME_Cr2(%rbp)\n\n    /* Store MxCsr register */\n    stmxcsr KTRAP_FRAME_MxCsr(%rbp)\n\n    /* Store XMM registers */\n    movdqa %xmm15, KTRAP_FRAME_Xmm15(%rbp)\n    movdqa %xmm14, KTRAP_FRAME_Xmm14(%rbp)\n    movdqa %xmm13, KTRAP_FRAME_Xmm13(%rbp)\n    movdqa %xmm12, KTRAP_FRAME_Xmm12(%rbp)\n    movdqa %xmm11, KTRAP_FRAME_Xmm11(%rbp)\n    movdqa %xmm10, KTRAP_FRAME_Xmm10(%rbp)\n    movdqa %xmm9, KTRAP_FRAME_Xmm9(%rbp)\n    movdqa %xmm8, KTRAP_FRAME_Xmm8(%rbp)\n    movdqa %xmm7, KTRAP_FRAME_Xmm7(%rbp)\n    movdqa %xmm6, KTRAP_FRAME_Xmm6(%rbp)\n    movdqa %xmm5, KTRAP_FRAME_Xmm5(%rbp)\n    movdqa %xmm4, KTRAP_FRAME_Xmm4(%rbp)\n    movdqa %xmm3, KTRAP_FRAME_Xmm3(%rbp)\n    movdqa %xmm2, KTRAP_FRAME_Xmm2(%rbp)\n    movdqa %xmm1, KTRAP_FRAME_Xmm1(%rbp)\n    movdqa %xmm0, KTRAP_FRAME_Xmm0(%rbp)\n\n    /* Test previous mode and swap GS if needed */\n    movl $0, KTRAP_FRAME_PreviousMode(%rbp)\n    mov KTRAP_FRAME_SegCs(%rbp), %ax\n    and $3, %al\n    mov %al, KTRAP_FRAME_PreviousMode(%rbp)\n\n    /* Skip swapgs as the interrupt originated from kernel mode */\n    jz Dispatch\\Type\\Vector\n\n    swapgs\n\nDispatch\\Type\\Vector:\n    /* Set up trap frame pointer for the dispatcher and clear the direction flag */\n    mov %rsp, %rcx\n    cld\n\n    /* Preserve the original stack pointer */\n    mov %rsp, %rbx\n\n    /* Force stack alignment */\n    and $-16, %rsp\n\n    /* Allocate 32 bytes of shadow space */\n    sub $32, %rsp\n\n    .ifc \\Type,Trap\n        /* Pass to the trap dispatcher */\n        call ArDispatchTrap\n    .else\n        /* Pass to the interrupt dispatcher */\n        call ArDispatchInterrupt\n    .endif\n\n    /* Restore the original trap frame stack pointer */\n    mov %rbx, %rsp\n\n    /* Test previous mode and swapgs if needed */\n    testb $1, KTRAP_FRAME_PreviousMode(%rbp)\n    jz RestoreState\\Type\\Vector\n    cli\n    swapgs\n\nRestoreState\\Type\\Vector:\n    /* Restore XMM registers */\n    movdqa KTRAP_FRAME_Xmm0(%rbp), %xmm0\n    movdqa KTRAP_FRAME_Xmm1(%rbp), %xmm1\n    movdqa KTRAP_FRAME_Xmm2(%rbp), %xmm2\n    movdqa KTRAP_FRAME_Xmm3(%rbp), %xmm3\n    movdqa KTRAP_FRAME_Xmm4(%rbp), %xmm4\n    movdqa KTRAP_FRAME_Xmm5(%rbp), %xmm5\n    movdqa KTRAP_FRAME_Xmm6(%rbp), %xmm6\n    movdqa KTRAP_FRAME_Xmm7(%rbp), %xmm7\n    movdqa KTRAP_FRAME_Xmm8(%rbp), %xmm8\n    movdqa KTRAP_FRAME_Xmm9(%rbp), %xmm9\n    movdqa KTRAP_FRAME_Xmm10(%rbp), %xmm10\n    movdqa KTRAP_FRAME_Xmm11(%rbp), %xmm11\n    movdqa KTRAP_FRAME_Xmm12(%rbp), %xmm12\n    movdqa KTRAP_FRAME_Xmm13(%rbp), %xmm13\n    movdqa KTRAP_FRAME_Xmm14(%rbp), %xmm14\n    movdqa KTRAP_FRAME_Xmm15(%rbp), %xmm15\n\n    /* Load MxCsr register */\n    ldmxcsr KTRAP_FRAME_MxCsr(%rbp)\n\n    /* Free stack space */\n    add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %rsp\n\n    /* Pop General Purpose Registers */\n    pop %rax\n    pop %rbx\n    pop %rcx\n    pop %rdx\n    pop %r8\n    pop %r9\n    pop %r10\n    pop %r11\n    pop %r12\n    pop %r13\n    pop %r14\n    pop %r15\n    pop %rsi\n    pop %rdi\n    pop %rbp\n\n    /* Skip error code and vector number, then return */\n    add $(2 * 8), %rsp\n    iretq\n.endm\n\n/* Populate common interrupt and trap handlers */\n.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n    .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n        ArCreateHandler 0x\\i\\j Interrupt\n        ArCreateHandler 0x\\i\\j Trap\n    .endr\n.endr\n\n/* Define array of pointers to the interrupt handlers */\n.global ArInterruptEntry\nArInterruptEntry:\n.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n    .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n        .quad ArInterrupt0x\\i\\j\n    .endr\n.endr\n\n/* Define array of pointers to the trap handlers */\n.global ArTrapEntry\nArTrapEntry:\n.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n    .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n        .quad ArTrap0x\\i\\j\n    .endr\n.endr\n\n/**\n * Enables eXtended Physical Addressing (XPA).\n *\n * @param PageMap\n *        Supplies a pointer to the page map to be used.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\n.global ArEnableExtendedPhysicalAddressing\nArEnableExtendedPhysicalAddressing:\n    /* Save the original CR4 register */\n    movq %cr4, %rax\n\n    /* Save the state of stack pointer and non-volatile registers */\n    movq %rsp, XpaRegisterSaveArea(%rip)\n    movq %rbp, XpaRegisterSaveArea+0x08(%rip)\n    movq %rax, XpaRegisterSaveArea+0x10(%rip)\n    movq %rbx, XpaRegisterSaveArea+0x18(%rip)\n\n    /* Save the original CR0 register */\n    movq %cr0, %rbp\n\n    /* Load temporary GDT required for mode transitions */\n    leaq XpaTemporaryGdtDesc(%rip), %rax\n    movq %rax, XpaTemporaryGdtBase(%rip)\n    lgdtq XpaTemporaryGdtSize(%rip)\n\n    /* Load addresses for entering compatibility mode and re-entering long mode */\n    leaq XpaEnterCompatMode(%rip), %rax\n    leaq XpaEnterLongMode(%rip), %rbx\n\n    /* Push the 32-bit code segment selector and the target address for a far jump */\n    pushq $KGDT_R0_CMCODE\n    pushq %rax\n\n    /* Perform a far return to switch to 32-bit compatibility mode */\n    lretq\n\nXpaEnterCompatMode:\n    /* Enter 32-bit compatibility mode */\n    .code32\n\n    /* Store the PageMap pointer on the stack for future use */\n    pushl %ecx\n\n    /* Set the stack segment to the 32-bit data segment selector */\n    movl $KGDT_R0_DATA, %eax\n    movl %eax, %ss\n\n    /* Disable PGE and PCIDE to ensure all TLB entries will be flushed */\n    movl %cr4, %eax\n    andl $~(CR4_PGE | CR4_PCIDE), %eax\n    movl %eax, %cr4\n\n    /* Temporarily disable paging */\n    movl %ebp, %eax\n    andl $~CR0_PG, %eax\n    movl %eax, %cr0\n\n    /* Disable Long Mode as prerequisite for enabling 5-level paging */\n    movl $X86_MSR_EFER, %ecx\n    rdmsr\n    andl $~X86_MSR_EFER_LME, %eax\n    wrmsr\n\n    /* Transition to 5-level paging (PML5/LA57) */\n    movl %cr4, %eax\n    orl $CR4_LA57, %eax\n    movl %eax, %cr4\n\n    /* Restore the PageMap pointer from the stack and load it into CR3 */\n    popl %ecx\n    movl %ecx, %cr3\n\n    /* Re-enable Long Mode */\n    movl $X86_MSR_EFER, %ecx\n    rdmsr\n    orl $X86_MSR_EFER_LME, %eax\n    wrmsr\n\n    /* Restore CR0 with paging enabled and flush the instruction pipeline */\n    movl %ebp, %cr0\n    call XpaFlushInstructions\n\nXpaFlushInstructions:\n    /* Push the 64-bit code segment selector and the target address for a far jump */\n    pushl $KGDT_R0_CODE\n    pushl %ebx\n\n    /* Perform a far return to switch to 64-bit long mode */\n    lretl\n\nXpaEnterLongMode:\n    /* Enter 64-bit long mode */\n    .code64\n\n    /* Restore the stack pointer and non-volatile registers */\n    movq XpaRegisterSaveArea(%rip), %rsp\n    movq XpaRegisterSaveArea+8(%rip), %rbp\n    movq XpaRegisterSaveArea+0x10(%rip), %rax\n    movq XpaRegisterSaveArea+0x18(%rip), %rbx\n\n    /* Restore the original CR4 register with LA57 bit set */\n    orq $CR4_LA57, %rax\n    movq %rax, %cr4\n\n    /* Return to the caller */\n    retq\n\n/* Data section for saving registers and temporary GDT */\nXpaRegisterSaveArea: .quad 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000\nXpaTemporaryGdtSize: .short ArEnableExtendedPhysicalAddressingEnd - XpaTemporaryGdtDesc - 1\nXpaTemporaryGdtBase: .quad 0x0000000000000000\nXpaTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF\n\n.global ArEnableExtendedPhysicalAddressingEnd\nArEnableExtendedPhysicalAddressingEnd:\n\n/**\n * Handles a spurious interrupt allowing it to end up.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\n.global ArHandleSpuriousInterrupt\nArHandleSpuriousInterrupt:\n    iretq\n\n/**\n * Starts an application processor (AP).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\n.global ArStartApplicationProcessor\nArStartApplicationProcessor:\n    /* Enter 16-bit real mode */\n    .code16\n\n    /* Disable interrupts and clear direction flag */\n    cli\n    cld\n\n    /* Establish a flat addressing baseline */\n    movw %cs, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n\n    /* Calculate absolute physical base address */\n    xorl %ebx, %ebx\n    movw %cs, %bx\n    shll $4, %ebx\n\n    /* Set up a temporary stack for the AP initialization */\n    movl %ebx, %esp\n    addl $0x1000, %esp\n\n    /* Load the temporary Global Descriptor Table */\n    leal (ApTemporaryGdtDesc - ArStartApplicationProcessor)(%ebx), %eax\n    movl %eax, (ApTemporaryGdtBase - ArStartApplicationProcessor)\n    lgdtl (ApTemporaryGdtSize - ArStartApplicationProcessor)\n\n    /* Enable Protected Mode */\n    movl %cr0, %eax\n    orl $0x01, %eax\n    movl %eax, %cr0\n\n    /* Far return to enter 32-bit protected mode */\n    leal (ApEnterProtectedMode - ArStartApplicationProcessor)(%ebx), %eax\n    pushl $KGDT_R0_CMCODE\n    pushl %eax\n    lretl\n\nApEnterProtectedMode:\n    /* Enter 32-bit protected mode */\n    .code32\n\n    /* Setup all data segment registers */\n    movw $KGDT_R0_DATA, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n    xorw %ax, %ax\n    movw %ax, %fs\n    movw %ax, %gs\n\n    /* Locate PROCESSOR_START_BLOCK structure */\n    leal (ArStartApplicationProcessorEnd - ArStartApplicationProcessor)(%ebx), %edi\n\n    /* Load CR4 from BSP, but mask PCIDE and PGE */\n    movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax\n    andl $~(CR4_PGE | CR4_PCIDE), %eax\n    movl %eax, %cr4\n\n    /* Load the Kernel Page Directory Base from BSP */\n    movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax\n    movl %eax, %cr3\n\n    /* Enable Long Mode and No-Execute */\n    movl $X86_MSR_EFER, %ecx\n    rdmsr\n    orl $(X86_MSR_EFER_LME | X86_MSR_EFER_NXE), %eax\n    wrmsr\n\n    /* Enable Paging */\n    movl %cr0, %eax\n    orl $CR0_PG, %eax\n    movl %eax, %cr0\n\n    /* Far return to enter 64-bit long mode */\n    leal (ApEnterLongMode - ArStartApplicationProcessor)(%ebx), %eax\n    pushl $KGDT_R0_CODE\n    pushl %eax\n    lretl\n\nApEnterLongMode:\n    /* Enter 64-bit long mode */\n    .code64\n\n    /* Clear all segment registers */\n    xorw %ax, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n    movw %ax, %fs\n    movw %ax, %gs\n\n    /* Zero-extend EDI into RDI to ensure safe 64-bit pointer usage */\n    movl %edi, %edi\n\n    /* Load dedicated Stack for AP */\n    movq PROCESSOR_START_BLOCK_Stack(%rdi), %rsp\n\n    /* Save the pointer to PROCESSOR_START_BLOCK */\n    movq %rdi, %rcx\n    pushq %rdi\n\n    /* Call the EntryPoint routine */\n    movq PROCESSOR_START_BLOCK_EntryPoint(%rdi), %rax\n    call *%rax\n\n    /* Fire the breakpoint and halt if the entry point returns */\n.ApNoReturnPoint:\n    int $0x03\n    hlt\n    jmp .ApNoReturnPoint\n\n/* Data section for temporary GDT */\n.align 8\nApTemporaryGdtSize: .short ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1\nApTemporaryGdtBase: .quad 0x0000000000000000\nApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00AF9A000000FFFF, 0x00CF92000000FFFF\n\n.global ArStartApplicationProcessorEnd\nArStartApplicationProcessorEnd:\n"
  },
  {
    "path": "xtoskrnl/ar/amd64/cpufunc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/amd64/cpufunc.cc\n * DESCRIPTION:     Routines to provide access to special AMD64 CPU instructions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Instructs the processor to clear the interrupt flag.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::ClearInterruptFlag(VOID)\n{\n    __asm__ volatile(\"cli\");\n}\n\n/**\n * Retrieves a various amount of information about the CPU.\n *\n * @param Registers\n *        Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID.\n *\n * @return This routine returns TRUE if CPUID function could be executed, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nAR::CpuFunctions::CpuId(IN OUT PCPUID_REGISTERS Registers)\n{\n    UINT32 MaxLeaf;\n\n    /* Get highest function ID available */\n    __asm__ volatile(\"cpuid\"\n                     : \"=a\" (MaxLeaf)\n                     : \"a\" (Registers->Leaf & 0x80000000)\n                     : \"rbx\",\n                       \"rcx\",\n                       \"rdx\");\n\n    /* Check if CPU supports this command */\n    if(Registers->Leaf > MaxLeaf)\n    {\n        /* Cannot call it, return FALSE */\n        return FALSE;\n    }\n\n    /* Execute CPUID function */\n    __asm__ volatile(\"cpuid\"\n                     : \"=a\" (Registers->Eax),\n                       \"=b\" (Registers->Ebx),\n                       \"=c\" (Registers->Ecx),\n                       \"=d\" (Registers->Edx)\n                     : \"a\" (Registers->Leaf),\n                       \"c\" (Registers->SubLeaf));\n\n    /* Return TRUE */\n    return TRUE;\n}\n\n/**\n * Partially flushes the Translation Lookaside Buffer (TLB)\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::FlushTlb(VOID)\n{\n    /* Flush the TLB by resetting the CR3 */\n    WriteControlRegister(3, ReadControlRegister(3));\n}\n\n/**\n * Gets the RFLAGS register.\n *\n * @return This routine returns the RFLAGS register.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG\nAR::CpuFunctions::GetCpuFlags(VOID)\n{\n    ULONG_PTR Flags;\n\n    /* Get RFLAGS register */\n    __asm__ volatile(\"pushf\\n\"\n                     \"pop %0\\n\"\n                     : \"=rm\" (Flags)\n                     :\n                     : \"memory\");\n\n    /* Return flags */\n    return Flags;\n}\n\n/**\n * Gets the address of the current stack register.\n *\n * @return This routine returns the current stack pointer.\n *\n * @since XT 1.0\n */\nXTASSEMBLY\nXTCDECL\nULONG_PTR\nAR::CpuFunctions::GetStackPointer(VOID)\n{\n    /* Get current stack pointer */\n    __asm__ volatile(\"movq %%rsp, %%rax\\n\"\n                     \"retq\\n\"\n                     :\n                     :\n                     :);\n}\n\n/**\n * Halts the central processing unit (CPU).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::Halt(VOID)\n{\n    __asm__ volatile(\"hlt\");\n}\n\n/**\n * Checks whether interrupts are enabled or not.\n *\n * @return This routine returns TRUE if interrupts are enabled, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nAR::CpuFunctions::InterruptsEnabled(VOID)\n{\n    ULONG_PTR Flags;\n\n    /* Get RFLAGS register */\n    Flags = GetCpuFlags();\n\n    /* Check if interrupts are enabled and return result */\n    return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE;\n}\n\n/**\n * Invalidates the TLB (Translation Lookaside Buffer) for specified virtual address.\n *\n * @param Address\n *        Suuplies a virtual address whose associated TLB entry will be invalidated.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::InvalidateTlbEntry(IN PVOID Address)\n{\n    __asm__ volatile(\"invlpg (%0)\"\n                     :\n                     : \"b\" (Address)\n                     : \"memory\");\n}\n\n/**\n * Loads the value in the source operand into the global descriptor table register (GDTR).\n *\n * @param Source\n *        Specifies a memory location that contains the base address of GDT.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadGlobalDescriptorTable(IN PVOID Source)\n{\n    __asm__ volatile(\"lgdt %0\"\n                     :\n                     : \"m\" (*(PSHORT)Source)\n                     : \"memory\");\n}\n\n/**\n * Loads the value in the source operand into the interrupt descriptor table register (IDTR).\n *\n * @param Source\n *        Specifies a memory location that contains the base address of IDT.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadInterruptDescriptorTable(IN PVOID Source)\n{\n    __asm__ volatile(\"lidt %0\"\n                     :\n                     : \"m\" (*(PSHORT)Source)\n                     : \"memory\");\n}\n\n/**\n * Loads the value in the source operand into the local descriptor table register (LDTR).\n *\n * @param Source\n *        Specifies a selector value.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadLocalDescriptorTable(IN USHORT Source)\n{\n    __asm__ volatile(\"lldtw %0\"\n                     :\n                     : \"g\" (Source));\n}\n\n/**\n * Loads the value in the source operand into the MXCSR register\n *\n * @param Source\n *        Supplies a source value to be loaded into the MXCSR register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadMxcsrRegister(IN ULONG Source)\n{\n    __asm__ volatile(\"ldmxcsr %0\"\n                     :\n                     : \"m\" (Source));\n}\n\n/**\n * Loads source data into specified segment.\n *\n * @param Segment\n *        Supplies a segment identification.\n *\n * @param Source\n *        Supplies a pointer to the memory area containing data that will be loaded into specified segment.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadSegment(IN USHORT Segment,\n                     IN ULONG Source)\n{\n    switch(Segment)\n    {\n        case SEGMENT_CS:\n            /* Load CS Segment */\n            __asm__ volatile(\"mov %0, %%rax\\n\"\n                             \"push %%rax\\n\"\n                             \"lea label(%%rip), %%rax\\n\"\n                             \"push %%rax\\n\"\n                             \"lretq\\n\"\n                             \"label:\"\n                             :\n                             : \"ri\" ((ULONGLONG)Source)\n                             : \"rax\");\n            break;\n        case SEGMENT_DS:\n            /* Load DS Segment */\n            __asm__ volatile(\"movl %0, %%ds\"\n                             :\n                             : \"r\" (Source));\n            break;\n        case SEGMENT_ES:\n            /* Load ES Segment */\n            __asm__ volatile(\"movl %0, %%es\"\n                             :\n                             : \"r\" (Source));\n            break;\n        case SEGMENT_FS:\n            /* Load FS Segment */\n            __asm__ volatile(\"movl %0, %%fs\"\n                             :\n                             : \"r\" (Source));\n            break;\n        case SEGMENT_GS:\n            /* Load GS Segment */\n            __asm__ volatile(\"movl %0, %%gs\"\n                             :\n                             : \"r\" (Source));\n            break;\n            /* Load SS Segment */\n        case SEGMENT_SS:\n            __asm__ volatile(\"movl %0, %%ss\"\n                             :\n                             : \"r\" (Source));\n            break;\n    }\n}\n\n/**\n * Loads Task Register (TR) with a segment selector that points to TSS.\n *\n * @param Source\n *        Supplies the segment selector in the GDT describing the TSS.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadTaskRegister(USHORT Source)\n{\n    __asm__ volatile(\"ltr %0\"\n                     :\n                     : \"rm\" (Source));\n}\n\n/**\n * Orders memory accesses as seen by other processors.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::MemoryBarrier(VOID)\n{\n    LONG Barrier;\n    __asm__ volatile(\"lock; orl $0, %0;\"\n                     :\n                     : \"m\"(Barrier));\n}\n\n/**\n * Reads the specified CPU control register and returns its value.\n *\n * @param ControlRegister\n *        Supplies a number of a control register which controls the general behavior of a CPU.\n *\n * @return This routine returns the value stored in the control register.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG_PTR\nAR::CpuFunctions::ReadControlRegister(IN USHORT ControlRegister)\n{\n    ULONG_PTR Value;\n\n    /* Read a value from specified CR register */\n    switch(ControlRegister)\n    {\n        case 0:\n            /* Read value from CR0 */\n            __asm__ volatile(\"mov %%cr0, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        case 2:\n            /* Read value from CR2 */\n            __asm__ volatile(\"mov %%cr2, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        case 3:\n            /* Read value from CR3 */\n            __asm__ volatile(\"mov %%cr3, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        case 4:\n            /* Read value from CR4 */\n            __asm__ volatile(\"mov %%cr4, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        case 8:\n            /* Read value from CR8 */\n            __asm__ volatile(\"mov %%cr8, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        default:\n            /* Invalid control register set */\n            Value = 0;\n            break;\n    }\n\n    /* Return value read from given CR register */\n    return Value;\n}\n\n/**\n * Reads the specified CPU debug register and returns its value.\n *\n * @param DebugRegister\n *        Supplies a number of a debug register to read from.\n *\n * @return This routine returns the value stored in the specified debug register.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG_PTR\nAR::CpuFunctions::ReadDebugRegister(IN USHORT DebugRegister)\n{\n    ULONG_PTR Value;\n\n    /* Read a value from specified DR register */\n    switch(DebugRegister)\n    {\n        case 0:\n            /* Read value from DR0 */\n            __asm__ volatile(\"mov %%dr0, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 1:\n            /* Read value from DR1 */\n            __asm__ volatile(\"mov %%dr1, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 2:\n            /* Read value from DR2 */\n            __asm__ volatile(\"mov %%dr2, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 3:\n            /* Read value from DR3 */\n            __asm__ volatile(\"mov %%dr3, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 4:\n            /* Read value from DR4 */\n            __asm__ volatile(\"mov %%dr4, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 5:\n            /* Read value from DR5 */\n            __asm__ volatile(\"mov %%dr5, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 6:\n            /* Read value from DR6 */\n            __asm__ volatile(\"mov %%dr6, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 7:\n            /* Read value from DR7 */\n            __asm__ volatile(\"mov %%dr7, %0\"\n                             : \"=r\" (Value));\n            break;\n        default:\n            /* Invalid debug register set */\n            Value = 0;\n            break;\n    }\n\n    /* Return value read from given DR register */\n    return Value;\n}\n\n/**\n * Reads quadword from a memory location specified by an offset relative to the beginning of the GS segment.\n *\n * @param Offset\n *        Specifies the offset from the beginning of GS segment.\n *\n * @return This routine returns the value read from the specified memory location relative to GS segment.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONGLONG\nAR::CpuFunctions::ReadGSQuadWord(ULONG Offset)\n{\n    ULONGLONG Value;\n\n    /* Read quadword from GS segment */\n    __asm__ volatile(\"movq %%gs:%a[Offset], %q[Value]\"\n                     : [Value] \"=r\" (Value)\n                     : [Offset] \"ir\" (Offset));\n    return Value;\n}\n\n/**\n * Reads a 64-bit value from the requested Model Specific Register (MSR).\n *\n * @param Register\n *        Supplies the MSR to read.\n *\n * @return This routine returns the 64-bit MSR value.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONGLONG\nAR::CpuFunctions::ReadModelSpecificRegister(IN ULONG Register)\n{\n    ULONG Low, High;\n\n    __asm__ volatile(\"rdmsr\"\n                     : \"=a\" (Low),\n                       \"=d\" (High)\n                     : \"c\" (Register));\n\n    return ((ULONGLONG)High << 32) | Low;\n}\n\n/**\n * Reads the contents of the MXCSR control/status register.\n *\n * @return This routine returns the contents of the MXCSR register as a 32-bit unsigned integer value.\n *\n * @since XT 1.0\n */\nXTCDECL\nUINT\nAR::CpuFunctions::ReadMxCsrRegister(VOID)\n{\n    return __builtin_ia32_stmxcsr();\n}\n\n/**\n * Reads the current value of the CPU's time-stamp counter.\n *\n * @return This routine returns the current instruction cycle count since the processor was started.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONGLONG\nAR::CpuFunctions::ReadTimeStampCounter(VOID)\n{\n    ULONGLONG Low, High;\n\n    __asm__ volatile(\"rdtsc\"\n                     : \"=a\" (Low),\n                       \"=d\" (High));\n\n    return ((ULONGLONG)High << 32) | Low;\n}\n\n/**\n * Reads the current value of the CPU's time-stamp counter and processor ID.\n *\n * @param TscAux\n *        Supplies a pointer to a variable that receives the auxiliary TSC information (IA32_TSC_AUX).\n *\n * @return This routine returns the current instruction cycle count since the processor was last reset.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONGLONG\nAR::CpuFunctions::ReadTimeStampCounterProcessor(OUT PULONG TscAux)\n{\n    ULONG Low, High;\n\n    /* Execute the RDTSCP instruction */\n    __asm__ volatile(\"rdtscp\"\n                     : \"=a\" (Low),\n                       \"=d\" (High),\n                       \"=c\" (*TscAux)\n    );\n\n    /* Combine the two 32-bit registers into a single 64-bit unsigned integer and return the value */\n    return ((ULONGLONG)High << 32) | Low;\n}\n\n/**\n * Orders memory accesses as seen by other processors, without fence.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::ReadWriteBarrier(VOID)\n{\n    __asm__ volatile(\"\"\n                     :\n                     :\n                     : \"memory\");\n}\n\n/**\n * Instructs the processor to set the interrupt flag.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::SetInterruptFlag(VOID)\n{\n    __asm__ volatile(\"sti\");\n}\n\n/**\n * Stores GDT register into the given memory area.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where GDT will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreGlobalDescriptorTable(OUT PVOID Destination)\n{\n    __asm__ volatile(\"sgdt %0\"\n                     : \"=m\" (*(PSHORT)Destination)\n                     :\n                     : \"memory\");\n}\n\n/**\n * Stores IDT register into the given memory area.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where IDT will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreInterruptDescriptorTable(OUT PVOID Destination)\n{\n    __asm__ volatile(\"sidt %0\"\n                     : \"=m\" (*(PSHORT)Destination)\n                     :\n                     : \"memory\");\n}\n\n/**\n * Stores LDT register into the given memory area.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where LDT will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreLocalDescriptorTable(OUT PVOID Destination)\n{\n    __asm__ volatile(\"sldt %0\"\n                     : \"=m\" (*(PSHORT)Destination)\n                     :\n                     : \"memory\");\n}\n\n/**\n * Stores specified segment into the given memory area.\n *\n * @param Segment\n *        Supplies a segment identification.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where segment data will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreSegment(IN USHORT Segment,\n                               OUT PVOID Destination)\n{\n    switch(Segment)\n    {\n        case SEGMENT_CS:\n            __asm__ volatile(\"movl %%cs, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_DS:\n            __asm__ volatile(\"movl %%ds, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_ES:\n            __asm__ volatile(\"movl %%es, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_FS:\n            __asm__ volatile(\"movl %%fs, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_GS:\n            __asm__ volatile(\"movl %%gs, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_SS:\n            __asm__ volatile(\"movl %%ss, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        default:\n            Destination = NULLPTR;\n            break;\n    }\n}\n\n/**\n * Stores TR into the given memory area.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where TR will be stores.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreTaskRegister(OUT PVOID Destination)\n{\n    __asm__ volatile(\"str %0\"\n                     : \"=m\" (*(PULONG)Destination)\n                     :\n                     : \"memory\");\n}\n\n/**\n * Writes a value to the specified CPU control register.\n *\n * @param ControlRegister\n *        Supplies a number of a control register which controls the general behavior of a CPU.\n *\n * @param Value\n *        Suplies a value to write to the CR register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::WriteControlRegister(IN USHORT ControlRegister,\n                                       IN UINT_PTR Value)\n{\n    /* Write a value into specified control register */\n    switch(ControlRegister)\n    {\n        case 0:\n            /* Write value to CR0 */\n            __asm__ volatile(\"mov %0, %%cr0\"\n                             :\n                             : \"r\"(Value)\n                             : \"memory\");\n            break;\n        case 2:\n            /* Write value to CR2 */\n            __asm__ volatile(\"mov %0, %%cr2\"\n                             :\n                             : \"r\"(Value)\n                             : \"memory\");\n            break;\n        case 3:\n            /* Write value to CR3 */\n            __asm__ volatile(\"mov %0, %%cr3\"\n                             :\n                             : \"r\"(Value)\n                             : \"memory\");\n            break;\n        case 4:\n            /* Write value to CR4 */\n            __asm__ volatile(\"mov %0, %%cr4\"\n                             :\n                             : \"r\"(Value)\n                             : \"memory\");\n            break;\n        case 8:\n            /* Write value to CR8 */\n            __asm__ volatile(\"mov %0, %%cr8\"\n                             :\n                             : \"r\"(Value)\n                             : \"memory\");\n            break;\n    }\n}\n\n/**\n * Writes a value to the specified CPU debug register.\n *\n * @param DebugRegister\n *        Supplies a number of a debug register for write operation.\n *\n * @param Value\n *        Suplies a value to write to the specified DR register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::WriteDebugRegister(IN USHORT DebugRegister,\n                                     IN UINT_PTR Value)\n{\n    /* Write a value into specified debug register */\n    switch(DebugRegister)\n    {\n        case 0:\n            /* Write value to DR0 */\n            __asm__ volatile(\"mov %0, %%dr0\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 1:\n            /* Write value to DR1 */\n            __asm__ volatile(\"mov %0, %%dr1\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 2:\n            /* Write value to DR2 */\n            __asm__ volatile(\"mov %0, %%dr2\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 3:\n            /* Write value to DR3 */\n            __asm__ volatile(\"mov %0, %%dr3\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 4:\n            /* Write value to DR4 */\n            __asm__ volatile(\"mov %0, %%dr4\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 5:\n            /* Write value to DR5 */\n            __asm__ volatile(\"mov %0, %%dr5\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 6:\n            /* Write value to DR6 */\n            __asm__ volatile(\"mov %0, %%dr6\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 7:\n            /* Write value to DR7 */\n            __asm__ volatile(\"mov %0, %%dr7\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n    }\n}\n\n/**\n * Writes the specified value to the program status and control (EFLAGS) register.\n *\n * @param Value\n *        The value to write to the EFLAGS register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::WriteEflagsRegister(IN UINT_PTR Value)\n{\n    __asm__ volatile(\"push %0\\n\"\n                     \"popf\"\n                     :\n                     : \"rim\" (Value));\n}\n\n/**\n * Writes a 64-bit value to the requested Model Specific Register (MSR).\n *\n * @param Register\n *        Supplies the MSR register to write.\n *\n * @param Value\n *        Supplies the 64-bit value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::WriteModelSpecificRegister(IN ULONG Register,\n                                             IN ULONGLONG Value)\n{\n    ULONG Low = Value & 0xFFFFFFFF;\n    ULONG High = Value >> 32;\n\n    __asm__ volatile(\"wrmsr\"\n                     :\n                     : \"c\" (Register),\n                       \"a\" (Low),\n                       \"d\" (High));\n}\n\n/**\n * Yields a current thread running on the processor.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::YieldProcessor(VOID)\n{\n    __asm__ volatile(\"pause\"\n                     :\n                     :\n                     : \"memory\");\n}\n"
  },
  {
    "path": "xtoskrnl/ar/amd64/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/amd64/data.cc\n * DESCRIPTION:     AMD64 architecture-specific global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* Initial kernel boot stack */\nUCHAR AR::ProcessorSupport::BootStack[KERNEL_STACK_SIZE] = {};\n\n/* Initial kernel fault stack */\nUCHAR AR::ProcessorSupport::FaultStack[KERNEL_STACK_SIZE] = {};\n\n/* Initial GDT */\nKGDTENTRY AR::ProcessorSupport::InitialGdt[GDT_ENTRIES] = {};\n\n/* Initial IDT */\nKIDTENTRY AR::ProcessorSupport::InitialIdt[IDT_ENTRIES] = {};\n\n/* Initial Processor Block */\nKPROCESSOR_BLOCK AR::ProcessorSupport::InitialProcessorBlock;\n\n/* Initial TSS */\nKTSS AR::ProcessorSupport::InitialTss;\n\n/* Initial kernel NMI stack */\nUCHAR AR::ProcessorSupport::NmiStack[KERNEL_STACK_SIZE] = {};\n\n/* Unhandled interrupt routine */\nPINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;\n"
  },
  {
    "path": "xtoskrnl/ar/amd64/procsup.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/amd64/procsup.cc\n * DESCRIPTION:     AMD64 processor functionality support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Gets the base address of the kernel boot stack.\n *\n * @return This routine returns a pointer to the kernel boot stack.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nAR::ProcessorSupport::GetBootStack(VOID)\n{\n    /* Return base address of kernel boot stack */\n    return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);\n}\n\nXTAPI\nVOID\nAR::ProcessorSupport::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,\n                                               OUT PVOID *TrampolineCode,\n                                               OUT PULONG_PTR TrampolineSize)\n{\n    /* Get trampoline information */\n    switch(TrampolineType)\n    {\n        case TrampolineApStartup:\n            /* Get AP startup trampoline information */\n            *TrampolineCode = (PVOID)ArStartApplicationProcessor;\n            *TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -\n                              (ULONG_PTR)ArStartApplicationProcessor;\n            break;\n        case TrampolineEnableXpa:\n            /* Get Enable XPA trampoline information */\n            *TrampolineCode = (PVOID)ArEnableExtendedPhysicalAddressing;\n            *TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd -\n                              (ULONG_PTR)ArEnableExtendedPhysicalAddressing;\n            break;\n        default:\n            /* Unknown trampoline type */\n            *TrampolineCode = NULLPTR;\n            *TrampolineSize = 0;\n            break;\n    }\n}\n\n/**\n * Identifies processor type (vendor, model, stepping) as well as looks for available CPU features and stores them\n * in Processor Control Block (PRCB).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::IdentifyProcessor(VOID)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    CPUID_REGISTERS CpuRegisters;\n    CPUID_SIGNATURE CpuSignature;\n\n    /* Get current processor control block */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n    /* Get CPU vendor by issueing CPUID instruction */\n    RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n\n    /* Store CPU vendor in processor control block */\n    Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;\n    *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;\n    *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;\n    *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;\n    Prcb->CpuId.VendorName[12] = '\\0';\n\n    /* Get CPU standard features */\n    RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n\n    /* Store CPU signature in processor control block */\n    CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;\n    Prcb->CpuId.Family = CpuSignature.Family;\n    Prcb->CpuId.Model = CpuSignature.Model;\n    Prcb->CpuId.Stepping = CpuSignature.Stepping;\n\n    /* CPU vendor specific quirks */\n    if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)\n    {\n        /* AMD CPU */\n        if(CpuSignature.Family == 0xF)\n        {\n            Prcb->CpuId.Family += CpuSignature.ExtendedFamily;\n            Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);\n        }\n    }\n    else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)\n    {\n        /* Intel CPU */\n        if(CpuSignature.Family == 0xF)\n        {\n            Prcb->CpuId.Family += CpuSignature.ExtendedFamily;\n        }\n\n        if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF))\n        {\n            Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);\n        }\n    }\n    else\n    {\n        /* Unknown CPU vendor */\n        Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;\n    }\n\n    /* Identify processor features */\n    IdentifyProcessorFeatures();\n}\n\n/**\n * Identifies processor features and stores them in Processor Control Block (PRCB).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::IdentifyProcessorFeatures(VOID)\n{\n    ULONG MaxExtendedLeaf, MaxStandardLeaf;\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    CPUID_REGISTERS CpuRegisters;\n\n    /* Get current processor control block */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n    /* Get maximum CPUID standard leaf */\n    RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n    MaxStandardLeaf = CpuRegisters.Eax;\n\n    /* Get maximum CPUID extended leaf */\n    RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n    MaxExtendedLeaf = CpuRegisters.Eax;\n\n    /* Check if CPU supports standard features leaf */\n    if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)\n    {\n        /* Get CPU standard features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU standard features in processor control block */\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;\n    }\n\n    /* Check if CPU supports standard7 features leaf */\n    if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES)\n    {\n        /* Get CPU standard features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU standard7 features in processor control block */\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;\n    }\n\n    /* Check if CPU supports power management leaf */\n    if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)\n    {\n        /* Get CPU power management features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU power management features in processor control block */\n        if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;\n    }\n\n    /* Check if CPU supports extended features leaf */\n    if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)\n    {\n        /* Get CPU extended features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU extended features in processor control block */\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;\n    }\n\n    /* Check if CPU supports advanced power management leaf */\n    if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)\n    {\n        /* Get CPU advanced power management features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU advanced power management features in processor control block */\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;\n    }\n}\n\n/**\n * Initializes the kernel's Global Descriptor Table (GDT).\n *\n * @param Gdt\n *        Supplies a pointer to the GDT to use.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)\n{\n    /* Initialize GDT entries */\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase,\n                sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase,\n                (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);\n}\n\n/**\n * Initializes the kernel's Interrupt Descriptor Table (IDT).\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block to use.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)\n{\n    UINT Vector;\n\n    /* Fill in all vectors */\n    for(Vector = 0; Vector < IDT_ENTRIES; Vector++)\n    {\n        /* Set the IDT to handle unexpected interrupts */\n        SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], KGDT_R0_CODE,\n                   KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);\n    }\n\n    /* Setup IDT handlers for known interrupts and traps */\n    SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_NMI, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrapEntry[0x1F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArInterruptEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);\n}\n\n/**\n * Initializes AMD64 processor specific structures.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeProcessor(IN PVOID ProcessorStructures)\n{\n    PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;\n    KDESCRIPTOR GdtDescriptor, IdtDescriptor;\n    PKPROCESSOR_BLOCK ProcessorBlock;\n    PKGDTENTRY Gdt;\n    PKIDTENTRY Idt;\n    PKTSS Tss;\n\n    /* Check if processor structures buffer provided */\n    if(ProcessorStructures)\n    {\n        /* Assign CPU structures from provided buffer */\n        InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,\n                                      &KernelBootStack, &KernelFaultStack, &KernelNmiStack);\n\n        /* Use global IDT */\n        Idt = InitialIdt;\n    }\n    else\n    {\n        /* Use initial structures */\n        Gdt = InitialGdt;\n        Idt = InitialIdt;\n        Tss = &InitialTss;\n        KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);\n        KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);\n        KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);\n        ProcessorBlock = &InitialProcessorBlock;\n    }\n\n    /* Initialize processor block */\n    InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);\n\n    /* Initialize GDT, IDT and TSS */\n    InitializeGdt(ProcessorBlock);\n    InitializeIdt(ProcessorBlock);\n    InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);\n\n    /* Set GDT and IDT descriptors */\n    GdtDescriptor.Base = Gdt;\n    GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;\n    IdtDescriptor.Base = Idt;\n    IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;\n\n    /* Load GDT, IDT and TSS */\n    AR::CpuFunctions::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);\n    AR::CpuFunctions::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);\n    AR::CpuFunctions::LoadTaskRegister((UINT)KGDT_SYS_TSS);\n\n    /* Initialize segment registers */\n    InitializeSegments();\n\n    /* Set GS base */\n    AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);\n    AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);\n\n    /* Initialize processor registers */\n    InitializeProcessorRegisters();\n\n    /* Identify processor */\n    IdentifyProcessor();\n}\n\n/**\n * Initializes processor block.\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block to initialize.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT for this processor block.\n *\n * @param Idt\n *        Supplies a pointer to the IDT for this processor block.\n *\n * @param Tss\n *        Supplies a pointer to the TSS for this processor block.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,\n                                               IN PKGDTENTRY Gdt,\n                                               IN PKIDTENTRY Idt,\n                                               IN PKTSS Tss,\n                                               IN PVOID DpcStack)\n{\n    /* Set processor block and processor control block */\n    ProcessorBlock->Self = ProcessorBlock;\n    ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;\n\n    /* Set GDT, IDT and TSS descriptors */\n    ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;\n    ProcessorBlock->IdtBase = Idt;\n    ProcessorBlock->TssBase = Tss;\n    ProcessorBlock->Prcb.RspBase = Tss->Rsp0;\n\n    /* Setup DPC stack */\n    ProcessorBlock->Prcb.DpcStack = DpcStack;\n\n    /* Setup processor control block */\n    ProcessorBlock->Prcb.CpuNumber = ProcessorBlock->CpuNumber;\n    ProcessorBlock->Prcb.SetMember = 1ULL << ProcessorBlock->CpuNumber;\n    ProcessorBlock->Prcb.MultiThreadProcessorSet = 1ULL << ProcessorBlock->CpuNumber;\n\n    /* Clear DR6 and DR7 registers */\n    ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0;\n    ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;\n\n    /* Set process and thread information */\n    ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;\n    ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock;\n    ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;\n    ProcessorBlock->Prcb.NextThread = NULLPTR;\n\n    /* Set initial MXCSR register value */\n    ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR;\n\n    /* Set initial runlevel */\n    ProcessorBlock->RunLevel = PASSIVE_LEVEL;\n}\n\n/**\n * Initializes processor registers and other boot structures.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeProcessorRegisters(VOID)\n{\n    ULONGLONG PatAttributes;\n\n    /* Enable FXSAVE restore */\n    AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_FXSR);\n\n    /* Enable XMMI exceptions */\n    AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_XMMEXCPT);\n\n    /* Set debugger extension */\n    AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_DE);\n\n    /* Enable large pages */\n    AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_PSE);\n\n    /* Enable write-protection */\n    AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_WP);\n\n    /* Set alignment mask */\n    AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_AM);\n\n    /* Disable FPU monitoring */\n    AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) & ~CR0_MP);\n\n    /* Disable x87 FPU exceptions */\n    AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) & ~CR0_NE);\n\n    /* Flush the TLB */\n    AR::CpuFunctions::FlushTlb();\n\n    /* Initialize system call MSRs */\n    AR::Traps::InitializeSystemCallMsrs();\n    \n    /* Enable No-Execute (NXE) in EFER MSR */\n    AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_EFER,\n                                                 CpuFunctions::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);\n\n    /* Initialize Page Attribute Table */\n    PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |\n                    (PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);\n    AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);\n\n    /* Initialize MXCSR register */\n    AR::CpuFunctions::LoadMxcsrRegister(INITIAL_MXCSR);\n}\n\n/**\n * Initializes i686 processor specific structures with provided memory buffer.\n *\n * @param ProcessorStructures\n *        Supplies a pointer to the allocated buffer with processor structures.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT.\n *\n * @param Tss\n *        Supplies a pointer to the TSS.\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block.\n *\n * @param KernelBootStack\n *        Supplies a pointer to the kernel boot stack.\n *\n * @param KernelFaultStack\n *        Supplies a pointer to the kernel fault stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeProcessorStructures(IN PVOID ProcessorStructures,\n                                                    OUT PKGDTENTRY *Gdt,\n                                                    OUT PKTSS *Tss,\n                                                    OUT PKPROCESSOR_BLOCK *ProcessorBlock,\n                                                    OUT PVOID *KernelBootStack,\n                                                    OUT PVOID *KernelFaultStack,\n                                                    OUT PVOID *KernelNmiStack)\n{\n    UINT_PTR Address;\n\n    /* Align address to page size boundary and move to kernel boot stack */\n    Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;\n\n    /* Assign a space for kernel boot stack and advance */\n    if(KernelBootStack != NULLPTR)\n    {\n        /* Return kernel boot stack address */\n        *KernelBootStack = (PVOID)Address;\n    }\n    Address += KERNEL_STACK_SIZE;\n\n    /* Assign a space for kernel fault stack and advance */\n    if(KernelFaultStack != NULLPTR)\n    {\n        /* Return kernel fault stack address */\n        *KernelFaultStack = (PVOID)Address;\n    }\n    Address += KERNEL_STACK_SIZE;\n\n    /* Assign a space for kernel NMI stack, no advance needed as stack grows down */\n    if(KernelNmiStack != NULLPTR)\n    {\n        /* Return kernel NMI stack address */\n        *KernelNmiStack = (PVOID)Address;\n    }\n\n    /* Assign a space for GDT and advance */\n    if(Gdt != NULLPTR)\n    {\n        /* Return GDT base address */\n        *Gdt = (PKGDTENTRY)(PVOID)Address;\n    }\n    Address += (GDT_ENTRIES * sizeof(KGDTENTRY));\n\n    /* Assign a space for TSS and advance */\n    if(Tss != NULLPTR)\n    {\n        *Tss = (PKTSS)(PVOID)Address;\n    }\n    Address += sizeof(KTSS);\n\n    /* Assign a space for Processor Block and advance */\n    if(ProcessorBlock != NULLPTR)\n    {\n        /* Return processor block address */\n        *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;\n    }\n}\n\n/**\n * Initializes segment registers.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeSegments(VOID)\n{\n    /* Initialize segments */\n    AR::CpuFunctions::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);\n    AR::CpuFunctions::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);\n    AR::CpuFunctions::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);\n    AR::CpuFunctions::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);\n    AR::CpuFunctions::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);\n    AR::CpuFunctions::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);\n}\n\n/**\n * Initializes the kernel's Task State Segment (TSS).\n *\n * @param Tss\n *        Supplies a pointer to the TSS to use.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT to use.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,\n                                    IN PVOID KernelBootStack,\n                                    IN PVOID KernelFaultStack,\n                                    IN PVOID KernelNmiStack)\n{\n    /* Fill TSS with zeroes */\n    RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));\n\n    /* Setup I/O map and stacks for ring0 & traps */\n    ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);\n    ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;\n    ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;\n    ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;\n    ProcessorBlock->TssBase->Ist[KIDT_IST_NMI] = (ULONG_PTR)KernelNmiStack;\n}\n\n/**\n * Fills in an AMD64 GDT entry.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT.\n *\n * @param Selector\n *        Specifies a segment selector of the GDT entry.\n *\n * @param Base\n *        Specifies a base address value of the descriptor.\n *\n * @param Limit\n *        Specifies a descriptor limit.\n *\n * @param Type\n *        Specifies a type of the descriptor.\n *\n * @param Dpl\n *        Specifies the descriptor privilege level.\n *\n * @param SegmentMode\n *        Specifies a segment mode of the descriptor.\n *\n * @return This routine does not return any value\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::SetGdtEntry(IN PKGDTENTRY Gdt,\n                                  IN USHORT Selector,\n                                  IN ULONG_PTR Base,\n                                  IN ULONG Limit,\n                                  IN UCHAR Type,\n                                  IN UCHAR Dpl,\n                                  IN UCHAR SegmentMode)\n{\n    PKGDTENTRY GdtEntry;\n    UCHAR Granularity;\n\n    /* Set the granularity flag depending on descriptor limit */\n    if(Limit < 0x100000)\n    {\n        /* Limit is in 1B blocks */\n        Granularity = 0;\n    }\n    else\n    {\n        /* Limit is in 4KB blocks */\n        Granularity = 1;\n        Limit >>= 12;\n    }\n\n    /* Get GDT entry */\n    GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));\n\n    /* Set GDT descriptor base */\n    GdtEntry->BaseLow = (Base & 0xFFFF);\n    GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);\n    GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);\n    GdtEntry->BaseUpper = (Base >> 32);\n\n    /* Set descriptor limit */\n    GdtEntry->LimitLow = (Limit & 0xFFFF);\n    GdtEntry->Bits.LimitHigh = ((Limit >> 16) & 0xF);\n\n    /* Initialize GDT entry */\n    GdtEntry->Bits.DefaultBig = !!(SegmentMode & 2);\n    GdtEntry->Bits.Dpl = (Dpl & 0x3);\n    GdtEntry->Bits.Granularity = Granularity;\n    GdtEntry->Bits.LongMode = !!(SegmentMode & 1);\n    GdtEntry->Bits.Present = (Type != 0);\n    GdtEntry->Bits.System = 0;\n    GdtEntry->Bits.Type = (Type & 0x1F);\n    GdtEntry->MustBeZero = 0;\n}\n\n/**\n * Updates an existing AMD64 GDT entry with new base address.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT.\n *\n * @param Selector\n *        Specifies a segment selector of the GDT entry.\n *\n * @param Base\n *        Specifies a base address value of the descriptor.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::SetGdtEntryBase(IN PKGDTENTRY Gdt,\n                                      IN USHORT Selector,\n                                      IN ULONG_PTR Base)\n{\n    PKGDTENTRY GdtEntry;\n\n    /* Get GDT entry */\n    GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));\n\n    /* Set new GDT descriptor base */\n    GdtEntry->BaseLow = (Base & 0xFFFF);\n    GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);\n    GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);\n    GdtEntry->BaseUpper = (Base >> 32);\n}\n\n/**\n * Fills in a call, interrupt, task or trap gate entry.\n *\n * @param Idt\n *        Supplies a pointer to IDT structure, where gate is located.\n *\n * @param Vector\n *        Supplies a gate vector pointing to the interrupt gate in the IDT\n *\n * @param Handler\n *        Supplies a pointer to the interrupt handler of the specified gate.\n *\n * @param Selector\n *        Supplies the code selector the gate should run in.\n *\n * @param Ist\n *        Supplies the interrupt stack table entry the gate should run in.\n *\n * @param Access\n *        Supplies the gate access rights.\n *\n * @param Type\n *        Supplies the gate type.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::SetIdtGate(IN PKIDTENTRY Idt,\n                                 IN USHORT Vector,\n                                 IN PVOID Handler,\n                                 IN USHORT Selector,\n                                 IN USHORT Ist,\n                                 IN USHORT Dpl,\n                                 IN USHORT Type)\n{\n    /* Set the handler's address */\n    Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);\n    Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);\n    Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;\n\n    /* Set the code segment selector */\n    Idt[Vector].Selector = Selector;\n\n    /* Initialize the gate's attributes and flags */\n    Idt[Vector].Access = 0;\n    Idt[Vector].Dpl = Dpl;\n    Idt[Vector].IstIndex = Ist;\n    Idt[Vector].Present = 1;\n    Idt[Vector].Reserved1 = 0;\n    Idt[Vector].Type = Type;\n}\n"
  },
  {
    "path": "xtoskrnl/ar/amd64/traps.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/amd64/traps.cc\n * DESCRIPTION:     AMD64 system traps\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Dispatches the interrupt provided by common interrupt handler.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common interrupt handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    PINTERRUPT_HANDLER Handler;\n\n    /* Read the handler pointer from the CPU's interrupt dispatch table */\n    Handler = (PINTERRUPT_HANDLER)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +\n                                                                   (TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));\n\n    /* Check if the interrupt has a handler registered */\n    if(Handler != NULLPTR)\n    {\n        /* Call the handler */\n        Handler(TrapFrame);\n    }\n    else if(UnhandledInterruptRoutine != NULLPTR)\n    {\n        /* Call the unhandled interrupt routine */\n        UnhandledInterruptRoutine(TrapFrame);\n    }\n    else\n    {\n        /* Dispatcher not initialized, print a debug message */\n        DebugPrint(L\"ERROR: Caught unhandled interrupt: 0x%.2llX\\n\", TrapFrame->Vector);\n    }\n}\n\n/**\n * Dispatches the trap provided by common trap handler.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Caught trap: 0x%.2llX with error code: %.4llX at RIP: 0x%.16llX\\n\"\n               L\"RAX: 0x%.16llX, RBX: 0x%.16llX, RCX: 0x%.16llX, RDX: 0x%.16llX\\n\"\n               L\"R8:  0x%.16llX, R9:  0x%.16llX, R10: 0x%.16llX, R11: 0x%.16llX\\n\"\n               L\"R12: 0x%.16llX, R13: 0x%.16llX, R14: 0x%.16llX, R15: 0x%.16llX\\n\"\n               L\"RBP: 0x%.16llX, RSP: 0x%.16llX, RDI: 0x%.16llX, RSI: 0x%.16llX\\n\"\n               L\"DR0: 0x%.16llX, DR1: 0x%.16llX, DR2: 0x%.16llX, DR3: 0x%.16llX\\n\"\n               L\"DR6: 0x%.16llX, DR7: 0x%.16llX\\n\"\n               L\"CR2: 0x%.16llX, CR3: 0x%.16llX, CS:  0x%.16llX, DS:  0x%.16hX\\n\"\n               L\"ES:  0x%.16hX, FS:  0x%.16hX, GS:  0x%.16hX, SS:  0x%.16llX\\n\",\n               TrapFrame->Vector, TrapFrame->ErrorCode, TrapFrame->Rip,\n               TrapFrame->Rax, TrapFrame->Rbx, TrapFrame->Rcx, TrapFrame->Rdx,\n               TrapFrame->R8, TrapFrame->R9, TrapFrame->R10, TrapFrame->R11,\n               TrapFrame->R12, TrapFrame->R13, TrapFrame->R14, TrapFrame->R15,\n               TrapFrame->Rbp, TrapFrame->Rsp, TrapFrame->Rdi, TrapFrame->Rsi,\n               TrapFrame->Dr0, TrapFrame->Dr1, TrapFrame->Dr2, TrapFrame->Dr3,\n               TrapFrame->Dr6, TrapFrame->Dr7,\n               TrapFrame->Cr2, TrapFrame->Cr3, TrapFrame->SegCs, TrapFrame->SegDs,\n               TrapFrame->SegEs, TrapFrame->SegFs, TrapFrame->SegGs, TrapFrame->SegSs);\n\n    /* Check vector and call appropriate handler */\n    switch(TrapFrame->Vector)\n    {\n        case 0x00:\n            /* Divide By Zero exception */\n            HandleTrap00(TrapFrame);\n            break;\n        case 0x01:\n            /* Debug exception */\n            HandleTrap01(TrapFrame);\n            break;\n        case 0x02:\n            /* Non-Maskable Interrupt (NMI) */\n            HandleTrap02(TrapFrame);\n            break;\n        case 0x03:\n            /* INT3 instruction executed */\n            HandleTrap03(TrapFrame);\n            break;\n        case 0x04:\n            /* Overflow exception */\n            HandleTrap04(TrapFrame);\n            break;\n        case 0x05:\n            /* Bound Range Exceeded exception */\n            HandleTrap05(TrapFrame);\n            break;\n        case 0x06:\n            /* Invalid Opcode exception */\n            HandleTrap06(TrapFrame);\n            break;\n        case 0x07:\n            /* Device Not Available exception */\n            HandleTrap07(TrapFrame);\n            break;\n        case 0x08:\n            /* Double Fault exception */\n            HandleTrap08(TrapFrame);\n            break;\n        case 0x09:\n            /* Segment Overrun exception */\n            HandleTrap09(TrapFrame);\n            break;\n        case 0x0A:\n            /* Invalid TSS exception */\n            HandleTrap0A(TrapFrame);\n            break;\n        case 0x0B:\n            /* Segment Not Present exception */\n            HandleTrap0B(TrapFrame);\n            break;\n        case 0x0C:\n            /* Stack Segment Fault exception */\n            HandleTrap0C(TrapFrame);\n            break;\n        case 0x0D:\n            /* General Protection Fault (GPF) exception*/\n            HandleTrap0D(TrapFrame);\n            break;\n        case 0x0E:\n            /* Page Fault exception */\n            HandleTrap0E(TrapFrame);\n            break;\n        case 0x10:\n            /* X87 Floating-Point exception */\n            HandleTrap10(TrapFrame);\n            break;\n        case 0x11:\n            /* Alignment Check exception */\n            HandleTrap11(TrapFrame);\n            break;\n        case 0x12:\n            /* Machine Check exception */\n            HandleTrap12(TrapFrame);\n            break;\n        case 0x13:\n            /* SIMD Floating-Point exception */\n            HandleTrap13(TrapFrame);\n            break;\n        case 0x1F:\n            /* Software Interrupt at APC level */\n            HandleTrap1F(TrapFrame);\n            break;\n        case 0x2C:\n            /* Assertion raised */\n            HandleTrap2C(TrapFrame);\n            break;\n        case 0x2D:\n            /* Debug-Service-Request raised */\n            HandleTrap2D(TrapFrame);\n            break;\n        case 0x2F:\n            /* Software Interrupt at DISPATCH level */\n            HandleTrap2F(TrapFrame);\n            break;\n        case 0xE1:\n            /* InterProcessor Interrupt (IPI) */\n            HandleTrapE1(TrapFrame);\n            break;\n        default:\n            /* Unknown/Unexpected trap */\n            HandleTrapFF(TrapFrame);\n            break;\n    }\n}\n\n/**\n * Handles a 32-bit system call.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleSystemCall32(VOID)\n{\n    DebugPrint(L\"Handled 32-bit system call!\\n\");\n}\n\n/**\n * Handles a 64-bit system call.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleSystemCall64(VOID)\n{\n    DebugPrint(L\"Handled 64-bit system call!\\n\");\n}\n\n/**\n * Handles the trap 0x00 when a Divide By Zero exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Division-By-Zero Error (0x00)!\\n\");\n    KE::Crash::Panic(0x00);\n}\n\n/**\n * Handles the trap 0x01 when Debug exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Debug exception (0x01)!\\n\");\n    KE::Crash::Panic(0x01);\n}\n\n/**\n * Handles the trap 0x02 when Non-Maskable Interrupt (NMI) occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Non-Maskable-Interrupt (0x02)!\\n\");\n}\n\n/**\n * Handles the trap 0x03 when the INT3 instruction is executed.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled INT3 (0x03)!\\n\");\n    KE::Crash::Panic(0x03);\n}\n\n/**\n * Handles the trap 0x04 when the INTO instruction is executed and overflow bit is set.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Overflow exception (0x04)!\\n\");\n    KE::Crash::Panic(0x04);\n}\n\n/**\n * Handles the trap 0x05 when the Bound Range Exceeded exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Bound-Range-Exceeded exception (0x05)!\\n\");\n    KE::Crash::Panic(0x05);\n}\n\n/**\n * Handles the trap 0x06 when the Invalid Opcode exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Invalid Opcode exception (0x06)!\\n\");\n    KE::Crash::Panic(0x06);\n}\n\n/**\n * Handles the trap 0x07 when the Device Not Available exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Device Not Available exception (0x07)!\\n\");\n    KE::Crash::Panic(0x07);\n}\n\n/**\n * Handles the trap 0x08 when Double Fault exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Double-Fault exception (0x08)!\\n\");\n    KE::Crash::Panic(0x08);\n}\n\n/**\n * Handles the trap 0x09 when the Segment Overrun exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Segment-Overrun exception (0x09)!\\n\");\n    KE::Crash::Panic(0x09);\n}\n\n/**\n * Handles the trap 0x0A when the Invalid TSS exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Invalid-TSS exception (0x0A)!\\n\");\n    KE::Crash::Panic(0x0A);\n}\n\n/**\n * Handles the trap 0x0B when the Segment Not Present exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Segment-Not-Present exception (0x0B)!\\n\");\n    KE::Crash::Panic(0x0B);\n}\n\n/**\n * Handles the trap 0x0C when the Stack Segment Fault exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Stack-Segment-Fault exception (0x0C)!\\n\");\n    KE::Crash::Panic(0x0C);\n}\n\n/**\n * Handles the trap 0x0D when General Protection Fault (GPF) exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled General-Protection-Fault (0x0D)!\\n\");\n    KE::Crash::Panic(0x0D);\n}\n\n/**\n * Handles the trap 0x0E when the Page Fault (PF) exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Page-Fault exception (0x0E)!\\n\");\n    KE::Crash::Panic(0x0E);\n}\n\n/**\n * Handles the trap 0x10 when the X87 Floating-Point exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled x87 Floating-Point exception (0x10)!\\n\");\n    KE::Crash::Panic(0x10);\n}\n\n/**\n * Handles the trap 0x11 when the Alignment Check exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Alignment-Check exception (0x11)!\\n\");\n    KE::Crash::Panic(0x11);\n}\n\n/**\n * Handles the trap 0x12 when the Machine Check exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Machine-Check exception (0x12)!\\n\");\n    KE::Crash::Panic(0x12);\n}\n\n/**\n * Handles the trap 0x13 when the SIMD Floating-Point exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled SIMD Floating-Point exception (0x13)!\\n\");\n    KE::Crash::Panic(0x13);\n}\n\n/**\n * Handles the trap 0x1F when software interrupt gets generated at APC_LEVEL.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap1F(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Unhandled software interrupt at APC level (0x1F)!\\n\");\n}\n\n/**\n * Handles the trap 0x2C when an assertion is raised.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Assertion (0x2C)!\\n\");\n    KE::Crash::Panic(0x2C);\n}\n\n/**\n * Handles the trap 0x2D when a debug service is being requested.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Debug-Service-Request (0x2D)!\\n\");\n    KE::Crash::Panic(0x2D);\n}\n\n/**\n * Handles the trap 0x2F when a software interrupt gets generated at DISPATCH_LEVEL.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap2F(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Unhandled software interrupt at DISPATCH level (0x2F)!\\n\");\n}\n\n/**\n * Handles the trap 0xE1 when InterProcessor Interrupt (IPI) occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrapE1(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Unhandled IPI interrupt (0xE1)!\\n\");\n}\n\n/**\n * Handles the trap 0xFF when Unexpected Interrupt occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Unexpected-Interrupt (0xFF)!\\n\");\n    KE::Crash::Panic(0xFF);\n}\n\n/**\n * Initializes system call MSRs.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::InitializeSystemCallMsrs(VOID)\n{\n    /* Initialize system calls MSR */\n    CpuFunctions::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));\n    CpuFunctions::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32);\n    CpuFunctions::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64);\n    CpuFunctions::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);\n\n    /* Enable system call extensions (SCE) in EFER MSR */\n    CpuFunctions::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunctions::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);\n}\n\n/**\n * Sets the unhandled interrupt routine used for vectors that have no handler registered.\n *\n * @param Handler\n *        Supplies the pointer to the interrupt handler routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)\n{\n    /* Set the unhandled interrupt routine */\n    UnhandledInterruptRoutine = Handler;\n}\n"
  },
  {
    "path": "xtoskrnl/ar/i686/archsup.S",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/i686/archsup.S\n * DESCRIPTION:     Provides i686 architecture features not implementable in C.\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtkmapi.h>\n#include <xtadk.h>\n\n.altmacro\n.text\n\n\n/**\n * Creates a task, trap or interrupt handler for the specified vector.\n *\n * @param Vector\n *        Supplies a vector number.\n *\n * @param Type\n *        Specifies whether the handler is designed to handle an interrupt, a task or a trap.\n *\n * @return This macro does not return any value.\n *\n * @since XT 1.0\n */\n.macro ArCreateHandler Vector Type\n.global _Ar\\Type\\Vector\n_Ar\\Type\\Vector:\n     /* Check handler type */\n    .ifc \\Type,Task\n_Ar\\Type\\Vector\\()Start:\n        /* Clear the Task Switch flag */\n        clts\n\n        /* Allocate the trap frame and inject the hardware vector for the dispatcher */\n        sub $KTRAP_FRAME_SIZE, %esp\n        movl $\\Vector, KTRAP_FRAME_Vector(%esp)\n\n        /* Pass the trap frame pointer as an argument and clear the direction flag */\n        push %esp\n        cld\n\n        /* Pass control to the trap dispatcher */\n        call _ArDispatchTrap\n\n        /* Discard the argument and deallocate the trap frame */\n        add $4, %esp\n        add $KTRAP_FRAME_SIZE, %esp\n\n        /* Hardware task return */\n        iretl\n\n        /* Spin back to the entry point to rearm the task gate */\n        jmp _Ar\\Type\\Vector\\()Start\n    .else\n        /* Check handler type */\n        .ifc \\Type,Trap\n            /* Push fake error code for non-error vector traps */\n            .if \\Vector != 8 && \\Vector != 10 && \\Vector != 11 && \\Vector != 12 && \\Vector != 13 && \\Vector != 14 && \\Vector != 17 && \\Vector != 30\n                push $0\n            .endif\n        .else\n            /* Push fake error code for interrupts */\n            push $0\n        .endif\n\n        /* Push vector number */\n        push $\\Vector\n\n        /* Push General Purpose Registers */\n        push %ebp\n        push %edi\n        push %esi\n        push %edx\n        push %ecx\n        push %ebx\n        push %eax\n\n        /* Reserve space for other registers and point RBP to the trap frame */\n        sub $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %esp\n        lea (%esp), %ebp\n\n        /* Store segment selectors */\n        mov %gs, KTRAP_FRAME_SegGs(%ebp)\n        mov %fs, KTRAP_FRAME_SegFs(%ebp)\n        mov %es, KTRAP_FRAME_SegEs(%ebp)\n        mov %ds, KTRAP_FRAME_SegDs(%ebp)\n\n        /* Store debug registers */\n        mov %dr7, %eax\n        mov %eax, KTRAP_FRAME_Dr7(%ebp)\n        mov %dr6, %eax\n        mov %eax, KTRAP_FRAME_Dr6(%ebp)\n        mov %dr3, %eax\n        mov %eax, KTRAP_FRAME_Dr3(%ebp)\n        mov %dr2, %eax\n        mov %eax, KTRAP_FRAME_Dr2(%ebp)\n        mov %dr1, %eax\n        mov %eax, KTRAP_FRAME_Dr1(%ebp)\n        mov %dr0, %eax\n        mov %eax, KTRAP_FRAME_Dr0(%ebp)\n\n        /* Store CR2 and CR3 */\n        mov %cr3, %eax\n        mov %eax, KTRAP_FRAME_Cr3(%ebp)\n        mov %cr2, %eax\n        mov %eax, KTRAP_FRAME_Cr2(%ebp)\n\n        /* Test previous mode */\n        movl $0, KTRAP_FRAME_PreviousMode(%ebp)\n        mov KTRAP_FRAME_SegCs(%ebp), %ax\n        and $3, %al\n        mov %al, KTRAP_FRAME_PreviousMode(%ebp)\n        jz Dispatch\\Type\\Vector\n\n        /* Load Kernel PB selector into FS */\n        mov $KGDT_R0_PB, %ax\n        mov %ax, %fs\n\n        /* Set sane data segment selectors */\n        mov $(KGDT_R3_DATA | RPL_MASK), %ax\n        mov %ax, %ds\n        mov %ax, %es\n\nDispatch\\Type\\Vector:\n        /* Push Frame Pointer and clear direction flag */\n        push %esp\n        cld\n\n        .ifc \\Type,Trap\n            /* Pass to the trap dispatcher */\n            call _ArDispatchTrap\n        .else\n            /* Pass to the interrupt dispatcher */\n            call _ArDispatchInterrupt\n        .endif\n\n        /* Clean up the stack */\n        add $4, %esp\n\n        /* Test previous mode and disable interrupts before user mode return */\n        testb $1, KTRAP_FRAME_PreviousMode(%ebp)\n        jz RestoreState\\Type\\Vector\n        cli\n\nRestoreState\\Type\\Vector:\n        /* Restore segment selectors */\n        mov KTRAP_FRAME_SegDs(%ebp), %ds\n        mov KTRAP_FRAME_SegEs(%ebp), %es\n        mov KTRAP_FRAME_SegFs(%ebp), %fs\n        mov KTRAP_FRAME_SegGs(%ebp), %gs\n\n        /* Free stack space */\n        add $(KTRAP_FRAME_SIZE - KTRAP_FRAME_REGISTERS_SIZE), %esp\n\n        /* Pop General Purpose Registers */\n        pop %eax\n        pop %ebx\n        pop %ecx\n        pop %edx\n        pop %esi\n        pop %edi\n        pop %ebp\n\n        /* Skip error code and vector number, then return */\n        add $(2 * 4), %esp\n        iretl\n    .endif\n.endm\n\n/* Populate common interrupt, task and trap handlers */\n.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n    .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n        ArCreateHandler 0x\\i\\j Interrupt\n        .if 0x\\i\\j == 0x02 || 0x\\i\\j == 0x08\n            ArCreateHandler 0x\\i\\j Task\n        .else\n            ArCreateHandler 0x\\i\\j Trap\n        .endif\n    .endr\n.endr\n\n/* Define array of pointers to the interrupt handlers */\n.global _ArInterruptEntry\n_ArInterruptEntry:\n.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n    .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n        .long _ArInterrupt0x\\i\\j\n    .endr\n.endr\n\n/* Define array of pointers to the trap handlers */\n.global _ArTrapEntry\n_ArTrapEntry:\n.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n    .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F\n        .if 0x\\i\\j == 0x02 || 0x\\i\\j == 0x08\n            .long _ArTask0x\\i\\j\n        .else\n            .long _ArTrap0x\\i\\j\n        .endif\n    .endr\n.endr\n\n/**\n * Enables eXtended Physical Addressing (XPA). On i386, this is just a stub.\n *\n * @param PageMap\n *        Supplies a pointer to the page map to be used.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\n.global ArEnableExtendedPhysicalAddressing\nArEnableExtendedPhysicalAddressing:\n\n.global ArEnableExtendedPhysicalAddressingEnd\nArEnableExtendedPhysicalAddressingEnd:\n\n/**\n * Handles a spurious interrupt allowing it to end up.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\n.global _ArHandleSpuriousInterrupt\n_ArHandleSpuriousInterrupt:\n    iret\n\n/**\n * Starts an application processor (AP).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\n.global _ArStartApplicationProcessor\n_ArStartApplicationProcessor:\n    /* Enter 16-bit real mode */\n    .code16\n\n    /* Disable interrupts and clear direction flag */\n    cli\n    cld\n\n    /* Establish a flat addressing baseline */\n    movw %cs, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n\n    /* Calculate absolute physical base address */\n    xorl %ebx, %ebx\n    movw %cs, %bx\n    shll $4, %ebx\n\n    /* Set up a temporary stack for the AP initialization */\n    movl %ebx, %esp\n    addl $0x1000, %esp\n\n    /* Load the temporary Global Descriptor Table */\n    leal (ApTemporaryGdtDesc - _ArStartApplicationProcessor)(%ebx), %eax\n    movl %eax, (ApTemporaryGdtBase - _ArStartApplicationProcessor)\n    lgdtl (ApTemporaryGdtSize - _ArStartApplicationProcessor)\n\n    /* Enable Protected Mode */\n    movl %cr0, %eax\n    orl $0x01, %eax\n    movl %eax, %cr0\n\n    /* Far return to enter 32-bit protected mode */\n    leal (ApEnterProtectedMode - _ArStartApplicationProcessor)(%ebx), %eax\n    pushl $KGDT_R0_CODE\n    pushl %eax\n    lretl\n\nApEnterProtectedMode:\n    /* Enter 32-bit protected mode */\n    .code32\n\n    /* Setup all data segment registers */\n    movw $KGDT_R0_DATA, %ax\n    movw %ax, %ds\n    movw %ax, %es\n    movw %ax, %ss\n    xorw %ax, %ax\n    movw %ax, %fs\n    movw %ax, %gs\n\n    /* Locate PROCESSOR_START_BLOCK structure */\n    leal (_ArStartApplicationProcessorEnd - _ArStartApplicationProcessor)(%ebx), %edi\n\n    /* Load CR4 from BSP, but mask PCIDE and PGE */\n    movl PROCESSOR_START_BLOCK_Cr4(%edi), %eax\n    andl $~(CR4_PGE | CR4_PCIDE), %eax\n    movl %eax, %cr4\n\n    /* Load the Kernel Page Directory Base from BSP */\n    movl PROCESSOR_START_BLOCK_Cr3(%edi), %eax\n    movl %eax, %cr3\n\n    /* Enable Paging */\n    movl %cr0, %eax\n    orl $CR0_PG, %eax\n    movl %eax, %cr0\n\n    /* Load dedicated Stack for AP */\n    movl PROCESSOR_START_BLOCK_Stack(%edi), %esp\n\n    /* Save the pointer to PROCESSOR_START_BLOCK */\n    movl %edi, %ecx\n    pushl %edi\n\n    /* Call the EntryPoint routine */\n    movl PROCESSOR_START_BLOCK_EntryPoint(%edi), %eax\n    call *%eax\n\n    /* Fire the breakpoint and halt if the entry point returns */\n.ApNoReturnPoint:\n    int $0x03\n    hlt\n    jmp .ApNoReturnPoint\n\n/* Data section for temporary GDT */\n.align 8\nApTemporaryGdtSize: .short _ArStartApplicationProcessorEnd - ApTemporaryGdtDesc - 1\nApTemporaryGdtBase: .long 0x00000000\nApTemporaryGdtDesc: .quad 0x0000000000000000, 0x00CF9A000000FFFF, 0x00CF92000000FFFF\n\n.global _ArStartApplicationProcessorEnd\n_ArStartApplicationProcessorEnd:\n"
  },
  {
    "path": "xtoskrnl/ar/i686/cpufunc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/i686/cpufunc.cc\n * DESCRIPTION:     Routines to provide access to special i686 CPU instructions\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Instructs the processor to clear the interrupt flag.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::ClearInterruptFlag(VOID)\n{\n    __asm__ volatile(\"cli\");\n}\n\n/**\n * Retrieves a various amount of information about the CPU.\n *\n * @param Registers\n *        Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID.\n *\n * @return This routine returns TRUE if CPUID function could be executed, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nAR::CpuFunctions::CpuId(IN OUT PCPUID_REGISTERS Registers)\n{\n    UINT32 MaxLeaf;\n\n    /* Get highest function ID available */\n    __asm__ volatile(\"cpuid\"\n                     : \"=a\" (MaxLeaf)\n                     : \"a\" (Registers->Leaf & 0x80000000)\n                     : \"rbx\",\n                       \"rcx\",\n                       \"rdx\");\n\n    /* Check if CPU supports this command */\n    if(Registers->Leaf > MaxLeaf)\n    {\n        /* Cannot call it, return FALSE */\n        return FALSE;\n    }\n\n    /* Execute CPUID function */\n    __asm__ volatile(\"cpuid\"\n                     : \"=a\" (Registers->Eax),\n                       \"=b\" (Registers->Ebx),\n                       \"=c\" (Registers->Ecx),\n                       \"=d\" (Registers->Edx)\n                     : \"a\" (Registers->Leaf),\n                       \"c\" (Registers->SubLeaf));\n\n    /* Return TRUE */\n    return TRUE;\n}\n\n/**\n * Partially flushes the Translation Lookaside Buffer (TLB)\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::FlushTlb(VOID)\n{\n    /* Flush the TLB by resetting the CR3 */\n    WriteControlRegister(3, ReadControlRegister(3));\n}\n\n/**\n * Gets the EFLAGS register.\n *\n * @return This routine returns the EFLAGS register.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG\nAR::CpuFunctions::GetCpuFlags(VOID)\n{\n    ULONG_PTR Flags;\n\n    /* Get EFLAGS register */\n    __asm__ volatile(\"pushf\\n\"\n                     \"pop %0\\n\"\n                     : \"=rm\" (Flags)\n                     :\n                     : \"memory\");\n\n    /* Return flags */\n    return Flags;\n}\n\n/**\n * Gets the address of the current stack register.\n *\n * @return This routine returns the current stack pointer.\n *\n * @since XT 1.0\n */\nXTASSEMBLY\nXTCDECL\nULONG_PTR\nAR::CpuFunctions::GetStackPointer(VOID)\n{\n    /* Get current stack pointer */\n    __asm__ volatile(\"mov %%esp, %%eax\\n\"\n                     \"ret\\n\"\n                      :\n                      :\n                      :);\n}\n\n/**\n * Halts the central processing unit (CPU).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::Halt(VOID)\n{\n    __asm__ volatile(\"hlt\");\n}\n\n/**\n * Checks whether interrupts are enabled or not.\n *\n * @return This routine returns TRUE if interrupts are enabled, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nAR::CpuFunctions::InterruptsEnabled(VOID)\n{\n    ULONG_PTR Flags;\n\n    /* Get RFLAGS register */\n    Flags = GetCpuFlags();\n\n    /* Check if interrupts are enabled and return result */\n    return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE;\n}\n\n/**\n * Invalidates the TLB (Translation Lookaside Buffer) for specified virtual address.\n *\n * @param Address\n *        Suuplies a virtual address whose associated TLB entry will be invalidated.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::InvalidateTlbEntry(PVOID Address)\n{\n    __asm__ volatile(\"invlpg (%0)\"\n                     :\n                     : \"b\" (Address)\n                     : \"memory\");\n}\n\n/**\n * Loads the value in the source operand into the global descriptor table register (GDTR).\n *\n * @param Source\n *        Specifies a memory location that contains the base address of GDT.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadGlobalDescriptorTable(IN PVOID Source)\n{\n    __asm__ volatile(\"lgdt %0\"\n                     :\n                     : \"m\" (*(PSHORT)Source)\n                     : \"memory\");\n}\n\n/**\n * Loads the value in the source operand into the interrupt descriptor table register (IDTR).\n *\n * @param Source\n *        Specifies a memory location that contains the base address of IDT.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadInterruptDescriptorTable(IN PVOID Source)\n{\n    __asm__ volatile(\"lidt %0\"\n                     :\n                     : \"m\" (*(PSHORT)Source)\n                     : \"memory\");\n}\n\n/**\n * Loads the value in the source operand into the local descriptor table register (LDTR).\n *\n * @param Source\n *        Specifies a selector value.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadLocalDescriptorTable(IN USHORT Source)\n{\n    __asm__ volatile(\"lldtw %0\"\n                     :\n                     : \"g\" (Source));\n}\n\n/**\n * Loads source data into specified segment.\n *\n * @param Segment\n *        Supplies a segment identification.\n *\n * @param Source\n *        Supplies a pointer to the memory area containing data that will be loaded into specified segment.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadSegment(IN USHORT Segment,\n                              IN ULONG Source)\n{\n    switch(Segment)\n    {\n        case SEGMENT_CS:\n            /* Load CS Segment */\n            __asm__ volatile(\"mov %0, %%eax\\n\"\n                             \"push %%eax\\n\"\n                             \"lea label, %%eax\\n\"\n                             \"push %%eax\\n\"\n                             \"lret\\n\"\n                             \"label:\"\n                             :\n                             : \"ri\" (Source)\n                             : \"eax\");\n            break;\n        case SEGMENT_DS:\n            /* Load DS Segment */\n            __asm__ volatile(\"movl %0, %%ds\"\n                             :\n                             : \"r\" (Source));\n            break;\n        case SEGMENT_ES:\n            /* Load ES Segment */\n            __asm__ volatile(\"movl %0, %%es\"\n                             :\n                             : \"r\" (Source));\n            break;\n        case SEGMENT_FS:\n            /* Load FS Segment */\n            __asm__ volatile(\"movl %0, %%fs\"\n                             :\n                             : \"r\" (Source));\n            break;\n        case SEGMENT_GS:\n            /* Load GS Segment */\n            __asm__ volatile(\"movl %0, %%gs\"\n                             :\n                             : \"r\" (Source));\n            break;\n        case SEGMENT_SS:\n            /* Load SS Segment */\n            __asm__ volatile(\"movl %0, %%ss\"\n                             :\n                             : \"r\" (Source));\n            break;\n    }\n}\n\n/**\n * Loads Task Register (TR) with a segment selector that points to TSS.\n *\n * @param Source\n *        Supplies the segment selector in the GDT describing the TSS.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::LoadTaskRegister(USHORT Source)\n{\n    __asm__ volatile(\"ltr %0\"\n                     :\n                     : \"rm\" (Source));\n}\n\n/**\n * Orders memory accesses as seen by other processors.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::MemoryBarrier(VOID)\n{\n   LONG Barrier;\n   __asm__ volatile(\"xchg %%eax, %0\"\n                    :\n                    : \"m\" (Barrier)\n                    : \"%eax\");\n}\n\n/**\n * Reads the specified CPU control register and returns its value.\n *\n * @param ControlRegister\n *        Supplies a number of a control register which controls the general behavior of a CPU.\n *\n * @return This routine returns the value stored in the control register.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG_PTR\nAR::CpuFunctions::ReadControlRegister(IN USHORT ControlRegister)\n{\n    ULONG_PTR Value;\n\n    /* Read a value from specified CR register */\n    switch(ControlRegister)\n    {\n        case 0:\n            /* Read value from CR0 */\n            __asm__ volatile(\"mov %%cr0, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        case 2:\n            /* Read value from CR2 */\n            __asm__ volatile(\"mov %%cr2, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        case 3:\n            /* Read value from CR3 */\n            __asm__ volatile(\"mov %%cr3, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        case 4:\n            /* Read value from CR4 */\n            __asm__ volatile(\"mov %%cr4, %0\"\n                             : \"=r\" (Value)\n                             :\n                             : \"memory\");\n            break;\n        default:\n            /* Invalid control register set */\n            Value = 0;\n            break;\n    }\n\n    /* Return value read from given CR register */\n    return Value;\n}\n\n/**\n * Reads the specified CPU debug register and returns its value.\n *\n * @param DebugRegister\n *        Supplies a number of a debug register to read from.\n *\n * @return This routine returns the value stored in the specified debug register.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG_PTR\nAR::CpuFunctions::ReadDebugRegister(IN USHORT DebugRegister)\n{\n    ULONG_PTR Value;\n\n    /* Read a value from specified DR register */\n    switch(DebugRegister)\n    {\n        case 0:\n            /* Read value from DR0 */\n            __asm__ volatile(\"mov %%dr0, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 1:\n            /* Read value from DR1 */\n            __asm__ volatile(\"mov %%dr1, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 2:\n            /* Read value from DR2 */\n            __asm__ volatile(\"mov %%dr2, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 3:\n            /* Read value from DR3 */\n            __asm__ volatile(\"mov %%dr3, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 4:\n            /* Read value from DR4 */\n            __asm__ volatile(\"mov %%dr4, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 5:\n            /* Read value from DR5 */\n            __asm__ volatile(\"mov %%dr5, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 6:\n            /* Read value from DR6 */\n            __asm__ volatile(\"mov %%dr6, %0\"\n                             : \"=r\" (Value));\n            break;\n        case 7:\n            /* Read value from DR7 */\n            __asm__ volatile(\"mov %%dr7, %0\"\n                             : \"=r\" (Value));\n            break;\n        default:\n            /* Invalid debug register set */\n            Value = 0;\n            break;\n    }\n\n    /* Return value read from given DR register */\n    return Value;\n}\n\n/**\n * Reads dualword from a memory location specified by an offset relative to the beginning of the FS segment.\n *\n * @param Offset\n *        Specifies the offset from the beginning of FS segment.\n *\n * @return This routine returns the value read from the specified memory location relative to FS segment.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG\nAR::CpuFunctions::ReadFSDualWord(ULONG Offset)\n{\n    ULONG Value;\n    __asm__ volatile(\"movl %%fs:%a[Offset], %k[Value]\"\n                     : [Value] \"=r\" (Value)\n                     : [Offset] \"ir\" (Offset));\n    return Value;\n}\n\n/**\n * Reads a 64-bit value from the requested Model Specific Register (MSR).\n *\n * @param Register\n *        Supplies the MSR to read.\n *\n * @return This routine returns the 64-bit MSR value.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONGLONG\nAR::CpuFunctions::ReadModelSpecificRegister(IN ULONG Register)\n{\n    ULONGLONG Value;\n\n    __asm__ volatile(\"rdmsr\"\n                     : \"=A\" (Value)\n                     : \"c\" (Register));\n    return Value;\n}\n\n/**\n * Reads the contents of the MXCSR control/status register.\n *\n * @return This routine returns the contents of the MXCSR register as a 32-bit unsigned integer value.\n *\n * @since XT 1.0\n */\nXTCDECL\nUINT\nAR::CpuFunctions::ReadMxCsrRegister(VOID)\n{\n    return __builtin_ia32_stmxcsr();\n}\n\n/**\n * Reads the current value of the CPU's time-stamp counter.\n *\n * @return This routine returns the current instruction cycle count since the processor was started.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONGLONG\nAR::CpuFunctions::ReadTimeStampCounter(VOID)\n{\n    ULONGLONG Value;\n\n    __asm__ volatile(\"rdtsc\"\n                     : \"=A\" (Value));\n\n    return Value;\n}\n\n/**\n * Reads the current value of the CPU's time-stamp counter and processor ID.\n *\n * @param TscAux\n *        Supplies a pointer to a variable that receives the auxiliary TSC information (IA32_TSC_AUX).\n *\n * @return This routine returns the current instruction cycle count since the processor was last reset.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONGLONG\nAR::CpuFunctions::ReadTimeStampCounterProcessor(OUT PULONG TscAux)\n{\n    ULONG Low, High;\n\n    /* Execute the RDTSCP instruction */\n    __asm__ volatile(\"rdtscp\"\n                     : \"=a\" (Low),\n                       \"=d\" (High),\n                       \"=c\" (*TscAux)\n    );\n\n    /* Combine the two 32-bit registers into a single 64-bit unsigned integer and return the value */\n    return ((ULONGLONG)High << 32) | Low;\n}\n\n/**\n * Orders memory accesses as seen by other processors, without fence.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::ReadWriteBarrier(VOID)\n{\n    __asm__ volatile(\"\"\n                     :\n                     :\n                     : \"memory\");\n}\n\n/**\n * Instructs the processor to set the interrupt flag.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::SetInterruptFlag(VOID)\n{\n    __asm__ volatile(\"sti\");\n}\n\n/**\n * Stores GDT register into the given memory area.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where GDT will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreGlobalDescriptorTable(OUT PVOID Destination)\n{\n    __asm__ volatile(\"sgdt %0\"\n                     : \"=m\" (*(PSHORT)Destination)\n                     :\n                     : \"memory\");\n}\n\n/**\n * Stores IDT register into the given memory area.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where IDT will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreInterruptDescriptorTable(OUT PVOID Destination)\n{\n    __asm__ volatile(\"sidt %0\"\n                     : \"=m\" (*(PSHORT)Destination)\n                     :\n                     : \"memory\");\n}\n\n/**\n * Stores LDT register into the given memory area.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where LDT will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreLocalDescriptorTable(OUT PVOID Destination)\n{\n    __asm__ volatile(\"sldt %0\"\n                     : \"=m\" (*(PSHORT)Destination)\n                     :\n                     : \"memory\");\n}\n\n/**\n * Stores specified segment into the given memory area.\n *\n * @param Segment\n *        Supplies a segment identification.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where segment data will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreSegment(IN USHORT Segment,\n                               OUT PVOID Destination)\n{\n    switch(Segment)\n    {\n        case SEGMENT_CS:\n            __asm__ volatile(\"movl %%cs, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_DS:\n            __asm__ volatile(\"movl %%ds, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_ES:\n            __asm__ volatile(\"movl %%es, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_FS:\n            __asm__ volatile(\"movl %%fs, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_GS:\n            __asm__ volatile(\"movl %%gs, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        case SEGMENT_SS:\n            __asm__ volatile(\"movl %%ss, %0\"\n                             : \"=r\" (*(PUINT)Destination));\n            break;\n        default:\n            Destination = NULLPTR;\n            break;\n    }\n}\n\n/**\n * Stores TR into the given memory area.\n *\n * @param Destination\n *        Supplies a pointer to the memory area where TR will be stores.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::StoreTaskRegister(OUT PVOID Destination)\n{\n    __asm__ volatile(\"str %0\"\n                     : \"=m\" (*(PULONG)Destination)\n                     :\n                     : \"memory\");\n}\n\n/**\n * Writes a value to the specified CPU control register.\n *\n * @param ControlRegister\n *        Supplies a number of a control register which controls the general behavior of a CPU.\n *\n * @param Value\n *        Suplies a value to write to the CR register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::WriteControlRegister(IN USHORT ControlRegister,\n                                       IN UINT_PTR Value)\n{\n    /* Write a value into specified control register */\n    switch(ControlRegister)\n    {\n        case 0:\n            /* Write value to CR0 */\n            __asm__ volatile(\"mov %0, %%cr0\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 2:\n            /* Write value to CR2 */\n            __asm__ volatile(\"mov %0, %%cr2\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 3:\n            /* Write value to CR3 */\n            __asm__ volatile(\"mov %0, %%cr3\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n        case 4:\n            /* Write value to CR4 */\n            __asm__ volatile(\"mov %0, %%cr4\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n            break;\n    }\n}\n\n/**\n * Writes a value to the specified CPU debug register.\n *\n * @param DebugRegister\n *        Supplies a number of a debug register for write operation.\n *\n * @param Value\n *        Suplies a value to write to the specified DR register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::WriteDebugRegister(IN USHORT DebugRegister,\n                                     IN UINT_PTR Value)\n{\n    /* Write a value into specified debug register */\n    switch(DebugRegister)\n    {\n        case 0:\n            /* Write value to DR0 */\n            __asm__ volatile(\"mov %0, %%dr0\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n        case 1:\n            /* Write value to DR1 */\n            __asm__ volatile(\"mov %0, %%dr1\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n        case 2:\n            /* Write value to DR2 */\n            __asm__ volatile(\"mov %0, %%dr2\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n        case 3:\n            /* Write value to DR3 */\n            __asm__ volatile(\"mov %0, %%dr3\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n        case 4:\n            /* Write value to DR4 */\n            __asm__ volatile(\"mov %0, %%dr4\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n        case 5:\n            /* Write value to DR5 */\n            __asm__ volatile(\"mov %0, %%dr5\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n        case 6:\n            /* Write value to DR6 */\n            __asm__ volatile(\"mov %0, %%dr6\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n        case 7:\n            /* Write value to DR7 */\n            __asm__ volatile(\"mov %0, %%dr7\"\n                             :\n                             : \"r\" (Value)\n                             : \"memory\");\n    }\n}\n\n/**\n * Writes the specified value to the program status and control (EFLAGS) register.\n *\n * @param Value\n *        The value to write to the EFLAGS register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::WriteEflagsRegister(IN UINT_PTR Value)\n{\n    __asm__ volatile(\"push %0\\n\"\n                     \"popf\"\n                     :\n                     : \"rim\" (Value));\n}\n\n/**\n * Writes a 64-bit value to the requested Model Specific Register (MSR).\n *\n * @param Register\n *        Supplies the MSR register to write.\n *\n * @param Value\n *        Supplies the 64-bit value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::WriteModelSpecificRegister(IN ULONG Register,\n                                             IN ULONGLONG Value)\n{\n    __asm__ volatile(\"wrmsr\"\n                     :\n                     : \"c\" (Register),\n                       \"A\" (Value));\n}\n\n/**\n * Yields a current thread running on the processor.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::CpuFunctions::YieldProcessor(VOID)\n{\n    __asm__ volatile(\"pause\"\n                     :\n                     :\n                     : \"memory\");\n}\n"
  },
  {
    "path": "xtoskrnl/ar/i686/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/i686/data.cc\n * DESCRIPTION:     I686 architecture-specific global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* Initial kernel boot stack */\nUCHAR AR::ProcessorSupport::BootStack[KERNEL_STACK_SIZE] = {};\n\n/* Double Fault gate */\nUCHAR AR::ProcessorSupport::DoubleFaultTss[KTSS_IO_MAPS];\n\n/* Initial kernel fault stack */\nUCHAR AR::ProcessorSupport::FaultStack[KERNEL_STACK_SIZE] = {};\n\n/* Initial GDT */\nKGDTENTRY AR::ProcessorSupport::InitialGdt[GDT_ENTRIES] = {};\n\n/* Initial IDT */\nKIDTENTRY AR::ProcessorSupport::InitialIdt[IDT_ENTRIES] = {};\n\n/* Initial Processor Block */\nKPROCESSOR_BLOCK AR::ProcessorSupport::InitialProcessorBlock;\n\n/* Initial TSS */\nKTSS AR::ProcessorSupport::InitialTss;\n\n/* Initial kernel NMI stack */\nUCHAR AR::ProcessorSupport::NmiStack[KERNEL_STACK_SIZE] = {};\n\n/* NMI task gate */\nUCHAR AR::ProcessorSupport::NonMaskableInterruptTss[KTSS_IO_MAPS];\n\n/* Unhandled interrupt routine */\nPINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;\n"
  },
  {
    "path": "xtoskrnl/ar/i686/procsup.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/i686/procsup.cc\n * DESCRIPTION:     I686 processor functionality support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Gets the base address of the kernel boot stack.\n *\n * @return This routine returns a pointer to the kernel boot stack.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nAR::ProcessorSupport::GetBootStack(VOID)\n{\n    /* Return base address of kernel boot stack */\n    return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);\n}\n\nXTAPI\nVOID\nAR::ProcessorSupport::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,\n                                               OUT PVOID *TrampolineCode,\n                                               OUT PULONG_PTR TrampolineSize)\n{\n    /* Get trampoline information */\n    switch(TrampolineType)\n    {\n        case TrampolineApStartup:\n            /* Get AP startup trampoline information */\n            *TrampolineCode = (PVOID)ArStartApplicationProcessor;\n            *TrampolineSize = (ULONG_PTR)ArStartApplicationProcessorEnd -\n                              (ULONG_PTR)ArStartApplicationProcessor;\n            break;\n        default:\n            /* Unknown trampoline type */\n            *TrampolineCode = NULLPTR;\n            *TrampolineSize = 0;\n            break;\n    }\n}\n\n/**\n * Identifies processor type (vendor, model, stepping) and stores them in Processor Control Block (PRCB).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::IdentifyProcessor(VOID)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    CPUID_REGISTERS CpuRegisters;\n    CPUID_SIGNATURE CpuSignature;\n\n    /* Get current processor control block */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n    /* Get CPU vendor by issueing CPUID instruction */\n    RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n\n    /* Store CPU vendor in processor control block */\n    Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;\n    *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;\n    *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;\n    *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;\n    Prcb->CpuId.VendorName[12] = '\\0';\n\n    /* Get CPU standard features */\n    RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n\n    /* Store CPU signature in processor control block */\n    CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;\n    Prcb->CpuId.Family = CpuSignature.Family;\n    Prcb->CpuId.Model = CpuSignature.Model;\n    Prcb->CpuId.Stepping = CpuSignature.Stepping;\n\n    /* CPU vendor specific quirks */\n    if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD)\n    {\n        /* AMD CPU */\n        if(CpuSignature.Family == 0xF)\n        {\n            Prcb->CpuId.Family += CpuSignature.ExtendedFamily;\n            Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);\n        }\n    }\n    else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL)\n    {\n        /* Intel CPU */\n        if(CpuSignature.Family == 0xF)\n        {\n            Prcb->CpuId.Family += CpuSignature.ExtendedFamily;\n        }\n\n        if((CpuSignature.Family == 0x6) || (CpuSignature.Family == 0xF))\n        {\n            Prcb->CpuId.Model += (CpuSignature.ExtendedModel << 4);\n        }\n    }\n    else\n    {\n        /* Unknown CPU vendor */\n        Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;\n    }\n\n    /* Identify processor features */\n    IdentifyProcessorFeatures();\n}\n\n/**\n * Identifies processor features and stores them in Processor Control Block (PRCB).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::IdentifyProcessorFeatures(VOID)\n{\n    ULONG MaxExtendedLeaf, MaxStandardLeaf;\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    CPUID_REGISTERS CpuRegisters;\n\n    /* Get current processor control block */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n    /* Get maximum CPUID standard leaf */\n    RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n    MaxStandardLeaf = CpuRegisters.Eax;\n\n    /* Get maximum CPUID extended leaf */\n    RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n    MaxExtendedLeaf = CpuRegisters.Eax;\n\n    /* Check if CPU supports standard features leaf */\n    if(MaxStandardLeaf >= CPUID_GET_STANDARD1_FEATURES)\n    {\n        /* Get CPU standard features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU standard features in processor control block */\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_VMX) Prcb->CpuId.FeatureBits |= KCF_VMX;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSSE3) Prcb->CpuId.FeatureBits |= KCF_SSSE3;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_1) Prcb->CpuId.FeatureBits |= KCF_SSE41;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4_2) Prcb->CpuId.FeatureBits |= KCF_SSE42;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_X2APIC) Prcb->CpuId.FeatureBits |= KCF_X2APIC;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_POPCNT) Prcb->CpuId.FeatureBits |= KCF_POPCNT;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TSC_DEADLINE) Prcb->CpuId.FeatureBits |= KCF_TSC_DEADLINE;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AES) Prcb->CpuId.FeatureBits |= KCF_AES;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_XSAVE) Prcb->CpuId.FeatureBits |= KCF_XSAVE;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_AVX) Prcb->CpuId.FeatureBits |= KCF_AVX;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_RDRAND) Prcb->CpuId.FeatureBits |= KCF_RDRAND;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_VME) Prcb->CpuId.FeatureBits |= KCF_VME;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE) Prcb->CpuId.FeatureBits |= KCF_LARGE_PAGE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSC) Prcb->CpuId.FeatureBits |= KCF_RDTSC;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) Prcb->CpuId.FeatureBits |= KCF_PAE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCE) Prcb->CpuId.FeatureBits |= KCF_MCE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CX8) Prcb->CpuId.FeatureBits |= KCF_CMPXCHG8B;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC) Prcb->CpuId.FeatureBits |= KCF_APIC;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SEP) Prcb->CpuId.FeatureBits |= KCF_FAST_SYSCALL;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MTRR) Prcb->CpuId.FeatureBits |= KCF_MTRR;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) Prcb->CpuId.FeatureBits |= KCF_GLOBAL_PAGE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MCA) Prcb->CpuId.FeatureBits |= KCF_MCA;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CMOV) Prcb->CpuId.FeatureBits |= KCF_CMOV;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PAT) Prcb->CpuId.FeatureBits |= KCF_PAT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PSE36) Prcb->CpuId.FeatureBits |= KCF_PSE36;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_CLFLUSH) Prcb->CpuId.FeatureBits |= KCF_CLFLUSH;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_FXSR) Prcb->CpuId.FeatureBits |= KCF_FXSR;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_ACPI) Prcb->CpuId.FeatureBits |= KCF_ACPI;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_MMX) Prcb->CpuId.FeatureBits |= KCF_MMX;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE) Prcb->CpuId.FeatureBits |= KCF_SSE;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SSE2) Prcb->CpuId.FeatureBits |= KCF_SSE2;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_HTT) Prcb->CpuId.FeatureBits |= KCF_SMT;\n    }\n\n    /* Check if CPU supports standard7 features leaf */\n    if(MaxStandardLeaf >= CPUID_GET_STANDARD7_FEATURES)\n    {\n        /* Get CPU standard features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU standard7 features in processor control block */\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_AVX2) Prcb->CpuId.FeatureBits |= KCF_AVX2;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMEP) Prcb->CpuId.FeatureBits |= KCF_SMEP;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_RDSEED) Prcb->CpuId.FeatureBits |= KCF_RDSEED;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SMAP) Prcb->CpuId.FeatureBits |= KCF_SMAP;\n        if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_SHA) Prcb->CpuId.FeatureBits |= KCF_SHA;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) Prcb->CpuId.FeatureBits |= KCF_LA57;\n    }\n\n    /* Check if CPU supports power management leaf */\n    if(MaxStandardLeaf >= CPUID_GET_POWER_MANAGEMENT)\n    {\n        /* Get CPU power management features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU power management features in processor control block */\n        if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;\n    }\n\n    /* Check if CPU supports extended features leaf */\n    if(MaxExtendedLeaf >= CPUID_GET_EXTENDED_FEATURES)\n    {\n        /* Get CPU extended features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU extended features in processor control block */\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE4A) Prcb->CpuId.ExtendedFeatureBits |= KCF_SSE4A;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_FMA4) Prcb->CpuId.ExtendedFeatureBits |= KCF_FMA4;\n        if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_TOPOLOGY_EXTENSIONS) Prcb->CpuId.ExtendedFeatureBits |= KCF_TOPOEXT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_SYSCALL_SYSRET) Prcb->CpuId.ExtendedFeatureBits |= KCF_SYSCALL;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_NX) Prcb->CpuId.ExtendedFeatureBits |= KCF_NX_BIT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_RDTSCP) Prcb->CpuId.ExtendedFeatureBits |= KCF_RDTSCP;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_LONG_MODE) Prcb->CpuId.ExtendedFeatureBits |= KCF_64BIT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW_EXT) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW_EXT;\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_3DNOW) Prcb->CpuId.ExtendedFeatureBits |= KCF_3DNOW;\n    }\n\n    /* Check if CPU supports advanced power management leaf */\n    if(MaxExtendedLeaf >= CPUID_GET_ADVANCED_POWER_MANAGEMENT)\n    {\n        /* Get CPU advanced power management features */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Store CPU advanced power management features in processor control block */\n        if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;\n    }\n}\n\n/**\n * Initializes the kernel's Global Descriptor Table (GDT).\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block to use.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)\n{\n    /* Initialize GDT entries */\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, I686_LDT, KGDT_DPL_SYSTEM, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);\n    SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);\n}\n\n/**\n * Initializes the kernel's Interrupt Descriptor Table (IDT).\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block to use.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)\n{\n    UINT Vector;\n\n    /* Fill in all vectors */\n    for(Vector = 0; Vector < IDT_ENTRIES; Vector++)\n    {\n        /* Set the IDT to handle unexpected interrupts */\n        SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector],\n                   KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    }\n\n    /* Setup IDT handlers for known interrupts and traps */\n    SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TASK_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrapEntry[0x2A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrapEntry[0x2B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);\n    SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrapEntry[0x2E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_INTERRUPT_GATE);\n}\n\n\n/**\n * Initializes i686 processor specific structures.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeProcessor(IN PVOID ProcessorStructures)\n{\n    KDESCRIPTOR GdtDescriptor, IdtDescriptor;\n    PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;\n    PKPROCESSOR_BLOCK ProcessorBlock;\n    PKGDTENTRY Gdt;\n    PKIDTENTRY Idt;\n    PKTSS Tss;\n\n    /* Check if processor structures buffer provided */\n    if(ProcessorStructures)\n    {\n        /* Assign CPU structures from provided buffer */\n        InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,\n                                      &KernelBootStack, &KernelFaultStack, &KernelNmiStack);\n\n        /* Use global IDT */\n        Idt = InitialIdt;\n    }\n    else\n    {\n        /* Use initial structures */\n        Gdt = InitialGdt;\n        Idt = InitialIdt;\n        Tss = &InitialTss;\n        KernelBootStack = (PVOID)((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE);\n        KernelFaultStack = (PVOID)((ULONG_PTR)&FaultStack + KERNEL_STACK_SIZE);\n        KernelNmiStack = (PVOID)((ULONG_PTR)&NmiStack + KERNEL_STACK_SIZE);\n        ProcessorBlock = &InitialProcessorBlock;\n    }\n\n    /* Initialize processor block */\n    InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);\n\n    /* Initialize GDT, IDT and TSS */\n    InitializeGdt(ProcessorBlock);\n    InitializeIdt(ProcessorBlock);\n    InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);\n\n    /* Set GDT and IDT descriptors */\n    GdtDescriptor.Base = Gdt;\n    GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;\n    IdtDescriptor.Base = Idt;\n    IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;\n\n    /* Load GDT, IDT and TSS */\n    AR::CpuFunctions::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);\n    AR::CpuFunctions::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);\n    AR::CpuFunctions::LoadTaskRegister((UINT)KGDT_SYS_TSS);\n\n    /* Initialize segment registers */\n    InitializeSegments();\n\n    /* Initialize processor registers */\n    InitializeProcessorRegisters();\n\n    /* Identify processor */\n    IdentifyProcessor();\n}\n\n/**\n * Initializes processor block.\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block to initialize.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT for this processor block.\n *\n * @param Idt\n *        Supplies a pointer to the IDT for this processor block.\n *\n * @param Tss\n *        Supplies a pointer to the TSS for this processor block.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,\n                                               IN PKGDTENTRY Gdt,\n                                               IN PKIDTENTRY Idt,\n                                               IN PKTSS Tss,\n                                               IN PVOID DpcStack)\n{\n    /* Set processor block and processor control block */\n    ProcessorBlock->Self = ProcessorBlock;\n    ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;\n\n    /* Set GDT, IDT and TSS descriptors */\n    ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;\n    ProcessorBlock->IdtBase = Idt;\n    ProcessorBlock->TssBase = Tss;\n\n    /* Setup DPC stack */\n    ProcessorBlock->Prcb.DpcStack = DpcStack;\n\n    /* Setup processor control block */\n    ProcessorBlock->Prcb.CpuNumber = ProcessorBlock->CpuNumber;\n    ProcessorBlock->Prcb.SetMember = 1 << ProcessorBlock->CpuNumber;\n    ProcessorBlock->Prcb.MultiThreadProcessorSet = 1 << ProcessorBlock->CpuNumber;\n\n    /* Clear DR6 and DR7 registers */\n    ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0;\n    ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;\n\n    /* Set process and thread information */\n    ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;\n    ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock;\n    ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;\n    ProcessorBlock->Prcb.NextThread = NULLPTR;\n\n    /* Set initial runlevel */\n    ProcessorBlock->RunLevel = PASSIVE_LEVEL;\n}\n\n/**\n * Initializes processor registers and other boot structures.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeProcessorRegisters(VOID)\n{\n    /* Clear EFLAGS register */\n    AR::CpuFunctions::WriteEflagsRegister(0);\n\n    /* Enable write-protection */\n    AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_WP);\n}\n\n/**\n * Initializes i686 processor specific structures with provided memory buffer.\n *\n * @param ProcessorStructures\n *        Supplies a pointer to the allocated buffer with processor structures.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT.\n *\n * @param Tss\n *        Supplies a pointer to the TSS.\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block.\n *\n * @param KernelBootStack\n *        Supplies a pointer to the kernel boot stack.\n *\n * @param KernelFaultStack\n *        Supplies a pointer to the kernel fault stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeProcessorStructures(IN PVOID ProcessorStructures,\n                                                    OUT PKGDTENTRY *Gdt,\n                                                    OUT PKTSS *Tss,\n                                                    OUT PKPROCESSOR_BLOCK *ProcessorBlock,\n                                                    OUT PVOID *KernelBootStack,\n                                                    OUT PVOID *KernelFaultStack,\n                                                    OUT PVOID *KernelNmiStack)\n{\n    UINT_PTR Address;\n\n    /* Align address to page size boundary and move to kernel boot stack */\n    Address = ROUND_UP((UINT_PTR)ProcessorStructures, MM_PAGE_SIZE) + KERNEL_STACK_SIZE;\n\n    /* Assign a space for kernel boot stack and advance */\n    if(KernelBootStack != NULLPTR)\n    {\n        /* Return kernel boot stack address */\n        *KernelBootStack = (PVOID)Address;\n    }\n    Address += KERNEL_STACK_SIZE;\n\n    /* Assign a space for kernel fault stack and advance */\n    if(KernelFaultStack != NULLPTR)\n    {\n        /* Return kernel fault stack address */\n        *KernelFaultStack = (PVOID)Address;\n    }\n    Address += KERNEL_STACK_SIZE;\n\n    /* Assign a space for kernel NMI stack, no advance needed as stack grows down */\n    if(KernelNmiStack != NULLPTR)\n    {\n        /* Return kernel NMI stack address */\n        *KernelNmiStack = (PVOID)Address;\n    }\n\n    /* Assign a space for GDT and advance */\n    if(Gdt != NULLPTR)\n    {\n        /* Return GDT base address */\n        *Gdt = (PKGDTENTRY)(PVOID)Address;\n    }\n    Address += (GDT_ENTRIES * sizeof(KGDTENTRY));\n\n    /* Assign a space for TSS and advance */\n    if(Tss != NULLPTR)\n    {\n        *Tss = (PKTSS)(PVOID)Address;\n    }\n    Address += sizeof(KTSS);\n\n    /* Assign a space for Processor Block and advance */\n    if(ProcessorBlock != NULLPTR)\n    {\n        /* Return processor block address */\n        *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;\n    }\n}\n\n/**\n * Initializes segment registers.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeSegments(VOID)\n{\n    /* Initialize segments */\n    AR::CpuFunctions::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);\n    AR::CpuFunctions::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);\n    AR::CpuFunctions::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);\n    AR::CpuFunctions::LoadSegment(SEGMENT_FS, KGDT_R0_PB);\n    AR::CpuFunctions::LoadSegment(SEGMENT_GS, 0);\n    AR::CpuFunctions::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);\n}\n\n/**\n * Initializes the kernel's Task State Segment (TSS).\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block to use.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,\n                                    IN PVOID KernelBootStack,\n                                    IN PVOID KernelFaultStack,\n                                    IN PVOID KernelNmiStack)\n{\n    PKGDTENTRY TssEntry;\n\n    /* Setup System TSS entry in Global Descriptor Table */\n    TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_SYS_TSS / sizeof(KGDTENTRY)]));\n    TssEntry->LimitLow = sizeof(KTSS) - 1;\n    TssEntry->Bits.LimitHigh = 0;\n    TssEntry->Bits.Dpl = 0;\n    TssEntry->Bits.Present = 1;\n    TssEntry->Bits.Type = I686_TSS;\n\n    /* Clear I/O map */\n    RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);\n\n    /* Fill Interrupt Direction Maps with zeroes */\n    RtlZeroMemory(ProcessorBlock->TssBase->IoMaps[0].DirectionMap, IOPM_DIRECTION_MAP_SIZE);\n\n    /* Enable DPMI support */\n    ProcessorBlock->TssBase->IoMaps[0].DirectionMap[0] = 4;\n    ProcessorBlock->TssBase->IoMaps[0].DirectionMap[3] = 0x18;\n    ProcessorBlock->TssBase->IoMaps[0].DirectionMap[4] = 0x18;\n\n    /* Fill default Interrupt Direction Map with zeroes */\n    RtlZeroMemory(ProcessorBlock->TssBase->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE);\n\n    /* Enable DPMI support */\n    ProcessorBlock->TssBase->IntDirectionMap[0] = 4;\n    ProcessorBlock->TssBase->IntDirectionMap[3] = 0x18;\n    ProcessorBlock->TssBase->IntDirectionMap[4] = 0x18;\n\n    /* Set I/O map base and disable traps */\n    ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS);\n    ProcessorBlock->TssBase->Flags = 0;\n\n    /* Set CR3, LDT and SS */\n    ProcessorBlock->TssBase->CR3 = AR::CpuFunctions::ReadControlRegister(3);\n    ProcessorBlock->TssBase->LDT = 0;\n    ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;\n\n    /* Initialize task gates for DoubleFault and NMI traps */\n    SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);\n    SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelNmiStack);\n}\n\n/**\n * Initializes the DoubleFault TSS entry in the Global Descriptor Table.\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block to use.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,\n                                             IN PVOID KernelFaultStack)\n{\n    PKGDTENTRY TaskGateEntry, TssEntry;\n    PKTSS Tss;\n\n    /* Setup task gate for DoubleFault trap */\n    TaskGateEntry = (PKGDTENTRY)&ProcessorBlock->IdtBase[8];\n    TaskGateEntry->Bits.Dpl = 0;\n    TaskGateEntry->Bits.Present = 1;\n    TaskGateEntry->Bits.Type = I686_TASK_GATE;\n    ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;\n\n    /* Initialize DoubleFault TSS and set initial state */\n    Tss = (PKTSS)DoubleFaultTss;\n    Tss->IoMapBase = sizeof(KTSS);\n    Tss->Flags = 0;\n    Tss->LDT = 0;\n    Tss->CR3 = AR::CpuFunctions::ReadControlRegister(3);\n    Tss->Esp = (ULONG_PTR)KernelFaultStack;\n    Tss->Esp0 = (ULONG_PTR)KernelFaultStack;\n    Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x08];\n    Tss->Cs = KGDT_R0_CODE;\n    Tss->Ds = KGDT_R3_DATA | RPL_MASK;\n    Tss->Es = KGDT_R3_DATA | RPL_MASK;\n    Tss->Fs = KGDT_R0_PB;\n    Tss->Ss = KGDT_R0_DATA;\n    Tss->Ss0 = KGDT_R0_DATA;\n\n    /* Setup DoubleFault TSS entry in Global Descriptor Table */\n    TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));\n    TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);\n    TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);\n    TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);\n    TssEntry->LimitLow = 0x68;\n    TssEntry->Bits.LimitHigh = 0;\n    TssEntry->Bits.Dpl = 0;\n    TssEntry->Bits.Present = 1;\n    TssEntry->Bits.Type = I686_TSS;\n}\n\n/**\n * Fills in an i686 GDT entry.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT.\n *\n * @param Selector\n *        Specifies a segment selector of the GDT entry.\n *\n * @param Base\n *        Specifies a base address value of the descriptor.\n *\n * @param Limit\n *        Specifies a descriptor limit.\n *\n * @param Type\n *        Specifies a type of the descriptor.\n *\n * @param Dpl\n *        Specifies the descriptor privilege level.\n *\n * @param SegmentMode\n *        Specifies a segment mode of the descriptor.\n *\n * @return This routine does not return any value\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::SetGdtEntry(IN PKGDTENTRY Gdt,\n                                  IN USHORT Selector,\n                                  IN ULONG_PTR Base,\n                                  IN ULONG Limit,\n                                  IN UCHAR Type,\n                                  IN UCHAR Dpl,\n                                  IN UCHAR SegmentMode)\n{\n    PKGDTENTRY GdtEntry;\n    UCHAR Granularity;\n\n    /* Set the granularity flag depending on descriptor limit */\n    if(Limit < 0x100000)\n    {\n        /* Limit is in 1B blocks */\n        Granularity = 0;\n    }\n    else\n    {\n        /* Limit is in 4KB blocks */\n        Granularity = 1;\n        Limit >>= 12;\n    }\n\n    /* Get GDT entry */\n    GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));\n\n    /* Set GDT descriptor base */\n    GdtEntry->BaseLow = (Base & 0xFFFF);\n    GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);\n    GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);\n\n    /* Set descriptor limit */\n    GdtEntry->LimitLow = (Limit & 0xFFFF);\n    GdtEntry->Bits.LimitHigh = ((Limit >> 16) & 0xF);\n\n    /* Initialize GDT entry */\n    GdtEntry->Bits.DefaultBig = !!(SegmentMode & 2);\n    GdtEntry->Bits.Dpl = (Dpl & 0x3);\n    GdtEntry->Bits.Granularity = Granularity;\n    GdtEntry->Bits.Reserved0 = 0;\n    GdtEntry->Bits.Present = (Type != 0);\n    GdtEntry->Bits.System = 0;\n    GdtEntry->Bits.Type = (Type & 0x1F);\n}\n\n/**\n * Updates an existing i686 GDT entry with new base address.\n *\n * @param Gdt\n *        Supplies a pointer to the GDT.\n *\n * @param Selector\n *        Specifies a segment selector of the GDT entry.\n *\n * @param Base\n *        Specifies a base address value of the descriptor.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::SetGdtEntryBase(IN PKGDTENTRY Gdt,\n                                      IN USHORT Selector,\n                                      IN ULONG_PTR Base)\n{\n    PKGDTENTRY GdtEntry;\n\n    /* Get GDT entry */\n    GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));\n\n    /* Set new GDT descriptor base */\n    GdtEntry->BaseLow = (Base & 0xFFFF);\n    GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);\n    GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);\n}\n\n/**\n * Fills in a call, interrupt, task or trap gate entry.\n *\n * @param Idt\n *        Supplies a pointer to IDT structure, where gate is located.\n *\n * @param Vector\n *        Supplies a gate vector pointing to the interrupt gate in the IDT\n *\n * @param Handler\n *        Supplies a pointer to the interrupt handler of the specified gate.\n *\n * @param Selector\n *        Supplies the code selector the gate should run in.\n *\n * @param Ist\n *        Supplies the interrupt stack table entry the gate should run in.\n *\n * @param Access\n *        Supplies the gate access rights.\n *\n * @param Type\n *        Supplies the gate type.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::SetIdtGate(IN PKIDTENTRY Idt,\n                                 IN USHORT Vector,\n                                 IN PVOID Handler,\n                                 IN USHORT Selector,\n                                 IN USHORT Ist,\n                                 IN USHORT Dpl,\n                                 IN USHORT Type)\n{\n    /* Set the handler's address */\n    Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);\n    Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);\n\n    /* Set the code segment selector */\n    Idt[Vector].Selector = Selector;\n\n    /* Initialize the gate's attributes and flags */\n    Idt[Vector].Access = 0;\n    Idt[Vector].Dpl = Dpl;\n    Idt[Vector].Present = 1;\n    Idt[Vector].Type = Type;\n}\n\n/**\n * Initializes the Non-Maskable Interrupt TSS entry in the Global Descriptor Table.\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block to use.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nAR::ProcessorSupport::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,\n                                                      IN PVOID KernelNmiStack)\n{\n    PKGDTENTRY TaskGateEntry, TssEntry;\n    PKTSS Tss;\n\n    /* Setup task gate for NMI */\n    TaskGateEntry = (PKGDTENTRY)&ProcessorBlock->IdtBase[2];\n    TaskGateEntry->Bits.Dpl = 0;\n    TaskGateEntry->Bits.Present = 1;\n    TaskGateEntry->Bits.Type = I686_TASK_GATE;\n    ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;\n\n    /* Initialize NMI TSS and set initial state */\n    Tss = (PKTSS)NonMaskableInterruptTss;\n    Tss->IoMapBase = sizeof(KTSS);\n    Tss->Flags = 0;\n    Tss->LDT = 0;\n    Tss->CR3 = AR::CpuFunctions::ReadControlRegister(3);\n    Tss->Esp = (ULONG_PTR)KernelNmiStack;\n    Tss->Esp0 = (ULONG_PTR)KernelNmiStack;\n    Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02];\n    Tss->Cs = KGDT_R0_CODE;\n    Tss->Ds = KGDT_R3_DATA | RPL_MASK;\n    Tss->Es = KGDT_R3_DATA | RPL_MASK;\n    Tss->Fs = KGDT_R0_PB;\n    Tss->Ss = KGDT_R0_DATA;\n    Tss->Ss0 = KGDT_R0_DATA;\n\n    /* Setup NMI TSS entry in Global Descriptor Table */\n    TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));\n    TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF);\n    TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16);\n    TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24);\n    TssEntry->LimitLow = 0x68;\n    TssEntry->Bits.LimitHigh = 0;\n    TssEntry->Bits.Dpl = 0;\n    TssEntry->Bits.Present = 1;\n    TssEntry->Bits.Type = I686_TSS;\n}\n"
  },
  {
    "path": "xtoskrnl/ar/i686/traps.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ar/i686/traps.cc\n * DESCRIPTION:     I686 system traps\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Dispatches the interrupt provided by common interrupt handler.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common interrupt handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    PINTERRUPT_HANDLER Handler;\n\n    /* Read the handler pointer from the CPU's interrupt dispatch table */\n    Handler = (PINTERRUPT_HANDLER)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +\n                                                                   (TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));\n\n    /* Check if the interrupt has a handler registered */\n    if(Handler != NULLPTR)\n    {\n        /* Call the handler */\n        Handler(TrapFrame);\n    }\n    else if(UnhandledInterruptRoutine != NULLPTR)\n    {\n        /* Call the unhandled interrupt routine */\n        UnhandledInterruptRoutine(TrapFrame);\n    }\n    else\n    {\n        /* Dispatcher not initialized, print a debug message */\n        DebugPrint(L\"ERROR: Caught unhandled interrupt: 0x%.2lX\\n\", TrapFrame->Vector);\n    }\n}\n\n/**\n * Dispatches the trap provided by common trap handler.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Caught trap: 0x%.2lX with error code: %.4lX at EIP: 0x%.8lX\\n\"\n               L\"EAX: 0x%.8lX, EBX: 0x%.8lX, ECX: 0x%.8lX, EDX: 0x%.8lX\\n\"\n               L\"EBP: 0x%.8lX, ESP: 0x%.8lX, EDI: 0x%.8lX, ESI: 0x%.8lX\\n\"\n               L\"DR0: 0x%.8lX, DR1: 0x%.8lX, DR2: 0x%.8lX, DR3: 0x%.8lX\\n\"\n               L\"DR6: 0x%.8lX, DR7: 0x%.8lX\\n\"\n               L\"CR2: 0x%.8lX, CR3: 0x%.8lX, CS:  0x%.8lX, DS:  0x%.8hX\\n\"\n               L\"ES:  0x%.8hX, FS:  0x%.8hX, GS:  0x%.8hX, SS:  0x%.8lX\\n\",\n               TrapFrame->Vector, TrapFrame->ErrorCode, TrapFrame->Eip,\n               TrapFrame->Eax, TrapFrame->Ebx, TrapFrame->Ecx, TrapFrame->Edx,\n               TrapFrame->Ebp, TrapFrame->Esp, TrapFrame->Edi, TrapFrame->Esi,\n               TrapFrame->Dr0, TrapFrame->Dr1, TrapFrame->Dr2, TrapFrame->Dr3,\n               TrapFrame->Dr6, TrapFrame->Dr7,\n               TrapFrame->Cr2, TrapFrame->Cr3, TrapFrame->SegCs, TrapFrame->SegDs,\n               TrapFrame->SegEs, TrapFrame->SegFs, TrapFrame->SegGs, TrapFrame->SegSs);\n\n    /* Check vector and call appropriate handler */\n    switch(TrapFrame->Vector)\n    {\n        case 0x00:\n            /* Divide By Zero exception */\n            HandleTrap00(TrapFrame);\n            break;\n        case 0x01:\n            /* Debug exception */\n            HandleTrap01(TrapFrame);\n            break;\n        case 0x02:\n            /* Non-Maskable Interrupt (NMI) */\n            HandleTrap02(TrapFrame);\n            break;\n        case 0x03:\n            /* INT3 instruction executed */\n            HandleTrap03(TrapFrame);\n            break;\n        case 0x04:\n            /* Overflow exception */\n            HandleTrap04(TrapFrame);\n            break;\n        case 0x05:\n            /* Bound Range Exceeded exception */\n            HandleTrap05(TrapFrame);\n            break;\n        case 0x06:\n            /* Invalid Opcode exception */\n            HandleTrap06(TrapFrame);\n            break;\n        case 0x07:\n            /* Device Not Available exception */\n            HandleTrap07(TrapFrame);\n            break;\n        case 0x08:\n            /* Double Fault exception */\n            HandleTrap08(TrapFrame);\n            break;\n        case 0x09:\n            /* Segment Overrun exception */\n            HandleTrap09(TrapFrame);\n            break;\n        case 0x0A:\n            /* Invalid TSS exception */\n            HandleTrap0A(TrapFrame);\n            break;\n        case 0x0B:\n            /* Segment Not Present exception */\n            HandleTrap0B(TrapFrame);\n            break;\n        case 0x0C:\n            /* Stack Segment Fault exception */\n            HandleTrap0C(TrapFrame);\n            break;\n        case 0x0D:\n            /* General Protection Fault (GPF) exception*/\n            HandleTrap0D(TrapFrame);\n            break;\n        case 0x0E:\n            /* Page Fault exception */\n            HandleTrap0E(TrapFrame);\n            break;\n        case 0x10:\n            /* X87 Floating-Point exception */\n            HandleTrap10(TrapFrame);\n            break;\n        case 0x11:\n            /* Alignment Check exception */\n            HandleTrap11(TrapFrame);\n            break;\n        case 0x12:\n            /* Machine Check exception */\n            HandleTrap12(TrapFrame);\n            break;\n        case 0x13:\n            /* SIMD Floating-Point exception */\n            HandleTrap13(TrapFrame);\n            break;\n        case 0x2A:\n            /* Tick Count service request */\n            HandleTrap2A(TrapFrame);\n            break;\n        case 0x2B:\n            /* User-mode callback return */\n            HandleTrap2B(TrapFrame);\n            break;\n        case 0x2C:\n            /* Assertion raised */\n            HandleTrap2C(TrapFrame);\n            break;\n        case 0x2D:\n            /* Debug-Service-Request raised */\n            HandleTrap2D(TrapFrame);\n            break;\n        case 0x2E:\n            /* System call service request */\n            HandleTrap2E(TrapFrame);\n            break;\n        default:\n            /* Unknown/Unexpected trap */\n            HandleTrapFF(TrapFrame);\n            break;\n    }\n}\n\n/**\n * Handles the trap 0x00 when a Divide By Zero exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Division-By-Zero Error (0x00)!\\n\");\n    KE::Crash::Panic(0x00);\n}\n\n/**\n * Handles the trap 0x01 when Debug exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Debug exception (0x01)!\\n\");\n    KE::Crash::Panic(0x01);\n}\n\n/**\n * Handles the trap 0x02 when Non-Maskable Interrupt (NMI) occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Non-Maskable-Interrupt (0x02)!\\n\");\n}\n\n/**\n * Handles the trap 0x03 when the INT3 instruction is executed.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled INT3 (0x03)!\\n\");\n    KE::Crash::Panic(0x03);\n}\n\n/**\n * Handles the trap 0x04 when the INTO instruction is executed and overflow bit is set.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Overflow exception (0x04)!\\n\");\n    KE::Crash::Panic(0x04);\n}\n\n/**\n * Handles the trap 0x05 when the Bound Range Exceeded exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Bound-Range-Exceeded exception (0x05)!\\n\");\n    KE::Crash::Panic(0x05);\n}\n\n/**\n * Handles the trap 0x06 when the Invalid Opcode exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Invalid Opcode exception (0x06)!\\n\");\n    KE::Crash::Panic(0x06);\n}\n\n/**\n * Handles the trap 0x07 when the Device Not Available exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Device Not Available exception (0x07)!\\n\");\n    KE::Crash::Panic(0x07);\n}\n\n/**\n * Handles the trap 0x08 when Double Fault exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Double-Fault exception (0x08)!\\n\");\n    KE::Crash::Panic(0x08);\n}\n\n/**\n * Handles the trap 0x09 when the Segment Overrun exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Segment-Overrun exception (0x09)!\\n\");\n    KE::Crash::Panic(0x09);\n}\n\n/**\n * Handles the trap 0x0A when the Invalid TSS exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Invalid-TSS exception (0x0A)!\\n\");\n    KE::Crash::Panic(0x0A);\n}\n\n/**\n * Handles the trap 0x0B when the Segment Not Present exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Segment-Not-Present exception (0x0B)!\\n\");\n    KE::Crash::Panic(0x0B);\n}\n\n/**\n * Handles the trap 0x0C when the Stack Segment Fault exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Stack-Segment-Fault exception (0x0C)!\\n\");\n    KE::Crash::Panic(0x0C);\n}\n\n/**\n * Handles the trap 0x0D when General Protection Fault (GPF) exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled General-Protection-Fault (0x0D)!\\n\");\n    KE::Crash::Panic(0x0D);\n}\n\n/**\n * Handles the trap 0x0E when the Page Fault (PF) exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Page-Fault exception (0x0E)!\\n\");\n    KE::Crash::Panic(0x0E);\n}\n\n/**\n * Handles the trap 0x10 when the X87 Floating-Point exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled x87 Floating-Point exception (0x10)!\\n\");\n    KE::Crash::Panic(0x10);\n}\n\n/**\n * Handles the trap 0x11 when the Alignment Check exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Alignment-Check exception (0x11)!\\n\");\n    KE::Crash::Panic(0x11);\n}\n\n/**\n * Handles the trap 0x12 when the Machine Check exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Machine-Check exception (0x12)!\\n\");\n    KE::Crash::Panic(0x12);\n}\n\n/**\n * Handles the trap 0x13 when the SIMD Floating-Point exception occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled SIMD Floating-Point exception (0x13)!\\n\");\n    KE::Crash::Panic(0x13);\n}\n\n/**\n * Handles the trap 0x2A when Tick Count service request occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap2A(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Unhandled Tick Count service request (0x2A)!\\n\");\n}\n\n/**\n * Handles the trap 0x2B when Callback return service request occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap2B(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Unhandled Callback return service request (0x2B)!\\n\");\n}\n\n/**\n * Handles the trap 0x2C when an assertion is raised.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Assertion (0x2C)!\\n\");\n    KE::Crash::Panic(0x2C);\n}\n\n/**\n * Handles the trap 0x2D when a debug service is being requested.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Debug-Service-Request (0x2D)!\\n\");\n    KE::Crash::Panic(0x2D);\n}\n\n/**\n * Handles the trap 0x2E when a system call is being requested.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrap2E(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Unhandled system call (0x2E)!\\n\");\n}\n\n/**\n * Handles the trap 0xFF then Unexpected Interrupt occurs.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common trap handler on the stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)\n{\n    DebugPrint(L\"Handled Unexpected-Interrupt (0xFF)!\\n\");\n    KE::Crash::Panic(0xFF);\n}\n\n/**\n * Sets the unhandled interrupt routine used for vectors that have no handler registered.\n *\n * @param Handler\n *        Supplies the pointer to the interrupt handler routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nAR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)\n{\n    /* Set the unhandled interrupt routine */\n    UnhandledInterruptRoutine = Handler;\n}\n"
  },
  {
    "path": "xtoskrnl/ex/exports.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ex/exports.cc\n * DESCRIPTION:     C-compatible API wrappers for exported kernel functions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Acquires the rundown protection for given descriptor.\n *\n * @param Descriptor\n *        Supplies a pointer to the rundown block descriptor.\n *\n * @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.\n *\n * @since NT 5.1\n */\nXTFASTCALL\nBOOLEAN\nExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    return EX::Rundown::AcquireProtection(Descriptor);\n}\n\n/**\n * Marks the rundown descriptor as completed.\n *\n * @param Descriptor\n *        Supplies a pointer to the descriptor to be completed.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTFASTCALL\nVOID\nExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    EX::Rundown::CompleteProtection(Descriptor);\n}\n\n/**\n * Initializes the rundown protection descriptor.\n *\n * @param Descriptor\n *        Supplies a pointer to the descriptor to be initialized.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTFASTCALL\nVOID\nExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    EX::Rundown::InitializeProtection(Descriptor);\n}\n\n/**\n * Reinitializes the rundown protection structure after it has been completed.\n *\n * @param Descriptor\n *        Supplies a pointer to the descriptor to be reinitialized.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTFASTCALL\nVOID\nExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    EX::Rundown::ReInitializeProtection(Descriptor);\n}\n\n/**\n * Releases the rundown protection for given descriptor.\n *\n * @param Descriptor\n *        Supplies a pointer to the descriptor to be initialized.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTFASTCALL\nVOID\nExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    EX::Rundown::ReleaseProtection(Descriptor);\n}\n\n/**\n * Waits until rundown protection calls are completed.\n *\n * @param Descriptor\n *        Supplies a pointer to the rundown block descriptor.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTFASTCALL\nVOID\nExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    EX::Rundown::WaitForProtectionRelease(Descriptor);\n}\n"
  },
  {
    "path": "xtoskrnl/ex/rundown.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ex/rundown.cc\n * DESCRIPTION:     Rundown protection mechanism\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Acquires the rundown protection for given descriptor.\n *\n * @param Descriptor\n *        Supplies a pointer to the rundown block descriptor.\n *\n * @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nEX::Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    ULONG_PTR CurrentValue, NewValue;\n\n    /* Get current value */\n    CurrentValue = Descriptor->Count;\n\n    /* Main loop execution */\n    while(TRUE)\n    {\n        /* Make sure protection is not active yet */\n        if(CurrentValue & 0x1)\n        {\n            /* Already active, nothing to do */\n            return FALSE;\n        }\n\n        /* Attempt to increment the usage count */\n        NewValue = CurrentValue + 2;\n\n        /* Exchange the value */\n        NewValue = (ULONG_PTR)RTL::Atomic::CompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue,\n                                                                  (PVOID)CurrentValue);\n\n        /* Make sure protection acquired */\n        if(NewValue == CurrentValue)\n        {\n            /* Successfully acquired protection */\n            return TRUE;\n        }\n\n        /* Update value and try once again */\n        CurrentValue = NewValue;\n    }\n}\n\n/**\n * Marks the rundown descriptor as completed.\n *\n * @param Descriptor\n *        Supplies a pointer to the descriptor to be completed.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nEX::Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    RTL::Atomic::ExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE);\n}\n\n/**\n * Initializes the rundown protection descriptor.\n *\n * @param Descriptor\n *        Supplies a pointer to the descriptor to be initialized.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nEX::Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    /* Reset descriptor counter */\n    Descriptor->Count = 0;\n}\n\n/**\n * Reinitializes the rundown protection structure after it has been completed.\n *\n * @param Descriptor\n *        Supplies a pointer to the descriptor to be reinitialized.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nEX::Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    RTL::Atomic::ExchangePointer(&Descriptor->Ptr, NULLPTR);\n}\n\n/**\n * Releases the rundown protection for given descriptor.\n *\n * @param Descriptor\n *        Supplies a pointer to the descriptor to be initialized.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nEX::Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    ULONG_PTR CurrentValue, NewValue;\n    PEX_RUNDOWN_WAIT_BLOCK WaitBlock;\n\n    CurrentValue = Descriptor->Count;\n\n    while(TRUE)\n    {\n        if(CurrentValue & 0x1)\n        {\n            WaitBlock = (PEX_RUNDOWN_WAIT_BLOCK)(CurrentValue & ~0x1);\n\n            if(!RTL::Atomic::Decrement64((PLONG_PTR)&WaitBlock->Count))\n            {\n                KE::Event::SetEvent(&WaitBlock->WakeEvent, 0, FALSE);\n            }\n\n            break;\n        }\n        else\n        {\n            /* Attempt to decrement the usage count */\n            NewValue = CurrentValue - 2;\n\n            /* Exchange the value */\n            NewValue = (ULONG_PTR)RTL::Atomic::CompareExchangePointer(&Descriptor->Ptr, (PVOID)NewValue,\n                                                                      (PVOID)CurrentValue);\n\n            if(NewValue == CurrentValue)\n            {\n                break;\n            }\n\n            CurrentValue = NewValue;\n        }\n    }\n}\n\n/**\n * Waits until rundown protection calls are completed.\n *\n * @param Descriptor\n *        Supplies a pointer to the rundown block descriptor.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nEX::Rundown::WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)\n{\n    UNIMPLEMENTED;\n}\n"
  },
  {
    "path": "xtoskrnl/hl/acpi.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/x86/acpi.cc\n * DESCRIPTION:     Advanced Configuration and Power Interface (ACPI) support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Stores given ACPI table in the kernel local cache.\n *\n * @param AcpiTable\n *        Supplies a pointer to ACPI table that will be stored in the cache.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)\n{\n    PACPI_CACHE_LIST AcpiCache;\n\n    /* Check if there are free slots in static early-boot cache array */\n    if(CacheCount >= ACPI_MAX_CACHED_TABLES)\n    {\n        /* Cache is full, the table is mapped but not cached */\n        return;\n    }\n\n    /* Get the next available static cache entry */\n    AcpiCache = &CacheEntries[CacheCount];\n    CacheCount++;\n\n    /* Store the pointer to the mapped ACPI table */\n    AcpiCache->Table = AcpiTable;\n\n    /* Insert entry into the global ACPI cache list */\n    RTL::LinkedList::InsertTailList(&CacheList, &AcpiCache->ListEntry);\n}\n\n/**\n * Gets a pointer to the ACPI system description pointer (RSDP).\n *\n * @param Rsdp\n *        Supplies a pointer to the memory area, where RSDP virtual address will be stored.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::GetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp)\n{\n    /* Get RSDP and return success */\n    *Rsdp = RsdpStructure;\n    return STATUS_SUCCESS;\n}\n\n/**\n * Gets an ACPI description table with given signature, available in the XSDT/RSDT.\n *\n * @param Signature\n *        Supplies the signature of the desired ACPI table.\n *\n * @param AcpiTable\n *        Supplies a pointer to memory area where ACPI table virtual address will be stored.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::GetAcpiTable(IN ULONG Signature,\n                       OUT PACPI_DESCRIPTION_HEADER *AcpiTable)\n{\n    PACPI_DESCRIPTION_HEADER Table;\n    XTSTATUS Status;\n\n    /* Assume ACPI table not found */\n    *AcpiTable = NULLPTR;\n\n    /* Attempt to get ACPI table from the cache */\n    Status = QueryAcpiCache(Signature, &Table);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Table not found in the cache, query ACPI tables */\n        Status = QueryAcpiTables(Signature, &Table);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* ACPI table not found, return error */\n            return STATUS_NOT_FOUND;\n        }\n    }\n\n    /* Store ACPI table and return success */\n    *AcpiTable = Table;\n    return STATUS_SUCCESS;\n}\n\n/**\n * Retrieves the ACPI timer information.\n *\n * @param AcpiTimerInfo\n *        Supplies a pointer to memory area, where ACPI timer information will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Acpi::GetAcpiTimerInfo(OUT PACPI_TIMER_INFO *AcpiTimerInfo)\n{\n    /* Check if ACPI timer info is available */\n    if(AcpiTimerInfo)\n    {\n        /* Return ACPI timer info */\n        *AcpiTimerInfo = &TimerInfo;\n    }\n}\n\n/**\n * Gets the ACPI system information structure containing processor and topology data.\n *\n * @param SystemInfo\n *        Supplies a pointer to the memory area where the pointer to the system information structure will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Acpi::GetSystemInformation(OUT PACPI_SYSTEM_INFO *SystemInfo)\n{\n    /* Return a pointer to the ACPI system information */\n    *SystemInfo = &HL::Acpi::SystemInfo;\n}\n\n/**\n * Performs an initialization of the ACPI subsystem.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::InitializeAcpi(VOID)\n{\n    PACPI_FADT Fadt;\n    XTSTATUS Status;\n\n    /* Initialize ACPI cache */\n    Status = InitializeAcpiCache();\n    if(Status != STATUS_SUCCESS)\n    {\n        /* ACPI cache initialization failed, return error */\n        return Status;\n    }\n\n    /* Get Fixed ACPI Description Table (FADT) */\n    Status = GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt);\n    if(Status != STATUS_SUCCESS || !Fadt)\n    {\n        /* Failed to get FADT, return error */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Initialize ACPI timer */\n    InitializeAcpiTimer();\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes the kernel's local ACPI cache storage.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::InitializeAcpiCache(VOID)\n{\n    PACPI_DESCRIPTION_HEADER Rsdt;\n    XTSTATUS Status;\n\n    /* Initialize ACPI cache list */\n    RTL::LinkedList::InitializeListHead(&CacheList);\n\n    /* Get XSDT/RSDT */\n    Status = InitializeAcpiSystemDescriptionTable(&Rsdt);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to get XSDT/RSDT, return error */\n        return Status;\n    }\n\n    /* Cache XSDT/RSDT table */\n    CacheAcpiTable(Rsdt);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes ACPI System Description Table (XSDT/RSDT) by finding proper table and mapping its virtual address.\n *\n * @param AcpiTable\n *        Supplies a pointer to memory area where ACPI table virtual address will be stored.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable)\n{\n    PHYSICAL_ADDRESS RsdpAddress, RsdtAddress;\n    PSYSTEM_RESOURCE_HEADER ResourceHeader;\n    PSYSTEM_RESOURCE_ACPI AcpiResource;\n    ULONG RsdtPages;\n    PACPI_RSDT Rsdt;\n    XTSTATUS Status;\n\n    /* Assume ACPI table not found */\n    *AcpiTable = NULLPTR;\n\n    /* Get ACPI system resource */\n    Status = KeGetSystemResource(SystemResourceAcpi, &ResourceHeader);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Resource not found */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Cast system resource to ACPI resource and store RSDP physical address */\n    AcpiResource = (PSYSTEM_RESOURCE_ACPI)ResourceHeader;\n    RsdpAddress.QuadPart = (LONGLONG)AcpiResource->Header.PhysicalAddress;\n\n    /* Map RSDP using hardware memory pool */\n    Status = MM::HardwarePool::MapHardwareMemory(RsdpAddress, 1, TRUE, (PVOID *)&RsdpStructure);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to map RSDP, return error */\n        return Status;\n    }\n\n    /* Mark RSDP as CD/WT to avoid delays in write-back cache */\n    MM::HardwarePool::MarkHardwareMemoryWriteThrough(RsdpStructure, 1);\n\n    /* Validate RSDP signature */\n    if(RsdpStructure->Signature != ACPI_RSDP_SIGNATURE)\n    {\n        /* Invalid RSDP signature, unmap and return error */\n        MM::HardwarePool::UnmapHardwareMemory(RsdpStructure, 1, TRUE);\n        RsdpStructure = NULLPTR;\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Check RSDP revision to determine RSDT/XSDT address */\n    if(RsdpStructure->Revision >= 2)\n    {\n        /* Get XSDT address */\n        RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->XsdtAddress;\n    }\n    else\n    {\n        /* Get RSDT address */\n        RsdtAddress.QuadPart = (LONGLONG)RsdpStructure->RsdtAddress;\n    }\n\n    /* Map RSDT/XSDT using hardware memory pool */\n    Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, 2, TRUE, (PVOID *)&Rsdt);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to map RSDT/XSDT, return error */\n        return Status;\n    }\n\n    /* Mark RSDT/XSDT as CD/WT */\n    MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, 2);\n\n    /* Validate RSDT/XSDT signature */\n    if(Rsdt->Header.Signature != ACPI_RSDT_SIGNATURE && Rsdt->Header.Signature != ACPI_XSDT_SIGNATURE)\n    {\n        /* Not mapped correctly or invalid RSDT/XSDT signature, unmap and return error */\n        MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Calculate the length of all available ACPI tables and remap it if needed */\n    RsdtPages = (((RsdtAddress.LowPart & (MM_PAGE_SIZE - 1)) + Rsdt->Header.Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);\n    if(RsdtPages != 2)\n    {\n        /* RSDT/XSDT needs less or more than 2 pages, remap it */\n        MM::HardwarePool::UnmapHardwareMemory(Rsdt, 2, TRUE);\n        Status = MM::HardwarePool::MapHardwareMemory(RsdtAddress, RsdtPages, TRUE, (PVOID *)&Rsdt);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Remapping failed, return error */\n            return STATUS_INSUFFICIENT_RESOURCES;\n        }\n\n        /* Mark remapped RSDT/XSDT as CD/WT */\n        MM::HardwarePool::MarkHardwareMemoryWriteThrough(Rsdt, RsdtPages);\n    }\n\n    /* Get ACPI table header and return success */\n    *AcpiTable = &Rsdt->Header;\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes System Information structure based on the ACPI provided data.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::InitializeAcpiSystemInformation(VOID)\n{\n    PACPI_MADT_LOCAL_X2APIC LocalX2Apic;\n    PACPI_MADT_LOCAL_APIC LocalApic;\n    PACPI_SUBTABLE_HEADER SubTable;\n    ULONG_PTR MadtTable;\n    PACPI_MADT Madt;\n    XTSTATUS Status;\n    USHORT CpuCount;\n\n    /* Allocate memory for ACPI system information structure */\n    Status = InitializeAcpiSystemStructure();\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to allocate memory, return error */\n        return STATUS_INSUFFICIENT_RESOURCES;\n    }\n\n    /* Get Multiple APIC Description Table (MADT) */\n    Status = GetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to get MADT, return error */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Set APIC table traverse pointer and initialize number of CPUs */\n    MadtTable = (ULONG_PTR)Madt->ApicTables;\n    CpuCount = 0;\n\n    /* Traverse all MADT tables to get system information */\n    while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))\n    {\n        /* Get current MADT subtable header */\n        SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;\n\n        /* Prevent infinite loops if BIOS provides 0 length */\n        if(SubTable->Length == 0)\n        {\n            /* Broken ACPI table, abort traversal */\n            break;\n        }\n\n        /* Check if this is a local APIC subtable */\n        if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC))\n        {\n            /* Get local APIC subtable */\n            LocalApic = (PACPI_MADT_LOCAL_APIC)MadtTable;\n\n            /* Make sure, this CPU can be enabled */\n            if(LocalApic->Flags & ACPI_MADT_PLAOC_ENABLED)\n            {\n                /* Store CPU number, APIC ID and CPU ID */\n                SystemInfo.CpuInfo[CpuCount].AcpiId = LocalApic->AcpiId;\n                SystemInfo.CpuInfo[CpuCount].ApicId = LocalApic->ApicId;\n                SystemInfo.CpuInfo[CpuCount].CpuNumber = CpuCount;\n\n                /* Increment number of CPUs */\n                CpuCount++;\n            }\n        }\n        else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC))\n        {\n            /* Get local X2APIC subtable */\n            LocalX2Apic = (PACPI_MADT_LOCAL_X2APIC)MadtTable;\n\n            /* Make sure, this CPU can be enabled */\n            if(LocalX2Apic->Flags & ACPI_MADT_PLAOC_ENABLED)\n            {\n                /* Store CPU number, APIC ID and CPU ID */\n                SystemInfo.CpuInfo[CpuCount].AcpiId = LocalX2Apic->AcpiId;\n                SystemInfo.CpuInfo[CpuCount].ApicId = LocalX2Apic->ApicId;\n                SystemInfo.CpuInfo[CpuCount].CpuNumber = CpuCount;\n\n                /* Increment number of CPUs */\n                CpuCount++;\n            }\n        }\n\n        /* Safely advance pointer using proper subtable length */\n        MadtTable += SubTable->Length;\n    }\n\n    /* Store number of CPUs */\n    SystemInfo.CpuCount = CpuCount;\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes ACPI System Information data structure based on the size of available ACPI data.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::InitializeAcpiSystemStructure(VOID)\n{\n    PHYSICAL_ADDRESS PhysicalAddress;\n    PACPI_SUBTABLE_HEADER SubTable;\n    PFN_NUMBER PageCount;\n    ULONG_PTR MadtTable;\n    PACPI_MADT Madt;\n    XTSTATUS Status;\n    ULONG CpuCount;\n\n    /* Get Multiple APIC Description Table (MADT) */\n    Status = GetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to get MADT, return error */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Set APIC table traverse pointer and initialize number of CPUs */\n    MadtTable = (ULONG_PTR)Madt->ApicTables;\n    CpuCount = 0;\n\n    /* Traverse all MADT tables to get number of processors */\n    while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))\n    {\n        SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;\n\n        /* Prevent infinite loops if BIOS provides 0 length */\n        if(SubTable->Length == 0)\n        {\n            /* Broken ACPI table, abort traversal */\n            break;\n        }\n\n        /* Check if this is a local APIC subtable */\n        if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_APIC))\n        {\n            /* Make sure, this CPU can be enabled */\n            if(((PACPI_MADT_LOCAL_APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)\n            {\n                /* Increment number of CPUs */\n                CpuCount++;\n            }\n        }\n        else if(SubTable->Type == ACPI_MADT_TYPE_LOCAL_X2APIC && SubTable->Length >= sizeof(ACPI_MADT_LOCAL_X2APIC))\n        {\n            /* Make sure, this CPU can be enabled */\n            if(((PACPI_MADT_LOCAL_X2APIC)MadtTable)->Flags & ACPI_MADT_PLAOC_ENABLED)\n            {\n                /* Increment number of CPUs */\n                CpuCount++;\n            }\n        }\n\n        /* Safely advance pointer using proper subtable length */\n        MadtTable += SubTable->Length;\n    }\n\n    /* Zero the ACPI system information structure */\n    RTL::Memory::ZeroMemory(&SystemInfo, sizeof(ACPI_SYSTEM_INFO));\n\n    /* Calculate number of pages needed to store CPU information */\n    PageCount = SIZE_TO_PAGES(CpuCount * sizeof(PROCESSOR_IDENTITY));\n\n    /* Allocate memory for CPU information */\n    Status = MM::HardwarePool::AllocateHardwareMemory(PageCount, TRUE, MM_MAXIMUM_PHYSICAL_ADDRESS, &PhysicalAddress);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to allocate memory, return error */\n        return Status;\n    }\n\n    /* Map physical address to the virtual memory area */\n    Status = MM::HardwarePool::MapHardwareMemory(PhysicalAddress, PageCount, TRUE, (PVOID *)&SystemInfo.CpuInfo);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to map memory, return error */\n        return Status;\n    }\n\n    /* Zero the CPU information structure */\n    RTL::Memory::ZeroMemory(SystemInfo.CpuInfo, PAGES_TO_SIZE(PageCount));\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes the ACPI Timer.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::InitializeAcpiTimer(VOID)\n{\n    PACPI_FADT Fadt;\n    XTSTATUS Status;\n\n    /* Get Fixed ACPI Description Table (FADT) */\n    Status = GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt);\n    if(Status != STATUS_SUCCESS || !Fadt)\n    {\n        /* Failed to get FADT, return error */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Set ACPI timer port address */\n    TimerInfo.TimerPort = Fadt->PmTmrBlkIoPort;\n\n    /* Determine whether 32-bit or 24-bit timer is used */\n    if(Fadt->Flags & ACPI_FADT_32BIT_TIMER)\n    {\n        /* 32-bit timer */\n        TimerInfo.MsbMask = ACPI_FADT_TIMER_32BIT;\n    }\n    else\n    {\n        /* 24-bit timer */\n        TimerInfo.MsbMask = ACPI_FADT_TIMER_24BIT;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Queries kernel local ACPI cache in attempt to find a requested ACPI table.\n *\n * @param Signature\n *        Supplies the signature of the desired ACPI table.\n *\n * @param AcpiTable\n *        Supplies a pointer to memory area where ACPI table virtual address will be stored.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::QueryAcpiCache(IN ULONG Signature,\n                         OUT PACPI_DESCRIPTION_HEADER *AcpiTable)\n{\n    PACPI_DESCRIPTION_HEADER TableHeader;\n    PACPI_CACHE_LIST AcpiCache;\n    PLIST_ENTRY ListEntry;\n\n    /* Initialize variables */\n    TableHeader = NULLPTR;\n\n    /* Iterate through ACPI tables cache list */\n    ListEntry = CacheList.Flink;\n    while(ListEntry != &CacheList)\n    {\n        /* Get cached ACPI table header */\n        AcpiCache = CONTAIN_RECORD(ListEntry, ACPI_CACHE_LIST, ListEntry);\n\n        /* Check if ACPI table signature matches */\n        if(AcpiCache->Table->Signature == Signature)\n        {\n            /* ACPI table found in cache, return it */\n            TableHeader = AcpiCache->Table;\n            break;\n        }\n\n        /* Go to the next cache entry */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Check if the requested ACPI table was found in the cache */\n    if(TableHeader == NULLPTR)\n    {\n        /* ACPI table not found in cache, return error */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Return table header and status code */\n    *AcpiTable = TableHeader;\n    return STATUS_SUCCESS;\n}\n\n/**\n * Queries XSDT/RSDT in order to find a requested ACPI table.\n * Once the desired ACPI table is found, it is being mapped and cached.\n *\n * @param Signature\n *        Supplies the signature of the desired ACPI table.\n *\n * @param AcpiTable\n *        Supplies a pointer to memory area where ACPI table virtual address will be stored.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Acpi::QueryAcpiTables(IN ULONG Signature,\n                          OUT PACPI_DESCRIPTION_HEADER *AcpiTable)\n{\n    ULONG TableCount, TableIndex, TablePages;\n    PACPI_DESCRIPTION_HEADER TableHeader;\n    PHYSICAL_ADDRESS TableAddress;\n    PACPI_FADT Fadt;\n    PACPI_RSDT Rsdt;\n    PACPI_XSDT Xsdt;\n    XTSTATUS Status;\n\n    /* Check if requesting a valid ACPI table */\n    if(Signature == ACPI_RSDT_SIGNATURE || Signature == ACPI_XSDT_SIGNATURE)\n    {\n        /* Cannot provide RSDP/XSDP table, it should be cached; return error */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Ensure that table header is not set before attempting to find ACPI table */\n    TableHeader = NULLPTR;\n\n    /* Check if DSDT or FACS table requested */\n    if(Signature == ACPI_DSDT_SIGNATURE || Signature == ACPI_FACS_SIGNATURE)\n    {\n        /* Get FADT as it contains a pointer to DSDT and FACS */\n        Status = GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Fadt);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to get FADT, return error */\n            return Status;\n        }\n\n        /* Check if DSDT or FACS table requested */\n        if(Signature == ACPI_DSDT_SIGNATURE)\n        {\n            /* Prefer 64-bit address on ACPI 2.0+ */\n            if(Fadt->Header.Revision >= 2 && Fadt->XDsdt.QuadPart != 0)\n            {\n                TableAddress.QuadPart = Fadt->XDsdt.QuadPart;\n            }\n            else\n            {\n                TableAddress.LowPart = Fadt->Dsdt;\n                TableAddress.HighPart = 0;\n            }\n        }\n        else\n        {\n            /* Prefer 64-bit address on ACPI 2.0+ */\n            if(Fadt->Header.Revision >= 2 && Fadt->XFirmwareCtrl.QuadPart != 0)\n            {\n                TableAddress.QuadPart = Fadt->XFirmwareCtrl.QuadPart;\n            }\n            else\n            {\n                TableAddress.LowPart = Fadt->FirmwareCtrl;\n                TableAddress.HighPart = 0;\n            }\n        }\n\n        /* Map table using hardware memory pool */\n        Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to map table, return error */\n            return Status;\n        }\n    }\n    else\n    {\n        /* Query cache for XSDT table */\n        Status = QueryAcpiCache(ACPI_XSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Xsdt);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* XSDT not found, query cache for RSDT table */\n            Xsdt = NULLPTR;\n            Status = QueryAcpiCache(ACPI_RSDT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Rsdt);\n        }\n\n        /* Check if XSDT or RSDT table found */\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to get XSDT/RSDT, return error */\n            return Status;\n        }\n\n        /* Get table count depending on root table type securely */\n        if(Xsdt != NULLPTR)\n        {\n            if(Xsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER;\n            TableCount = (Xsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8;\n        }\n        else\n        {\n            if(Rsdt->Header.Length < sizeof(ACPI_DESCRIPTION_HEADER)) return STATUS_INVALID_PARAMETER;\n            TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4;\n        }\n\n        /* Iterate over all ACPI tables */\n        for(TableIndex = 0; TableIndex < TableCount; TableIndex++)\n        {\n            /* Check if XSDT or RSDT is used */\n            if(Xsdt != NULLPTR)\n            {\n                /* Get table header physical address from XSDT */\n                TableAddress.QuadPart = Xsdt->Tables[TableIndex];\n            }\n            else\n            {\n                /* Get table header physical address from RSDT */\n                TableAddress.LowPart = Rsdt->Tables[TableIndex];\n                TableAddress.HighPart = 0;\n            }\n\n            /* Map table using hardware memory pool */\n            Status = MM::HardwarePool::MapHardwareMemory(TableAddress, 2, TRUE, (PVOID*)&TableHeader);\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to map table, return error */\n                return Status;\n            }\n\n            /* Verify table signature */\n            if(TableHeader->Signature == Signature)\n            {\n                /* Found requested ACPI table */\n                break;\n            }\n\n            /* Unmap non-matching table and try next one */\n            MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);\n            TableHeader = NULLPTR;\n        }\n    }\n\n    /* Ensure the table was actually found and mapped */\n    if(TableHeader == NULLPTR)\n    {\n        /* ACPI table not found, return error */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Check if we broke out of the loop with the wrong table (safety check) */\n    if(TableHeader->Signature != Signature)\n    {\n        /* Unmap non-matching ACPI table and return error */\n        MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Don't validate FACS and FADT on old, broken firmwares with ACPI 2.0 or older */\n    if((TableHeader->Signature != ACPI_FADT_SIGNATURE || TableHeader->Revision > 2) &&\n       (TableHeader->Signature != ACPI_FACS_SIGNATURE))\n    {\n        /* Validate table checksum */\n        if(!ValidateAcpiTable(TableHeader, TableHeader->Length))\n        {\n            /* Checksum mismatch, unmap table and return error */\n            MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, TRUE);\n            return STATUS_CRC_ERROR;\n        }\n    }\n\n    /* Calculate the length of ACPI table and remap it if needed */\n    TablePages = (((TableAddress.LowPart & (MM_PAGE_SIZE - 1)) + TableHeader->Length + (MM_PAGE_SIZE - 1)) >> MM_PAGE_SHIFT);\n    if(TablePages != 2)\n    {\n        /* ACPI table needs less or more than 2 pages, remap it */\n        MM::HardwarePool::UnmapHardwareMemory(TableHeader, 2, FALSE);\n        Status = MM::HardwarePool::MapHardwareMemory(TableAddress, TablePages, TRUE, (PVOID*)&TableHeader);\n\n        /* Make sure remapping was successful */\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Remapping failed, return error */\n            return STATUS_INSUFFICIENT_RESOURCES;\n        }\n    }\n\n    /* Mark table as write through and store it in local cache */\n    MM::HardwarePool::MarkHardwareMemoryWriteThrough(TableHeader, TablePages);\n    CacheAcpiTable(TableHeader);\n\n    /* Store ACPI table and return success */\n    *AcpiTable = TableHeader;\n    return STATUS_SUCCESS;\n}\n\n/**\n * Validates given ACPI table by calculating its checksum.\n *\n * @param Buffer\n *        Supplies a pointer to the table to checksum.\n *\n * @param Size\n *        Supplies the size of the table, in bytes.\n *\n * @return This routine returns TRUE if the table is valid, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nHL::Acpi::ValidateAcpiTable(IN PVOID Buffer,\n                            IN UINT_PTR Size)\n{\n    PUCHAR Pointer;\n    UCHAR Sum;\n\n    /* Initialize variables */\n    Sum = 0;\n    Pointer = (PUCHAR)Buffer;\n\n    /* Calculate checksum of given table */\n    while(Size != 0)\n    {\n        Sum = (UCHAR)(Sum + *Pointer);\n        Pointer += 1;\n        Size -= 1;\n    }\n\n    /* Return calculated checksum */\n    return (Sum == 0) ? TRUE : FALSE;\n}\n"
  },
  {
    "path": "xtoskrnl/hl/amd64/cpu.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/amd64/cpu.cc\n * DESCRIPTION:     HAL AMD64 processor support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* Include common CPU interface */\n#include ARCH_COMMON(cpu.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/amd64/firmware.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/amd64/firmware.cc\n * DESCRIPTION:     UEFI/BIOS Firmware support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Include common Firmware interface */\n#include ARCH_COMMON(firmware.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/amd64/ioport.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/amd64/ioport.cc\n * DESCRIPTION:     I/O port access routines for AMD64 platform\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Reads the 8-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return This routine returns the value read from the port.\n *\n * @since XT 1.0\n */\nXTCDECL\nUCHAR\nHL::IoPort::ReadPort8(IN USHORT Port)\n{\n    UCHAR Value;\n    __asm__ volatile(\"inb %1, %0\"\n                     : \"=a\" (Value)\n                     : \"Nd\" (Port));\n    return Value;\n}\n\n/**\n * Reads the 16-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return This routine returns the value read from the port.\n *\n * @since XT 1.0\n */\nXTCDECL\nUSHORT\nHL::IoPort::ReadPort16(IN USHORT Port)\n{\n    USHORT Value;\n    __asm__ volatile(\"inw %1, %0\"\n                     : \"=a\" (Value)\n                     : \"Nd\" (Port));\n    return Value;\n}\n\n/**\n * Reads the 32-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return This routine returns the value read from the port.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG\nHL::IoPort::ReadPort32(IN USHORT Port)\n{\n    ULONG Value;\n    __asm__ volatile(\"inl %1, %0\"\n                     : \"=a\" (Value)\n                     : \"Nd\" (Port));\n    return Value;\n}\n\n/**\n * Writes the 8-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::IoPort::WritePort8(IN USHORT Port,\n                       IN UCHAR Value)\n{\n    __asm__ volatile(\"outb %0, %1\"\n                     :\n                     : \"a\" (Value),\n                       \"Nd\" (Port));\n}\n\n/**\n * Writes the 16-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::IoPort::WritePort16(IN USHORT Port,\n                        IN USHORT Value)\n{\n    __asm__ volatile(\"outw %0, %1\"\n                     :\n                     : \"a\" (Value),\n                       \"Nd\" (Port));\n}\n\n/**\n * Writes the 32-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::IoPort::WritePort32(IN USHORT Port,\n                        IN ULONG Value)\n{\n    __asm__ volatile(\"outl %0, %1\"\n                     :\n                     : \"a\" (Value),\n                       \"Nd\" (Port));\n}\n"
  },
  {
    "path": "xtoskrnl/hl/amd64/irq.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/amd64/irq.cc\n * DESCRIPTION:     Interrupts support for AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Begins a system interrupt handler by raising the processor's run level and re-enabling\n * hardware interrupts to allow preemption by higher-priority events.\n *\n * @param RunLevel\n *        Supplies the target run level to raise the processor to.\n *\n * @param OldRunLevel\n *        Receives the previous run level before the elevation.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,\n                              OUT PKRUNLEVEL OldRunLevel)\n{\n    /* Get the current IRQL */\n    *OldRunLevel = KE::RunLevel::GetCurrentRunLevel();\n\n    /* Raise run level */\n    KE::RunLevel::RaiseRunLevel(RunLevel);\n\n    /* Enable interrupts */\n    AR::CpuFunctions::SetInterruptFlag();\n}\n\n/**\n * Safely concludes an interrupt handler by disabling hardware interrupts.\n *\n * @param TrapFrame\n *        Supplies a pointer to the kernel trap frame containing the interrupted execution state.\n *\n * @param OldRunLevel\n *        Supplies the previous run level to restore.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,\n                      IN KRUNLEVEL OldRunLevel)\n{\n    /* Disable interrupts */\n    AR::CpuFunctions::ClearInterruptFlag();\n\n    /* End system interrupt */\n    EndSystemInterrupt(TrapFrame, OldRunLevel);\n}\n\n/**\n * Concludes a system interrupt by sending an End of Interrupt (EOI) to the hardware\n * controller and restoring the processor's previous run level.\n *\n * @param TrapFrame\n *        Supplies a pointer to the kernel trap frame containing the interrupted execution state.\n *\n * @param OldRunLevel\n *        Supplies the previous run level to restore.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame,\n                            IN KRUNLEVEL OldRunLevel)\n{\n    /* Send EOI */\n    HL::Pic::SendEoi();\n\n    /* Restore previous run level */\n    KE::RunLevel::LowerRunLevel(OldRunLevel);\n}\n\n/**\n * Handles profiling interrupt.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common interrupt handler.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    /* Send EOI */\n    HL::Pic::SendEoi();\n}\n\n/**\n * Handles unexpected or unmapped system interrupts.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common interrupt handler.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    UNIMPLEMENTED;\n\n    /* Disable interrupts */\n    AR::CpuFunctions::ClearInterruptFlag();\n\n    /* Print debug message and raise kernel panic */\n    DebugPrint(L\"ERROR: Caught unexpected interrupt (0x%.2llX)!\\n\", TrapFrame->Vector);\n    KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);\n}\n\n/**\n * Returns the registered interrupt handler for the specified IDT vector.\n *\n * @param Vector\n *        Supplies the interrupt vector number.\n *\n * @return This routine returns the pointer to the IDT interrupt handler routine.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nHL::Irq::QueryInterruptHandler(IN ULONG Vector)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n    PKIDTENTRY IdtEntry;\n\n    /* Get current processor block and IDT entry */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n    IdtEntry = &ProcessorBlock->IdtBase[Vector];\n\n    /* Return address of the interrupt handler */\n    return (PVOID)((ULONGLONG)IdtEntry->OffsetHigh << 32 |\n                   (ULONGLONG)IdtEntry->OffsetMiddle << 16 |\n                   (ULONGLONG)IdtEntry->OffsetLow);\n}\n\n/**\n * Returns the registered interrupt handler for the specified vector.\n *\n * @param Vector\n *        Supplies the interrupt vector number.\n *\n * @return This routine returns the pointer to the interrupt handler routine.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nHL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];\n}\n\n/**\n * Registers new interrupt handler for the existing IDT entry.\n *\n * @param HalVector\n *        Supplies the interrupt vector number.\n *\n * @param Handler\n *        Supplies the pointer to the interrupt handler routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::RegisterInterruptHandler(IN ULONG Vector,\n                                  IN PVOID Handler)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    /* Update interrupt handler */\n    AR::ProcessorSupport::SetIdtGate(ProcessorBlock->IdtBase,\n                                     Vector,\n                                     Handler,\n                                     KGDT_R0_CODE,\n                                     0,\n                                     KIDT_ACCESS_RING0,\n                                     AMD64_INTERRUPT_GATE);\n}\n\n/**\n * Registers the interrupt handler for the specified vector.\n *\n * @param HalVector\n *        Supplies the interrupt vector number.\n *\n * @param Handler\n *        Supplies the pointer to the interrupt handler routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,\n                                        IN PINTERRUPT_HANDLER Handler)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    /* Update interrupt handler in the processor's interrupt dispatch table */\n    ProcessorBlock->InterruptDispatchTable[Vector] = Handler;\n}\n\n/**\n * Requests a software interrupt by sending a Self-IPI mapped to the specified run level.\n *\n * @param RunLevel\n *        Supplies the target run level for the software interrupt.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nHL::Irq::SendSoftwareInterrupt(IN KRUNLEVEL RunLevel)\n{\n    /* Request a software interrupt */\n    HL::Pic::SendSelfIpi(HL::RunLevel::TransformRunLevelToSoftwareVector(RunLevel));\n}\n"
  },
  {
    "path": "xtoskrnl/hl/amd64/pic.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/amd64/pic.cc\n * DESCRIPTION:     Programmable Interrupt Controller (PIC) for AMD64 support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* Include common PIC interface */\n#include ARCH_COMMON(pic.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/amd64/rtc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/amd64/rtc.cc\n * DESCRIPTION:     Hardware Real-Time Clock (RTC) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Include common RTC interface */\n#include ARCH_COMMON(rtc.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/amd64/runlevel.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/amd64/runlevel.cc\n * DESCRIPTION:     Run Level management support for AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Gets the current run level from APIC for the current processor.\n *\n * @return This routine returns the current run level.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nKRUNLEVEL\nHL::RunLevel::GetRunLevel(VOID)\n{\n    /* Read current run level */\n    return (KRUNLEVEL)AR::CpuFunctions::ReadControlRegister(8);\n}\n\n/**\n * Sets new run level for the current processor.\n *\n * @param RunLevel\n *        Supplies the new run level to store into APIC.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nHL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)\n{\n    /* Set new run level */\n    AR::CpuFunctions::WriteControlRegister(8, RunLevel);\n}\n\n/**\n * Maps APIC interrupt vector to XT run level.\n *\n * @param Tpr\n *        Supplies the interrupt vector rad from APIC Task Priority Register.\n *\n * @return This routine returns the XT run level corresponding to the specified APIC interrupt vector.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nKRUNLEVEL\nHL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr)\n{\n    /* Transform APIC TPR to run level */\n    return (KRUNLEVEL)(Tpr >> 4);\n}\n\n/**\n * Maps XT run level to interrupt vector suitable for the APIC Task Priority Register.\n *\n * @param RunLevel\n *        Supplies the XT run level.\n *\n * @return This routine returns the APIC interrupt vector corresponding to the specified XT run level.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nUCHAR\nHL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel)\n{\n    /* Transform run level to APIC TPR */\n    return (RunLevel << 4);\n}\n\n/**\n * Transforms a given execution run level into a corresponding hardware interrupt vector\n * suitable for software interrupts.\n *\n * @param RunLevel\n *        Supplies the run level to be translated into a software interrupt vector.\n *\n * @return This routine returns the 8-bit APIC vector corresponding to the requested software interrupt level.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nUCHAR\nHL::RunLevel::TransformRunLevelToSoftwareVector(IN KRUNLEVEL RunLevel)\n{\n    /* Transform run level to APIC interrupt vector */\n    return TransformRunLevelToApicTpr(RunLevel) | 0xF;\n}\n"
  },
  {
    "path": "xtoskrnl/hl/amd64/timer.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/amd64/timer.cc\n * DESCRIPTION:     Timer support for AMD64\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Include common Timer interface */\n#include ARCH_COMMON(timer.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/cport.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/cport.cc\n * DESCRIPTION:     Serial (COM) port support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * This routine gets a byte from serial port.\n *\n * @param Port\n *        Address of port object describing a port settings.\n *\n * @param Byte\n *        Address of variable where to store the result.\n *\n * @param Wait\n *        Specifies whether to wait for a data or not.\n *\n * @param Poll\n *        Indicates whether to only poll, not reading the data.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nHL::ComPort::ReadComPort(IN PCPPORT Port,\n                         OUT PUCHAR Byte,\n                         IN BOOLEAN Wait,\n                         IN BOOLEAN Poll)\n{\n    UCHAR Lsr;\n    ULONG Retry;\n\n    /* Make sure the port has been initialized */\n    if(Port->Address == 0)\n    {\n        return STATUS_DEVICE_NOT_READY;\n    }\n\n    /* Retry getting data if allowed to wait */\n    Retry = Wait ? COMPORT_WAIT_TIMEOUT : 1;\n    while(Retry--)\n    {\n        /* Get LSR for data ready */\n        Lsr = ReadComPortLsr(Port, COMPORT_LSR_DR);\n        if((Lsr & COMPORT_LSR_DR) == COMPORT_LSR_DR)\n        {\n            /* Check for errors */\n            if(Lsr & (COMPORT_LSR_FE | COMPORT_LSR_OE | COMPORT_LSR_PE))\n            {\n                /* Framing, parity or overrun error occurred */\n                *Byte = 0;\n                return STATUS_IO_DEVICE_ERROR;\n            }\n\n            /* Check if only polling */\n            if(Poll)\n            {\n                /* Only polling, return success */\n                return STATUS_SUCCESS;\n            }\n\n            /* Read the byte from serial port */\n            *Byte = HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_RBR));\n\n            /* Check if in modem control mode */\n            if(Port->Flags & COMPORT_FLAG_MC)\n            {\n                /* Handle Carrier Detected (CD) */\n                if((HL::IoPort::ReadPort8(PtrToShort(Port->Address + (ULONG)COMPORT_REG_MSR)) & COMPORT_MSR_DCD) == 0)\n                {\n                    /* Skip byte if no CD present */\n                    continue;\n                }\n            }\n            return STATUS_SUCCESS;\n        }\n    }\n\n    /* Reset LSR and return that no data found */\n    ReadComPortLsr(Port, 0);\n    return STATUS_NOT_FOUND;\n}\n\n/**\n * Reads LSR from specified serial port.\n *\n * @param Port\n *        Address of COM port.\n *\n * @param Byte\n *        Value expected from the port.\n *\n * @return This routine returns a byte read from COM port.\n *\n * @since XT 1.0\n */\nXTCDECL\nUCHAR\nHL::ComPort::ReadComPortLsr(IN PCPPORT Port,\n                            IN UCHAR Byte)\n{\n    UCHAR Lsr, Msr;\n\n    /* Read the Line Status Register (LSR) */\n    Lsr = HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_LSR));\n\n    /* Check if expected byte is present */\n    if((Lsr & Byte) == 0)\n    {\n        /* Check Modem Status Register (MSR) for ring indicator */\n        Msr = HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR));\n        Port->Ring |= (Msr & COMPORT_MSR_RI) ? 1 : 2;\n        if(Port->Ring == 3)\n        {\n            /* Ring indicator toggled, use modem control */\n            Port->Flags |= COMPORT_FLAG_MC;\n        }\n    }\n\n    /* Return byte read */\n    return Lsr;\n}\n\n/**\n * This routine initializes the COM port.\n *\n * @param Port\n *        Address of port object describing a port settings.\n *\n * @param PortNumber\n *        Supplies a port number.\n *\n * @param PortAddress\n *        Supplies an address of the COM port.\n *\n * @param BaudRate\n *        Supplies an optional port baud rate.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nHL::ComPort::InitializeComPort(IN OUT PCPPORT Port,\n                               IN PUCHAR PortAddress,\n                               IN ULONG BaudRate)\n{\n    USHORT Flags;\n    UCHAR Byte;\n    ULONG Mode;\n\n    /* Initialize variables */\n    Byte = 0;\n    Flags = 0;\n\n    /* Check if baud rate is set */\n    if(BaudRate == 0)\n    {\n        /* Use default baud (clock) rate if not set */\n        BaudRate = COMPORT_CLOCK_RATE;\n        Flags |= COMPORT_FLAG_DBR;\n    }\n\n    /* Check whether this port is not already initialized */\n    if((Port->Address == PortAddress) && (Port->Baud == BaudRate))\n    {\n        return STATUS_SUCCESS;\n    }\n\n    /* Test if chosen COM port exists */\n    do\n    {\n        /* Check whether the 16450/16550 scratch register exists */\n        HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_SR), Byte);\n        if(HL::IoPort::ReadPort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_SR)) != Byte)\n        {\n            return STATUS_NOT_FOUND;\n        }\n    }\n    while(++Byte != 0);\n\n    /* Disable interrupts */\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), COMPORT_LSR_DIS);\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_IER), COMPORT_LSR_DIS);\n\n    /* Enable Divisor Latch Access Bit (DLAB) */\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR), COMPORT_LCR_DLAB);\n\n    /* Set baud rate */\n    Mode = COMPORT_CLOCK_RATE / BaudRate;\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_DIV_DLL), (UCHAR)(Mode & 0xFF));\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_DIV_DLM), (UCHAR)((Mode >> 8) & 0xFF));\n\n    /* Set 8 data bits, 1 stop bits, no parity (8n1) */\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_LCR),\n                              COMPORT_LCR_8DATA | COMPORT_LCR_1STOP | COMPORT_LCR_PARN);\n\n    /* Enable DTR, RTS and OUT2 */\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_MCR),\n                              COMPORT_MCR_DTR | COMPORT_MCR_RTS | COMPORT_MCR_OUT2);\n\n    /* Enable FIFO */\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_FCR),\n                              COMPORT_FCR_ENABLE | COMPORT_FCR_RCVR_RESET | COMPORT_FCR_TXMT_RESET);\n\n    /* Mark port as fully initialized */\n    Flags |= COMPORT_FLAG_INIT;\n\n    /* Make sure port works in Normal Operation Mode (NOM) */\n    HL::IoPort::WritePort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_MCR), COMPORT_MCR_NOM);\n\n    /* Read junk data out of the Receive Buffer Register (RBR) */\n    HL::IoPort::ReadPort8(PtrToUshort(PortAddress + (ULONG)COMPORT_REG_RBR));\n\n    /* Store port details */\n    Port->Address = PortAddress;\n    Port->Baud = BaudRate;\n    Port->Flags = Flags;\n    Port->Ring = 0;\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * This routine writes a byte to the serial port.\n *\n * @param Port\n *        Address of port object describing a port settings.\n *\n * @param Byte\n *        Data to be written.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nHL::ComPort::WriteComPort(IN PCPPORT Port,\n                          IN UCHAR Byte)\n{\n    UCHAR Lsr, Msr;\n\n    /* Make sure the port has been initialized */\n    if(Port->Address == 0)\n    {\n        return STATUS_DEVICE_NOT_READY;\n    }\n\n    /* Check if port is in modem control */\n    while(Port->Flags & COMPORT_FLAG_MC)\n    {\n        /* Get the Modem Status Register (MSR) */\n        Msr = HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR)) & COMPORT_MSR_DSRCTSCD;\n        if(Msr != COMPORT_MSR_DSRCTSCD)\n        {\n            /* Take character, if CD is not set */\n            Lsr = ReadComPortLsr(Port, 0);\n            if((Msr & COMPORT_MSR_DCD) == 0 && (Lsr & COMPORT_LSR_DR) == COMPORT_LSR_DR)\n            {\n                /* Eat the character */\n                HL::IoPort::ReadPort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_RBR));\n            }\n        }\n        else\n        {\n            /* CD, CTS and DSR are set, we can continue */\n            break;\n        }\n    }\n\n    /* Wait for busy port */\n    while((ReadComPortLsr(Port, COMPORT_LSR_THRE) & COMPORT_LSR_THRE) == 0);\n\n    /* Send byte to the port */\n    HL::IoPort::WritePort8(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_THR), Byte);\n\n    return STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "xtoskrnl/hl/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/data.cc\n * DESCRIPTION:     Hardware Layer global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* Tracks the total number of currently cached ACPI tables */\nULONG HL::Acpi::CacheCount = 0;\n\n/* Array holding the cached ACPI tables */\nACPI_CACHE_LIST HL::Acpi::CacheEntries[ACPI_MAX_CACHED_TABLES];\n\n/* Head of the linked list tracking dynamically mapped ACPI tables */\nLIST_ENTRY HL::Acpi::CacheList;\n\n/* Pointer to the ACPI Root System Description Pointer (RSDP) */\nPACPI_RSDP HL::Acpi::RsdpStructure;\n\n/* Global architectural system states and hardware feature flags parsed from the ACPI tables */\nACPI_SYSTEM_INFO HL::Acpi::SystemInfo;\n\n/* Hardware configuration details and port addresses for the ACPI Power Management Timer */\nACPI_TIMER_INFO HL::Acpi::TimerInfo;\n\n/* Represents the number of active processors */\nKAFFINITY HL::Cpu::ActiveProcessors;\n\n/* Metadata detailing the linear frame buffer geometry */\nHL_FRAMEBUFFER_DATA HL::FrameBuffer::FrameBufferData;\n\n/* Pointer to the RAM shadow buffer used for double-buffered rendering */\nPVOID HL::FrameBuffer::ScreenShadowBuffer;\n\n/* Tracks the bounding box, dimensions, and cursor position for the kernel video console */\nHL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;\n\n/* Indicates the active hardware interrupt controller mode */\nAPIC_MODE HL::Pic::ApicMode;\n\n/* Total number of I/O APIC chips discovered and initialized */\nULONG HL::Pic::ControllerCount;\n\n/* Array containing MMIO bases, IDs, and line counts for all I/O APICs */\nIOAPIC_DATA HL::Pic::Controllers[IOAPIC_MAX_CONTROLLERS];\n\n/* Total number of legacy ISA interrupt routing overrides */\nULONG HL::Pic::IrqOverrideCount;\n\n/* Hardware routing definitions mapping legacy ISA interrupts to Global System Interrupts (GSI) */\nACPI_MADT_INTERRUPT_OVERRIDE HL::Pic::IrqOverrides[IOAPIC_MAX_OVERRIDES];\n\n/* Lookup table mapping allocated hardware APIC vectors to their assigned Run Levels */\nUCHAR HL::Pic::MappedVectors[256];\n\n/* Accumulated tick value of the ACPI Power Management Timer */\nULONG HL::Timer::AcpiPmPerformanceCounter = 0;\n\n/* Primary hardware timer driving the periodic system clock interrupt */\nTIMER_TYPE HL::Timer::ClockType;\n\n/* Fractional remainder used to maintain long-term system clock accuracy */\nULONG HL::Timer::FractionalIncrement = 0;\n\n/* Virtual address mapped to the HPET hardware MMIO registers */\nPVOID HL::Timer::HpetAddress = NULLPTR;\n\n/* Operating frequency of the High Precision Event Timer in ticks per second */\nULONGLONG HL::Timer::HpetFrequency = 0;\n\n/* Spinlock protecting concurrent multiprocessor access to the global performance counters */\nKSPIN_LOCK HL::Timer::PerformanceCounterLock;\n\n/* The performance counter frequency in ticks per second */\nULONGLONG HL::Timer::PerformanceFrequency = 0;\n\n/* Absolute monotonic tick count driven by the legacy Programmable Interval Timer */\nULONGLONG HL::Timer::PitPerformanceCounter;\n\n/* Programmed hardware divider interval used to increment the PIT performance counter */\nULONG HL::Timer::PitRollover;\n\n/* Flag indicating whether statistical system execution profiling is currently active */\nBOOLEAN HL::Timer::ProfilingEnabled = FALSE;\n\n/* Tick interval required to trigger a profile interrupt */\nULONG HL::Timer::ProfilingTicks;\n\n/* Global accumulator for fractional time drift and precision compensation */\nULONG HL::Timer::RunningFraction = 0;\n\n/* System counter driven by the highest precision available hardware */\nULONGLONG HL::Timer::SystemPerformanceCounter;\n\n/* Current base clock increment in standard 100-nanosecond intervals */\nULONG HL::Timer::TimeIncrement = 0;\n\n/* Timer capabilities */\nTIMER_CAPABILITIES HL::Timer::TimerCapabilities = {0};\n\n/* APIC timer frequency */\nULONG HL::Timer::TimerFrequency;\n\n/* Function dispatch table for the active hardware timer backend */\nTIMER_ROUTINES HL::Timer::TimerRoutines = {0};\n\n/* Identifies the hardware timer backing */\nTIMER_TYPE HL::Timer::TimerType;\n"
  },
  {
    "path": "xtoskrnl/hl/exports.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/exports.cc\n * DESCRIPTION:     C-compatible API wrappers for exported kernel functions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Retrieves the current value of the high-resolution performance counter.\n *\n * @param PerformanceFrequency\n *        Suplies an optional pointer to a variable that receives the performance counter frequency in Hz.\n *\n * @return This routine returns the current 64-bit monotonic tick count.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLARGE_INTEGER\nHlQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency)\n{\n    return HL::Timer::QueryPerformanceCounter(PerformanceFrequency);\n}\n\n/**\n * Reads the 8-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return The value read from the port.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nUCHAR\nHlReadPort8(IN USHORT Port)\n{\n    return HL::IoPort::ReadPort8(Port);\n}\n\n/**\n * Reads the 16-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return The value read from the port.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nUSHORT\nHlReadPort16(IN USHORT Port)\n{\n    return HL::IoPort::ReadPort16(Port);\n}\n\n/**\n * Reads the 32-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return The value read from the port.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nULONG\nHlReadPort32(IN USHORT Port)\n{\n    return HL::IoPort::ReadPort32(Port);\n}\n\n/**\n * Reads an 8-bit data from a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address holding data to read.\n *\n * @return This routine returns a value at the specified register.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nUCHAR\nHlReadRegister8(IN PVOID Register)\n{\n    return HL::IoRegister::ReadRegister8(Register);\n}\n\n/**\n * Reads a 16-bit data from a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address holding data to read.\n *\n * @return This routine returns a value at the specified register.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nUSHORT\nHlReadRegister16(IN PVOID Register)\n{\n    return HL::IoRegister::ReadRegister16(Register);\n}\n\n/**\n * Reads a 32-bit data from a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address holding data to read.\n *\n * @return This routine returns a value at the specified register.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nULONG\nHlReadRegister32(IN PVOID Register)\n{\n    return HL::IoRegister::ReadRegister32(Register);\n}\n\n/**\n * Requests a dynamic adjustment of the system clock resolution.\n *\n * @param Rate\n *        The requested clock rate change in 100-nanosecond units.\n *\n * @return This routine returns the actual clock rate granted by the hardware.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nULONG\nHlSetClockRate(IN ULONG Rate)\n{\n    return HL::Timer::SetClockRate(Rate);\n}\n\n/**\n * Writes the 8-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\nHlWritePort8(IN USHORT Port,\n             IN UCHAR Value)\n{\n    HL::IoPort::WritePort8(Port, Value);\n}\n\n/**\n * Writes the 16-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\nHlWritePort16(IN USHORT Port,\n              IN USHORT Value)\n{\n    HL::IoPort::WritePort16(Port, Value);\n}\n\n/**\n * Writes the 32-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\nHlWritePort32(IN USHORT Port,\n              IN ULONG Value)\n{\n    HL::IoPort::WritePort32(Port, Value);\n}\n\n/**\n * Writes an 8-bit value into a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address where data will be written.\n *\n * @param Value\n *        Supplies a new value that will be stored into a register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nHlWriteRegister8(IN PVOID Register,\n                 IN UCHAR Value)\n{\n    HL::IoRegister::WriteRegister8(Register, Value);\n}\n\n/**\n * Writes a 16-bit value into a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address where data will be written.\n *\n * @param Value\n *        Supplies a new value that will be stored into a register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nHlWriteRegister16(IN PVOID Register,\n                  IN USHORT Value)\n{\n    HL::IoRegister::WriteRegister16(Register, Value);\n}\n\n/**\n * Writes a 32-bit value into a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address where data will be written.\n *\n * @param Value\n *        Supplies a new value that will be stored into a register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nHlWriteRegister32(IN PVOID Register,\n                  IN ULONG Value)\n{\n    HL::IoRegister::WriteRegister32(Register, Value);\n}\n"
  },
  {
    "path": "xtoskrnl/hl/fbdev.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/fbdev.cc\n * DESCRIPTION:     FrameBuffer support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n#include <xtfont.h>\n\n\n/**\n * Clears the screen by drawing a box filled with specified color.\n *\n * @param Color\n *        Specifies the color of the box used to fill the screen in (A)RGB format.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::FrameBuffer::ClearScreen(IN ULONG Color)\n{\n    ULONG BackgroundColor, PositionY;\n    PCHAR CurrentLine, TargetBuffer;\n    UCHAR FillByte;\n\n    /* Make sure frame buffer is already initialized */\n    if(FrameBufferData.Initialized == FALSE)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return;\n    }\n\n    /* Convert background color */\n    BackgroundColor = GetRGBColor(Color);\n\n    /* Extract the lower byte for SetMemory */\n    FillByte = (UCHAR)(BackgroundColor & 0xFF);\n\n    /* Determine target buffer */\n    TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;\n    CurrentLine = TargetBuffer;\n\n    /* Fill the screen with the specified color */\n    for(PositionY = 0; PositionY < FrameBufferData.Height; PositionY++, CurrentLine += FrameBufferData.Pitch)\n    {\n        /* Fill the current scanline with the background color byte */\n        RTL::Memory::SetMemory(CurrentLine, FillByte, FrameBufferData.Width * FrameBufferData.BytesPerPixel);\n    }\n\n    /* Check if Shadow Buffer is active */\n    if(ScreenShadowBuffer != NULLPTR)\n    {\n        /* Flush changes to VRAM */\n        RTL::Memory::CopyMemory(FrameBufferData.Address, ScreenShadowBuffer,\n                                FrameBufferData.Pitch * FrameBufferData.Height);\n    }\n}\n\n/**\n * Displays a single character at the current cursor position inside the scroll region.\n *\n * @param Character\n *        Supplies the character to be displayed.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nHL::FrameBuffer::DisplayCharacter(IN WCHAR Character)\n{\n    ULONG CharacterX, CharacterY;\n    PSSFN_FONT_HEADER FbFont;\n    BOOLEAN VisibleCharacter;\n\n    /* Make sure frame buffer is already initialized */\n    if(FrameBufferData.Initialized == FALSE)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return STATUS_DEVICE_NOT_READY;\n    }\n\n    /* Get font information */\n    FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;\n\n    /* Assume invisible character */\n    VisibleCharacter = FALSE;\n\n    /* Handle special characters */\n    switch(Character)\n    {\n        case L'\\n':\n            /* Move cursor to the beginning of the next line */\n            ScrollRegionData.CursorX = ScrollRegionData.Left;\n            ScrollRegionData.CursorY += FbFont->Height;\n            break;\n        case L'\\t':\n            /* Move cursor to the next tab stop */\n            ScrollRegionData.CursorX += (8 - (ScrollRegionData.CursorX - ScrollRegionData.Left) / FbFont->Width % 8) * FbFont->Width;\n            if(ScrollRegionData.CursorX >= ScrollRegionData.Right)\n            {\n                ScrollRegionData.CursorX = ScrollRegionData.Left;\n                ScrollRegionData.CursorY += FbFont->Height;\n            }\n            break;\n        default:\n            /* Save cursor position */\n            CharacterX = ScrollRegionData.CursorX;\n            CharacterY = ScrollRegionData.CursorY;\n\n            /* Draw the character to RAM and mark it as visible */\n            DrawCharacter(CharacterX, CharacterY, ScrollRegionData.TextColor, Character);\n            VisibleCharacter = TRUE;\n\n            /* Advance cursor */\n            ScrollRegionData.CursorX += FbFont->Width;\n\n            /* Check if cursor reached end of line */\n            if(ScrollRegionData.CursorX >= ScrollRegionData.Right)\n            {\n                /* Reset cursor to the left margin and advance to the next line */\n                ScrollRegionData.CursorX = ScrollRegionData.Left;\n                ScrollRegionData.CursorY += FbFont->Height;\n            }\n            break;\n    }\n\n    /* Check if cursor reached end of scroll region */\n    if(ScrollRegionData.CursorY >= ScrollRegionData.Bottom)\n    {\n        /* Scroll one line up */\n        ScrollRegion();\n        ScrollRegionData.CursorY = ScrollRegionData.Bottom - FbFont->Height;\n    }\n    else if(VisibleCharacter == TRUE)\n    {\n        /* Flush visible character to VRAM */\n        UpdateScreenRegion(CharacterX, CharacterY,\n                           CharacterX + FbFont->Width,\n                           CharacterY + FbFont->Height);\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Draws a character on the framebuffer at the given position and color using the SSFN font.\n *\n * @param PositionX\n *        Supplies the X coordinate of the character.\n *\n * @param PositionY\n *        Supplies the Y coordinate of the character.\n *\n * @param Color\n *        Supplies the font color in (A)RGB format.\n *\n * @param WideCharacter\n *        Supplies the wide character to be drawn on the framebuffer.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::FrameBuffer::DrawCharacter(IN ULONG PositionX,\n                               IN ULONG PositionY,\n                               IN ULONG Color,\n                               IN WCHAR WideCharacter)\n{\n    UINT CurrentFragment, Glyph, GlyphLimit, Index, Line, Mapping;\n    PUCHAR Character, CharacterMapping, Fragment;\n    ULONG FontColor, GlyphOffset, PixelOffset;\n    PSSFN_FONT_HEADER FbFont;\n\n    /* Make sure frame buffer is already initialized */\n    if(FrameBufferData.Initialized == FALSE)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return;\n    }\n\n    /* Get pointers to font data */\n    FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;\n    CharacterMapping = (PUCHAR)FbFont + FbFont->CharactersOffset;\n\n    /* Find the character in the font's character table */\n    Character = 0;\n    for(Index = 0; Index < 0x110000; Index++)\n    {\n        if(CharacterMapping[0] == 0xFF)\n        {\n            /* Skip 65535 code points */\n            Index += 65535;\n            CharacterMapping++;\n        }\n        else if((CharacterMapping[0] & 0xC0) == 0xC0)\n        {\n            /* Skip (N << 8 + additional byte) + 1 code points (up to 16128) */\n            Index += (((CharacterMapping[0] & 0x3F) << 8) | CharacterMapping[1]);\n            CharacterMapping += 2;\n        }\n        else if((CharacterMapping[0] & 0xC0) == 0x80)\n        {\n            /* Skip N + 1 code points (up to 64) */\n            Index += (CharacterMapping[0] & 0x3F);\n            CharacterMapping++;\n        }\n        else\n        {\n            /* There is a glyph for this character, check if it matches */\n            if(Index == WideCharacter)\n            {\n                /* Found the character, break loop */\n                Character = CharacterMapping;\n                break;\n            }\n\n            /* Move to next character table entry */\n            CharacterMapping += (6 + CharacterMapping[1] * (CharacterMapping[0] & 0x40 ? 6 : 5));\n        }\n    }\n\n    /* Make sure the character has been found in the font */\n    if(!Character)\n    {\n        /* Character not found, don't draw anything */\n        return;\n    }\n\n    /* Find the glyph position on the frame buffer and set font color */\n    GlyphOffset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);\n    FontColor = GetRGBColor(Color);\n\n    /* Check all kerning fragments */\n    Mapping = 0;\n    CharacterMapping = Character + 6;\n    for(Index = 0; Index < Character[1]; Index++)\n    {\n        /* Check if number of fragments is not exceeded */\n        if(CharacterMapping[0] == 255 && CharacterMapping[1] == 255)\n        {\n            /* Get next mapping */\n            continue;\n        }\n\n        /* Get pointer to fragment */\n        Fragment = (PUCHAR)FbFont + (CharacterMapping[2] |\n                                     (CharacterMapping[3] << 8) |\n                                     (CharacterMapping[4] << 16) |\n                                     ((Character[0] & 0x40) ? (CharacterMapping[5] << 24) : 0));\n\n        /* Check if fragment is printable */\n        if((Fragment[0] & 0xE0) != 0x80)\n        {\n            /* Skip fragment */\n            continue;\n        }\n\n        /* Get initial glyph line */\n        GlyphOffset += (CharacterMapping[1] - Mapping) * FrameBufferData.Pitch;\n        Mapping = CharacterMapping[1];\n\n        /* Extract glyph data from fragments table and advance */\n        Glyph = ((Fragment[0] & 0x1F) + 1) << 3;\n        GlyphLimit = Fragment[1] + 1;\n        Fragment += 2;\n\n        /* Look for kerning group for next code point */\n        CurrentFragment = 1;\n        while(GlyphLimit--)\n        {\n            /* Set the initial pixel offset for the current glyph fragment */\n            PixelOffset = GlyphOffset;\n            for(Line = 0; Line < Glyph; Line++)\n            {\n                /* Decode compressed offsets */\n                if(CurrentFragment > 0x80)\n                {\n                    /* Advance to next fragment */\n                    Fragment++;\n                    CurrentFragment = 1;\n                }\n\n                /* Check if pixel should be drawn */\n                if(*Fragment & CurrentFragment)\n                {\n                    /* Route the pixel draw operation to the active buffer */\n                    if(ScreenShadowBuffer != NULLPTR)\n                    {\n                        /* Draw glyph pixel to Shadow Buffer */\n                        *((PULONG)((PCHAR)ScreenShadowBuffer + PixelOffset)) = FontColor;\n                    }\n                    else\n                    {\n                        /* Draw glyph pixel directly to VRAM */\n                        *((PULONG)((PCHAR)FrameBufferData.Address + PixelOffset)) = FontColor;\n                    }\n                }\n\n                /* Advance pixel pointer */\n                PixelOffset += FrameBufferData.BytesPerPixel;\n                CurrentFragment <<= 1;\n            }\n\n            /* Advance to next line and increase mapping */\n            GlyphOffset += FrameBufferData.Pitch;\n            Mapping++;\n        }\n\n        /* Get next mapping */\n        CharacterMapping += Character[0] & 0x40 ? 6 : 5;\n    }\n}\n\n/**\n * Draw a pixel on the screen at the given position and color.\n *\n * @param PositionX\n *        Supplies the X coordinate of the pixel.\n *\n * @param PositionY\n *        Supplies the Y coordinate of the pixel.\n *\n * @param Color\n *        Specifies the color of the pixel in (A)RGB format.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::FrameBuffer::DrawPixel(IN ULONG PositionX,\n                           IN ULONG PositionY,\n                           IN ULONG Color)\n{\n    ULONG Offset;\n\n    /* Make sure frame buffer is already initialized */\n    if(FrameBufferData.Initialized == FALSE)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return;\n    }\n\n    /* Make sure point is not offscreen */\n    if(PositionX >= FrameBufferData.Width || PositionY >= FrameBufferData.Height || Color > 0xFFFFFFFF)\n    {\n        /* Invalid pixel position or color given */\n        return;\n    }\n\n    /* Calculate the address of the pixel in the frame buffer memory */\n    Offset = (PositionY * FrameBufferData.Pitch) + (PositionX * FrameBufferData.BytesPerPixel);\n\n    /* Route the pixel draw operation to the active buffer */\n    if(ScreenShadowBuffer != NULLPTR)\n    {\n        /* Set the color of the pixel by writing to the corresponding memory location (RAM) */\n        *((PULONG)((PCHAR)ScreenShadowBuffer + Offset)) = GetRGBColor(Color);\n    }\n    else\n    {\n        /* Set the color of the pixel by writing to the corresponding memory location (VRAM) */\n        *((PULONG)((PCHAR)FrameBufferData.Address + Offset)) = GetRGBColor(Color);\n    }\n}\n\n/**\n * Enables the Shadow Buffer (Double Buffering) for high-performance rendering.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::FrameBuffer::EnableShadowBuffer(VOID)\n{\n    ULONG FrameBufferSize;\n    XTSTATUS Status;\n\n    /* Check if the shadow buffer is already enabled */\n    if(ScreenShadowBuffer != NULLPTR)\n    {\n        /* Nothing to do, return success */\n        return STATUS_SUCCESS;\n    }\n\n    /* Make sure frame buffer is already initialized */\n    if(FrameBufferData.Initialized == FALSE)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return STATUS_DEVICE_NOT_READY;\n    }\n\n    /* Calculate the total size of the framebuffer */\n    FrameBufferSize = FrameBufferData.Pitch * FrameBufferData.Height;\n\n    /* Allocate non-paged memory for the shadow buffer */\n    Status = MM::Allocator::AllocatePool(NonPagedPool, FrameBufferSize,\n                                         &ScreenShadowBuffer, SIGNATURE32('F', 'B', 'U', 'F'));\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Allocation failed, return status code */\n        ScreenShadowBuffer = NULLPTR;\n        return Status;\n    }\n\n    /* Synchronize the newly allocated shadow buffer with the current on-screen contents */\n    RTL::Memory::CopyMemory(ScreenShadowBuffer, FrameBufferData.Address, FrameBufferSize);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Returns the current resolution of the frame buffer display.\n *\n * @param Width\n *        A pointer to memory area where the screen width will be stored.\n *\n * @param Height\n *        A pointer to memory area where the screen height will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::FrameBuffer::GetFrameBufferResolution(OUT PULONG Width,\n                                          OUT PULONG Height)\n{\n    *Width = FrameBufferData.Width;\n    *Height = FrameBufferData.Height;\n}\n\n/**\n * Converts color format from (A)RGB one expected by current FrameBuffer.\n *\n * @param Color\n *        Specifies the color in (A)RGB format.\n *\n * @return This routine returns the color in FrameBuffer format.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nHL::FrameBuffer::GetRGBColor(IN ULONG Color)\n{\n    USHORT Blue, Green, Red, Reserved;\n\n    /* Extract color components from (A)RGB value */\n    Blue = (USHORT)(Color & 0xFF);\n    Green = (USHORT)((Color >> 8) & 0xFF);\n    Red = (USHORT)((Color >> 16) & 0xFF);\n    Reserved = (USHORT)((Color >> 24) & 0xFF);\n\n    /* Return color in FrameBuffer pixel format */\n    return (ULONG)((Blue << FrameBufferData.Pixels.BlueShift) | (Green << FrameBufferData.Pixels.GreenShift) |\n                   (Red << FrameBufferData.Pixels.RedShift) | (Reserved << FrameBufferData.Pixels.ReservedShift));\n}\n\n/**\n * Initializes frame buffer display.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::FrameBuffer::InitializeFrameBuffer(VOID)\n{\n    PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;\n    PSYSTEM_RESOURCE_HEADER SystemResource;\n    XTSTATUS Status;\n\n    /* Check if display already initialized */\n    if(FrameBufferData.Initialized)\n    {\n        /* Nothing to do */\n        return STATUS_SUCCESS;\n    }\n\n    /* Get FrameBuffer system resource */\n    Status = KeGetSystemResource(SystemResourceFrameBuffer, &SystemResource);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Resource not found */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Cast system resource to FrameBuffer resource */\n    FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)SystemResource;\n\n    /* Check if bootloader provided a framebuffer address */\n    if(!FrameBufferResource->Header.VirtualAddress)\n    {\n        /* Display probably not initialized */\n        return STATUS_DEVICE_NOT_READY;\n    }\n\n    /* Check if bootloader provided a custom font */\n    if(FrameBufferResource->Font)\n    {\n        /* Use custom font */\n        FrameBufferData.Font = FrameBufferResource->Font;\n    }\n    else\n    {\n        /* Use default font */\n        FrameBufferData.Font = (PVOID)&XtFbDefaultFont;\n    }\n\n    /* Save framebuffer information and mark display as initialized */\n    FrameBufferData.Address = FrameBufferResource->Header.VirtualAddress;\n    FrameBufferData.Width = FrameBufferResource->Width;\n    FrameBufferData.Height = FrameBufferResource->Height;\n    FrameBufferData.BytesPerPixel = FrameBufferResource->BitsPerPixel / 8;\n    FrameBufferData.PixelsPerScanLine = FrameBufferResource->PixelsPerScanLine;\n    FrameBufferData.Pitch = FrameBufferResource->Pitch;\n    FrameBufferData.Pixels.BlueShift = FrameBufferResource->Pixels.BlueShift;\n    FrameBufferData.Pixels.BlueSize = FrameBufferResource->Pixels.BlueSize;\n    FrameBufferData.Pixels.GreenShift = FrameBufferResource->Pixels.GreenShift;\n    FrameBufferData.Pixels.GreenSize = FrameBufferResource->Pixels.GreenSize;\n    FrameBufferData.Pixels.RedShift = FrameBufferResource->Pixels.RedShift;\n    FrameBufferData.Pixels.RedSize = FrameBufferResource->Pixels.RedSize;\n    FrameBufferData.Pixels.ReservedShift = FrameBufferResource->Pixels.ReservedShift;\n    FrameBufferData.Pixels.ReservedSize = FrameBufferResource->Pixels.ReservedSize;\n    FrameBufferData.Initialized = TRUE;\n\n    /* Clear screen */\n    ClearScreen(0x00000000);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Sets the scrollable region of the screen and calculates character dimensions.\n *\n * @param Left\n *        Supplies the left pixel coordinate of the scroll region.\n *\n * @param Top\n *        Supplies the top pixel coordinate of the scroll region.\n *\n * @param Right\n *        Supplies the right pixel coordinate of the scroll region.\n *\n * @param Bottom\n *        Supplies the bottom pixel coordinate of the scroll region.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::FrameBuffer::InitializeScrollRegion(IN ULONG Left,\n                                        IN ULONG Top,\n                                        IN ULONG Right,\n                                        IN ULONG Bottom,\n                                        IN ULONG FontColor)\n{\n    PSSFN_FONT_HEADER FbFont;\n    PCHAR PixelAddress;\n\n    /* Make sure frame buffer is already initialized */\n    if(FrameBufferData.Initialized == FALSE)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return;\n    }\n\n    /* Store pixel coordinates of the scroll region */\n    ScrollRegionData.Left = Left;\n    ScrollRegionData.Top = Top;\n    ScrollRegionData.Right = Right;\n    ScrollRegionData.Bottom = Bottom;\n\n    /* Get font information */\n    FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;\n\n    /* Validate font information */\n    if(FbFont && FbFont->Width > 0 && FbFont->Height > 0)\n    {\n        /* Calculate character dimensions */\n        ScrollRegionData.WidthInChars = (Right - Left) / FbFont->Width;\n        ScrollRegionData.HeightInChars = (Bottom - Top) / FbFont->Height;\n\n        /* Ensure the bottom of the scroll region is an exact multiple of the font height */\n        ScrollRegionData.Bottom = ScrollRegionData.Top + (ScrollRegionData.HeightInChars * FbFont->Height);\n    }\n    else\n    {\n        /* Fallback to 0 if font info is not available or invalid */\n        ScrollRegionData.WidthInChars = 0;\n        ScrollRegionData.HeightInChars = 0;\n    }\n\n    /* Initialize cursor position and font color */\n    ScrollRegionData.CursorX = ScrollRegionData.Left;\n    ScrollRegionData.CursorY = ScrollRegionData.Top;\n    ScrollRegionData.TextColor = FontColor;\n\n    /* Get the background color by reading the pixel at the top-left corner of the scroll region */\n    PixelAddress = (PCHAR)FrameBufferData.Address + (Top * FrameBufferData.Pitch) +\n                          (Left * FrameBufferData.BytesPerPixel);\n    ScrollRegionData.BackgroundColor = *((PULONG)PixelAddress);\n}\n\n/**\n * Scrolls the content of the scroll region up by one line.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::FrameBuffer::ScrollRegion(VOID)\n{\n    PCHAR TargetBuffer, Destination, Source;\n    ULONG Line, PositionX, LineBytes;\n    PSSFN_FONT_HEADER FbFont;\n    PULONG Pixel;\n\n    /* Make sure frame buffer is already initialized */\n    if(FrameBufferData.Initialized == FALSE)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return;\n    }\n\n    /* Retrieve font metrics and calculate line properties for the scroll operation */\n    FbFont = (PSSFN_FONT_HEADER)FrameBufferData.Font;\n    LineBytes = (ScrollRegionData.Right - ScrollRegionData.Left) * FrameBufferData.BytesPerPixel;\n    TargetBuffer = (ScreenShadowBuffer != NULLPTR) ? (PCHAR)ScreenShadowBuffer : (PCHAR)FrameBufferData.Address;\n\n    /* Process every line in the scroll region */\n    for(Line = ScrollRegionData.Top; Line < ScrollRegionData.Bottom; Line++)\n    {\n        /* Calculate destination address for the current line */\n        Destination = TargetBuffer + (Line * FrameBufferData.Pitch) +\n                      (ScrollRegionData.Left * FrameBufferData.BytesPerPixel);\n\n        /* Check if the current line needs to be copied from below or cleared */\n        if(Line < ScrollRegionData.Bottom - FbFont->Height)\n        {\n            /* Copy the line from below */\n            Source = Destination + (FbFont->Height * FrameBufferData.Pitch);\n            RTL::Memory::CopyMemory(Destination, Source, LineBytes);\n        }\n        else\n        {\n            /* Fill the bottom line(s) with the background color */\n            Pixel = (PULONG)Destination;\n            for(PositionX = 0; PositionX < (ScrollRegionData.Right - ScrollRegionData.Left); PositionX++)\n            {\n                /* Overwrite the pixel with the background color */\n                Pixel[PositionX] = ScrollRegionData.BackgroundColor;\n            }\n        }\n    }\n\n    /* Flush changes to VRAM if Shadow Buffer was used */\n    if(ScreenShadowBuffer != NULLPTR)\n    {\n        /* Flush the updated scroll region to VRAM */\n        UpdateScreenRegion(ScrollRegionData.Left,\n                           ScrollRegionData.Top,\n                           ScrollRegionData.Right,\n                           ScrollRegionData.Bottom);\n    }\n}\n\n/**\n * Flushes the current content of the Shadow Buffer to the visible FrameBuffer (VRAM).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::FrameBuffer::UpdateScreen(VOID)\n{\n    /* Make sure framebuffer is already initialized and shadow buffer is ready */\n    if(FrameBufferData.Initialized == FALSE || ScreenShadowBuffer == NULLPTR)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return;\n    }\n\n    /* Flush RAM to VRAM */\n    RTL::Memory::CopyMemory(FrameBufferData.Address,\n                            ScreenShadowBuffer,\n                            FrameBufferData.Pitch * FrameBufferData.Height);\n}\n\n/**\n * Flushes a specific rectangular region from the Shadow Buffer to the visible FrameBuffer (VRAM).\n *\n * @param Left\n *        Supplies the left pixel coordinate of the region to update.\n *\n * @param Top\n *        Supplies the top pixel coordinate of the region to update.\n *\n * @param Right\n *        Supplies the right pixel coordinate of the region to update.\n *\n * @param Bottom\n *        Supplies the bottom pixel coordinate of the region to update.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::FrameBuffer::UpdateScreenRegion(IN ULONG Left,\n                                    IN ULONG Top,\n                                    IN ULONG Right,\n                                    IN ULONG Bottom)\n{\n    ULONG Line, LineBytes;\n    PCHAR Source, Destination;\n\n    /* Make sure framebuffer is already initialized and shadow buffer is ready */\n    if(FrameBufferData.Initialized == FALSE || ScreenShadowBuffer == NULLPTR)\n    {\n        /* Unable to operate on non-initialized frame buffer */\n        return;\n    }\n\n    /* Make sure parameters are valid to prevent memory corruption */\n    if(Left >= Right || Top >= Bottom || Right > FrameBufferData.Width || Bottom > FrameBufferData.Height)\n    {\n        /* Invalid region coordinates provided */\n        return;\n    }\n\n    /* Calculate the width of the region */\n    LineBytes = (Right - Left) * FrameBufferData.BytesPerPixel;\n\n    /* Copy the specified region line by line */\n    for(Line = Top; Line < Bottom; Line++)\n    {\n        /* Calculate the source address in the shadow buffer */\n        Source = (PCHAR)ScreenShadowBuffer +\n                 (Line * FrameBufferData.Pitch) +\n                 (Left * FrameBufferData.BytesPerPixel);\n\n        /* Calculate the destination address in the VRAM */\n        Destination = (PCHAR)FrameBufferData.Address +\n                      (Line * FrameBufferData.Pitch) +\n                      (Left * FrameBufferData.BytesPerPixel);\n\n        /* Flush RAM to VRAM */\n        RTL::Memory::CopyMemory(Destination, Source, LineBytes);\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/hl/i686/cpu.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/i686/cpu.cc\n * DESCRIPTION:     HAL i686 processor support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* Include common CPU interface */\n#include ARCH_COMMON(cpu.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/i686/firmware.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/i686/firmware.cc\n * DESCRIPTION:     UEFI/BIOS Firmware support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Include common Firmware interface */\n#include ARCH_COMMON(firmware.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/i686/ioport.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/i686/ioport.cc\n * DESCRIPTION:     I/O port access routines for i686 platform\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Reads the 8-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return This routine returns the value read from the port.\n *\n * @since XT 1.0\n */\nXTCDECL\nUCHAR\nHL::IoPort::ReadPort8(IN USHORT Port)\n{\n    UCHAR Value;\n    __asm__ volatile(\"inb %1, %0\"\n                     : \"=a\" (Value)\n                     : \"Nd\" (Port));\n    return Value;\n}\n\n/**\n * Reads the 16-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return This routine returns the value read from the port.\n *\n * @since XT 1.0\n */\nXTCDECL\nUSHORT\nHL::IoPort::ReadPort16(IN USHORT Port)\n{\n    USHORT Value;\n    __asm__ volatile(\"inw %1, %0\"\n                     : \"=a\" (Value)\n                     : \"Nd\" (Port));\n    return Value;\n}\n\n/**\n * Reads the 32-bit data from the specified I/O port.\n *\n * @param Port\n *        Specifies the address to read from, in the range of 0-0xFFFF.\n *\n * @return This routine returns the value read from the port.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONG\nHL::IoPort::ReadPort32(IN USHORT Port)\n{\n    ULONG Value;\n    __asm__ volatile(\"inl %1, %0\"\n                     : \"=a\" (Value)\n                     : \"Nd\" (Port));\n    return Value;\n}\n\n/**\n * Writes the 8-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::IoPort::WritePort8(IN USHORT Port,\n                       IN UCHAR Value)\n{\n    __asm__ volatile(\"outb %0, %1\"\n                     :\n                     : \"a\" (Value),\n                       \"Nd\" (Port));\n}\n\n/**\n * Writes the 16-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::IoPort::WritePort16(IN USHORT Port,\n                        IN USHORT Value)\n{\n    __asm__ volatile(\"outw %0, %1\"\n                     :\n                     : \"a\" (Value),\n                       \"Nd\" (Port));\n}\n\n/**\n * Writes the 32-bit data to the specified I/O port.\n *\n * @param Port\n *        Specifies the address to write to, in the range of 0-0xFFFF.\n *\n * @param Value\n *        Supplies the value to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::IoPort::WritePort32(IN USHORT Port,\n                        IN ULONG Value)\n{\n    __asm__ volatile(\"outl %0, %1\"\n                     :\n                     : \"a\" (Value),\n                       \"Nd\" (Port));\n}\n"
  },
  {
    "path": "xtoskrnl/hl/i686/irq.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/i686/irq.cc\n * DESCRIPTION:     Interrupts support for i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n\n/**\n * Begins a system interrupt handler by raising the processor's run level and re-enabling\n * hardware interrupts to allow preemption by higher-priority events.\n *\n * @param RunLevel\n *        Supplies the target run level to raise the processor to.\n *\n * @param OldRunLevel\n *        Receives the previous run level before the elevation.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,\n                              OUT PKRUNLEVEL OldRunLevel)\n{\n    /* Get the current IRQL */\n    *OldRunLevel = KE::RunLevel::GetCurrentRunLevel();\n\n    /* Raise run level */\n    KE::RunLevel::RaiseRunLevel(RunLevel);\n\n    /* Enable interrupts */\n    AR::CpuFunctions::SetInterruptFlag();\n}\n\n/**\n * Safely concludes an interrupt handler by disabling hardware interrupts.\n *\n * @param TrapFrame\n *        Supplies a pointer to the kernel trap frame containing the interrupted execution state.\n *\n * @param OldRunLevel\n *        Supplies the previous run level to restore.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,\n                      IN KRUNLEVEL OldRunLevel)\n{\n    /* Disable interrupts */\n    AR::CpuFunctions::ClearInterruptFlag();\n\n    /* End system interrupt */\n    EndSystemInterrupt(TrapFrame, OldRunLevel);\n}\n\n/**\n * Concludes a system interrupt by sending an End of Interrupt (EOI) to the hardware\n * controller and restoring the processor's previous run level.\n *\n * @param TrapFrame\n *        Supplies a pointer to the kernel trap frame containing the interrupted execution state.\n *\n * @param OldRunLevel\n *        Supplies the previous run level to restore.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame,\n                            IN KRUNLEVEL OldRunLevel)\n{\n    /* Send EOI */\n    HL::Pic::SendEoi();\n\n    /* Restore previous run level */\n    KE::RunLevel::LowerRunLevel(OldRunLevel);\n}\n\n/**\n * Handles profiling interrupt.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common interrupt handler.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::Irq::HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    /* Send EOI */\n    HL::Pic::SendEoi();\n}\n\n/**\n * Handles unexpected or unmapped system interrupts.\n *\n * @param TrapFrame\n *        Supplies a kernel trap frame pushed by common interrupt handler.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    UNIMPLEMENTED;\n\n    /* Disable interrupts */\n    AR::CpuFunctions::ClearInterruptFlag();\n\n    /* Print debug message and raise kernel panic */\n    DebugPrint(L\"ERROR: Caught unexpected interrupt (0x%.2lX)!\\n\", TrapFrame->Vector);\n    KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);\n}\n\n/**\n * Returns the registered interrupt handler for the specified IDT vector.\n *\n * @param Vector\n *        Supplies the interrupt vector number.\n *\n * @return This routine returns the pointer to the IDT interrupt handler routine.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nHL::Irq::QueryInterruptHandler(IN ULONG Vector)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n    PKIDTENTRY IdtEntry;\n\n    /* Get current processor block and IDT entry */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n    IdtEntry = &ProcessorBlock->IdtBase[Vector];\n\n    /* Return address of the interrupt handler */\n    return (PVOID)(((IdtEntry->ExtendedOffset << 16) & 0xFFFF0000) | (IdtEntry->Offset & 0xFFFF));\n}\n\n/**\n * Returns the registered interrupt handler for the specified vector.\n *\n * @param Vector\n *        Supplies the interrupt vector number.\n *\n * @return This routine returns the pointer to the interrupt handler routine.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nHL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];\n}\n\n/**\n * Registers new interrupt handler for the existing IDT entry.\n *\n * @param HalVector\n *        Supplies the interrupt vector number.\n *\n * @param Handler\n *        Supplies the pointer to the interrupt handler routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::RegisterInterruptHandler(IN ULONG Vector,\n                                  IN PVOID Handler)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    /* Update interrupt handler */\n    AR::ProcessorSupport::SetIdtGate(ProcessorBlock->IdtBase,\n                                     Vector,\n                                     Handler,\n                                     KGDT_R0_CODE,\n                                     0,\n                                     KIDT_ACCESS_RING0,\n                                     I686_INTERRUPT_GATE);\n}\n\n/**\n * Registers the interrupt handler for the specified vector.\n *\n * @param HalVector\n *        Supplies the interrupt vector number.\n *\n * @param Handler\n *        Supplies the pointer to the interrupt handler routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,\n                                        IN PINTERRUPT_HANDLER Handler)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    /* Update interrupt handler in the processor's interrupt dispatch table */\n    ProcessorBlock->InterruptDispatchTable[Vector] = Handler;\n}\n\n/**\n * Requests a software interrupt by sending a Self-IPI mapped to the specified run level.\n *\n * @param RunLevel\n *        Supplies the target run level for the software interrupt.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nHL::Irq::SendSoftwareInterrupt(IN KRUNLEVEL RunLevel)\n{\n    /* Request a software interrupt */\n    HL::Pic::SendSelfIpi(HL::RunLevel::TransformRunLevelToSoftwareVector(RunLevel));\n}\n"
  },
  {
    "path": "xtoskrnl/hl/i686/pic.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/i686/pic.cc\n * DESCRIPTION:     Programmable Interrupt Controller (PIC) for i686 support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* Include common PIC interface */\n#include ARCH_COMMON(pic.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/i686/rtc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/i686/rtc.cc\n * DESCRIPTION:     Hardware Real-Time Clock (RTC) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Include common RTC interface */\n#include ARCH_COMMON(rtc.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/i686/runlevel.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/i686/runlevel.cc\n * DESCRIPTION:     Run Level management support for i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Gets the current run level from APIC for the current processor.\n *\n * @return This routine returns the current run level.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nKRUNLEVEL\nHL::RunLevel::GetRunLevel(VOID)\n{\n    /* Read current run level */\n    return TransformApicTprToRunLevel(HL::Pic::ReadApicRegister(APIC_TPR));\n}\n\n/**\n * Sets new run level for the current processor.\n *\n * @param RunLevel\n *        Supplies the new run level to store into APIC.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nHL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)\n{\n    /* Set new run level */\n    HL::Pic::WriteApicRegister(APIC_TPR, TransformRunLevelToApicTpr(RunLevel));\n}\n\n/**\n * Maps APIC interrupt vector to XT run level.\n *\n * @param Tpr\n *        Supplies the interrupt vector rad from APIC Task Priority Register.\n *\n * @return This routine returns the XT run level corresponding to the specified APIC interrupt vector.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nKRUNLEVEL\nHL::RunLevel::TransformApicTprToRunLevel(IN UCHAR Tpr)\n{\n    STATIC KRUNLEVEL TransformationTable[16] =\n    {\n        PASSIVE_LEVEL,\n        PASSIVE_LEVEL,\n        PASSIVE_LEVEL,\n        APC_LEVEL,\n        DISPATCH_LEVEL,\n        DEVICE1_LEVEL,\n        DEVICE2_LEVEL,\n        DEVICE3_LEVEL,\n        DEVICE4_LEVEL,\n        DEVICE5_LEVEL,\n        DEVICE6_LEVEL,\n        DEVICE7_LEVEL,\n        PROFILE_LEVEL,\n        CLOCK_LEVEL,\n        IPI_LEVEL,\n        HIGH_LEVEL\n    };\n\n    /* Return the run level corresponding to the TPR from the transformation table. */\n    return TransformationTable[Tpr / 16];\n}\n\n/**\n * Maps XT run level to interrupt vector suitable for the APIC Task Priority Register.\n *\n * @param RunLevel\n *        Supplies the XT run level.\n *\n * @return This routine returns the APIC interrupt vector corresponding to the specified XT run level.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nUCHAR\nHL::RunLevel::TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel)\n{\n    STATIC UCHAR TransformationTable[32] =\n    {\n        APIC_VECTOR_ZERO,\n        APIC_VECTOR_APC,\n        APIC_VECTOR_DPC,\n        APIC_VECTOR_DPC,\n        APIC_VECTOR_DEVICE1,\n        APIC_VECTOR_DEVICE2,\n        APIC_VECTOR_DEVICE3,\n        APIC_VECTOR_DEVICE4,\n        APIC_VECTOR_DEVICE5,\n        APIC_VECTOR_DEVICE6,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_DEVICE7,\n        APIC_VECTOR_GENERIC,\n        APIC_VECTOR_CLOCK,\n        APIC_VECTOR_IPI,\n        APIC_VECTOR_POWERFAIL,\n        APIC_VECTOR_NMI\n    };\n\n    /* Return the TPR corresponding to the run level from the transformation table. */\n    return TransformationTable[RunLevel];\n}\n\n/**\n * Transforms a given execution run level into a corresponding hardware interrupt vector\n * suitable for software interrupts.\n *\n * @param RunLevel\n *        Supplies the run level to be translated into a software interrupt vector.\n *\n * @return This routine returns the 8-bit APIC vector corresponding to the requested software interrupt level.\n *\n * @since XT 1.0\n */\n\nXTFASTCALL\nUCHAR\nHL::RunLevel::TransformRunLevelToSoftwareVector(IN KRUNLEVEL RunLevel)\n{\n    /* Transform run level to APIC interrupt vector */\n    return TransformRunLevelToApicTpr(RunLevel);\n}\n"
  },
  {
    "path": "xtoskrnl/hl/i686/timer.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/i686/timer.cc\n * DESCRIPTION:     Timer support for i686\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Include common Timer interface */\n#include ARCH_COMMON(timer.cc)\n"
  },
  {
    "path": "xtoskrnl/hl/init.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/init.cc\n * DESCRIPTION:     Hardware layer initialization code\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Initializes the hardware layer subsystem\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Init::InitializeSystem(VOID)\n{\n    XTSTATUS Status;\n\n    /* Initialize ACPI */\n    Status = HL::Acpi::InitializeAcpi();\n    if(Status != STATUS_SUCCESS)\n    {\n        return Status;\n    }\n\n    /* Get system information from ACPI */\n    Status = HL::Acpi::InitializeAcpiSystemInformation();\n    if(Status != STATUS_SUCCESS)\n    {\n        return Status;\n    }\n\n    /* Initialize I/O APIC */\n    HL::Pic::InitializeIOApic();\n\n    /* Initialize timer */\n    HL::Timer::InitializeTimer();\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "xtoskrnl/hl/ioreg.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/ioreg.cc\n * DESCRIPTION:     Basic I/O registers access functionality\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Reads an 8-bit data from a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address holding data to read.\n *\n * @return This routine returns a value at the specified register.\n *\n * @since XT 1.0\n */\nXTAPI\nUCHAR\nHL::IoRegister::ReadRegister8(IN PVOID Register)\n{\n    return *((VOLATILE PUCHAR)Register);\n}\n\n/**\n * Reads a 16-bit data from a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address holding data to read.\n *\n * @return This routine returns a value at the specified register.\n *\n * @since XT 1.0\n */\nXTAPI\nUSHORT\nHL::IoRegister::ReadRegister16(IN PVOID Register)\n{\n    return *((VOLATILE PUSHORT)Register);\n}\n\n/**\n * Reads a 32-bit data from a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address holding data to read.\n *\n * @return This routine returns a value at the specified register.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nHL::IoRegister::ReadRegister32(IN PVOID Register)\n{\n    return *((VOLATILE PULONG)Register);\n}\n\n/**\n * Writes an 8-bit value into a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address where data will be written.\n *\n * @param Value\n *        Supplies a new value that will be stored into a register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::IoRegister::WriteRegister8(IN PVOID Register,\n                               IN UCHAR Value)\n{\n    *((VOLATILE PUCHAR)Register) = Value;\n}\n\n/**\n * Writes a 16-bit value into a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address where data will be written.\n *\n * @param Value\n *        Supplies a new value that will be stored into a register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::IoRegister::WriteRegister16(IN PVOID Register,\n                                IN USHORT Value)\n{\n    *((VOLATILE PUSHORT)Register) = Value;\n}\n\n/**\n * Writes a 32-bit value into a specified register address.\n *\n * @param Register\n *        Supplies a pointer to register address where data will be written.\n *\n * @param Value\n *        Supplies a new value that will be stored into a register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::IoRegister::WriteRegister32(IN PVOID Register,\n                                IN ULONG Value)\n{\n    *((VOLATILE PULONG)Register) = Value;\n}\n"
  },
  {
    "path": "xtoskrnl/hl/x86/cpu.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/x86/cpu.cc\n * DESCRIPTION:     HAL x86 (i686/AMD64) processor support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Initializes the processor.\n *\n * @param CpuNumber\n *        Supplies the number of the CPU, that is being initialized.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Cpu::InitializeProcessor(VOID)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n    KAFFINITY Affinity;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    /* Set initial stall factor, CPU number and mask interrupts */\n    ProcessorBlock->StallScaleFactor = INITIAL_STALL_FACTOR;\n    ProcessorBlock->Idr = 0xFFFFFFFF;\n\n    /* Set processor affinity */\n    Affinity = (KAFFINITY) 1 << ProcessorBlock->CpuNumber;\n\n    /* Apply affinity to a set of processors */\n    ActiveProcessors |= Affinity;\n\n    /* Initialize APIC for this processor */\n    HL::Pic::InitializePic();\n\n    /* Set the APIC running level */\n    HL::RunLevel::SetRunLevel(KE::Processor::GetCurrentProcessorBlock()->RunLevel);\n}\n\n/**\n * Wakes up and initializes all Application Processors (APs) and transitions them into the active kernel.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Cpu::StartAllProcessors(VOID)\n{\n    ULONG CpuNumber, Index, MaxCpus, SipiVector, Timeout, TrampolinePages;\n    PVOID CpuStructures, TrampolineAddress, TrampolineCode;\n    ULONG_PTR AllocationSize, TrampolineCodeSize;\n    PPROCESSOR_START_BLOCK StartBlock;\n    PKPROCESSOR_BLOCK ProcessorBlock;\n    PACPI_SYSTEM_INFO SysInfo;\n    WCHAR ParameterValue[16];\n    XTSTATUS Status;\n\n    /* Determine the maximum number of CPUs to start */\n    HL::Acpi::GetSystemInformation(&SysInfo);\n    MaxCpus = SysInfo->CpuCount;\n\n    /* Check if user forced a specific CPU limit */\n    if(KE::BootInformation::GetKernelParameterValue(L\"MAXCPUS\", ParameterValue, 16) == STATUS_SUCCESS)\n    {\n        /* Convert string value to number */\n        Status = RTL::WideString::WideStringToNumber(ParameterValue, 0, &MaxCpus);\n        if(Status == STATUS_SUCCESS)\n        {\n            /* Ensure safe boundaries */\n            if(MaxCpus == 0)\n            {\n                /* Fallback to 1 CPU (BSP) */\n                MaxCpus = 1;\n            }\n        }\n        else\n        {\n            /* Failed to parse value, fallback to ACPI value */\n            MaxCpus = SysInfo->CpuCount;\n        }\n    }\n\n    /* Check if single core CPU or set a CPU limit */\n    if(MaxCpus == 1 || SysInfo->CpuCount == 1)\n    {\n        /* Single core CPU, return success */\n        return STATUS_SUCCESS;\n    }\n\n    /* Get trampoline information */\n    AR::ProcessorSupport::GetTrampolineInformation(TrampolineApStartup, &TrampolineCode, &TrampolineCodeSize);\n\n    /* Verify trampoline information */\n    if(TrampolineCode == NULLPTR || TrampolineCodeSize == 0)\n    {\n        /* Failed to get trampoline information, return error */\n        return STATUS_UNSUCCESSFUL;\n    }\n\n    /* Compute trampoline memory allocation size (trampoline + processor start block + temporary stack) */\n    AllocationSize = TrampolineCodeSize + sizeof(PROCESSOR_START_BLOCK) + 512;\n    TrampolinePages = (ULONG)(ROUND_UP(AllocationSize, MM_PAGE_SIZE) / MM_PAGE_SIZE);\n\n    /* Allocate real mode memory for AP trampoline */\n    Status = MM::HardwarePool::AllocateRealModeMemory(TrampolinePages, &TrampolineAddress);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to allocate memory, print error message and return error */\n        DebugPrint(L\"Failed to allocate %lu pages for AP Trampoline!\\n\", TrampolinePages);\n        return Status;\n    }\n\n    /* Copy trampoline code to low memory */\n    RTL::Memory::CopyMemory(TrampolineAddress, TrampolineCode, TrampolineCodeSize);\n\n    /* Get start block address relative to trampoline address */\n    StartBlock = (PPROCESSOR_START_BLOCK)((PUCHAR)TrampolineAddress + TrampolineCodeSize);\n\n    /* Get SIPI vector */\n    SipiVector = (ULONG)((ULONG_PTR)TrampolineAddress >> 12);\n\n    /* Loop over all CPUs */\n    CpuNumber = 0;\n    for(Index = 0; Index < SysInfo->CpuCount; Index++)\n    {\n        /* Check if destination CPU is the BSP */\n        if(SysInfo->CpuInfo[Index].ApicId == HL::Pic::GetCpuApicId())\n        {\n            /* Skip current CPU */\n            continue;\n        }\n\n        /* Increment CPU number */\n        CpuNumber++;\n\n        /* Verify if the CPU limit has been reached */\n        if((CpuNumber) >= MaxCpus)\n        {\n            /* Maximum allowed CPUs reached, break the loop */\n            break;\n        }\n\n        /* Allocate memory for the processor structures (Stacks, GDT, and Processor Block) */\n        Status = MM::KernelPool::AllocateProcessorStructures(&CpuStructures);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to allocate memory, unmap memory and return error */\n            MM::HardwarePool::UnmapHardwareMemory(TrampolineAddress, TrampolinePages, TRUE);\n            return Status;\n        }\n\n        /* Get ProcessorBlock and Stack address */\n        AR::ProcessorSupport::InitializeProcessorStructures(CpuStructures, NULLPTR, NULLPTR, &ProcessorBlock,\n                                                            &StartBlock->Stack, NULLPTR, NULLPTR);\n\n        /* Set processor number directly in the processor block */\n        ProcessorBlock->CpuNumber = CpuNumber;\n\n        /* Save processor block in the array */\n        KE::Processor::RegisterProcessorBlock(CpuNumber, ProcessorBlock);\n\n        /* Initialize processor start block */\n        StartBlock->Cr3 = AR::CpuFunctions::ReadControlRegister(3);\n        StartBlock->Cr4 = AR::CpuFunctions::ReadControlRegister(4);\n        StartBlock->EntryPoint = (PVOID)&KE::KernelInit::BootstrapApplicationProcessor;\n        StartBlock->ProcessorStructures = CpuStructures;\n        StartBlock->Started = FALSE;\n\n        /* Memory barrier */\n        AR::CpuFunctions::MemoryBarrier();\n\n        /* Send INIT IPI and wait for 10ms */\n        HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, 0, APIC_DM_INIT, APIC_DSH_Destination, APIC_TGM_EDGE);\n        HL::Timer::StallExecution(10000);\n\n        /* Send STARTUP IPI (SIPI) and wait for 200us */\n        HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, SipiVector, APIC_DM_STARTUP, APIC_DSH_Destination, APIC_TGM_EDGE);\n        HL::Timer::StallExecution(200);\n\n        /* Send STARTUP IPI (SIPI) again */\n        HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, SipiVector, APIC_DM_STARTUP, APIC_DSH_Destination, APIC_TGM_EDGE);\n\n        /* Wait until the processor has started or timeout expires */\n        Timeout = 0;\n        while(!StartBlock->Started && Timeout < 100000)\n        {\n            /* Yield processor and wait for 10us */\n            AR::CpuFunctions::YieldProcessor();\n            HL::Timer::StallExecution(10);\n            Timeout++;\n        }\n\n        /* Check if the processor has not started */\n        if(!StartBlock->Started)\n        {\n            /* Free processor structures and unregister processor block */\n            MM::KernelPool::FreeProcessorStructures(CpuStructures);\n            KE::Processor::RegisterProcessorBlock(CpuNumber, NULLPTR);\n\n            /* Decrement the CPU counter back */\n            CpuNumber--;\n        }\n    }\n\n    /* Unmap trampoline memory and return success */\n    MM::HardwarePool::UnmapHardwareMemory(TrampolineAddress, TrampolinePages, TRUE);\n    return STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "xtoskrnl/hl/x86/firmware.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/x86/firmware.cc\n * DESCRIPTION:     UEFI/BIOS Firmware support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Reads a byte from the specified CMOS register.\n *\n * @param Register\n *        Supplies the CMOS register index to read from.\n *\n * @return This routine returns the data read from the register.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nUCHAR\nHL::Firmware::ReadCmosRegister(IN UCHAR Register)\n{\n    /* Select the register (Setting the highest bit disables NMI) */\n    HL::IoPort::WritePort8(CMOS_SELECT_PORT, Register | CMOS_NMI_SELECT);\n\n    /* Read value from the data port */\n    return HL::IoPort::ReadPort8(CMOS_DATA_PORT);\n}\n\n/**\n * Writes a byte to the specified CMOS register.\n *\n * @param Register\n *        Supplies the CMOS register index to write to.\n *\n * @param Value\n *        Supplies the value to write to the register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nHL::Firmware::WriteCmosRegister(IN UCHAR Register,\n                                IN UCHAR Value)\n{\n    /* Select the register (Setting the highest bit disables NMI) */\n    HL::IoPort::WritePort8(CMOS_SELECT_PORT, Register | CMOS_NMI_SELECT);\n\n    /* Write the provided value to the data port */\n    HL::IoPort::WritePort8(CMOS_DATA_PORT, Value);\n}\n"
  },
  {
    "path": "xtoskrnl/hl/x86/pic.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/x86/pic.cc\n * DESCRIPTION:     Programmable Interrupt Controller (PIC) for x86 (i686/AMD64) support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Allocates, maps and commits a requested system interrupt level internally.\n *\n * @param Irq\n *        Supplies the hardware IRQ line number to be allocated and mapped.\n *\n * @param RunLevel\n *        Supplies the actual system run level to allocate.\n *\n * @param Vector\n *        Supplies the interrupt handler vector assigned to process requests originating on the line.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::AllocateSystemInterrupt(IN UCHAR Irq,\n                                 IN UCHAR RunLevel,\n                                 IN UCHAR Vector)\n{\n    IOAPIC_REDIRECTION_REGISTER Register;\n    PIOAPIC_DATA Controller;\n    ULONG EntryNumber, Gsi;\n    XTSTATUS Status;\n    USHORT Flags;\n\n    /* Determine the GSI and flags for the requested IRQ */\n    ResolveInterruptOverride(Irq, &Gsi, &Flags);\n\n    /* Find the APIC controller for the GSI */\n    Status = GetIoApicController(Gsi, &Controller, &EntryNumber);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* GSI maps to an invalid controller, return */\n        DebugPrint(L\"ERROR: Hardware IRQ / GSI maps to an invalid controller!\\n\");\n        return;\n    }\n\n    /* Model a logical connection */\n    Register.LongLong = 0;\n    Register.DeliveryMode = APIC_DM_FIXED;\n    Register.DeliveryStatus = 0;\n    Register.Destination = HL::Pic::ReadApicRegister(APIC_ID) >> 24;\n    Register.DestinationMode = APIC_DM_Physical;\n    Register.Mask = 0;\n    Register.PinPolarity = ((Flags & 0x03) == 0x03) ? 1 : 0;\n    Register.RemoteIRR = 0;\n    Register.Reserved = 0;\n    Register.TriggerMode = (((Flags >> 2) & 0x03) == 0x03) ? APIC_TGM_LEVEL : APIC_TGM_EDGE;\n    Register.Vector = Vector;\n\n    /* Flash logical rules back into the hardware configuration index */\n    WriteRedirectionEntry(Controller, EntryNumber, Register);\n\n    /* Persist the allocated slot so standard routing algorithms don't overlap it */\n    MappedVectors[Vector] = RunLevel;\n}\n\n/**\n * Checks whether the APIC is supported by the processor.\n *\n * @return This routine returns TRUE if APIC is supported, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nHL::Pic::CheckApicSupport(VOID)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n\n    /* Get current processor control block */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n    /* Return APIC status */\n    return (Prcb->CpuId.FeatureBits & KCF_APIC) ? TRUE : FALSE;\n}\n\n/**\n * Checks whether the x2APIC extension is supported by the processor.\n *\n * @return This routine returns TRUE if x2APIC is supported, or FALSE otherwise.\n *\n * @since XT 1.0\n *\n * @todo Check if bits 0 and 1 of DMAR ACPI table flags are set after implementing ACPI support.\n *       Intel VT-d spec says x2apic should not be enabled if they are.\n */\nXTAPI\nBOOLEAN\nHL::Pic::CheckX2ApicSupport(VOID)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    PCWSTR KernelParameter;\n\n    /* Check if the user forced xAPIC via boot parameters */\n    if(KE::BootInformation::GetKernelParameter(L\"NOX2APIC\", &KernelParameter) == STATUS_SUCCESS)\n    {\n        /* The NOX2APIC flag is present, explicitly disable x2APIC support */\n        return FALSE;\n    }\n\n    /* Get current processor control block */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n    /* Return x2APIC status */\n    return (Prcb->CpuId.FeatureBits & KCF_X2APIC) ? TRUE : FALSE;\n}\n\n/**\n * Clears all errors on the APIC.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::ClearApicErrors(VOID)\n{\n    /* Clear APIC errors */\n    WriteApicRegister(APIC_ESR, 0);\n}\n\n/**\n * Searches the ACPI MADT tables for the I/O APIC controllers.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Pic::DetectIoApicControllers(VOID)\n{\n    PACPI_MADT_INTERRUPT_OVERRIDE OverrideDescriptor;\n    PACPI_MADT_IOAPIC IoApicDescriptor;\n    PACPI_SUBTABLE_HEADER SubTable;\n    ULONG_PTR MadtTable;\n    PACPI_MADT Madt;\n    XTSTATUS Status;\n\n    /* Initialize number of I/O APIC Controllers */\n    ControllerCount = 0;\n\n    /* Get Multiple APIC Description Table (MADT) */\n    Status = HL::Acpi::GetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt);\n    if(Status == STATUS_SUCCESS && Madt != NULLPTR)\n    {\n        /* Set APIC table traverse pointer */\n        MadtTable = (ULONG_PTR)Madt->ApicTables;\n\n        /* Traverse all MADT tables to discover IOAPIC configurations */\n        while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))\n        {\n            /* Extract active header element */\n            SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;\n\n            /* Prevent infinite traversal loops on corrupted firmware definitions */\n            if(SubTable->Length == 0)\n            {\n                /* Invalid MADT table, break loop */\n                break;\n            }\n\n            /* Test specifically for I/O APIC component identity */\n            if(SubTable->Type == ACPI_MADT_TYPE_IOAPIC &&\n               SubTable->Length >= sizeof(ACPI_MADT_IOAPIC))\n            {\n                /* Extract I/O APIC descriptor */\n                IoApicDescriptor = (PACPI_MADT_IOAPIC)MadtTable;\n\n                /* Set information about this I/O APIC Controller */\n                Controllers[ControllerCount].GsiBase = IoApicDescriptor->GlobalIrqBase;\n                Controllers[ControllerCount].Identifier = IoApicDescriptor->IoApicId;\n                Controllers[ControllerCount].PhysicalAddress.QuadPart = IoApicDescriptor->IoApicAddress;\n\n                /* Increment I/O APIC controller index */\n                ControllerCount++;\n            }\n            else if(SubTable->Type == ACPI_MADT_TYPE_INT_OVERRIDE &&\n                    SubTable->Length >= sizeof(ACPI_MADT_INTERRUPT_OVERRIDE))\n            {\n                /* Check if maximum number of interrupt overrides has not been reached */\n                if(IrqOverrideCount < IOAPIC_MAX_OVERRIDES)\n                {\n                    /* Extract interrupt override descriptor */\n                    OverrideDescriptor = (PACPI_MADT_INTERRUPT_OVERRIDE)MadtTable;\n\n                    /* Save information about this interrupt override */\n                    IrqOverrides[IrqOverrideCount].Bus = OverrideDescriptor->Bus;\n                    IrqOverrides[IrqOverrideCount].Flags = OverrideDescriptor->Flags;\n                    IrqOverrides[IrqOverrideCount].GlobalSystemInterrupt = OverrideDescriptor->GlobalSystemInterrupt;\n                    IrqOverrides[IrqOverrideCount].SourceIrq = OverrideDescriptor->SourceIrq;\n\n                    /* Increment interrupt override index */\n                    IrqOverrideCount++;\n                }\n            }\n\n            /* Ensure, maximum number of I/O APIC controllers has not been reached */\n            if(ControllerCount >= IOAPIC_MAX_CONTROLLERS)\n            {\n                /* No more I/O APIC controllers supported, break loop */\n                break;\n            }\n\n            /* Go to the next subtable */\n            MadtTable += SubTable->Length;\n        }\n    }\n\n    /* Check if any I/O APIC controllers were found */\n    if(ControllerCount == 0)\n    {\n        /* No I/O APIC controllers found, return failure */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Gets the local APIC ID of the current processor.\n *\n * @return This routine returns the current processor's local APIC ID.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nHL::Pic::GetCpuApicId(VOID)\n{\n    ULONG ApicId;\n\n    /* Read APIC ID register */\n    ApicId = ReadApicRegister(APIC_ID);\n\n    /* Return logical CPU ID depending on current APIC mode */\n    return (ApicMode == APIC_MODE_COMPAT) ? ((ApicId & 0xFFFFFFFF) >> APIC_XAPIC_LDR_SHIFT) : ApicId;\n}\n\n/**\n * Gets the I/O APIC controller information for the specified GSI.\n *\n * @param Gsi\n *        Supplies the GSI to get the I/O APIC controller information for.\n *\n * @param Controller\n *        Supplies a pointer to the memory area where the I/O APIC controller information will be stored.\n *\n * @param EntryNumber\n *        Supplies a pointer to the memory area where the entry number will be stored.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Pic::GetIoApicController(IN ULONG Gsi,\n                             OUT PIOAPIC_DATA *Controller,\n                             OUT PULONG EntryNumber)\n{\n    ULONG ControllerIndex;\n\n    /* Iterate over all available I/O APIC controllers */\n    for(ControllerIndex = 0; ControllerIndex < ControllerCount; ControllerIndex++)\n    {\n        /* Check if the GSI belongs to this I/O APIC controller */\n        if(Gsi >= Controllers[ControllerIndex].GsiBase &&\n           Gsi < (Controllers[ControllerIndex].GsiBase + Controllers[ControllerIndex].LineCount))\n        {\n            /* Return I/O APIC controller information */\n            *Controller = &Controllers[ControllerIndex];\n            *EntryNumber = (ULONG)(Gsi - Controllers[ControllerIndex].GsiBase);\n            return STATUS_SUCCESS;\n        }\n    }\n\n    /* GSI does not belong to any I/O APIC controller, return failure */\n    return STATUS_NOT_FOUND;\n}\n\n/**\n * Services the APIC Error interrupt, invoked when the APIC detects an internal hardware or message passing error.\n *\n * @param TrapFrame\n *        Supplies a pointer to the hardware trap frame representing the interrupted execution context.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::Pic::HandleApicErrorInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    ULONG ErrorStatus;\n\n    /* Write 0 to the ESR register to trigger an internal state update, then read the latched status */\n    WriteApicRegister(APIC_ESR, 0);\n    ErrorStatus = (ULONG)ReadApicRegister(APIC_ESR);\n\n    /* Log the detected hardware error */\n    DebugPrint(L\"Caught APIC Error interrupt with ESR = 0x%08X\\n\", ErrorStatus);\n\n    /* Acknowledge the interrupt to allow further interrupt delivery */\n    SendEoi();\n}\n\n/**\n * Initializes the APIC interrupt controller.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::InitializeApic(VOID)\n{\n    APIC_SPURIOUS_REGISTER SpuriousRegister;\n    APIC_BASE_REGISTER BaseRegister;\n    APIC_LVT_REGISTER LvtRegister;\n    ULONG CpuNumber;\n\n    /* Check APIC support */\n    if(!CheckApicSupport())\n    {\n        /* APIC is not supported, raise kernel panic */\n        DebugPrint(L\"ERROR: Local APIC not present.\\n\");\n        KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);\n    }\n\n    /* Determine APIC mode (xAPIC compatibility or x2APIC) */\n    if(CheckX2ApicSupport())\n    {\n        /* Enable x2APIC mode */\n        ApicMode = APIC_MODE_X2APIC;\n    }\n    else\n    {\n        /* Fall back to xAPIC compatibility mode */\n        ApicMode = APIC_MODE_COMPAT;\n    }\n\n    /* Get current processor number */\n    CpuNumber = KE::Processor::GetCurrentProcessorNumber();\n\n    /* Enable the APIC */\n    BaseRegister.LongLong = AR::CpuFunctions::ReadModelSpecificRegister(APIC_LAPIC_MSR_BASE);\n    BaseRegister.Enable = 1;\n    BaseRegister.ExtendedMode = (ApicMode == APIC_MODE_X2APIC);\n    BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0;\n    AR::CpuFunctions::WriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong);\n\n    /* Mask all interrupts by raising Task Priority Register (TPR)  */\n    WriteApicRegister(APIC_TPR, 0xFF);\n\n    /* Perform initialization specific to xAPIC compatibility mode */\n    if(ApicMode == APIC_MODE_COMPAT)\n    {\n        /* Use Flat Model for destination format (not supported in x2APIC) */\n        WriteApicRegister(APIC_DFR, APIC_DF_FLAT);\n\n        /* Set the logical APIC ID for this processor (read-only in x2APIC) */\n        WriteApicRegister(APIC_LDR, (1UL << CpuNumber) << 24);\n    }\n\n    /* Report the APIC ID to the kernel logic */\n    KE::Processor::RegisterHardwareId(GetCpuApicId());\n\n    /* Configure the spurious interrupt vector */\n    SpuriousRegister.Long = ReadApicRegister(APIC_SIVR);\n    SpuriousRegister.Vector = APIC_VECTOR_SPURIOUS;\n    SpuriousRegister.SoftwareEnable = 1;\n    SpuriousRegister.CoreChecking = 0;\n    WriteApicRegister(APIC_SIVR, SpuriousRegister.Long);\n\n    /* Setup the LVT Error entry to deliver APIC errors on a dedicated vector */\n    WriteApicRegister(APIC_ERRLVTR, APIC_VECTOR_ERROR);\n\n    /* Mask the APIC Timer */\n    LvtRegister.Long = 0;\n    LvtRegister.Mask = 1;\n    WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);\n\n    /* Configure the performance counter overflow */\n    LvtRegister.Long = 0;\n    LvtRegister.Mask = 0;\n    LvtRegister.DeliveryMode = APIC_DM_FIXED;\n    LvtRegister.TimerMode = 0;\n    LvtRegister.TriggerMode = APIC_TGM_EDGE;\n    LvtRegister.Vector = APIC_VECTOR_PERF;\n    WriteApicRegister(APIC_PCLVTR, LvtRegister.Long);\n\n    /* Configure the LINT0 pin */\n    LvtRegister.Long = 0;\n    LvtRegister.Mask = 1;\n    LvtRegister.DeliveryMode = APIC_DM_FIXED;\n    LvtRegister.TimerMode = 0;\n    LvtRegister.TriggerMode = APIC_TGM_EDGE;\n    LvtRegister.Vector = APIC_VECTOR_SPURIOUS;\n    WriteApicRegister(APIC_LINT0, LvtRegister.Long);\n\n    /* Configure the LINT1 pin */\n    LvtRegister.Long = 0;\n    LvtRegister.Mask = 0;\n    LvtRegister.DeliveryMode = APIC_DM_NMI;\n    LvtRegister.TimerMode = 0;\n    LvtRegister.TriggerMode = APIC_TGM_EDGE;\n    LvtRegister.Vector = APIC_VECTOR_NMI;\n    WriteApicRegister(APIC_LINT1, LvtRegister.Long);\n\n    /* Register interrupt handlers */\n    HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_ERROR, HandleApicErrorInterrupt);\n    HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_PROFILE, HL::Irq::HandleProfileInterrupt);\n    HL::Irq::RegisterInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);\n\n    /* Clear any pre-existing errors */\n    WriteApicRegister(APIC_ESR, 0);\n\n    /* Re-enable all interrupts by lowering the Task Priority Register */\n    WriteApicRegister(APIC_TPR, 0x00);\n}\n\n/**\n * Initializes the global I/O APIC controller setup over the entire redirection span.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::InitializeIOApic(VOID)\n{\n    ULONG ControllerIndex, LineIndex, Vector, VersionRegister;\n    IOAPIC_REDIRECTION_REGISTER Register;\n    XTSTATUS Status;\n\n    /* Detect I/O APIC controllers */\n    Status = DetectIoApicControllers();\n    if(Status != STATUS_SUCCESS)\n    {\n        DebugPrint(L\"ERROR: I/O APIC Controller not present.\\n\");\n        KE::Crash::Panic(0x5D, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);\n    }\n\n    /* Iterate over all I/O APIC controllers */\n    ControllerIndex = 0;\n    while(ControllerIndex < ControllerCount)\n    {\n        /* Map the I/O APIC controller memory into hardware space */\n        Status = MM::HardwarePool::MapHardwareMemory(Controllers[ControllerIndex].PhysicalAddress,\n                                                     1,\n                                                     FALSE,\n                                                     (PVOID*)&Controllers[ControllerIndex].VirtualAddress);\n        if(Status != STATUS_SUCCESS || Controllers[ControllerIndex].VirtualAddress == 0)\n        {\n            DebugPrint(L\"ERROR: Failed to map I/O APIC Controller\\n\");\n            KE::Crash::Panic(0x0E, 0x0, 0x0, 0x0, 0x0);\n        }\n\n        /* Perform a memory barrier */\n        AR::CpuFunctions::MemoryBarrier();\n        AR::CpuFunctions::ReadWriteBarrier();\n\n        /* Read the version register and calculate the maximum number of redirection entries */\n        VersionRegister = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_VER);\n        Controllers[ControllerIndex].LineCount = ((VersionRegister >> 16) & 0xFF) + 1;\n\n        /* Set up the default redirection entry for this controller */\n        Register.LongLong = 0;\n        Register.DeliveryMode = APIC_DM_FIXED;\n        Register.DeliveryStatus = 0;\n        Register.Destination = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_ID) >> 24;\n        Register.DestinationMode = 0;\n        Register.Mask = 1;\n        Register.PinPolarity = 0;\n        Register.RemoteIRR = 0;\n        Register.Reserved = 0;\n        Register.TriggerMode = APIC_TGM_EDGE;\n        Register.Vector = IOAPIC_VECTOR_FREE;\n\n        /* Propagate defaults across the array of potential handlers */\n        for(LineIndex = 0; LineIndex < Controllers[ControllerIndex].LineCount; LineIndex++)\n        {\n            /* Write default values into the redirection table */\n            WriteRedirectionEntry(&Controllers[ControllerIndex], LineIndex, Register);\n        }\n\n        /* Print information about the I/O APIC controller */\n        DebugPrint(L\"Initialized I/O APIC Controller #%lu at 0x%llX (ID: %lu, GSI Base: %lu, Line Count: %lu)\\n\",\n                   ControllerIndex, Controllers[ControllerIndex].VirtualAddress,\n                   Controllers[ControllerIndex].Identifier, Controllers[ControllerIndex].GsiBase,\n                   Controllers[ControllerIndex].LineCount);\n\n        /* Go to the next I/O APIC controller */\n        ControllerIndex++;\n    }\n\n    /* Assign initial clean state for mapping translations */\n    for(Vector = 0; Vector <= 255; Vector++)\n    {\n        /* Set vector to free */\n        MappedVectors[Vector] = IOAPIC_VECTOR_FREE;\n    }\n}\n\n/**\n * Initializes the legacy PIC interrupt controller.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::InitializeLegacyPic(VOID)\n{\n    PIC_I8259_ICW1 Icw1;\n    PIC_I8259_ICW2 Icw2;\n    PIC_I8259_ICW3 Icw3;\n    PIC_I8259_ICW4 Icw4;\n\n    /* Initialize ICW1 for PIC1 port */\n    Icw1.Init = TRUE;\n    Icw1.InterruptMode = EdgeTriggered;\n    Icw1.InterruptVectorAddress = 0;\n    Icw1.Interval = Interval8;\n    Icw1.NeedIcw4 = TRUE;\n    Icw1.OperatingMode = Cascade;\n    HL::IoPort::WritePort8(PIC1_CONTROL_PORT, Icw1.Bits);\n\n    /* Initialize ICW2 for PIC1 port */\n    Icw2.Bits = 0x00;\n    HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw2.Bits);\n\n    /* Initialize ICW3 for PIC1 port */\n    Icw3.Bits = 0;\n    Icw3.SlaveIrq2 = TRUE;\n    HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw3.Bits);\n\n    /* Initialize ICW4 for PIC1 port */\n    Icw4.BufferedMode = NonBuffered;\n    Icw4.EoiMode = NormalEoi;\n    Icw4.Reserved = 0;\n    Icw4.SpecialFullyNestedMode = FALSE;\n    Icw4.SystemMode = New8086Mode;\n    HL::IoPort::WritePort8(PIC1_DATA_PORT, Icw4.Bits);\n\n    /* Mask all interrupts on PIC1 port */\n    HL::IoPort::WritePort8(PIC1_DATA_PORT, 0xFF);\n\n    /* Initialize ICW1 for PIC2 port */\n    Icw1.Init = TRUE;\n    Icw1.InterruptMode = EdgeTriggered;\n    Icw1.InterruptVectorAddress = 0;\n    Icw1.Interval = Interval8;\n    Icw1.NeedIcw4 = TRUE;\n    Icw1.OperatingMode = Cascade;\n    HL::IoPort::WritePort8(PIC2_CONTROL_PORT, Icw1.Bits);\n\n    /* Initialize ICW2 for PIC2 port */\n    Icw2.Bits = 0x08;\n    HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw2.Bits);\n\n    /* Initialize ICW3 for PIC2 port */\n    Icw3.Bits = 0;\n    Icw3.SlaveId = 2;\n    HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw3.Bits);\n\n    /* Initialize ICW4 for PIC2 port */\n    Icw4.BufferedMode = NonBuffered;\n    Icw4.EoiMode = NormalEoi;\n    Icw4.Reserved = 0;\n    Icw4.SpecialFullyNestedMode = FALSE;\n    Icw4.SystemMode = New8086Mode;\n    HL::IoPort::WritePort8(PIC2_DATA_PORT, Icw4.Bits);\n\n    /* Mask all interrupts on PIC2 port */\n    HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);\n\n    /* Register interrupt handler */\n    HL::Irq::RegisterInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);\n}\n\n/**\n * Initializes the (A)PIC interrupt controller.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @todo Initialize APIC only when supported, otherwise fall back to legacy PIC.\n */\nXTAPI\nVOID\nHL::Pic::InitializePic(VOID)\n{\n    /* Initialize APIC */\n    InitializeApic();\n\n    /* Initialize legacy PIC */\n    InitializeLegacyPic();\n}\n\n/**\n * Reads from the APIC register.\n *\n * @param Register\n *        Supplies the APIC register to read from.\n *\n * @return This routine returns the value read from the APIC register.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nULONGLONG\nHL::Pic::ReadApicRegister(IN APIC_REGISTER Register)\n{\n    if(ApicMode == APIC_MODE_X2APIC)\n    {\n        /* Read from x2APIC MSR */\n        return AR::CpuFunctions::ReadModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register));\n    }\n    else\n    {\n        /* Read from xAPIC */\n        return HL::IoRegister::ReadRegister32((PULONG)(APIC_BASE + (Register << 4)));\n    }\n}\n\n/**\n * Reads from the I/O APIC register.\n *\n * @param Controller\n *        Supplies the I/O APIC controller to read from.\n *\n * @param Register\n *        Supplies the I/O APIC register to read from.\n *\n * @return This routine returns the value read from the given IO APIC register.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nULONG\nHL::Pic::ReadIOApicRegister(IN PIOAPIC_DATA Controller,\n                            IN UCHAR Register)\n{\n    /* Write the target address into the index register */\n    HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOREGSEL), Register);\n\n    /* Fetch the resultant value from the data window */\n    return HL::IoRegister::ReadRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOWIN));\n}\n\n/**\n * Reads a configuration entry from the I/O APIC redirection table.\n *\n * @param Controller\n *        Supplies the I/O APIC controller to read from.\n *\n * @param EntryNumber\n *        Supplies the redirection table entry number to read.\n *\n * @return This routine returns the populated redirection table entry.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nIOAPIC_REDIRECTION_REGISTER\nHL::Pic::ReadRedirectionEntry(IN PIOAPIC_DATA Controller,\n                              IN ULONG EntryNumber)\n{\n    IOAPIC_REDIRECTION_REGISTER Register;\n    ULONG Offset;\n\n    /* Derive the offset corresponding to the index */\n    Offset = IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE);\n\n    /* Read the low and high portions mapping to the 64-bit construct */\n    Register.Base = ReadIOApicRegister(Controller, Offset);\n    Register.Extended = ReadIOApicRegister(Controller, Offset + 1);\n\n    /* Return the redirection table entry */\n    return Register;\n}\n\n/**\n * Resolves the GSI and flags for the specified IRQ.\n *\n * @param Irq\n *        Supplies the IRQ number to get the GSI and flags for.\n *\n * @param Gsi\n *        Supplies a pointer to the memory area where the GSI will be stored.\n *\n * @param Flags\n *        Supplies a pointer to the memory area where the flags will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::ResolveInterruptOverride(IN UCHAR Irq,\n                                  OUT PULONG Gsi,\n                                  OUT PUSHORT Flags)\n{\n    ULONG Index;\n\n    /* Iterate over all I/O APIC overrides */\n    for(Index = 0; Index < IrqOverrideCount; Index++)\n    {\n        /* Check if this IRQ has been overridden */\n        if(IrqOverrides[Index].SourceIrq == Irq)\n        {\n            /* Return overridden GSI and flags */\n            *Flags = IrqOverrides[Index].Flags;\n            *Gsi = IrqOverrides[Index].GlobalSystemInterrupt;\n            return;\n        }\n    }\n\n    /* Return original IRQ number as GSI and no flags */\n    *Flags = 0;\n    *Gsi = (ULONG)Irq;\n}\n\n/**\n * Sends a Broadcast IPI (Inter-Processor Interrupt) to all processors in the system.\n *\n * @param Vector\n *        Supplies the hardware interrupt vector to trigger on the target processors.\n *\n * @param Self\n *        Supplies a boolean value indicating the broadcast scope.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::SendBroadcastIpi(IN ULONG Vector,\n                          IN BOOLEAN Self)\n{\n    PKPROCESSOR_BLOCK CurrentProcessorBlock, TargetProcessorBlock;\n    PACPI_SYSTEM_INFO SysInfo;\n    BOOLEAN Interrupts;\n    ULONG Index;\n\n    /* Get the current processor block */\n    CurrentProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n    if(CurrentProcessorBlock == NULLPTR)\n    {\n        /* Processor block not available, return */\n        return;\n    }\n\n    /* Get the ACPI system information */\n    HL::Acpi::GetSystemInformation(&SysInfo);\n\n    /* Check whether interrupts are enabled */\n    Interrupts = AR::CpuFunctions::InterruptsEnabled();\n\n    /* Disable interrupts */\n    AR::CpuFunctions::ClearInterruptFlag();\n\n    /* Iterate over all logical CPUs */\n    for(Index = 0; Index < SysInfo->CpuCount; Index++)\n    {\n        /* Retrieve the target processor block by its Logical CPU Number */\n        TargetProcessorBlock = KE::Processor::GetProcessorBlock(Index);\n\n        /* Only send to processors that exist and have successfully started */\n        if(TargetProcessorBlock != NULLPTR && TargetProcessorBlock->Started)\n        {\n            /* Check if this processor originated the broadcast */\n            if(TargetProcessorBlock->HardwareId == CurrentProcessorBlock->HardwareId)\n            {\n                /* Check if this is a self broadcast */\n                if(Self)\n                {\n                    /* Dispatch the IPI to the current processor */\n                    SendSelfIpi(Vector);\n                }\n            }\n            else\n            {\n                /* Dispatch the IPI to the target processor */\n                SendIpi(TargetProcessorBlock->HardwareId, Vector, APIC_DM_FIXED, APIC_DSH_Destination, APIC_TGM_EDGE);\n            }\n        }\n    }\n\n    /* Check whether interrupts need to be re-enabled */\n    if(Interrupts)\n    {\n        /* Re-enable interrupts */\n        AR::CpuFunctions::SetInterruptFlag();\n    }\n}\n\n/**\n * Signals to the APIC that handling an interrupt is complete.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::SendEoi(VOID)\n{\n    /* Send APIC EOI */\n    WriteApicRegister(APIC_EOI, 0);\n}\n\n/**\n * Sends an IPI (Inter-Processor Interrupt) to the specified CPU.\n *\n * @param ApicId\n *        Supplies a CPU APIC ID to send an IPI to.\n *\n * @param Vector\n *        Supplies the IPI vector to send.\n *\n * @param DeliveryMode\n *        Supplies the delivery mode for the IPI.\n *\n * @param DestinationShorthand\n *        Supplies the shorthand.\n *\n * @param TriggerMode\n *        Supplies the trigger mode (Edge or Level).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::SendIpi(IN ULONG ApicId,\n                 IN ULONG Vector,\n                 IN APIC_DM DeliveryMode,\n                 IN APIC_DSH DestinationShortHand,\n                 IN ULONG TriggerMode)\n{\n    APIC_COMMAND_REGISTER Register;\n    BOOLEAN Interrupts;\n\n    /* Check whether interrupts are enabled */\n    Interrupts = AR::CpuFunctions::InterruptsEnabled();\n\n    /* Disable interrupts */\n    AR::CpuFunctions::ClearInterruptFlag();\n\n    /* Check current APIC mode and destination */\n    if(ApicMode == APIC_MODE_X2APIC && DestinationShortHand == APIC_DSH_Self)\n    {\n        /* In x2APIC mode, a dedicated Self-IPI register is used */\n        WriteApicRegister(APIC_SIPI, Vector);\n\n        /* Check whether interrupts need to be re-enabled */\n        if(Interrupts)\n        {\n            /* Check whether interrupts need to be re-enabled */\n            AR::CpuFunctions::SetInterruptFlag();\n        }\n\n        /* Nothing more to do */\n        return;\n    }\n\n    /* Prepare APIC command register struct */\n    Register.LongLong = 0;\n    Register.DeliveryMode = DeliveryMode;\n    Register.Destination = ApicId;\n    Register.DestinationShortHand = DestinationShortHand;\n    Register.Level = 1;\n    Register.TriggerMode = TriggerMode;\n    Register.Vector = Vector;\n\n    /* Check current APIC mode */\n    if(ApicMode == APIC_MODE_X2APIC)\n    {\n        /* Set destination APIC ID */\n        Register.Long1 = ApicId;\n\n        /* Send IPI using x2APIC mode */\n        WriteApicRegister(APIC_ICR0, Register.LongLong);\n    }\n    else\n    {\n        /* Wait for the APIC to clear the delivery status */\n        while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)\n        {\n            /* Yield the processor */\n            AR::CpuFunctions::YieldProcessor();\n        }\n\n        /* In xAPIC compatibility mode, write the command to the ICR registers */\n        WriteApicRegister(APIC_ICR1, Register.Long1);\n        WriteApicRegister(APIC_ICR0, Register.Long0);\n\n        /* Check if this is a Self-IPI */\n        if(DestinationShortHand == APIC_DSH_Self)\n        {\n            /* Wait until the interrupt physically arrives in the requested state */\n            while((ReadApicRegister((APIC_REGISTER)(APIC_IRR + (Vector / 32))) & (1UL << (Vector % 32))) == 0)\n            {\n                /* Yield the processor */\n                AR::CpuFunctions::YieldProcessor();\n            }\n        }\n    }\n\n    /* Check whether interrupts need to be re-enabled */\n    if(Interrupts)\n    {\n        /* Re-enable interrupts */\n        AR::CpuFunctions::SetInterruptFlag();\n    }\n}\n\n/**\n * Sends a Self-IPI (Inter-Processor Interrupt) to the current CPU.\n *\n * @param Vector\n *        Supplies the IPI vector to send.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Pic::SendSelfIpi(IN ULONG Vector)\n{\n    SendIpi(0, Vector, APIC_DM_FIXED, APIC_DSH_Self, APIC_TGM_EDGE);\n}\n\n/**\n * Translates a given Global System Interrupt (GSI) into an active system interrupt vector.\n *\n * @param Gsi\n *        Supplies the GSI to translate.\n *\n * @return This routine returns the underlying associated system vector mapping.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nUCHAR\nHL::Pic::TranslateGsiToVector(IN ULONG Gsi)\n{\n    IOAPIC_REDIRECTION_REGISTER Register;\n    PIOAPIC_DATA Controller;\n    ULONG EntryNumber;\n    XTSTATUS Status;\n\n    /* Find the APIC controller for the GSI */\n    Status = GetIoApicController(Gsi, &Controller, &EntryNumber);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* GSI maps to an invalid controller, return free */\n        return IOAPIC_VECTOR_FREE;\n    }\n\n    /* Read the redirection table entry */\n    Register.Base = ReadIOApicRegister(Controller, IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE));\n\n    /* Return the vector */\n    return (UCHAR)Register.Vector;\n}\n\n/**\n * Writes to the APIC register.\n *\n * @param Register\n *        Supplies the APIC register to write to.\n *\n * @param Value\n *        Supplies the value to write to the APIC register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nHL::Pic::WriteApicRegister(IN APIC_REGISTER Register,\n                           IN ULONGLONG Value)\n{\n    if(ApicMode == APIC_MODE_X2APIC)\n    {\n        /* Write to x2APIC MSR */\n        AR::CpuFunctions::WriteModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register), Value);\n    }\n    else\n    {\n        /* Write to xAPIC */\n        HL::IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);\n    }\n}\n\n/**\n * Writes a value to the I/O APIC register.\n *\n * @param Controller\n *        Supplies the I/O APIC controller to write to.\n *\n * @param Register\n *        Supplies the I/O APIC register to write to.\n *\n * @param DataValue\n *        Supplies the value to write to the designated I/O APIC register.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nHL::Pic::WriteIOApicRegister(IN PIOAPIC_DATA Controller,\n                             IN UCHAR Register,\n                             IN ULONG DataValue)\n{\n    /* Provide the index to the control port */\n    HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOREGSEL), Register);\n\n    /* Commit the value via the data port */\n    HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOWIN), DataValue);\n}\n\n/**\n * Writes a configuration entry into the I/O APIC redirection table.\n *\n * @param Controller\n *        Supplies the I/O APIC controller to write to.\n *\n * @param EntryNumber\n *        Supplies the redirection table entry number to write.\n *\n * @param EntryData\n *        Supplies the redirection table entry data to write.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nHL::Pic::WriteRedirectionEntry(IN PIOAPIC_DATA Controller,\n                               IN ULONG EntryNumber,\n                               IN IOAPIC_REDIRECTION_REGISTER EntryData)\n{\n    ULONG Offset;\n\n    /* Calculate the offset of the redirection entry */\n    Offset = IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE);\n\n    /* Mask the entry to prevent spurious interrupts */\n    WriteIOApicRegister(Controller, Offset, IOAPIC_RTE_MASKED);\n\n    /* Write the lower and upper chunks of the entry */\n    WriteIOApicRegister(Controller, Offset + 1, EntryData.Extended);\n    WriteIOApicRegister(Controller, Offset, EntryData.Base);\n}\n"
  },
  {
    "path": "xtoskrnl/hl/x86/rtc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/x86/rtc.cc\n * DESCRIPTION:     Hardware Real-Time Clock (RTC) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Queries the hardware Real-Time Clock (RTC) for the current date and time.\n *\n * @param Time\n *        Supplies a pointer to a structure to receive the system time.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Rtc::GetRealTimeClock(OUT PTIME_FIELDS Time)\n{\n    UCHAR Century1, Century2, CenturyRegister, RegisterB;\n    TIME_FIELDS TimeProbe1, TimeProbe2;\n    PACPI_FADT FadtTable;\n    BOOLEAN PostMeridiem;\n    XTSTATUS Status;\n    ULONG Index;\n\n    /* Locate the ACPI FADT table */\n    Status = HL::Acpi::GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&FadtTable);\n    if(Status == STATUS_SUCCESS && FadtTable && FadtTable->CenturyAlarmIndex)\n    {\n        /* Cache the dynamically provided Century register index */\n        CenturyRegister = FadtTable->CenturyAlarmIndex;\n    }\n    else\n    {\n        /* Century register is unavailable */\n        CenturyRegister = 0;\n        Century1 = 0;\n        Century2 = 0;\n    }\n\n    /* Read the RTC Status Register B to determine hardware data formats */\n    RegisterB = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_B);\n\n    /* Assume failure */\n    Status = STATUS_UNSUCCESSFUL;\n\n    /* Execute a maximum of 100 retries to obtain a stable RTC snapshot */\n    for(Index = 0; Index < 100; Index++)\n    {\n        /* Wait until the RTC hardware finishes any ongoing background updates */\n        while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)\n        {\n            /* Yield the processor */\n            AR::CpuFunctions::YieldProcessor();\n        }\n\n        /* Latch the first sequential hardware time snapshot */\n        TimeProbe1.Hour = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_HOUR);\n        TimeProbe1.Minute = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MINUTE);\n        TimeProbe1.Second = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_SECOND);\n        TimeProbe1.Day = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_DAY);\n        TimeProbe1.Month = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MONTH);\n        TimeProbe1.Year = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_YEAR);\n        TimeProbe1.Weekday = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_WEEKDAY);\n\n        /* Check if Century register is available */\n        if(CenturyRegister)\n        {\n            /* Read the corresponding Century register */\n            Century1 = HL::Firmware::ReadCmosRegister(CenturyRegister);\n        }\n\n        /* Wait until the RTC hardware finishes any ongoing background updates */\n        while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)\n        {\n            /* Yield the processor */\n            AR::CpuFunctions::YieldProcessor();\n        }\n\n        /* Latch the second sequential hardware time snapshot for verification */\n        TimeProbe2.Hour = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_HOUR);\n        TimeProbe2.Minute = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MINUTE);\n        TimeProbe2.Second = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_SECOND);\n        TimeProbe2.Day = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_DAY);\n        TimeProbe2.Month = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_MONTH);\n        TimeProbe2.Year = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_YEAR);\n        TimeProbe2.Weekday = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_WEEKDAY);\n\n        /* Check if Century register is available */\n        if(CenturyRegister)\n        {\n            /* Read the corresponding Century register */\n            Century2 = HL::Firmware::ReadCmosRegister(CenturyRegister);\n        }\n\n        /* Compare both snapshots to guarantee data consistency */\n        if((TimeProbe1.Hour == TimeProbe2.Hour) &&\n           (TimeProbe1.Minute == TimeProbe2.Minute) &&\n           (TimeProbe1.Second == TimeProbe2.Second) &&\n           (TimeProbe1.Day == TimeProbe2.Day) &&\n           (TimeProbe1.Month == TimeProbe2.Month) &&\n           (TimeProbe1.Year == TimeProbe2.Year) &&\n           (TimeProbe1.Weekday == TimeProbe2.Weekday) &&\n           (Century1 == Century2))\n        {\n            /* A stable time sample was acquired, break the loop */\n            Status = STATUS_SUCCESS;\n            break;\n        }\n    }\n\n    /* Copy the validated data into the output buffer */\n    Time->Hour = TimeProbe1.Hour;\n    Time->Minute = TimeProbe1.Minute;\n    Time->Second = TimeProbe1.Second;\n    Time->Milliseconds = 0;\n    Time->Day = TimeProbe1.Day;\n    Time->Month = TimeProbe1.Month;\n    Time->Year = TimeProbe1.Year;\n    Time->Weekday = TimeProbe1.Weekday;\n\n    /* Check if RTC is operating in 12-hour mode */\n    if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))\n    {\n        /* Cache the PM status and strip the hardware flag */\n        PostMeridiem = (Time->Hour & CMOS_RTC_POST_MERIDIEM) != 0;\n        Time->Hour &= ~CMOS_RTC_POST_MERIDIEM;\n    }\n\n    /* Convert Binary-Coded Decimal (BCD) values to standard integers if necessary */\n    if(!(RegisterB & CMOS_REGISTER_B_BINARY))\n    {\n        /* Decode all standard time fields */\n        Time->Hour = BCD_TO_DECIMAL(Time->Hour);\n        Time->Minute = BCD_TO_DECIMAL(Time->Minute);\n        Time->Second = BCD_TO_DECIMAL(Time->Second);\n        Time->Day = BCD_TO_DECIMAL(Time->Day);\n        Time->Month = BCD_TO_DECIMAL(Time->Month);\n        Time->Year = BCD_TO_DECIMAL(Time->Year);\n        Time->Weekday = BCD_TO_DECIMAL(Time->Weekday);\n\n        /* Check if Century byte is available */\n        if(CenturyRegister)\n        {\n            /* Convert Century byte */\n            Century1 = BCD_TO_DECIMAL(Century1);\n        }\n    }\n\n    /* Standardize hours into a strict 24-hour format */\n    if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))\n    {\n        /* Adjust for midnight and noon boundary cases */\n        if(Time->Hour == 12)\n        {\n            /* 12 AM evaluates to 00:00, 12 PM evaluates to 12:00 */\n            Time->Hour = PostMeridiem ? 12 : 0;\n        }\n        else\n        {\n            /* Add 12 hours for PM times */\n            Time->Hour += PostMeridiem ? 12 : 0;\n        }\n    }\n\n    /* Merge the century offset with the 2-digit hardware year */\n    if(Century1 >= 19 && Century1 <= 30)\n    {\n        /* Utilize the hardware-provided century base */\n        Time->Year += (Century1 * 100);\n    }\n    else\n    {\n        /* Century byte is invalid; apply the sliding window */\n        Time->Year += (Time->Year > 80) ? 1900 : 2000;\n    }\n\n    /* Return status code */\n    return Status;\n}\n\n/**\n * Updates the hardware Real-Time Clock (RTC) with the provided date and time.\n *\n * @param Time\n *        Supplies a pointer to a structure with populated data and time.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Rtc::SetRealTimeClock(IN PTIME_FIELDS Time)\n{\n    UCHAR Century, CenturyRegister, RegisterB;\n    TIME_FIELDS SystemTime;\n    BOOLEAN PostMeridiem;\n    PACPI_FADT FadtTable;\n    XTSTATUS Status;\n\n    /* Validate the input time boundaries against calendar limits */\n    if(Time->Hour > 23 || Time->Minute > 59 || Time->Second > 59 ||\n       Time->Day == 0 || Time->Day > 31 || Time->Month == 0 ||\n       Time->Month > 12 || Time->Weekday == 0 || Time->Weekday > 7)\n    {\n        /* Invalid time parameters, return error code */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Assume Ante Meridiem */\n    PostMeridiem = FALSE;\n\n    /* Extract local copy */\n    SystemTime.Hour = Time->Hour;\n    SystemTime.Minute = Time->Minute;\n    SystemTime.Second = Time->Second;\n    SystemTime.Day = Time->Day;\n    SystemTime.Month = Time->Month;\n    SystemTime.Year = (Time->Year % 100);\n    SystemTime.Weekday = Time->Weekday;\n    Century = (UCHAR)(Time->Year / 100);\n\n    /* Locate the ACPI FADT table */\n    Status = HL::Acpi::GetAcpiTable(ACPI_FADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&FadtTable);\n    if(Status == STATUS_SUCCESS && FadtTable && FadtTable->CenturyAlarmIndex)\n    {\n        /* Cache the dynamically provided Century register index */\n        CenturyRegister = FadtTable->CenturyAlarmIndex;\n    }\n    else\n    {\n        /* Century register is unavailable */\n        CenturyRegister = 0;\n    }\n\n    /* Read the RTC Status Register B to determine hardware data formats */\n    RegisterB = HL::Firmware::ReadCmosRegister(CMOS_REGISTER_B);\n\n    /* Format hours if the hardware is running in 12-hour mode */\n    if(!(RegisterB & CMOS_REGISTER_B_24_HOUR))\n    {\n        /* Determine if the time is PM */\n        PostMeridiem = (SystemTime.Hour >= 12);\n\n        /* Adjust for midnight and noon boundary cases */\n        if(SystemTime.Hour == 0)\n        {\n            /* Midnight evaluates to 12 AM */\n            SystemTime.Hour = 12;\n        }\n        else if(SystemTime.Hour > 12)\n        {\n            /* Post-noon hour */\n            SystemTime.Hour -= 12;\n        }\n\n        /* Convert to BCD first if needed and apply the hardware PM flag */\n        if(!(RegisterB & CMOS_REGISTER_B_BINARY))\n        {\n            /* Encode to BCD */\n            SystemTime.Hour = DECIMAL_TO_BCD(SystemTime.Hour);\n        }\n\n        /* Apply the hardware PM flag to the highest bit */\n        if(PostMeridiem)\n        {\n            /* Set PM flag */\n            SystemTime.Hour |= CMOS_RTC_POST_MERIDIEM;\n        }\n    }\n    else\n    {\n        /* 24-hour mode, simply encode to BCD if necessary */\n        if(!(RegisterB & CMOS_REGISTER_B_BINARY))\n        {\n            /* Encode to BCD */\n            SystemTime.Hour = DECIMAL_TO_BCD(SystemTime.Hour);\n        }\n    }\n\n    /* Convert remaining standard fields to BCD if necessary */\n    if(!(RegisterB & CMOS_REGISTER_B_BINARY))\n    {\n        /* Encode all standard time fields */\n        SystemTime.Minute  = DECIMAL_TO_BCD(SystemTime.Minute);\n        SystemTime.Second  = DECIMAL_TO_BCD(SystemTime.Second);\n        SystemTime.Day     = DECIMAL_TO_BCD(SystemTime.Day);\n        SystemTime.Month   = DECIMAL_TO_BCD(SystemTime.Month);\n        SystemTime.Year    = DECIMAL_TO_BCD(SystemTime.Year);\n        SystemTime.Weekday = DECIMAL_TO_BCD((UCHAR)SystemTime.Weekday);\n\n        /* Encode the Century byte */\n        Century = DECIMAL_TO_BCD(Century);\n    }\n\n    /* Freeze the RTC to prevent data tearing */\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_B, RegisterB | CMOS_REGISTER_B_SET_CLOCK);\n\n    /* Push the formatted time values into the hardware registers */\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_HOUR, SystemTime.Hour);\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_MINUTE, SystemTime.Minute);\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_SECOND, SystemTime.Second);\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_DAY, SystemTime.Day);\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_MONTH, SystemTime.Month);\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_YEAR, SystemTime.Year);\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_WEEKDAY, SystemTime.Weekday);\n\n    /* Check if Century register is available */\n    if(CenturyRegister)\n    {\n        /* Write the corresponding Century register */\n        HL::Firmware::WriteCmosRegister(CenturyRegister, Century);\n    }\n\n    /* Unfreeze the RTC */\n    HL::Firmware::WriteCmosRegister(CMOS_REGISTER_B, RegisterB);\n\n    /* Return success status code */\n    return STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "xtoskrnl/hl/x86/timer.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/hl/x86/timer.cc\n * DESCRIPTION:     Timer support for x86 (i686/AMD64)\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Calibrates the Local APIC timer frequency.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Timer::CalibrateApicTimer()\n{\n    ULONG CurrentCount, Frequency, InitialCount;\n\n    /* Get APIC timer frequency from the Core Crystal Clock */\n    if(TimerCapabilities.Art && TimerCapabilities.TimerFrequency != 0)\n    {\n        /* CCC available, use it as the source of APIC timer frequency */\n        Frequency = TimerCapabilities.TimerFrequency;\n    }\n    else\n    {\n        /* CCC unavailable, fallback to PIT calibration */\n        InitialCount = 0xFFFFFFFF;\n\n        /* Load the initial count into the APIC Timer and begin the countdown */\n        HL::Pic::WriteApicRegister(APIC_TICR, InitialCount);\n\n        /* Stall CPU execution for exactly 10 milliseconds */\n        StallExecution(10000);\n\n        /* Read current tick count from APIC timer and clear APIC timer */\n        CurrentCount = HL::Pic::ReadApicRegister(APIC_TCCR);\n        HL::Pic::WriteApicRegister(APIC_TICR, 0);\n\n        /* Calculate APIC timer frequency based on ticks passed */\n        Frequency = (InitialCount - CurrentCount) * 100;\n\n        /* Verify APIC timer frequency */\n        if(Frequency == 0)\n        {\n            /* Unable to calibrate APIC timer, return error */\n            return STATUS_UNSUCCESSFUL;\n        }\n    }\n\n    /* Save APIC timer frequency */\n    TimerFrequency = Frequency;\n\n    /* Print APIC timer frequency and return success */\n    DebugPrint(L\"APIC Timer calibrated: %u Ticks/s\\n\", TimerFrequency);\n    return STATUS_SUCCESS;\n}\n\n/**\n * Calibrates the Invariant TSC frequency.\n *\n * @return This routine returns the calculated TSC frequency in Hz.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nHL::Timer::CalibrateTscCounter(VOID)\n{\n    ULONGLONG InitialTickCount, FinalTickCount;\n    ULONG TscAux;\n\n    /* Get TSC frequency from the Core Crystal Clock */\n    if(TimerCapabilities.Art && TimerCapabilities.TimerFrequency != 0 && TimerCapabilities.TscDenominator != 0)\n    {\n        /* CCC available, use it as the source of TSC frequency */\n        return (TimerCapabilities.TimerFrequency * TimerCapabilities.TscNumerator) / TimerCapabilities.TscDenominator;\n    }\n\n    /* Latch the initial TSC value */\n    InitialTickCount = AR::CpuFunctions::ReadTimeStampCounterProcessor(&TscAux);\n\n    /* Stall CPU execution for exactly 10 milliseconds */\n    StallExecution(10000);\n\n    /* Read current tick count from TSC */\n    FinalTickCount = AR::CpuFunctions::ReadTimeStampCounterProcessor(&TscAux);\n\n    /* Calculate the elapsed ticks over the 10ms window */\n    return (FinalTickCount - InitialTickCount) * 100;\n}\n\n/**\n * Calculates and configures the system time increments based on hardware timer properties.\n *\n * @param BaseFrequency\n *        Supplies the base running frequency of the hardware timer in Hz.\n *\n * @param HardwareDivider\n *        Supplies the programmed threshold/divider for the interrupt generation.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::ConfigureTimeIncrement(IN ULONGLONG BaseFrequency, IN ULONGLONG HardwareDivider)\n{\n    /* Calculate the time increment */\n    TimeIncrement = (ULONG)((10000000ULL * HardwareDivider) / BaseFrequency);\n\n    /* Extract the fractional remainder */\n    FractionalIncrement = (ULONG)((10000000000ULL * HardwareDivider) / BaseFrequency) % 1000;\n    RunningFraction = 0;\n\n    /* Synchronize the kernel's global timekeeping state with the new resolution settings */\n    KE::SystemTime::SetTimeIncrement(TimeIncrement, TimeIncrement);\n}\n\n/**\n * Initializes the High Precision Event Timer (HPET) by discovering its ACPI configuration and mapping\n * its hardware registers into the kernel's virtual address space.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Timer::DetectHpet(VOID)\n{\n    ULONGLONG CounterPeriod;\n    PACPI_HPET HpetTable;\n    PHPET_REGISTERS Hpet;\n    XTSTATUS Status;\n\n    /* Reset global HPET state */\n    HpetAddress = NULLPTR;\n    HpetFrequency = 0;\n\n    /* Retrieve the HPET table from the ACPI subsystem */\n    Status = HL::Acpi::GetAcpiTable(ACPI_HPET_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&HpetTable);\n    if(Status != STATUS_SUCCESS || !HpetTable)\n    {\n        /* HPET is not present on this system, return error code */\n        return STATUS_NOT_FOUND;\n    }\n\n    /* Verify that the hardware registers are accessible via MMIO */\n    if(HpetTable->BaseAddress.AddressSpaceID != ACPI_ADDRESS_SPACE_MEMORY)\n    {\n        /* HPET base address not found, return error */\n        return STATUS_NOT_SUPPORTED;\n    }\n\n    /* Extract the physical base address from the Generic Address Structure (GAS) */\n    if(HpetTable->BaseAddress.Address.QuadPart == 0)\n    {\n        /* Invalid address provided by firmware, return error code */\n        return STATUS_UNSUCCESSFUL;\n    }\n\n    /* Map the physical hardware registers into the kernel's virtual memory space */\n    Status = MM::HardwarePool::MapHardwareMemory(HpetTable->BaseAddress.Address, 1, FALSE, &HpetAddress);\n    if(Status != STATUS_SUCCESS || !HpetAddress)\n    {\n        /* Memory mapping failed, return error code */\n        return Status;\n    }\n\n    /* Configure the mapped memory region with Write-Through caching semantics */\n    MM::HardwarePool::MarkHardwareMemoryWriteThrough(HpetAddress, 1);\n\n    /* Extract the main counter period */\n    Hpet = (PHPET_REGISTERS)HpetAddress;\n    CounterPeriod = (Hpet->GeneralCapabilities >> 32) & 0xFFFFFFFF;\n\n    /* Calculate the HPET operating frequency */\n    if(CounterPeriod != 0)\n    {\n        /* Convert femtoseconds per tick to ticks per second */\n        HpetFrequency = 1000000000000000ULL / CounterPeriod;\n    }\n    else\n    {\n        /* Assume the standard minimum HPET frequency (14.31818 MHz) */\n        HpetFrequency = 14318180;\n    }\n\n    /* Enable the HPET main counter and disable legacy replacement */\n    Hpet->GeneralConfiguration = (Hpet->GeneralConfiguration & ~HPET_CONFIG_LEGACY_REPLACEMENT) | HPET_CONFIG_ENABLE;\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Services the primary hardware clock interrupt, advancing the global system time,\n * maintaining local CPU thread quantums and performing profiling.\n *\n * @param TrapFrame\n *        Supplies a pointer to the hardware trap frame representing the interrupted execution context.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::Timer::HandleClockInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    KRUNLEVEL RunLevel;\n    ULONG Increment;\n\n    /* Start the interrupt */\n    HL::Irq::BeginSystemInterrupt(CLOCK_LEVEL, &RunLevel);\n\n    /* Check if PIT is the source of the interrupt */\n    if(ClockType == TimerPit)\n    {\n        /* Check if system clock initialized the rollover */\n        if(PitRollover != 0)\n        {\n            /* Update the PIT counter */\n            PitPerformanceCounter += PitRollover;\n        }\n    }\n\n    /* Check if profiling is currently active */\n    if(ProfilingEnabled)\n    {\n        /* Retrieve the processor-specific control block */\n        Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n        /* Trigger a profile sample if the countdown has expired */\n        if(Prcb->ProfilingCountdown == 0)\n        {\n            /* Dispatch the profile interrupt */\n            HL::Irq::HandleProfileInterrupt(TrapFrame);\n\n            /* Reset the local countdown */\n            Prcb->ProfilingCountdown = ProfilingTicks;\n        }\n\n        /* Decrement the profiling countdown for the current hardware tick */\n        Prcb->ProfilingCountdown--;\n    }\n\n    /* Initialize the increment and update the fractional drift accumulator */\n    Increment = TimeIncrement;\n    RunningFraction += FractionalIncrement;\n\n    /* Check for fractional overflow */\n    if(RunningFraction >= 1000)\n    {\n        /* Apply the compensation tick and normalize the fractional remainder */\n        Increment++;\n        RunningFraction -= 1000;\n    }\n\n    /* Route the timekeeping logic based on the underlying timer topology */\n    if(ClockType == TimerLapic)\n    {\n        /* Restrict global system time updates exclusively to the Bootstrap Processor */\n        if(KE::Processor::GetCurrentProcessorNumber() == 0)\n        {\n            /* Advance the global system time */\n            KE::SystemTime::UpdateSystemTime(TrapFrame, Increment, RunLevel);\n        }\n        else\n        {\n            /* Limit Application Processors (APs) to update runtimes */\n            KE::Dispatcher::UpdateRunTime(TrapFrame, RunLevel);\n        }\n    }\n    else\n    {\n        /* Advance the global system time */\n        KE::SystemTime::UpdateSystemTime(TrapFrame, Increment, RunLevel);\n\n        /* Broadcast an IPI to awaken all APs for local quantum updates */\n        HL::Pic::SendBroadcastIpi(APIC_VECTOR_CLOCK_IPI, FALSE);\n    }\n\n    /* End the interrupt */\n    HL::Irq::EndInterrupt(TrapFrame, RunLevel);\n}\n\n/**\n * Services the inter-processor clock interrupt, maintaining local CPU thread quantums and performing profiling.\n *\n * @param TrapFrame\n *        Supplies a pointer to the hardware trap frame representing the interrupted execution context.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nHL::Timer::HandleClockIpiInterrupt(IN PKTRAP_FRAME TrapFrame)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    KRUNLEVEL RunLevel;\n\n    /* Start the interrupt */\n    HL::Irq::BeginSystemInterrupt(CLOCK_LEVEL, &RunLevel);\n\n    /* Check if profiling is currently active */\n    if(ProfilingEnabled)\n    {\n        /* Retrieve the processor-specific control block */\n        Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n        /* Trigger a profile sample if the countdown has expired */\n        if(Prcb->ProfilingCountdown == 0)\n        {\n            /* Dispatch the profile interrupt */\n            HL::Irq::HandleProfileInterrupt(TrapFrame);\n\n            /* Reset the local countdown */\n            Prcb->ProfilingCountdown = ProfilingTicks;\n        }\n\n        /* Decrement the profiling countdown for the current hardware tick */\n        Prcb->ProfilingCountdown--;\n    }\n\n    /* Call the kernel to update runtimes */\n    KE::Dispatcher::UpdateRunTime(TrapFrame, RunLevel);\n\n    /* End the interrupt */\n    HL::Irq::EndInterrupt(TrapFrame, RunLevel);\n}\n\n/**\n * Initializes and calibrates the Local APIC Timer.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Timer::InitializeApicTimer(VOID)\n{\n    APIC_LVT_REGISTER LvtRegister;\n    XTSTATUS Status;\n    ULONG Divider;\n\n    /* Set APIC timer to divide by 1 */\n    HL::Pic::WriteApicRegister(APIC_TDCR, TIMER_DivideBy1);\n\n    /* Calibrate the APIC timer */\n    Status = CalibrateApicTimer();\n    if(Status != STATUS_SUCCESS)\n    {\n        /* APIC calibration failed, return error code */\n        return Status;\n    }\n\n    /* Calculate the hardware threshold */\n    Divider = TimerFrequency / 1000;\n\n    /* Program the APIC timer for periodic mode */\n    LvtRegister.Long = 0;\n    LvtRegister.Mask = 0;\n    LvtRegister.TimerMode = 1;\n    LvtRegister.DeliveryMode = APIC_DM_FIXED;\n    LvtRegister.TriggerMode = APIC_TGM_EDGE;\n    LvtRegister.Vector = APIC_VECTOR_CLOCK;\n    HL::Pic::WriteApicRegister(APIC_TMRLVTR, LvtRegister.Long);\n\n    /* Jump-start the heartbeat */\n    HL::Pic::WriteApicRegister(APIC_TICR, Divider);\n\n    /* Configure the kernel timekeeping abstractions based on calibrated APIC metrics */\n    HL::Timer::ConfigureTimeIncrement(TimerFrequency, Divider);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes the High Precision Event Timer (HPET) Timer.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Timer::InitializeHpetTimer(VOID)\n{\n    ULONGLONG ClockPeriodTicks, TicksPerMillisecond;\n    PHPET_REGISTERS Hpet;\n\n    /* Ensure the HPET hardware registers are successfully mapped */\n    if(!HpetAddress)\n    {\n        /* The hardware mapping is not present, return error code */\n        return STATUS_UNSUCCESSFUL;\n    }\n\n    /* Cast the mapped virtual address to the HPET hardware register */\n    Hpet = (PHPET_REGISTERS)HpetAddress;\n\n    /* Halt the main counter and disable legacy routing */\n    Hpet->GeneralConfiguration &= ~(HPET_CONFIG_ENABLE | HPET_CONFIG_LEGACY_REPLACEMENT);\n\n    /* Reset the main counter to a known baseline */\n    Hpet->MainCounterValue = 0;\n\n    /* Calculate the required hardware ticks for a standard 1-millisecond system clock interval */\n    TicksPerMillisecond = HpetFrequency / 1000;\n    ClockPeriodTicks = TicksPerMillisecond * 1;\n\n    /* Configure Comparator 0 for periodic mode with interrupt enable */\n    Hpet->Timers[0].Configuration |= (HPET_TIMER_CONFIG_ENABLED |\n                                      HPET_TIMER_CONFIG_PERIODIC |\n                                      HPET_TIMER_CONFIG_VALUE_ACCUMULATOR);\n\n    /* Write the initial comparator value */\n    Hpet->Timers[0].Comparator = ClockPeriodTicks;\n\n    /* Write the periodic interval into the accumulator */\n    Hpet->Timers[0].Comparator = ClockPeriodTicks;\n\n    /* Enable the main counter and activate legacy replacement routing */\n    Hpet->GeneralConfiguration |= (HPET_CONFIG_ENABLE | HPET_CONFIG_LEGACY_REPLACEMENT);\n\n    /* Configure the kernel timekeeping abstractions based on HPET metrics */\n    ConfigureTimeIncrement(HpetFrequency, ClockPeriodTicks);\n\n    /* Route the IRQ 0 to the primary system clock vector */\n    HL::Pic::AllocateSystemInterrupt(0, CLOCK_LEVEL, APIC_VECTOR_CLOCK);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes the legacy Programmable Interval Timer (PIT).\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nHL::Timer::InitializePitTimer(VOID)\n{\n    UCHAR LowByte, HighByte;\n    ULONG Divider;\n\n    /* Set the target frequency (1000 Hz) and calculate the required hardware divider */\n    Divider = PIT_BASE_FREQUENCY / 1000;\n\n    /* Clamp the calculated divider to prevent 16-bit hardware overflow */\n    if(Divider > 65535)\n    {\n        /* Cap the maximum possible interval */\n        Divider = 65535;\n    }\n    else if(Divider < 1)\n    {\n        /* Enforce a minimum hardware divider */\n        Divider = 1;\n    }\n\n    /* Persist the calculated divider into a global state */\n    PitRollover = Divider;\n\n    /* Split the 16-bit divider into an independent LSB and MSB */\n    LowByte = (UCHAR)(Divider & 0xFF);\n    HighByte = (UCHAR)((Divider >> 8) & 0xFF);\n\n    /* Configure Channel 0 for LSB/MSB access, Mode 2 */\n    HL::IoPort::WritePort8(PIT_COMMAND_PORT, PIT_CMD_CHANNEL0 |\n                                             PIT_CMD_ACCESS_LOWBYTE_HIGHBYTE |\n                                             PIT_MODE2_RATE_GENERATOR);\n\n    /* Transmit the Least Significant Byte (LSB) */\n    HL::IoPort::WritePort8(PIT_DATA_PORT0, LowByte);\n\n    /* Transmit the Most Significant Byte (MSB) */\n    HL::IoPort::WritePort8(PIT_DATA_PORT0, HighByte);\n\n    /* Configure the kernel timekeeping abstractions based on legacy PIT metrics */\n    ConfigureTimeIncrement(PIT_BASE_FREQUENCY, Divider);\n\n    /* Route the standard PIT IRQ 0 to the primary system clock vector */\n    HL::Pic::AllocateSystemInterrupt(0, CLOCK_LEVEL, APIC_VECTOR_CLOCK);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Performs the primary initialization of the system timer.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::InitializeTimer(VOID)\n{\n    XTSTATUS Status;\n\n    /* Probe hardware capabilities */\n    ProbeTimerType();\n\n    /* Check if a suitable hardware timer was selected */\n    if(TimerRoutines.InitializeClock)\n    {\n        /* Proceed with system clock initialization */\n        Status = TimerRoutines.InitializeClock();\n        if(Status != STATUS_SUCCESS)\n        {\n            /* System cannot operate without a functional system clock interrupt */\n            KE::Crash::Panic(0);\n        }\n    }\n\n    /* Set the default system profile interval */\n    HL::Timer::SetProfileInterval(1000);\n\n    /* Ensure the profile interrupt generation is explicitly disabled */\n    StopProfileInterrupt(ProfileXtKernel);\n\n    /* Register the system clock interrupt handler */\n    HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_CLOCK, HandleClockInterrupt);\n    HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_CLOCK_IPI, HandleClockIpiInterrupt);\n}\n\n/**\n * Performs an initial Timer initialization, discovering hardware and routing the Timer Dispatch table.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::ProbeTimerType(VOID)\n{\n    PACPI_TIMER_INFO AcpiTimerInfo;\n    WCHAR ParameterValue[16];\n    XTSTATUS Status;\n\n    /* Enumerate hardware timing capabilities */\n    QueryTimerCapabilities();\n\n    /* Discover and map the High Precision Event Timer */\n    Status = DetectHpet();\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Diagnostic warning upon HPET subsystem initialization failure */\n        DebugPrint(L\"TIMER: HPET initialization failed or HPET not present\\n\");\n    }\n\n    /* Initialize the hardware selection states */\n    ClockType = TimerNone;\n    TimerType = TimerNone;\n\n    /* Query the kernel boot environment for a user-specified system clock override */\n    if(KE::BootInformation::GetKernelParameterValue(L\"CLOCK\", ParameterValue, 16) == STATUS_SUCCESS)\n    {\n        /* Evaluate the boot parameter string */\n        if(RTL::WideString::FindWideStringInsensitive(ParameterValue, L\"HPET\"))\n        {\n            /* Designate the HPET */\n            ClockType = TimerHpet;\n        }\n        else if(RTL::WideString::FindWideStringInsensitive(ParameterValue, L\"LAPIC\"))\n        {\n            /* Designate the Local APIC */\n            ClockType = TimerLapic;\n        }\n        else if(RTL::WideString::FindWideStringInsensitive(ParameterValue, L\"PIT\"))\n        {\n            /* Designate the legacy PIT */\n            ClockType = TimerPit;\n        }\n    }\n\n    /* Query the kernel boot environment for a user-specified performance counter override */\n    if(KE::BootInformation::GetKernelParameterValue(L\"TIMER\", ParameterValue, 16) == STATUS_SUCCESS)\n    {\n        /* Evaluate the boot parameter string */\n        if(RTL::WideString::FindWideStringInsensitive(ParameterValue, L\"ACPI\") ||\n           RTL::WideString::FindWideStringInsensitive(ParameterValue, L\"PM\"))\n        {\n            /* Designate the ACPI PM Timer */\n            TimerType = TimerAcpiPm;\n        }\n        else if(RTL::WideString::FindWideStringInsensitive(ParameterValue, L\"HPET\"))\n        {\n            /* Designate the HPET */\n            TimerType = TimerHpet;\n        }\n        else if(RTL::WideString::FindWideStringInsensitive(ParameterValue, L\"PIT\"))\n        {\n            /* Designate the legacy PIT */\n            TimerType = TimerPit;\n        }\n        else if(RTL::WideString::FindWideStringInsensitive(ParameterValue, L\"TSC\"))\n        {\n            /* Designate the Invariant TSC */\n            TimerType = TimerTsc;\n        }\n    }\n\n    /* Verify the hardware viability of the requested system clock */\n    if(ClockType != TimerNone && !ValidateTimerSupport(ClockType, TRUE))\n    {\n        /* Invalidate the clock selection upon hardware validation failure */\n        DebugPrint(L\"TIMER: Requested system clock [%d] unavailable\\n\", ClockType);\n        ClockType = TimerNone;\n    }\n\n    /* Verify the hardware viability of the requested performance counter */\n    if(TimerType != TimerNone && !ValidateTimerSupport(TimerType, FALSE))\n    {\n        /* Invalidate the counter selection upon hardware validation failure */\n        DebugPrint(L\"TIMER: Requested hardware counter [%d] unavailable\\n\", TimerType);\n        TimerType = TimerNone;\n    }\n\n    /* Execute the autonomous hardware selection for the system clock */\n    if(ClockType == TimerNone)\n    {\n        /* Probe system clock suitability */\n        if(ValidateTimerSupport(TimerLapic, TRUE))\n        {\n            /* Select the Local APIC */\n            ClockType = TimerLapic;\n        }\n        else if(ValidateTimerSupport(TimerHpet, TRUE))\n        {\n            /* Select the HPET */\n            ClockType = TimerHpet;\n        }\n        else\n        {\n            /* Fallback to the legacy PIT */\n            ClockType = TimerPit;\n        }\n    }\n\n    /* Execute the autonomous hardware selection for the performance counter */\n    if(TimerType == TimerNone)\n    {\n        /* Probe the performance counter suitability */\n        if(ValidateTimerSupport(TimerTsc, FALSE))\n        {\n            /* Select the Invariant TSC */\n            TimerType = TimerTsc;\n        }\n        else if(ValidateTimerSupport(TimerHpet, FALSE))\n        {\n            /* Select the HPET */\n            TimerType = TimerHpet;\n        }\n        else if(ValidateTimerSupport(TimerAcpiPm, FALSE))\n        {\n            /* Select the ACPI PM Timer */\n            TimerType = TimerAcpiPm;\n        }\n        else\n        {\n            /* Fallback to the legacy PIT */\n            TimerType = TimerPit;\n        }\n    }\n\n    /* Retrieve the ACPI PM Timer hardware configuration */\n    HL::Acpi::GetAcpiTimerInfo(&AcpiTimerInfo);\n\n    /* Determine if the ACPI PM Timer port is physically provisioned */\n    if(AcpiTimerInfo->TimerPort != 0)\n    {\n        /* Temporarily route execution stalls through the active ACPI PM hardware */\n        TimerRoutines.StallExecution = StallExecutionAcpiPm;\n    }\n    else\n    {\n        /* Temporarily route execution stalls through the legacy PIT hardware */\n        TimerRoutines.StallExecution = StallExecutionPit;\n    }\n\n    /* Dispatch the initialization routines based on the resolved system clock */\n    switch(ClockType)\n    {\n        case TimerLapic:\n            /* Register the Local APIC initialization handler */\n            TimerRoutines.InitializeClock = InitializeApicTimer;\n            TimerRoutines.SetClockRate = SetClockRateApic;\n            DebugPrint(L\"System Clock: Local APIC Timer (ARAT), \");\n            break;\n        case TimerHpet:\n            /* Register the HPET comparator initialization handler */\n            TimerRoutines.InitializeClock = InitializeHpetTimer;\n            TimerRoutines.SetClockRate = NULLPTR;\n            DebugPrint(L\"System Clock: HPET Comparator, \");\n            break;\n        default:\n            /* Register the legacy PIT initialization handler */\n            TimerRoutines.InitializeClock = InitializePitTimer;\n            TimerRoutines.SetClockRate = NULLPTR;\n            DebugPrint(L\"System Clock: Legacy PIT, \");\n            break;\n    }\n\n    /* Dispatch the routines and configure baseline frequencies for the performance counter */\n    switch(TimerType)\n    {\n        case TimerTsc:\n            /* Register the TSC */\n            PerformanceFrequency = CalibrateTscCounter();\n            TimerRoutines.QueryPerformanceCounter = QueryPerformanceCounterTsc;\n            TimerRoutines.StallExecution = StallExecutionTsc;\n            DebugPrint(L\"Performance Counter: Invariant TSC @ %lluHz\\n\", PerformanceFrequency);\n            break;\n        case TimerHpet:\n            /* Register the HPET */\n            PerformanceFrequency = HpetFrequency;\n            TimerRoutines.QueryPerformanceCounter = QueryPerformanceCounterHpet;\n            TimerRoutines.StallExecution = StallExecutionHpet;\n            DebugPrint(L\"Performance Counter: HPET @ %lluHz\\n\", PerformanceFrequency);\n            break;\n        case TimerAcpiPm:\n            /* Register the ACPI PM */\n            PerformanceFrequency = 3579545;\n            TimerRoutines.QueryPerformanceCounter = QueryPerformanceCounterAcpiPm;\n            TimerRoutines.StallExecution = StallExecutionAcpiPm;\n            KeInitializeSpinLock(&PerformanceCounterLock);\n            DebugPrint(L\"Performance Counter: ACPI PM Timer\\n\");\n            break;\n        default:\n            /* Register the legacy PIT */\n            PerformanceFrequency = 1193182;\n            TimerRoutines.QueryPerformanceCounter = QueryPerformanceCounterPit;\n            TimerRoutines.StallExecution = StallExecutionPit;\n            KeInitializeSpinLock(&PerformanceCounterLock);\n            DebugPrint(L\"Performance Counter: Legacy PIT\\n\");\n            break;\n    }\n}\n\n/**\n * Retrieves the current value of the high-resolution performance counter.\n *\n * @param PerformanceFrequency\n *        Suplies an optional pointer to a variable that receives the performance counter frequency in Hz.\n *\n * @return This routine returns the current 64-bit monotonic tick count.\n *\n * @since XT 1.0\n */\nXTAPI\nLARGE_INTEGER\nHL::Timer::QueryPerformanceCounter(OUT PLARGE_INTEGER Frequency)\n{\n    LARGE_INTEGER CurrentCounter;\n\n    /* Check if the caller requested the frequency */\n    if(Frequency)\n    {\n        /* Assign the cached hardware frequency */\n        Frequency->QuadPart = PerformanceFrequency;\n    }\n\n    /* Dispatch to the specific hardware implementation */\n    CurrentCounter.QuadPart = TimerRoutines.QueryPerformanceCounter();\n\n    /* Return the retrieved timestamp */\n    return CurrentCounter;\n}\n\n/**\n * Queries the current value of the ACPI Power Management Timer.\n *\n * @return This routine returns the current ACPI timer tick count.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nHL::Timer::QueryPerformanceCounterAcpiPm(VOID)\n{\n    PACPI_TIMER_INFO AcpiTimerInfo;\n    ULONG CurrentValue;\n\n    /* Retrieve the ACPI Timer configuration */\n    HL::Acpi::GetAcpiTimerInfo(&AcpiTimerInfo);\n\n    /* Raise RunLevel to DISPATCH_LEVEL and acquire spinlock */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::SpinLockGuard SpinLockGuard(&PerformanceCounterLock);\n\n    /* Read the current hardware value and apply the bitmask */\n    CurrentValue = HL::IoPort::ReadPort32(AcpiTimerInfo->TimerPort) & AcpiTimerInfo->MsbMask;\n\n    /* Calculate delta, accumulate the results and update last value for the next call */\n    SystemPerformanceCounter += (CurrentValue - AcpiPmPerformanceCounter) & AcpiTimerInfo->MsbMask;\n    AcpiPmPerformanceCounter = CurrentValue;\n\n    /* Return the accumulated value */\n    return SystemPerformanceCounter;\n}\n\n/**\n * Queries the current value of the High Precision Event Timer (HPET).\n *\n * @return This routine returns the current HPET main counter value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nHL::Timer::QueryPerformanceCounterHpet(VOID)\n{\n    /* Perform a direct MMIO read from the register address */\n    return ((PHPET_REGISTERS)HpetAddress)->MainCounterValue;\n}\n\n/**\n * Queries the current value of the Legacy PIT.\n *\n * @return This routine returns the interpolated tick count.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nHL::Timer::QueryPerformanceCounterPit(VOID)\n{\n    ULONG ClockDelta, CounterValue;\n    ULONGLONG PerformanceCounter;\n\n    /* Check if system clock initialized the rollover */\n    if(PitRollover == 0)\n    {\n        /* Return the baseline counter value */\n        return SystemPerformanceCounter;\n    }\n\n    /* Raise RunLevel to DISPATCH_LEVEL and acquire spinlock */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::SpinLockGuard SpinLockGuard(&PerformanceCounterLock);\n\n    /* Repeatedly sample the global tick count and the hardware counter */\n    do\n    {\n        /* Get the current global performance tick updated by ISR */\n        PerformanceCounter = PitPerformanceCounter;\n\n        /* Send the LATCH command to freeze value in the PIT buffer */\n        HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x00);\n\n        /* Read the remaining count from the data port */\n        CounterValue = HL::IoPort::ReadPort8(PIT_DATA_PORT0) | (HL::IoPort::ReadPort8(PIT_DATA_PORT0) << 8);\n    }\n    while(PerformanceCounter != PitPerformanceCounter);\n\n    /* Clamp the value in case of a hardware glitch right at the rollover point */\n    if(CounterValue > PitRollover)\n    {\n        /* Force the sampled counter value to the maximum programmed reload threshold */\n        CounterValue = PitRollover;\n    }\n\n    /* Calculate how many ticks have passed since the last interrupt */\n    ClockDelta = PitRollover - CounterValue;\n\n    /* Synthesize the final high-precision timestamp */\n    PerformanceCounter += ClockDelta;\n\n    /* Guard against time drifting backward */\n    if(PerformanceCounter < SystemPerformanceCounter)\n    {\n        /* Compensate missing interrupt */\n        PerformanceCounter += PitRollover;\n    }\n\n    /* Update the last recorded counter */\n    SystemPerformanceCounter = PerformanceCounter;\n\n    /* Return the timestamp */\n    return PerformanceCounter;\n}\n\n/**\n * Queries the current value of the Time Stamp Counter (TSC).\n *\n * @return This routine returns the current invariant TSC tick count.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nHL::Timer::QueryPerformanceCounterTsc(VOID)\n{\n    ULONG TscAux;\n\n    /* Retrieve the timestamp */\n    return AR::CpuFunctions::ReadTimeStampCounterProcessor(&TscAux);\n}\n\n/**\n * Probes the processor via CPUID to detect available modern timing and clock generation features.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::QueryTimerCapabilities(VOID)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    CPUID_REGISTERS CpuRegisters;\n    ULONG MaxStandardLeaf;\n\n    /* Get current processor control block */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n\n    /* Set timer capabilities based on supported CPU features */\n    TimerCapabilities.Arat = (Prcb->CpuId.FeatureBits & KCF_ARAT) != 0;\n    TimerCapabilities.InvariantTsc= (Prcb->CpuId.ExtendedFeatureBits & KCF_INVARIANT_TSC) != 0;\n    TimerCapabilities.RDTSCP = (Prcb->CpuId.ExtendedFeatureBits & KCF_RDTSCP) != 0;\n    TimerCapabilities.TscDeadline = (Prcb->CpuId.FeatureBits & KCF_TSC_DEADLINE) != 0;\n\n    /* Query maximum standard CPUID leaf */\n    RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n    CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n    MaxStandardLeaf = CpuRegisters.Eax;\n\n    /* Check Always Running Timer - ART if leaf supported */\n    if(MaxStandardLeaf >= CPUID_GET_TSC_CRYSTAL_CLOCK)\n    {\n        /* Query the Time Stamp Counter and Core Crystal Clock information CPUID leaf */\n        RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));\n        CpuRegisters.Leaf = CPUID_GET_TSC_CRYSTAL_CLOCK;\n        AR::CpuFunctions::CpuId(&CpuRegisters);\n\n        /* Verify Always Running Timer support */\n        if(CpuRegisters.Eax != 0 && CpuRegisters.Ebx != 0)\n        {\n            /* Mark the ART as supported */\n            TimerCapabilities.Art = TRUE;\n\n            /* Save the TSC scaling ratios */\n            TimerCapabilities.TscDenominator = CpuRegisters.Eax;\n            TimerCapabilities.TscNumerator = CpuRegisters.Ebx;\n\n            /* Check if ECX contains the nominal frequency of the core crystal clock */\n            if(CpuRegisters.Ecx != 0)\n            {\n                /* Save the base frequency for the APIC Timer */\n                TimerCapabilities.TimerFrequency = CpuRegisters.Ecx;\n            }\n        }\n    }\n}\n\n/**\n * Requests a dynamic adjustment of the system clock resolution.\n *\n * @param Rate\n *        Supplies the requested clock rate change in 100-nanosecond units.\n *\n * @return This routine returns the actual clock rate granted by the hardware.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nHL::Timer::SetClockRate(IN ULONG Rate)\n{\n    ULONG HardwareRate;\n\n    /* Validate and clamp the clock rate against architectural limits */\n    if(Rate < HL_MINIMUM_CLOCK_RATE)\n    {\n        /* Enforce minimum resolution to prevent system-wide interrupt storms */\n        Rate = HL_MINIMUM_CLOCK_RATE;\n    }\n    else if(Rate > HL_MAXIMUM_CLOCK_RATE)\n    {\n        /* Cap the clock rate to ensure responsiveness */\n        Rate = HL_MAXIMUM_CLOCK_RATE;\n    }\n\n    /* Check if the active hardware backend supports dynamic rate scaling */\n    if(TimerRoutines.SetClockRate)\n    {\n        /* Dispatch the reprogramming request */\n        HardwareRate = TimerRoutines.SetClockRate(Rate);\n    }\n    else\n    {\n        /* Fallback to the current fixed rate as scaling is unsupported */\n        HardwareRate = TimeIncrement;\n    }\n\n    /* Return the actual clock rate set */\n    return HardwareRate;\n}\n\n/**\n * Adjusts the Local APIC Timer frequency to match the requested resolution.\n *\n * @param Rate\n *        Supplies the requested clock rate change in 100-nanosecond units.\n *\n * @return This routine returns the actual clock rate granted by the hardware.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nHL::Timer::SetClockRateApic(ULONG Rate)\n{\n    ULONG NewDivider;\n    BOOLEAN Interrupts;\n\n    /* TODO: Implement IPI broadcast to synchronize all cores in SMP mode */\n    UNIMPLEMENTED;\n\n    /* Calculate the hardware-specific tick count for the requested rate */\n    NewDivider = (ULONG)(((ULONGLONG)TimerFrequency * Rate) / 10000000ULL);\n\n    /* Prevent an invalid zero-count state */\n    if(NewDivider == 0)\n    {\n        /* Enforce a single-tick */\n        NewDivider = 1;\n    }\n\n    /* Check whether interrupts are enabled */\n    Interrupts = AR::CpuFunctions::InterruptsEnabled();\n\n    /* Disable interrupts */\n    AR::CpuFunctions::ClearInterruptFlag();\n\n    /* Commit the new divider to the TICR register */\n    HL::Pic::WriteApicRegister(APIC_TICR, NewDivider);\n\n    /* Synchronize the kernel's timekeeping math with the new hardware state */\n    ConfigureTimeIncrement(TimerFrequency, NewDivider);\n\n    /* Check whether interrupts need to be re-enabled */\n    if(Interrupts)\n    {\n        /* Re-enable interrupts */\n        AR::CpuFunctions::SetInterruptFlag();\n    }\n\n    /* Return the actual clock rate set */\n    return TimeIncrement;\n}\n\n/**\n * Sets the profile interrupt interval. The interval may be bounded by hardware capabilities.\n *\n * @param Interval\n *        Supplies the requested profile interval in 100-nanosecond units.\n *\n * @return This routine returns the actual profile interval that was set.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nHL::Timer::SetProfileInterval(IN ULONG_PTR Interval)\n{\n    /* Validate and bound the requested profile interval against hardware limits */\n    if(Interval < MIN_PROFILE_INTERVAL)\n    {\n        /* Enforce the minimum profile interval limit */\n        Interval = MIN_PROFILE_INTERVAL;\n    }\n    else if(Interval > MAX_PROFILE_INTERVAL)\n    {\n        /* Enforce the maximum profile interval limit */\n        Interval = MAX_PROFILE_INTERVAL;\n    }\n\n    /* Calculate the required number of ticks for the requested interval */\n    ProfilingTicks = (ULONG)(Interval / 10000);\n\n    /* Return the actual interval */\n    return Interval;\n}\n\n/**\n * Stalls the CPU execution for a specified duration.\n *\n * @param MicroSeconds\n *        Supplies the number of microseconds to stall execution.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::StallExecution(IN ULONG MicroSeconds)\n{\n    /* Dispatch the stall request */\n    TimerRoutines.StallExecution(MicroSeconds);\n}\n\n/**\n * Stalls the CPU execution for a specified duration using the ACPI Power Management Timer.\n *\n * @param MicroSeconds\n *        Supplies the number of microseconds to stall execution.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::StallExecutionAcpiPm(IN ULONG MicroSeconds)\n{\n    PACPI_TIMER_INFO AcpiTimerInfo;\n    ULONG StartTick, CurrentTick, Delta, TicksElapsed;\n    ULONGLONG TargetTicks;\n\n    /* Validate input parameter */\n    if(MicroSeconds == 0)\n    {\n        /* Nothing to do */\n        return;\n    }\n    else if(MicroSeconds > 3000000)\n    {\n        /* Cap execution stall to 3 seconds */\n        MicroSeconds = 3000000;\n    }\n\n    /* Retrieve the ACPI PM Timer hardware configuration */\n    HL::Acpi::GetAcpiTimerInfo(&AcpiTimerInfo);\n\n    /* Calculate the target number of ticks based on the standard ACPI PM frequency */\n    TargetTicks = ((ULONGLONG)MicroSeconds * 3579545ULL) / 1000000ULL;\n    TicksElapsed = 0;\n\n    /* Sample the initial hardware tick count and apply the hardware-specific bitmask */\n    StartTick = HL::IoPort::ReadPort32(AcpiTimerInfo->TimerPort) & AcpiTimerInfo->MsbMask;\n\n    /* Spin the processor until the accumulated hardware ticks reach the calculated target */\n    while(TicksElapsed < TargetTicks)\n    {\n        /* Sample the current hardware tick count */\n        CurrentTick = HL::IoPort::ReadPort32(AcpiTimerInfo->TimerPort) & AcpiTimerInfo->MsbMask;\n\n        /* Calculate the tick delta */\n        Delta = (CurrentTick - StartTick) & AcpiTimerInfo->MsbMask;\n\n        /* Accumulate the elapsed ticks and advance the start marker */\n        TicksElapsed += Delta;\n        StartTick = CurrentTick;\n\n        /* Issue a PAUSE instruction to relieve memory bus contention */\n        AR::CpuFunctions::YieldProcessor();\n    }\n}\n\n/**\n * Stalls the CPU execution for a specified duration (maximum 3 seconds) using the High Precision Event Timer (HPET).\n *\n * @param MicroSeconds\n *        Supplies the number of microseconds to stall execution.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::StallExecutionHpet(IN ULONG MicroSeconds)\n{\n    PHPET_REGISTERS Hpet;\n    ULONGLONG StartTick, TargetTicks;\n\n    /* Validate input parameter */\n    if(MicroSeconds == 0)\n    {\n        /* Nothing to do */\n        return;\n    }\n    else if(MicroSeconds > 3000000)\n    {\n        /* Cap execution stall to 3 seconds */\n        MicroSeconds = 3000000;\n    }\n\n    /* Cast the mapped virtual address to the HPET hardware register */\n    Hpet = (PHPET_REGISTERS)HpetAddress;\n\n    /* Calculate target ticks based on HPET frequency */\n    TargetTicks = ((ULONGLONG)MicroSeconds * PerformanceFrequency) / 1000000ULL;\n    StartTick = Hpet->MainCounterValue;\n\n    /* Spin until the elapsed ticks reach the target */\n    while((Hpet->MainCounterValue - StartTick) < TargetTicks)\n    {\n        /* Issue a PAUSE instruction to relieve memory bus contention */\n        AR::CpuFunctions::YieldProcessor();\n    }\n}\n\n/**\n * Stalls the CPU execution for a specified duration (maximum 3 seconds) using the legacy PIT timer.\n *\n * @param MicroSeconds\n *        Specifies the number of microseconds to stall execution.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::StallExecutionPit(IN ULONG MicroSeconds)\n{\n    USHORT CurrentCount, PreviousCount;\n    ULONG TargetTicks, TickCounter;\n    UCHAR Port61State;\n\n    /* Validate input parameter */\n    if(MicroSeconds == 0)\n    {\n        /* Nothing to do */\n        return;\n    }\n    else if(MicroSeconds > 3000000)\n    {\n        /* Cap execution stall to 3 seconds */\n        MicroSeconds = 3000000;\n    }\n\n    /* Convert microseconds to PIT ticks using exact frequency arithmetic */\n    TargetTicks = (ULONG)(((ULONGLONG)MicroSeconds * 1193182ULL) / 1000000ULL);\n    TickCounter = 0;\n\n    /* Save the current state of System Control Port B */\n    Port61State = HL::IoPort::ReadPort8(0x61);\n\n    /* Enable PIT Channel 2 and disable the PC Speaker */\n    HL::IoPort::WritePort8(0x61, (Port61State & ~0x02) | 0x01);\n\n    /* Configure PIT Channel 2 for Read/Write LSB then MSB, Mode 0 */\n    HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0xB0);\n\n    /* Initialize the PIT counter with the maximum possible value */\n    HL::IoPort::WritePort8(PIT_DATA_PORT2, 0xFF);\n    HL::IoPort::WritePort8(PIT_DATA_PORT2, 0xFF);\n\n    /* Latch and read the initial counter value */\n    HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x80);\n    PreviousCount = HL::IoPort::ReadPort8(PIT_DATA_PORT2);\n    PreviousCount |= (HL::IoPort::ReadPort8(PIT_DATA_PORT2) << 8);\n\n    /* Poll the PIT */\n    while(TickCounter < TargetTicks)\n    {\n        /* Latch the current counter value without stopping the timer */\n        HL::IoPort::WritePort8(PIT_COMMAND_PORT, 0x80);\n        CurrentCount = HL::IoPort::ReadPort8(PIT_DATA_PORT2);\n        CurrentCount |= (HL::IoPort::ReadPort8(PIT_DATA_PORT2) << 8);\n\n        /* Calculate elapsed ticks since the last read */\n        TickCounter += (PreviousCount - CurrentCount) & 0xFFFF;\n\n        /* Update the tracking variable */\n        PreviousCount = CurrentCount;\n    }\n\n    /* Restore the original state of PIT Port */\n    HL::IoPort::WritePort8(0x61, Port61State);\n}\n\n/**\n * Stalls the CPU execution for a specified duration (maximum 3 seconds) using the Time Stamp Counter (TSC).\n *\n * @param MicroSeconds\n *        Supplies the number of microseconds to stall execution.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::StallExecutionTsc(IN ULONG MicroSeconds)\n{\n    ULONGLONG StartTick, TargetTicks;\n\n    /* Validate input parameter */\n    if(MicroSeconds == 0)\n    {\n        /* Nothing to do */\n        return;\n    }\n    else if(MicroSeconds > 3000000)\n    {\n        /* Cap execution stall to 3 seconds */\n        MicroSeconds = 3000000;\n    }\n\n    /* Calculate target ticks based on calibrated TSC frequency */\n    TargetTicks = ((ULONGLONG)MicroSeconds * PerformanceFrequency) / 1000000ULL;\n    StartTick = AR::CpuFunctions::ReadTimeStampCounter();\n\n    /* Spin until the elapsed ticks reach the target */\n    while((AR::CpuFunctions::ReadTimeStampCounter() - StartTick) < TargetTicks)\n    {\n        /* Issue a PAUSE instruction to relieve memory bus contention */\n        AR::CpuFunctions::YieldProcessor();\n    }\n}\n\n/**\n * Enables the profile interrupt for the specified profile source.\n *\n * @param ProfileSource\n *        Supplies the source of the profile interrupt to start.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::StartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)\n{\n    /* Handle only ProfileTime and ProfileXtKernel */\n    if(ProfileSource != ProfileTime && ProfileSource != ProfileXtKernel)\n    {\n        /* Invalid profile source, do nothing */\n        return;\n    }\n\n    /* Set the global software flag to enable profiling */\n    ProfilingEnabled = TRUE;\n}\n\n/**\n * Disables the profile interrupt for the specified profile source.\n *\n * @param ProfileSource\n *        Supplies the source of the profile interrupt to stop.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nHL::Timer::StopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)\n{\n    /* Handle only ProfileTime and ProfileXtKernel */\n    if(ProfileSource != ProfileTime && ProfileSource != ProfileXtKernel)\n    {\n        /* Invalid profile source, do nothing */\n        return;\n    }\n\n    /* Clear the global software flag to disable profiling */\n    ProfilingEnabled = FALSE;\n}\n\n/**\n * Checks if the specified hardware timer is supported and available on the current system.\n *\n * @param TimerType\n *        Supplies the hardware timer type to query.\n *\n * @param IsClock\n *        Supplies TRUE if the timer is intended to be used as an interrupt generator (System Clock),\n *        or FALSE if it is intended to be used as a performance counter (Stoper).\n *\n * @return This routine returns TRUE if the timer is available and supported, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nHL::Timer::ValidateTimerSupport(IN TIMER_TYPE TimerType,\n                                IN BOOLEAN IsClock)\n{\n    PACPI_TIMER_INFO AcpiTimerInfo;\n\n    /* Query ACPI timer info */\n    HL::Acpi::GetAcpiTimerInfo(&AcpiTimerInfo);\n\n    /* Validate timer type */\n    switch(TimerType)\n    {\n        case TimerTsc:\n            /* Check if TSC and RDTSCP are supported */\n            return (TimerCapabilities.InvariantTsc && TimerCapabilities.RDTSCP) ? TRUE : FALSE;\n        case TimerHpet:\n            /* Check if HPET is supported */\n            return (HpetAddress != NULLPTR) ? TRUE : FALSE;\n        case TimerAcpiPm:\n            /* Check if ACPI PM Timer is supported */\n            return (!IsClock && AcpiTimerInfo->TimerPort != 0) ? TRUE : FALSE;\n        case TimerLapic:\n            /* Check if LAPIC Timer (ARAT) is supported */\n            return (IsClock && TimerCapabilities.Arat) ? TRUE : FALSE;\n        case TimerPit:\n            /* PIT Timer is always supported */\n            return TRUE;\n        default:\n            /* Invalid timer type, return FALSE */\n            return FALSE;\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/includes/ar/amd64/asmsup.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar/amd64/asmsup.hh\n * DESCRIPTION:     Architecture-specific assembler prototypes\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_ASMSUP_HH\n#define __XTOSKRNL_AR_ASMSUP_HH\n\n#include <xtos.hh>\n\n\n/* TrampolineEnableXpa end address to calculate trampoline size */\nXTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];\n\n/* External array of pointers to the interrupt handlers */\nXTCLINK ULONG_PTR ArInterruptEntry[256];\n\n/* TrampolineApStartup end address to calculate trampoline size */\nXTCLINK PVOID ArStartApplicationProcessorEnd[];\n\n/* External array of pointers to the trap handlers */\nXTCLINK ULONG_PTR ArTrapEntry[256];\n\n/* Forward reference for assembler code */\nXTCLINK\nXTCDECL\nVOID\nArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);\n\nXTCLINK\nXTCDECL\nVOID\nArHandleSpuriousInterrupt(VOID);\n\nXTCLINK\nXTCDECL\nVOID\nArStartApplicationProcessor(VOID);\n\n#endif /* __XTOSKRNL_AR_ASMSUP_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ar/amd64/cpufunc.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar/amd64/cpufunc.hh\n * DESCRIPTION:     Architecture-specific CPU control and utility functions for low-level system operations\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_CPUFUNC_HH\n#define __XTOSKRNL_AR_CPUFUNC_HH\n\n#include <xtos.hh>\n\n\n/* Architecture-specific Library */\nnamespace AR\n{\n    class CpuFunctions\n    {\n        public:\n            STATIC XTCDECL VOID ClearInterruptFlag(VOID);\n            STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);\n            STATIC XTCDECL VOID FlushTlb(VOID);\n            STATIC XTCDECL ULONG GetCpuFlags(VOID);\n            STATIC XTASSEMBLY XTCDECL ULONG_PTR GetStackPointer(VOID);\n            STATIC XTCDECL VOID Halt(VOID);\n            STATIC XTCDECL BOOLEAN InterruptsEnabled(VOID);\n            STATIC XTCDECL VOID InvalidateTlbEntry(IN PVOID Address);\n            STATIC XTCDECL VOID LoadGlobalDescriptorTable(IN PVOID Source);\n            STATIC XTCDECL VOID LoadInterruptDescriptorTable(IN PVOID Source);\n            STATIC XTCDECL VOID LoadLocalDescriptorTable(IN USHORT Source);\n            STATIC XTCDECL VOID LoadMxcsrRegister(IN ULONG Source);\n            STATIC XTCDECL VOID LoadSegment(IN USHORT Segment,\n                                            IN ULONG Source);\n            STATIC XTCDECL VOID LoadTaskRegister(USHORT Source);\n            STATIC XTCDECL VOID MemoryBarrier(VOID);\n            STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);\n            STATIC XTCDECL ULONG_PTR ReadDebugRegister(IN USHORT DebugRegister);\n            STATIC XTCDECL ULONGLONG ReadGSQuadWord(ULONG Offset);\n            STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);\n            STATIC XTCDECL UINT ReadMxCsrRegister(VOID);\n            STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);\n            STATIC XTCDECL ULONGLONG ReadTimeStampCounterProcessor(OUT PULONG TscAux);\n            STATIC XTCDECL VOID ReadWriteBarrier(VOID);\n            STATIC XTCDECL VOID SetInterruptFlag(VOID);\n            STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);\n            STATIC XTCDECL VOID StoreInterruptDescriptorTable(OUT PVOID Destination);\n            STATIC XTCDECL VOID StoreLocalDescriptorTable(OUT PVOID Destination);\n            STATIC XTCDECL VOID StoreSegment(IN USHORT Segment,\n                                             OUT PVOID Destination);\n            STATIC XTCDECL VOID StoreTaskRegister(OUT PVOID Destination);\n            STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,\n                                                     IN UINT_PTR Value);\n            STATIC XTCDECL VOID WriteDebugRegister(IN USHORT DebugRegister,\n                                                   IN UINT_PTR Value);\n            STATIC XTCDECL VOID WriteEflagsRegister(IN UINT_PTR Value);\n            STATIC XTCDECL VOID WriteModelSpecificRegister(IN ULONG Register,\n                                                           IN ULONGLONG Value);\n            STATIC XTCDECL VOID YieldProcessor(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_AR_CPUFUNC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ar/amd64/procsup.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar/amd64/procsup.hh\n * DESCRIPTION:     Architecture-specific routines for AMD64 processor initialization and system structure setup\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_PROCSUP_HH\n#define __XTOSKRNL_AR_PROCSUP_HH\n\n#include <xtos.hh>\n\n\n/* Architecture-specific Library */\nnamespace AR\n{\n    class ProcessorSupport\n    {\n        private:\n            STATIC UCHAR BootStack[KERNEL_STACK_SIZE];\n            STATIC UCHAR FaultStack[KERNEL_STACK_SIZE];\n            STATIC KGDTENTRY InitialGdt[GDT_ENTRIES];\n            STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];\n            STATIC KPROCESSOR_BLOCK InitialProcessorBlock;\n            STATIC KTSS InitialTss;\n            STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];\n\n        public:\n            STATIC XTAPI PVOID GetBootStack(VOID);\n            STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,\n                                                       OUT PVOID *TrampolineCode,\n                                                       OUT PULONG_PTR TrampolineSize);\n            STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);\n            STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,\n                                                            OUT PKGDTENTRY *Gdt,\n                                                            OUT PKTSS *Tss,\n                                                            OUT PKPROCESSOR_BLOCK *ProcessorBlock,\n                                                            OUT PVOID *KernelBootStack,\n                                                            OUT PVOID *KernelFaultStack,\n                                                            OUT PVOID *KernelNmiStack);\n            STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,\n                                         IN USHORT Vector,\n                                         IN PVOID Handler,\n                                         IN USHORT Selector,\n                                         IN USHORT Ist,\n                                         IN USHORT Dpl,\n                                         IN USHORT Type);\n\n        private:\n            STATIC XTAPI VOID IdentifyProcessor(VOID);\n            STATIC XTAPI VOID IdentifyProcessorFeatures(VOID);\n            STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);\n            STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);\n            STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,\n                                                       IN PKGDTENTRY Gdt,\n                                                       IN PKIDTENTRY Idt,\n                                                       IN PKTSS Tss,\n                                                       IN PVOID DpcStack);\n            STATIC XTAPI VOID InitializeProcessorRegisters(VOID);\n            STATIC XTAPI VOID InitializeSegments(VOID);\n            STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,\n                                            IN PVOID KernelBootStack,\n                                            IN PVOID KernelFaultStack,\n                                            IN PVOID KernelNmiStack);\n            STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,\n                                          IN USHORT Selector,\n                                          IN ULONG_PTR Base,\n                                          IN ULONG Limit,\n                                          IN UCHAR Type,\n                                          IN UCHAR Dpl,\n                                          IN UCHAR SegmentMode);\n            STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,\n                                              IN USHORT Selector,\n                                              IN ULONG_PTR Base);\n    };\n}\n\n#endif /* __XTOSKRNL_AR_PROCSUP_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ar/amd64/traps.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar/amd64/traps.hh\n * DESCRIPTION:     Trap handling routines and the dispatcher for processor exceptions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_TRAPS_HH\n#define __XTOSKRNL_AR_TRAPS_HH\n\n#include <xtos.hh>\n\n\n/* Architecture-specific Library */\nnamespace AR\n{\n    class Traps\n    {\n        private:\n            STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;\n\n        public:\n            STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL(\"ArDispatchInterrupt\");\n            STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL(\"ArDispatchTrap\");\n            STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);\n            STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);\n\n        private:\n            STATIC XTCDECL VOID HandleSystemCall32(VOID);\n            STATIC XTCDECL VOID HandleSystemCall64(VOID);\n            STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap01(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap02(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap03(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap04(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap05(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap06(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap07(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap08(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap09(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0A(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0B(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0C(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0D(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0E(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap10(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap11(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap12(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap13(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap1F(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap2C(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap2D(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap2F(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrapE1(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrapFF(IN PKTRAP_FRAME TrapFrame);\n    };\n}\n\n#endif /* __XTOSKRNL_AR_TRAPS_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ar/i686/asmsup.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar/i686/asmsup.hh\n * DESCRIPTION:     Architecture-specific assembler prototypes\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_ASMSUP_HH\n#define __XTOSKRNL_AR_ASMSUP_HH\n\n#include <xtos.hh>\n\n\n/* TrampolineEnableXpa end address to calculate trampoline size */\nXTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];\n\n/* External array of pointers to the interrupt handlers */\nXTCLINK ULONG_PTR ArInterruptEntry[256];\n\n/* TrampolineApStartup end address to calculate trampoline size */\nXTCLINK PVOID ArStartApplicationProcessorEnd[];\n\n/* External array of pointers to the trap handlers */\nXTCLINK ULONG_PTR ArTrapEntry[256];\n\n/* Forward reference for assembler code */\nXTCLINK\nXTCDECL\nVOID\nArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);\n\nXTCLINK\nXTCDECL\nVOID\nArHandleSpuriousInterrupt(VOID);\n\nXTCLINK\nXTCDECL\nVOID\nArStartApplicationProcessor(VOID);\n\n#endif /* __XTOSKRNL_AR_ASMSUP_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ar/i686/cpufunc.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar/i686/cpufunc.hh\n * DESCRIPTION:     Architecture-specific CPU control and utility functions for low-level system operations\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_CPUFUNC_HH\n#define __XTOSKRNL_AR_CPUFUNC_HH\n\n#include <xtos.hh>\n\n\n/* Architecture-specific Library */\nnamespace AR\n{\n    class CpuFunctions\n    {\n        public:\n            STATIC XTCDECL VOID ClearInterruptFlag(VOID);\n            STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);\n            STATIC XTCDECL VOID FlushTlb(VOID);\n            STATIC XTCDECL ULONG GetCpuFlags(VOID);\n            STATIC XTASSEMBLY XTCDECL ULONG_PTR GetStackPointer(VOID);\n            STATIC XTCDECL VOID Halt(VOID);\n            STATIC XTCDECL BOOLEAN InterruptsEnabled(VOID);\n            STATIC XTCDECL VOID InvalidateTlbEntry(IN PVOID Address);\n            STATIC XTCDECL VOID LoadGlobalDescriptorTable(IN PVOID Source);\n            STATIC XTCDECL VOID LoadInterruptDescriptorTable(IN PVOID Source);\n            STATIC XTCDECL VOID LoadLocalDescriptorTable(IN USHORT Source);\n            STATIC XTCDECL VOID LoadSegment(IN USHORT Segment,\n                                            IN ULONG Source);\n            STATIC XTCDECL VOID LoadTaskRegister(USHORT Source);\n            STATIC XTCDECL VOID MemoryBarrier(VOID);\n            STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);\n            STATIC XTCDECL ULONG_PTR ReadDebugRegister(IN USHORT DebugRegister);\n            STATIC XTCDECL ULONG ReadFSDualWord(ULONG Offset);\n            STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);\n            STATIC XTCDECL UINT ReadMxCsrRegister(VOID);\n            STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);\n            STATIC XTCDECL ULONGLONG ReadTimeStampCounterProcessor(OUT PULONG TscAux);\n            STATIC XTCDECL VOID ReadWriteBarrier(VOID);\n            STATIC XTCDECL VOID SetInterruptFlag(VOID);\n            STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);\n            STATIC XTCDECL VOID StoreInterruptDescriptorTable(OUT PVOID Destination);\n            STATIC XTCDECL VOID StoreLocalDescriptorTable(OUT PVOID Destination);\n            STATIC XTCDECL VOID StoreSegment(IN USHORT Segment,\n                                             OUT PVOID Destination);\n            STATIC XTCDECL VOID StoreTaskRegister(OUT PVOID Destination);\n            STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,\n                                                     IN UINT_PTR Value);\n            STATIC XTCDECL VOID WriteDebugRegister(IN USHORT DebugRegister,\n                                                   IN UINT_PTR Value);\n            STATIC XTCDECL VOID WriteEflagsRegister(IN UINT_PTR Value);\n            STATIC XTCDECL VOID WriteModelSpecificRegister(IN ULONG Register,\n                                                           IN ULONGLONG Value);\n            STATIC XTCDECL VOID YieldProcessor(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_AR_CPUFUNC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ar/i686/procsup.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar/i686/procsup.hh\n * DESCRIPTION:     Architecture-specific routines for i686 processor initialization and system structure setup\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_PROCSUP_HH\n#define __XTOSKRNL_AR_PROCSUP_HH\n\n#include <xtos.hh>\n\n\n/* Architecture-specific Library */\nnamespace AR\n{\n    class ProcessorSupport\n    {\n        private:\n            STATIC UCHAR BootStack[KERNEL_STACK_SIZE];\n            STATIC UCHAR DoubleFaultTss[KTSS_IO_MAPS];\n            STATIC UCHAR FaultStack[KERNEL_STACK_SIZE];\n            STATIC KGDTENTRY InitialGdt[GDT_ENTRIES];\n            STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];\n            STATIC KPROCESSOR_BLOCK InitialProcessorBlock;\n            STATIC KTSS InitialTss;\n            STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];\n            STATIC UCHAR NonMaskableInterruptTss[KTSS_IO_MAPS];\n\n\n        public:\n            STATIC XTAPI PVOID GetBootStack(VOID);\n            STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,\n                                                       OUT PVOID *TrampolineCode,\n                                                       OUT PULONG_PTR TrampolineSize);\n            STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);\n            STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,\n                                                            OUT PKGDTENTRY *Gdt,\n                                                            OUT PKTSS *Tss,\n                                                            OUT PKPROCESSOR_BLOCK *ProcessorBlock,\n                                                            OUT PVOID *KernelBootStack,\n                                                            OUT PVOID *KernelFaultStack,\n                                                            OUT PVOID *KernelNmiStack);\n            STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,\n                                         IN USHORT Vector,\n                                         IN PVOID Handler,\n                                         IN USHORT Selector,\n                                         IN USHORT Ist,\n                                         IN USHORT Dpl,\n                                         IN USHORT Type);\n\n        private:\n            STATIC XTAPI VOID IdentifyProcessor(VOID);\n            STATIC XTAPI VOID IdentifyProcessorFeatures(VOID);\n            STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);\n            STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);\n            STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,\n                                                       IN PKGDTENTRY Gdt,\n                                                       IN PKIDTENTRY Idt,\n                                                       IN PKTSS Tss,\n                                                       IN PVOID DpcStack);\n            STATIC XTAPI VOID InitializeProcessorRegisters(VOID);\n            STATIC XTAPI VOID InitializeSegments(VOID);\n            STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,\n                                            IN PVOID KernelBootStack,\n                                            IN PVOID KernelFaultStack,\n                                            IN PVOID KernelNmiStack);\n            STATIC XTAPI VOID SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,\n                                                     IN PVOID KernelFaultStack);\n            STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,\n                                          IN USHORT Selector,\n                                          IN ULONG_PTR Base,\n                                          IN ULONG Limit,\n                                          IN UCHAR Type,\n                                          IN UCHAR Dpl,\n                                          IN UCHAR SegmentMode);\n            STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,\n                                              IN USHORT Selector,\n                                              IN ULONG_PTR Base);\n            STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,\n                                                              IN PVOID KernelNmiStack);\n    };\n}\n\n#endif /* __XTOSKRNL_AR_PROCSUP_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ar/i686/traps.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar/i686/traps.hh\n * DESCRIPTION:     Trap handling routines and the dispatcher for processor exceptions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_TRAPS_HH\n#define __XTOSKRNL_AR_TRAPS_HH\n\n#include <xtos.hh>\n\n\n/* Architecture-specific Library */\nnamespace AR\n{\n    class Traps\n    {\n        private:\n            STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;\n\n        public:\n            STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL(\"_ArDispatchInterrupt\");\n            STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL(\"_ArDispatchTrap\");\n            STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);\n\n        private:\n            STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap01(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap02(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap03(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap04(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap05(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap06(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap07(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap08(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap09(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0A(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0B(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0C(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0D(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap0E(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap10(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap11(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap12(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap13(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap2A(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap2B(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap2C(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap2D(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrap2E(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleTrapFF(IN PKTRAP_FRAME TrapFrame);\n    };\n}\n\n#endif /* __XTOSKRNL_AR_TRAPS_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ar.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ar.hh\n * DESCRIPTION:     Architecture Library\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_AR_HH\n#define __XTOSKRNL_AR_HH\n\n#include <xtos.hh>\n\n#include XTOS_ARCH_HEADER(ar, asmsup.hh)\n#include XTOS_ARCH_HEADER(ar, cpufunc.hh)\n#include XTOS_ARCH_HEADER(ar, procsup.hh)\n#include XTOS_ARCH_HEADER(ar, traps.hh)\n\n#endif /* __XTOSKRNL_AR_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ex/rundown.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ex/rundown.hh\n * DESCRIPTION:     Rundown protection mechanism\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_EX_RUNDOWN_HH\n#define __XTOSKRNL_EX_RUNDOWN_HH\n\n#include <xtos.hh>\n\n\n/* Architecture-specific Library */\nnamespace EX\n{\n    class Rundown\n    {\n        public:\n            STATIC XTFASTCALL BOOLEAN AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n            STATIC XTFASTCALL VOID CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n            STATIC XTFASTCALL VOID InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n            STATIC XTFASTCALL VOID ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n            STATIC XTFASTCALL VOID ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);\n            STATIC XTFASTCALL VOID WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);\n    };\n}\n\n#endif /* __XTOSKRNL_EX_RUNDOWN_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ex.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ex.hh\n * DESCRIPTION:     Kernel Executive\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_EX_HH\n#define __XTOSKRNL_EX_HH\n\n#include <xtos.hh>\n\n#include <ex/rundown.hh>\n\n#endif /* __XTOSKRNL_EX_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/acpi.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/acpi.hh\n * DESCRIPTION:     Advanced Configuration and Power Interface (ACPI) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_ACPI_HH\n#define __XTOSKRNL_HL_ACPI_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class Acpi\n    {\n        private:\n            STATIC ULONG CacheCount;\n            STATIC ACPI_CACHE_LIST CacheEntries[ACPI_MAX_CACHED_TABLES];\n            STATIC LIST_ENTRY CacheList;\n            STATIC PACPI_RSDP RsdpStructure;\n            STATIC ACPI_SYSTEM_INFO SystemInfo;\n            STATIC ACPI_TIMER_INFO TimerInfo;\n\n        public:\n            STATIC XTAPI XTSTATUS GetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp);\n            STATIC XTAPI XTSTATUS GetAcpiTable(IN ULONG Signature,\n                                               OUT PACPI_DESCRIPTION_HEADER *AcpiTable);\n            STATIC XTAPI VOID GetAcpiTimerInfo(OUT PACPI_TIMER_INFO *AcpiTimerInfo);\n            STATIC XTAPI VOID GetSystemInformation(OUT PACPI_SYSTEM_INFO *SystemInfo);\n            STATIC XTAPI XTSTATUS InitializeAcpi(VOID);\n            STATIC XTAPI XTSTATUS InitializeAcpiSystemInformation(VOID);\n        \n        private:\n            STATIC XTAPI VOID CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable);\n            STATIC XTAPI XTSTATUS InitializeAcpiCache(VOID);\n            STATIC XTAPI XTSTATUS InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *AcpiTable);\n            STATIC XTAPI XTSTATUS InitializeAcpiSystemStructure(VOID);\n            STATIC XTAPI XTSTATUS InitializeAcpiTimer(VOID);\n            STATIC XTAPI XTSTATUS QueryAcpiCache(IN ULONG Signature,\n                                                 OUT PACPI_DESCRIPTION_HEADER *AcpiTable);\n            STATIC XTAPI XTSTATUS QueryAcpiTables(IN ULONG Signature,\n                                                  OUT PACPI_DESCRIPTION_HEADER *AcpiTable);\n            STATIC XTAPI BOOLEAN ValidateAcpiTable(IN PVOID Buffer,\n                                                   IN UINT_PTR Size);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_ACPI_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/cport.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/cpu.hh\n * DESCRIPTION:     Serial (COM) port support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_CPORT_HH\n#define __XTOSKRNL_HL_CPORT_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class ComPort\n    {\n        public:\n            STATIC XTCDECL XTSTATUS ReadComPort(IN PCPPORT Port,\n                                                OUT PUCHAR Byte,\n                                                IN BOOLEAN Wait,\n                                                IN BOOLEAN Poll);\n            STATIC XTCDECL UCHAR ReadComPortLsr(IN PCPPORT Port,\n                                                IN UCHAR Byte);\n            STATIC XTCDECL XTSTATUS InitializeComPort(IN OUT PCPPORT Port,\n                                                      IN PUCHAR PortAddress,\n                                                      IN ULONG BaudRate);\n            STATIC XTCDECL XTSTATUS WriteComPort(IN PCPPORT Port,\n                                                 IN UCHAR Byte);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_CPORT_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/cpu.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/cpu.hh\n * DESCRIPTION:     HAL processor support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_CPU_HH\n#define __XTOSKRNL_HL_CPU_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class Cpu\n    {\n        private:\n            STATIC KAFFINITY ActiveProcessors;\n\n        public:\n            STATIC XTAPI VOID InitializeProcessor(VOID);\n            STATIC XTAPI XTSTATUS StartAllProcessors(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_CPU_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/fbdev.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/fbdev.hh\n * DESCRIPTION:     FrameBuffer support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_FBDEV_HH\n#define __XTOSKRNL_HL_FBDEV_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class FrameBuffer\n    {\n        private:\n            STATIC HL_FRAMEBUFFER_DATA FrameBufferData;\n            STATIC PVOID ScreenShadowBuffer;\n            STATIC HL_SCROLL_REGION_DATA ScrollRegionData;\n\n        public:\n            STATIC XTAPI VOID ClearScreen(IN ULONG Color);\n            STATIC XTCDECL XTSTATUS DisplayCharacter(IN WCHAR Character);\n            STATIC XTAPI XTSTATUS EnableShadowBuffer(VOID);\n            STATIC XTAPI VOID GetFrameBufferResolution(OUT PULONG Width,\n                                                       OUT PULONG Height);\n            STATIC XTAPI XTSTATUS InitializeFrameBuffer(VOID);\n            STATIC XTAPI VOID InitializeScrollRegion(IN ULONG Left,\n                                                     IN ULONG Top,\n                                                     IN ULONG Right,\n                                                     IN ULONG Bottom,\n                                                     IN ULONG FontColor);\n            STATIC XTAPI VOID UpdateScreen(VOID);\n            STATIC XTAPI VOID UpdateScreenRegion(IN ULONG Left,\n                                                 IN ULONG Top,\n                                                 IN ULONG Right,\n                                                 IN ULONG Bottom);\n\n        private:\n            STATIC XTAPI VOID DrawCharacter(IN ULONG PositionX,\n                                            IN ULONG PositionY,\n                                            IN ULONG Color,\n                                            IN WCHAR WideCharacter);\n            STATIC XTAPI VOID DrawPixel(IN ULONG PositionX,\n                                        IN ULONG PositionY,\n                                        IN ULONG Color);\n            STATIC XTAPI ULONG GetRGBColor(IN ULONG Color);\n            STATIC XTAPI VOID ScrollRegion(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_FBDEV_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/firmware.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/firmware.hh\n * DESCRIPTION:     UEFI/BIOS Firmware support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_FIRMWARE_HH\n#define __XTOSKRNL_HL_FIRMWARE_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class Firmware\n    {\n        public:\n            STATIC XTFASTCALL UCHAR ReadCmosRegister(IN UCHAR Register);\n            STATIC XTFASTCALL VOID WriteCmosRegister(IN UCHAR Register,\n                                                     IN UCHAR Value);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_FIRMWARE_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/init.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/init.hh\n * DESCRIPTION:     Hardware layer initialization\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_INIT_HH\n#define __XTOSKRNL_HL_INIT_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class Init\n    {\n        public:\n            STATIC XTAPI XTSTATUS InitializeSystem(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_INIT_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/ioport.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/ioport.hh\n * DESCRIPTION:     I/O port access routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_IOPORT_HH\n#define __XTOSKRNL_HL_IOPORT_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class IoPort\n    {\n        public:\n            STATIC XTCDECL UCHAR ReadPort8(IN USHORT Port);\n            STATIC XTCDECL USHORT ReadPort16(IN USHORT Port);\n            STATIC XTCDECL ULONG ReadPort32(IN USHORT Port);\n            STATIC XTCDECL VOID WritePort8(IN USHORT Port,\n                                           IN UCHAR Value);\n            STATIC XTCDECL VOID WritePort16(IN USHORT Port,\n                                            IN USHORT Value);\n            STATIC XTCDECL VOID WritePort32(IN USHORT Port,\n                                            IN ULONG Value);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_IOPORT_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/ioreg.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/ioreg.hh\n * DESCRIPTION:     Basic I/O registers access functionality\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_IOREG_HH\n#define __XTOSKRNL_HL_IOREG_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class IoRegister\n    {\n        public:\n            STATIC XTAPI UCHAR ReadRegister8(IN PVOID Register);\n            STATIC XTAPI USHORT ReadRegister16(IN PVOID Register);\n            STATIC XTAPI ULONG ReadRegister32(IN PVOID Register);\n            STATIC XTAPI VOID WriteRegister8(IN PVOID Register,\n                                             IN UCHAR Value);\n            STATIC XTAPI VOID WriteRegister16(IN PVOID Register,\n                                              IN USHORT Value);\n            STATIC XTAPI VOID WriteRegister32(IN PVOID Register,\n                                              IN ULONG Value);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_IOREG_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/irq.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/irq.hh\n * DESCRIPTION:     Interrupts support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_IRQ_HH\n#define __XTOSKRNL_HL_IRQ_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class Irq\n    {\n        public:\n            STATIC XTAPI VOID BeginSystemInterrupt(IN KRUNLEVEL RunLevel,\n                                                   OUT PKRUNLEVEL OldRunLevel);\n            STATIC XTAPI VOID EndInterrupt(IN PKTRAP_FRAME TrapFrame,\n                                           IN KRUNLEVEL RunLevel);\n            STATIC XTAPI VOID EndSystemInterrupt(IN PKTRAP_FRAME TrapFrame,\n                                                 IN KRUNLEVEL RunLevel);\n            STATIC XTCDECL VOID HandleProfileInterrupt(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTAPI PVOID QueryInterruptHandler(IN ULONG Vector);\n            STATIC XTAPI PVOID QuerySystemInterruptHandler(IN ULONG Vector);\n            STATIC XTAPI VOID RegisterInterruptHandler(IN ULONG Vector,\n                                                       IN PVOID Handler);\n            STATIC XTAPI VOID RegisterSystemInterruptHandler(IN ULONG Vector,\n                                                             IN PINTERRUPT_HANDLER Handler);\n            STATIC XTFASTCALL VOID SendSoftwareInterrupt(IN KRUNLEVEL RunLevel);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_IRQ_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/pic.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/pic.hh\n * DESCRIPTION:     HAL processor support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_PIC_HH\n#define __XTOSKRNL_HL_PIC_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class Pic\n    {\n        private:\n            STATIC APIC_MODE ApicMode;\n            STATIC ULONG ControllerCount;\n            STATIC IOAPIC_DATA Controllers[IOAPIC_MAX_CONTROLLERS];\n            STATIC ULONG IrqOverrideCount;\n            STATIC ACPI_MADT_INTERRUPT_OVERRIDE IrqOverrides[IOAPIC_MAX_OVERRIDES];\n            STATIC UCHAR MappedVectors[256];\n\n        public:\n            STATIC XTAPI VOID AllocateSystemInterrupt(IN UCHAR Irq,\n                                                      IN UCHAR RunLevel,\n                                                      IN UCHAR Vector);\n            STATIC XTAPI VOID ClearApicErrors(VOID);\n            STATIC XTAPI ULONG GetCpuApicId(VOID);\n            STATIC XTAPI VOID InitializeIOApic(VOID);\n            STATIC XTAPI VOID InitializePic(VOID);\n            STATIC XTFASTCALL ULONGLONG ReadApicRegister(IN APIC_REGISTER Register);\n            STATIC XTAPI VOID SendBroadcastIpi(IN ULONG Vector,\n                                               IN BOOLEAN Self);\n            STATIC XTAPI VOID SendEoi(VOID);\n            STATIC XTAPI VOID SendIpi(IN ULONG ApicId,\n                                      IN ULONG Vector,\n                                      IN APIC_DM DeliveryMode,\n                                      IN APIC_DSH Destination,\n                                      IN ULONG TriggerMode);\n            STATIC XTAPI VOID SendSelfIpi(IN ULONG Vector);\n            STATIC XTFASTCALL VOID WriteApicRegister(IN APIC_REGISTER Register,\n                                                     IN ULONGLONG Value);\n\n        private:\n            STATIC XTAPI BOOLEAN CheckApicSupport(VOID);\n            STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);\n            STATIC XTAPI XTSTATUS DetectIoApicControllers(VOID);\n            STATIC XTAPI VOID ResolveInterruptOverride(IN UCHAR Irq,\n                                                       OUT PULONG Gsi,\n                                                       OUT PUSHORT Flags);\n            STATIC XTAPI XTSTATUS GetIoApicController(IN ULONG Gsi,\n                                                      OUT PIOAPIC_DATA *Controller,\n                                                      OUT PULONG EntryNumber);\n            STATIC XTCDECL VOID HandleApicErrorInterrupt(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTAPI VOID InitializeApic(VOID);\n            STATIC XTAPI VOID InitializeLegacyPic(VOID);\n            STATIC XTFASTCALL ULONG ReadIOApicRegister(IN PIOAPIC_DATA Controller,\n                                                       IN UCHAR Register);\n            STATIC XTFASTCALL IOAPIC_REDIRECTION_REGISTER ReadRedirectionEntry(IN PIOAPIC_DATA Controller,\n                                                                               IN ULONG EntryNumber);\n            STATIC XTFASTCALL UCHAR TranslateGsiToVector(IN ULONG Gsi);\n            STATIC XTFASTCALL VOID WriteIOApicRegister(IN PIOAPIC_DATA Controller,\n                                                       IN UCHAR Register,\n                                                       IN ULONG DataValue);\n            STATIC XTFASTCALL VOID WriteRedirectionEntry(IN PIOAPIC_DATA Controller,\n                                                         IN ULONG EntryNumber,\n                                                         IN IOAPIC_REDIRECTION_REGISTER EntryData);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_PIC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/rtc.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/rtc.hh\n * DESCRIPTION:     Hardware Real-Time Clock (RTC) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_RTC_HH\n#define __XTOSKRNL_HL_RTC_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class Rtc\n    {\n        public:\n            STATIC XTAPI XTSTATUS GetRealTimeClock(OUT PTIME_FIELDS Time);\n            STATIC XTAPI XTSTATUS SetRealTimeClock(IN PTIME_FIELDS Time);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_RTC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/runlevel.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/runlevel.hh\n * DESCRIPTION:     Run Level management support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_RUNLEVEL_HH\n#define __XTOSKRNL_HL_RUNLEVEL_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class RunLevel\n    {\n        public:\n            STATIC XTFASTCALL KRUNLEVEL GetRunLevel(VOID);\n            STATIC XTFASTCALL VOID SetRunLevel(IN KRUNLEVEL RunLevel);\n            STATIC XTFASTCALL UCHAR TransformRunLevelToSoftwareVector(IN KRUNLEVEL RunLevel);\n\n        private:\n            STATIC XTFASTCALL KRUNLEVEL TransformApicTprToRunLevel(IN UCHAR Tpr);\n            STATIC XTFASTCALL UCHAR TransformRunLevelToApicTpr(IN KRUNLEVEL RunLevel);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_RUNLEVEL_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl/timer.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl/timer.hh\n * DESCRIPTION:     ACPI Timer support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_TIMER_HH\n#define __XTOSKRNL_HL_TIMER_HH\n\n#include <xtos.hh>\n\n\n/* Hardware Layer */\nnamespace HL\n{\n    class Timer\n    {\n        private:\n            STATIC ULONG AcpiPmPerformanceCounter;\n            STATIC TIMER_TYPE ClockType;\n            STATIC ULONG FractionalIncrement;\n            STATIC PVOID HpetAddress;\n            STATIC ULONGLONG HpetFrequency;\n            STATIC KSPIN_LOCK PerformanceCounterLock;\n            STATIC ULONGLONG PerformanceFrequency;\n            STATIC ULONGLONG PitPerformanceCounter;\n            STATIC ULONG PitRollover;\n            STATIC BOOLEAN ProfilingEnabled;\n            STATIC ULONG ProfilingTicks;\n            STATIC ULONG RunningFraction;\n            STATIC ULONGLONG SystemPerformanceCounter;\n            STATIC ULONG TimeIncrement;\n            STATIC TIMER_CAPABILITIES TimerCapabilities;\n            STATIC ULONG TimerFrequency;\n            STATIC TIMER_ROUTINES TimerRoutines;\n            STATIC TIMER_TYPE TimerType;\n\n        public:\n            STATIC XTAPI VOID InitializeTimer(VOID);\n            STATIC XTAPI LARGE_INTEGER QueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency);\n            STATIC XTAPI ULONG SetClockRate(IN ULONG Rate);\n            STATIC XTAPI ULONG_PTR SetProfileInterval(IN ULONG_PTR Interval);\n            STATIC XTAPI VOID StallExecution(IN ULONG MicroSeconds);\n            STATIC XTAPI VOID StartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource);\n            STATIC XTAPI VOID StopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource);\n\n        private:\n            STATIC XTAPI XTSTATUS CalibrateApicTimer();\n            STATIC XTAPI ULONGLONG CalibrateTscCounter(VOID);\n            STATIC XTAPI VOID ConfigureTimeIncrement(IN ULONGLONG BaseFrequency,\n                                                     IN ULONGLONG HardwareDivider);\n            STATIC XTAPI XTSTATUS DetectHpet(VOID);\n            STATIC XTCDECL VOID HandleClockInterrupt(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTCDECL VOID HandleClockIpiInterrupt(IN PKTRAP_FRAME TrapFrame);\n            STATIC XTAPI XTSTATUS InitializeApicTimer(VOID);\n            STATIC XTAPI XTSTATUS InitializeHpetTimer(VOID);\n            STATIC XTAPI XTSTATUS InitializePitTimer(VOID);\n            STATIC XTAPI VOID ProbeTimerType(VOID);\n            STATIC XTAPI ULONGLONG QueryPerformanceCounterAcpiPm(VOID);\n            STATIC XTAPI ULONGLONG QueryPerformanceCounterHpet(VOID);\n            STATIC XTAPI ULONGLONG QueryPerformanceCounterPit(VOID);\n            STATIC XTAPI ULONGLONG QueryPerformanceCounterTsc(VOID);\n            STATIC XTAPI VOID QueryTimerCapabilities(VOID);\n            STATIC XTAPI ULONG SetClockRateApic(ULONG TargetIncrement);\n            STATIC XTAPI VOID StallExecutionAcpiPm(IN ULONG MicroSeconds);\n            STATIC XTAPI VOID StallExecutionHpet(IN ULONG MicroSeconds);\n            STATIC XTAPI VOID StallExecutionPit(IN ULONG MicroSeconds);\n            STATIC XTAPI VOID StallExecutionTsc(IN ULONG MicroSeconds);\n            STATIC XTAPI BOOLEAN ValidateTimerSupport(IN TIMER_TYPE TimerType,\n                                                      IN BOOLEAN IsClock);\n    };\n}\n\n#endif /* __XTOSKRNL_HL_TIMER_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/hl.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/hl.hh\n * DESCRIPTION:     Hardware Layer\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_HL_HH\n#define __XTOSKRNL_HL_HH\n\n#include <xtos.hh>\n\n#include <hl/acpi.hh>\n#include <hl/cport.hh>\n#include <hl/cpu.hh>\n#include <hl/fbdev.hh>\n#include <hl/firmware.hh>\n#include <hl/init.hh>\n#include <hl/ioport.hh>\n#include <hl/ioreg.hh>\n#include <hl/irq.hh>\n#include <hl/pic.hh>\n#include <hl/rtc.hh>\n#include <hl/runlevel.hh>\n#include <hl/timer.hh>\n\n\n#endif /* __XTOSKRNL_HL_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/kd/dbg.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/kd/dbg.hh\n * DESCRIPTION:     Kernel debugging support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KD_DBG_HH\n#define __XTOSKRNL_KD_DBG_HH\n\n#include <xtos.hh>\n\n\n/* Redefine DebugPrint macro for the kernel to enable early debugging */\n#undef DebugPrint\n#ifdef DBG\n    #define DebugPrint(Format, ...)     if(KD::DebugIo::KdPrint) KD::DebugIo::KdPrint(Format, __VA_ARGS__);\n#else\n    #define DebugPrint(Format, ...)     ((VOID)NULLPTR)\n#endif\n\n#endif /* __XTOSKRNL_KD_DBG_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/kd/dbgio.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/kd/dbgio.hh\n * DESCRIPTION:     Kernel Debugger I/O support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KD_DBGIO_HH\n#define __XTOSKRNL_KD_DBGIO_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Debugger */\nnamespace KD\n{\n    class DebugIo\n    {\n        public:\n            STATIC PKD_PRINT_ROUTINE KdPrint;\n\n        private:\n            STATIC KSPIN_LOCK DebugIoLock;\n            STATIC KD_DEBUG_MODE DebugMode;\n            STATIC PKD_INIT_ROUTINE IoProvidersInitRoutines[KDBG_PROVIDERS_COUNT];\n            STATIC LIST_ENTRY Providers;\n            STATIC CPPORT SerialPort;\n            STATIC ULONG SerialPortList[COMPORT_COUNT];\n\n        public:\n            STATIC XTCDECL VOID DbgPrint(PCWSTR Format,\n                                         ...);\n            STATIC XTCDECL VOID DbgPrint(PCWSTR Format,\n                                         VA_LIST Arguments);\n            STATIC XTAPI XTSTATUS InitializeDebugIoProviders(VOID);\n            STATIC XTAPI VOID SetPrintRoutine(PKD_PRINT_ROUTINE DebugPrintRoutine);\n\n        private:\n            STATIC XTAPI XTSTATUS DetectDebugPorts(VOID);\n            STATIC XTAPI XTSTATUS InitializeFrameBufferProvider(VOID);\n            STATIC XTAPI XTSTATUS InitializeSerialPortProvider(VOID);\n            STATIC XTCDECL XTSTATUS SerialWriteCharacter(WCHAR Character);\n    };\n}\n\n#endif /* __XTOSKRNL_KD_DBGIO_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/kd.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/kd.hh\n * DESCRIPTION:     Kernel Debugger\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KD_HH\n#define __XTOSKRNL_KD_HH\n\n#include <xtos.hh>\n\n#include <kd/dbg.hh>\n#include <kd/dbgio.hh>\n\n#endif /* __XTOSKRNL_KD_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/apc.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/apc.hh\n * DESCRIPTION:     Kernel APC objects support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_APC_HH\n#define __XTOSKRNL_KE_APC_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class Apc\n    {\n        public:\n            STATIC XTAPI VOID InitializeApc(IN PKAPC Apc,\n                                            IN PKTHREAD Thread,\n                                            IN KAPC_ENVIRONMENT Environment,\n                                            IN PKKERNEL_ROUTINE KernelRoutine,\n                                            IN PKRUNDOWN_ROUTINE RundownRoutine,\n                                            IN PKNORMAL_ROUTINE NormalRoutine,\n                                            IN KPROCESSOR_MODE ApcMode,\n                                            IN PVOID Context);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_APC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/bootinfo.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/bootinfo.hh\n * DESCRIPTION:     Bootloader-provided system information handling support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_BOOTINFO_HH\n#define __XTOSKRNL_KE_BOOTINFO_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class BootInformation\n    {\n        private:\n            STATIC PKERNEL_INITIALIZATION_BLOCK InitializationBlock;\n\n        public:\n            STATIC XTAPI PKD_PRINT_ROUTINE GetDebugPrint(VOID);\n            STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID);\n            STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName,\n                                                     OUT PCWSTR *Parameter);\n            STATIC XTAPI XTSTATUS GetKernelParameterValue(IN PCWSTR ParameterName,\n                                                          OUT PWSTR ValueBuffer,\n                                                          IN SIZE_T BufferSize);\n            STATIC XTAPI PLIST_ENTRY GetMemoryDescriptors(VOID);\n            STATIC XTAPI PLIST_ENTRY GetSystemResources(VOID);\n            STATIC XTAPI VOID InitializeInitializationBlock(IN PKERNEL_INITIALIZATION_BLOCK Block);\n\n            /* TEMPORARY FOR COMPATIBILITY WITH C CODE */\n            STATIC XTAPI PKERNEL_INITIALIZATION_BLOCK GetInitializationBlock(VOID)\n            {\n                return InitializationBlock;\n            }\n    };\n}\n\n#endif /* __XTOSKRNL_KE_BOOTINFO_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/crash.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/crash.hh\n * DESCRIPTION:     System shutdown and kernel panic mechanism\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_CRASH_HH\n#define __XTOSKRNL_KE_CRASH_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class Crash\n    {\n        public:\n            STATIC XTAPI VOID HaltSystem(VOID);\n            STATIC XTAPI VOID Panic(IN ULONG Code);\n            STATIC XTAPI VOID Panic(IN ULONG Code,\n                                    IN ULONG_PTR Parameter1,\n                                    IN ULONG_PTR Parameter2,\n                                    IN ULONG_PTR Parameter3,\n                                    IN ULONG_PTR Parameter4);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_CRASH_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/dispatch.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/dispatch.hh\n * DESCRIPTION:     Kernel Thread Dispatcher\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTOSKRNL_KE_DISPATCH_HH\n#define __XTOSKRNL_KE_DISPATCH_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class Dispatcher\n    {\n        public:\n            STATIC XTFASTCALL VOID ExitDispatcher(IN KRUNLEVEL OldRunLevel);\n            STATIC XTFASTCALL BOOLEAN SwitchContext(IN PKTHREAD CurrentThread,\n                                                    IN KRUNLEVEL RunLevel);\n            STATIC XTAPI VOID UpdateRunTime(IN PKTRAP_FRAME TrapFrame,\n                                            IN KRUNLEVEL RunLevel);\n\n        private:\n            STATIC XTFASTCALL BOOLEAN SwitchThreadContext(IN PKTHREAD CurrentThread,\n                                                          IN BOOLEAN ApcBypass);\n            STATIC XTFASTCALL BOOLEAN SwitchThreadStack(IN PKTHREAD CurrentThread,\n                                                        IN KRUNLEVEL RunLevel);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_DISPATCH_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/dpc.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/dpc.hh\n * DESCRIPTION:     Deferred Procedure Call (DPC) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_DPC_HH\n#define __XTOSKRNL_KE_DPC_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class Dpc\n    {\n        public:\n            STATIC XTAPI VOID InitializeDpc(IN PKDPC Dpc,\n                                            IN PKDEFERRED_ROUTINE DpcRoutine,\n                                            IN PVOID DpcContext);\n            STATIC XTAPI VOID InitializeThreadedDpc(IN PKDPC Dpc,\n                                                    IN PKDEFERRED_ROUTINE DpcRoutine,\n                                                    IN PVOID DpcContext);\n            STATIC XTAPI VOID SetTargetProcessor(IN PKDPC Dpc,\n                                                 IN CCHAR Number);\n            STATIC XTAPI VOID SignalCallDone(IN PVOID SystemArgument);\n            STATIC XTAPI BOOLEAN SignalCallSynchronize(IN PVOID SystemArgument);\n\n        private:\n            STATIC XTFASTCALL VOID RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_DPC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/event.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/event.hh\n * DESCRIPTION:     Kernel events support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_EVENT_HH\n#define __XTOSKRNL_KE_EVENT_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class Event\n    {\n        public:\n            STATIC XTAPI VOID ClearEvent(IN PKEVENT Event);\n            STATIC XTAPI VOID InitializeEvent(OUT PKEVENT Event,\n                                              IN KEVENT_TYPE EventType,\n                                              IN BOOLEAN InitialState);\n            STATIC XTAPI LONG SetEvent(IN PKEVENT Event,\n                                       IN KPRIORITY Increment,\n                                       IN BOOLEAN Wait);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_EVENT_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/guard.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/guard.hh\n * DESCRIPTION:     Kernel synchronization guard\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_GUARD_HH\n#define __XTOSKRNL_KE_GUARD_HH\n\n#include <xtos.hh>\n#include <ke/spinlock.hh>\n\n/* Kernel Library */\nnamespace KE\n{\n    class QueuedSpinLockGuard\n    {\n        private:\n            KSPIN_LOCK_QUEUE_LEVEL QueuedLockLevel;\n\n        public:\n            QueuedSpinLockGuard(IN OUT KSPIN_LOCK_QUEUE_LEVEL LockLevel)\n            {\n                QueuedLockLevel = LockLevel;\n                KE::SpinLock::AcquireQueuedSpinLock(QueuedLockLevel);\n            }\n\n            ~QueuedSpinLockGuard()\n            {\n                KE::SpinLock::ReleaseQueuedSpinLock(QueuedLockLevel);\n            }\n\n            QueuedSpinLockGuard(const QueuedSpinLockGuard&) = delete;\n            QueuedSpinLockGuard& operator=(const QueuedSpinLockGuard&) = delete;\n    };\n\n    class SpinLockGuard\n    {\n        private:\n            PKSPIN_LOCK Lock;\n\n        public:\n            SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock)\n            {\n                Lock = SpinLock;\n                KE::SpinLock::AcquireSpinLock(Lock);\n            }\n\n            ~SpinLockGuard()\n            {\n                KE::SpinLock::ReleaseSpinLock(Lock);\n            }\n\n            SpinLockGuard(const SpinLockGuard&) = delete;\n            SpinLockGuard& operator=(const SpinLockGuard&) = delete;\n    };\n}\n\n#endif /* __XTOSKRNL_KE_GUARD_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/kprocess.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/kprocess.hh\n * DESCRIPTION:     XT kernel process manipulation support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_KPROCESS_HH\n#define __XTOSKRNL_KE_KPROCESS_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class KProcess\n    {\n        private:\n            STATIC EPROCESS InitialProcess;\n\n        public:\n            STATIC XTAPI PEPROCESS GetInitialProcess(VOID);\n            STATIC XTAPI VOID InitializeProcess(IN OUT PKPROCESS Process,\n                                                IN KPRIORITY Priority,\n                                                IN KAFFINITY Affinity,\n                                                IN PULONG_PTR DirectoryTable,\n                                                IN BOOLEAN Alignment);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_KPROCESS_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/krnlinit.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/krnlinit.hh\n * DESCRIPTION:     XTOS Kernel initialization\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_KRNLINIT_HH\n#define __XTOSKRNL_KE_KRNLINIT_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class KernelInit\n    {\n        public:\n            STATIC XTAPI VOID BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock);\n            STATIC XTAPI VOID InitializeMachine(VOID);\n            STATIC XTAPI VOID SwitchBootStack(VOID);\n\n        private:\n            STATIC XTAPI VOID BootstrapKernel(VOID);\n            STATIC XTAPI VOID InitializeKernel(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_KRNLINIT_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/kthread.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/kthread.hh\n * DESCRIPTION:     XT kernel thread manipulation support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_KTHREAD_HH\n#define __XTOSKRNL_KE_KTHREAD_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class KThread\n    {\n        private:\n            STATIC ETHREAD InitialThread;\n\n        public:\n            STATIC XTAPI PETHREAD GetInitialThread(VOID);\n            STATIC XTAPI XTSTATUS InitializeThread(IN PKPROCESS Process,\n                                                   IN OUT PKTHREAD Thread,\n                                                   IN PKSYSTEM_ROUTINE SystemRoutine,\n                                                   IN PKSTART_ROUTINE StartRoutine,\n                                                   IN PVOID StartContext,\n                                                   IN PCONTEXT Context,\n                                                   IN PVOID EnvironmentBlock,\n                                                   IN PVOID Stack,\n                                                   IN BOOLEAN StartThread);\n            STATIC XTAPI VOID StartThread(IN PKTHREAD Thread);\n\n        private:\n            STATIC XTAPI VOID InitializeThreadContext(IN PKTHREAD Thread,\n                                                      IN PKSYSTEM_ROUTINE SystemRoutine,\n                                                      IN PKSTART_ROUTINE StartRoutine,\n                                                      IN PVOID StartContext,\n                                                      IN PCONTEXT ContextRecord);\n            STATIC XTAPI VOID SuspendNop(IN PKAPC Apc,\n                                         IN OUT PKNORMAL_ROUTINE *NormalRoutine,\n                                         IN OUT PVOID *NormalContext,\n                                         IN OUT PVOID *SystemArgument1,\n                                         IN OUT PVOID *SystemArgument2);\n            STATIC XTAPI VOID SuspendRundown(IN PKAPC Apc);\n            STATIC XTAPI VOID SuspendThread(IN PVOID NormalContext,\n                                            IN PVOID SystemArgument1,\n                                            IN PVOID SystemArgument2);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_KTHREAD_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/kubsan.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/kubsan.hh\n * DESCRIPTION:     Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_KUBSAN_HH\n#define __XTOSKRNL_KE_KUBSAN_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class KUbsan\n    {\n        private:\n            STATIC BOOLEAN ActiveFrame;\n\n        public:\n            STATIC XTCDECL VOID HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,\n                                                       PVOID Lhs,\n                                                       PVOID Rhs);\n            STATIC XTCDECL VOID HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,\n                                                        ULONG_PTR Lhs,\n                                                        ULONG_PTR Rhs);\n            STATIC XTCDECL VOID HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,\n                                                           ULONG_PTR Pointer);\n            STATIC XTCDECL VOID HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data,\n                                                      ULONG_PTR Lhs,\n                                                      ULONG_PTR Rhs);\n            STATIC XTCDECL VOID HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data);\n            STATIC XTCDECL VOID HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data,\n                                                       ULONG_PTR Pointer);\n            STATIC XTCDECL VOID HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data,\n                                                     ULONG_PTR OldValue);\n            STATIC XTCDECL VOID HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data);\n            STATIC XTCDECL VOID HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,\n                                                         ULONG_PTR Pointer);\n            STATIC XTCDECL VOID HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data,\n                                                  ULONG_PTR Index);\n            STATIC XTCDECL VOID HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data,\n                                                      ULONG_PTR Lhs,\n                                                      ULONG_PTR Rhs);\n            STATIC XTCDECL VOID HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,\n                                                       ULONG_PTR Lhs,\n                                                       ULONG_PTR Rhs);\n            STATIC XTCDECL VOID HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,\n                                                   ULONG_PTR Pointer);\n\n        private:\n            STATIC XTCDECL BOOLEAN CheckReport(PKUBSAN_SOURCE_LOCATION Location);\n            STATIC XTCDECL VOID EnterFrame(PKUBSAN_SOURCE_LOCATION Location,\n                                           PCCHAR Reason);\n            STATIC XTCDECL LONGLONG GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,\n                                                   PVOID Value);\n            STATIC XTCDECL PCCHAR GetTypeKind(UCHAR TypeCheckKind);\n            STATIC XTCDECL ULONGLONG GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,\n                                                      PVOID Value);\n            STATIC XTCDECL VOID LeaveFrame();\n    };\n}\n\n#endif /* __XTOSKRNL_KE_KUBSAN_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/proc.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/proc.hh\n * DESCRIPTION:     Processor-related functionality for the kernel\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_PROC_HH\n#define __XTOSKRNL_KE_PROC_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class Processor\n    {\n        private:\n            STATIC ULONG InstalledCpus;\n            STATIC PKPROCESSOR_BLOCK *ProcessorBlocks;\n\n        public:\n            STATIC XTAPI PKPROCESSOR_BLOCK GetCurrentProcessorBlock(VOID);\n            STATIC XTAPI PKPROCESSOR_CONTROL_BLOCK GetCurrentProcessorControlBlock(VOID);\n            STATIC XTAPI ULONG GetCurrentProcessorNumber(VOID);\n            STATIC XTAPI PKTHREAD GetCurrentThread(VOID);\n            STATIC XTAPI PKPROCESSOR_BLOCK GetProcessorBlock(IN ULONG CpuNumber);\n            STATIC XTAPI XTSTATUS InitializeProcessorBlocks();\n            STATIC XTAPI VOID RegisterHardwareId(IN ULONG HardwareId);\n            STATIC XTAPI VOID RegisterProcessorBlock(ULONG CpuNumber,\n                                                     PKPROCESSOR_BLOCK ProcessorBlock);\n            STATIC XTAPI VOID SaveProcessorState(OUT PKPROCESSOR_STATE CpuState);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_PROC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/runlevel.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/runlevel.hh\n * DESCRIPTION:     Running Level management support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_RUNLEVEL_HH\n#define __XTOSKRNL_KE_RUNLEVEL_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class RunLevel\n    {\n        public:\n            STATIC XTFASTCALL KRUNLEVEL GetCurrentRunLevel(VOID);\n            STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);\n            STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);\n    };\n\n    class LowerRunLevel\n    {\n        private:\n            KRUNLEVEL PreviousRunLevel;\n\n        public:\n            LowerRunLevel(KRUNLEVEL RunLevel)\n            {\n                PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();\n                KE::RunLevel::LowerRunLevel(RunLevel);\n            }\n\n            ~LowerRunLevel()\n            {\n                KE::RunLevel::RaiseRunLevel(PreviousRunLevel);\n            }\n\n            LowerRunLevel(const LowerRunLevel&) = delete;\n            LowerRunLevel& operator=(const LowerRunLevel&) = delete;\n    };\n\n    class RaiseRunLevel\n    {\n        private:\n            KRUNLEVEL PreviousRunLevel;\n\n        public:\n            RaiseRunLevel(KRUNLEVEL RunLevel)\n            {\n                PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();\n                KE::RunLevel::RaiseRunLevel(RunLevel);\n            }\n\n            ~RaiseRunLevel()\n            {\n                KE::RunLevel::LowerRunLevel(PreviousRunLevel);\n            }\n\n            RaiseRunLevel(const RaiseRunLevel&) = delete;\n            RaiseRunLevel& operator=(const RaiseRunLevel&) = delete;\n    };\n}\n\n#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/semphore.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/semphore.hh\n * DESCRIPTION:     Semaphores support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_SEMPHORE_HH\n#define __XTOSKRNL_KE_SEMPHORE_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class Semaphore\n    {\n        public:\n            STATIC XTAPI VOID InitializeSemaphore(IN PKSEMAPHORE Semaphore,\n                                                  IN LONG Count,\n                                                  IN LONG Limit);\n            STATIC XTAPI LONG ReadState(IN PKSEMAPHORE Semaphore);\n            STATIC XTAPI LONG ReleaseSemaphore(IN PKSEMAPHORE Semaphore,\n                                               IN KPRIORITY Increment,\n                                               IN LONG Adjustment,\n                                               IN BOOLEAN Wait);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_SEMPHORE_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/shdata.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/shdata.hh\n * DESCRIPTION:     Kernel Shared Data\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_SHDATA_HH\n#define __XTOSKRNL_KE_SHDATA_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class SharedData\n    {\n        private:\n            STATIC PKSHARED_DATA KernelSharedData;\n\n        public:\n            STATIC XTAPI LARGE_INTEGER GetInterruptTime(VOID);\n            STATIC XTAPI PKSHARED_DATA GetKernelSharedData(VOID);\n            STATIC XTAPI LARGE_INTEGER GetSystemTime(VOID);\n            STATIC XTAPI LARGE_INTEGER GetTickCount(VOID);\n            STATIC XTAPI VOID IncrementTickCount();\n            STATIC XTAPI VOID InitializeKernelSharedData(VOID);\n            STATIC XTAPI VOID SetInterruptTime(IN LARGE_INTEGER Time);\n            STATIC XTAPI VOID SetSystemTime(IN LARGE_INTEGER Time);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_SHDATA_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/spinlock.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/spinlock.hh\n * DESCRIPTION:     Spinlocks support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_SPINLOCK_HH\n#define __XTOSKRNL_KE_SPINLOCK_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class SpinLock\n    {\n        private:\n            STATIC KSPIN_LOCK DispatcherLockQueue;\n            STATIC KSPIN_LOCK ExpansionLockQueue;\n            STATIC KSPIN_LOCK FileSystemLockQueue;\n            STATIC KSPIN_LOCK IoCancelLockQueue;\n            STATIC KSPIN_LOCK IoCompletionLockQueue;\n            STATIC KSPIN_LOCK IoDatabaseLockQueue;\n            STATIC KSPIN_LOCK IoVpbLockQueue;\n            STATIC KSPIN_LOCK MasterLockQueue;\n            STATIC KSPIN_LOCK NonPagedAllocLockQueue;\n            STATIC KSPIN_LOCK NonPagedPoolLockQueue;\n            STATIC KSPIN_LOCK PfnLockQueue;\n            STATIC KSPIN_LOCK SystemSpaceLockQueue;\n            STATIC KSPIN_LOCK TimerTableLockQueue;\n            STATIC KSPIN_LOCK VacbLockQueue;\n            STATIC KSPIN_LOCK WorkLockQueue;\n\n        public:\n            STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);\n            STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);\n            STATIC XTAPI VOID InitializeAllLocks();\n            STATIC XTAPI VOID InitializeLockQueues();\n            STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);\n            STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);\n            STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);\n            STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_SPINLOCK_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/sysres.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/sysres.hh\n * DESCRIPTION:     System boot resources management\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_SYSRES_HH\n#define __XTOSKRNL_KE_SYSRES_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class SystemResources\n    {\n        private:\n            STATIC LIST_ENTRY ResourcesListHead;\n            STATIC KSPIN_LOCK ResourcesLock;\n\n        public:\n            STATIC XTAPI XTSTATUS AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                                                  OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);\n            STATIC XTAPI XTSTATUS GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                                              OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);\n            STATIC XTAPI VOID InitializeResources(VOID);\n            STATIC XTAPI VOID ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader);\n\n        private:\n            STATIC XTAPI XTSTATUS GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                                                    IN BOOLEAN ResourceLock,\n                                                    OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);\n\n    };\n}\n\n#endif /* __XTOSKRNL_KE_SYSRES_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/systime.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/systime.hh\n * DESCRIPTION:     Timebase and system clock support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_SYSTIME_HH\n#define __XTOSKRNL_KE_SYSTIME_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class SystemTime\n    {\n        private:\n            STATIC LARGE_INTEGER BootTime;\n            STATIC ULONG MaximumIncrement;\n            STATIC ULONG MinimumIncrement;\n            STATIC LONG TickOffset;\n            STATIC ULONG TimeAdjustment;\n\n        public:\n            STATIC XTAPI VOID GetSystemTime(OUT PLARGE_INTEGER SystemTime);\n            STATIC XTAPI VOID SetSystemTime(IN PLARGE_INTEGER NewTime,\n                                            OUT PLARGE_INTEGER OldTime,\n                                            IN BOOLEAN AdjustInterruptTime,\n                                            IN BOOLEAN WriteToRtc);\n            STATIC XTAPI VOID SetTimeIncrement(IN ULONG MinIncrement,\n                                               IN ULONG MaxIncrement);\n            STATIC XTFASTCALL VOID UpdateSystemTime(IN PKTRAP_FRAME TrapFrame,\n                                                    IN ULONG Increment,\n                                                    IN KRUNLEVEL RunLevel);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_SYSTIME_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke/timer.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke/timer.hh\n * DESCRIPTION:     Kernel timer object support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_TIMER_HH\n#define __XTOSKRNL_KE_TIMER_HH\n\n#include <xtos.hh>\n\n\n/* Kernel Library */\nnamespace KE\n{\n    class Timer\n    {\n        public:\n            STATIC XTAPI BOOLEAN CancelTimer(IN PKTIMER Timer);\n            STATIC XTAPI VOID ClearTimer(IN PKTIMER Timer);\n            STATIC XTAPI BOOLEAN GetState(IN PKTIMER Timer);\n            STATIC XTAPI VOID InitializeTimer(OUT PKTIMER Timer,\n                                              IN KTIMER_TYPE Type);\n            STATIC XTAPI ULONGLONG QueryTimer(IN PKTIMER Timer);\n            STATIC XTAPI VOID SetTimer(IN PKTIMER Timer,\n                                       IN LARGE_INTEGER DueTime,\n                                       IN LONG Period,\n                                       IN PKDPC Dpc);\n\n        private:\n            STATIC XTAPI VOID RemoveTimer(IN OUT PKTIMER Timer);\n    };\n}\n\n#endif /* __XTOSKRNL_KE_TIMER_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/ke.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/ke.hh\n * DESCRIPTION:     Kernel Library\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_KE_HH\n#define __XTOSKRNL_KE_HH\n\n#include <xtos.hh>\n\n#include <ke/apc.hh>\n#include <ke/bootinfo.hh>\n#include <ke/crash.hh>\n#include <ke/dispatch.hh>\n#include <ke/dpc.hh>\n#include <ke/event.hh>\n#include <ke/guard.hh>\n#include <ke/kprocess.hh>\n#include <ke/krnlinit.hh>\n#include <ke/kthread.hh>\n#include <ke/kubsan.hh>\n#include <ke/proc.hh>\n#include <ke/runlevel.hh>\n#include <ke/semphore.hh>\n#include <ke/shdata.hh>\n#include <ke/spinlock.hh>\n#include <ke/sysres.hh>\n#include <ke/systime.hh>\n#include <ke/timer.hh>\n\n#endif /* __XTOSKRNL_KE_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/alloc.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/alloc.hh\n * DESCRIPTION:     Memory Manager pool allocator\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_ALLOC_HH\n#define __XTOSKRNL_MM_ALLOC_HH\n\n#include <xtos.hh>\n#include <mm/pool.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Allocator final : private Pool\n    {\n        private:\n            STATIC PPOOL_TRACKING_TABLE AllocationsTrackingExpansionTable;\n            STATIC SIZE_T AllocationsTrackingExpansionTableSize;\n            STATIC PPOOL_TRACKING_TABLE AllocationsTrackingTable;\n            STATIC KSPIN_LOCK AllocationsTrackingTableLock;\n            STATIC SIZE_T AllocationsTrackingTableMask;\n            STATIC SIZE_T AllocationsTrackingTableSize;\n            STATIC ULONG BigAllocationsInUse;\n            STATIC PPOOL_TRACKING_BIG_ALLOCATIONS BigAllocationsTrackingTable;\n            STATIC SIZE_T BigAllocationsTrackingTableHash;\n            STATIC KSPIN_LOCK BigAllocationsTrackingTableLock;\n            STATIC SIZE_T BigAllocationsTrackingTableSize;\n            STATIC PPOOL_TRACKING_TABLE TagTables[MM_POOL_TRACKING_TABLES];\n\n        public:\n            STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType,\n                                                IN SIZE_T Bytes,\n                                                OUT PVOID *Memory);\n            STATIC XTAPI XTSTATUS AllocatePool(IN MMPOOL_TYPE PoolType,\n                                               IN SIZE_T Bytes,\n                                               OUT PVOID *Memory);\n            STATIC XTAPI XTSTATUS AllocatePool(IN MMPOOL_TYPE PoolType,\n                                               IN SIZE_T Bytes,\n                                               OUT PVOID *Memory,\n                                               IN ULONG Tag);\n            STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress);\n            STATIC XTAPI XTSTATUS FreePages(IN PVOID VirtualAddress,\n                                            OUT PPFN_NUMBER PagesFreed);\n            STATIC XTAPI XTSTATUS FreePool(IN PVOID VirtualAddress);\n            STATIC XTAPI XTSTATUS FreePool(IN PVOID VirtualAddress,\n                                           IN ULONG Tag);\n            STATIC XTAPI VOID InitializeAllocationsTracking(VOID);\n            STATIC XTAPI VOID InitializeBigAllocationsTracking(VOID);\n\n        private:\n            STATIC XTAPI XTSTATUS AllocateNonPagedPoolPages(IN PFN_COUNT Pages,\n                                                            OUT PVOID *Memory);\n            STATIC XTAPI XTSTATUS AllocatePagedPoolPages(IN PFN_COUNT Pages,\n                                                         OUT PVOID *Memory);\n            STATIC XTINLINE ULONG ComputeHash(IN PVOID VirtualAddress);\n            STATIC XTINLINE ULONG ComputeHash(IN ULONG Tag,\n                                              IN ULONG TableMask);\n            STATIC XTAPI BOOLEAN ExpandBigAllocationsTable(VOID);\n            STATIC XTAPI XTSTATUS FreeNonPagedPoolPages(IN PVOID VirtualAddress,\n                                                        OUT PPFN_NUMBER PagesFreed);\n            STATIC XTAPI XTSTATUS FreePagedPoolPages(IN PVOID VirtualAddress,\n                                                     OUT PPFN_NUMBER PagesFreed);\n            STATIC XTAPI VOID RegisterAllocationTag(IN ULONG Tag,\n                                                    IN SIZE_T Bytes,\n                                                    IN MMPOOL_TYPE PoolType);\n            STATIC XTAPI VOID RegisterAllocationTagExpansion(IN ULONG Tag,\n                                                             IN SIZE_T Bytes,\n                                                             IN MMPOOL_TYPE PoolType);\n            STATIC XTAPI BOOLEAN RegisterBigAllocationTag(IN PVOID VirtualAddress,\n                                                          IN ULONG Tag,\n                                                          IN ULONG Pages,\n                                                          IN MMPOOL_TYPE PoolType);\n            STATIC XTAPI VOID UnregisterAllocationTag(IN ULONG Tag,\n                                                      IN SIZE_T Bytes,\n                                                      IN MMPOOL_TYPE PoolType);\n            STATIC XTAPI VOID UnregisterAllocationTagExpansion(IN ULONG Tag,\n                                                               IN SIZE_T Bytes,\n                                                               IN MMPOOL_TYPE PoolType);\n            STATIC XTAPI ULONG UnregisterBigAllocationTag(IN PVOID VirtualAddress,\n                                                          OUT PULONG_PTR Pages,\n                                                          IN MMPOOL_TYPE PoolType);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_ALLOC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/amd64/pagemap.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/amd64/pagemap.hh\n * DESCRIPTION:     Low-level support for page map manipulation\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_AMD64_PAGEMAP_HH\n#define __XTOSKRNL_MM_AMD64_PAGEMAP_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    typedef class PageMap\n    {\n        protected:\n            MMPAGEMAP_INFO PageMapInfo;\n\n        public:\n            XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,\n                                    IN LONG Count);\n            XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);\n            XTAPI VOID ClearPte(IN PMMPTE PtePointer);\n            XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);\n            XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);\n            XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);\n            XTAPI PMMP5E GetP5eAddress(IN PVOID Address);\n            XTAPI ULONG GetP5eOffset(IN PVOID Address);\n            XTAPI PVOID GetP5eVirtualAddress(IN PMMP5E P5ePointer);\n            XTAPI USHORT GetPageMapLevel();\n            XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);\n            XTAPI PMMPDE GetPdeAddress(IN PVOID Address);\n            XTAPI ULONG GetPdeOffset(IN PVOID Address);\n            VIRTUAL XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer) = 0;\n            XTAPI PMMPPE GetPpeAddress(IN PVOID Address);\n            XTAPI ULONG GetPpeOffset(IN PVOID Address);\n            VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0;\n            XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);\n            XTAPI PMMPTE GetPteAddress(IN PVOID Address);\n            XTAPI LONG GetPteDistance(PMMPTE EndPte,\n                                      PMMPTE StartPte);\n            XTAPI ULONG GetPteOffset(IN PVOID Address);\n            XTAPI ULONG GetPteSize(VOID);\n            XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);\n            XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);\n            XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);\n            VIRTUAL XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer) = 0;\n            XTAPI PMMPXE GetPxeAddress(IN PVOID Address);\n            XTAPI ULONG GetPxeOffset(IN PVOID Address);\n            VIRTUAL XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer) = 0;\n            XTAPI BOOLEAN GetXpaStatus();\n            VIRTUAL XTAPI VOID InitializePageMapInfo(VOID) = 0;\n            XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);\n            XTAPI VOID SetNextEntry(IN PMMPTE Pte,\n                                    IN ULONG_PTR Value);\n            XTAPI VOID SetOneEntry(IN PMMPTE Pte,\n                                   IN BOOLEAN Value);\n            XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                              IN PFN_NUMBER PageFrameNumber,\n                              IN ULONGLONG AttributesMask);\n            XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                              IN ULONGLONG Attributes);\n            XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,\n                                     IN BOOLEAN CacheDisable,\n                                     IN BOOLEAN WriteThrough);\n            XTAPI VOID TransitionPte(IN PMMPTE PointerPte,\n                                     IN ULONG_PTR Protection);\n            XTAPI VOID WritePte(IN PMMPTE Pte,\n                                IN MMPTE Value);\n    } PAGEMAP, *PPAGEMAP;\n\n    class PageMapBasic final : public PageMap\n    {\n        public:\n            XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);\n            XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);\n            XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);\n            XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);\n            XTAPI VOID InitializePageMapInfo(VOID);\n    };\n\n    class PageMapXpa final : public PageMap\n    {\n        public:\n            XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);\n            XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);\n            XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);\n            XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);\n            XTAPI VOID InitializePageMapInfo(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_AMD64_PAGEMAP_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/amd64/paging.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/amd64/paging.hh\n * DESCRIPTION:     Low level page management support for AMD64\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_AMD64_PAGING_HH\n#define __XTOSKRNL_MM_AMD64_PAGING_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Paging\n    {\n        private:\n            STATIC PPAGEMAP PmlRoutines;\n\n        public:\n            STATIC XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,\n                                           IN LONG Count);\n            STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);\n            STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);\n            STATIC XTAPI VOID FlushEntireTlb(VOID);\n            STATIC XTAPI VOID FlushTlb(VOID);\n            STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);\n            STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);\n            STATIC XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);\n            STATIC XTAPI PMMP5E GetP5eAddress(IN PVOID Address);\n            STATIC XTAPI PVOID GetP5eVirtualAddress(IN PMMP5E P5ePointer);\n            STATIC XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);\n            STATIC XTAPI USHORT GetPageMapLevel();\n            STATIC XTAPI PMMPDE GetPdeAddress(IN PVOID Address);\n            STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);\n            STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);\n            STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);\n            STATIC XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);\n            STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);\n            STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,\n                                             PMMPTE StartPte);\n            STATIC XTAPI ULONG GetPteSize(VOID);\n            STATIC XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);\n            STATIC XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);\n            STATIC XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);\n            STATIC XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);\n            STATIC XTAPI PMMPXE GetPxeAddress(IN PVOID Address);\n            STATIC XTAPI PVOID GetPxeVirtualAddress(IN PMMPXE PxePointer);\n            STATIC XTAPI BOOLEAN GetXpaStatus(VOID);\n            STATIC XTAPI VOID InitializePageMapSupport(VOID);\n            STATIC XTAPI XTSTATUS MapVirtualAddress(IN PVOID VirtualAddress,\n                                                    IN PFN_NUMBER PageFrameNumber,\n                                                    IN ULONGLONG Attributes);\n            STATIC XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);\n            STATIC XTAPI VOID SetNextEntry(IN PMMPTE Pte,\n                                           IN ULONG_PTR Value);\n            STATIC XTAPI VOID SetOneEntry(IN PMMPTE Pte,\n                                          IN BOOLEAN Value);\n            STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                                     IN PFN_NUMBER PageFrameNumber,\n                                     IN ULONGLONG AttributesMask);\n            STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                                     IN ULONGLONG Attributes);\n            STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,\n                                            IN BOOLEAN CacheDisable,\n                                            IN BOOLEAN WriteThrough);\n            STATIC XTAPI VOID WritePte(IN PMMPTE Pte,\n                                       IN MMPTE Value);\n            STATIC XTAPI VOID TransitionPte(IN PMMPTE PointerPte,\n                                            IN ULONG_PTR Protection);\n            STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address,\n                                             IN ULONG Size);\n\n        private:\n            STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID);\n            STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID);\n            STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_AMD64_PAGING_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/amd64/pte.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/amd64/pte.hh\n * DESCRIPTION:     Page Table Entry (PTE) for AMD64 support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_AMD64_PTE_HH\n#define __XTOSKRNL_MM_AMD64_PTE_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Pte\n    {\n        private:\n            STATIC MMPTE FirstSystemFreePte[MaximumPtePoolTypes];\n            STATIC PMMPTE SystemPteBase;\n            STATIC PMMPTE SystemPtesEnd[MaximumPtePoolTypes];\n            STATIC PMMPTE SystemPtesStart[MaximumPtePoolTypes];\n            STATIC PFN_COUNT TotalSystemFreePtes[MaximumPtePoolTypes];\n            STATIC MMPTE ValidPte;\n\n        public:\n            STATIC XTAPI BOOLEAN AddressValid(IN PVOID VirtualAddress);\n            STATIC XTAPI PFN_COUNT GetPtesPerPage(VOID);\n            STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);\n            STATIC XTAPI PMMPTE GetValidPte(VOID);\n            STATIC XTAPI VOID InitializePageTable(VOID);\n            STATIC XTAPI VOID InitializeSystemPte(VOID);\n            STATIC XTAPI VOID InitializeSystemPtePool(IN PMMPTE StartingPte,\n                                                      IN PFN_COUNT NumberOfPtes,\n                                                      IN MMSYSTEM_PTE_POOL_TYPE PoolType);\n            STATIC XTAPI VOID InitializeSystemPteSpace(VOID);\n            STATIC XTAPI VOID MapP5E(IN PVOID StartAddress,\n                                     IN PVOID EndAddress,\n                                     IN PMMP5E TemplateP5e);\n            STATIC XTAPI VOID MapPDE(IN PVOID StartAddress,\n                                     IN PVOID EndAddress,\n                                     IN PMMPDE TemplatePde);\n            STATIC XTAPI VOID MapPPE(IN PVOID StartAddress,\n                                     IN PVOID EndAddress,\n                                     IN PMMPPE TemplatePpe);\n            STATIC XTAPI VOID MapPTE(IN PVOID StartAddress,\n                                     IN PVOID EndAddress,\n                                     IN PMMPTE TemplatePte);\n            STATIC XTAPI VOID MapPXE(IN PVOID StartAddress,\n                                     IN PVOID EndAddress,\n                                     IN PMMPXE TemplatePxe);\n            STATIC XTAPI VOID ReleaseSystemPtes(IN PMMPTE StartingPte,\n                                                IN PFN_COUNT NumberOfPtes,\n                                                IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);\n            STATIC XTAPI PMMPTE ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,\n                                                  IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);\n\n        private:\n            STATIC XTAPI BOOLEAN FindFreeCluster(IN PFN_COUNT NumberOfPtes,\n                                                 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,\n                                                 OUT PMMPTE *FoundCluster,\n                                                 OUT PMMPTE *PreviousClusterNode);\n            STATIC XTAPI ULONG GetClusterSize(IN PMMPTE Pte);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_AMD64_PTE_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/colors.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/colors.hh\n * DESCRIPTION:     Memory manager page coloring subsystem\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_COLORS_HH\n#define __XTOSKRNL_MM_COLORS_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Colors\n    {\n        private:\n            STATIC PMMCOLOR_TABLES FreePages[FreePageList + 1];\n            STATIC MMPFNLIST ModifiedPages[MM_PAGING_COLORS];\n            STATIC ULONG PagingColors;\n            STATIC ULONG PagingColorsMask;\n\n        public:\n            STATIC XTAPI VOID ComputePageColoring(VOID);\n            STATIC XTAPI PMMCOLOR_TABLES GetFreePages(IN MMPAGELISTS PageList,\n                                                      IN ULONG Color);\n            STATIC XTAPI PMMPFNLIST GetModifiedPages(IN ULONG Color);\n            STATIC XTAPI ULONG GetNextColor(VOID);\n            STATIC XTAPI ULONG GetPagingColors(VOID);\n            STATIC XTAPI ULONG GetPagingColorsMask(VOID);\n            STATIC XTAPI VOID InitializeColorTables(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_COLORS_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/guard.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/guard.hh\n * DESCRIPTION:     Memory Manager synchronization guard\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_GUARD_HH\n#define __XTOSKRNL_MM_GUARD_HH\n\n#include <xtos.hh>\n#include <ke/runlevel.hh>\n#include <ke/spinlock.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class PoolLockGuard\n    {\n        private:\n            BOOLEAN Locked;\n            MMPOOL_TYPE LockPoolType;\n            KRUNLEVEL PreviousRunLevel;\n\n        public:\n            PoolLockGuard(IN MMPOOL_TYPE PoolType)\n            {\n                LockPoolType = PoolType;\n\n                /* Determine the appropriate synchronization mechanism based on the requested pool type */\n                if(LockPoolType == NonPagedPool)\n                {\n                    /* Elevate the runlevel to DISPATCH_LEVEL */\n                    PreviousRunLevel = KE::RunLevel::RaiseRunLevel(DISPATCH_LEVEL);\n\n                    /* Acquire the global queued spinlock protecting the non-paged pool */\n                    KE::SpinLock::AcquireQueuedSpinLock(NonPagedPoolLock);\n                }\n                else\n                {\n                    /* Paged pool requires a mutex, currently unimplemented */\n                    UNIMPLEMENTED;\n                }\n\n                /* Mark the guard as actively holding the lock */\n                Locked = TRUE;\n            }\n\n            ~PoolLockGuard(VOID)\n            {\n                /* Automatically release the held lock upon going out of scope */\n                Release();\n            }\n\n            PoolLockGuard(const PoolLockGuard&) = delete;\n            PoolLockGuard& operator=(const PoolLockGuard&) = delete;\n\n            VOID Release(VOID)\n            {\n                /* Check if the guard is currently holding a lock */\n                if(!Locked)\n                {\n                    /* Return, to prevent a double-free */\n                    return;\n                }\n\n                /* Determine the appropriate synchronization mechanism based on the requested pool type */\n                if(LockPoolType == NonPagedPool)\n                {\n                    /* Release the non-paged pool spinlock and subsequently restore the original runlevel */\n                    KE::SpinLock::ReleaseQueuedSpinLock(NonPagedPoolLock);\n                    KE::RunLevel::LowerRunLevel(PreviousRunLevel);\n                }\n                else\n                {\n                    /* Paged pool requires a mutex, currently unimplemented */\n                    UNIMPLEMENTED;\n                }\n\n                /* Update the internal state, indicating that the lock is no longer held */\n                Locked = FALSE;\n            }\n    };\n}\n\n#endif /* __XTOSKRNL_MM_GUARD_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/hlpool.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/hlpool.hh\n * DESCRIPTION:     Hardware layer pool memory management\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_HLPOOL_HH\n#define __XTOSKRNL_MM_HLPOOL_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class HardwarePool\n    {\n        private:\n            STATIC LOADER_MEMORY_DESCRIPTOR HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS];\n            STATIC PVOID HardwareHeapStart;\n            STATIC ULONG UsedHardwareAllocationDescriptors;\n\n        public:\n            STATIC XTAPI XTSTATUS AllocateHardwareMemory(IN PFN_NUMBER PageCount,\n                                                         IN BOOLEAN Aligned,\n                                                         IN ULONGLONG MaximumAddress,\n                                                         OUT PPHYSICAL_ADDRESS Buffer);\n            STATIC XTAPI XTSTATUS AllocateRealModeMemory(IN PFN_NUMBER PageCount,\n                                                         OUT PVOID *MemoryAddress);\n            STATIC XTAPI XTSTATUS MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress,\n                                                    IN PFN_NUMBER PageCount,\n                                                    IN BOOLEAN FlushTlb,\n                                                    OUT PVOID *VirtualAddress);\n            STATIC XTAPI VOID MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress,\n                                                             IN PFN_NUMBER PageCount);\n            STATIC XTAPI VOID RemapHardwareMemory(IN PVOID VirtualAddress,\n                                                  IN PHYSICAL_ADDRESS PhysicalAddress,\n                                                  IN BOOLEAN FlushTlb);\n            STATIC XTAPI XTSTATUS UnmapHardwareMemory(IN PVOID VirtualAddress,\n                                                      IN PFN_NUMBER PageCount,\n                                                      IN BOOLEAN FlushTlb);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_HLPOOL_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/i686/pagemap.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/i686/pagemap.hh\n * DESCRIPTION:     Low-level support for page map manipulation\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_I686_PAGEMAP_HH\n#define __XTOSKRNL_MM_I686_PAGEMAP_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    typedef class PageMap\n    {\n        protected:\n            MMPAGEMAP_INFO PageMapInfo;\n\n        public:\n            VIRTUAL XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,\n                                            IN ULONG Count) = 0;\n            XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);\n            VIRTUAL XTAPI VOID ClearPte(IN PMMPTE PtePointer) = 0;\n            VIRTUAL XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte) = 0;\n            VIRTUAL XTAPI PMMPTE GetNextPte(IN PMMPTE Pte) = 0;\n            VIRTUAL XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte) = 0;\n            VIRTUAL XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte) = 0;\n            XTAPI USHORT GetPageMapLevel();\n            XTAPI PMMPDE GetPdeAddress(IN PVOID Address);\n            XTAPI ULONG GetPdeOffset(IN PVOID Address);\n            VIRTUAL XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer) = 0;\n            XTAPI PMMPPE GetPpeAddress(IN PVOID Address);\n            XTAPI ULONG GetPpeOffset(IN PVOID Address);\n            XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);\n            VIRTUAL XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer) = 0;\n            XTAPI PMMPTE GetPteAddress(IN PVOID Address);\n            XTAPI ULONG GetPteOffset(IN PVOID Address);\n            VIRTUAL XTAPI LONG GetPteDistance(PMMPTE EndPte,\n                                              PMMPTE StartPte) = 0;\n            VIRTUAL XTAPI ULONG GetPteSize(VOID) = 0;\n            VIRTUAL XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer) = 0;\n            VIRTUAL XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer) = 0;\n            VIRTUAL XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer) = 0;\n            VIRTUAL XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer) = 0;\n            XTAPI BOOLEAN GetXpaStatus();\n            VIRTUAL XTAPI VOID InitializePageMapInfo(VOID) = 0;\n            VIRTUAL XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer) = 0;\n            VIRTUAL XTAPI VOID SetNextEntry(IN PMMPTE Pte,\n                                            IN ULONG_PTR Value) = 0;\n            VIRTUAL XTAPI VOID SetOneEntry(IN PMMPTE Pte,\n                                           IN BOOLEAN Value) = 0;\n            VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                                      IN PFN_NUMBER PageFrameNumber,\n                                      IN ULONGLONG AttributesMask) = 0;\n            VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                                      IN ULONGLONG Attributes) = 0;\n            VIRTUAL XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,\n                                             IN BOOLEAN CacheDisable,\n                                             IN BOOLEAN WriteThrough) = 0;\n            VIRTUAL XTAPI VOID TransitionPte(IN PMMPTE PointerPte,\n                                             IN ULONG_PTR Protection) = 0;\n            VIRTUAL XTAPI VOID WritePte(IN PMMPTE Pte,\n                                        IN MMPTE Value) = 0;\n\n    } PAGEMAP, *PPAGEMAP;\n\n    class PageMapBasic final : public PageMap\n    {\n        public:\n            XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,\n                                    IN ULONG Count);\n            XTAPI VOID ClearPte(IN PMMPTE PtePointer);\n            XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);\n            XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);\n            XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);\n            XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);\n            XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);\n            XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);\n            XTAPI LONG GetPteDistance(PMMPTE EndPte,\n                                      PMMPTE StartPte);\n            XTAPI ULONG GetPteSize(VOID);\n            XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);\n            XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);\n            XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);\n            XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);\n            XTAPI VOID InitializePageMapInfo(VOID);\n            XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);\n            XTAPI VOID SetNextEntry(IN PMMPTE Pte,\n                                    IN ULONG_PTR Value);\n            XTAPI VOID SetOneEntry(IN PMMPTE Pte,\n                                   IN BOOLEAN Value);\n            XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                              IN PFN_NUMBER PageFrameNumber,\n                              IN ULONGLONG AttributesMask);\n            XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                              IN ULONGLONG Attributes);\n            XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,\n                                     IN BOOLEAN CacheDisable,\n                                     IN BOOLEAN WriteThrough);\n            XTAPI VOID TransitionPte(IN PMMPTE PointerPte,\n                                     IN ULONG_PTR Protection);\n            XTAPI VOID WritePte(IN PMMPTE Pte,\n                                IN MMPTE Value);\n    };\n\n    class PageMapXpa final : public PageMap\n    {\n        public:\n            XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,\n                                    IN ULONG Count);\n            XTAPI VOID ClearPte(IN PMMPTE PtePointer);\n            XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);\n            XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);\n            XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);\n            XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);\n            XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);\n            XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);\n            XTAPI LONG GetPteDistance(PMMPTE EndPte,\n                                      PMMPTE StartPte);\n            XTAPI ULONG GetPteSize(VOID);\n            XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);\n            XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);\n            XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);\n            XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);\n            XTAPI VOID InitializePageMapInfo(VOID);\n            XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);\n            XTAPI VOID SetNextEntry(IN PMMPTE Pte,\n                                    IN ULONG_PTR Value);\n            XTAPI VOID SetOneEntry(IN PMMPTE Pte,\n                                   IN BOOLEAN Value);\n            XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                              IN PFN_NUMBER PageFrameNumber,\n                              IN ULONGLONG AttributesMask);\n            XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                              IN ULONGLONG Attributes);\n            XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,\n                                     IN BOOLEAN CacheDisable,\n                                     IN BOOLEAN WriteThrough);\n            XTAPI VOID TransitionPte(IN PMMPTE PointerPte,\n                                     IN ULONG_PTR Protection);\n            XTAPI VOID WritePte(IN PMMPTE Pte,\n                                IN MMPTE Value);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_I686_PAGEMAP_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/i686/paging.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/i686/paging.hh\n * DESCRIPTION:     Low level page management support for i686\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_I686_PAGING_HH\n#define __XTOSKRNL_MM_I686_PAGING_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Paging\n    {\n        private:\n            STATIC PPAGEMAP PmlRoutines;\n\n        public:\n            STATIC XTAPI PMMPTE AdvancePte(IN PMMPTE Pte,\n                                           IN LONG Count);\n            STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress);\n            STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer);\n            STATIC XTAPI VOID FlushEntireTlb(VOID);\n            STATIC XTAPI VOID FlushTlb(VOID);\n            STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte);\n            STATIC XTAPI PMMPTE GetNextPte(IN PMMPTE Pte);\n            STATIC XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);\n            STATIC XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);\n            STATIC XTAPI USHORT GetPageMapLevel();\n            STATIC XTAPI PMMPDE GetPdeAddress(IN PVOID Address);\n            STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);\n            STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);\n            STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);\n            STATIC XTAPI ULONGLONG GetPte(IN PMMPTE PtePointer);\n            STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);\n            STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,\n                                             PMMPTE StartPte);\n            STATIC XTAPI ULONG GetPteSize(VOID);\n            STATIC XTAPI ULONG GetPteSoftwareProtection(IN PMMPTE PtePointer);\n            STATIC XTAPI ULONG GetPteSoftwarePrototype(IN PMMPTE PtePointer);\n            STATIC XTAPI ULONG GetPteSoftwareTransition(IN PMMPTE PtePointer);\n            STATIC XTAPI PVOID GetPteVirtualAddress(IN PMMPTE PtePointer);\n            STATIC XTAPI BOOLEAN GetXpaStatus(VOID);\n            STATIC XTAPI VOID InitializePageMapSupport(VOID);\n            STATIC XTAPI XTSTATUS MapVirtualAddress(IN PVOID VirtualAddress,\n                                                    IN PFN_NUMBER PageFrameNumber,\n                                                    IN ULONGLONG Attributes);\n            STATIC XTAPI BOOLEAN PteValid(IN PMMPTE PtePointer);\n            STATIC XTAPI VOID SetNextEntry(IN PMMPTE Pte,\n                                           IN ULONG_PTR Value);\n            STATIC XTAPI VOID SetOneEntry(IN PMMPTE Pte,\n                                          IN BOOLEAN Value);\n            STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                                     IN PFN_NUMBER PageFrameNumber,\n                                     IN ULONGLONG AttributesMask);\n            STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,\n                                     IN ULONGLONG Attributes);\n            STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,\n                                            IN BOOLEAN CacheDisable,\n                                            IN BOOLEAN WriteThrough);\n            STATIC XTAPI VOID WritePte(IN PMMPTE Pte,\n                                       IN MMPTE Value);\n            STATIC XTAPI VOID TransitionPte(IN PMMPTE PointerPte,\n                                            IN ULONG_PTR Protection);\n            STATIC XTFASTCALL VOID ZeroPages(IN PVOID Address,\n                                             IN ULONG Size);\n\n        private:\n            STATIC XTAPI BOOLEAN GetExtendedPhysicalAddressingStatus(VOID);\n            STATIC XTAPI PPAGEMAP GetPageMapBasicRoutines(VOID);\n            STATIC XTAPI PPAGEMAP GetPageMapXpaRoutines(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_I686_PAGING_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/i686/pte.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/i686/pte.hh\n * DESCRIPTION:     Page Table Entry (PTE) for i686 support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_I686_PTE_HH\n#define __XTOSKRNL_MM_I686_PTE_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Pte\n    {\n        private:\n            STATIC MMPTE FirstSystemFreePte[MaximumPtePoolTypes];\n            STATIC PMMPTE SystemPteBase;\n            STATIC PMMPTE SystemPtesEnd[MaximumPtePoolTypes];\n            STATIC PMMPTE SystemPtesStart[MaximumPtePoolTypes];\n            STATIC PFN_COUNT TotalSystemFreePtes[MaximumPtePoolTypes];\n            STATIC MMPTE ValidPte;\n\n        public:\n            STATIC XTAPI BOOLEAN AddressValid(IN PVOID VirtualAddress);\n            STATIC XTAPI PFN_COUNT GetPtesPerPage(VOID);\n            STATIC XTAPI PMMPTE GetSystemPteBaseAddress(VOID);\n            STATIC XTAPI PMMPTE GetValidPte(VOID);\n            STATIC XTAPI VOID InitializePageTable(VOID);\n            STATIC XTAPI VOID InitializeSystemPte(VOID);\n            STATIC XTAPI VOID InitializeSystemPtePool(IN PMMPTE StartingPte,\n                                                      IN PFN_COUNT NumberOfPtes,\n                                                      IN MMSYSTEM_PTE_POOL_TYPE PoolType);\n            STATIC XTAPI VOID InitializeSystemPteSpace(VOID);\n            STATIC XTAPI VOID MapPDE(IN PVOID StartAddress,\n                                     IN PVOID EndAddress,\n                                     IN PMMPDE TemplatePde);\n            STATIC XTAPI VOID MapPPE(IN PVOID StartAddress,\n                                     IN PVOID EndAddress,\n                                     IN PMMPPE TemplatePpe);\n            STATIC XTAPI VOID MapPTE(IN PVOID StartAddress,\n                                     IN PVOID EndAddress,\n                                     IN PMMPTE TemplatePte);\n            STATIC XTAPI VOID ReleaseSystemPtes(IN PMMPTE StartingPte,\n                                                IN PFN_COUNT NumberOfPtes,\n                                                IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);\n            STATIC XTAPI PMMPTE ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,\n                                                  IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType);\n\n        private:\n            STATIC XTAPI BOOLEAN FindFreeCluster(IN PFN_COUNT NumberOfPtes,\n                                                 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,\n                                                 OUT PMMPTE *FoundCluster,\n                                                 OUT PMMPTE *PreviousClusterNode);\n            STATIC XTAPI ULONG GetClusterSize(IN PMMPTE Pte);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_I686_PTE_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/kpool.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/hlpool.hh\n * DESCRIPTION:     Kernel pool memory management\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_KPOOL_HH\n#define __XTOSKRNL_MM_KPOOL_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class KernelPool\n    {\n        public:\n            STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack,\n                                                      IN ULONG StackSize);\n            STATIC XTAPI XTSTATUS AllocateProcessorStructures(OUT PVOID *StructuresData);\n            STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack,\n                                              IN ULONG StackSize);\n            STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_KPOOL_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/mmgr.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/mmgr.hh\n * DESCRIPTION:     Memory Manager\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_MMGR_HH\n#define __XTOSKRNL_MM_MMGR_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Manager\n    {\n        private:\n            STATIC MMMEMORY_LAYOUT MemoryLayout;\n            STATIC PFN_NUMBER NumberOfSystemPtes;\n            STATIC PPHYSICAL_MEMORY_DESCRIPTOR PhysicalMemoryBlock;\n\n        public:\n            STATIC XTAPI ULONG_PTR GetInstalledMemorySize(VOID);\n            STATIC XTAPI PMMMEMORY_LAYOUT GetMemoryLayout(VOID);\n            STATIC XTAPI PFN_NUMBER GetNumberOfSystemPtes(VOID);\n            STATIC XTAPI PPHYSICAL_MEMORY_DESCRIPTOR GetPhysicalMemoryBlock(VOID);\n            STATIC XTAPI VOID InitializeMemoryLayout(VOID);\n            STATIC XTAPI VOID InitializeMemoryManager(VOID);\n            STATIC XTAPI XTSTATUS MapKernelSharedData(VOID);\n            STATIC XTAPI BOOLEAN VerifyMemoryTypeFree(IN LOADER_MEMORY_TYPE MemoryType);\n            STATIC XTAPI BOOLEAN VerifyMemoryTypeInvisible(IN LOADER_MEMORY_TYPE MemoryType);\n\n        private:\n            STATIC XTAPI VOID ComputeBootImageSize(OUT PPFN_NUMBER BootImageSize);\n            STATIC XTAPI VOID ComputeMaximumNonPagedPoolSize(OUT PPFN_NUMBER PoolSize);\n            STATIC XTAPI VOID ComputeNonPagedPoolSize(OUT PPFN_NUMBER PoolSize);\n            STATIC XTAPI VOID ComputePagedPoolSize(OUT PPFN_NUMBER PoolSize);\n            STATIC XTAPI VOID ComputeSessionSpaceSize(OUT PPFN_NUMBER SpaceSize);\n            STATIC XTAPI VOID ComputeSystemPteSize(OUT PPFN_NUMBER PteSize);\n            STATIC XTAPI VOID DumpMemoryLayout(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_MMGR_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/pfault.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/pfault.hh\n * DESCRIPTION:     Page fault support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_PFAULT_HH\n#define __XTOSKRNL_MM_PFAULT_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class PageFault\n    {\n        public:\n            STATIC XTFASTCALL XTSTATUS CheckPdeForPagedPool(IN PVOID VirtualAddress);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_PFAULT_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/pfn.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/pfn.hh\n * DESCRIPTION:     Physical Frame Number (PFN) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_PFN_HH\n#define __XTOSKRNL_MM_PFN_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Pfn\n    {\n        private:\n            STATIC PFN_NUMBER AvailablePages;\n            STATIC MMPFNLIST BadPagesList;\n            STATIC PLOADER_MEMORY_DESCRIPTOR FreeDescriptor;\n            STATIC MMPFNLIST FreePagesList;\n            STATIC ULONG_PTR HighestPhysicalPage;\n            STATIC PVOID HighestUserAddress;\n            STATIC ULONG_PTR LowestPhysicalPage;\n            STATIC MMPFNLIST ModifiedPagesList;\n            STATIC MMPFNLIST ModifiedReadOnlyPagesList;\n            STATIC ULONGLONG NumberOfPhysicalPages;\n            STATIC LOADER_MEMORY_DESCRIPTOR OriginalFreeDescriptor;\n            STATIC PMMPFNLIST PageLocationList[];\n            STATIC RTL_BITMAP PfnBitMap;\n            STATIC MMPFNLIST RomPagesList;\n            STATIC MMPFNLIST StandbyPagesList;\n            STATIC MMPFNLIST ZeroedPagesList;\n\n        public:\n            STATIC XTAPI PFN_NUMBER AllocateBootstrapPages(IN PFN_NUMBER NumberOfPages);\n            STATIC XTAPI PFN_NUMBER AllocatePhysicalPage(IN ULONG Color);\n            STATIC XTAPI VOID ComputePfnDatabaseSize(OUT PPFN_NUMBER DatabaseSize);\n            STATIC XTAPI VOID DecrementReferenceCount(IN PMMPFN Pfn1,\n                                                      IN PFN_NUMBER PageFrameIndex,\n                                                      IN BOOLEAN BeginStandbyList = FALSE);\n            STATIC XTAPI VOID DecrementShareCount(IN PMMPFN Pfn1,\n                                                  IN PFN_NUMBER PageFrameIndex,\n                                                  IN BOOLEAN BeginStandbyList = FALSE);\n            STATIC XTAPI VOID FreePhysicalPage(IN PMMPTE PointerPte);\n            STATIC XTAPI PFN_NUMBER GetAvailablePages(VOID);\n            STATIC XTAPI ULONG_PTR GetHighestPhysicalPage(VOID);\n            STATIC XTAPI ULONGLONG GetNumberOfPhysicalPages(VOID);\n            STATIC XTAPI PMMPFN GetPfnEntry(IN PFN_NUMBER Pfn);\n            STATIC XTAPI VOID InitializePfnBitmap(VOID);\n            STATIC XTAPI VOID InitializePfnDatabase(VOID);\n            STATIC XTAPI VOID LinkPfn(IN PFN_NUMBER PageFrameIndex,\n                                      IN PMMPTE PointerPte,\n                                      IN BOOLEAN Modified);\n            STATIC XTAPI VOID LinkPfnWithParent(IN PFN_NUMBER PageFrameIndex,\n                                                IN PMMPTE PointerPte,\n                                                IN PFN_NUMBER ParentFrame);\n            STATIC XTAPI VOID ScanMemoryDescriptors(VOID);\n\n        private:\n            STATIC XTAPI VOID DecrementAvailablePages(VOID);\n            STATIC XTAPI VOID IncrementAvailablePages(VOID);\n            STATIC XTAPI VOID InitializePageDirectory(IN PMMPDE StartingPde,\n                                                      IN PMMPDE EndingPde);\n            STATIC XTAPI VOID InitializePageTablePfns(VOID);\n            STATIC XTAPI VOID LinkFreePage(IN PFN_NUMBER PageFrameIndex);\n            STATIC XTAPI VOID LinkPage(IN PMMPFNLIST ListHead,\n                                       IN PFN_NUMBER PageFrameIndex);\n            STATIC XTAPI VOID LinkPfnForPageTable(IN PFN_NUMBER PageFrameIndex,\n                                                  IN PMMPTE PointerPte);\n            STATIC XTFASTCALL VOID LinkStandbyPage(IN PFN_NUMBER PageFrameIndex);\n            STATIC XTAPI VOID ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,\n                                                      IN PFN_NUMBER PageCount,\n                                                      IN LOADER_MEMORY_TYPE MemoryType);\n            STATIC XTAPI VOID ScanPageTable(IN PMMPTE PointerPte,\n                                            IN ULONG Level);\n            STATIC XTAPI PFN_NUMBER UnlinkFreePage(IN PFN_NUMBER PageFrameIndex,\n                                                   IN ULONG Color);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_PFN_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm/pool.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm/pool.hh\n * DESCRIPTION:     Memory Manager pool manager\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_POOL_HH\n#define __XTOSKRNL_MM_POOL_HH\n\n#include <xtos.hh>\n\n\n/* Memory Manager */\nnamespace MM\n{\n    class Pool\n    {\n        protected:\n            STATIC POOL_DESCRIPTOR NonPagedPoolDescriptor;\n            STATIC PFN_NUMBER NonPagedPoolFrameEnd;\n            STATIC PFN_NUMBER NonPagedPoolFrameStart;\n            STATIC LIST_ENTRY NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];\n            STATIC ULONG PoolSecureCookie;\n            STATIC PPOOL_DESCRIPTOR PoolVector[2];\n\n        public:\n            STATIC XTAPI MMPOOL_TYPE DeterminePoolType(IN PVOID VirtualAddress);\n            STATIC XTAPI VOID InitializeNonPagedPool(VOID);\n            STATIC XTAPI VOID InitializePagedPool(VOID);\n            STATIC XTAPI VOID InitializePoolSecurity(VOID);\n\n        protected:\n            STATIC XTAPI PLIST_ENTRY DecodePoolLink(IN PLIST_ENTRY PoolLink);\n            STATIC XTAPI PLIST_ENTRY EncodePoolLink(IN PLIST_ENTRY PoolLink);\n            STATIC XTAPI PPOOL_HEADER GetPoolBlock(IN PPOOL_HEADER Header, IN SSIZE_T Index);\n            STATIC XTAPI PPOOL_HEADER GetPoolEntry(IN PVOID Payload);\n            STATIC XTAPI PLIST_ENTRY GetPoolFreeBlock(IN PPOOL_HEADER Header);\n            STATIC XTAPI PPOOL_HEADER GetPoolNextBlock(IN PPOOL_HEADER Header);\n            STATIC XTAPI PPOOL_HEADER GetPoolPreviousBlock(IN PPOOL_HEADER Header);\n            STATIC XTAPI VOID InsertPoolHeadList(IN PLIST_ENTRY ListHead,\n                                                 IN PLIST_ENTRY Entry);\n            STATIC XTAPI VOID InsertPoolTailList(IN PLIST_ENTRY ListHead,\n                                                 IN PLIST_ENTRY Entry);\n            STATIC XTAPI BOOLEAN PoolListEmpty(IN PLIST_ENTRY ListHead);\n            STATIC XTAPI VOID RemovePoolEntryList(IN PLIST_ENTRY Entry);\n            STATIC XTAPI PLIST_ENTRY RemovePoolHeadList(IN PLIST_ENTRY ListHead);\n            STATIC XTAPI PLIST_ENTRY RemovePoolTailList(IN PLIST_ENTRY ListHead);\n            STATIC XTAPI VOID VerifyPoolBlocks(IN PVOID Block);\n            STATIC XTAPI VOID VerifyPoolHeader(IN PPOOL_HEADER Entry);\n            STATIC XTAPI VOID VerifyPoolLinks(IN PLIST_ENTRY ListHead);\n            STATIC XTAPI VOID VerifyRunLevel(IN MMPOOL_TYPE PoolType,\n                                             IN SIZE_T Bytes,\n                                             IN PVOID Entry);\n\n        private:\n            STATIC XTAPI VOID InitializePoolDescriptor(IN PPOOL_DESCRIPTOR Descriptor,\n                                                       IN MMPOOL_TYPE PoolType,\n                                                       IN ULONG Index,\n                                                       IN ULONG Threshold,\n                                                       IN PVOID LockAddress);\n            STATIC XTAPI VOID InitializePoolListHead(IN PLIST_ENTRY ListHead);\n            STATIC XTAPI VOID MapNonPagedPool(VOID);\n    };\n}\n\n#endif /* __XTOSKRNL_MM_POOL_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/mm.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/mm.hh\n * DESCRIPTION:     Memory Manager\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_MM_HH\n#define __XTOSKRNL_MM_HH\n\n#include <xtos.hh>\n\n#include XTOS_ARCH_HEADER(mm, pagemap.hh)\n#include XTOS_ARCH_HEADER(mm, paging.hh)\n#include XTOS_ARCH_HEADER(mm, pte.hh)\n\n#include <mm/alloc.hh>\n#include <mm/colors.hh>\n#include <mm/guard.hh>\n#include <mm/hlpool.hh>\n#include <mm/kpool.hh>\n#include <mm/mmgr.hh>\n#include <mm/pfault.hh>\n#include <mm/pfn.hh>\n#include <mm/pool.hh>\n\n#endif /* __XTOSKRNL_MM_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/po/idle.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/po/idle.hh\n * DESCRIPTION:     Processor idle functionality support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_PO_IDLE_HH\n#define __XTOSKRNL_PO_IDLE_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace PO\n{\n    class Idle\n    {\n        public:\n            STATIC XTAPI VOID InitializeProcessorIdleState(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb);\n\n        private:\n            STATIC XTFASTCALL VOID Idle0Function(IN PPROCESSOR_POWER_STATE PowerState);\n            STATIC XTAPI VOID PerfIdle(IN PPROCESSOR_POWER_STATE PowerState);\n            STATIC XTAPI VOID PerfIdleDpc(IN PKDPC Dpc,\n                                          IN PVOID DeferredContext,\n                                          IN PVOID SystemArgument1,\n                                          IN PVOID SystemArgument2);\n    };\n}\n\n#endif /* __XTOSKRNL_PO_IDLE_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/po.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/po.hh\n * DESCRIPTION:     Power Management\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_PO_HH\n#define __XTOSKRNL_PO_HH\n\n#include <xtos.hh>\n\n#include <po/idle.hh>\n\n\n#endif /* __XTOSKRNL_PO_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/amd64/intrin.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/amd64/intrin.hh\n * DESCRIPTION:     Compiler intrinsic support routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_AMD64_INTRIN_HH\n#define __XTOSKRNL_RTL_AMD64_INTRIN_HH\n\n#include <xtos.hh>\n\n\n/* Forward declarations enforcing the XTAPI calling convention and preserving the raw unmangled symbol names */\n\n#endif /* __XTOSKRNL_RTL_AMD64_INTRIN_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/atomic.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/atomic.hh\n * DESCRIPTION:     Atomic operations support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_ATOMIC_HH\n#define __XTOSKRNL_RTL_ATOMIC_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class Atomic\n    {\n        public:\n            STATIC XTFASTCALL CHAR And8(IN PCHAR Address,\n                                        IN CHAR Mask);\n            STATIC XTFASTCALL SHORT And16(IN PSHORT Address,\n                                          IN SHORT Mask);\n            STATIC XTFASTCALL LONG And32(IN PLONG Address,\n                                         IN LONG Mask);\n            STATIC XTFASTCALL LONG_PTR And64(IN PLONG_PTR Address,\n                                             IN LONG_PTR Mask);\n            STATIC XTFASTCALL UCHAR BitTestAndSet(IN PLONG Base,\n                                                  IN LONG Offset);\n            STATIC XTFASTCALL UCHAR BitTestAndSet64(IN PLONGLONG Base,\n                                                    IN LONGLONG Offset);\n            STATIC XTFASTCALL CHAR CompareExchange8(IN PCHAR Address,\n                                                 IN CHAR Comperand,\n                                                 IN CHAR Exchange);\n            STATIC XTFASTCALL SHORT CompareExchange16(IN PSHORT Address,\n                                                   IN SHORT Comperand,\n                                                   IN SHORT Exchange);\n            STATIC XTFASTCALL LONG CompareExchange32(IN PLONG Address,\n                                                  IN LONG Comperand,\n                                                  IN LONG Exchange);\n            STATIC XTFASTCALL LONG_PTR CompareExchange64(IN PLONG_PTR Address,\n                                                      IN LONG_PTR Comperand,\n                                                      IN LONG_PTR Exchange);\n            STATIC XTFASTCALL PVOID CompareExchangePointer(IN PVOID *Address,\n                                                        IN PVOID Comperand,\n                                                        IN PVOID Exchange);\n            STATIC XTFASTCALL CHAR Decrement8(IN PCHAR Address);\n            STATIC XTFASTCALL SHORT Decrement16(IN PSHORT Address);\n            STATIC XTFASTCALL LONG Decrement32(IN PLONG Address);\n            STATIC XTFASTCALL LONG_PTR Decrement64(IN PLONG_PTR Address);\n            STATIC XTFASTCALL CHAR Exchange8(IN PCHAR Address,\n                                             IN CHAR Exchange);\n            STATIC XTFASTCALL SHORT Exchange16(IN PSHORT Address,\n                                               IN SHORT Exchange);\n            STATIC XTFASTCALL LONG Exchange32(IN PLONG Address,\n                                              IN LONG Exchange);\n            STATIC XTFASTCALL LONG_PTR Exchange64(IN PLONG_PTR Address,\n                                                  IN LONG_PTR Exchange);\n            STATIC XTFASTCALL CHAR ExchangeAdd8(IN PCHAR Address,\n                                                IN CHAR Value);\n            STATIC XTFASTCALL SHORT ExchangeAdd16(IN PSHORT Address,\n                                                  IN SHORT Value);\n            STATIC XTFASTCALL LONG ExchangeAdd32(IN PLONG Address,\n                                                 IN LONG Value);\n            STATIC XTFASTCALL LONG_PTR ExchangeAdd64(IN PLONG_PTR Address,\n                                                     IN LONG_PTR Value);\n            STATIC XTFASTCALL PVOID ExchangePointer(IN PVOID *Address,\n                                                    IN PVOID Exchange);\n            STATIC XTFASTCALL PSINGLE_LIST_ENTRY FlushSingleList(IN PSINGLE_LIST_HEADER Header);\n            STATIC XTFASTCALL CHAR Increment8(IN PCHAR Address);\n            STATIC XTFASTCALL SHORT Increment16(IN PSHORT Address);\n            STATIC XTFASTCALL LONG Increment32(IN PLONG Address);\n            STATIC XTFASTCALL LONG_PTR Increment64(IN PLONG_PTR Address);\n            STATIC XTFASTCALL CHAR Or8(IN PCHAR Address,\n                                       IN CHAR Mask);\n            STATIC XTFASTCALL SHORT Or16(IN PSHORT Address,\n                                         IN SHORT Mask);\n            STATIC XTFASTCALL LONG Or32(IN PLONG Address,\n                                        IN LONG Mask);\n            STATIC XTFASTCALL LONG_PTR Or64(IN PLONG_PTR Address,\n                                            IN LONG_PTR Mask);\n            STATIC XTFASTCALL XTFASTCALL PSINGLE_LIST_ENTRY PopEntrySingleList(IN PSINGLE_LIST_HEADER Header);\n            STATIC XTFASTCALL PSINGLE_LIST_ENTRY PushEntrySingleList(IN PSINGLE_LIST_HEADER Header,\n                                                                     IN PSINGLE_LIST_ENTRY Entry);\n            STATIC XTFASTCALL CHAR Xor8(IN PCHAR Address,\n                                        IN CHAR Mask);\n            STATIC XTFASTCALL SHORT Xor16(IN PSHORT Address,\n                                          IN SHORT Mask);\n            STATIC XTFASTCALL LONG Xor32(IN PLONG Address,\n                                         IN LONG Mask);\n            STATIC XTFASTCALL LONG_PTR Xor64(IN PLONG_PTR Address,\n                                             IN LONG_PTR Mask);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_ATOMIC_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/bitmap.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/bitmap.hh\n * DESCRIPTION:     Bit maps support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_BITMAP_HH\n#define __XTOSKRNL_RTL_BITMAP_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class BitMap\n    {\n        public:\n            STATIC XTAPI VOID ClearAllBits(IN PRTL_BITMAP BitMap);\n            STATIC XTAPI VOID ClearBit(IN PRTL_BITMAP BitMap,\n                                       IN ULONG_PTR Bit);\n            STATIC XTAPI VOID ClearBits(IN PRTL_BITMAP BitMap,\n                                        IN ULONG_PTR StartingIndex,\n                                        IN ULONG_PTR Length);\n            STATIC XTAPI ULONG ClearSetBits(IN PRTL_BITMAP BitMap,\n                                            IN ULONG_PTR Length,\n                                            IN ULONG_PTR Index);\n            STATIC XTAPI VOID DumpBitMap(IN PRTL_BITMAP BitMap);\n            STATIC XTAPI ULONG_PTR FindClearBits(IN PRTL_BITMAP BitMap,\n                                                 IN ULONG_PTR Length,\n                                                 IN ULONG_PTR Index);\n            STATIC XTAPI ULONG_PTR FindSetBits(IN PRTL_BITMAP BitMap,\n                                               IN ULONG_PTR Length,\n                                               IN ULONG_PTR Index);\n            STATIC XTAPI VOID InitializeBitMap(IN PRTL_BITMAP BitMap,\n                                               IN PULONG_PTR Buffer,\n                                               IN ULONG Size);\n            STATIC XTAPI VOID SetAllBits(IN PRTL_BITMAP BitMap);\n            STATIC XTAPI VOID SetBit(IN PRTL_BITMAP BitMap,\n                                     IN ULONG_PTR Bit);\n            STATIC XTAPI VOID SetBits(IN PRTL_BITMAP BitMap,\n                                      IN ULONG_PTR StartingIndex,\n                                      IN ULONG_PTR Length);\n            STATIC XTAPI ULONG SetClearBits(IN PRTL_BITMAP BitMap,\n                                            IN ULONG_PTR Length,\n                                            IN ULONG_PTR Index);\n            STATIC XTAPI BOOLEAN TestBit(IN PRTL_BITMAP BitMap,\n                                         IN ULONG_PTR Bit);\n\n        private:\n            STATIC XTAPI ULONG_PTR CountBits(IN PRTL_BITMAP BitMap,\n                                             IN ULONG_PTR Length,\n                                             IN ULONG_PTR StartingIndex,\n                                             IN BOOLEAN SetBits);\n            STATIC XTAPI ULONG_PTR FindBits(IN PRTL_BITMAP BitMap,\n                                            IN ULONG_PTR Length,\n                                            IN ULONG_PTR StartingIndex,\n                                            IN BOOLEAN SetBits);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_BITMAP_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/dispatch.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/dispatch.hh\n * DESCRIPTION:     Dispatching support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_DISPATCH_HH\n#define __XTOSKRNL_RTL_DISPATCH_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class Dispatcher\n    {\n        public:\n            STATIC XTAPI VOID GetStackLimits(OUT PULONG_PTR StackBase,\n                                             OUT PULONG_PTR StackLimit);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_DISPATCH_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/endian.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/endian.hh\n * DESCRIPTION:     Endian conversion routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_ENDIAN_HH\n#define __XTOSKRNL_RTL_ENDIAN_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class Endianness\n    {\n        public:\n            STATIC XTFASTCALL USHORT SwapByte16(IN USHORT Source);\n            STATIC XTFASTCALL ULONG SwapByte32(IN ULONG Source);\n            STATIC XTFASTCALL ULONGLONG SwapByte64(IN ULONGLONG Source);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_ENDIAN_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/guid.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/guid.hh\n * DESCRIPTION:     Endian conversion routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_GUID_HH\n#define __XTOSKRNL_RTL_GUID_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class Guid\n    {\n        public:\n            STATIC XTAPI BOOLEAN CompareGuids(IN PGUID Guid1,\n                                              IN PGUID Guid2);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_GUID_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/i686/intrin.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/i686/intrin.hh\n * DESCRIPTION:     Compiler intrinsic support routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_I686_INTRIN_HH\n#define __XTOSKRNL_RTL_I686_INTRIN_HH\n\n#include <xtos.hh>\n\n\n/* Forward declarations enforcing the XTAPI calling convention and preserving the raw unmangled symbol names */\nXTCLINK XTAPI LONGLONG _alldiv(IN LONGLONG Dividend, IN LONGLONG Divisor) XTSYMBOL(\"__alldiv\");\nXTCLINK XTAPI LONGLONG _alldvrm(IN LONGLONG Dividend, IN LONGLONG Divisor, OUT PLONGLONG Remainder) XTSYMBOL(\"__alldvrm\");\nXTCLINK XTAPI LONGLONG _allrem(IN LONGLONG Dividend, IN LONGLONG Divisor) XTSYMBOL(\"__allrem\");\nXTCLINK XTAPI ULONGLONG _aulldiv(IN ULONGLONG Dividend, IN ULONGLONG Divisor) XTSYMBOL(\"__aulldiv\");\nXTCLINK XTAPI ULONGLONG _aulldvrm(IN ULONGLONG Dividend, IN ULONGLONG Divisor, OUT PULONGLONG Remainder) XTSYMBOL(\"__aulldvrm\");\nXTCLINK XTAPI ULONGLONG _aullrem(IN ULONGLONG Dividend, IN ULONGLONG Divisor) XTSYMBOL(\"__aullrem\");\n\n#endif /* __XTOSKRNL_RTL_I686_INTRIN_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/llist.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/llist.hh\n * DESCRIPTION:     Linked list manipulation routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n *                  Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTOSKRNL_RTL_LLIST_HH\n#define __XTOSKRNL_RTL_LLIST_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class LinkedList\n    {\n        public:\n            STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead);\n            STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);\n            STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);\n            STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,\n                                               IN PLIST_ENTRY Entry);\n            STATIC XTCDECL VOID InsertTailList(IN OUT PLIST_ENTRY ListHead,\n                                               IN PLIST_ENTRY Entry);\n            STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);\n            STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);\n            STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);\n            STATIC XTCDECL VOID SpliceHeadList(IN OUT PLIST_ENTRY ListHead,\n                                               IN OUT PLIST_ENTRY SpliceList);\n            STATIC XTCDECL VOID SpliceTailList(IN OUT PLIST_ENTRY ListHead,\n                                               IN OUT PLIST_ENTRY SpliceList);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_LLIST_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/math.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/math.hh\n * DESCRIPTION:     Kernel math support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_MATH_HH\n#define __XTOSKRNL_RTL_MATH_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class Math\n    {\n        public:\n            STATIC XTAPI LARGE_INTEGER ConvertToLargeInteger32(IN LONG Value);\n            STATIC XTAPI LARGE_INTEGER ConvertToLargeIntegerUnsigned32(IN ULONG Value);\n            STATIC XTAPI INT CountLeadingZeroes32(IN ULONG Value);\n            STATIC XTAPI INT CountLeadingZeroes64(IN ULONGLONG Value);\n            STATIC XTAPI INT CountTrailingZeroes32(IN ULONG Value);\n            STATIC XTAPI INT CountTrailingZeroes64(IN ULONGLONG Value);\n            STATIC XTAPI LONGLONG Divide32(IN LONG Dividend,\n                                           IN LONG Divisor,\n                                           OUT PLONG Remainder);\n            STATIC XTAPI LONGLONG Divide64(IN LONGLONG Dividend,\n                                           IN LONGLONG Divisor,\n                                           OUT PLONGLONG Remainder);\n            STATIC XTAPI ULONGLONG DivideUnsigned32(IN ULONG Dividend,\n                                                    IN ULONG Divisor,\n                                                    OUT PULONG Remainder);\n            STATIC XTAPI ULONGLONG DivideUnsigned64(IN ULONGLONG Dividend,\n                                                    IN ULONGLONG Divisor,\n                                                    OUT PULONGLONG Remainder);\n            STATIC XTAPI LARGE_INTEGER DivideLargeInteger(IN LARGE_INTEGER Dividend,\n                                                          IN ULONG Divisor,\n                                                          OUT PULONG Remainder);\n            STATIC XTAPI LONG GetBaseExponent(IN DOUBLE Value,\n                                               OUT PDOUBLE PowerOfTen);\n            STATIC XTAPI BOOLEAN InfiniteDouble(IN DOUBLE Value);\n            STATIC XTAPI LARGE_INTEGER MultiplyLargeInteger(IN LARGE_INTEGER Multiplicand,\n                                                            IN LONG Multiplier);\n            STATIC XTAPI BOOLEAN NanDouble(IN DOUBLE Value);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_MATH_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/memory.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/memory.hh\n * DESCRIPTION:     Memory related routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_MEMORY_HH\n#define __XTOSKRNL_RTL_MEMORY_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class Memory\n    {\n        public:\n            STATIC XTAPI SIZE_T CompareMemory(IN PCVOID LeftBuffer,\n                                              IN PCVOID RightBuffer,\n                                              IN SIZE_T Length);\n            STATIC XTAPI VOID CopyMemory(OUT PVOID Destination,\n                                         IN PCVOID Source,\n                                         IN SIZE_T Length);\n            STATIC XTAPI VOID MoveMemory(OUT PVOID Destination,\n                                         IN PCVOID Source,\n                                         IN SIZE_T Length);\n            STATIC XTAPI BOOLEAN SameMemory(IN PCVOID LeftBuffer,\n                                            IN PCVOID RightBuffer,\n                                            IN SIZE_T Length);\n            STATIC XTAPI VOID SetMemory(OUT PVOID Destination,\n                                        IN UCHAR Byte,\n                                        IN SIZE_T Length);\n            STATIC XTAPI VOID ZeroMemory(OUT PVOID Destination,\n                                         IN SIZE_T Length);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_MEMORY_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/sha1.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/sha1.hh\n * DESCRIPTION:     SHA1 computation support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTOSKRNL_RTL_SHA1_HH\n#define __XTOSKRNL_RTL_SHA1_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class SHA1\n    {\n        public:\n            STATIC XTAPI XTSTATUS ComputeDigest(IN PCUCHAR Buffer,\n                                                IN SIZE_T BufferSize,\n                                                OUT PUCHAR Digest);\n\n        private:\n            STATIC XTAPI VOID ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,\n                                              OUT PUCHAR Digest);\n            STATIC XTAPI VOID HashData(IN OUT PRTL_SHA1_CONTEXT Context,\n                                       IN PCUCHAR Data,\n                                       IN ULONG Length);\n            STATIC XTAPI XTSTATUS InitializeContext(OUT PRTL_SHA1_CONTEXT Context);\n            STATIC XTAPI VOID TransformData(IN OUT PULONG State,\n                                            IN PCUCHAR Buffer);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_SHA1_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/slist.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/slist.hh\n * DESCRIPTION:     Singly linked list manipulation routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#ifndef __XTOSKRNL_RTL_SLIST_HH\n#define __XTOSKRNL_RTL_SLIST_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class SinglyList\n    {\n        public:\n            STATIC XTCDECL PSINGLE_LIST_ENTRY GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead);\n            STATIC XTCDECL VOID InitializeListHead(IN PSINGLE_LIST_HEADER ListHead);\n            STATIC XTCDECL PSINGLE_LIST_ENTRY InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,\n                                                             IN PSINGLE_LIST_ENTRY Entry);\n            STATIC XTCDECL PSINGLE_LIST_ENTRY InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,\n                                                             IN PSINGLE_LIST_ENTRY Entry);\n            STATIC XTCDECL BOOLEAN ListEmpty(IN PSINGLE_LIST_HEADER ListHead);\n            STATIC XTAPI USHORT QueryListDepth(IN PSINGLE_LIST_HEADER ListHead);\n            STATIC XTCDECL VOID RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,\n                                                IN PSINGLE_LIST_ENTRY Entry);\n            STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,\n                                                             IN OUT PSINGLE_LIST_HEADER SpliceList);\n            STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,\n                                                             IN OUT PSINGLE_LIST_HEADER SpliceList);\n            STATIC XTCDECL PSINGLE_LIST_ENTRY TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_SLIST_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/string.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/string.hh\n * DESCRIPTION:     String support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_STRING_HH\n#define __XTOSKRNL_RTL_STRING_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class String\n    {\n        public:\n            STATIC XTAPI SIZE_T CompareString(IN PCSTR String1,\n                                              IN PCSTR String2,\n                                              IN SIZE_T Length);\n            STATIC XTAPI SIZE_T CompareStringInsensitive(IN PCSTR String1,\n                                                         IN PCSTR String2,\n                                                         IN SIZE_T Length);\n            STATIC XTAPI PCHAR ConcatenateString(OUT PCHAR Destination,\n                                                 IN PCHAR Source,\n                                                 IN SIZE_T Count);\n            STATIC XTAPI VOID CopyString(IN PCHAR Destination,\n                                         IN PCSTR Source,\n                                         IN ULONG Length);\n            STATIC XTAPI PCSTR FindString(IN PCSTR Source,\n                                          IN PCSTR Search);\n            STATIC XTAPI PCSTR FindStringInsensitive(IN PCSTR Source,\n                                                     IN PCSTR Search);\n            STATIC XTAPI VOID ReverseString(IN OUT PCHAR String,\n                                            IN ULONG Length);\n            STATIC XTAPI SIZE_T StringLength(IN PCSTR String,\n                                             IN SIZE_T MaxLength);\n            STATIC XTAPI XTSTATUS StringToNumber(IN PCSTR String,\n                                                 IN ULONG Base,\n                                                 OUT PULONG Value);\n            STATIC XTAPI SIZE_T StringToWideString(OUT PWCHAR Destination,\n                                                   IN PCSTR *Source,\n                                                   IN SIZE_T Length);\n            STATIC XTAPI PCHAR TokenizeString(IN PCHAR String,\n                                              IN PCSTR Delimiter,\n                                              IN OUT PCHAR *SavePtr);\n            STATIC XTAPI CHAR ToLowerCharacter(IN CHAR Character);\n            STATIC XTAPI CHAR ToUpperCharacter(IN CHAR Character);\n            STATIC XTAPI PCHAR TrimLeftString(IN PCHAR String);\n            STATIC XTAPI PCHAR TrimRightString(IN PCHAR String);\n            STATIC XTAPI PCHAR TrimString(IN PCHAR String);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_STRING_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/time.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/time.hh\n * DESCRIPTION:     Time conversion support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_TIME_HH\n#define __XTOSKRNL_RTL_TIME_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class Time\n    {\n        private:\n            STATIC CUSHORT DaysInMonth[2][12];\n\n        public:\n            STATIC XTAPI XTSTATUS TimeFieldsToUnixEpoch(IN PTIME_FIELDS TimeFields,\n                                                        OUT PLONGLONG UnixTime);\n            STATIC XTAPI XTSTATUS TimeFieldsToXtEpoch(IN PTIME_FIELDS TimeFields,\n                                                      OUT PLARGE_INTEGER XtTime);\n            STATIC XTAPI XTSTATUS UnixEpochToTimeFields(IN PLONGLONG UnixTime,\n                                                        OUT PTIME_FIELDS TimeFields);\n            STATIC XTAPI XTSTATUS XtEpochToTimeFields(IN PLARGE_INTEGER XtTime,\n                                                      OUT PTIME_FIELDS TimeFields);\n\n        private:\n            STATIC XTFASTCALL BOOLEAN LeapYear(SHORT Year);\n\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_TIME_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl/widestr.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl/widestr.hh\n * DESCRIPTION:     Wide string support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_WIDESTR_HH\n#define __XTOSKRNL_RTL_WIDESTR_HH\n\n#include <xtos.hh>\n\n\n/* Runtime Library */\nnamespace RTL\n{\n    class WideString\n    {\n        public:\n            STATIC XTAPI SIZE_T CompareWideString(IN PCWSTR String1,\n                                                  IN PCWSTR String2,\n                                                  IN SIZE_T Length);\n            STATIC XTAPI SIZE_T CompareWideStringInsensitive(IN PCWSTR String1,\n                                                             IN PCWSTR String2,\n                                                             IN SIZE_T Length);\n            STATIC XTAPI PWCHAR ConcatenateWideString(OUT PWCHAR Destination,\n                                                      IN PWCHAR Source,\n                                                      IN SIZE_T Count);\n            STATIC XTAPI VOID CopyWideString(IN PWCHAR Destination,\n                                             IN PCWSTR Source,\n                                             IN ULONG Length);\n            STATIC XTAPI PCWSTR FindWideString(IN PCWSTR Source,\n                                               IN PCWSTR Search);\n            STATIC XTAPI PCWSTR FindWideStringInsensitive(IN PCWSTR Source,\n                                                          IN PCWSTR Search);\n            STATIC XTAPI XTSTATUS FormatWideString(IN PRTL_PRINT_CONTEXT Context,\n                                                   IN PCWSTR Format,\n                                                   IN VA_LIST ArgumentList);\n            STATIC XTAPI VOID ReverseWideString(IN OUT PWCHAR String,\n                                                IN ULONG Length);\n            STATIC XTAPI PWCHAR TokenizeWideString(IN PWCHAR String,\n                                                   IN PCWSTR Delimiter,\n                                                   IN OUT PWCHAR *SavePtr);\n            STATIC XTAPI WCHAR ToLowerWideCharacter(IN WCHAR Character);\n            STATIC XTAPI WCHAR ToUpperWideCharacter(IN WCHAR Character);\n            STATIC XTAPI PWCHAR TrimLeftWideString(IN PWCHAR String);\n            STATIC XTAPI PWCHAR TrimRightWideString(IN PWCHAR String);\n            STATIC XTAPI PWCHAR TrimWideString(IN PWCHAR String);\n            STATIC XTAPI SIZE_T WideStringLength(IN PCWSTR String,\n                                                 IN SIZE_T MaxLength);\n            STATIC XTAPI XTSTATUS WideStringToNumber(IN PCWSTR String,\n                                                     IN ULONG Base,\n                                                     OUT PULONG Value);\n\n        private:\n            STATIC XTAPI XTSTATUS FormatArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context,\n                                                          IN PCWSTR Format,\n                                                          IN PVA_LIST ArgumentList,\n                                                          IN OUT PULONG Index);\n            STATIC XTAPI ULONGLONG GetArgument(IN PVA_LIST ArgumentList,\n                                               IN ULONG ArgumentNumber,\n                                               IN LONG ArgumentSize);\n            STATIC XTAPI ULONGLONG GetSpecifierValue(IN PWCHAR *Format);\n            STATIC XTAPI XTSTATUS WriteWideCharacter(IN PRTL_PRINT_CONTEXT Context,\n                                                     IN WCHAR Character);\n            STATIC XTCDECL XTSTATUS WriteCustomValue(IN PRTL_PRINT_CONTEXT Context,\n                                                     IN PCWSTR Format,\n                                                     IN ...);\n            STATIC XTAPI XTSTATUS WriteDoubleValue(IN PRTL_PRINT_CONTEXT Context,\n                                                   IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                                   IN DOUBLE Value);\n            STATIC XTAPI XTSTATUS WriteHexDoubleValue(IN PRTL_PRINT_CONTEXT Context,\n                                                      IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                                      IN DOUBLE Double);\n            STATIC XTAPI XTSTATUS WriteIntegerValue(IN PRTL_PRINT_CONTEXT Context,\n                                                    IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                                    IN ULONGLONG Integer);\n            STATIC XTAPI XTSTATUS WriteStringValue(PRTL_PRINT_CONTEXT Context,\n                                                   PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                                   PCSTR String,\n                                                   SIZE_T StringLength);\n            STATIC XTAPI XTSTATUS WriteValue(PRTL_PRINT_CONTEXT Context,\n                                             PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                             PCWSTR String,\n                                             SIZE_T StringLength);\n    };\n}\n\n#endif /* __XTOSKRNL_RTL_WIDESTR_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/rtl.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/rtl.hh\n * DESCRIPTION:     Runtime Library\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#ifndef __XTOSKRNL_RTL_HH\n#define __XTOSKRNL_RTL_HH\n\n#include <xtos.hh>\n\n#include XTOS_ARCH_HEADER(rtl, intrin.hh)\n\n#include <rtl/atomic.hh>\n#include <rtl/bitmap.hh>\n#include <rtl/dispatch.hh>\n#include <rtl/endian.hh>\n#include <rtl/guid.hh>\n#include <rtl/llist.hh>\n#include <rtl/math.hh>\n#include <rtl/memory.hh>\n#include <rtl/sha1.hh>\n#include <rtl/slist.hh>\n#include <rtl/string.hh>\n#include <rtl/time.hh>\n#include <rtl/widestr.hh>\n\n#endif /* __XTOSKRNL_RTL_HH */\n"
  },
  {
    "path": "xtoskrnl/includes/xtos.hh",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/includes/xtos.hh\n * DESCRIPTION:     Top level header for the XT kernel\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n\n/* Preprocessor macro for including arch-specific headers */\n#define XTOS_ARCH_HEADER(subsystem, header) STRINGIFY(subsystem/_ARCH/header)\n\n/* XT Kernel Mode Development Kit */\n#include <xtkmapi.h>\n\n/* XT OS version */\n#include <xtver.h>\n\n/* Kernel specific headers */\n#include <ar.hh>\n#include <ex.hh>\n#include <hl.hh>\n#include <kd.hh>\n#include <ke.hh>\n#include <mm.hh>\n#include <po.hh>\n#include <rtl.hh>\n"
  },
  {
    "path": "xtoskrnl/kd/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/kd/globals.cc\n * DESCRIPTION:     Kernel Debugger global and static data\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Debug I/O spinlock */\nKSPIN_LOCK KD::DebugIo::DebugIoLock;\n\n/* Kernel Debugger mode */\nKD_DEBUG_MODE KD::DebugIo::DebugMode;\n\n/* Debugger I/O providers initialization routines */\nPKD_INIT_ROUTINE KD::DebugIo::IoProvidersInitRoutines[KDBG_PROVIDERS_COUNT] = {\n    InitializeFrameBufferProvider,\n    InitializeSerialPortProvider\n};\n\n/* Pointer to DbgPrint() routine */\nPKD_PRINT_ROUTINE KD::DebugIo::KdPrint = NULLPTR;\n\n/* List of active I/O providers */\nLIST_ENTRY KD::DebugIo::Providers;\n\n/* Debugger's serial port handle */\nCPPORT KD::DebugIo::SerialPort;\n\n/* Pre-defined serial port addresses */\nULONG KD::DebugIo::SerialPortList[COMPORT_COUNT] = COMPORT_ADDRESS;\n"
  },
  {
    "path": "xtoskrnl/kd/dbgio.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/kd/dbgio.cc\n * DESCRIPTION:     Kernel Debugger I/O routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Prints a formatted string using the configured debug output providers.\n *\n * @param Format\n *        Supplies the format string.\n *\n * @param ...\n *        Supplies the variable argument list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKD::DebugIo::DbgPrint(PCWSTR Format,\n                      ...)\n{\n    VA_LIST Arguments;\n\n    /* Initialise the va_list */\n    VA_START(Arguments, Format);\n\n    /* Call the actual debug print routine */\n    DbgPrint(Format, Arguments);\n\n    /* Clean up the va_list */\n    VA_END(Arguments);\n}\n\n/**\n * Prints a formatted string using the configured debug output providers (va_list variant).\n *\n * @param Format\n *        Supplies the format string.\n *\n * @param ...\n *        Supplies the variable argument list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKD::DebugIo::DbgPrint(PCWSTR Format,\n                      VA_LIST Arguments)\n{\n    PLIST_ENTRY DispatchTableEntry;\n    PKD_DISPATCH_TABLE DispatchTable;\n\n    /* Raise runlevel and acquire the Debug I/O lock */\n    KE::RaiseRunLevel RunLevel(HIGH_LEVEL);\n    KE::SpinLockGuard SpinLock(&DebugIoLock);\n\n    /* Iterate over all registered debug providers */\n    DispatchTableEntry = Providers.Flink;\n    while(DispatchTableEntry != &Providers)\n    {\n        /* Get dispatch table */\n        DispatchTable = CONTAIN_RECORD(DispatchTableEntry, KD_DISPATCH_TABLE, ListEntry);\n\n        /* Print formatted string using the provider's print context */\n        RTL::WideString::FormatWideString(&DispatchTable->PrintContext, (PWCHAR)Format, Arguments);\n\n        /* Move to the next provider */\n        DispatchTableEntry = DispatchTableEntry->Flink;\n    }\n}\n\n/**\n * Detects and enables the kernel's debug ports based on the 'DEBUG' parameter passed to the kernel.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKD::DebugIo::DetectDebugPorts(VOID)\n{\n    PCWSTR DebugOption;\n    XTSTATUS Status;\n\n    /* Get debug parameter */\n    Status = KE::BootInformation::GetKernelParameter(L\"DEBUG\", &DebugOption);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Debug parameter not found, disable debugging */\n        DebugMode.Enabled = FALSE;\n        return Status;\n    }\n\n    /* Skip parameter name and check if it is set */\n    DebugOption += 5;\n    if(*DebugOption != L'=')\n    {\n        /* Debug parameter not set, disable debugging */\n        DebugMode.Enabled = FALSE;\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Skip '=' symbol */\n    DebugOption++;\n\n    /* Iterate over all debug ports */\n    while(*DebugOption != L'\\0' && *DebugOption != L' ')\n    {\n        /* Check what port is set for debugging */\n        if(RTL::WideString::CompareWideStringInsensitive(DebugOption, L\"COM\", 3) == 0)\n        {\n            /* Enable serial port debugging mode */\n            DebugMode.Mode |= DEBUG_PROVIDER_COMPORT;\n\n            /* Read COM port number */\n            DebugOption += 3;\n            while(*DebugOption >= '0' && *DebugOption <= '9')\n            {\n                /* Get port number */\n                DebugMode.ComPortNumber *= 10;\n                DebugMode.ComPortNumber += *DebugOption - '0';\n                DebugOption++;\n            }\n\n            /* Check if custom COM port address supplied */\n            if(DebugMode.ComPortNumber == 0 && RTL::WideString::CompareWideStringInsensitive(DebugOption, L\":0x\", 3) == 0)\n            {\n                /* COM port address provided */\n                DebugOption += 3;\n                while((*DebugOption >= '0' && *DebugOption <= '9') ||\n                      (*DebugOption >= 'A' && *DebugOption <= 'F') ||\n                      (*DebugOption >= 'a' && *DebugOption <= 'f'))\n                {\n                    /* Get port address */\n                    DebugMode.ComPortAddress *= 16;\n                    if(*DebugOption >= '0' && *DebugOption <= '9')\n                    {\n                        DebugMode.ComPortAddress += *DebugOption - '0';\n                    }\n                    else if(*DebugOption >= 'A' && *DebugOption <= 'F')\n                    {\n                        DebugMode.ComPortAddress += *DebugOption - 'A' + 10;\n                    }\n                    else if(*DebugOption >= 'a' && *DebugOption <= 'f')\n                    {\n                        DebugMode.ComPortAddress += *DebugOption - 'a' + 10;\n                    }\n                    DebugOption++;\n                }\n            }\n\n            /* Look for additional COM port parameters */\n            if(*DebugOption == ',')\n            {\n                /* Baud rate provided */\n                DebugOption++;\n                while(*DebugOption >= '0' && *DebugOption <= '9')\n                {\n                    /* Get baud rate */\n                    DebugMode.ComPortBaudRate *= 10;\n                    DebugMode.ComPortBaudRate += *DebugOption - '0';\n                    DebugOption++;\n                }\n            }\n        }\n        else if(RTL::WideString::CompareWideStringInsensitive(DebugOption, L\"SCREEN\", 6) == 0)\n        {\n            /* Enable framebuffer debugging mode */\n            DebugMode.Mode |= DEBUG_PROVIDER_FRAMEBUFFER;\n            DebugOption += 6;\n        }\n        else if(*DebugOption == L';')\n        {\n            /* Skip separator */\n            DebugOption++;\n        }\n        else\n        {\n            /* Invalid debug option, skip it */\n            while(*DebugOption != L'\\0' && *DebugOption != L' ' && *DebugOption != L';')\n            {\n                /* Advance debug option */\n                DebugOption++;\n            }\n\n        }\n    }\n\n    /* Ensure at least one debug port is enabled */\n    if(DebugMode.Mode != 0)\n    {\n        /* Enable debugging */\n        DebugMode.Enabled = TRUE;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes the kernel's debugger I/O providers.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKD::DebugIo::InitializeDebugIoProviders(VOID)\n{\n    ULONG Index;\n    XTSTATUS ProviderStatus, Status;\n\n    /* Initialize debug I/O spinlock */\n    KE::SpinLock::InitializeSpinLock(&DebugIoLock);\n\n    /* Initialize debug providers list */\n    RTL::LinkedList::InitializeListHead(&Providers);\n\n    RTL::Memory::ZeroMemory(&DebugMode, sizeof(KD_DEBUG_MODE));\n    DetectDebugPorts();\n\n    /* Iterate over providers initialization routines */\n    for(Index = 0; Index < KDBG_PROVIDERS_COUNT; Index++)\n    {\n        /* Initialize provider */\n        ProviderStatus = IoProvidersInitRoutines[Index]();\n        Status = (Status || ProviderStatus);\n    }\n\n    /* Initialize debug print routine */\n    SetPrintRoutine((PKD_PRINT_ROUTINE)DbgPrint);\n\n    /* Return status code */\n    return Status;\n}\n\n/**\n * Initializes the framebuffer device provider for the kernel debugger.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKD::DebugIo::InitializeFrameBufferProvider(VOID)\n{\n    STATIC KD_DISPATCH_TABLE DispatchTable;\n    ULONG Height, Width;\n\n    /* Check if framebuffer provider is enabled */\n    if(DebugMode.Enabled && (DebugMode.Mode & DEBUG_PROVIDER_FRAMEBUFFER) == 0)\n    {\n        /* Screen is not enabled, no need to initialize provider */\n        return STATUS_PORT_DISCONNECTED;\n    }\n\n    /* Ensure frame buffer is initialized and get FB resolution */\n    HL::FrameBuffer::InitializeFrameBuffer();\n    HL::FrameBuffer::GetFrameBufferResolution(&Width, &Height);\n\n    /* Print debug message */\n    DebugPrint(L\"Initializing debug console at framebuffer device (%lu x %lu)\\n\", Width, Height);\n\n    /* Initialize scroll region to full screen and white font color */\n    HL::FrameBuffer::InitializeScrollRegion(0, 0, Width - 1, Height - 1, 0xFFFFFFFF);\n\n    /* Initialize screen dispatch table */\n    DispatchTable.PrintContext.WriteWideCharacter = HL::FrameBuffer::DisplayCharacter;\n    RTL::LinkedList::InsertHeadList(&Providers, &DispatchTable.ListEntry);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes the serial port device provider for the kernel debugger.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKD::DebugIo::InitializeSerialPortProvider(VOID)\n{\n    STATIC KD_DISPATCH_TABLE DispatchTable;\n    XTSTATUS Status;\n\n    /* Check if serial port provider is enabled */\n    if(DebugMode.Enabled && (DebugMode.Mode & DEBUG_PROVIDER_COMPORT) == 0)\n    {\n        /* Serial port is not enabled, no need to initialize provider */\n        return STATUS_PORT_DISCONNECTED;\n    }\n\n    /* Check if custom COM port address supplied */\n    if(!DebugMode.ComPortAddress)\n    {\n        /* We support only a pre-defined number of ports */\n        if(DebugMode.ComPortNumber > COMPORT_COUNT)\n        {\n            /* Fail if wrong/unsupported port used */\n            return STATUS_INVALID_PARAMETER;\n        }\n\n        /* Check if serial port is set */\n        if(DebugMode.ComPortNumber == 0)\n        {\n            /* Use COM1 by default */\n            DebugMode.ComPortNumber = 1;\n        }\n\n        /* Set custom port address based on the port number and print debug message */\n        DebugMode.ComPortAddress = SerialPortList[DebugMode.ComPortNumber - 1];\n        DebugPrint(L\"Initializing debug console at serial port (COM%lu, BaudRate: %lu)\\n\",\n                   DebugMode.ComPortNumber, DebugMode.ComPortBaudRate);\n    }\n    else\n    {\n        /* Custom port address supplied, print debug message */\n        DebugPrint(L\"Initializing debug console at serial port (0x%lX, BaudRate: %lu)\\n\",\n                   DebugMode.ComPortAddress, DebugMode.ComPortBaudRate);\n    }\n\n    /* Initialize COM port */\n    Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(DebugMode.ComPortAddress), DebugMode.ComPortBaudRate);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Serial port initialization failed */\n        return Status;\n    }\n\n    /* Initialize serial port dispatch table */\n    DispatchTable.PrintContext.WriteWideCharacter = SerialWriteCharacter;\n    RTL::LinkedList::InsertHeadList(&Providers, &DispatchTable.ListEntry);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Configures the kernel's debug print routine by setting a new output handler.\n *\n * @param DebugPrintRoutine\n *        Supplies a pointer to the new debug print routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKD::DebugIo::SetPrintRoutine(PKD_PRINT_ROUTINE DebugPrintRoutine)\n{\n    /* Set debug print routine */\n    KdPrint = DebugPrintRoutine;\n}\n\n\n/**\n * Writes a character to the serial console.\n *\n * @param Character\n *        The integer promotion of the character to be written.\n *\n * @return This routine returns a status code indicating the success or failure of the operation.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nKD::DebugIo::SerialWriteCharacter(WCHAR Character)\n{\n    WCHAR Buffer[2];\n\n    /* Write character to the serial console */\n    Buffer[0] = Character;\n    Buffer[1] = 0;\n    return HL::ComPort::WriteComPort(&SerialPort, Buffer[0]);\n}\n"
  },
  {
    "path": "xtoskrnl/kd/exports.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/kd/exports.cc\n * DESCRIPTION:     C-compatible API wrappers for exported kernel functions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Prints a formatted string using the configured debug output providers.\n *\n * @param Format\n *        Supplies the format string.\n *\n * @param ...\n *        Supplies the variable argument list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\nDbgPrint(PCWSTR Format,\n         ...)\n{\n    VA_LIST Arguments;\n\n    /* Initialise the va_list */\n    VA_START(Arguments, Format);\n\n    KD::DebugIo::DbgPrint(Format, Arguments);\n\n    /* Clean up the va_list */\n    VA_END(Arguments);\n}\n"
  },
  {
    "path": "xtoskrnl/ke/amd64/dispatch.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/amd64/dispatch.cc\n * DESCRIPTION:     Kernel Thread Dispatcher\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Entry point for thread context switching.\n *\n * @param CurrentThread\n *        Pointer to the KTHREAD structure of the current thread being suspended.\n *\n * @param RunLevel\n *        Supplies the running level at which the wait was initiated.\n *\n * @return This routine returns TRUE if a kernel APC is pending and can be delivered, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nKE::Dispatcher::SwitchContext(IN PKTHREAD CurrentThread,\n                              IN KRUNLEVEL RunLevel)\n{\n    BOOLEAN PendingApc;\n\n    /* Save non-volatile and XMM registers to the exception frame, align the stack and invoke the switch routine */\n    __asm__ volatile(\"subq %[ExFrameSize], %%rsp\\n\"\n                     \"movq %%rbp, %c[ExRbp](%%rsp)\\n\"\n                     \"movq %%rbx, %c[ExRbx](%%rsp)\\n\"\n                     \"movq %%rdi, %c[ExRdi](%%rsp)\\n\"\n                     \"movq %%rsi, %c[ExRsi](%%rsp)\\n\"\n                     \"movq %%r12, %c[ExR12](%%rsp)\\n\"\n                     \"movq %%r13, %c[ExR13](%%rsp)\\n\"\n                     \"movq %%r14, %c[ExR14](%%rsp)\\n\"\n                     \"movq %%r15, %c[ExR15](%%rsp)\\n\"\n                     \"movdqa %%xmm6, %c[ExXmm6](%%rsp)\\n\"\n                     \"movdqa %%xmm7, %c[ExXmm7](%%rsp)\\n\"\n                     \"movdqa %%xmm8, %c[ExXmm8](%%rsp)\\n\"\n                     \"movdqa %%xmm9, %c[ExXmm9](%%rsp)\\n\"\n                     \"movdqa %%xmm10, %c[ExXmm10](%%rsp)\\n\"\n                     \"movdqa %%xmm11, %c[ExXmm11](%%rsp)\\n\"\n                     \"movdqa %%xmm12, %c[ExXmm12](%%rsp)\\n\"\n                     \"movdqa %%xmm13, %c[ExXmm13](%%rsp)\\n\"\n                     \"movdqa %%xmm14, %c[ExXmm14](%%rsp)\\n\"\n                     \"movdqa %%xmm15, %c[ExXmm15](%%rsp)\\n\"\n                     \"callq %P[SwitchRoutine]\\n\"\n                     \"movq %c[ExRbp](%%rsp), %%rbp\\n\"\n                     \"movq %c[ExRbx](%%rsp), %%rbx\\n\"\n                     \"movq %c[ExRdi](%%rsp), %%rdi\\n\"\n                     \"movq %c[ExRsi](%%rsp), %%rsi\\n\"\n                     \"movq %c[ExR12](%%rsp), %%r12\\n\"\n                     \"movq %c[ExR13](%%rsp), %%r13\\n\"\n                     \"movq %c[ExR14](%%rsp), %%r14\\n\"\n                     \"movq %c[ExR15](%%rsp), %%r15\\n\"\n                     \"movdqa %c[ExXmm6](%%rsp), %%xmm6\\n\"\n                     \"movdqa %c[ExXmm7](%%rsp), %%xmm7\\n\"\n                     \"movdqa %c[ExXmm8](%%rsp), %%xmm8\\n\"\n                     \"movdqa %c[ExXmm9](%%rsp), %%xmm9\\n\"\n                     \"movdqa %c[ExXmm10](%%rsp), %%xmm10\\n\"\n                     \"movdqa %c[ExXmm11](%%rsp), %%xmm11\\n\"\n                     \"movdqa %c[ExXmm12](%%rsp), %%xmm12\\n\"\n                     \"movdqa %c[ExXmm13](%%rsp), %%xmm13\\n\"\n                     \"movdqa %c[ExXmm14](%%rsp), %%xmm14\\n\"\n                     \"movdqa %c[ExXmm15](%%rsp), %%xmm15\\n\"\n                     \"addq %[ExFrameSize], %%rsp\\n\"\n                     : \"=a\" (PendingApc)\n                     : \"c\" (CurrentThread),\n                       \"d\" (RunLevel),\n                       [ExFrameSize] \"i\" (sizeof(KEXCEPTION_FRAME) - 8),\n                       [ExR12] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, R12)),\n                       [ExR13] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, R13)),\n                       [ExR14] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, R14)),\n                       [ExR15] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, R15)),\n                       [ExRbp] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Rbp)),\n                       [ExRbx] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Rbx)),\n                       [ExRdi] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Rdi)),\n                       [ExRsi] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Rsi)),\n                       [ExXmm6] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm6)),\n                       [ExXmm7] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm7)),\n                       [ExXmm8] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm8)),\n                       [ExXmm9] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm9)),\n                       [ExXmm10] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm10)),\n                       [ExXmm11] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm11)),\n                       [ExXmm12] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm12)),\n                       [ExXmm13] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm13)),\n                       [ExXmm14] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm14)),\n                       [ExXmm15] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Xmm15)),\n                       [SwitchRoutine] \"i\" (SwitchThreadStack)\n                     : \"cc\", \"memory\", \"r8\", \"r9\", \"r10\", \"r11\");\n\n    /* Return the APC status */\n    return PendingApc;\n}\n\n/**\n * Switches context from current thread to the new thread.\n *\n * @param CurrentThread\n *        Pointer to the KTHREAD structure of the current thread being suspended.\n *\n * @param ApcBypass\n *        Indicates whether the APC delivery should be bypassed.\n *\n * @return This routine returns TRUE if a kernel APC is pending and can be delivered, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nKE::Dispatcher::SwitchThreadContext(IN PKTHREAD CurrentThread,\n                                    IN BOOLEAN ApcBypass)\n{\n    UNIMPLEMENTED;\n\n    return FALSE;\n}\n\n/**\n * Switches the thread stack and performs necessary operations to prepare for context switching.\n *\n * @param CurrentThread\n *        Pointer to the KTHREAD structure of the current thread being suspended.\n *\n * @param RunLevel\n *        Supplies the running level at which the wait was initiated.\n *\n * @return This routine returns TRUE if a kernel APC is pending and can be delivered, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nKE::Dispatcher::SwitchThreadStack(IN PKTHREAD CurrentThread,\n                                  IN KRUNLEVEL RunLevel)\n{\n    BOOLEAN PendingApc;\n\n    /* Preserve MXCSR, synchronize with CPUs, switch stack and call the switch routine */\n    __asm__ volatile(\"pushq %%rbp\\n\"\n                     \"subq %[FrameSize], %%rsp\\n\"\n                     \"stmxcsr %c[SwMxCsr](%%rsp)\\n\"\n                     \"movq %%gs:%c[PrcbcCurrentThread], %%r8\\n\"\n                     \"BusyLoop:\\n\"\n                     \"cmpb $0, %c[ThrdSwapBusy](%%r8)\\n\"\n                     \"je ExitLoop\\n\"\n                     \"pause\\n\"\n                     \"jmp BusyLoop\\n\"\n                     \"ExitLoop:\\n\"\n                     \"movb %%dl, %c[SwApcBypass](%%rsp)\\n\"\n                     \"movq %%rsp, %c[ThrdStack](%%rcx)\\n\"\n                     \"movq %c[ThrdStack](%%r8), %%rsp\\n\"\n                     \"movzbl %c[SwApcBypass](%%rsp), %%edx\\n\"\n                     \"callq %P[SwitchRoutine]\\n\"\n                     \"ldmxcsr %c[SwMxCsr](%%rsp)\\n\"\n                     \"addq %[FrameSize], %%rsp\\n\"\n                     \"popq %%rbp\\n\"\n                     : \"=a\" (PendingApc)\n                     : \"c\" (CurrentThread),\n                       \"d\" (RunLevel),\n                       [FrameSize] \"i\" (FIELD_OFFSET(KSWITCH_FRAME, Rbp)),\n                       [PrcbcCurrentThread] \"i\" (FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)),\n                       [SwApcBypass] \"i\" (FIELD_OFFSET(KSWITCH_FRAME, ApcBypass)),\n                       [SwMxCsr] \"i\" (FIELD_OFFSET(KSWITCH_FRAME, MxCsr)),\n                       [SwitchRoutine] \"i\" (SwitchThreadContext),\n                       [ThrdStack] \"i\" (FIELD_OFFSET(KTHREAD, KernelStack)),\n                       [ThrdSwapBusy] \"i\" (FIELD_OFFSET(KTHREAD, SwapBusy))\n                     : \"cc\", \"memory\", \"r8\", \"r9\", \"r10\", \"r11\");\n\n    /* Return the APC status */\n    return PendingApc;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/amd64/krnlinit.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/amd64/krnlinit.cc\n * DESCRIPTION:     CPU architecture specific kernel initialization\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Bootstraps an Application Processor (AP) into the active kernel. This routine is executed exclusively by secondary\n * processors after being awakened by the BSP. It is called directly from the startup trampoline.\n *\n * @param StartBlock\n *        Supplies a pointer to the processor start block containing initialization information provided by the kernel.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n\n    /* Initialize application CPU */\n    AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);\n\n    /* Initialize processor */\n    HL::Cpu::InitializeProcessor();\n\n    /* Raise to HIGH runlevel */\n    KE::RunLevel::RaiseRunLevel(HIGH_LEVEL);\n\n    /* Mark processor as started */\n    StartBlock->Started = TRUE;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    /* Enter infinite loop */\n    DebugPrint(L\"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\\n\",\n               ProcessorBlock->CpuNumber);\n    KE::Crash::HaltSystem();\n}\n\n/**\n * Bootstraps the XT kernel and global subsystems. This routine is executed exclusively by the Bootstrap Processor\n * and it is called immediately after switching to the kernel boot stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::BootstrapKernel(VOID)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    ULONG_PTR PageDirectory[2];\n    PKPROCESS CurrentProcess;\n    PKTHREAD CurrentThread;\n\n    /* Get processor control block and current thread */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n    CurrentThread = KE::Processor::GetCurrentThread();\n\n    /* Get current process */\n    CurrentProcess = CurrentThread->ApcState.Process;\n\n    /* Initialize CPU power state structures */\n    PO::Idle::InitializeProcessorIdleState(Prcb);\n\n    /* Save processor state */\n    KE::Processor::SaveProcessorState(&Prcb->ProcessorState);\n\n    /* Initialize spin locks */\n    KE::SpinLock::InitializeAllLocks();\n    KE::SpinLock::InitializeLockQueues();\n\n    /* Lower to APC runlevel */\n    KE::RunLevel::LowerRunLevel(APC_LEVEL);\n\n    /* Initialize XTOS kernel */\n    InitializeKernel();\n\n    /* Initialize Idle process */\n    PageDirectory[0] = 0;\n    PageDirectory[1] = 0;\n    KE::KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);\n    CurrentProcess->Quantum = MAXCHAR;\n\n    /* Initialize Idle thread */\n    KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,\n                                  NULLPTR, NULLPTR, AR::ProcessorSupport::GetBootStack(), TRUE);\n    CurrentThread->NextProcessor = Prcb->CpuNumber;\n    CurrentThread->Priority = THREAD_HIGH_PRIORITY;\n    CurrentThread->State = Running;\n    CurrentThread->Affinity = (ULONG_PTR)1 << Prcb->CpuNumber;\n    CurrentThread->WaitRunLevel = DISPATCH_LEVEL;\n    CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;\n\n    /* Initialize Memory Manager */\n    MM::Manager::InitializeMemoryManager();\n\n    /* Enable shadow buffer for framebuffer */\n    HL::FrameBuffer::EnableShadowBuffer();\n\n    /* Start all application processors */\n    KE::Processor::InitializeProcessorBlocks();\n    HL::Cpu::StartAllProcessors();\n\n    /* Enter infinite loop */\n    DebugPrint(L\"KernelInit::BootstrapKernel() finished. Entering infinite loop.\\n\");\n    KE::Crash::HaltSystem();\n}\n\n/**\n * This routine initializes XT kernel.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::InitializeKernel(VOID)\n{\n    XTSTATUS Status;\n\n    /* Initialize hardware layer subsystem */\n    Status = HL::Init::InitializeSystem();\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Hardware layer initialization failed, kernel panic */\n        DebugPrint(L\"Failed to initialize hardware layer subsystem!\\n\");\n        KE::Crash::Panic(0);\n    }\n}\n\n/**\n * Performs architecture-specific initialization for the kernel executive.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::InitializeMachine(VOID)\n{\n    /* Re-enable IDE interrupts */\n    HL::IoPort::WritePort8(0x376, 0);\n    HL::IoPort::WritePort8(0x3F6, 0);\n\n    /* Initialize frame buffer */\n    HL::FrameBuffer::InitializeFrameBuffer();\n\n    /* Initialize page map support */\n    MM::Paging::InitializePageMapSupport();\n\n    /* Initialize Kernel Shared Data (KSD) */\n    KE::SharedData::InitializeKernelSharedData();\n\n    /* Initialize processor */\n    HL::Cpu::InitializeProcessor();\n}\n\n/**\n * Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::SwitchBootStack(VOID)\n{\n    ULONG_PTR Stack;\n    PVOID StartKernel;\n\n    /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */\n    Stack = ((ULONG_PTR)AR::ProcessorSupport::GetBootStack() & ~(STACK_ALIGNMENT - 1));\n\n    /* Get address of KernelInit::StartKernel() */\n    StartKernel = (PVOID)KE::KernelInit::BootstrapKernel;\n\n    /* Discard old stack frame, switch stack and jump to KernelInit::StartKernel() */\n    __asm__ volatile(\"movq %[Stack], %%rsp\\n\"\n                     \"subq %[TotalSize], %%rsp\\n\"\n                     \"xorq %%rbp, %%rbp\\n\"\n                     \"jmp *%[TargetRoutine]\\n\"\n                     :\n                     : [Stack] \"r\" (Stack),\n                       [TargetRoutine] \"r\" (StartKernel),\n                       [TotalSize] \"i\" (FLOATING_SAVE_AREA_SIZE + KEXCEPTION_FRAME_SIZE +\n                                        KSWITCH_FRAME_SIZE + KRETURN_ADDRESS_SIZE)\n                     : \"memory\", \"rbp\", \"rsp\");\n}\n"
  },
  {
    "path": "xtoskrnl/ke/amd64/kthread.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/amd64/kthread.cc\n * DESCRIPTION:     AMD64 thread manipulation support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Initializes CPU architecture dependent context of a thread.\n *\n * @param Thread\n *        Supplies a pointer to the thread being initialized.\n *\n * @param SystemRoutine\n *        Supplies a pointer to the routine called during first scheduling.\n *\n * @param StartRoutine\n *        Supplies a pointer to the routine called during thread startup.\n *\n * @param StartContext\n *        Supplies a pointer to a context data that will be passed to start routine.\n *\n * @param ContextRecord\n *        Supplies a pointer to a context record which stores the initial state of the user mode thread.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KThread::InitializeThreadContext(IN PKTHREAD Thread,\n                                     IN PKSYSTEM_ROUTINE SystemRoutine,\n                                     IN PKSTART_ROUTINE StartRoutine,\n                                     IN PVOID StartContext,\n                                     IN PCONTEXT ContextRecord)\n{\n    PKTHREAD_INIT_FRAME ThreadFrame;\n\n    /* Set initial thread frame */\n    ThreadFrame = ((PKTHREAD_INIT_FRAME)Thread->InitialStack) - 1;\n\n    /* Fill floating point save area with zeroes */\n    RTL::Memory::ZeroMemory(&ThreadFrame->NpxFrame, sizeof(FLOATING_SAVE_AREA));\n\n    /* Check if context provided for this thread */\n    if(ContextRecord)\n    {\n        /* User mode thread needs further initialization, this is not completed */\n        UNIMPLEMENTED;\n\n        /* Fill exception and trap frames with zeroes */\n        RTL::Memory::ZeroMemory(&ThreadFrame->ExceptionFrame, sizeof(KEXCEPTION_FRAME));\n        RTL::Memory::ZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME));\n\n        /* Disable debug registers and enable context registers */\n        ContextRecord->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS | CONTEXT_CONTROL;\n\n        /* Align the stack and reserve space for 4 parameters and return value */\n        ContextRecord->Rsp = (ContextRecord->Rsp & ~15) - 40;\n\n        /* Set CS and SS segments for user mode */\n        ContextRecord->SegCs = KGDT_R3_CODE | RPL_MASK;\n        ContextRecord->SegSs = KGDT_R3_DATA | RPL_MASK;\n\n        /* This is user mode thread */\n        Thread->PreviousMode = UserMode;\n\n        /* Enable floating point state */\n        Thread->NpxState = NPX_STATE_SCRUB;\n\n        /* Set initial floating point state */\n        ThreadFrame->NpxFrame.ControlWord = 0x27F;\n        ThreadFrame->NpxFrame.TagWord = 0xFFFF;\n\n        /* Clear DR6 and DR7 registers */\n        ThreadFrame->TrapFrame.Dr6 = 0;\n        ThreadFrame->TrapFrame.Dr7 = 0;\n\n        /* Set initial MXCSR register value */\n        ThreadFrame->TrapFrame.MxCsr = INITIAL_MXCSR;\n\n        /* Initialize exception frame */\n        ThreadFrame->ExceptionFrame.P1Home = (ULONG64)StartContext;\n        ThreadFrame->ExceptionFrame.P2Home = (ULONG64)StartRoutine;\n        ThreadFrame->ExceptionFrame.P3Home = (ULONG64)SystemRoutine;\n        ThreadFrame->ExceptionFrame.P4Home = (ULONG64)SystemRoutine;\n    }\n    else\n    {\n        /* This is kernel mode thread */\n        Thread->PreviousMode = KernelMode;\n\n        /* Disable floating point state */\n        Thread->NpxState = NPX_STATE_UNUSED;\n\n        /* Set thread start address */\n        ThreadFrame->StartFrame.Return = (ULONG64)NULLPTR;\n    }\n\n    /* Initialize thread startup information */\n    ThreadFrame->StartFrame.P1Home = (ULONG64)StartContext;\n    ThreadFrame->StartFrame.P2Home = (ULONG64)StartRoutine;\n    ThreadFrame->StartFrame.P3Home = (ULONG64)SystemRoutine;\n    ThreadFrame->StartFrame.P4Home = (ULONG64)SystemRoutine;\n\n    /* Initialize switch frame */\n    ThreadFrame->SwitchFrame.ApcBypass = APC_LEVEL;\n    ThreadFrame->SwitchFrame.MxCsr = INITIAL_MXCSR;\n    ThreadFrame->SwitchFrame.Rbp = (ULONG64)&ThreadFrame->TrapFrame;\n\n    /* Set thread stack */\n    Thread->KernelStack = &ThreadFrame->SwitchFrame;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/amd64/proc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/amd64/proc.cc\n * DESCRIPTION:     AMD64 processor-related functionality for the kernel\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Gets the processor block for the currently executing processor.\n *\n * @return This routine returns the current processor block read from the GS register.\n *\n * @since XT 1.0\n */\nXTAPI\nPKPROCESSOR_BLOCK\nKE::Processor::GetCurrentProcessorBlock(VOID)\n{\n    /* Get processor block from GS register */\n    return (PKPROCESSOR_BLOCK)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));\n}\n\n/**\n * Gets the processor control block for the currently executing processor.\n *\n * @return This routine returns the current processor control block read from the GS register.\n *\n * @since XT 1.0\n */\nXTAPI\nPKPROCESSOR_CONTROL_BLOCK\nKE::Processor::GetCurrentProcessorControlBlock(VOID)\n{\n    return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));\n}\n\n/**\n * Gets the number of the currently executing processor.\n *\n * @return This routine returns the zero-indexed processor number.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nKE::Processor::GetCurrentProcessorNumber(VOID)\n{\n    return (ULONG)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));\n}\n\n/**\n * Gets the current thread running on the currently executing processor.\n *\n * @return This routine returns the address of the current thread object.\n *\n * @since NT 3.5\n */\nXTAPI\nPKTHREAD\nKE::Processor::GetCurrentThread(VOID)\n{\n    return (PKTHREAD)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));\n}\n\n/**\n * Gets the processor block for the specified processor number.\n *\n * @param CpuNumber\n *        Supplies the zero-indexed processor number.\n *\n * @return This routine returns a pointer to the processor block, or NULLPTR if invalid.\n *\n * @since XT 1.0\n */\nXTAPI\nPKPROCESSOR_BLOCK\nKE::Processor::GetProcessorBlock(IN ULONG CpuNumber)\n{\n    /* Check if the requested CPU number is within dynamic bounds */\n    if(CpuNumber >= InstalledCpus || ProcessorBlocks == NULLPTR || ProcessorBlocks[CpuNumber] == NULLPTR)\n    {\n        /* Invalid CPU number, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Return requested processor block */\n    return ProcessorBlocks[CpuNumber];\n}\n\n/**\n * Initializes the global processor structures by allocating an array of processor block pointers.\n *\n * @return This routine returns a status code indicating the success or failure of the allocation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKE::Processor::InitializeProcessorBlocks()\n{\n    PACPI_SYSTEM_INFO SystemInfo;\n    XTSTATUS Status;\n\n    /* Save number of CPUs installed */\n    HL::Acpi::GetSystemInformation(&SystemInfo);\n    InstalledCpus = SystemInfo->CpuCount;\n\n    /* Allocate an array of pointers */\n    Status = MM::Allocator::AllocatePool(NonPagedPool,\n                                         InstalledCpus * sizeof(PKPROCESSOR_BLOCK),\n                                         (PVOID*)&ProcessorBlocks);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to allocate memory, return error */\n        return Status;\n    }\n\n    /* Zero the array initially */\n    RTL::Memory::ZeroMemory(ProcessorBlocks, InstalledCpus * sizeof(PKPROCESSOR_BLOCK));\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Registers the hardware APIC ID for the currently executing processor.\n *\n * @param ApicId\n *        Supplies the hardware APIC ID to register in the processor block.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Processor::RegisterHardwareId(IN ULONG HardwareId)\n{\n    PKPROCESSOR_BLOCK CurrentBlock;\n\n    /* Retrieve the processor block for the executing core */\n    CurrentBlock = GetCurrentProcessorBlock();\n    if(CurrentBlock != NULLPTR)\n    {\n        /* Register the hardware identifier for IPI targeting */\n        CurrentBlock->HardwareId = HardwareId;\n    }\n}\n\n/**\n * Registers or deregisters a processor block in the global CPU table.\n *\n * @param CpuNumber\n *        Specifies the logical processor number.\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block. \n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Processor::RegisterProcessorBlock(ULONG CpuNumber,\n                                      PKPROCESSOR_BLOCK ProcessorBlock)\n{\n    /* Check if the requested CPU number is within dynamic bounds */\n    if(ProcessorBlocks != NULLPTR && CpuNumber < InstalledCpus)\n    {\n        /* Register processor block */\n        ProcessorBlocks[CpuNumber] = ProcessorBlock;\n    }\n}\n\n/**\n * Saves the current processor state.\n *\n * @param State\n *        Supplies a pointer to the processor state structure.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState)\n{\n    /* Save CR registers */\n    CpuState->SpecialRegisters.Cr0 = AR::CpuFunctions::ReadControlRegister(0);\n    CpuState->SpecialRegisters.Cr2 = AR::CpuFunctions::ReadControlRegister(2);\n    CpuState->SpecialRegisters.Cr3 = AR::CpuFunctions::ReadControlRegister(3);\n    CpuState->SpecialRegisters.Cr4 = AR::CpuFunctions::ReadControlRegister(4);\n    CpuState->SpecialRegisters.Cr8 = AR::CpuFunctions::ReadControlRegister(8);\n\n    /* Save DR registers */\n    CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunctions::ReadDebugRegister(0);\n    CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunctions::ReadDebugRegister(1);\n    CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunctions::ReadDebugRegister(2);\n    CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunctions::ReadDebugRegister(3);\n    CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunctions::ReadDebugRegister(6);\n    CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunctions::ReadDebugRegister(7);\n\n    /* Save MSR registers */\n    CpuState->SpecialRegisters.MsrGsBase = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_GSBASE);\n    CpuState->SpecialRegisters.MsrGsSwap = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE);\n    CpuState->SpecialRegisters.MsrCStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_CSTAR);\n    CpuState->SpecialRegisters.MsrLStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_LSTAR);\n    CpuState->SpecialRegisters.MsrStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_STAR);\n    CpuState->SpecialRegisters.MsrSyscallMask = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_FMASK);\n\n    /* Save XMM control/status register */\n    CpuState->SpecialRegisters.MxCsr = AR::CpuFunctions::ReadMxCsrRegister();\n\n    /* Save GDT, IDT, LDT and TaskRegister */\n    AR::CpuFunctions::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);\n    AR::CpuFunctions::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);\n    AR::CpuFunctions::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);\n    AR::CpuFunctions::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);\n}\n"
  },
  {
    "path": "xtoskrnl/ke/apc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/apc.cc\n * DESCRIPTION:     Kernel APC objects support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Initializes an APC object.\n *\n * @param Apc\n *        Supplies a pointer to the APC object.\n *\n * @param Thread\n *        Supplies a pointer to the thread object.\n *\n * @param Environment\n *        Specifies an environment in which the APC will run.\n *\n * @param KernelRoutine\n *        Supplies a pointer to routine called at APC_LEVEL.\n *\n * @param RundownRoutine\n *        Supplies a pointer to routine called on thread exit.\n *\n * @param NormalRoutine\n *        Supplies a pointer to routine called at IRQL 0.\n *\n * @param ApcMode\n *        Specifies processor mode, in which NormalRoutine gets called.\n *\n * @param Context\n *        Supplies a pointer to memory area containing data passed to NormalRoutine.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nKE::Apc::InitializeApc(IN PKAPC Apc,\n                       IN PKTHREAD Thread,\n                       IN KAPC_ENVIRONMENT Environment,\n                       IN PKKERNEL_ROUTINE KernelRoutine,\n                       IN PKRUNDOWN_ROUTINE RundownRoutine,\n                       IN PKNORMAL_ROUTINE NormalRoutine,\n                       IN KPROCESSOR_MODE ApcMode,\n                       IN PVOID Context)\n{\n    /* Set APC type and thread */\n    Apc->Type = ApcObject;\n    Apc->Thread = Thread;\n\n    /* Set routines */\n    Apc->KernelRoutine = KernelRoutine;\n    Apc->RundownRoutine = RundownRoutine;\n    Apc->NormalRoutine = NormalRoutine;\n\n    /* Check target environment */\n    if(Environment == CurrentApcEnvironment)\n    {\n        /* Use current APC environment taken from thread */\n        Apc->ApcStateIndex = Thread->ApcStateIndex;\n    }\n    else\n    {\n        /* Use new APC environment */\n        Apc->ApcStateIndex = Environment;\n    }\n\n    /* Check if normal routine specified */\n    if(NormalRoutine)\n    {\n        /* Set context and mode for notmal APC */\n        Apc->ApcMode = ApcMode;\n        Apc->NormalContext = Context;\n    }\n    else\n    {\n        /* Set context and mode for special APC */\n        Apc->ApcMode = KernelMode;\n        Apc->NormalContext = NULLPTR;\n    }\n\n    /* Mark APC as not inserted yet */\n    Apc->Inserted = FALSE;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/bootinfo.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/bootinfo.cc\n * DESCRIPTION:     Bootloader-provided system information handling support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Retrieves a pointer to the DebugPrint routine provided by the bootloader.\n *\n * @return This routine returns a pointer to the DebugPrint routine.\n *\n * @since XT 1.0\n */\nXTAPI\nPKD_PRINT_ROUTINE\nKE::BootInformation::GetDebugPrint(VOID)\n{\n    return (PKD_PRINT_ROUTINE)InitializationBlock->LoaderInformation.DbgPrint;\n}\n\n/**\n * Retrieves the system firmware type (BIOS or UEFI).\n *\n * @return This routine returns the type of the system firmware.\n *\n * @since XT 1.0\n */\nXTAPI\nSYSTEM_FIRMWARE_TYPE\nKE::BootInformation::GetFirmwareType(VOID)\n{\n    return InitializationBlock->FirmwareInformation.FirmwareType;\n}\n\n/**\n * Retrieves a pointer to the specified kernel parameter within the kernel parameters list.\n *\n * @param ParameterName\n *        Supplies a pointer to a null-terminated wide string specifying the name of the parameter to search for.\n *\n * @param Parameter\n *        Supplies a pointer to a variable that receives a pointer to the matching parameter, or NULLPTR if not found.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKE::BootInformation::GetKernelParameter(IN PCWSTR ParameterName,\n                                        OUT PCWSTR *Parameter)\n{\n    PCWSTR Match, SearchStart;\n    SIZE_T ParameterNameLength;\n\n    /* Validate input parameters */\n    if(!ParameterName || !Parameter)\n    {\n        /* Invalid input parameters, return error */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Get the length of the parameter name we are looking for */\n    ParameterNameLength = RTL::WideString::WideStringLength(ParameterName, 0);\n    if(ParameterNameLength == 0)\n    {\n        /* Do not allow empty parameter names */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Assume the requested parameter is not present in the kernel parameters */\n    *Parameter = NULLPTR;\n\n    /* Start searching from the beginning of the list */\n    SearchStart = InitializationBlock->KernelParameters;\n\n    /* Search for the parameter name */\n    while((Match = RTL::WideString::FindWideStringInsensitive(SearchStart, ParameterName)))\n    {\n        /* Check if the match is at the start of the string or preceded by a space */\n        if(Match == InitializationBlock->KernelParameters || *(Match - 1) == L' ')\n        {\n            /* Check the character after the match to avoid matching prefixes */\n            if(Match[ParameterNameLength] == L'\\0' ||\n               Match[ParameterNameLength] == L' ' ||\n               Match[ParameterNameLength] == L'=')\n            {\n                /* A valid parameter was found, return a pointer to it */\n                *Parameter = Match;\n                return STATUS_SUCCESS;\n            }\n        }\n\n        /* The match was a substring of a larger token, continue searching */\n        SearchStart = Match + 1;\n    }\n\n    /* Parameter not found */\n    return STATUS_NOT_FOUND;\n}\n\n/**\n * Retrieves the value of a specified kernel parameter and copies it into a buffer.\n *\n * @param ParameterName\n *        Supplies a pointer to a null-terminated wide string specifying the name of the parameter to search for.\n *\n * @param ValueBuffer\n *        Supplies a pointer to a variable that receives the null-terminated value of the matching parameter.\n *\n * @param BufferSize\n *        Supplies the size of the value buffer, in wide characters.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKE::BootInformation::GetKernelParameterValue(IN PCWSTR ParameterName,\n                                             OUT PWSTR ValueBuffer,\n                                             IN SIZE_T BufferSize)\n{\n    PCWSTR Match;\n    SIZE_T NameLength, Index;\n    XTSTATUS Status;\n\n    /* Validate input parameters */\n    if(!ParameterName || !ValueBuffer || BufferSize == 0)\n    {\n        /* Invalid input parameters, return error */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Initialize the output buffer to an empty string */\n    ValueBuffer[0] = L'\\0';\n\n    /* Find the parameter in the list using the base function */\n    Status = GetKernelParameter(ParameterName, &Match);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Parameter not found, return error */\n        return Status;\n    }\n\n    /* Move pointer past the parameter name */\n    NameLength = RTL::WideString::WideStringLength(ParameterName, 0);\n    Match += NameLength;\n\n    /* If the parameter has a value (indicated by '='), copy it */\n    if(*Match == L'=')\n    {\n        /* Skip the assignment operator */\n        Match++;\n\n        /* Copy the value to the caller's buffer until a space or end of string is reached */\n        Index = 0;\n        while(*Match != L'\\0' && *Match != L' ' && Index < (BufferSize - 1))\n        {\n            /* Copy the character */\n            ValueBuffer[Index] = *Match;\n            Index++;\n            Match++;\n        }\n\n        /* Null-terminate the isolated value string */\n        ValueBuffer[Index] = L'\\0';\n    }\n\n    /* Value successfully retrieved (or parameter exists without value) */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Retrieves a pointer to the list of memory descriptors.\n *\n * @return This routine returns a pointer to the list of memory descriptors.\n *\n * @since XT 1.0\n */\nXTAPI\nPLIST_ENTRY\nKE::BootInformation::GetMemoryDescriptors(VOID)\n{\n    return &InitializationBlock->MemoryDescriptorListHead;\n}\n\n/**\n * Retrieves a pointer to the list of system resources.\n *\n * @return This routine returns a pointer to the list of system resources.\n *\n * @since XT 1.0\n */\nXTAPI\nPLIST_ENTRY\nKE::BootInformation::GetSystemResources(VOID)\n{\n    return &InitializationBlock->SystemResourcesListHead;\n}\n\n/**\n * Initializes the bootloader-provided system information.\n *\n * @param Block\n *        Supplies a pointer to the kernel initialization block.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::BootInformation::InitializeInitializationBlock(IN PKERNEL_INITIALIZATION_BLOCK Block)\n{\n    /* Check if the initialization block is already initialized */\n    if(!InitializationBlock)\n    {\n        /* Save the kernel initialization block */\n        InitializationBlock = Block;\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/ke/crash.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/panic.cc\n * DESCRIPTION:     System shutdown and kernel panic mechanism\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Halts the system.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Crash::HaltSystem(VOID)\n{\n    /* Enter infinite loop */\n    for(;;)\n    {\n        /* Halt system */\n        AR::CpuFunctions::ClearInterruptFlag();\n        AR::CpuFunctions::Halt();\n    }\n}\n\n/**\n * Crashes the system upon detecting a fatal error in which either it is unable to recover or continue to run system.\n *\n * @param Code\n *        Specifies the reason for the kernel panic.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Crash::Panic(IN ULONG Code)\n{\n    Panic(Code, 0, 0, 0, 0);\n}\n\n/**\n * Crashes the system upon detecting a fatal error in which either it is unable to recover or continue to run system.\n *\n * @param Code\n *        Specifies the reason for the kernel panic.\n *\n * @param Parameter1\n *        Supplies additional information about the kernel panic.\n *\n * @param Parameter2\n *        Supplies additional information about the kernel panic.\n *\n * @param Parameter3\n *        Supplies additional information about the kernel panic.\n *\n * @param Parameter4\n *        Supplies additional information about the kernel panic.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Crash::Panic(IN ULONG Code,\n                 IN ULONG_PTR Parameter1,\n                 IN ULONG_PTR Parameter2,\n                 IN ULONG_PTR Parameter3,\n                 IN ULONG_PTR Parameter4)\n{\n    KD::DebugIo::KdPrint(L\"Fatal System Error: 0x%08lx (0x%zx 0x%zx 0x%zx 0x%zx)\\nKernel Panic!\\n\\n\",\n                         Code, Parameter1, Parameter2, Parameter3, Parameter4);\n    HaltSystem();\n}\n"
  },
  {
    "path": "xtoskrnl/ke/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/data.cc\n * DESCRIPTION:     Kernel Library global and static data\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Kernel initialization block passed by boot loader */\nPKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};\n\n/* Kernel initial process */\nEPROCESS KE::KProcess::InitialProcess;\n\n/* Kernel initial thread */\nETHREAD KE::KThread::InitialThread = {};\n\n/* Kernel UBSAN active frame flag */\nBOOLEAN KE::KUbsan::ActiveFrame = FALSE;\n\n/* Total number of installed processors in the system */\nULONG KE::Processor::InstalledCpus;\n\n/* Array of pointers to processor control blocks */\nPKPROCESSOR_BLOCK *KE::Processor::ProcessorBlocks;\n\n/* Kernel shared data (KSD) */\nPKSHARED_DATA KE::SharedData::KernelSharedData;\n\n/* Kernel dispatcher lock queue */\nKSPIN_LOCK KE::SpinLock::DispatcherLockQueue;\n\n/* Kernel expansion lock queue */\nKSPIN_LOCK KE::SpinLock::ExpansionLockQueue;\n\n/* Kernel file system structures lock queue */\nKSPIN_LOCK KE::SpinLock::FileSystemLockQueue;\n\n/* Kernel IO cancel lock queue */\nKSPIN_LOCK KE::SpinLock::IoCancelLockQueue;\n\n/* Kernel IO completion lock queue */\nKSPIN_LOCK KE::SpinLock::IoCompletionLockQueue;\n\n/* Kernel IO database lock queue */\nKSPIN_LOCK KE::SpinLock::IoDatabaseLockQueue;\n\n/* Kernel IO VPB lock queue */\nKSPIN_LOCK KE::SpinLock::IoVpbLockQueue;\n\n/* Kernel cache master lock queue */\nKSPIN_LOCK KE::SpinLock::MasterLockQueue;\n\n/* Kernel non-paged allocator lock queue */\nKSPIN_LOCK KE::SpinLock::NonPagedAllocLockQueue;\n\n/* Kernel non-paged pool lock queue */\nKSPIN_LOCK KE::SpinLock::NonPagedPoolLockQueue;\n\n/* Kernel PFN lock queue */\nKSPIN_LOCK KE::SpinLock::PfnLockQueue;\n\n/* Kernel system space lock queue */\nKSPIN_LOCK KE::SpinLock::SystemSpaceLockQueue;\n\n/* Kernel Timer table lock queue */\nKSPIN_LOCK KE::SpinLock::TimerTableLockQueue;\n\n/* Kernel VACB lock queue */\nKSPIN_LOCK KE::SpinLock::VacbLockQueue;\n\n/* Kernel work queue lock queue */\nKSPIN_LOCK KE::SpinLock::WorkLockQueue;\n\n/* Kernel boot resources list */\nLIST_ENTRY KE::SystemResources::ResourcesListHead;\n\n/* Kernel boot resources lock */\nKSPIN_LOCK KE::SystemResources::ResourcesLock;\n\n/* Kernel boot time */\nLARGE_INTEGER KE::SystemTime::BootTime;\n\n/* The maximum interval between system clock interrupts */\nULONG KE::SystemTime::MaximumIncrement;\n\n/* The minimum interval between system clock interrupts */\nULONG KE::SystemTime::MinimumIncrement;\n\n/* Accumulator tracking fractional ticks, decremented until a full tick elapses */\nLONG KE::SystemTime::TickOffset;\n\n/* The runtime adjustment value applied to the system clock at each interrupt */\nULONG KE::SystemTime::TimeAdjustment;\n"
  },
  {
    "path": "xtoskrnl/ke/dispatch.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/dispatch.cc\n * DESCRIPTION:     Kernel Thread Dispatcher\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Exits the dispatcher, switches context to a new thread and lowers runlevel to its original state.\n *\n * @param OldRunLevel\n *        Supplies the original runlevel state.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nKE::Dispatcher::ExitDispatcher(IN KRUNLEVEL OldRunLevel)\n{\n    UNIMPLEMENTED;\n\n    /* Lower runlevel */\n    RunLevel::LowerRunLevel(OldRunLevel);\n}\n\n/**\n * Updates the runtime quantum of the currently executing thread and handles preemption.\n *\n * @param TrapFrame\n *        Supplies a pointer to the hardware trap frame representing the interrupted execution context.\n *\n * @param RunLevel\n *        Supplies the system run level at which the interrupt was taken.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Dispatcher::UpdateRunTime(IN PKTRAP_FRAME TrapFrame,\n                              IN KRUNLEVEL RunLevel)\n{\n}\n"
  },
  {
    "path": "xtoskrnl/ke/dpc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/dpc.cc\n * DESCRIPTION:     Deferred Procedure Call (DPC) support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Initializes Deferred Procedure Call (DPC) object.\n *\n * @param Dpc\n *        Supplies a pointer to the DPC being initialized.\n *\n * @param DpcRoutine\n *        Supplies a pointer to the DPC routine being called on object removal.\n *\n * @param DpcContext\n *        Supplies a pointer to memory area containing context data for DPC routine.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nKE::Dpc::InitializeDpc(IN PKDPC Dpc,\n                       IN PKDEFERRED_ROUTINE DpcRoutine,\n                       IN PVOID DpcContext)\n{\n    /* Initialize DPC */\n    Dpc->Type = DpcObject;\n    Dpc->Number = 0;\n    Dpc->Importance = MediumImportance;\n\n    /* Initialize DPC routine and context data */\n    Dpc->DeferredContext = DpcContext;\n    Dpc->DeferredRoutine = DpcRoutine;\n    Dpc->DpcData = NULLPTR;\n}\n\n/**\n * Initializes Deferred Procedure Call (DPC) object.\n *\n * @param Dpc\n *        Supplies a pointer to the DPC being initialized.\n *\n * @param DpcRoutine\n *        Supplies a pointer to the DPC routine being called on object removal.\n *\n * @param DpcContext\n *        Supplies a pointer to memory area containing context data for DPC routine.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.2\n */\nXTAPI\nVOID\nKE::Dpc::InitializeThreadedDpc(IN PKDPC Dpc,\n                               IN PKDEFERRED_ROUTINE DpcRoutine,\n                               IN PVOID DpcContext)\n{\n    /* Initialize threaded DPC */\n    Dpc->Type = ThreadedDpcObject;\n    Dpc->Number = 0;\n    Dpc->Importance = MediumImportance;\n\n    /* Initialize DPC routine and context data */\n    Dpc->DeferredContext = DpcContext;\n    Dpc->DeferredRoutine = DpcRoutine;\n    Dpc->DpcData = NULLPTR;\n}\n\n/**\n * Sets the target processor number for DPC.\n *\n * @param Dpc\n *        Supplies a pointer to the DPC object.\n *\n * @param Number\n *        Supplies the target processor number.\n *\n * @return This routine does not return any value.\n *\n * @since NT 4.0\n */\nXTAPI\nVOID\nKE::Dpc::SetTargetProcessor(IN PKDPC Dpc,\n                            IN CCHAR Number)\n{\n    Dpc->Number = MAXIMUM_PROCESSORS + Number;\n}\n\n/**\n * Decrements the DPC call barier.\n *\n * @param SystemArgument\n *        Supplies an address of the DPC call barrier.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.2\n */\nXTAPI\nVOID\nKE::Dpc::SignalCallDone(IN PVOID SystemArgument)\n{\n    RTL::Atomic::Decrement32((PLONG)SystemArgument);\n}\n\n/**\n * Decrements the DPC call reverse barier.\n *\n * @param SystemArgument\n *        Supplies an address of the DPC call barrier.\n *\n * @return This routine returns TRUE if just one processor is waiting on the barrier, FALSE if more.\n *\n * @since NT 5.2\n */\nXTAPI\nBOOLEAN\nKE::Dpc::SignalCallSynchronize(IN PVOID SystemArgument)\n{\n    UNIMPLEMENTED;\n\n    /* SMP not yet implemented, return TRUE */\n    return TRUE;\n}\n\n/**\n * Retires the expired DPC objects found in the DPC list.\n *\n * @param Prcb\n *        Supplies apointer to the Prcessor Control Block (PRCB).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nKE::Dpc::RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb)\n{\n    UNIMPLEMENTED;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/event.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/event.cc\n * DESCRIPTION:     Kernel events support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Clears the signal state of the event.\n *\n * @param Event\n *        Supplies a pointer to the event object.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nKE::Event::ClearEvent(IN PKEVENT Event)\n{\n    /* Clear event's signal state */\n    Event->Header.SignalState = FALSE;\n}\n\n/**\n * Initializes a kernel event.\n *\n * @param Event\n *        Supplies a pointer to the event object.\n *\n * @param EventType\n *        Specifies an event type.\n *\n * @param InitialState\n *        Specifies the initial signal state of the event.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nKE::Event::InitializeEvent(OUT PKEVENT Event,\n                           IN KEVENT_TYPE EventType,\n                           IN BOOLEAN InitialState)\n{\n    /* Initialize event dispatcher header */\n    Event->Header.Type = EventType;\n    Event->Header.SignalState = InitialState;\n\n    /* Initialize event wait list */\n    RtlInitializeListHead(&Event->Header.WaitListHead);\n}\n\n/**\n * Sets new signal state and satisfy waits if possible.\n *\n * @param Event\n *        Supplies a pointer to the event object.\n *\n * @param Increment\n *        Specifies an event priority boost value.\n *\n * @param Wait\n *        Specifies whether to call kernel wait routines or not.\n *\n * @return This routine returns the previous signal state of the event.\n *\n * @since NT 3.5\n */\nXTAPI\nLONG\nKE::Event::SetEvent(IN PKEVENT Event,\n                    IN KPRIORITY Increment,\n                    IN BOOLEAN Wait)\n{\n    UNIMPLEMENTED;\n\n    return 0;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/exports.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/exports.cc\n * DESCRIPTION:     C-compatible API wrappers for exported kernel functions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Acquires a specified queued spinlock.\n *\n * @param LockLevel\n *        Supplies the queued spinlock level.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTFASTCALL\nVOID\nKeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)\n{\n    KE::SpinLock::AcquireQueuedSpinLock(LockLevel);\n}\n\n/**\n * Acquires a kernel spin lock.\n *\n * @param SpinLock\n *        Supplies a pointer to the kernel spin lock.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTFASTCALL\nVOID\nKeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)\n{\n    KE::SpinLock::AcquireSpinLock(SpinLock);\n}\n\n/**\n * Looks for an unacquired system resource of the specified type and acquires it.\n *\n * @param ResourceType\n *        Supplies system resource type.\n *\n * @param ResourceHeader\n *        Specifies a memory area where a pointer to the system resource header will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nXTSTATUS\nKeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                        OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)\n{\n    return KE::SystemResources::AcquireResource(ResourceType, ResourceHeader);\n}\n\n/**\n * Cancels the timer.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @return This routine returns TRUE if the cancelled timer was set, or FALSE otherwise.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nBOOLEAN\nKeCancelTimer(IN PKTIMER Timer)\n{\n    return KE::Timer::CancelTimer(Timer);\n}\n\n/**\n * Gets the current running level of the current processor.\n *\n * @return This routine returns the current running level.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTFASTCALL\nKRUNLEVEL\nKeGetCurrentRunLevel(VOID)\n{\n    return KE::RunLevel::GetCurrentRunLevel();\n}\n\n/**\n * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership.\n *\n * @param ResourceType\n *        Supplies system resource type.\n *\n * @param ResourceHeader\n *        Specifies a memory area where a pointer to the system resource header will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nXTSTATUS\nKeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                    OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)\n{\n    return KE::SystemResources::GetResource(ResourceType, ResourceHeader);\n}\n\n/**\n * Reads the current signal state of the given timer.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @return This routine returns TRUE if the timer is set, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nBOOLEAN\nKeGetTimerState(IN PKTIMER Timer)\n{\n    return KE::Timer::GetState(Timer);\n}\n\n/**\n * Initializes an APC object.\n *\n * @param Apc\n *        Supplies a pointer to the APC object.\n *\n * @param Thread\n *        Supplies a pointer to the thread object.\n *\n * @param Environment\n *        Specifies an environment in which the APC will run.\n *\n * @param KernelRoutine\n *        Supplies a pointer to routine called at APC_LEVEL.\n *\n * @param RundownRoutine\n *        Supplies a pointer to routine called on thread exit.\n *\n * @param NormalRoutine\n *        Supplies a pointer to routine called at IRQL 0.\n *\n * @param ApcMode\n *        Specifies processor mode, in which NormalRoutine gets called.\n *\n * @param Context\n *        Supplies a pointer to memory area containing data passed to NormalRoutine.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nKeInitializeApc(IN PKAPC Apc,\n                IN PKTHREAD Thread,\n                IN KAPC_ENVIRONMENT Environment,\n                IN PKKERNEL_ROUTINE KernelRoutine,\n                IN PKRUNDOWN_ROUTINE RundownRoutine,\n                IN PKNORMAL_ROUTINE NormalRoutine,\n                IN KPROCESSOR_MODE ApcMode,\n                IN PVOID Context)\n{\n    KE::Apc::InitializeApc(Apc, Thread, Environment, KernelRoutine, RundownRoutine, NormalRoutine, ApcMode, Context);\n\n}\n\n/**\n * Initializes Deferred Procedure Call (DPC) object.\n *\n * @param Dpc\n *        Supplies a pointer to the DPC being initialized.\n *\n * @param DpcRoutine\n *        Supplies a pointer to the DPC routine being called on object removal.\n *\n * @param DpcContext\n *        Supplies a pointer to memory area containing context data for DPC routine.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nKeInitializeDpc(IN PKDPC Dpc,\n                IN PKDEFERRED_ROUTINE DpcRoutine,\n                IN PVOID DpcContext)\n{\n    KE::Dpc::InitializeDpc(Dpc, DpcRoutine, DpcContext);\n\n}\n\n/**\n * Initializes Deferred Procedure Call (DPC) object.\n *\n * @param Dpc\n *        Supplies a pointer to the DPC being initialized.\n *\n * @param DpcRoutine\n *        Supplies a pointer to the DPC routine being called on object removal.\n *\n * @param DpcContext\n *        Supplies a pointer to memory area containing context data for DPC routine.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.2\n */\nXTCLINK\nXTAPI\nVOID\nKeInitializeThreadedDpc(IN PKDPC Dpc,\n                        IN PKDEFERRED_ROUTINE DpcRoutine,\n                        IN PVOID DpcContext)\n{\n    KE::Dpc::InitializeThreadedDpc(Dpc, DpcRoutine, DpcContext);\n}\n\n/**\n * Initializes an extended kernel timer.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @param Type\n *        Supplies the type of the timer.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nKeInitializeTimer(OUT PKTIMER Timer,\n                  IN KTIMER_TYPE Type)\n{\n    KE::Timer::InitializeTimer(Timer, Type);\n}\n\n/**\n * Initializes a kernel semaphore object.\n *\n * @param Semaphore\n *        Supplies a pointer to a semaphore object.\n *\n * @param Count\n *        Specifies the initial count value of the semaphore.\n *\n * @param Limit\n *        Specifies a maximum count value of the semaphore.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nKeInitializeSemaphore(IN PKSEMAPHORE Semaphore,\n                      IN LONG Count,\n                      IN LONG Limit)\n{\n    KE::Semaphore::InitializeSemaphore(Semaphore, Count, Limit);\n}\n\n/**\n * Initializes a kernel spinlock object.\n *\n * @param SpinLock\n *        Supplies a pointer to a kernel spin lock.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nKeInitializeSpinLock(IN PKSPIN_LOCK SpinLock)\n{\n    KE::SpinLock::InitializeSpinLock(SpinLock);\n}\n\n/**\n * Lowers the running level of the current processor.\n *\n * @param RunLevel\n *        Supplies the new running level to lower to.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTFASTCALL\nVOID\nKeLowerRunLevel(KRUNLEVEL RunLevel)\n{\n    KE::RunLevel::LowerRunLevel(RunLevel);\n}\n\n/**\n * Raises the running level of the current processor.\n *\n * @param RunLevel\n *        Supplies the new running level to raise to.\n *\n * @return This routine returns the old running level.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTFASTCALL\nKRUNLEVEL\nKeRaiseRunLevel(KRUNLEVEL RunLevel)\n{\n    return KE::RunLevel::RaiseRunLevel(RunLevel);\n}\n\n/**\n * Reads semaphore's current signal state.\n *\n * @param Semaphore\n *        Supplies a pointer to a semaphore object.\n *\n * @return This routine returns the current signal state of the semaphore.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLONG\nKeReadSemaphoreState(IN PKSEMAPHORE Semaphore)\n{\n    return KE::Semaphore::ReadState(Semaphore);\n}\n\n/**\n * Releases a queued spinlock.\n *\n * @param LockLevel\n *        Supplies the queued spinlock level.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTFASTCALL\nVOID\nKeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)\n{\n    KE::SpinLock::ReleaseQueuedSpinLock(LockLevel);\n}\n\n/**\n * Releases a semaphore.\n *\n * @param Semaphore\n *        Supplies a pointer to a semaphore object.\n *\n * @param Increment\n *        Specifies the priority increment value of the semaphore.\n *\n * @param Adjustment\n *        Specifies adjustment value added to the semaphore's initial count value.\n *\n * @param Wait\n *        Determines whether release of the semaphore will be followed by a kernel wait routine call or not.\n *\n * @return This routine returns a previous signal state of the semaphore.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nLONG\nKeReleaseSemaphore(IN PKSEMAPHORE Semaphore,\n                   IN KPRIORITY Increment,\n                   IN LONG Adjustment,\n                   IN BOOLEAN Wait)\n{\n    return KE::Semaphore::ReleaseSemaphore(Semaphore, Increment, Adjustment, Wait);\n}\n\n/**\n * Releases a kernel spin lock.\n *\n * @param SpinLock\n *        Supplies a pointer to the kernel spin lock.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTFASTCALL\nVOID\nKeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)\n{\n    KE::SpinLock::ReleaseSpinLock(SpinLock);\n}\n\n/**\n * Releases system resource.\n *\n * @param ResourceHeader\n *        Specifies a pointer to the system resource header.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nKeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)\n{\n    KE::SystemResources::ReleaseResource(ResourceHeader);\n}\n\n/**\n * Sets the target processor number for DPC.\n *\n * @param Dpc\n *        Supplies a pointer to the DPC object.\n *\n * @param Number\n *        Supplies the target processor number.\n *\n * @return This routine does not return any value.\n *\n * @since NT 4.0\n */\nXTCLINK\nXTAPI\nVOID\nKeSetTargetProcessorDpc(IN PKDPC Dpc,\n                        IN CCHAR Number)\n{\n    KE::Dpc::SetTargetProcessor(Dpc, Number);\n}\n\n/**\n * Sets the maximum and minimum time increment values in 100ns units.\n *\n * @param MaxIncrement\n *        Supplies the maximum time increment.\n *\n * @param MinIncrement\n *        Supplies the minimum time increment.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nKeSetTimeIncrement(IN ULONG MaxIncrement,\n                   IN ULONG MinIncrement)\n{\n    KE::SystemTime::SetTimeIncrement(MaxIncrement, MinIncrement);\n}\n\n/**\n * Sets the supplied timer to expire at the specified time.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @param DueTime\n *        Supplies the time at which the timer should expire (both absolute and relative times are supported).\n *\n * @param Period\n *        Supplies the timer period.\n *\n * @param Dpc\n *        Supplies a pointer to a Deferred Procedure Call (DPC) object.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nKeSetTimer(IN PKTIMER Timer,\n           IN LARGE_INTEGER DueTime,\n           IN LONG Period,\n           IN PKDPC Dpc)\n{\n    KE::Timer::SetTimer(Timer, DueTime, Period, Dpc);\n}\n\n/**\n * Decrements the DPC call barier.\n *\n * @param SystemArgument\n *        Supplies an address of the DPC call barrier.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.2\n */\nXTCLINK\nXTAPI\nVOID\nKeSignalCallDpcDone(IN PVOID SystemArgument)\n{\n    KE::Dpc::SignalCallDone(SystemArgument);\n}\n\n/**\n * Decrements the DPC call reverse barier.\n *\n * @param SystemArgument\n *        Supplies an address of the DPC call barrier.\n *\n * @return This routine returns TRUE if just one processor is waiting on the barrier, FALSE if more.\n *\n * @since NT 5.2\n */\nXTCLINK\nXTAPI\nBOOLEAN\nKeSignalCallDpcSynchronize(IN PVOID SystemArgument)\n{\n    return KE::Dpc::SignalCallSynchronize(SystemArgument);\n}\n"
  },
  {
    "path": "xtoskrnl/ke/i686/dispatch.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/i686/dispatch.cc\n * DESCRIPTION:     Kernel Thread Dispatcher\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Entry point for thread context switching.\n *\n * @param CurrentThread\n *        Pointer to the KTHREAD structure of the current thread being suspended.\n *\n * @param RunLevel\n *        Supplies the running level at which the wait was initiated.\n *\n * @return This routine returns TRUE if a kernel APC is pending and can be delivered, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nKE::Dispatcher::SwitchContext(IN PKTHREAD CurrentThread,\n                              IN KRUNLEVEL RunLevel)\n{\n    BOOLEAN PendingApc;\n\n    /* Save registers to the exception frame and invoke the stack switch routine */\n    __asm__ volatile(\"subl %[ExFrameSize], %%esp\\n\"\n                     \"movl %%esi, %c[ExEsi](%%esp)\\n\"\n                     \"movl %%edi, %c[ExEdi](%%esp)\\n\"\n                     \"movl %%ebx, %c[ExEbx](%%esp)\\n\"\n                     \"movl %%ebp, %c[ExEbp](%%esp)\\n\"\n                     \"call %P[SwitchRoutine]\\n\"\n                     \"movl %c[ExEbp](%%esp), %%ebp\\n\"\n                     \"movl %c[ExEbx](%%esp), %%ebx\\n\"\n                     \"movl %c[ExEdi](%%esp), %%edi\\n\"\n                     \"movl %c[ExEsi](%%esp), %%esi\\n\"\n                     \"addl %[ExFrameSize], %%esp\\n\"\n                     : \"=a\" (PendingApc)\n                     : \"c\" (CurrentThread),\n                       \"d\" (RunLevel),\n                       [ExFrameSize] \"i\" (sizeof(KEXCEPTION_FRAME) - 4),\n                       [ExEbp] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Ebp)),\n                       [ExEbx] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Ebx)),\n                       [ExEdi] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Edi)),\n                       [ExEsi] \"i\" (FIELD_OFFSET(KEXCEPTION_FRAME, Esi)),\n                       [SwitchRoutine] \"i\" (SwitchThreadStack)\n                     : \"cc\", \"memory\");\n\n    /* Return the APC status */\n    return PendingApc;\n}\n\n/**\n * Switches context from current thread to the new thread.\n *\n * @param CurrentThread\n *        Pointer to the KTHREAD structure of the current thread being suspended.\n *\n * @param ApcBypass\n *        Indicates whether the APC delivery should be bypassed.\n *\n * @return This routine returns TRUE if a kernel APC is pending and can be delivered, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nKE::Dispatcher::SwitchThreadContext(IN PKTHREAD CurrentThread,\n                                    IN BOOLEAN ApcBypass)\n{\n    UNIMPLEMENTED;\n\n    return FALSE;\n}\n\n/**\n * Switches the thread stack and performs necessary operations to prepare for context switching.\n *\n * @param CurrentThread\n *        Pointer to the KTHREAD structure of the current thread being suspended.\n *\n * @param RunLevel\n *        Supplies the running level at which the wait was initiated.\n *\n * @return This routine returns TRUE if a kernel APC is pending and can be delivered, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nKE::Dispatcher::SwitchThreadStack(IN PKTHREAD CurrentThread,\n                                  IN KRUNLEVEL RunLevel)\n{\n    BOOLEAN PendingApc;\n\n    /* Save old state, synchronize with CPUs, switch stack and call the switch routine */\n    __asm__ volatile(\"subl %[FrameSize], %%esp\\n\"\n                     \"movl %%fs:%c[PrcbcCurrentThread], %%ebx\\n\"\n                     \"BusyLoop:\\n\"\n                     \"cmpb $0, %c[ThrdSwapBusy](%%ebx)\\n\"\n                     \"je ExitLoop\\n\"\n                     \"pause\\n\"\n                     \"jmp BusyLoop\\n\"\n                     \"ExitLoop:\\n\"\n                     \"movl %%fs:%c[ThrdInfoExceptions], %%eax\\n\"\n                     \"movl %%eax, %c[SwExceptionList](%%esp)\\n\"\n                     \"movb %%dl, %c[SwApcBypass](%%esp)\\n\"\n                     \"movl %%esp, %c[ThrdStack](%%ecx)\\n\"\n                     \"movl %c[ThrdStack](%%ebx), %%esp\\n\"\n                     \"movzbl %c[SwApcBypass](%%esp), %%edx\\n\"\n                     \"call %P[SwitchRoutine]\\n\"\n                     \"addl %[FrameSize], %%esp\\n\"\n                     : \"=a\" (PendingApc)\n                     : \"c\" (CurrentThread),\n                       \"d\" (RunLevel),\n                       [FrameSize] \"i\" (sizeof(KSWITCH_FRAME) - 4),\n                       [PrcbcCurrentThread] \"i\" (FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)),\n                       [SwApcBypass] \"i\" (FIELD_OFFSET(KSWITCH_FRAME, ApcBypassDisabled)),\n                       [SwExceptionList] \"i\" (FIELD_OFFSET(KSWITCH_FRAME, ExceptionList)),\n                       [SwitchRoutine] \"i\" (SwitchThreadContext),\n                       [ThrdInfoExceptions] \"i\" (FIELD_OFFSET(THREAD_INFORMATION_BLOCK, ExceptionList)),\n                       [ThrdStack] \"i\" (FIELD_OFFSET(KTHREAD, KernelStack)),\n                       [ThrdSwapBusy] \"i\" (FIELD_OFFSET(KTHREAD, SwapBusy))\n                     : \"cc\", \"memory\");\n\n    /* Return the APC status */\n    return PendingApc;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/i686/krnlinit.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/i686/krnlinit.cc\n * DESCRIPTION:     CPU architecture specific kernel initialization\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Bootstraps an Application Processor (AP) into the active kernel. This routine is executed exclusively by secondary\n * processors after being awakened by the BSP. It is called directly from the startup trampoline.\n *\n * @param StartBlock\n *        Supplies a pointer to the processor start block containing initialization information provided by the kernel.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)\n{\n    PKPROCESSOR_BLOCK ProcessorBlock;\n\n    /* Initialize application CPU */\n    AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);\n\n    /* Initialize processor */\n    HL::Cpu::InitializeProcessor();\n\n    /* Raise to HIGH runlevel */\n    KE::RunLevel::RaiseRunLevel(HIGH_LEVEL);\n\n    /* Mark processor as started */\n    StartBlock->Started = TRUE;\n\n    /* Get current processor block */\n    ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();\n\n    /* Enter infinite loop */\n    DebugPrint(L\"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\\n\",\n               ProcessorBlock->CpuNumber);\n    KE::Crash::HaltSystem();\n}\n\n/**\n * Bootstraps the XT kernel and global subsystems. This routine is executed exclusively by the Bootstrap Processor\n * and it is called immediately after switching to the kernel boot stack.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::BootstrapKernel(VOID)\n{\n    PKPROCESSOR_CONTROL_BLOCK Prcb;\n    ULONG_PTR PageDirectory[2];\n    PKPROCESS CurrentProcess;\n    PKTHREAD CurrentThread;\n\n    /* Get processor control block and current thread */\n    Prcb = KE::Processor::GetCurrentProcessorControlBlock();\n    CurrentThread = KE::Processor::GetCurrentThread();\n\n    /* Get current process */\n    CurrentProcess = CurrentThread->ApcState.Process;\n\n    /* Initialize CPU power state structures */\n    PO::Idle::InitializeProcessorIdleState(Prcb);\n\n    /* Save processor state */\n    KE::Processor::SaveProcessorState(&Prcb->ProcessorState);\n\n    /* Initialize spin locks */\n    KE::SpinLock::InitializeAllLocks();\n    KE::SpinLock::InitializeLockQueues();\n\n    /* Lower to APC runlevel */\n    KE::RunLevel::LowerRunLevel(APC_LEVEL);\n\n    /* Initialize XTOS kernel */\n    InitializeKernel();\n\n    /* Initialize Idle process */\n    PageDirectory[0] = 0;\n    PageDirectory[1] = 0;\n    KE::KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);\n    CurrentProcess->Quantum = MAXCHAR;\n\n    /* Initialize Idle thread */\n    KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,\n                                  NULLPTR, NULLPTR, AR::ProcessorSupport::GetBootStack(), TRUE);\n    CurrentThread->NextProcessor = Prcb->CpuNumber;\n    CurrentThread->Priority = THREAD_HIGH_PRIORITY;\n    CurrentThread->State = Running;\n    CurrentThread->Affinity = (ULONG_PTR)1 << Prcb->CpuNumber;\n    CurrentThread->WaitRunLevel = DISPATCH_LEVEL;\n    CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;\n\n    /* Initialize Memory Manager */\n    MM::Manager::InitializeMemoryManager();\n\n    /* Enable shadow buffer for framebuffer */\n    HL::FrameBuffer::EnableShadowBuffer();\n\n    /* Start all application processors */\n    KE::Processor::InitializeProcessorBlocks();\n    HL::Cpu::StartAllProcessors();\n\n    /* Enter infinite loop */\n    DebugPrint(L\"KernelInit::BootstrapKernel() finished. Entering infinite loop.\\n\");\n    KE::Crash::HaltSystem();\n}\n\n/**\n * This routine initializes XT kernel.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::InitializeKernel(VOID)\n{\n    XTSTATUS Status;\n\n    /* Initialize hardware layer subsystem */\n    Status = HL::Init::InitializeSystem();\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Hardware layer initialization failed, kernel panic */\n        DebugPrint(L\"Failed to initialize hardware layer subsystem!\\n\");\n        KE::Crash::Panic(0);\n    }\n}\n\n/**\n * Performs architecture-specific initialization for the kernel executive.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::InitializeMachine(VOID)\n{\n    /* Re-enable IDE interrupts */\n    HL::IoPort::WritePort8(0x376, 0);\n    HL::IoPort::WritePort8(0x3F6, 0);\n\n    /* Initialize frame buffer */\n    HL::FrameBuffer::InitializeFrameBuffer();\n\n    /* Initialize page map support */\n    MM::Paging::InitializePageMapSupport();\n\n    /* Initialize Kernel Shared Data (KSD) */\n    KE::SharedData::InitializeKernelSharedData();\n\n    /* Initialize processor */\n    HL::Cpu::InitializeProcessor();\n}\n\n/**\n * Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KernelInit::SwitchBootStack(VOID)\n{\n    ULONG_PTR Stack;\n    PVOID StartKernel;\n\n    /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */\n    Stack = ((ULONG_PTR)AR::ProcessorSupport::GetBootStack() & ~(STACK_ALIGNMENT - 1));\n\n    /* Get address of KernelInit::StartKernel() */\n    StartKernel = (PVOID)KE::KernelInit::BootstrapKernel;\n\n    /* Discard old stack frame, switch stack, make space for NPX and jump to KernelInit::StartKernel() */\n    __asm__ volatile(\"movl %[Stack], %%esp\\n\"\n                     \"subl %[TotalSize], %%esp\\n\"\n                     \"xorl %%ebp, %%ebp\\n\"\n                     \"pushl %[Cr0Value]\\n\"\n                     \"jmp *%[TargetRoutine]\\n\"\n                     :\n                     : [Cr0Value] \"i\" (CR0_EM | CR0_MP | CR0_TS),\n                       [Stack] \"r\" (Stack),\n                       [TargetRoutine] \"r\" (StartKernel),\n                       [TotalSize] \"i\" (KTRAP_FRAME_ALIGN + KTRAP_FRAME_SIZE + NPX_FRAME_SIZE + KRETURN_ADDRESS_SIZE)\n                     : \"ebp\", \"esp\", \"memory\");\n}\n"
  },
  {
    "path": "xtoskrnl/ke/i686/kthread.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/i686/kthread.cc\n * DESCRIPTION:     I686 thread manipulation support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Initializes CPU architecture dependent context of a thread.\n *\n * @param Thread\n *        Supplies a pointer to the thread being initialized.\n *\n * @param SystemRoutine\n *        Supplies a pointer to the routine called during first scheduling.\n *\n * @param StartRoutine\n *        Supplies a pointer to the routine called during thread startup.\n *\n * @param StartContext\n *        Supplies a pointer to a context data that will be passed to start routine.\n *\n * @param ContextRecord\n *        Supplies a pointer to a context record which stores the initial state of the user mode thread.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KThread::InitializeThreadContext(IN PKTHREAD Thread,\n                                     IN PKSYSTEM_ROUTINE SystemRoutine,\n                                     IN PKSTART_ROUTINE StartRoutine,\n                                     IN PVOID StartContext,\n                                     IN PCONTEXT ContextRecord)\n{\n    PKTHREAD_INIT_FRAME ThreadFrame;\n    PFX_SAVE_FORMAT FxSaveFormat;\n\n    /* Set initial thread frame */\n    ThreadFrame = (PKTHREAD_INIT_FRAME)((ULONG_PTR)Thread->InitialStack - sizeof(KTHREAD_INIT_FRAME));\n\n    /* Fill floating point save area with zeroes */\n    RTL::Memory::ZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA));\n\n    /* Check if context provided for this thread */\n    if(ContextRecord)\n    {\n        /* User mode thread needs further initialization, this is not completed */\n        UNIMPLEMENTED;\n\n        /* Fill trap frame with zeroes */\n        RTL::Memory::ZeroMemory(&ThreadFrame->TrapFrame, sizeof(KTRAP_FRAME));\n\n        /* Disable debug registers and enable context registers */\n        ContextRecord->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS | CONTEXT_CONTROL;\n\n        /* This is user mode thread */\n        ThreadFrame->StartFrame.UserMode = TRUE;\n        Thread->PreviousMode = UserMode;\n\n        /* Disable coprocessor floating point state */\n        Thread->NpxState = NPX_STATE_UNLOADED;\n        Thread->Header.NpxIrql = PASSIVE_LEVEL;\n\n        /* Set initial floating point state */\n        FxSaveFormat = (PFX_SAVE_FORMAT)ContextRecord->ExtendedRegisters;\n        FxSaveFormat->ControlWord = 0x27F;\n        FxSaveFormat->MxCsr = 0x1F80;\n        ContextRecord->FloatSave.Cr0NpxState = 0;\n        ThreadFrame->NpxFrame.Cr0NpxState = 0;\n        ThreadFrame->NpxFrame.NpxSavedCpu = 0;\n\n        /* Clear DR6 and DR7 registers */\n        ThreadFrame->TrapFrame.Dr6 = 0;\n        ThreadFrame->TrapFrame.Dr7 = 0;\n\n        /* Set DS, ES and SS segments for user mode */\n        ThreadFrame->TrapFrame.SegDs |= RPL_MASK;\n        ThreadFrame->TrapFrame.SegEs |= RPL_MASK;\n        ThreadFrame->TrapFrame.SegSs |= RPL_MASK;\n\n        /* Set user mode thread in the trap frame */\n        ThreadFrame->TrapFrame.PreviousMode = UserMode;\n    }\n    else\n    {\n        /* This is kernel mode thread */\n        ThreadFrame->StartFrame.UserMode = FALSE;\n        Thread->PreviousMode = KernelMode;\n\n        /* Disable coprocessor floating point state */\n        Thread->NpxState = NPX_STATE_UNLOADED;\n\n        /* Set initial floating point state */\n        ThreadFrame->NpxFrame.FxArea.ControlWord = 0x27F;\n        ThreadFrame->NpxFrame.FxArea.MxCsr = 0x1F80;\n    }\n\n    /* Initialize thread startup information */\n    ThreadFrame->StartFrame.StartContext = StartContext;\n    ThreadFrame->StartFrame.StartRoutine = StartRoutine;\n    ThreadFrame->StartFrame.SystemRoutine = SystemRoutine;\n\n    /* Initialize switch frame */\n    ThreadFrame->SwitchFrame.ApcBypassDisabled = TRUE;\n    ThreadFrame->SwitchFrame.ExceptionList = (PEXCEPTION_REGISTRATION_RECORD) - 1;\n\n    /* Set thread stack */\n    Thread->KernelStack = &ThreadFrame->SwitchFrame;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/i686/proc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/i686/proc.c\n * DESCRIPTION:     I686 processor-related functionality for the kernel\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Gets the processor block for the currently executing processor.\n *\n * @return This routine returns the current processor block read from the FS register.\n *\n * @since XT 1.0\n */\nXTAPI\nPKPROCESSOR_BLOCK\nKE::Processor::GetCurrentProcessorBlock(VOID)\n{\n    /* Get processor block from FS register */\n    return (PKPROCESSOR_BLOCK)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));\n}\n\n/**\n * Gets the processor control block for the currently executing processor.\n *\n * @return This routine returns the current processor control block read from the FS register.\n *\n * @since XT 1.0\n */\nXTAPI\nPKPROCESSOR_CONTROL_BLOCK\nKE::Processor::GetCurrentProcessorControlBlock(VOID)\n{\n    return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));\n}\n\n/**\n * Gets the number of the currently executing processor.\n *\n * @return This routine returns the zero-indexed processor number.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nKE::Processor::GetCurrentProcessorNumber(VOID)\n{\n    return (ULONG)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));\n}\n\n/**\n * Gets the current thread running on the currently executing processor.\n *\n * @return This routine returns the address of the current thread object.\n *\n * @since NT 3.5\n */\nXTAPI\nPKTHREAD\nKE::Processor::GetCurrentThread(VOID)\n{\n    return (PKTHREAD)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));\n}\n\n/**\n * Gets the processor block for the specified processor number.\n *\n * @param CpuNumber\n *        Supplies the zero-indexed processor number.\n *\n * @return This routine returns a pointer to the processor block, or NULLPTR if invalid.\n *\n * @since XT 1.0\n */\nXTAPI\nPKPROCESSOR_BLOCK\nKE::Processor::GetProcessorBlock(IN ULONG CpuNumber)\n{\n    /* Check if the requested CPU number is within dynamic bounds */\n    if(CpuNumber >= InstalledCpus || ProcessorBlocks == NULLPTR || ProcessorBlocks[CpuNumber] == NULLPTR)\n    {\n        /* Invalid CPU number, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Return requested processor block */\n    return ProcessorBlocks[CpuNumber];\n}\n\n/**\n * Initializes the global processor structures by allocating an array of processor block pointers.\n *\n * @return This routine returns a status code indicating the success or failure of the allocation.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKE::Processor::InitializeProcessorBlocks()\n{\n    PACPI_SYSTEM_INFO SystemInfo;\n    XTSTATUS Status;\n\n    /* Save number of CPUs installed */\n    HL::Acpi::GetSystemInformation(&SystemInfo);\n    InstalledCpus = SystemInfo->CpuCount;\n\n    /* Allocate an array of pointers */\n    Status = MM::Allocator::AllocatePool(NonPagedPool,\n                                         InstalledCpus * sizeof(PKPROCESSOR_BLOCK),\n                                         (PVOID*)&ProcessorBlocks);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to allocate memory, return error */\n        return Status;\n    }\n\n    /* Zero the array initially */\n    RTL::Memory::ZeroMemory(ProcessorBlocks, InstalledCpus * sizeof(PKPROCESSOR_BLOCK));\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Registers the hardware APIC ID for the currently executing processor.\n *\n * @param ApicId\n *        Supplies the hardware APIC ID to register in the processor block.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Processor::RegisterHardwareId(IN ULONG HardwareId)\n{\n    PKPROCESSOR_BLOCK CurrentBlock;\n\n    /* Retrieve the processor block for the executing core */\n    CurrentBlock = GetCurrentProcessorBlock();\n    if(CurrentBlock != NULLPTR)\n    {\n        /* Register the hardware identifier for IPI targeting */\n        CurrentBlock->HardwareId = HardwareId;\n    }\n}\n\n/**\n * Registers or deregisters a processor block in the global CPU table.\n *\n * @param CpuNumber\n *        Specifies the logical processor number.\n *\n * @param ProcessorBlock\n *        Supplies a pointer to the processor block. \n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Processor::RegisterProcessorBlock(ULONG CpuNumber,\n                                      PKPROCESSOR_BLOCK ProcessorBlock)\n{\n    /* Check if the requested CPU number is within dynamic bounds */\n    if(ProcessorBlocks != NULLPTR && CpuNumber < InstalledCpus)\n    {\n        /* Register processor block */\n        ProcessorBlocks[CpuNumber] = ProcessorBlock;\n    }\n}\n\n/**\n * Saves the current processor state.\n *\n * @param State\n *        Supplies a pointer to the processor state structure.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState)\n{\n    /* Save CR registers */\n    CpuState->SpecialRegisters.Cr0 = AR::CpuFunctions::ReadControlRegister(0);\n    CpuState->SpecialRegisters.Cr2 = AR::CpuFunctions::ReadControlRegister(2);\n    CpuState->SpecialRegisters.Cr3 = AR::CpuFunctions::ReadControlRegister(3);\n    CpuState->SpecialRegisters.Cr4 = AR::CpuFunctions::ReadControlRegister(4);\n\n    /* Save DR registers */\n    CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunctions::ReadDebugRegister(0);\n    CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunctions::ReadDebugRegister(1);\n    CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunctions::ReadDebugRegister(2);\n    CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunctions::ReadDebugRegister(3);\n    CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunctions::ReadDebugRegister(6);\n    CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunctions::ReadDebugRegister(7);\n\n    /* Save GDT, IDT, LDT and TaskRegister */\n    AR::CpuFunctions::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);\n    AR::CpuFunctions::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);\n    AR::CpuFunctions::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);\n    AR::CpuFunctions::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);\n}\n"
  },
  {
    "path": "xtoskrnl/ke/kprocess.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/kprocess.cc\n * DESCRIPTION:     XT kernel process manipulation support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\nXTAPI\nPEPROCESS\nKE::KProcess::GetInitialProcess(VOID)\n{\n    return &InitialProcess;\n}\n\n/**\n * Initializes the process.\n *\n * @param Process\n *        Supplies a pointer to process that will be initialized.\n *\n * @param Priority\n *        Specifies the process priority.\n *\n * @param Affinity\n *        Specifies a process affinity designating processors on which process can run.\n *\n * @param DirectoryTable\n *        Supplies a pointer to the directory table.\n *\n * @param Alignment\n *        Specifies the exceptions alignment of the process.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nKE::KProcess::InitializeProcess(IN OUT PKPROCESS Process,\n                                IN KPRIORITY Priority,\n                                IN KAFFINITY Affinity,\n                                IN PULONG_PTR DirectoryTable,\n                                IN BOOLEAN Alignment)\n{\n    /* Initialize process dispatcher header */\n    Process->Header.Type = ProcessObject;\n\n    /* Initialize process wait list */\n    RtlInitializeListHead(&Process->Header.WaitListHead);\n\n    /* Initialize process list heads */\n    RtlInitializeListHead(&Process->ProfileListHead);\n    RtlInitializeListHead(&Process->ReadyListHead);\n    RtlInitializeListHead(&Process->ThreadListHead);\n\n    /* Set base process properties */\n    Process->BasePriority = Priority;\n    Process->Affinity = Affinity;\n    Process->AutoAlignment = Alignment;\n    Process->DirectoryTable[0] = DirectoryTable[0];\n    Process->DirectoryTable[1] = DirectoryTable[1];\n    Process->StackCount = MAXSHORT;\n\n    /* Set thread quantum */\n    Process->Quantum = THREAD_QUANTUM;\n\n    /* Set IOPM offset */\n    Process->IopmOffset = sizeof(KTSS);\n\n    /* Set initial process state */\n    Process->State = ProcessInMemory;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/krnlinit.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/krnlinit.cc\n * DESCRIPTION:     XT kernel initialization\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* Use routines from Kernel Library */\nusing namespace KE;\n\n/**\n * This routine starts up the XT kernel. It is called by boot loader.\n *\n * @param Parameters\n *        Supplies a pointer to memory area containing parameters passed to kernel by bootloader.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)\n{\n    /* Verify kernel and boot loader compatibility */\n    if(Parameters->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) ||\n       Parameters->BlockVersion != INITIALIZATION_BLOCK_VERSION ||\n       Parameters->ProtocolVersion != BOOT_PROTOCOL_VERSION)\n    {\n        /* Kernel and boot loader version mismatch */\n        KE::Crash::HaltSystem();\n    }\n\n    /* Save the kernel initialization block */\n    KE::BootInformation::InitializeInitializationBlock(Parameters);\n\n    /* Check if debugging enabled and if boot loader provided routine for debug printing */\n    if(DEBUG && KE::BootInformation::GetDebugPrint())\n    {\n        /* Use loader's provided DbgPrint() routine for early printing to serial console */\n        KD::DebugIo::SetPrintRoutine(KE::BootInformation::GetDebugPrint());\n        DebugPrint(L\"Initializing ExectOS v%d.%d for %s\\n\", XTOS_VERSION_MAJOR, XTOS_VERSION_MINOR, _ARCH_NAME);\n    }\n\n    /* Initialize boot CPU and set the unhandled interrupt routine */\n    AR::ProcessorSupport::InitializeProcessor(NULLPTR);\n    AR::Traps::SetUnhandledInterruptRoutine(HL::Irq::HandleUnexpectedInterrupt);\n\n    /* Initialize system resources */\n    KE::SystemResources::InitializeResources();\n\n    /* Check if debugging enabled */\n    if(DEBUG)\n    {\n        /* Initialize debug I/O */\n        KD::DebugIo::InitializeDebugIoProviders();\n    }\n\n    /* Announce kernel startup */\n    DebugPrint(L\"Starting ExectOS v%d.%d for %s (%s-%s-%s-%s / %s %s)\\n\",\n               XTOS_VERSION_MAJOR, XTOS_VERSION_MINOR, _ARCH_NAME, XTOS_VERSION_DATE,\n               XTOS_VERSION_BUILD, XTOS_VERSION_ARCH, XTOS_VERSION_HASH,\n               XTOS_COMPILER_NAME, XTOS_COMPILER_VERSION);\n\n    /* Architecture specific kernel initialization */\n    KE::KernelInit::InitializeMachine();\n\n    /* Raise to HIGH runlevel */\n    KE::RunLevel::RaiseRunLevel(HIGH_LEVEL);\n\n    /* Switch the boot stack and transfer control to the KepStartKernel() routine */\n    KE::KernelInit::SwitchBootStack();\n}\n"
  },
  {
    "path": "xtoskrnl/ke/kthread.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/kthread.cc\n * DESCRIPTION:     XT kernel thread manipulation support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\nXTAPI\nPETHREAD\nKE::KThread::GetInitialThread(VOID)\n{\n    return &InitialThread;\n}\n\n/**\n * Initializes the thread.\n *\n * @param Process\n *        Supplies a pointer to the process that owns the thread.\n *\n * @param Thread\n *        Supplies a pointer to thread that will be initialized.\n *\n * @param SystemRoutine\n *        Supplies a pointer to the routine called during first scheduling.\n *\n * @param StartRoutine\n *        Supplies a pointer to the routine called during thread startup.\n *\n * @param StartContext\n *        Supplies a pointer to a context data that will be passed to start routine.\n *\n * @param Context\n *        Supplies a pointer to the context frame containing state of the user mode thread.\n *\n * @param EnvironmentBlock\n *        Supplies a pointer to the environment block of the thread.\n *\n * @param Stack\n *        Supplies a pointer to the stack of the thread.\n *\n * @return This routine returns a status code.\n *\n * @since NT 3.5\n */\nXTAPI\nXTSTATUS\nKE::KThread::InitializeThread(IN PKPROCESS Process,\n                              IN OUT PKTHREAD Thread,\n                              IN PKSYSTEM_ROUTINE SystemRoutine,\n                              IN PKSTART_ROUTINE StartRoutine,\n                              IN PVOID StartContext,\n                              IN PCONTEXT Context,\n                              IN PVOID EnvironmentBlock,\n                              IN PVOID Stack,\n                              IN BOOLEAN RunThread)\n{\n    PKWAIT_BLOCK TimerWaitBlock;\n    BOOLEAN Allocation;\n    XTSTATUS Status;\n    ULONG Index;\n\n    /* No stack allocation was done yet */\n    Allocation = FALSE;\n\n    /* Initialize thread dispatcher header */\n    Thread->Header.Type = ThreadObject;\n    Thread->Header.SignalState = 0;\n\n    /* Initialize thread wait list */\n    RTL::LinkedList::InitializeListHead(&Thread->Header.WaitListHead);\n\n    /* Initialize thread mutant list head */\n    RTL::LinkedList::InitializeListHead(&Thread->MutantListHead);\n\n    /* Initialize the builtin wait blocks */\n    for(Index = 0; Index <= KTHREAD_WAIT_BLOCK; Index++)\n    {\n        Thread->WaitBlock[Index].Thread = Thread;\n    }\n\n    /* Initialize stack resident and stack swap */\n    Thread->AutoAlignment = Process->AutoAlignment;\n    Thread->StackResident = TRUE;\n    Thread->StackSwap = TRUE;\n    Thread->SwapBusy = FALSE;\n\n    /* Set priority adjustment reason */\n    Thread->AdjustReason = AdjustNone;\n\n    /* Initialize thread lock */\n    KE::SpinLock::InitializeSpinLock(&Thread->ThreadLock);\n\n    /* Initialize thread APC */\n    Thread->ApcStatePointer[0] = &Thread->ApcState;\n    Thread->ApcStatePointer[1] = &Thread->SavedApcState;\n    Thread->ApcQueueable = TRUE;\n    Thread->ApcState.Process = Process;\n    Thread->Process = Process;\n\n    /* Initialize APC list heads */\n    RTL::LinkedList::InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);\n    RTL::LinkedList::InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);\n\n    /* Initialize APC queue lock */\n    KE::SpinLock::InitializeSpinLock(&Thread->ApcQueueLock);\n\n    /* Initialize kernel-mode suspend APC */\n    KE::Apc::InitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, SuspendNop,\n                           SuspendRundown, SuspendThread, KernelMode, NULLPTR);\n\n    /* Initialize suspend semaphore */\n    KE::Semaphore::InitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);\n\n    /* Initialize the builtin timer */\n    KE::Timer::InitializeTimer(&Thread->Timer, NotificationTimer);\n    TimerWaitBlock = &Thread->WaitBlock[KTIMER_WAIT_BLOCK];\n    TimerWaitBlock->Object = &Thread->Timer;\n    TimerWaitBlock->WaitKey = STATUS_TIMEOUT;\n    TimerWaitBlock->WaitType = WaitAny;\n    TimerWaitBlock->WaitListEntry.Flink = &(&Thread->Timer)->Header.WaitListHead;\n    TimerWaitBlock->WaitListEntry.Blink = &(&Thread->Timer)->Header.WaitListHead;\n\n    /* Initialize Thread Environment Block*/\n    Thread->EnvironmentBlock = (PTHREAD_ENVIRONMENT_BLOCK)EnvironmentBlock;\n\n    /* Make sure there is a valid stack available */\n    if(!Stack)\n    {\n        /* Allocate new stack */\n        Status = MM::KernelPool::AllocateKernelStack(&Stack, KERNEL_STACK_SIZE);\n        if(Status != STATUS_SUCCESS || !Stack)\n        {\n            /* Stack allocation failed */\n            return STATUS_INSUFFICIENT_RESOURCES;\n        }\n\n        /* Mark allocation as successful */\n        Allocation = TRUE;\n    }\n\n    Thread->InitialStack = Stack;\n    Thread->StackBase = Stack;\n    Thread->StackLimit = (PVOID)((ULONG_PTR)Stack - KERNEL_STACK_SIZE);\n\n    __try\n    {\n        /* Initialize thread context */\n        InitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context);\n    }\n    __except(EXCEPTION_EXECUTE_HANDLER)\n    {\n        /* Failed to initialize thread context, check stack allocation */\n        if(Allocation)\n        {\n            /* Deallocate stack */\n            MM::KernelPool::FreeKernelStack(Stack, FALSE);\n            Thread->InitialStack = NULLPTR;\n            Thread->StackBase = NULLPTR;\n        }\n\n        /* Thread initialization failed */\n        return STATUS_UNSUCCESSFUL;\n    }\n\n    /* Mark thread as initialized and run it */\n    Thread->State = Initialized;\n\n    /* Check if thread should be started */\n    if(RunThread)\n    {\n        /* Start thread */\n        StartThread(Thread);\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Starts the thread.\n *\n * @param Thread\n *        Supplies a pointer to the thread.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTAPI\nVOID\nKE::KThread::StartThread(IN PKTHREAD Thread)\n{\n    UNIMPLEMENTED;\n}\n\n/**\n * Suspend APC-built thread NOP routine. It takes no actions.\n *\n * @param Apc\n *        Supplies a pointer to the APC object.\n *\n * @param NormalRoutine\n *        Supplies a pointer to the normal routine set during the APC initialization. Unused by this routine.\n *\n * @param NormalContext\n *        Supplies a pointer a context data set during the APC initialization. Unused by this routine.\n *\n * @param SystemArgument1\n *        Supplies a pointer to an unused system argument.\n *\n * @param SystemArgument2\n *        Supplies a pointer to an unused system argument.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KThread::SuspendNop(IN PKAPC Apc,\n                        IN OUT PKNORMAL_ROUTINE *NormalRoutine,\n                        IN OUT PVOID *NormalContext,\n                        IN OUT PVOID *SystemArgument1,\n                        IN OUT PVOID *SystemArgument2)\n{\n    /* No action here */\n}\n\n/**\n * Suspend APC-built thread rundown routine. It takes no actions.\n *\n * @param Apc\n *        Supplies a pointer to the APC object.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KThread::SuspendRundown(IN PKAPC Apc)\n{\n    /* No action here */\n}\n\n/**\n * Suspends thread execution by waiting on the thread's semaphore.\n *\n * @param NormalContext\n *        Supplies a pointer a context data set during the APC initialization. Unused by this routine.\n *\n * @param SystemArgument1\n *        Supplies a pointer to an unused system argument.\n *\n * @param SystemArgument2\n *        Supplies a pointer to an unused system argument.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::KThread::SuspendThread(IN PVOID NormalContext,\n                           IN PVOID SystemArgument1,\n                           IN PVOID SystemArgument2)\n{\n    UNIMPLEMENTED;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/kubsan.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/kubsan.cc\n * DESCRIPTION:     Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Checks whether handled UBSAN error should be reported.\n *\n * @param Location\n *        Supplies a pointer to the UBSAN location descriptor.\n *\n * @return This routine returns TRUE if UBSAN error should be reported, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nKE::KUbsan::CheckReport(PKUBSAN_SOURCE_LOCATION Location)\n{\n    /* Make sure, this error should be reported */\n    return !ActiveFrame;\n}\n\n/**\n * Enters UBSAN frame and marks it as active.\n *\n * @param Location\n *        Supplies a pointer to the UBSAN location descriptor.\n *\n * @param Reason\n *        Supplies a pointer to the reason of the UBSAN failure.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::EnterFrame(PKUBSAN_SOURCE_LOCATION Location,\n                       PCCHAR Reason)\n{\n    /* Enter UBSAN frame */\n    ActiveFrame = TRUE;\n\n    /* Print generic error message to debug console */\n    DebugPrint(L\"UBSAN: Undefined behavior (%s) in %s:%d:%d\\n\",\n               Reason, Location->FileName, Location->Line, Location->Column);\n}\n\n/**\n * Gets signed value from UBSAN.\n *\n * @param Type\n *        Supplies a pointer to the UBSAN type descriptor.\n *\n * @param Value\n *        Supplies a pointer to the UBSAN value.\n *\n * @return This routine returns a 64-bit signed integer.\n *\n * @since XT 1.0\n */\nXTCDECL\nLONGLONG\nKE::KUbsan::GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,\n                           PVOID Value)\n{\n    ULONG BitWidth, ExtraBits;\n    ULONG_PTR LongValue;\n\n    /* Calculate bit width of the type */\n    BitWidth = 1 << (Type->TypeInfo >> 1);\n\n    /* Check if inline integer */\n    if(BitWidth <= sizeof(ULONG) * 8)\n    {\n        /* Calculate extra bits and return value */\n        ExtraBits = sizeof(LONGLONG) * 8 - BitWidth;\n        LongValue = (ULONG_PTR)Value;\n        return ((LONGLONG)LongValue) << ExtraBits >> ExtraBits;\n    }\n\n    /* Return 64-bit integer */\n    return *(PLONGLONG)Value;\n}\n\n/**\n * Gets a string representation of the UBSAN type kind.\n *\n * @param TypeCheckKind\n *        Supplies a UBSAN type kind as a numeric value.\n *\n * @return This routine returns a string representation of the UBSAN type.\n *\n * @since XT 1.0\n */\nXTCDECL\nPCCHAR\nKE::KUbsan::GetTypeKind(UCHAR TypeCheckKind)\n{\n    /* Get type kind name */\n    switch(TypeCheckKind)\n    {\n        case 0:\n            return \"Load of\";\n        case 1:\n            return \"Store to\";\n        case 2:\n            return \"Reference binding to\";\n        case 3:\n            return \"Member access within\";\n        case 4:\n            return \"Member call on\";\n        case 5:\n            return \"Constructor call on\";\n        case 6:\n            return \"Downcast of\";\n        case 7:\n            return \"Downcast of\";\n        case 8:\n            return \"Upcast of\";\n        case 9:\n            return \"Cast to virtual base of\";\n        default:\n            return \"Unrecognized failure code\";\n    }\n}\n\n/**\n * Gets unsigned value from UBSAN.\n *\n * @param Type\n *        Supplies a pointer to the UBSAN type descriptor.\n *\n * @param Value\n *        Supplies a pointer to the UBSAN value.\n *\n * @return This routine returns a 64-bit unsigned integer.\n *\n * @since XT 1.0\n */\nXTCDECL\nULONGLONG\nKE::KUbsan::GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,\n                             PVOID Value)\n{\n    ULONG BitWidth;\n\n    /* Calculate bit width of the type */\n    BitWidth = 1 << (Type->TypeInfo >> 1);\n\n    /* Check if inline integer */\n    if(BitWidth <= sizeof(ULONG) * 8)\n    {\n        /* Return value */\n        return (ULONG_PTR)Value;\n    }\n\n    /* Return 64-bit integer */\n    return *(PULONGLONG)Value;\n}\n\n/**\n * Handles the division overflow error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,\n                                   PVOID Lhs,\n                                   PVOID Rhs)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Division-Overflow\");\n\n    /* Check if signed type, which value is -1 */\n    if((Data->Type->TypeInfo & 1) && (GetSignedValue(Data->Type, Rhs) == -1))\n    {\n        /* Division by -1, print error message to debug console */\n        DebugPrint(L\"UBSAN: Division by -1 cannot be represented in type %s\\n\", Data->Type->TypeName);\n    }\n    else\n    {\n        /* Division by 0, print error message to debug console */\n        DebugPrint(L\"UBSAN: Division by zero\\n\");\n    }\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the float cast overflow error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN float cast overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,\n                                    ULONG_PTR Lhs,\n                                    ULONG_PTR Rhs)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Float-Cast-Overflow\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"Value of type %s is outside the range of type %s\\n\", Data->LhsType->TypeName, Data->RhsType->TypeName);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the function type mismatch error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN function type mismatch data.\n *\n * @param Pointer\n *        Supplies pointer operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,\n                                       ULONG_PTR Pointer)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Float-Cast-Overflow\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"UBSAN: Indirect function call through %P address of a wrong type %s\\n\",\n               (PVOID)Pointer, Data->Type->TypeName);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the integer overflow error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data,\n                                  ULONG_PTR Lhs,\n                                  ULONG_PTR Rhs)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Integer-Overflow\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"UBSAN: The result of an arithmetic operation cannot be represented in type %s\\n\", Data->Type->TypeName);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the invalid builtin error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN invalid builtin data.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Invalid-Builtin\");\n\n    /* Check kind of UBSAN error */\n    if(Data->Kind == 0 || Data->Kind == 1)\n    {\n        /* Invalid ctz()/clz() parameter, print error message to debug console */\n        DebugPrint(L\"UBSAN: Passing zero to ctz() or clz() which is not a valid argument\\n\");\n    }\n    else\n    {\n        /* Unknown kind, print error message to debug console */\n        DebugPrint(L\"UBSAN: Unknown kind %u\\n\", Data->Kind);\n    }\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the misaligned access error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN type mismatch data.\n *\n * @param Pointer\n *        Supplies a pointer operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data,\n                                   ULONG_PTR Pointer)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Misaligned-Access\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"UBSAN: %s misaligned address %p for type %s which requires %ld byte alignment\\n\",\n               GetTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName, Data->Alignment);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the negate overflow error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param OldValue\n *        Supplies old value.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data,\n                                 ULONG_PTR OldValue)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Negate-Overflow\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"UBSAN: Negation of %lu cannot be represented in type %s\\n\", OldValue, Data->Type->TypeName);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n\n/**\n * Handles the NULL pointer dereference error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN type mismatch data.\n *\n * @param Pointer\n *        Supplies a pointer operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"NULL-Pointer-Dereference\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"UBSAN: %s NULL pointer of type %s\\n\", GetTypeKind(Data->TypeCheckKind), Data->Type->TypeName);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the object size mismatch error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN type mismatch data.\n *\n * @param Pointer\n *        Supplies a pointer operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,\n                                     ULONG_PTR Pointer)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Object-Size-Mismatch\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"UBSAN: %s address %p with insufficient space for an object of type %s\\n\",\n               GetTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the out of bounds error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN out of bounds data.\n *\n * @param Index\n *        Supplies an index operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data,\n                              ULONG_PTR Index)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Array-Index-Out-Of-Bounds\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"UBSAN: index is out of range for type %s\", Data->ArrayType->TypeName);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the pointer overflow error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data,\n                                  ULONG_PTR Lhs,\n                                  ULONG_PTR Rhs)\n{\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Pointer-Overflow\");\n\n    /* Print error message to debug console */\n    DebugPrint(L\"UBSAN: Pointer operation %s %p to %p\\n\",\n               Lhs > Rhs ? \"overflowed\" : \"underflowed\", (PVOID)Lhs, (PVOID)Rhs);\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n\n/**\n * Handles the shift out of bounds error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN shift out of bounds data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,\n                                   ULONG_PTR Lhs,\n                                   ULONG_PTR Rhs)\n{\n    ULONG LhsBitWidth;\n\n    /* Check if this error was already reported */\n    if(!CheckReport(&Data->Location))\n    {\n        /* Don't report twice */\n        return;\n    }\n\n    /* Enter UBSAN frame */\n    EnterFrame(&Data->Location, \"Shift-Out-Of-Bounds\");\n\n    /* Calculate Lhs bit width */\n    LhsBitWidth = 1 << (Data->LhsType->TypeInfo >> 1);\n\n    /* Check a type of out of bounds error */\n    if((Data->RhsType->TypeInfo & 1) && (GetSignedValue(Data->RhsType, (PVOID)Rhs) < 0))\n    {\n        /* Negative shift exponent, print error message to debug console */\n        DebugPrint(L\"UBSAN: Shift exponent %lld is negative\\n\", GetSignedValue(Data->RhsType, (PVOID)Rhs));\n    }\n    else if((Data->LhsType->TypeInfo & 1) && (GetSignedValue(Data->LhsType, (PVOID)Lhs) < 0))\n    {\n        /* Negative left shift value, print error message to debug console */\n        DebugPrint(L\"UBSAN: Left shift of negative value %lld\\n\", GetSignedValue(Data->LhsType, (PVOID)Lhs));\n    }\n    else if(GetUnsignedValue(Data->RhsType, (PVOID)Rhs) >= LhsBitWidth)\n    {\n        /* Shift exponent too large, print error message to debug console */\n        DebugPrint(L\"UBSAN: Shift exponent %lld is too large for %u-bit type %s\\n\",\n                   GetUnsignedValue(Data->RhsType, (PVOID)Rhs), LhsBitWidth, Data->LhsType->TypeName);\n    }\n    else\n    {\n        /* Left shift too large, print error message to debug console */\n        DebugPrint(L\"UBSAN: Left shift of %lld by %lld places cannot be represented in type %s\\n\",\n                   GetSignedValue(Data->LhsType, (PVOID)Lhs), GetSignedValue(Data->RhsType, (PVOID)Rhs),\n                   Data->LhsType->TypeName);\n    }\n\n    /* Leave UBSAN frame */\n    LeaveFrame();\n}\n\n/**\n * Handles the type mismatch error reported by UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN type mismatch data.\n *\n * @param Pointer\n *        Supplies a pointer operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,\n                               ULONG_PTR Pointer)\n{\n    /* Check the type of mismatch */\n    if(!Pointer)\n    {\n        /* Handle NULL pointer dereference */\n        HandleNullPointerDereference(Data);\n    }\n    else if(Data->Alignment && (((Pointer) & ((decltype(Pointer))(Data->Alignment) - 1)) != 0)) \n    {\n        /* Handle misaligned access */\n        HandleMisalignedAccess(Data, Pointer);\n    }\n    else\n    {\n        /* Handle object size mismatch */\n        HandleObjectSizeMismatch(Data, Pointer);\n    }\n}\n\n/**\n * Leaves the UBSAN frame by marking it as inactive.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nKE::KUbsan::LeaveFrame()\n{\n    /* Leave UBSAN frame */\n    ActiveFrame = FALSE;\n}\n\n/**\n * Handles the addition overflow error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data,\n                            IN ULONG_PTR Lhs,\n                            IN ULONG_PTR Rhs)\n{\n    /* Call UBSAN arithmetic overflow handler */\n    KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs);\n}\n\n/**\n * Handles the division overflow error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data,\n                               IN PVOID Lhs,\n                               IN PVOID Rhs)\n{\n    /* Call UBSAN division overflow handler */\n    KE::KUbsan::HandleDivisionOverflow(Data, Lhs, Rhs);\n}\n\n/**\n * Handles the float cast overflow error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN float cast overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_float_cast_overflow(IN PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,\n                                   IN ULONG_PTR Lhs,\n                                   IN ULONG_PTR Rhs)\n{\n    /* Call UBSAN float cast overflow handler */\n    KE::KUbsan::HandleFloatCastOverflow(Data, Lhs, Rhs);\n}\n\n/**\n * Handles the function type mismatch error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN function type mismatch data.\n *\n * @param Pointer\n *        Supplies pointer operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_function_type_mismatch(IN PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,\n                                      IN ULONG_PTR Pointer)\n{\n    /* Call UBSAN function type mismatch handler */\n    KE::KUbsan::HandleFunctionTypeMismatch(Data, Pointer);\n}\n\n/**\n * Handles the invalid builtin error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN invalid builtin data.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_invalid_builtin(IN PKUBSAN_INVALID_BUILTIN_DATA Data)\n{\n    /* Call UBSAN invalid builtin handler */\n    KE::KUbsan::HandleInvalidBuiltin(Data);\n}\n\n/**\n * Handles the multiplication overflow error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_mul_overflow(IN PKUBSAN_OVERFLOW_DATA Data,\n                            IN ULONG_PTR Lhs,\n                            IN ULONG_PTR Rhs)\n{\n    /* Call UBSAN arithmetic overflow handler */\n    KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs);\n}\n\n/**\n * Handles the negate overflow error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param OldValue\n *        Supplies old value.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_negate_overflow(IN PKUBSAN_OVERFLOW_DATA Data,\n                               IN ULONG_PTR OldValue)\n{\n    /* Call UBSAN negate overflow handler */\n    KE::KUbsan::HandleNegateOverflow(Data, OldValue);\n}\n\n/**\n * Handles the out of bounds error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN out of bounds data.\n *\n * @param Index\n *        Supplies an index operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_out_of_bounds(IN PKUBSAN_OUT_OF_BOUNDS_DATA Data,\n                             IN ULONG_PTR Index)\n{\n    /* Call UBSAN out of bounds handler */\n    KE::KUbsan::HandleOutOfBounds(Data, Index);\n}\n\n/**\n * Handles the pointer overflow error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_pointer_overflow(IN PKUBSAN_OVERFLOW_DATA Data,\n                                IN ULONG_PTR Lhs,\n                                IN ULONG_PTR Rhs)\n{\n    /* Call UBSAN pointer overflow handler */\n    KE::KUbsan::HandlePointerOverflow(Data, Lhs, Rhs);\n}\n\n/**\n * Handles the shift out of bounds error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN shift out of bounds data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_shift_out_of_bounds(IN PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,\n                                   IN ULONG_PTR Lhs,\n                                   IN ULONG_PTR Rhs)\n{\n    /* Call UBSAN out of bounds handler */\n    KE::KUbsan::HandleShiftOutOfBounds(Data, Lhs, Rhs);\n}\n\n/**\n * Handles the subtraction overflow error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN overflow data.\n *\n * @param Lhs\n *        Supplies LHS operand.\n *\n * @param Rhs\n *        Supplies RHS operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_sub_overflow(IN PKUBSAN_OVERFLOW_DATA Data,\n                            IN ULONG_PTR Lhs,\n                            IN ULONG_PTR Rhs)\n{\n    /* Call UBSAN arithmetic overflow handler */\n    KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs);\n}\n\n/**\n * Handles the type mismatch error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN type mismatch data.\n *\n * @param Pointer\n *        Supplies a pointer operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_type_mismatch(IN PKUBSAN_TYPE_MISMATCH_DATA Data,\n                             IN ULONG_PTR Pointer)\n{\n    /* Call UBSAN type mismatch handler */\n    KE::KUbsan::HandleTypeMismatch(Data, Pointer);\n}\n\n/**\n * Handles the type mismatch error. This is internal routine implementing ABI defined by CLANG UBSAN.\n *\n * @param Data\n *        Supplies a pointer to the UBSAN type mismatch data.\n *\n * @param Pointer\n *        Supplies a pointer operand.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n *\n * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113\n */\nXTCLINK\nXTCDECL\nVOID\n__ubsan_handle_type_mismatch_v1(IN PKUBSAN_TYPE_MISMATCH_DATA_V1 Data,\n                                IN ULONG_PTR Pointer)\n{\n    KUBSAN_TYPE_MISMATCH_DATA MismatchData;\n\n    /* Prepare UBSAN type mismatch data in old format */\n    MismatchData.Alignment = 1UL << Data->LogAlignment;\n    MismatchData.Location = Data->Location;\n    MismatchData.Type = Data->Type;\n    MismatchData.TypeCheckKind = Data->TypeCheckKind;\n\n    /* Call UBSAN type mismatch handler */\n    KE::KUbsan::HandleTypeMismatch(&MismatchData, Pointer);\n}\n"
  },
  {
    "path": "xtoskrnl/ke/runlevel.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/runlevel.cc\n * DESCRIPTION:     Running Level management support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Gets the current running level of the current processor.\n *\n * @return This routine returns the current running level.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nKRUNLEVEL\nKE::RunLevel::GetCurrentRunLevel(VOID)\n{\n    return HL::RunLevel::GetRunLevel();\n}\n\n/**\n * Lowers the running level of the current processor.\n *\n * @param RunLevel\n *        Supplies the new running level to lower to.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nKE::RunLevel::LowerRunLevel(IN KRUNLEVEL RunLevel)\n{\n    KRUNLEVEL OldRunLevel;\n\n    /* Read current run level */\n    OldRunLevel = HL::RunLevel::GetRunLevel();\n\n    /* Validate run level lowerage */\n    if(OldRunLevel > RunLevel)\n    {\n        /* Set new, lower run level */\n        HL::RunLevel::SetRunLevel(RunLevel);\n    }\n}\n\n/**\n * Raises the running level of the current processor.\n *\n * @param RunLevel\n *        Supplies the new running level to raise to.\n *\n * @return This routine returns the old running level.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nKRUNLEVEL\nKE::RunLevel::RaiseRunLevel(IN KRUNLEVEL RunLevel)\n{\n    KRUNLEVEL OldRunLevel;\n\n    /* Read current run level */\n    OldRunLevel = HL::RunLevel::GetRunLevel();\n\n    /* Validate run level raise */\n    if(OldRunLevel < RunLevel)\n    {\n        /* Set new, higher run level */\n        HL::RunLevel::SetRunLevel(RunLevel);\n    }\n\n    /* Return old run level */\n    return OldRunLevel;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/semphore.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/semphore.cc\n * DESCRIPTION:     Semaphores support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Initializes a kernel semaphore object.\n *\n * @param Semaphore\n *        Supplies a pointer to a semaphore object.\n *\n * @param Count\n *        Specifies the initial count value of the semaphore.\n *\n * @param Limit\n *        Specifies a maximum count value of the semaphore.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nKE::Semaphore::InitializeSemaphore(IN PKSEMAPHORE Semaphore,\n                                   IN LONG Count,\n                                   IN LONG Limit)\n{\n    /* Initialize semaphore header and limit */\n    Semaphore->Header.Type = SemaphoreObject;\n    Semaphore->Header.SignalState = Count;\n    Semaphore->Limit = Limit;\n\n    /* Initialize semaphore wait list */\n    RTL::LinkedList::InitializeListHead(&Semaphore->Header.WaitListHead);\n}\n\n/**\n * Reads semaphore's current signal state.\n *\n * @param Semaphore\n *        Supplies a pointer to a semaphore object.\n *\n * @return This routine returns the current signal state of the semaphore.\n *\n * @since XT 1.0\n */\nXTAPI\nLONG\nKE::Semaphore::ReadState(IN PKSEMAPHORE Semaphore)\n{\n    /* Return semaphore's signal state */\n    return Semaphore->Header.SignalState;\n}\n\n/**\n * Releases a semaphore.\n *\n * @param Semaphore\n *        Supplies a pointer to a semaphore object.\n *\n * @param Increment\n *        Specifies the priority increment value of the semaphore.\n *\n * @param Adjustment\n *        Specifies adjustment value added to the semaphore's initial count value.\n *\n * @param Wait\n *        Determines whether release of the semaphore will be followed by a kernel wait routine call or not.\n *\n * @return This routine returns a previous signal state of the semaphore.\n *\n * @since NT 3.5\n */\nXTAPI\nLONG\nKE::Semaphore::ReleaseSemaphore(IN PKSEMAPHORE Semaphore,\n                                IN KPRIORITY Increment,\n                                IN LONG Adjustment,\n                                IN BOOLEAN Wait)\n{\n    UNIMPLEMENTED;\n    return 0;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/shdata.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/shdata.cc\n * DESCRIPTION:     Kernel Shared Data\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Retrieves the current interrupt time using a lock-free read mechanism.\n *\n * @return This routine returns a LARGE_INTEGER containing the interrupt time.\n *\n * @since XT 1.0\n */\nXTAPI\nLARGE_INTEGER\nKE::SharedData::GetInterruptTime(VOID)\n{\n    LARGE_INTEGER InterruptTime;\n\n    /* Initialize to zero */\n    InterruptTime.QuadPart = 0;\n\n    /* Perform a lock-free read sequence */\n    do\n    {\n        /* Read the primary high part and low part */\n        InterruptTime.HighPart = KernelSharedData->InterruptTime.High1Part;\n        InterruptTime.LowPart = KernelSharedData->InterruptTime.LowPart;\n    }\n    while(InterruptTime.HighPart != KernelSharedData->InterruptTime.High2Part);\n\n    /* Return the 64-bit time */\n    return InterruptTime;\n}\n\n/**\n * Retrieves a pointer to the memory-mapped Kernel Shared Data.\n *\n * @return This routine returns a pointer to the KSHARED_DATA structure.\n *\n * @since XT 1.0\n */\nXTAPI\nPKSHARED_DATA\nKE::SharedData::GetKernelSharedData(VOID)\n{\n    /* Return the internally managed pointer */\n    return KernelSharedData;\n}\n\n/**\n * Retrieves the current system time using a lock-free read mechanism.\n *\n * @return This routine returns a LARGE_INTEGER containing the system time.\n *\n * @since XT 1.0\n */\nXTAPI\nLARGE_INTEGER\nKE::SharedData::GetSystemTime(VOID)\n{\n    LARGE_INTEGER CurrentTime;\n\n    /* Initialize to zero */\n    CurrentTime.QuadPart = 0;\n\n    /* Perform a lock-free read sequence */\n    do\n    {\n        /* Read the primary high part and low part */\n        CurrentTime.HighPart = KernelSharedData->SystemTime.High1Part;\n        CurrentTime.LowPart = KernelSharedData->SystemTime.LowPart;\n    }\n    while(CurrentTime.HighPart != KernelSharedData->SystemTime.High2Part);\n\n    /* Return the 64-bit time */\n    return CurrentTime;\n}\n\n/**\n * Retrieves the global system tick count.\n *\n * @return This routine returns the current tick count.\n *\n * @since XT 1.0\n */\nXTAPI\nLARGE_INTEGER\nKE::SharedData::GetTickCount(VOID)\n{\n    LARGE_INTEGER Ticks;\n\n    /* Read the 64-bit tick count */\n    Ticks.QuadPart = (*(ULONGLONG*)&KernelSharedData->TickCount);\n\n    /* Return the retrieved tick count */\n    return Ticks;\n}\n\n/**\n * Increments the global system tick count by one using a strict lock-free write mechanism.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SharedData::IncrementTickCount()\n{\n    LARGE_INTEGER Ticks;\n\n    /* Increment tick count */\n    Ticks.QuadPart = (*(ULONGLONG*)&KernelSharedData->TickCount) + 1;\n\n    /* Set the new tick count */\n    KernelSharedData->TickCount.High2Part = Ticks.HighPart;\n    KernelSharedData->TickCount.LowPart = Ticks.LowPart;\n    KernelSharedData->TickCount.High1Part = Ticks.HighPart;\n}\n\n/**\n * Maps and initializes the Kernel Shared Data (KSD) structure.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SharedData::InitializeKernelSharedData(VOID)\n{\n    PCSTR SourceString;\n    XTSTATUS Status;\n\n    /* Map Kernel Shared Data (KSD) */\n    Status = MM::Manager::MapKernelSharedData();\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to map KSD, raise kernel panic */\n        KE::Crash::Panic(0);\n    }\n\n    /* Bind the pointer to the architectural virtual address */\n    KernelSharedData = (PKSHARED_DATA)MM_KERNEL_SHARED_DATA_ADDRESS;\n\n    /* Populate numeric version identifiers */\n    KernelSharedData->XtMajorVersion = XTOS_VERSION_MAJOR;\n    KernelSharedData->XtMinorVersion = XTOS_VERSION_MINOR;\n\n    /* Convert and copy system build string */\n    SourceString = XTOS_VERSION_BUILD;\n    RTL::String::StringToWideString(KernelSharedData->XtBuild, (PCSTR*)&SourceString,\n                                    (sizeof(KernelSharedData->XtBuild) / sizeof(WCHAR)) - 1);\n\n    /* Convert and copy system build hash string */\n    SourceString = XTOS_VERSION_HASH;\n    RTL::String::StringToWideString(KernelSharedData->XtBuildHash, (PCSTR*)&SourceString,\n                                    (sizeof(KernelSharedData->XtBuildHash) / sizeof(WCHAR)) - 1);\n\n    /* Convert and copy system architecture string */\n    SourceString = XTOS_VERSION_ARCH;\n    RTL::String::StringToWideString(KernelSharedData->XtArchitecture, (PCSTR*)&SourceString,\n                                    (sizeof(KernelSharedData->XtArchitecture) / sizeof(WCHAR)) - 1);\n\n    /* Convert and copy system build date string */\n    SourceString = XTOS_VERSION_DATE;\n    RTL::String::StringToWideString(KernelSharedData->XtDate, (PCSTR*)&SourceString,\n                                    (sizeof(KernelSharedData->XtDate) / sizeof(WCHAR)) - 1);\n\n    /* Convert and copy system build full date string */\n    SourceString = XTOS_VERSION_FULLDATE;\n    RTL::String::StringToWideString(KernelSharedData->XtFullDate, (PCSTR*)&SourceString,\n                                    (sizeof(KernelSharedData->XtFullDate) / sizeof(WCHAR)) - 1);\n}\n\n/**\n * Updates the global interrupt time using a strict lock-free write mechanism.\n *\n * @param Time\n *        Supplies the new interrupt time as a 64-bit LARGE_INTEGER value.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SharedData::SetInterruptTime(IN LARGE_INTEGER Time)\n{\n    /* Set the new interrupt time */\n    KernelSharedData->InterruptTime.High2Part = Time.HighPart;\n    KernelSharedData->InterruptTime.LowPart = Time.LowPart;\n    KernelSharedData->InterruptTime.High1Part = Time.HighPart;\n}\n\n/**\n * Updates the global system time using a strict lock-free write mechanism.\n *\n * @param Time\n *        Supplies the new system time as a 64-bit LARGE_INTEGER value.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SharedData::SetSystemTime(IN LARGE_INTEGER Time)\n{\n    /* Set the new system time */\n    KernelSharedData->SystemTime.High2Part = Time.HighPart;\n    KernelSharedData->SystemTime.LowPart = Time.LowPart;\n    KernelSharedData->SystemTime.High1Part = Time.HighPart;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/spinlock.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/spinlock.cc\n * DESCRIPTION:     Spinlocks support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Acquires a specified queued spinlock.\n *\n * @param LockLevel\n *        Supplies the queued spinlock level.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nKE::SpinLock::AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)\n{\n    /* Acquire the queued spinlock */\n    AcquireSpinLock(KE::Processor::GetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock);\n}\n\n/**\n * Acquires a kernel spin lock.\n *\n * @param SpinLock\n *        Supplies a pointer to the kernel spin lock.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nKE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)\n{\n    /* Try to acquire the lock */\n    while(RTL::Atomic::BitTestAndSet((PLONG)SpinLock, 0))\n    {\n        /* Wait until locked is cleared */\n        while(*(VOLATILE PKSPIN_LOCK)SpinLock & 1)\n        {\n                /* Yield processor and keep waiting */\n                AR::CpuFunctions::YieldProcessor();\n        }\n    }\n\n    /* Add an explicit memory barrier */\n    AR::CpuFunctions::ReadWriteBarrier();\n}\n\n/**\n * Initializes all kernel spinlocks.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SpinLock::InitializeAllLocks()\n{\n    /* Initialize all spin locks */\n    InitializeSpinLock(&DispatcherLockQueue);\n    InitializeSpinLock(&PfnLockQueue);\n    InitializeSpinLock(&SystemSpaceLockQueue);\n}\n\n/**\n * Initializes spinlock queues for current processor.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SpinLock::InitializeLockQueues()\n{\n    PKPROCESSOR_CONTROL_BLOCK ControlBlock;\n\n    /* Get current processor control block */\n    ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();\n\n    /* Initialize PCB lock queues */\n    ControlBlock->LockQueue[DispatcherLock].Lock = &DispatcherLockQueue;\n    ControlBlock->LockQueue[DispatcherLock].Next = NULLPTR;\n    ControlBlock->LockQueue[ExpansionLock].Lock = &ExpansionLockQueue;\n    ControlBlock->LockQueue[ExpansionLock].Next = NULLPTR;\n    ControlBlock->LockQueue[PfnLock].Lock = &PfnLockQueue;\n    ControlBlock->LockQueue[PfnLock].Next = NULLPTR;\n    ControlBlock->LockQueue[SystemSpaceLock].Lock = &SystemSpaceLockQueue;\n    ControlBlock->LockQueue[SystemSpaceLock].Next = NULLPTR;\n    ControlBlock->LockQueue[VacbLock].Lock = &VacbLockQueue;\n    ControlBlock->LockQueue[VacbLock].Next = NULLPTR;\n    ControlBlock->LockQueue[MasterLock].Lock = &MasterLockQueue;\n    ControlBlock->LockQueue[MasterLock].Next = NULLPTR;\n    ControlBlock->LockQueue[NonPagedAllocPoolLock].Lock = &NonPagedAllocLockQueue;\n    ControlBlock->LockQueue[NonPagedAllocPoolLock].Next = NULLPTR;\n    ControlBlock->LockQueue[IoCancelLock].Lock = &IoCancelLockQueue;\n    ControlBlock->LockQueue[IoCancelLock].Next = NULLPTR;\n    ControlBlock->LockQueue[WorkQueueLock].Lock = &WorkLockQueue;\n    ControlBlock->LockQueue[WorkQueueLock].Next = NULLPTR;\n    ControlBlock->LockQueue[IoVpbLock].Lock = &IoVpbLockQueue;\n    ControlBlock->LockQueue[IoVpbLock].Next = NULLPTR;\n    ControlBlock->LockQueue[IoDatabaseLock].Lock = &IoDatabaseLockQueue;\n    ControlBlock->LockQueue[IoDatabaseLock].Next = NULLPTR;\n    ControlBlock->LockQueue[IoCompletionLock].Lock = &IoCompletionLockQueue;\n    ControlBlock->LockQueue[IoCompletionLock].Next = NULLPTR;\n    ControlBlock->LockQueue[FileSystemLock].Lock = &FileSystemLockQueue;\n    ControlBlock->LockQueue[FileSystemLock].Next = NULLPTR;\n    ControlBlock->LockQueue[AfdWorkQueueLock].Lock = NULLPTR;\n    ControlBlock->LockQueue[AfdWorkQueueLock].Next = NULLPTR;\n    ControlBlock->LockQueue[BcbLock].Lock = NULLPTR;\n    ControlBlock->LockQueue[BcbLock].Next = NULLPTR;\n    ControlBlock->LockQueue[NonPagedPoolLock].Lock = &NonPagedPoolLockQueue;\n    ControlBlock->LockQueue[NonPagedPoolLock].Next = NULLPTR;\n    ControlBlock->LockQueue[ReservedSystemLock].Lock = NULLPTR;\n    ControlBlock->LockQueue[ReservedSystemLock].Next = NULLPTR;\n    ControlBlock->LockQueue[TimerTableLock].Lock = &TimerTableLockQueue;\n    ControlBlock->LockQueue[TimerTableLock].Next = NULLPTR;\n}\n\n/**\n * Initializes a kernel spinlock object.\n *\n * @param SpinLock\n *        Supplies a pointer to a kernel spin lock.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nKE::SpinLock::InitializeSpinLock(IN PKSPIN_LOCK SpinLock)\n{\n    /* Zero initialize spinlock */\n    *SpinLock = 0;\n}\n\n/**\n * Releases a queued spinlock.\n *\n * @param LockLevel\n *        Supplies the queued spinlock level.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nKE::SpinLock::ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)\n{\n    /* Clear the lock */\n    ReleaseSpinLock(KE::Processor::GetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock);\n}\n\n/**\n * Releases a kernel spin lock.\n *\n * @param SpinLock\n *        Supplies a pointer to the kernel spin lock.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nKE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)\n{\n    /* Clear the lock */\n    RTL::Atomic::And32((PLONG)SpinLock, 0);\n\n    /* Add an explicit memory barrier */\n    AR::CpuFunctions::ReadWriteBarrier();\n}\n\n/**\n * Tests a kernel spin lock.\n *\n * @param SpinLock\n *        Supplies a pointer to the kernel spin lock.\n *\n * @return This routine returns TRUE if the lock is free, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nTestSpinLock(IN PKSPIN_LOCK SpinLock)\n{\n    /* Check if the lock is free */\n    if(*SpinLock)\n    {\n        /* Spinlock is busy, yield processor and return FALSE */\n        AR::CpuFunctions::YieldProcessor();\n        return FALSE;\n    }\n\n    /* Spinlock is free, return TRUE */\n    return TRUE;\n}\n"
  },
  {
    "path": "xtoskrnl/ke/sysres.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/sysres.cc\n * DESCRIPTION:     System resources management; This code is based on the MinocaOS implementation\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Looks for an unacquired system resource of the specified type and acquires it.\n *\n * @param ResourceType\n *        Supplies system resource type.\n *\n * @param ResourceHeader\n *        Specifies a memory area where a pointer to the system resource header will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKE::SystemResources::AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                                     OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)\n{\n    /* Get system resource and acquire an ownership */\n    return GetSystemResource(ResourceType, TRUE, ResourceHeader);\n}\n\n/**\n * Looks for an unacquired system resource of the specified type.\n *\n * @param ResourceType\n *        Supplies system resource type.\n *\n * @param Acquire\n *        Specifies whether system resource should be acquired or not.\n *\n * @param ResourceHeader\n *        Specifies a memory area where a pointer to the system resource header will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                                       IN BOOLEAN ResourceLock,\n                                       OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)\n{\n    PSYSTEM_RESOURCE_HEADER Resource;\n    PLIST_ENTRY ListEntry;\n    BOOLEAN Interrupts;\n    XTSTATUS Status;\n\n    /* Assume resource found successfully */\n    Status = STATUS_SUCCESS;\n\n    /* Check if interrupts are enabled */\n    Interrupts = AR::CpuFunctions::InterruptsEnabled();\n\n    /* Disable interrupts and acquire a spinlock */\n    AR::CpuFunctions::ClearInterruptFlag();\n    KE::SpinLock::AcquireSpinLock(&ResourcesLock);\n\n    /* Iterate through system resources list */\n    ListEntry = ResourcesListHead.Flink;\n    while(ListEntry != &ResourcesListHead)\n    {\n        /* Get resource header */\n        Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry);\n\n        /* Check if resource type matches */\n        if(Resource->ResourceType == ResourceType)\n        {\n            /* Check if resource is locked */\n            if(Resource->ResourceLocked)\n            {\n                /* Resource locked, set status code and stop browsing a list */\n                Status = STATUS_RESOURCE_LOCKED;\n                break;\n            }\n\n            /* Check if resource lock should be acquired */\n            if(ResourceLock)\n            {\n                /* Acquire resource lock */\n                Resource->ResourceLocked = TRUE;\n            }\n\n            /* Stop browsing a list */\n            break;\n        }\n\n        /* Go to the next list entry */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Check if resource was found */\n    if(ListEntry == &ResourcesListHead)\n    {\n        /* Resource not found, return NULLPTR */\n        Resource = NULLPTR;\n        Status = STATUS_NOT_FOUND;\n    }\n\n    /* Release spinlock and re-enable interrupts if necessary */\n    KE::SpinLock::ReleaseSpinLock(&ResourcesLock);\n    if(Interrupts)\n    {\n        /* Re-enable interrupts */\n        AR::CpuFunctions::SetInterruptFlag();\n    }\n\n    /* Return resource header and status code */\n    *ResourceHeader = Resource;\n    return Status;\n}\n\n/**\n * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership.\n *\n * @param ResourceType\n *        Supplies system resource type.\n *\n * @param ResourceHeader\n *        Specifies a memory area where a pointer to the system resource header will be stored.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nKE::SystemResources::GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType,\n                                 OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)\n{\n    /* Get system resource without acquiring an ownership */\n    return GetSystemResource(ResourceType, FALSE, ResourceHeader);\n}\n\n/**\n * Initializes system resource management.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SystemResources::InitializeResources(VOID)\n{\n    PSYSTEM_RESOURCE_HEADER ResourceHeader;\n    PLIST_ENTRY ListEntry, NextListEntry;\n    ULONG ResourceSize;\n\n    /* Initialize system resources spin lock and resource list */\n    KE::SpinLock::InitializeSpinLock(&ResourcesLock);\n    RTL::LinkedList::InitializeListHead(&ResourcesListHead);\n\n    /* Make sure there are some system resources available */\n    if(!RTL::LinkedList::ListEmpty(KE::BootInformation::GetSystemResources()))\n    {\n        /* Iterate through system resources list */\n        ListEntry = KE::BootInformation::GetSystemResources()->Flink;\n        while(ListEntry != KE::BootInformation::GetSystemResources())\n        {\n            /* Get resource header and next list entry */\n            ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry);\n            NextListEntry = ListEntry->Flink;\n\n            /* Basic resource type validation */\n            switch(ResourceHeader->ResourceType)\n            {\n                case SystemResourceAcpi:\n                    /* ACPI system resource */\n                    ResourceSize = sizeof(SYSTEM_RESOURCE_ACPI);\n                    break;\n                case SystemResourceFrameBuffer:\n                    /* FrameBuffer system resource */\n                    ResourceSize = sizeof(SYSTEM_RESOURCE_FRAMEBUFFER);\n                    break;\n                default:\n                    /* Unknown system resource type, skip it */\n                    ResourceSize = 0;\n                    break;\n            }\n\n            /* Validate resource size */\n            if(ResourceSize != 0 && ResourceSize == ResourceHeader->ResourceSize)\n            {\n                /* Move valid resource to the internal kernel list of system resources */\n                RTL::LinkedList::RemoveEntryList(&ResourceHeader->ListEntry);\n                RTL::LinkedList::InsertTailList(&ResourcesListHead, &ResourceHeader->ListEntry);\n            }\n\n            /* Go to the next list entry */\n            ListEntry = NextListEntry;\n        }\n    }\n}\n\n/**\n * Releases boot system resource.\n *\n * @param ResourceHeader\n *        Specifies a pointer to the boot system resource header.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)\n{\n    /* Disable interrupts and acquire a spinlock */\n    AR::CpuFunctions::ClearInterruptFlag();\n    KE::SpinLock::AcquireSpinLock(&ResourcesLock);\n\n    /* Release resource lock */\n    ResourceHeader->ResourceLocked = FALSE;\n\n    /* Release spinlock and enable interrupts */\n    KE::SpinLock::ReleaseSpinLock(&ResourcesLock);\n    AR::CpuFunctions::SetInterruptFlag();\n}\n"
  },
  {
    "path": "xtoskrnl/ke/systime.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/systime.cc\n * DESCRIPTION:     Timebase and system clock support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n\n/**\n * Returns the current system time.\n *\n * @param SystemTime\n *        Supplies a pointer to a variable that receives the current system time.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SystemTime::GetSystemTime(OUT PLARGE_INTEGER SystemTime)\n{\n    LARGE_INTEGER CurrentTime;\n\n    /* Fetch the time using the lock-free shared data mechanism and return it */\n    CurrentTime = KE::SharedData::GetSystemTime();\n    SystemTime->QuadPart = CurrentTime.QuadPart;\n}\n\n/**\n * Sets the system time, updates the boot time, and optionally updates the hardware Real-Time Clock (RTC).\n *\n * @param NewTime\n *        Supplies a pointer to the new system time.\n *\n * @param OldTime\n *        Supplies a pointer to a variable that receives the previous system time.\n *\n * @param CorrectInterruptTime\n *        Specifies if the physical interrupt time should be corrected.\n *\n * @param WriteToRtc\n *        Specifies if the new system time should be written to RTC.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SystemTime::SetSystemTime(IN PLARGE_INTEGER NewTime,\n                              OUT PLARGE_INTEGER OldTime,\n                              IN BOOLEAN CorrectInterruptTime,\n                              IN BOOLEAN WriteToRtc)\n{\n    LARGE_INTEGER TimeDelta;\n    TIME_FIELDS TimeFields;\n\n    /* Check if the new system time should be written to the RTC */\n    if(WriteToRtc)\n    {\n        /* Convert the new system time to a human-readable calendar structure */\n        RTL::Time::XtEpochToTimeFields(NewTime, &TimeFields);\n    }\n\n    /* Start a guarded code block */\n    {\n        /* Raise runlevel to HIGH level */\n        KE::RaiseRunLevel Runlevel(HIGH_LEVEL);\n\n        /* Save the previous system time for the caller and for delta calculation */\n        GetSystemTime(OldTime);\n\n        /* Write new system time to the Kernel Shared Data */\n        KE::SharedData::SetSystemTime(*NewTime);\n\n        /* Check if the new system time should be written to the RTC */\n        if(WriteToRtc)\n        {\n            /* Update the hardware CMOS clock */\n            HL::Rtc::SetRealTimeClock(&TimeFields);\n        }\n\n        /* Calculate the time difference */\n        TimeDelta.QuadPart = NewTime->QuadPart - OldTime->QuadPart;\n\n        /* Update the boot time by the delta */\n        BootTime.QuadPart += TimeDelta.QuadPart;\n    }\n\n    /* Check if interrupt time needs to be corrected */\n    if(CorrectInterruptTime)\n    {\n        UNIMPLEMENTED;\n    }\n}\n\n/**\n * Sets the maximum and minimum time increment values in 100ns units.\n *\n * @param MinIncrement\n *        Supplies the minimum time increment.\n *\n * @param MaxIncrement\n *        Supplies the maximum time increment.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::SystemTime::SetTimeIncrement(IN ULONG MinIncrement,\n                                 IN ULONG MaxIncrement)\n{\n    /* Store resolution boundaries while enforcing a 1ms architectural floor */\n    MaximumIncrement = MaxIncrement;\n    MinimumIncrement = MAX(MinIncrement, 10000);\n\n    /* Set the tick offset to the maximum increment */\n    TickOffset = (LONG)MaxIncrement;\n\n    /* Set the default time adjustment to the full tick period */\n    TimeAdjustment = MaxIncrement;\n}\n\n/**\n * Services the periodic clock interrupt by advancing the global interrupt time, detecting full\n * system tick boundaries via the tick offset accumulator, and advancing the wall-clock system time.\n *\n * @param TrapFrame\n *        Supplies a pointer to the hardware trap frame representing the interrupted execution context.\n *\n * @param Increment\n *        Supplies the calibrated time delta for this hardware interrupt in 100-nanosecond units.\n *\n * @param RunLevel\n *        Supplies the system run level at which the interrupt was taken.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nKE::SystemTime::UpdateSystemTime(IN PKTRAP_FRAME TrapFrame,\n                                 IN ULONG Increment,\n                                 IN KRUNLEVEL RunLevel)\n{\n    LARGE_INTEGER InterruptTime, SystemTime;\n    LONG CurrentTickOffset;\n\n    /* Advance the global interrupt time on every hardware tick */\n    InterruptTime = KE::SharedData::GetInterruptTime();\n    InterruptTime.QuadPart += Increment;\n    KE::SharedData::SetInterruptTime(InterruptTime);\n\n    /* Atomically consume the current tick budget and retrieve the pre-decrement value */\n    CurrentTickOffset = RTL::Atomic::ExchangeAdd32((PLONG)&TickOffset, -(LONG)Increment);\n\n    /* Determine whether the accumulated increments have crossed the full tick boundary */\n    if(CurrentTickOffset <= (LONG)Increment)\n    {\n        /* A full system tick has elapsed, advance the wall-clock time by the configured adjustment */\n        SystemTime = KE::SharedData::GetSystemTime();\n        SystemTime.QuadPart += TimeAdjustment;\n        KE::SharedData::SetSystemTime(SystemTime);\n\n        /* Update the tick count */\n        KE::SharedData::IncrementTickCount();\n\n        /* Reload the tick offset accumulator for the next full tick period */\n        TickOffset += MaximumIncrement;\n\n        /* Update processor and thread runtime accounting */\n        KE::Dispatcher::UpdateRunTime(TrapFrame, RunLevel);\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/ke/timer.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/ke/timer.cc\n * DESCRIPTION:     Kernel timer object support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Cancels the timer.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @return This routine returns TRUE if the cancelled timer was set, or FALSE otherwise.\n *\n * @since NT 3.5\n */\nXTAPI\nBOOLEAN\nKE::Timer::CancelTimer(IN PKTIMER Timer)\n{\n    BOOLEAN Result;\n    KRUNLEVEL RunLevel;\n\n    /* Set default result value */\n    Result = FALSE;\n\n    /* Raise run level and acquire dispatcher lock */\n    RunLevel = KE::RunLevel::RaiseRunLevel(SYNC_LEVEL);\n    KE::SpinLock::AcquireQueuedSpinLock(DispatcherLock);\n\n    /* Check timer status */\n    if(Timer->Header.Inserted)\n    {\n        /* Remove the timer from the list */\n        RemoveTimer(Timer);\n        Result = TRUE;\n    }\n\n    /* Release dispatcher lock and process the deferred ready list */\n    KE::SpinLock::ReleaseQueuedSpinLock(DispatcherLock);\n    KE::Dispatcher::ExitDispatcher(RunLevel);\n\n    /* Return result */\n    return Result;\n}\n\n/**\n * Clears the signal state of the timer.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @return This routine does not return any value.\n *\n * @since NT 4.0\n */\nXTAPI\nVOID\nKE::Timer::ClearTimer(IN PKTIMER Timer)\n{\n    /* Clear signal state */\n    Timer->Header.SignalState = 0;\n}\n\n/**\n * Reads the current signal state of the given timer.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @return This routine returns TRUE if the timer is set, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nKE::Timer::GetState(IN PKTIMER Timer)\n{\n    /* Return timer state */\n    return (BOOLEAN)Timer->Header.SignalState;\n}\n\n/**\n * Initializes an extended kernel timer.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @param Type\n *        Supplies the type of the timer.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Timer::InitializeTimer(OUT PKTIMER Timer,\n                           IN KTIMER_TYPE Type)\n{\n    /* Initialize the header */\n    Timer->Header.Type = TimerNotificationObject + (UCHAR)Type;\n    Timer->Header.Inserted = 0;\n    Timer->Header.SignalState = 0;\n\n    /* Initialize the timer data */\n    Timer->DueTime.QuadPart = 0;\n    Timer->Period = 0;\n\n    /* Initialize linked lists */\n    RTL::LinkedList::InitializeListHead(&Timer->Header.WaitListHead);\n    RTL::LinkedList::InitializeListHead(&Timer->TimerListEntry);\n}\n\n/**\n * Queries the timer's interrupt due time.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @return This routine returns the time remaining on the timer, or 0 if the timer is not set.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nKE::Timer::QueryTimer(IN PKTIMER Timer)\n{\n    KRUNLEVEL RunLevel;\n    ULONGLONG DueTime;\n\n    /* Set initial due time */\n    DueTime = 0;\n\n    /* Raise run level and acquire dispatcher lock */\n    RunLevel = KE::RunLevel::RaiseRunLevel(SYNC_LEVEL);\n    KE::SpinLock::AcquireQueuedSpinLock(DispatcherLock);\n\n    /* Check timer status */\n    if(Timer->Header.Inserted)\n    {\n        /* Get timer's due time */\n        DueTime = Timer->DueTime.QuadPart;\n    }\n\n    /* Release dispatcher lock and process the deferred ready list */\n    KE::SpinLock::ReleaseQueuedSpinLock(DispatcherLock);\n    KE::Dispatcher::ExitDispatcher(RunLevel);\n\n    /* Return timer's due time */\n    return DueTime;\n}\n\n/**\n * Sets the supplied timer to expire at the specified time.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @param DueTime\n *        Supplies the time at which the timer should expire (both absolute and relative times are supported).\n *\n * @param Period\n *        Supplies the timer period.\n *\n * @param Dpc\n *        Supplies a pointer to a Deferred Procedure Call (DPC) object.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Timer::SetTimer(IN PKTIMER Timer,\n                    IN LARGE_INTEGER DueTime,\n                    IN LONG Period,\n                    IN PKDPC Dpc)\n{\n    UNIMPLEMENTED;\n}\n\n/**\n * Removes a specified timer from the timer list.\n *\n * @param Timer\n *        Supplies a pointer to a timer object.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nKE::Timer::RemoveTimer(IN OUT PKTIMER Timer)\n{\n    /* Remove the timer from the list */\n    Timer->Header.Inserted = FALSE;\n    RTL::LinkedList::RemoveEntryList(&Timer->TimerListEntry);\n}\n"
  },
  {
    "path": "xtoskrnl/mm/alloc.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/alloc.cc\n * DESCRIPTION:     Memory Manager pool allocator\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Allocates pages from the non-paged pool.\n *\n * @param Pages\n *        Specifies the number of pages to allocate.\n *\n * @param Memory\n *        Supplies a pointer to the allocated pool of pages.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::AllocateNonPagedPoolPages(IN PFN_COUNT Pages,\n                                         OUT PVOID *Memory)\n{\n    PMMPTE CurrentPte, PointerPte, ValidPte;\n    PLIST_ENTRY Entry, LastHead, ListHead;\n    PMMFREE_POOL_ENTRY FreePage;\n    PFN_NUMBER PageFrameNumber;\n    PVOID BaseAddress;\n    ULONG Index;\n    PMMPFN Pfn;\n\n    /* Calculate the free list index based on the requested page count, capped at the maximum list head index */\n    Index = MIN(Pages, MM_MAX_FREE_PAGE_LIST_HEADS) - 1;\n\n    /* Set the starting list head and the boundary for the search loop */\n    ListHead = &NonPagedPoolFreeList[Index];\n    LastHead = &NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];\n\n    /* Start a guarded code block */\n    {\n        /* Acquire the Non-Paged pool lock and raise runlevel to DISPATCH level */\n        KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n        KE::QueuedSpinLockGuard NonPagedPoolSpinLock(NonPagedPoolLock);\n\n        /* Iterate through the free lists */\n        do\n        {\n            /* Iterate through the free entries in the current list */\n            Entry = ListHead->Flink;\n            while(Entry != ListHead)\n            {\n                /* Get the free pool entry structure from the list entry */\n                FreePage = CONTAIN_RECORD(Entry, MMFREE_POOL_ENTRY, List);\n\n                /* Check if this block is large enough to satisfy the request */\n                if(FreePage->Size >= Pages)\n                {\n                    /* Adjust the size of the free block to account for the allocated pages */\n                    FreePage->Size -= Pages;\n\n                    /* Calculate the base address of the allocated block */\n                    BaseAddress = (PVOID)((ULONG_PTR)FreePage + (FreePage->Size  << MM_PAGE_SHIFT));\n\n                    /* Remove the entry from the free list */\n                    RTL::LinkedList::RemoveEntryList(&FreePage->List);\n\n                    /* Check if there is remaining space in the entry */\n                    if(FreePage->Size != 0)\n                    {\n                        /* Calculate the new list index for the remaining fragment */\n                        Index = MIN(FreePage->Size, MM_MAX_FREE_PAGE_LIST_HEADS) - 1;\n\n                        /* Insert the entry into the free list */\n                        RTL::LinkedList::InsertTailList(&NonPagedPoolFreeList[Index], &FreePage->List);\n                    }\n\n                    /* Get the PTE for the allocated address */\n                    PointerPte = MM::Paging::GetPteAddress(BaseAddress);\n\n                    /* Get the PFN database entry for the corresponding physical page */\n                    Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));\n\n                    /* Denote allocation boundaries */\n                    Pfn->u3.e1.ReadInProgress = 1;\n\n                    /* Check if multiple pages were requested */\n                    if(Pages != 1)\n                    {\n                        /* Advance to the PTE of the last page in the allocation */\n                        PointerPte = MM::Paging::AdvancePte(PointerPte, Pages - 1);\n\n                        /* Get the PFN entry for the last page */\n                        Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));\n                    }\n\n                    /* Denote allocation boundaries */\n                    Pfn->u3.e1.WriteInProgress = 1;\n\n                    /* Set the allocated memory address and return success */\n                    *Memory = BaseAddress;\n                    return STATUS_SUCCESS;\n                }\n\n                /* Move to the next entry in the free list */\n                Entry = FreePage->List.Flink;\n            }\n        }\n        while(++ListHead < LastHead);\n    }\n\n    /* No suitable free block found; try to expand the pool by reserving system PTEs */\n    PointerPte = MM::Pte::ReserveSystemPtes(Pages, NonPagedPoolExpansion);\n    if(PointerPte == NULLPTR)\n    {\n        /* PTE reservation failed, return insufficient resources */\n        return STATUS_INSUFFICIENT_RESOURCES;\n    }\n\n    /* Acquire the Non-Paged pool lock and raise runlevel to DISPATCH level */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::QueuedSpinLockGuard NonPagedPoolSpinLock(NonPagedPoolLock);\n\n    /* Acquire the PFN database lock */\n    KE::QueuedSpinLockGuard PfnSpinLock(PfnLock);\n\n    /* Check if there are enough available physical pages to back the allocation */\n    if(Pages >= MM::Pfn::GetAvailablePages())\n    {\n        /* Not enough physical pages, release the reserved system PTEs */\n        MM::Pte::ReleaseSystemPtes(PointerPte, Pages, NonPagedPoolExpansion);\n\n        /* Return failure due to insufficient resources */\n        return STATUS_INSUFFICIENT_RESOURCES;\n    }\n\n    /* Set the tracking pointer to iterate through the reserved PTE space */\n    CurrentPte = PointerPte;\n\n    /* Get a template valid PTE and loop through the allocation to map physical pages */\n    ValidPte = MM::Pte::GetValidPte();\n    do\n    {\n        /* Allocate a physical page */\n        PageFrameNumber = MM::Pfn::AllocatePhysicalPage(MM::Colors::GetNextColor());\n\n        /* Initialize the PFN entry for the allocated physical page */\n        Pfn = MM::Pfn::GetPfnEntry(PageFrameNumber);\n        MM::Paging::SetPte(&Pfn->OriginalPte, 0, MM_READWRITE << MM_PROTECT_FIELD_SHIFT);\n        Pfn->PteAddress = CurrentPte;\n        Pfn->u2.ShareCount = 1;\n        Pfn->u3.e1.PageLocation = ActiveAndValid;\n        Pfn->u3.e2.ReferenceCount = 1;\n        Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress(CurrentPte));\n\n        /* Build a valid PTE pointing to the allocated page frame */\n        MM::Paging::SetPte(ValidPte, PageFrameNumber, 0);\n\n        /* Write the valid PTE into the system PTE range and advance to the next PTE */\n        *CurrentPte = *ValidPte;\n        CurrentPte = MM::Paging::GetNextPte(CurrentPte);\n    }\n    while(--Pages > 0);\n\n    /* Dnote allocation boundaries */\n    Pfn->u3.e1.WriteInProgress = 1;\n\n    /* Get the PFN entry for the first page of the allocation */\n    Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));\n\n    /* Denote allocation boundaries */\n    Pfn->u3.e1.ReadInProgress = 1;\n\n    /* Convert the PTE address to the virtual address and store in the buffer */\n    *Memory = MM::Paging::GetPteVirtualAddress(PointerPte);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Allocates pages from the paged pool.\n *\n * @param Pages\n *        Specifies the number of pages to allocate.\n *\n * @param Memory\n *        Supplies a pointer to the allocated pool of pages.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::AllocatePagedPoolPages(IN PFN_COUNT Pages,\n                                      OUT PVOID *Memory)\n{\n    UNIMPLEMENTED;\n\n    /* Return not implemented status code */\n    return STATUS_NOT_IMPLEMENTED;\n}\n\n/**\n * Allocates pages from the specified pool type.\n *\n * @param PoolType\n *        Specifies the type of pool to allocate pages from.\n *\n * @param Bytes\n *        Specifies the number of bytes to allocate.\n *\n * @param Memory\n *        Supplies a pointer to the allocated pool of pages.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::AllocatePages(IN MMPOOL_TYPE PoolType,\n                             IN SIZE_T Bytes,\n                             OUT PVOID *Memory)\n{\n    PFN_COUNT Pages;\n\n    /* Initialize the output parameter */\n    *Memory = NULLPTR;\n\n    /* Convert bytes to pages */\n    Pages = SIZE_TO_PAGES(Bytes);\n\n    /* Check if there are any pages to allocate */\n    if(!Pages)\n    {\n        /* Nothing to allocate, return NULLPTR */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Switch on pool type */\n    switch(PoolType & MM_POOL_TYPE_MASK)\n    {\n        case NonPagedPool:\n            /* Allocate non-paged pool */\n            return AllocateNonPagedPoolPages(Pages, Memory);\n        case PagedPool:\n            /* Allocate paged pool */\n            return AllocatePagedPoolPages(Pages, Memory);\n    }\n\n    /* Invalid pool type specified, return error */\n    return STATUS_INVALID_PARAMETER;\n}\n\n/**\n * Allocates a block of memory from the specified pool type.\n *\n * @param PoolType\n *        Specifies the type of pool to allocate from.\n *\n * @param Bytes\n *        Specifies the number of bytes to allocate.\n *\n * @param Memory\n *        Supplies a pointer to the allocated memory.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::AllocatePool(IN MMPOOL_TYPE PoolType,\n                            IN SIZE_T Bytes,\n                            OUT PVOID *Memory)\n{\n    /* Allocate pool */\n    return AllocatePool(PoolType, Bytes, Memory, SIGNATURE32('N', 'o', 'n', 'e'));\n}\n\n/**\n * Allocates a block of memory from the specified pool type.\n *\n * @param PoolType\n *        Specifies the type of pool to allocate from.\n *\n * @param Bytes\n *        Specifies the number of bytes to allocate.\n *\n * @param Memory\n *        Supplies a pointer to the allocated memory.\n *\n * @param Tag\n *        Specifies the allocation identifying tag.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::AllocatePool(IN MMPOOL_TYPE PoolType,\n                            IN SIZE_T Bytes,\n                            OUT PVOID *Memory,\n                            IN ULONG Tag)\n{\n    PPOOL_HEADER PoolEntry, NextPoolEntry, PoolRemainder;\n    PPOOL_DESCRIPTOR PoolDescriptor;\n    USHORT BlockSize, Index;\n    PLIST_ENTRY ListHead;\n    XTSTATUS Status;\n\n    /* Verify run level for the specified pool */\n    VerifyRunLevel(PoolType, Bytes, NULLPTR);\n\n    /* Check if there are any bytes to allocate */\n    if(!Bytes)\n    {\n        /* Allocate at least a single byte */\n        Bytes = 1;\n    }\n\n    /* Retrieve the specific pool descriptor based on the masked pool type */\n    PoolDescriptor = PoolVector[PoolType & MM_POOL_TYPE_MASK];\n\n    /* Determine if the requested size exceeds the maximum standard pool block capacity */\n    if(Bytes > (MM_PAGE_SIZE - (sizeof(POOL_HEADER) + MM_POOL_BLOCK_SIZE)))\n    {\n        /* Allocate new, raw pages directly to satisfy the large allocation request */\n        Status = AllocatePages(PoolType, Bytes, (PVOID*)&PoolEntry);\n        if(Status != STATUS_SUCCESS || !PoolEntry)\n        {\n            /* Allocation failed, clear the output pointer and return the error status */\n            *Memory = NULLPTR;\n            return Status;\n        }\n\n        /* Update the pool descriptor statistical counters */\n        RTL::Atomic::ExchangeAdd32((PLONG)&PoolDescriptor->TotalBigAllocations, (LONG)SIZE_TO_PAGES(Bytes));\n        RTL::Atomic::ExchangeAdd64((PLONG_PTR)&PoolDescriptor->TotalBytes, (LONG_PTR)Bytes);\n        RTL::Atomic::Increment32((PLONG)&PoolDescriptor->RunningAllocations);\n\n        /* Attempt to register the big allocation within the tracking table */\n        if(!RegisterBigAllocationTag(PoolEntry, Tag, (ULONG)SIZE_TO_PAGES(Bytes), PoolType))\n        {\n            /* Fallback to a default tag */\n            Tag = SIGNATURE32('B', 'i', 'g', 'A');\n        }\n\n        /* Register the allocation in the tracking table */\n        RegisterAllocationTag(Tag, SIZE_TO_PAGES(Bytes), PoolType);\n\n        /* Supply the allocated address and return success */\n        *Memory = PoolEntry;\n        return STATUS_SUCCESS;\n    }\n\n    /* Calculate the required block index */\n    Index = (USHORT)((Bytes + sizeof(POOL_HEADER) + (MM_POOL_BLOCK_SIZE - 1)) / MM_POOL_BLOCK_SIZE);\n\n    /* Resolve the appropriate list head for the calculated block index */\n    ListHead = &PoolDescriptor->ListHeads[Index];\n    while(ListHead != &PoolDescriptor->ListHeads[MM_POOL_LISTS_PER_PAGE])\n    {\n        /* Check whether the target free list contains available blocks */\n        if(!PoolListEmpty(ListHead))\n        {\n            /* Start a guarded code block */\n            {\n                /* Acquire the pool lock */\n                PoolLockGuard PoolLock((MMPOOL_TYPE)(PoolDescriptor->PoolType & MM_POOL_TYPE_MASK));\n\n                /* Re-evaluate the list emptiness to prevent race conditions */\n                if(PoolListEmpty(ListHead))\n                {\n                    /* Proceed to evaluate the next list head */\n                    continue;\n                }\n\n                /* Validate the structural integrity of the pool list */\n                VerifyPoolLinks(ListHead);\n\n                /* Extract the first available free block from the list and resolve its header */\n                PoolEntry = GetPoolEntry(RemovePoolHeadList(ListHead));\n\n                /* Re-validate the pool list and verify integrity of the extracted block */\n                VerifyPoolLinks(ListHead);\n                VerifyPoolBlocks(PoolEntry);\n\n                /* Check whether the extracted block requires splitting */\n                if(PoolEntry->BlockSize != Index)\n                {\n                    /* Check if the block is located at the absolute beginning of a page */\n                    if(PoolEntry->PreviousSize == 0)\n                    {\n                        /* Split the block and initialize the remainder */\n                        PoolRemainder = GetPoolBlock(PoolEntry, Index);\n                        PoolRemainder->BlockSize = PoolEntry->BlockSize - Index;\n                        PoolRemainder->PreviousSize = Index;\n\n                        /* Resolve the subsequent block and update its previous size field */\n                        NextPoolEntry = GetPoolNextBlock(PoolRemainder);\n                        if(PAGE_ALIGN(NextPoolEntry) != NextPoolEntry)\n                        {\n                            /* Adjust the adjacent block to reflect the new size of the remainder */\n                            NextPoolEntry->PreviousSize = PoolRemainder->BlockSize;\n                        }\n                    }\n                    else\n                    {\n                        /* Split the extracted block */\n                        PoolRemainder = PoolEntry;\n                        PoolEntry->BlockSize -= Index;\n\n                        /* Advance the pointer to the new block and update its previous size */\n                        PoolEntry = GetPoolNextBlock(PoolEntry);\n                        PoolEntry->PreviousSize = PoolRemainder->BlockSize;\n\n                        /* Resolve the adjacent next block and adjust its previous size */\n                        NextPoolEntry = GetPoolBlock(PoolEntry, Index);\n                        if(PAGE_ALIGN(NextPoolEntry) != NextPoolEntry)\n                        {\n                            /* Adjust the adjacent block */\n                            NextPoolEntry->PreviousSize = Index;\n                        }\n                    }\n\n                    /* Finalize the structural sizing fields */\n                    BlockSize = PoolRemainder->BlockSize;\n                    PoolEntry->BlockSize = Index;\n                    PoolRemainder->PoolType = 0;\n\n                    /* Validate the target free list */\n                    VerifyPoolLinks(&PoolDescriptor->ListHeads[BlockSize - 1]);\n\n                    /* Ensure the remainder block is large enough to contain valid list */\n                    if(BlockSize != 1)\n                    {\n                        /* Insert the new remainder block into the appropriate free list and verify links */\n                        InsertPoolTailList(&PoolDescriptor->ListHeads[BlockSize - 1], GetPoolFreeBlock(PoolRemainder));\n                        VerifyPoolLinks(GetPoolFreeBlock(PoolRemainder));\n                    }\n                }\n\n                /* Update the active pool type and verify structural invariants */\n                PoolEntry->PoolType = PoolType + 1;\n                VerifyPoolBlocks(PoolEntry);\n            }\n\n            /* Update the pool descriptor statistical counters */\n            RTL::Atomic::ExchangeAdd64((PLONG_PTR)&PoolDescriptor->TotalBytes, (LONG_PTR)(PoolEntry->BlockSize * MM_POOL_BLOCK_SIZE));\n            RTL::Atomic::Increment32((PLONG)&PoolDescriptor->RunningAllocations);\n\n            /* Register the allocation in the tracking table */\n            RegisterAllocationTag(Tag, PoolEntry->BlockSize * MM_POOL_BLOCK_SIZE, PoolType);\n\n            /* Assign the specified identification tag */\n            PoolEntry->PoolTag = Tag;\n\n            /* Clear the internal list links */\n            (GetPoolFreeBlock(PoolEntry))->Flink = NULLPTR;\n            (GetPoolFreeBlock(PoolEntry))->Blink = NULLPTR;\n\n            /* Supply the allocated address and return success */\n            *Memory = GetPoolFreeBlock(PoolEntry);\n            return STATUS_SUCCESS;\n        }\n\n        /* Advance to the next list head */\n        ListHead++;\n    }\n\n    /* Allocate a new page to fulfill the request */\n    Status = AllocatePages(PoolType, MM_PAGE_SIZE, (PVOID *)&PoolEntry);\n    if(Status != STATUS_SUCCESS || !PoolEntry)\n    {\n        /* Allocation failed, clear the output pointer and return the error status */\n        *Memory = NULLPTR;\n        return Status;\n    }\n\n    /* Initialize the structural header */\n    PoolEntry->Long = 0;\n    PoolEntry->BlockSize = Index;\n    PoolEntry->PoolType = PoolType + 1;\n\n    /* Calculate the block size of the remaining unused space */\n    BlockSize = (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE) - Index;\n\n    /* Initialize the remainder entry representing the free space */\n    PoolRemainder = GetPoolBlock(PoolEntry, Index);\n    PoolRemainder->Long = 0;\n    PoolRemainder->BlockSize = BlockSize;\n    PoolRemainder->PreviousSize = Index;\n\n    /* Update the pool descriptor statistical counters */\n    RTL::Atomic::Increment32((PLONG)&PoolDescriptor->TotalPages);\n    RTL::Atomic::ExchangeAdd64((PLONG_PTR)&PoolDescriptor->TotalBytes, (LONG_PTR)(PoolEntry->BlockSize * MM_POOL_BLOCK_SIZE));\n\n    /* Check if the remainder block is large enough */\n    if(PoolRemainder->BlockSize != 1)\n    {\n        /* Acquire the pool lock */\n        PoolLockGuard PoolLock((MMPOOL_TYPE)(PoolDescriptor->PoolType & MM_POOL_TYPE_MASK));\n\n        /* Validate the target free list structure */\n        VerifyPoolLinks(&PoolDescriptor->ListHeads[BlockSize - 1]);\n\n        /* Insert the remainder block into the free list */\n        InsertPoolTailList(&PoolDescriptor->ListHeads[BlockSize - 1], GetPoolFreeBlock(PoolRemainder));\n\n        /* Verify the structural integrity of the remainder and the allocated blocks */\n        VerifyPoolLinks(GetPoolFreeBlock(PoolRemainder));\n        VerifyPoolBlocks(PoolEntry);\n    }\n    else\n    {\n        /* Verify the allocated block invariants */\n        VerifyPoolBlocks(PoolEntry);\n    }\n\n    /* Increment the running allocation counter for the pool descriptor */\n    RTL::Atomic::Increment32((PLONG)&PoolDescriptor->RunningAllocations);\n\n    /* Register the allocation in the tracking table */\n    RegisterAllocationTag(Tag, PoolEntry->BlockSize * MM_POOL_BLOCK_SIZE, PoolType);\n\n    /* Perform a final structural validation of the pool block */\n    VerifyPoolBlocks(PoolEntry);\n\n    /* Apply the requested identification tag */\n    PoolEntry->PoolTag = Tag;\n\n    /* Supply the allocated address and return success */\n    *Memory = GetPoolFreeBlock(PoolEntry);\n    return STATUS_SUCCESS;\n}\n\n/**\n * Computes a hash for a given virtual address to be used in the big allocation tracker.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address to be hashed.\n *\n * @return This routine returns the computed hash value.\n *\n * @since XT 1.0\n */\nXTINLINE\nULONG\nMM::Allocator::ComputeHash(IN PVOID VirtualAddress)\n{\n    ULONG Result;\n\n    /* Transform the virtual address into a page frame number representation */\n    Result = (ULONG)((ULONG_PTR)VirtualAddress >> MM_PAGE_SHIFT);\n\n    /* Fold the page number bits using XOR to distribute the entropy across the lower bits */\n    return (Result >> 24) ^ (Result >> 16) ^ (Result >> 8) ^ Result;\n}\n\n/**\n * Computes a hash for a given pool tag to be used in the allocation tracker.\n *\n * @param Tag\n *        Supplies the 32-bit pool tag to be hashed.\n *\n * @param TableMask\n *        Supplies the bitmask used to bound the resulting hash index to the table size.\n *\n * @return This routine returns the computed hash value.\n *\n * @since XT 1.0\n */\nXTINLINE\nULONG\nMM::Allocator::ComputeHash(IN ULONG Tag,\n                           IN ULONG TableMask)\n{\n    ULONG Result;\n\n    /* Fold the bytes using arithmetic shifts and XORs */\n    Result = ((((((Tag & 0xFF) << 2) ^ ((Tag >> 8)  & 0xFF)) << 2) ^ ((Tag >> 16) & 0xFF)) << 2) ^ ((Tag >> 24) & 0xFF);\n\n    /* Multiply by the NT magic prime-like constant and shift down */\n    return ((40543 * Result) >> 2) & TableMask;\n}\n\n/**\n * Expands the big allocation tracking table to accommodate additional large allocations.\n *\n * @return This routine returns TRUE if the table was successfully expanded, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Allocator::ExpandBigAllocationsTable(VOID)\n{\n    PPOOL_TRACKING_BIG_ALLOCATIONS NewTable, OldTable;\n    SIZE_T AllocationBytes, OldSize, NewSize;\n    ULONG Hash, HashMask, Index;\n    PFN_NUMBER PagesFreed;\n    XTSTATUS Status;\n    BOOLEAN Abort;\n\n    /* Initialize the abort flag and snapshot current table capacity */\n    Abort = FALSE;\n    OldSize = BigAllocationsTrackingTableSize;\n\n    /* Check if doubling the size would cause an integer overflow */\n    if(OldSize > ((~(SIZE_T)0) / 2))\n    {\n        /* Abort expansion to prevent integer wrap-around */\n        return FALSE;\n    }\n\n    /* Calculate the target capacity by safely doubling table capacity */\n    NewSize = OldSize * 2;\n\n    /* Ensure the new capacity does not result in fractional memory pages */\n    NewSize = ROUND_DOWN(NewSize, MM_PAGE_SIZE / sizeof(POOL_TRACKING_BIG_ALLOCATIONS));\n\n    /* Check if calculating the total byte size would cause an integer overflow */\n    if(NewSize > ((~(SIZE_T)0) / sizeof(POOL_TRACKING_BIG_ALLOCATIONS)))\n    {\n        /* Abort expansion to prevent allocating a truncated memory block */\n        return FALSE;\n    }\n\n    /* Compute the size required for the newly expanded tracking table */\n    AllocationBytes = NewSize * sizeof(POOL_TRACKING_BIG_ALLOCATIONS);\n\n    /* Allocate the required memory */\n    Status = AllocatePages(NonPagedPool, AllocationBytes, (PVOID*)&NewTable);\n    if(Status != STATUS_SUCCESS || !NewTable)\n    {\n        /* Memory allocation failed, abort the table expansion */\n        return FALSE;\n    }\n\n    /* Zero the newly allocated table */\n    RTL::Memory::ZeroMemory(NewTable, AllocationBytes);\n\n    /* Iterate through the allocated memory block */\n    for(Index = 0; Index < NewSize; Index++)\n    {\n        /* Mark the tracking entry as free and available */\n        NewTable[Index].VirtualAddress = (PVOID)MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE;\n    }\n\n    /* Start a guarded code block */\n    {\n        /* Acquire the tracking table lock and raise runlevel to DISPATCH level */\n        KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n        KE::SpinLockGuard TrackingTableLock(&BigAllocationsTrackingTableLock);\n\n        /* Verify if another thread has already expanded the table concurrently */\n        if(BigAllocationsTrackingTableSize >= NewSize)\n        {\n            /* Another thread has already expanded the table, discard changes */\n            Abort = TRUE;\n        }\n        else\n        {\n            /* Cache the legacy table pointer and calculate new hash mask */\n            HashMask = NewSize - 1;\n            OldTable = BigAllocationsTrackingTable;\n\n            /* Rehash and migrate all active entries from the old table */\n            for(Index = 0; Index < OldSize; Index++)\n            {\n                /* Bypass unallocated entries in the legacy table */\n                if((ULONG_PTR)OldTable[Index].VirtualAddress & MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE)\n                {\n                    /* Skip to the next entry */\n                    continue;\n                }\n\n                /* Compute the updated hash index */\n                Hash = ComputeHash(OldTable[Index].VirtualAddress) & HashMask;\n\n                /* Resolve hash collisions using linear probing */\n                while(!((ULONG_PTR)NewTable[Hash].VirtualAddress & MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE))\n                {\n                    /* Advance the bucket index and check for table boundary overflow */\n                    if(++Hash == NewSize)\n                    {\n                        /* Wrap the probing index back to the beginning */\n                        Hash = 0;\n                    }\n                }\n\n                /* Migrate the active entry to its new hash bucket */\n                NewTable[Hash] = OldTable[Index];\n            }\n\n            /* Activate the newly populated table globally */\n            BigAllocationsTrackingTable = NewTable;\n            BigAllocationsTrackingTableHash = NewSize - 1;\n            BigAllocationsTrackingTableSize = NewSize;\n        }\n    }\n\n    /* Check if another thread has already expanded the table concurrently */\n    if(Abort)\n    {\n        /* Free memory allocated for the new table and return */\n        FreePages(NewTable);\n        return TRUE;\n    }\n\n    /* Free memory allocated for the legacy table */\n    FreePages(OldTable, &PagesFreed);\n\n    /* Update the pool tracking statistics */\n    UnregisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'), PagesFreed << MM_PAGE_SHIFT, (MMPOOL_TYPE)0);\n    RegisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'), ROUND_UP(NewSize, MM_PAGE_SIZE), (MMPOOL_TYPE)0);\n\n    /* Return success */\n    return TRUE;\n}\n\n/**\n * Frees a previously allocated block of pages from the non-paged pool.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address of the non-paged pool pages allocation to free.\n *\n * @param PagesFreed\n *        Supplies a pointer to a variable that will receive the number of pages freed.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::FreeNonPagedPoolPages(IN PVOID VirtualAddress,\n                                     OUT PPFN_NUMBER PagesFreed)\n{\n    PMMFREE_POOL_ENTRY FreePage, NextPage, LastPage;\n    PMMMEMORY_LAYOUT MemoryLayout;\n    PFN_COUNT FreePages, Pages;\n    PFN_NUMBER PageFrameNumber;\n    PMMPFN Pfn, FirstPfn;\n    PMMPTE PointerPte;\n    ULONG Index;\n\n    /* Retrieve memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Get the first PTE of the allocation */\n    PointerPte = MM::Paging::GetPteAddress(VirtualAddress);\n    Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));\n\n    /* Verify that the address is within the non-paged pool */\n    if((VirtualAddress < MemoryLayout->NonPagedPoolStart ||\n        VirtualAddress >= MemoryLayout->NonPagedPoolEnd) &&\n       (VirtualAddress < MemoryLayout->NonPagedExpansionPoolStart ||\n        VirtualAddress >= MemoryLayout->NonPagedExpansionPoolEnd))\n    {\n        /* Address does not belong to the non-paged pool, raise kernel panic */\n        KE::Crash::Panic(0xC2, 0x43, (ULONG_PTR)VirtualAddress, 0, 0);\n    }\n\n    /* Basic sanity check to prevent double-frees or freeing unallocated memory */\n    if(Pfn->u3.e1.ReadInProgress == 0)\n    {\n        /* Address is not an allocation head, raise kernel panic */\n        KE::Crash::Panic(0xC2, 0x41, (ULONG_PTR)VirtualAddress, (ULONG_PTR)Pfn, 0);\n    }\n\n    /* Save the first PFN entry and initialize the allocation page counter */\n    FirstPfn = Pfn;\n    Pages = 1;\n\n    /* Seek to the end of the allocation */\n    while(Pfn->u3.e1.WriteInProgress == 0)\n    {\n        /* Get the next PTE and its PFN */\n        PointerPte = MM::Paging::GetNextPte(PointerPte);\n        Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));\n\n        /* Increment the page count */\n        Pages++;\n    }\n\n    /* Save the total free page count */\n    FreePages = Pages;\n\n    /* Acquire the Non-Paged pool lock and raise runlevel to DISPATCH level */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::QueuedSpinLockGuard NonPagedPoolSpinLock(NonPagedPoolLock);\n\n    /* Denote allocation boundaries */\n    FirstPfn->u3.e1.ReadInProgress = 0;\n    Pfn->u3.e1.WriteInProgress = 0;\n\n    /* Check if the address belongs to the non-paged expansion pool */\n    if(VirtualAddress >= MemoryLayout->NonPagedExpansionPoolStart)\n    {\n        /* Check if the allocation spans more than 3 pages and should be reclaimed */\n        if(Pages > 3)\n        {\n            /* Get the first PTE of the allocation and iterate over all pages */\n            PointerPte = MM::Paging::GetPteAddress(VirtualAddress);\n            for(Index = 0; Index < Pages; Index++)\n            {\n                /* Get the page frame number from the PTE */\n                PageFrameNumber = MM::Paging::GetPageFrameNumber(PointerPte);\n                Pfn = MM::Pfn::GetPfnEntry(PageFrameNumber);\n\n                /* Clear PFN shared count and mark the PFN as ready for removal */\n                Pfn->u2.ShareCount = 0;\n                Pfn->PteAddress = (PMMPTE)((ULONG_PTR)Pfn->PteAddress | 0x1);\n\n                /* Decrement the reference count of the page table */\n                MM::Pfn::DecrementReferenceCount(Pfn, PageFrameNumber, FALSE);\n\n                /* Invalidate the PTE */\n                MM::Paging::ClearPte(PointerPte);\n\n                /* Get the next PTE */\n                PointerPte = MM::Paging::GetNextPte(PointerPte);\n            }\n\n            /* Release reserved system PTEs back to the pool */\n            MM::Pte::ReleaseSystemPtes(MM::Paging::GetPteAddress(VirtualAddress), Pages, NonPagedPoolExpansion);\n\n            /* Check if a page count was requested */\n            if(PagesFreed != NULLPTR)\n            {\n                /* Return the number of pages freed */\n                *PagesFreed = FreePages;\n            }\n\n            /* Return success */\n            return STATUS_SUCCESS;\n        }\n    }\n\n    /* Get the next PTE */\n    PointerPte = MM::Paging::GetNextPte(PointerPte);\n\n    /* Check if the end of the initial nonpaged pool has been reached */\n    if(Pfn - MemoryLayout->PfnDatabase == NonPagedPoolFrameEnd)\n    {\n        /* Ignore the last page of the initial nonpaged pool */\n        Pfn = NULLPTR;\n    }\n    else\n    {\n        /* Check if the PTE is valid */\n        if(MM::Paging::PteValid(PointerPte))\n        {\n            /* Get the PFN entry for the page laying in either the expansion or initial non-paged pool */\n            Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));\n        }\n        else\n        {\n            /* Ignore the last page of the non-paged expansion pool */\n            Pfn = NULLPTR;\n        }\n    }\n\n    /* Check if the adjacent physical page following the allocation is free */\n    if((Pfn) && (Pfn->u3.e1.ReadInProgress == 0))\n    {\n        /* Calculate the virtual address of the adjacent forward free pool entry */\n        FreePage = (PMMFREE_POOL_ENTRY)((ULONG_PTR)VirtualAddress + (Pages << MM_PAGE_SHIFT));\n\n        /* Absorb the adjacent free block's pages into the current free page count */\n        FreePages += FreePage->Size;\n\n        /* Unlink the adjacent free block from its current segregated free list */\n        RTL::LinkedList::RemoveEntryList(&FreePage->List);\n    }\n\n    /* Get the free pool entry structure from the list entry */\n    FreePage = (PMMFREE_POOL_ENTRY)VirtualAddress;\n\n    /* Check if the beginning of the initial nonpaged pool has been reached */\n    if(FirstPfn - MemoryLayout->PfnDatabase == NonPagedPoolFrameStart)\n    {\n        /* Ignore the first page of the initial nonpaged pool */\n        Pfn = NULLPTR;\n    }\n    else\n    {\n        /* Calculate the PTE address for the page immediately preceding the allocation */\n        PointerPte = MM::Paging::AdvancePte(PointerPte, -Pages - 1);\n\n        /* Check if the PTE is valid */\n        if(MM::Paging::PteValid(PointerPte))\n        {\n            /* Get the PFN entry for the page laying in either the expansion or initial nonpaged pool */\n            Pfn = MM::Pfn::GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPte));\n        }\n        else\n        {\n            /* Ignore the first page of the expansion nonpaged pool */\n            Pfn = NULLPTR;\n        }\n    }\n\n    /* Check if the adjacent physical page preceding the allocation is free */\n    if((Pfn) && (Pfn->u3.e1.WriteInProgress == 0))\n    {\n        /* Retrieve the owner header of the preceding free block for backward coalescing */\n        FreePage = (PMMFREE_POOL_ENTRY)((ULONG_PTR)VirtualAddress - MM_PAGE_SIZE);\n        FreePage = FreePage->Owner;\n\n        /* Check if the allocation is small enough */\n        if(FreePage->Size < MM_MAX_FREE_PAGE_LIST_HEADS)\n        {\n            /* Remove the entry from the list */\n            RTL::LinkedList::RemoveEntryList(&FreePage->List);\n\n            /* Adjust the size of the free block to account for the allocated pages */\n            FreePage->Size += FreePages;\n\n            /* Calculate the new list index */\n            Index = MIN(FreePage->Size, MM_MAX_FREE_PAGE_LIST_HEADS) - 1;\n\n            /* Insert the entry into the head of the list */\n            RTL::LinkedList::InsertHeadList(&NonPagedPoolFreeList[Index], &FreePage->List);\n        }\n        else\n        {\n            /* Adjust the size of the free block to account for the allocated pages */\n            FreePage->Size += FreePages;\n        }\n    }\n\n    /* Check if backward coalescing failed, requiring the freed block to become a new list head */\n    if(FreePage == VirtualAddress)\n    {\n        /* Adjust the size of the free block to account for the allocated pages */\n        FreePage->Size = FreePages;\n\n        /* Calculate the new list index */\n        Index = MIN(FreePage->Size, MM_MAX_FREE_PAGE_LIST_HEADS) - 1;\n\n        /* Insert the entry into the head of the list */\n        RTL::LinkedList::InsertHeadList(&NonPagedPoolFreeList[Index], &FreePage->List);\n    }\n\n    /* Calculate the start and end boundaries for updating the owner pointers */\n    NextPage = (PMMFREE_POOL_ENTRY)VirtualAddress;\n    LastPage = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextPage + (FreePages << MM_PAGE_SHIFT));\n\n    /* Iterate through all freed and coalesced pages to update their owner reference */\n    while(NextPage != LastPage)\n    {\n        /* Link the page to the owner */\n        NextPage->Owner = FreePage;\n        NextPage = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextPage + MM_PAGE_SIZE);\n    }\n\n    /* Check if a page count was requested */\n    if(PagesFreed != NULLPTR)\n    {\n        /* Return the number of pages freed */\n        *PagesFreed = FreePages;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Frees a previously allocated block of pages from the paged pool.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address of the paged pool pages allocation to free.\n *\n * @param PagesFreed\n *        Supplies a pointer to a variable that will receive the number of pages freed.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::FreePagedPoolPages(IN PVOID VirtualAddress,\n                                  OUT PPFN_NUMBER PagesFreed)\n{\n    UNIMPLEMENTED;\n\n    /* Return not implemented status code */\n    return STATUS_NOT_IMPLEMENTED;\n}\n\n/**\n * Frees a previously allocated block of pages.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address of the pages allocation to free.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::FreePages(IN PVOID VirtualAddress)\n{\n    return FreePages(VirtualAddress, NULLPTR);\n}\n\n/**\n * Frees a previously allocated block of pages.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address of the pages allocation to free.\n *\n * @param PagesFreed\n *        Supplies a pointer to a variable that will receive the number of pages freed.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::FreePages(IN PVOID VirtualAddress,\n                         OUT PPFN_NUMBER PagesFreed)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Retrieve memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Check if the address is in the paged pool */\n    if(VirtualAddress >= MemoryLayout->PagedPoolStart && VirtualAddress < MemoryLayout->PagedPoolEnd)\n    {\n        /* Free pages from the paged pool */\n        return FreePagedPoolPages(VirtualAddress, PagesFreed);\n    }\n    else\n    {\n        /* Free pages from the non-paged pool */\n        return FreeNonPagedPoolPages(VirtualAddress, PagesFreed);\n    }\n}\n\n/**\n * Frees a previously allocated memory pool.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address of the pool allocation to free.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::FreePool(IN PVOID VirtualAddress)\n{\n    /* Free pool */\n    return FreePool(VirtualAddress, SIGNATURE32('N', 'o', 'n', 'e'));\n}\n\n/**\n * Frees a previously allocated memory pool.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address of the pool allocation to free.\n *\n * @param Tag\n *        Specifies the allocation identifying tag.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Allocator::FreePool(IN PVOID VirtualAddress,\n                        IN ULONG Tag)\n{\n    PPOOL_HEADER PoolEntry, NextPoolEntry;\n    PFN_NUMBER PageCount, RealPageCount;\n    PPOOL_DESCRIPTOR PoolDescriptor;\n    MMPOOL_TYPE PoolType;\n    USHORT BlockSize;\n    BOOLEAN Combined;\n    XTSTATUS Status;\n\n    /* Determine if the allocation is page-aligned */\n    if(PAGE_ALIGN(VirtualAddress) == VirtualAddress)\n    {\n        /* Determine and the memory pool type from the VA mapping */\n        PoolType = DeterminePoolType(VirtualAddress);\n\n        /* Verify run level for the specified pool */\n        VerifyRunLevel(PoolType, 0, VirtualAddress);\n\n        /* Retrieve original metadata while removing the allocation from the tracking table */\n        Tag = UnregisterBigAllocationTag(VirtualAddress, &PageCount, PoolType);\n        if(Tag & MM_POOL_PROTECTED)\n        {\n            /* Strip the protected pool bit */\n            Tag &= ~MM_POOL_PROTECTED;\n        }\n        else if(!Tag)\n        {\n            /* Fallback to a default tag */\n            Tag = SIGNATURE32('B', 'i', 'g', 'A');\n            PageCount = 1;\n        }\n\n        /* Remove the allocation from the tracking table */\n        UnregisterAllocationTag(Tag, PageCount << MM_PAGE_SHIFT, PoolType);\n\n        /* Retrieve the specific pool descriptor based on the masked pool type */\n        PoolDescriptor = PoolVector[PoolType];\n\n        /* Update the pool descriptor statistical counters */\n        RTL::Atomic::Increment32((PLONG)&PoolDescriptor->RunningFrees);\n        RTL::Atomic::ExchangeAdd64((PLONG_PTR)&PoolDescriptor->TotalBytes, -(LONG_PTR)(PageCount << MM_PAGE_SHIFT));\n\n        /* Release the underlying physical pages */\n        Status = FreePages(VirtualAddress, &RealPageCount);\n        if(Status == STATUS_SUCCESS)\n        {\n            /* Adjust the big allocation counter */\n            RTL::Atomic::ExchangeAdd32((PLONG)&PoolDescriptor->TotalBigAllocations, -(LONG)RealPageCount);\n        }\n\n        /* Return status code */\n        return Status;\n    }\n\n    /* Resolve the pool header */\n    PoolEntry = (PPOOL_HEADER)VirtualAddress;\n    PoolEntry--;\n\n    /* Extract the structural block size from the pool header */\n    BlockSize = PoolEntry->BlockSize;\n\n    /* Determine the underlying pool type and resolve its corresponding pool descriptor */\n    PoolType = (MMPOOL_TYPE)((PoolEntry->PoolType - 1) & MM_POOL_TYPE_MASK);\n    PoolDescriptor = PoolVector[PoolType];\n\n    /* Verify run level for the specified pool */\n    VerifyRunLevel(PoolType, 0, VirtualAddress);\n\n    /* Extract the allocation identifying tag and initialize the consolidation flag */\n    Tag = PoolEntry->PoolTag;\n    Combined = FALSE;\n\n    /* Check if the allocation tag carries the protected pool modifier */\n    if(Tag & MM_POOL_PROTECTED)\n    {\n        /* Strip the protected pool bit */\n        Tag &= ~MM_POOL_PROTECTED;\n    }\n\n    /* Remove the allocation from the tracking table */\n    UnregisterAllocationTag(Tag, BlockSize * MM_POOL_BLOCK_SIZE, (MMPOOL_TYPE)(PoolEntry->PoolType - 1));\n\n    /* Locate the adjacent forward pool block */\n    NextPoolEntry = GetPoolBlock(PoolEntry, BlockSize);\n\n    /* Update the pool descriptor statistical counters */\n    RTL::Atomic::Increment32((PLONG)&PoolDescriptor->RunningFrees);\n    RTL::Atomic::ExchangeAdd64((PLONG_PTR)&PoolDescriptor->TotalBytes, (LONG_PTR)(-BlockSize * MM_POOL_BLOCK_SIZE));\n\n    /* Acquire the pool lock */\n    PoolLockGuard PoolLock((MMPOOL_TYPE)(PoolDescriptor->PoolType & MM_POOL_TYPE_MASK));\n\n    /* Validate the structural integrity of the base block */\n    VerifyPoolBlocks(PoolEntry);\n\n    /* Ensure the adjacent forward block does not cross a page boundary */\n    if(PAGE_ALIGN(NextPoolEntry) != NextPoolEntry)\n    {\n        /* Check if the adjacent forward block is currently marked as free */\n        if(NextPoolEntry->PoolType == 0)\n        {\n            /* Flag the deallocation as having triggered a forward block merge */\n            Combined = TRUE;\n\n            /* Check if the forward block is large enough */\n            if(NextPoolEntry->BlockSize != 1)\n            {\n                /* Validate the list links */\n                VerifyPoolLinks(GetPoolFreeBlock(NextPoolEntry));\n\n                /* Unlink the forward block from its respective free list */\n                RemovePoolEntryList(GetPoolFreeBlock(NextPoolEntry));\n\n                /* Re-validate the surrounding list links */\n                VerifyPoolLinks(DecodePoolLink((GetPoolFreeBlock(NextPoolEntry))->Flink));\n                VerifyPoolLinks(DecodePoolLink((GetPoolFreeBlock(NextPoolEntry))->Blink));\n            }\n\n            /* Expand the size of the current block to include the forward free block */\n            PoolEntry->BlockSize += NextPoolEntry->BlockSize;\n        }\n    }\n\n    /* Check if a valid adjacent backward block exists */\n    if(PoolEntry->PreviousSize)\n    {\n        /* Resolve the adjacent backward block and check if it is free */\n        NextPoolEntry = GetPoolPreviousBlock(PoolEntry);\n        if(NextPoolEntry->PoolType == 0)\n        {\n            /* Flag the deallocation as having triggered a backward block merge */\n            Combined = TRUE;\n\n            /* Check if the backward free block contains embedded list links */\n            if(NextPoolEntry->BlockSize != 1)\n            {\n                /* Validate the backward block list links */\n                VerifyPoolLinks(GetPoolFreeBlock(NextPoolEntry));\n\n                /* Extract the backward block from the free list */\n                RemovePoolEntryList(GetPoolFreeBlock(NextPoolEntry));\n\n                /* Re-validate the adjacent free list */\n                VerifyPoolLinks(DecodePoolLink((GetPoolFreeBlock(NextPoolEntry))->Flink));\n                VerifyPoolLinks(DecodePoolLink((GetPoolFreeBlock(NextPoolEntry))->Blink));\n            }\n\n            /* Expand the backward block to include the freed base block */\n            NextPoolEntry->BlockSize += PoolEntry->BlockSize;\n\n            /* Shift the base entry pointer */\n            PoolEntry = NextPoolEntry;\n        }\n    }\n\n    /* Check whether the consolidated block spans an entire page */\n    if((PAGE_ALIGN(PoolEntry) == PoolEntry) &&\n       (PAGE_ALIGN(GetPoolNextBlock(PoolEntry)) == GetPoolNextBlock(PoolEntry)))\n    {\n        /* Release the pool lock */\n        PoolLock.Release();\n\n        /* Decrement the total page count and return the entire page back */\n        RTL::Atomic::ExchangeAdd32((PLONG)&PoolDescriptor->TotalPages, -1);\n        return FreePages(PoolEntry);\n    }\n\n    /* Finalize the consolidated block size and mark the primary header as free */\n    BlockSize = PoolEntry->BlockSize;\n    PoolEntry->PoolType = 0;\n\n    /* Check if any coalescing occurred */\n    if(Combined)\n    {\n        /* Resolve the new adjacent forward block and verify it resides on the same page */\n        NextPoolEntry = GetPoolNextBlock(PoolEntry);\n        if(PAGE_ALIGN(NextPoolEntry) != NextPoolEntry)\n        {\n            /* Adjust the backward reference of the forward block */\n            NextPoolEntry->PreviousSize = BlockSize;\n        }\n    }\n\n    /* Insert the freed and consolidated block into the pool free list */\n    InsertPoolHeadList(&PoolDescriptor->ListHeads[BlockSize - 1], GetPoolFreeBlock(PoolEntry));\n\n    /* Perform a final linkvalidation and return success */\n    VerifyPoolLinks(GetPoolFreeBlock(PoolEntry));\n    return STATUS_SUCCESS;\n}\n\n/**\n * Initializes the allocations tracking table during early system boot.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Allocator::InitializeAllocationsTracking(VOID)\n{\n    SIZE_T TableSize;\n    ULONG Index;\n    XTSTATUS Status;\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Not fully implemented yet, HIVE support needed */\n    UNIMPLEMENTED;\n\n    /* Retrieve memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* TODO: Retrieve tracking table size from the HIVE */\n    AllocationsTrackingTableSize = 0;\n\n    /* Calculate the target table size */\n    TableSize = MIN(AllocationsTrackingTableSize, (MemoryLayout->NonPagedPoolSize * MM_PAGE_SIZE) >> 8);\n\n    /* Perform a bit-scan to determine the highest set bit */\n    for(Index = 0; Index < 32; Index++)\n    {\n        /* Check if the lowest bit is currently set */\n        if(TableSize & 1)\n        {\n            /* Verify if this is the only remaining set bit */\n            if(!(TableSize & ~1))\n            {\n                /* Exit the loop as the highest bit has been found */\n                break;\n            }\n        }\n\n        /* Shift the size down by one bit to evaluate higher bits */\n        TableSize >>= 1;\n    }\n\n    /* Check if the bit-scan completed without finding any set bits */\n    if(Index == 32)\n    {\n        /* Apply the default size of 1024 entries */\n        AllocationsTrackingTableSize = 1024;\n    }\n    else\n    {\n        /* Calculate the aligned power of two size, enforcing a minimum of 64 entries */\n        AllocationsTrackingTableSize = MAX(1 << Index, 64);\n    }\n\n    /* Iteratively attempt to allocate the tracking table */\n    while(TRUE)\n    {\n        /* Prevent integer overflow when calculating the required byte size for the table */\n        if(AllocationsTrackingTableSize + 1 > (MAXULONG_PTR / sizeof(POOL_TRACKING_TABLE)))\n        {\n            /* Halve the requested entry count and restart the evaluation */\n            AllocationsTrackingTableSize >>= 1;\n            continue;\n        }\n\n        /* Attempt to allocate physical memory for the table */\n        Status = MM::Allocator::AllocatePages(NonPagedPool,\n                                              (AllocationsTrackingTableSize + 1) *\n                                              sizeof(POOL_TRACKING_TABLE), (PVOID *)&AllocationsTrackingTable);\n\n        /* Check if the allocation succeeded */\n        if(Status != STATUS_SUCCESS || !AllocationsTrackingTable)\n        {\n            /* Check if the allocation failed duefor a single entry */\n            if(AllocationsTrackingTableSize == 1)\n            {\n                /* Failed to initialize the pool tracker, raise kernel panic */\n                KE::Crash::Panic(0x41, TableSize, (ULONG_PTR)~0, (ULONG_PTR)~0, (ULONG_PTR)~0);\n            }\n\n            /* Halve the requested entry count */\n            AllocationsTrackingTableSize >>= 1;\n        }\n        else\n        {\n            /* Allocation succeeded */\n            break;\n        }\n    }\n\n    /* Increment the table size to account for the overflow bucket entry */\n    AllocationsTrackingTableSize++;\n\n    /* Zero the entire memory used by the table */\n    RtlZeroMemory(AllocationsTrackingTable, AllocationsTrackingTableSize * sizeof(POOL_TRACKING_TABLE));\n\n    /* Assign the global tracking table as the local table for the bootstrap processor */\n    TagTables[0] = AllocationsTrackingTable;\n\n    /* Calculate and store the hash mask */\n    AllocationsTrackingTableMask = AllocationsTrackingTableSize - 2;\n\n    /* Initialize the spinlock used to synchronize concurrent modifications to the tracking table */\n    KE::SpinLock::InitializeSpinLock(&AllocationsTrackingTableLock);\n}\n\n/**\n * Initializes the big allocations tracking table during early system boot.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Allocator::InitializeBigAllocationsTracking(VOID)\n{\n    SIZE_T TableSize;\n    ULONG Index;\n    XTSTATUS Status;\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Not fully implemented yet, HIVE support needed */\n    UNIMPLEMENTED;\n\n    /* Retrieve memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* TODO: Retrieve initial big allocation table size from the HIVE */\n    BigAllocationsTrackingTableSize = 0;\n\n    /* Calculate the target table size */\n    TableSize = MIN(BigAllocationsTrackingTableSize, (MemoryLayout->NonPagedPoolSize * MM_PAGE_SIZE) >> 12);\n\n    /* Perform a bit-scan to determine the highest set bit */\n    for(Index = 0; Index < 32; Index++)\n    {\n        /* Check if the lowest bit is currently set */\n        if(TableSize & 1)\n        {\n            /* Verify if this is the only remaining set bit */\n            if(!(TableSize & ~1))\n            {\n                /* Exit the loop as the highest bit has been found */\n                break;\n            }\n        }\n\n        /* Shift the size down by one bit to evaluate higher bits */\n        TableSize >>= 1;\n    }\n\n    /* Check if the bit-scan completed without finding any set bits */\n    if(Index == 32)\n    {\n        /* Apply the default size of 4096 entries */\n        BigAllocationsTrackingTableSize = 4096;\n    }\n    else\n    {\n        /* Calculate the aligned power of two size, enforcing a minimum of 64 entries */\n        BigAllocationsTrackingTableSize = MAX(1 << Index, 64);\n    }\n\n    /* Iteratively attempt to allocate the tracking table */\n    while(TRUE)\n    {\n        /* Prevent integer overflow when calculating the required byte size for the table */\n        if((BigAllocationsTrackingTableSize + 1) > (MAXULONG_PTR / sizeof(POOL_TRACKING_BIG_ALLOCATIONS)))\n        {\n            /* Halve the requested entry count and restart the evaluation */\n            BigAllocationsTrackingTableSize >>= 1;\n            continue;\n        }\n\n        /* Attempt to allocate physical memory for the table */\n        Status = AllocatePages(NonPagedPool,\n                               BigAllocationsTrackingTableSize * sizeof(POOL_TRACKING_BIG_ALLOCATIONS),\n                               (PVOID*)&BigAllocationsTrackingTable);\n\n        /* Check if the allocation succeeded */\n        if(Status != STATUS_SUCCESS || !BigAllocationsTrackingTable)\n        {\n            /* Check if the allocation failed duefor a single entry */\n            if(BigAllocationsTrackingTableSize == 1)\n            {\n                /* Failed to initialize the pool tracker, raise kernel panic */\n                KE::Crash::Panic(0x41, TableSize, (ULONG_PTR)~0, (ULONG_PTR)~0, (ULONG_PTR)~0);\n            }\n\n            /* Halve the requested entry count */\n            BigAllocationsTrackingTableSize >>= 1;\n        }\n        else\n        {\n            /* Allocation succeeded */\n            break;\n        }\n    }\n\n    /* Zero the entire memory used by the table */\n    RtlZeroMemory(BigAllocationsTrackingTable, BigAllocationsTrackingTableSize * sizeof(POOL_TRACKING_BIG_ALLOCATIONS));\n\n    /* Iterate through the newly allocated table */\n    for(Index = 0; Index < BigAllocationsTrackingTableSize; Index++)\n    {\n        /* Mark the individual pool tracker entry as free and available */\n        BigAllocationsTrackingTable[Index].VirtualAddress = (PVOID)MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE;\n    }\n\n    /* Calculate and store the hash mask */\n    BigAllocationsTrackingTableHash = BigAllocationsTrackingTableSize - 1;\n\n    /* Initialize the spinlock used to synchronize concurrent modifications to the tracking table */\n    KE::SpinLock::InitializeSpinLock(&BigAllocationsTrackingTableLock);\n\n    /* Register the allocation in the tracking table */\n    RegisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'),\n                          SIZE_TO_PAGES(BigAllocationsTrackingTableSize * sizeof(POOL_TRACKING_BIG_ALLOCATIONS)),\n                          NonPagedPool);\n}\n\n/**\n * Registers a pool memory allocation in the tracking table.\n *\n * @param Tag\n *        Supplies the tag used to identify the allocation.\n *\n * @param Bytes\n *        Supplies the size of the allocation.\n *\n * @param PoolType\n *        Specifies the type of pool from which the memory was allocated.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Allocator::RegisterAllocationTag(IN ULONG Tag,\n                                     IN SIZE_T Bytes,\n                                     IN MMPOOL_TYPE PoolType)\n{\n    PPOOL_TRACKING_TABLE CpuTable, TableEntry;\n    ULONG Hash, Index, Processor;\n\n    /* Retrieve the local tracking table for the current processor */\n    Processor = KE::Processor::GetCurrentProcessorNumber();\n    CpuTable = TagTables[Processor];\n\n    /* Strip the protected pool bit */\n    Tag &= ~MM_POOL_PROTECTED;\n\n    /* Compute the initial hash index */\n    Hash = ComputeHash(Tag, AllocationsTrackingTableMask);\n    Index = Hash;\n\n    /* Probe the tracking table until a match or an empty slot is found */\n    do\n    {\n        /* Fetch the tracker entry from the CPU table */\n        TableEntry = &CpuTable[Hash];\n\n        /* Check if the current entry tracks the requested pool tag */\n        if(TableEntry->Tag == Tag)\n        {\n            /* Update the appropriate statistics based on the pool type */\n            if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool)\n            {\n                /* Update the non-paged allocation statistics */\n                RTL::Atomic::Increment32(&TableEntry->NonPagedAllocations);\n                RTL::Atomic::ExchangeAdd64((PLONG_PTR)&TableEntry->NonPagedBytes, Bytes);\n            }\n            else\n            {\n                /* Update the paged allocation statistics */\n                RTL::Atomic::Increment32(&TableEntry->PagedAllocations);\n                RTL::Atomic::ExchangeAdd64((PLONG_PTR)&TableEntry->PagedBytes, Bytes);\n            }\n\n            /* The allocation has been successfully tracked, return */\n            return;\n        }\n\n        /* Check if the CPU table is entirely empty */\n        if(TableEntry->Tag == 0)\n        {\n            /* Check if another processor has claimed this slot in the global table */\n            if(AllocationsTrackingTable[Hash].Tag != 0)\n            {\n                /* Synchronize the local table with the global table */\n                TableEntry->Tag = AllocationsTrackingTable[Hash].Tag;\n\n                /* Restart the loop to evaluation */\n                continue;\n            }\n\n            /* Check if this is not the designated overflow bucket */\n            if(Hash != (AllocationsTrackingTableSize - 1))\n            {\n                /* Start a guarded code block */\n                {\n                    /* Acquire the tracking table lock */\n                    KE::SpinLockGuard TrackingTableLock(&AllocationsTrackingTableLock);\n\n                    /* Perform a double-checked lock */\n                    if(AllocationsTrackingTable[Hash].Tag == 0)\n                    {\n                        /* Claim the slot in both, local and global tracking tables */\n                        AllocationsTrackingTable[Hash].Tag = Tag;\n                        TableEntry->Tag = Tag;\n                    }\n                }\n\n                /* Restart the loop */\n                continue;\n            }\n        }\n\n        /* Advance to the next index as hash collision occurred */\n        Hash = (Hash + 1) & AllocationsTrackingTableMask;\n    }\n    while(Hash != Index);\n\n    /* Fallback to the expansion path */\n    RegisterAllocationTagExpansion(Tag, Bytes, PoolType);\n}\n\n/**\n * Registers a pool memory allocation in the tracking expansion table.\n *\n * @param Tag\n *        Supplies the tag used to identify the allocation.\n *\n * @param Bytes\n *        Supplies the size of the allocation.\n *\n * @param PoolType\n *        Specifies the type of pool from which the memory was allocated.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Allocator::RegisterAllocationTagExpansion(IN ULONG Tag,\n                                              IN SIZE_T Bytes,\n                                              IN MMPOOL_TYPE PoolType)\n{\n    PPOOL_TRACKING_TABLE NewTrackingTable, OldTrackingTable;\n    SIZE_T Footprint, NewSize, Size;\n    BOOLEAN UseOverflowBucket;\n    PFN_NUMBER FreedPages;\n    XTSTATUS Status;\n    ULONG Hash;\n\n    /* Initialize local state */\n    NewTrackingTable = NULLPTR;\n    OldTrackingTable = NULLPTR;\n    UseOverflowBucket = FALSE;\n\n    /* Start a guarded code block */\n    {\n        /* Acquire the tracking table lock */\n        KE::SpinLockGuard TrackingTableLock(&AllocationsTrackingTableLock);\n\n        /* Scan the expansion table to locate the requested tag */\n        for(Hash = 0; Hash < AllocationsTrackingExpansionTableSize; Hash++)\n        {\n            /* Check if the current entry already tracks the requested pool tag */\n            if(AllocationsTrackingExpansionTable[Hash].Tag == Tag)\n            {\n                /* Target entry found, break out */\n                break;\n            }\n\n            /* Check if an unassigned slot has been reached */\n            if(AllocationsTrackingExpansionTable[Hash].Tag == 0)\n            {\n                /* Claim the empty slot for the new pool tag and stop searching */\n                AllocationsTrackingExpansionTable[Hash].Tag = Tag;\n                break;\n            }\n        }\n\n        /* Check if the tag was successfully located or a new slot was successfully claimed */\n        if(Hash != AllocationsTrackingExpansionTableSize)\n        {\n            /* Update the appropriate statistics based on the pool type */\n            if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool)\n            {\n                /* Update the non-paged allocation statistics */\n                AllocationsTrackingExpansionTable[Hash].NonPagedAllocations++;\n                AllocationsTrackingExpansionTable[Hash].NonPagedBytes += Bytes;\n            }\n            else\n            {\n                /* Update the paged allocation statistics */\n                AllocationsTrackingExpansionTable[Hash].PagedAllocations++;\n                AllocationsTrackingExpansionTable[Hash].PagedBytes += Bytes;\n            }\n\n            /* Nothing more to do */\n            return;\n        }\n\n        /* Check if the global overflow bucket has been activated */\n        if(AllocationsTrackingTable[AllocationsTrackingTableSize - 1].Tag != 0)\n        {\n            /* Use the overflow bucket */\n            UseOverflowBucket = TRUE;\n        }\n        else\n        {\n            /* Calculate the exact bytes of the expansion table */\n            Size = AllocationsTrackingExpansionTableSize * sizeof(POOL_TRACKING_TABLE);\n\n            /* Determine the required physical memory */\n            Footprint = ROUND_UP(Size, MM_PAGE_SIZE) + MM_PAGE_SIZE;\n\n            /* Calculate the usable byte size */\n            NewSize = ((Footprint / sizeof(POOL_TRACKING_TABLE)) * sizeof(POOL_TRACKING_TABLE));\n\n            /* Allocate memory for the expanded tracking table */\n            Status = AllocatePages(NonPagedPool, NewSize, (PVOID *)&NewTrackingTable);\n            if(Status != STATUS_SUCCESS || !NewTrackingTable)\n            {\n                /* Activate the global overflow bucket */\n                AllocationsTrackingTable[AllocationsTrackingTableSize - 1].Tag = SIGNATURE32('O', 'v', 'f', 'l');\n                UseOverflowBucket = TRUE;\n            }\n            else\n            {\n                /* Check if a previous expansion table exists */\n                if(AllocationsTrackingExpansionTable != NULLPTR)\n                {\n                    /* Migrate the existing tracking entries into the new expansion table */\n                    RtlCopyMemory(NewTrackingTable, AllocationsTrackingExpansionTable, Size);\n                }\n\n                /* Zero out the added usable space */\n                RtlZeroMemory((PVOID)(NewTrackingTable + AllocationsTrackingExpansionTableSize), NewSize - Size);\n\n                /* Swap the active expansion table pointers and update the entry count */\n                OldTrackingTable = AllocationsTrackingExpansionTable;\n                AllocationsTrackingExpansionTable = NewTrackingTable;\n                AllocationsTrackingExpansionTableSize = Footprint / sizeof(POOL_TRACKING_TABLE);;\n\n                /* Register the new allocation tag */\n                RegisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'), Footprint, NonPagedPool);\n            }\n        }\n    }\n\n    /* Handle the fallback scenario */\n    if(UseOverflowBucket)\n    {\n        /* Target the overflow bucket at the end of the tracking table */\n        Hash = (ULONG)AllocationsTrackingTableSize - 1;\n\n        /* Update the appropriate statistics based on the pool type */\n        if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool)\n        {\n            /* Update the non-paged allocation statistics */\n            RTL::Atomic::Increment32((PLONG)&AllocationsTrackingTable[Hash].NonPagedAllocations);\n            RTL::Atomic::ExchangeAdd64((PLONG_PTR)&AllocationsTrackingTable[Hash].NonPagedBytes, Bytes);\n        }\n        else\n        {\n            /* Update the paged allocation statistics */\n            RTL::Atomic::Increment32((PLONG)&AllocationsTrackingTable[Hash].PagedAllocations);\n            RTL::Atomic::ExchangeAdd64((PLONG_PTR)&AllocationsTrackingTable[Hash].PagedBytes, Bytes);\n        }\n\n        /* Nothing more to do */\n        return;\n    }\n\n    /* Check if an older expansion table needs to be freed */\n    if(OldTrackingTable != NULLPTR)\n    {\n        /* Free the old tracking table and unregister the allocation tag */\n        FreePages(OldTrackingTable, &FreedPages);\n        UnregisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'), (SIZE_T)FreedPages * MM_PAGE_SIZE, NonPagedPool);\n    }\n\n    /* Register the caller's original allocation */\n    RegisterAllocationTagExpansion(Tag, Bytes, PoolType);\n}\n\n/**\n * Registers a big allocation within the tracking table.\n *\n * @param VirtualAddress\n *        Supplies the virtual address of the big allocation.\n *\n * @param Tag\n *        Supplies the tag used to identify the allocation.\n *\n * @param Pages\n *        Supplies the number of physical pages backing the allocation.\n *\n * @param PoolType\n *        Specifies the type of pool from which the memory was allocated.\n *\n * @return This routine returns TRUE on successful insertion, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Allocator::RegisterBigAllocationTag(IN PVOID VirtualAddress,\n                                        IN ULONG Tag,\n                                        IN ULONG Pages,\n                                        IN MMPOOL_TYPE PoolType)\n{\n    PPOOL_TRACKING_BIG_ALLOCATIONS Entry;\n    BOOLEAN Inserted, RequiresExpansion;\n    ULONG Hash, StartHash;\n\n    /* Wrap the insertion logic in a retry loop */\n    while(TRUE)\n    {\n        /* Initialize local variables */\n        Inserted = FALSE;\n        RequiresExpansion = FALSE;\n\n        /* Calculate the initial hash bucket index */\n        Hash = ComputeHash(VirtualAddress);\n\n        /* Start a guarded code block */\n        {\n            /* Acquire the tracking table lock and raise runlevel to DISPATCH level */\n            KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n            KE::SpinLockGuard TrackingTableLock(&BigAllocationsTrackingTableLock);\n\n            /* Retrieve the tracker entry */\n            Hash &= BigAllocationsTrackingTableHash;\n            StartHash = Hash;\n\n            /* Traverse the hash table */\n            do\n            {\n                /* Retrieve the tracker entry */\n                Entry = &BigAllocationsTrackingTable[Hash];\n\n                /* Check if the current bucket is marked as free */\n                if((ULONG_PTR)Entry->VirtualAddress & MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE)\n                {\n                    /* Populate the available bucket with the allocation metadata */\n                    Entry->NumberOfPages = Pages;\n                    Entry->Tag = Tag;\n                    Entry->VirtualAddress = VirtualAddress;\n\n                    /* Increment the global usage counter */\n                    BigAllocationsInUse++;\n\n                    /* Determine if the table capacity has reached the critical 75% threshold */\n                    if(BigAllocationsInUse > (BigAllocationsTrackingTableSize * 3 / 4))\n                    {\n                        /* Flag the table for expansion */\n                        RequiresExpansion = TRUE;\n                    }\n\n                    /* Mark insertion as successful and break out of the probing loop */\n                    Inserted = TRUE;\n                    break;\n                }\n\n                /* Advance to the next bucket */\n                if(++Hash >= BigAllocationsTrackingTableSize)\n                {\n                    /* Wrap the index back to the beginning of the table */\n                    Hash = 0;\n                }\n\n                /* If the traversal has wrapped entirely back to the starting index, the table is saturated */\n                if(Hash == StartHash)\n                {\n                    /* Break out of the probing loop */\n                    break;\n                }\n            }\n            while(Hash != StartHash);\n        }\n\n        /* Check if the insertion succeeded */\n        if(Inserted)\n        {\n            /* Check if a table expansion is required */\n            if(RequiresExpansion)\n            {\n                /* Trigger a table expansion asynchronously */\n                ExpandBigAllocationsTable();\n            }\n\n            /* Return success */\n            return TRUE;\n        }\n\n        /* The table is completely saturated, attempt to expand the table */\n        if(ExpandBigAllocationsTable())\n        {\n            /* The table was successfully expanded, retry the insertion */\n            continue;\n        }\n\n        /* Table expansion failed, break out of the retry loop */\n        break;\n    }\n\n    /* Return failure */\n    return FALSE;\n}\n\n/**\n * Unregisters a pool memory allocation in the tracking table.\n *\n * @param Tag\n *        Supplies the tag used to identify the allocation.\n *\n * @param Bytes\n *        Supplies the size of the allocation.\n *\n * @param PoolType\n *        Specifies the type of pool from which the memory was allocated.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Allocator::UnregisterAllocationTag(IN ULONG Tag,\n                                       IN SIZE_T Bytes,\n                                       IN MMPOOL_TYPE PoolType)\n{\n    ULONG Hash, Index;\n    PPOOL_TRACKING_TABLE CpuTable;\n    PPOOL_TRACKING_TABLE TableEntry;\n    ULONG Processor;\n\n    /* Retrieve the local tracking table for the current processor */\n    Processor = KE::Processor::GetCurrentProcessorNumber();\n    CpuTable = TagTables[Processor];\n\n    /* Strip the protected pool bit */\n    Tag &= ~MM_POOL_PROTECTED;\n\n    /* Compute the initial hash index */\n    Hash = ComputeHash(Tag, AllocationsTrackingTableMask);\n    Index = Hash;\n\n    /* Probe the tracking table until a match or an empty slot is found */\n    do\n    {\n        /* Fetch the tracker entry from the CPU table */\n        TableEntry = &CpuTable[Hash];\n\n        /* Check if the current entry tracks the requested pool tag */\n        if(TableEntry->Tag == Tag)\n        {\n            /* Update the appropriate statistics based on the pool type */\n            if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool)\n            {\n                /* Update the non-paged allocation statistics */\n                RTL::Atomic::Increment32(&TableEntry->NonPagedFrees);\n                RTL::Atomic::ExchangeAdd64((PLONG_PTR)&TableEntry->NonPagedBytes, 0 - Bytes);\n            }\n            else\n            {\n                /* Update the paged allocation statistics */\n                RTL::Atomic::Increment32(&TableEntry->PagedFrees);\n                RTL::Atomic::ExchangeAdd64((PLONG_PTR)&TableEntry->PagedBytes, 0 - Bytes);\n            }\n\n            /* The allocation has been successfully tracked, return */\n            return;\n        }\n\n        /* Check if the CPU table is entirely empty */\n        if(TableEntry->Tag == 0)\n        {\n            /* Check if another processor has claimed this slot in the global table */\n            if(AllocationsTrackingTable[Hash].Tag != 0)\n            {\n                /* Synchronize the local table with the global table */\n                TableEntry->Tag = AllocationsTrackingTable[Hash].Tag;\n\n                /* Restart the loop to evaluation */\n                continue;\n            }\n        }\n\n        /* Advance to the next index as hash collision occurred */\n        Hash = (Hash + 1) & AllocationsTrackingTableMask;\n    }\n    while(Hash != Index);\n\n    /* Fallback to the expansion path */\n    UnregisterAllocationTagExpansion(Tag, Bytes, PoolType);\n}\n\n/**\n * Unregisters a pool memory allocation in the tracking expansion table.\n *\n * @param Tag\n *        Supplies the tag used to identify the allocation.\n *\n * @param Bytes\n *        Supplies the size of the allocation.\n *\n * @param PoolType\n *        Specifies the type of pool from which the memory was allocated.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Allocator::UnregisterAllocationTagExpansion(IN ULONG Tag,\n                                                IN SIZE_T Bytes,\n                                                IN MMPOOL_TYPE PoolType)\n{\n    PPOOL_TRACKING_TABLE CpuTable;\n    ULONG Hash;\n    ULONG Processor;\n\n    /* Start a guarded code block */\n    {\n        /* Acquire the tracking table lock */\n        KE::SpinLockGuard TrackingTableLock(&AllocationsTrackingTableLock);\n\n        /* Scan the expansion table */\n        for(Hash = 0; Hash < AllocationsTrackingExpansionTableSize; Hash++)\n        {\n            /* Check if the current entry matches the tag */\n            if(AllocationsTrackingExpansionTable[Hash].Tag == Tag)\n            {\n                /* Update the appropriate statistics based on the pool type */\n                if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool)\n                {\n                    /* Update the non-paged allocation statistics */\n                    AllocationsTrackingExpansionTable[Hash].NonPagedFrees++;\n                    AllocationsTrackingExpansionTable[Hash].NonPagedBytes -= Bytes;\n                }\n                else\n                {\n                    /* Update the paged allocation statistics */\n                    AllocationsTrackingExpansionTable[Hash].PagedFrees++;\n                    AllocationsTrackingExpansionTable[Hash].PagedBytes -= Bytes;\n                }\n\n                /* Nothing more to do */\n                return;\n            }\n\n            /* Check if an empty slot is encountered */\n            if(AllocationsTrackingExpansionTable[Hash].Tag == 0)\n            {\n                /* Stop scanning as all active tags are contiguous */\n                break;\n            }\n        }\n    }\n\n    /* Target the index of the overflow bucket */\n    Hash = (ULONG)AllocationsTrackingTableSize - 1;\n\n    /* Retrieve the local tracking table for the current processor */\n    Processor = KE::Processor::GetCurrentProcessorNumber();\n    CpuTable = TagTables[Processor];\n\n    /* Update the appropriate statistics based on the pool type */\n    if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool)\n    {\n        /* Update the non-paged allocation statistics */\n        RTL::Atomic::Increment32((PLONG)&CpuTable[Hash].NonPagedFrees);\n        RTL::Atomic::ExchangeAdd64((PLONG_PTR)&CpuTable[Hash].NonPagedBytes, 0 - Bytes);\n    }\n    else\n    {\n        /* Update the paged allocation statistics */\n        RTL::Atomic::Increment32((PLONG)&CpuTable[Hash].PagedFrees);\n        RTL::Atomic::ExchangeAdd64((PLONG_PTR)&CpuTable[Hash].PagedBytes, 0 - Bytes);\n    }\n}\n\n/**\n * Unregisters a big allocation from the tracking table and retrieves its metadata.\n *\n * @param VirtualAddress\n *        Supplies the virtual address of the big allocation to be removed.\n *\n * @param Pages\n *        Supplies the number of physical pages backing the allocation.\n *\n * @param PoolType\n *        Specifies the pool type of the allocation.\n *\n * @return This routine returns the allocation pool tag if found, or a default signature otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Allocator::UnregisterBigAllocationTag(IN PVOID VirtualAddress,\n                                          OUT PULONG_PTR Pages,\n                                          IN MMPOOL_TYPE PoolType)\n{\n    ULONG Hash, StartHash;\n    ULONG PoolTag;\n    BOOLEAN Found;\n    PPOOL_TRACKING_BIG_ALLOCATIONS Entry;\n\n    /* Initialize default state */\n    Found = FALSE;\n\n    /* Calculate the initial hash bucket index */\n    Hash = ComputeHash(VirtualAddress);\n\n    /* Start a guarded code block */\n    {\n        /* Acquire the tracking table lock and raise runlevel to DISPATCH level */\n        KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n        KE::SpinLockGuard TrackingTableLock(&BigAllocationsTrackingTableLock);\n\n        /* Mask the computed hash and record the starting bucket */\n        Hash &= BigAllocationsTrackingTableHash;\n        StartHash = Hash;\n\n        /* Traverse the hash table using linear probing to pinpoint the exact allocation address */\n        while(TRUE)\n        {\n            /* Retrieve the tracker entry */\n            Entry = &BigAllocationsTrackingTable[Hash];\n\n            /* Check if the bucket contains the target virtual address */\n            if(Entry->VirtualAddress == VirtualAddress)\n            {\n                /* Capture the allocation metadata */\n                *Pages = Entry->NumberOfPages;\n                PoolTag = Entry->Tag;\n\n                /* Invalidate the entry */\n                Entry->VirtualAddress = (PVOID)MM_POOL_BIG_ALLOCATIONS_ENTRY_FREE;\n\n                /* Decrement the global usage counter */\n                BigAllocationsInUse--;\n\n                /* Update the found flag and break out of the probing loop */\n                Found = TRUE;\n                break;\n            }\n\n            /* Advance to the next bucket */\n            if(++Hash >= BigAllocationsTrackingTableSize)\n            {\n                /* Wrap the hash index back to zero */\n                Hash = 0;\n            }\n\n            /* Check if the traversal has wrapped entirely back to the starting index */\n            if(Hash == StartHash)\n            {\n                /* Abort the search */\n                break;\n            }\n        }\n    }\n\n    /* Evaluate the result of the table traversal */\n    if(Found)\n    {\n        /* Return the original tag captured from the tracker */\n        return PoolTag;\n    }\n\n    /* Return an empty page count and a fallback tag */\n    *Pages = 0;\n    return SIGNATURE32('B', 'i', 'g', 'A');\n}\n"
  },
  {
    "path": "xtoskrnl/mm/amd64/mmgr.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/amd64/mmgr.cc\n * DESCRIPTION:     Memory Manager\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Calculates the maximum possible size of the non-paged pool.\n *\n * @param PoolSize\n *        A pointer to a variable that will receive the number of pages available for the non-paged pool.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeMaximumNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)\n{\n    ULONG_PTR MaximumNonPagedPoolSize;\n\n    /* Start with the 1MiB and add 400KiB for each MiB above 16MiB */\n    MaximumNonPagedPoolSize = 1048576 + (((MM::Pfn::GetNumberOfPhysicalPages() - 4096) / 256) * 409600);\n\n    /* Check if non-paged pool does not exceed 128GiB */\n    if(MaximumNonPagedPoolSize > 137438953472)\n    {\n        /* Limit non-paged pool size to 128GiB */\n        MaximumNonPagedPoolSize = 137438953472;\n    }\n\n    /* Return non-paged pool size */\n    *PoolSize = SIZE_TO_PAGES(MaximumNonPagedPoolSize);\n}\n\n/**\n * Calculates the size of the non-paged pool.\n *\n * @param PoolSize\n *        A pointer to a variable that will receive the number of pages available for the non-paged pool.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)\n{\n    ULONG_PTR NonPagedPoolSize;\n\n    /* Start with 1MiB and add 32KiB for each MiB above 16MiB */\n    NonPagedPoolSize = 1048576 + (((MM::Pfn::GetNumberOfPhysicalPages() - 4096) / 256) * 32768);\n\n    /* Check if non-paged pool does not exceed 128GiB */\n    if(NonPagedPoolSize > 137438953472)\n    {\n        /* Limit non-paged pool size to 128GiB */\n        NonPagedPoolSize = 137438953472;\n    }\n\n    /* Return non-paged pool size in pages, aligned up to page size boundary */\n    *PoolSize = SIZE_TO_PAGES(ROUND_UP(NonPagedPoolSize, MM_PAGE_SIZE));\n}\n\n/**\n * Calculates the size of the paged pool.\n *\n * @param PoolSize\n *        A pointer to a variable that will receive the number of pages available for the paged pool.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputePagedPoolSize(OUT PPFN_NUMBER PoolSize)\n{\n    ULONGLONG PagedPoolSize, PteCount;\n    ULONG PtesPerPage;\n\n    /* Start with 4x maximum non-paged pool size and at least 48MiB */\n    ComputeMaximumNonPagedPoolSize(&PagedPoolSize);\n    PagedPoolSize *= 4 * MM_PAGE_SIZE;\n\n    /* Ensure that paged pool size is at least 48MiB */\n    if(PagedPoolSize < 50331648)\n    {\n        /* Increase paged pool size to at least 48MiB */\n        PagedPoolSize = 50331648;\n    }\n\n    /* Check if paged pool does not overlap non-paged pool */\n    if(PagedPoolSize > (ULONGLONG)MemoryLayout.NonPagedSystemPoolStart - (ULONGLONG)MemoryLayout.PagedPoolStart)\n    {\n        /* Limit paged pool size to maximum possible */\n        PagedPoolSize = (ULONGLONG)MemoryLayout.NonPagedSystemPoolStart - (ULONGLONG)MemoryLayout.PagedPoolStart;\n    }\n\n    /* Check if paged pool does not exceed 128GiB */\n    if(PagedPoolSize > 137438953472)\n    {\n        /* Limit paged pool size to 128GiB */\n        PagedPoolSize = 137438953472;\n    }\n\n    /* Get the number of PTEs per page and calculate size of paged pool */\n    PtesPerPage = MM::Pte::GetPtesPerPage();\n    PteCount = ((SIZE_TO_PAGES(PagedPoolSize) + (PtesPerPage - 1)) / PtesPerPage);\n\n    /* Return paged pool size */\n    *PoolSize = PteCount * PtesPerPage;\n}\n\n/**\n * Calculates the size of the session space.\n *\n * @param SpaceSize\n *        A pointer to a variable that will receive the number of pages available by the session space.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeSessionSpaceSize(OUT PPFN_NUMBER SpaceSize)\n{\n    PFN_NUMBER SessionSpaceSize;\n\n    /* Session Pool, Session View, Session Image, Session Working Set and System View takes 1120MiB */\n    SessionSpaceSize = 1174405120;\n\n    /* Return number of pages used by the session space */\n    *SpaceSize = SessionSpaceSize / MM_PAGE_SIZE;\n}\n\n/**\n * Calculates the size of the system PTEs.\n *\n * @param PteSize\n *        A pointer to a variable that will receive the number of system PTEs.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeSystemPteSize(OUT PPFN_NUMBER PteSize)\n{\n    PFN_NUMBER SystemPteSize;\n\n    /* Check if system has less than 24MiB of physical memory */\n    if(MM::Pfn::GetNumberOfPhysicalPages() < 6144)\n    {\n        /* Set minimal system PTE size */\n        SystemPteSize = 7000;\n    }\n    else\n    {\n        /* Use standard system PTE size */\n        SystemPteSize = 11000;\n\n        /* Check if system has more than 32MiB of physical memory */\n        if(MM::Pfn::GetNumberOfPhysicalPages() > 8192)\n        {\n            /* Double system PTE size */\n            SystemPteSize *= 2;\n\n            /* Check if system has more than 256MiB of physical memory */\n            if(MM::Pfn::GetNumberOfPhysicalPages() > 65536)\n            {\n                /* Double system PTE size */\n                SystemPteSize *= 2;\n            }\n        }\n    }\n\n    /* Return system PTE size */\n    *PteSize = SystemPteSize;\n}\n\n/**\n * Dumps the kernel's memory layout.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::DumpMemoryLayout(VOID)\n{\n    /* Dump memory layout */\n    DebugPrint(L\"System with %zu MiB of installed memory:\\n\"\n               L\"User Space:               %.16P - %.16P\\n\"\n               L\"Non-Canonical:            %.16P - %.16P\\n\"\n               L\"Reserved System Pool:     %.16P - %.16P\\n\"\n               L\"PTE Space:                %.16P - %.16P\\n\"\n               L\"Hyper Space:              %.16P - %.16P\\n\"\n               L\"Shared System Page:       %.16P - %.16P\\n\"\n               L\"System Working Set:       %.16P - %.16P\\n\"\n               L\"Loader Mappings:          %.16P - %.16P\\n\"\n               L\"Non-Paged System Pool:    %.16P - %.16P\\n\"\n               L\"Paged Pool:               %.16P - %.16P\\n\"\n               L\"Session Space:            %.16P - %.16P\\n\"\n               L\"System Cache:             %.16P - %.16P\\n\"\n               L\"PFN Database:             %.16P - %.16P\\n\"\n               L\"Non-Paged Pool:           %.16P - %.16P\\n\"\n               L\"Non-Paged Expansion Pool: %.16P - %.16P\\n\"\n               L\"Hardware Pool:            %.16P - %.16P\\n\",\n               GetInstalledMemorySize(),\n               MemoryLayout.UserSpaceStart,\n               MemoryLayout.UserSpaceEnd,\n               MemoryLayout.NonCanonicalStart,\n               MemoryLayout.NonCanonicalEnd,\n               MemoryLayout.ReservedSystemPoolStart,\n               MemoryLayout.ReservedSystemPoolEnd,\n               MemoryLayout.PteSpaceStart,\n               MemoryLayout.PteSpaceEnd,\n               MemoryLayout.HyperSpaceStart,\n               MemoryLayout.HyperSpaceEnd,\n               MemoryLayout.SharedSystemPageStart,\n               MemoryLayout.SharedSystemPageEnd,\n               MemoryLayout.SystemWorkingSetStart,\n               MemoryLayout.SystemWorkingSetEnd,\n               MemoryLayout.LoaderMappingsStart,\n               MemoryLayout.LoaderMappingsEnd,\n               MemoryLayout.NonPagedSystemPoolStart,\n               MemoryLayout.NonPagedSystemPoolEnd,\n               MemoryLayout.PagedPoolStart,\n               MemoryLayout.PagedPoolEnd,\n               MemoryLayout.SessionSpaceStart,\n               MemoryLayout.SessionSpaceEnd,\n               MemoryLayout.SystemCacheStart,\n               MemoryLayout.SystemCacheEnd,\n               MemoryLayout.PfnDatabase,\n               (PVOID)((ULONG_PTR)MemoryLayout.PfnDatabase + (ULONG_PTR)MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE),\n               MemoryLayout.NonPagedPoolStart,\n               MemoryLayout.NonPagedPoolEnd,\n               MemoryLayout.NonPagedExpansionPoolStart,\n               MemoryLayout.NonPagedExpansionPoolEnd,\n               MemoryLayout.HardwarePoolStart,\n               MemoryLayout.HardwarePoolEnd);\n}\n\n/**\n * Initializes the kernel's virtual memory layout.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::InitializeMemoryLayout(VOID)\n{\n    PFN_NUMBER MaximumNonPagedPoolSize;\n    ULONG_PTR PfnDatabaseEnd;\n\n    /* Check if 5-level paging (LA57) is enabled */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* Set PML5 base address */\n        MemoryLayout.SelfMapAddress = (PVOID)MM_P5E_LA57_BASE;\n\n        /* Define memory layout for 5-level paging */\n        MemoryLayout.UserSpaceStart = (PVOID)0x0000000000010000;\n        MemoryLayout.UserSpaceEnd = (PVOID)0x00FFFFFFFFFEFFFF;\n        MemoryLayout.NonCanonicalStart = (PVOID)0x0080000000000000;\n        MemoryLayout.NonCanonicalEnd = (PVOID)0xFEFFFFFFFFFFFFFF;\n        MemoryLayout.ReservedSystemPoolStart = (PVOID)0xFF00000000000000;\n        MemoryLayout.ReservedSystemPoolEnd = (PVOID)0xFFECFFFFFFFFFFFF;\n        MemoryLayout.PteSpaceStart = (PVOID)0xFFED000000000000;\n        MemoryLayout.PteSpaceEnd = (PVOID)0xFFEDFFFFFFFFFFFF;\n        MemoryLayout.HyperSpaceStart = (PVOID)0xFFFFF70000000000;\n        MemoryLayout.HyperSpaceEnd = (PVOID)0xFFFFF77FFFFFFFFF;\n        MemoryLayout.SharedSystemPageStart = (PVOID)0xFFFFF78000000000;\n        MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF;\n        MemoryLayout.SystemWorkingSetStart = (PVOID)0xFFFFF78000001000;\n        MemoryLayout.SystemWorkingSetEnd = (PVOID)0xFFFFF7FFFFFFFFFF;\n        MemoryLayout.LoaderMappingsStart = (PVOID)0xFFFFF80000000000;\n        MemoryLayout.LoaderMappingsEnd = (PVOID)0xFFFFF87FFFFFFFFF;\n        MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xFFFFF88000000000;\n        MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xFFFFF89FFFFFFFFF;\n        MemoryLayout.PagedPoolStart = (PVOID)0xFFFFF8A000000000;\n        MemoryLayout.PagedPoolEnd = (PVOID)0xFFFFF8BFFFFFFFFF;\n        MemoryLayout.SessionSpaceStart = (PVOID)0xFFFFF90000000000;\n        MemoryLayout.SessionSpaceEnd = (PVOID)0xFFFFF98000000000;\n        MemoryLayout.SystemCacheStart = (PVOID)0xFFFFF98000000000;\n        MemoryLayout.SystemCacheEnd = (PVOID)0xFFFFFA7FFFFFFFFF;\n        MemoryLayout.NonPagedPoolStart = (PVOID)0xFFFFFA8000000000;\n        MemoryLayout.NonPagedPoolEnd = (PVOID)0xFFFFFFFFFFBFFFFF;\n        MemoryLayout.HardwarePoolStart = (PVOID)0xFFFFFFFFFFC00000;\n        MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFFFFFFFFFF;\n    }\n    else\n    {\n        /* Set PML4 base address */\n        MemoryLayout.SelfMapAddress = (PVOID)MM_PXE_BASE;\n\n        /* Define memory layout for 4-level paging */\n        MemoryLayout.UserSpaceStart = (PVOID)0x0000000000010000;\n        MemoryLayout.UserSpaceEnd = (PVOID)0x000007FFFFFEFFFF;\n        MemoryLayout.NonCanonicalStart = (PVOID)0x0000800000000000;\n        MemoryLayout.NonCanonicalEnd = (PVOID)0xFFFF7FFFFFFFFFFF;\n        MemoryLayout.ReservedSystemPoolStart = (PVOID)0xFFFF800000000000;\n        MemoryLayout.ReservedSystemPoolEnd = (PVOID)0xFFFFF67FFFFFFFFF;\n        MemoryLayout.PteSpaceStart = (PVOID)0xFFFFF68000000000;\n        MemoryLayout.PteSpaceEnd = (PVOID)0xFFFFF6FFFFFFFFFF;\n        MemoryLayout.HyperSpaceStart = (PVOID)0xFFFFF70000000000;\n        MemoryLayout.HyperSpaceEnd = (PVOID)0xFFFFF77FFFFFFFFF;\n        MemoryLayout.SharedSystemPageStart = (PVOID)0xFFFFF78000000000;\n        MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF;\n        MemoryLayout.SystemWorkingSetStart = (PVOID)0xFFFFF78000001000;\n        MemoryLayout.SystemWorkingSetEnd = (PVOID)0xFFFFF7FFFFFFFFFF;\n        MemoryLayout.LoaderMappingsStart = (PVOID)0xFFFFF80000000000;\n        MemoryLayout.LoaderMappingsEnd = (PVOID)0xFFFFF87FFFFFFFFF;\n        MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xFFFFF88000000000;\n        MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xFFFFF89FFFFFFFFF;\n        MemoryLayout.PagedPoolStart = (PVOID)0xFFFFF8A000000000;\n        MemoryLayout.PagedPoolEnd = (PVOID)0xFFFFF8BFFFFFFFFF;\n        MemoryLayout.SessionSpaceStart = (PVOID)0xFFFFF90000000000;\n        MemoryLayout.SessionSpaceEnd = (PVOID)0xFFFFF98000000000;\n        MemoryLayout.SystemCacheStart = (PVOID)0xFFFFF98000000000;\n        MemoryLayout.SystemCacheEnd = (PVOID)0xFFFFFA7FFFFFFFFF;\n        MemoryLayout.NonPagedPoolStart = (PVOID)0xFFFFFA8000000000;\n        MemoryLayout.NonPagedPoolEnd = (PVOID)0xFFFFFFFFFFBFFFFF;\n        MemoryLayout.HardwarePoolStart = (PVOID)0xFFFFFFFFFFC00000;\n        MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFFFFFFFFFF;\n    }\n\n    /* Compute allocation size for the PFN database */\n    MM::Pfn::ComputePfnDatabaseSize(&MemoryLayout.PfnDatabaseSize);\n\n    /* Compute boot image size */\n    ComputeBootImageSize(&MemoryLayout.LoaderMappingsSize);\n\n    /* Compute session space size */\n    ComputeSessionSpaceSize(&MemoryLayout.SessionSpaceSize);\n\n    /* Update loader mappings space end address */\n    MemoryLayout.LoaderMappingsEnd = (PVOID)((ULONGLONG)MemoryLayout.LoaderMappingsStart +\n                                             MemoryLayout.LoaderMappingsSize * MM_PAGE_SIZE);\n\n    /* Update session space start address */\n    MemoryLayout.SessionSpaceStart = (PVOID)((ULONGLONG)MemoryLayout.SessionSpaceEnd -\n                                             MemoryLayout.SessionSpaceSize * MM_PAGE_SIZE);\n\n    /* Compute system PTE size */\n    ComputeSystemPteSize(&NumberOfSystemPtes);\n\n    /* Compute non-paged pool size */\n    ComputeNonPagedPoolSize(&MemoryLayout.NonPagedPoolSize);\n    ComputeMaximumNonPagedPoolSize(&MaximumNonPagedPoolSize);\n\n    /* Compute paged pool size */\n    ComputePagedPoolSize(&MemoryLayout.PagedPoolSize);\n\n    /* Insert the PFN database at the beginning of the non-paged pool */\n    MemoryLayout.PfnDatabase = (PMMPFN)MemoryLayout.NonPagedPoolStart;\n\n    /* Compute the PFN database page-aligned end address */\n    PfnDatabaseEnd = (ULONGLONG)MemoryLayout.PfnDatabase + (MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE);\n    PfnDatabaseEnd = ROUND_UP(PfnDatabaseEnd, MM_PAGE_SIZE);\n\n    /* Shrink the non-paged pool to fit the PFN database */\n    MemoryLayout.NonPagedPoolStart = (PVOID)PfnDatabaseEnd;\n\n    /* Assign the rest of the non-paged pool to the expansion pool */\n    MemoryLayout.NonPagedExpansionPoolStart = (PVOID)((ULONGLONG)MemoryLayout.NonPagedPoolStart +\n                                                      MemoryLayout.NonPagedPoolSize * MM_PAGE_SIZE);\n    MemoryLayout.NonPagedPoolEnd = MemoryLayout.NonPagedExpansionPoolStart;\n    MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)((ULONGLONG)MemoryLayout.NonPagedPoolStart +\n                                                    MaximumNonPagedPoolSize * MM_PAGE_SIZE);\n    MemoryLayout.NonPagedExpansionPoolSize = ((ULONGLONG)MemoryLayout.NonPagedExpansionPoolEnd -\n                                              (ULONGLONG)MemoryLayout.NonPagedExpansionPoolStart) / MM_PAGE_SIZE;\n\n    /* Update paged pool end address */\n    MemoryLayout.PagedPoolEnd = (PVOID)(((ULONGLONG)MemoryLayout.PagedPoolStart +\n                                         MemoryLayout.PagedPoolSize * MM_PAGE_SIZE) - 1);\n}\n"
  },
  {
    "path": "xtoskrnl/mm/amd64/pagemap.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/i686/pagemap.cc\n * DESCRIPTION:     Low-level support for i686 page map manipulation\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Advances a PTE pointer by a given number of entries, considering the actual PTE size.\n *\n * @param Pte\n *        The PTE pointer to advance.\n *\n * @param Count\n *        The number of PTE entries to advance by.\n *\n * @return The advanced PTE pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::PageMap::AdvancePte(IN PMMPTE Pte,\n                        IN LONG Count)\n{\n    /* Return advanced PTE pointer */\n    return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPTE)));\n}\n\n/**\n * Checks if the given address is canonical.\n *\n * @param VirtualAddress\n *        Specifies the virtual address to check.\n *\n * @return This routine returns TRUE if the address is canonical, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMap::CanonicalAddress(IN PVOID VirtualAddress)\n{\n    ULONG Shift;\n\n    /* Calculate the number of unused upper bits based on the paging mode */\n    Shift = 64 - PageMapInfo.VaBits;\n\n    /* Sign-extend via arithmetic shifts to verify the canonical form */\n    return ((((LONGLONG)VirtualAddress << Shift) >> Shift) == (LONGLONG)VirtualAddress);\n}\n\n/**\n * Clears the contents of a page table entry (PTE).\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to be cleared.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMap::ClearPte(IN PMMPTE PtePointer)\n{\n    /* Clear PTE */\n    PtePointer->Long = 0;\n}\n\n/**\n * Gets the next entry in a PTE list.\n *\n * @param Pte\n *        The PTE pointer to get the next entry from.\n *\n * @return This routine returns the next entry in the PTE list.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nMM::PageMap::GetNextEntry(IN PMMPTE Pte)\n{\n    /* Return next entry in PTE list */\n    return Pte->List.NextEntry;\n}\n\n/**\n * Advances a PTE pointer, considering the actual PTE size.\n *\n * @param Pte\n *        The PTE pointer to advance.\n *\n * @return The advanced PTE pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::PageMap::GetNextPte(IN PMMPTE Pte)\n{\n    /* Return advanced PTE pointer */\n    return AdvancePte(Pte, 1);\n}\n\n/**\n * Checks if a PTE list contains only one entry.\n *\n * @param Pte\n *        The PTE pointer to check.\n *\n * @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMap::GetOneEntry(IN PMMPTE Pte)\n{\n    /* Return one entry status */\n    return Pte->List.OneEntry;\n}\n\n/**\n * Gets the address of the P5E (Page Map Level 5 Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding P5E.\n *\n * @return This routine returns the address of the P5E, or NULLPTR if LA57 is not enabled.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMP5E\nMM::PageMap::GetP5eAddress(IN PVOID Address)\n{\n    ULONGLONG Offset;\n\n    /* Calculate offset and return P5E address */\n    Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_P5I_SHIFT) << MM_PTE_SHIFT);\n    return (PMMP5E)((PageMapInfo.P5eBase + Offset) * PageMapInfo.Xpa);\n}\n\n/**\n * Gets the Offset of the P5E (Page Map Level 5 Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding P5E.\n *\n * @return This routine returns the Offset of the P5E, or NULLPTR if LA57 is not enabled.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetP5eOffset(IN PVOID Address)\n{\n    /* Return P5E Offset */\n    return (((((ULONGLONG)Address) >> MM_P5I_SHIFT) & 0x1FF) * PageMapInfo.Xpa);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Map Level 5 Entry.\n *\n * @param P5ePointer\n *        Specifies the address of the P5E.\n *\n * @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMap::GetP5eVirtualAddress(IN PMMP5E P5ePointer)\n{\n    return (PVOID)((((LONGLONG)P5ePointer << 52) >> 7) * PageMapInfo.Xpa);\n}\n\n/**\n * Gets the page frame number from a corresponding PTE.\n *\n * @param Pte\n *        The PTE pointer to get the page frame number from.\n *\n * @return This routine returns the page frame number.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_NUMBER\nMM::PageMap::GetPageFrameNumber(IN PMMPTE Pte)\n{\n    return Pte->Hardware.PageFrameNumber;\n}\n\n/**\n * Gets Page Map Level (PML) for current paging mode.\n *\n * @return This routine returns the page map level.\n *\n * @since XT 1.0\n */\nXTAPI\nUSHORT\nMM::PageMap::GetPageMapLevel()\n{\n    return PageMapInfo.Xpa ? 5 : 4;\n}\n\n/**\n * Gets the address of the PDE (Page Directory Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PDE.\n *\n * @return This routine returns the address of the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPDE\nMM::PageMap::GetPdeAddress(IN PVOID Address)\n{\n    ULONGLONG Offset;\n\n    /* Calculate offset and return PDE address */\n    Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PDI_SHIFT) << MM_PTE_SHIFT);\n    return (PMMPDE)(PageMapInfo.PdeBase + Offset);\n}\n\n/**\n * Gets the Offset of the PDE (Page Directory Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PDE.\n *\n * @return This routine returns the Offset of the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPdeOffset(IN PVOID Address)\n{\n    /* Return PDE Offset */\n    return ((((ULONGLONG)Address) >> MM_PDI_SHIFT) & 0x1FF);\n}\n\n/**\n * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PPE.\n *\n * @return This routine returns the address of the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPPE\nMM::PageMap::GetPpeAddress(IN PVOID Address)\n{\n    ULONGLONG Offset;\n\n    /* Calculate offset and return PPE address */\n    Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PPI_SHIFT) << MM_PTE_SHIFT);\n    return (PMMPPE)(PageMapInfo.PpeBase + Offset);\n}\n\n/**\n * Gets the Offset of the PPE (Page Directory Pointer Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PPE.\n *\n * @return This routine returns the Offset of the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPpeOffset(IN PVOID Address)\n{\n    /* Return PPE Offset */\n    return ((((ULONGLONG)Address) >> MM_PPI_SHIFT) & 0x1FF);\n}\n\n /**\n * Gets the entire contents of a Page Table Entry (PTE) as a single value.\n *\n * @param PtePointer\n *        Pointer to the Page Table Entry (PTE) to read.\n *\n * @return This routine returns the contents of the PTE as a single value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nMM::PageMap::GetPte(IN PMMPTE PtePointer)\n{\n    /* Return PTE value */\n    return PtePointer->Long;\n}\n\n/**\n * Gets the address of the PTE (Page Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PTE.\n *\n * @return This routine returns the address of the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::PageMap::GetPteAddress(IN PVOID Address)\n{\n    ULONGLONG Offset;\n\n    /* Calculate offset and return PTE address */\n    Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PTI_SHIFT) << MM_PTE_SHIFT);\n    return (PMMPTE)(PageMapInfo.PteBase + Offset);\n}\n\n/**\n * Calculates the distance between two PTE pointers.\n *\n * @param EndPte\n *        Pointer to the ending Page Table Entry.\n *\n * @param StartPte\n *        Pointer to the starting Page Table Entry.\n *\n * @return This routine returns a signed value representing the number of PTEs between EndPte and StartPte.\n *\n * @since XT 1.0\n */\nXTAPI\nLONG\nMM::PageMap::GetPteDistance(PMMPTE EndPte,\n                            PMMPTE StartPte)\n{\n    /* Return distance between PTE pointers */\n    return ((ULONG_PTR)EndPte - (ULONG_PTR)StartPte) / sizeof(MMPTE);\n}\n\n/**\n * Gets the Offset of the PTE (Page Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PTE.\n *\n * @return This routine returns the Offset of the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPteOffset(IN PVOID Address)\n{\n    /* Return PTE Offset */\n    return ((((ULONGLONG)Address) >> MM_PTI_SHIFT) & 0x1FF);\n}\n\n/**\n * Gets the size of a PTE.\n *\n * @return This routine returns the size of a PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPteSize(VOID)\n{\n    /* Return the size of MMPTE */\n    return sizeof(MMPTE);\n}\n\n/**\n * Gets the software protection value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software protection value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPteSoftwareProtection(IN PMMPTE PtePointer)\n{\n    /* Return PTE software protection value */\n    return (ULONG)PtePointer->Software.Protection;\n}\n\n/**\n * Gets the software prototype value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software prototype value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPteSoftwarePrototype(IN PMMPTE PtePointer)\n{\n    /* Return PTE software prototype value */\n    return (ULONG)PtePointer->Software.Prototype;\n}\n\n/**\n * Gets the software transition value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software transition value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPteSoftwareTransition(IN PMMPTE PtePointer)\n{\n    /* Return PTE software transition value */\n    return (ULONG)PtePointer->Software.Transition;\n}\n\n/**\n * Gets the address of the PXE (Extended Page Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PXE.\n *\n * @return This routine returns the address of the PXE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPXE\nMM::PageMap::GetPxeAddress(IN PVOID Address)\n{\n    ULONGLONG Offset;\n\n    /* Calculate offset and return PXE address */\n    Offset = ((((ULONGLONG)Address & (((ULONGLONG)1 << PageMapInfo.VaBits) - 1)) >> MM_PXI_SHIFT) << MM_PTE_SHIFT);\n    return (PMMPXE)(PageMapInfo.PxeBase + Offset);\n}\n\n/**\n * Gets the Offset of the PXE (Extended Page Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PXE.\n *\n * @return This routine returns the Offset of the PXE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPxeOffset(IN PVOID Address)\n{\n    /* Return PXE Offset */\n    return ((((ULONGLONG)Address) >> MM_PXI_SHIFT) & 0x1FF);\n}\n\n/**\n * Gets the status of Extended Paging Address (XPA) mode.\n *\n * @return This routine returns TRUE if XPA is enabled, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMap::GetXpaStatus()\n{\n    return PageMapInfo.Xpa;\n}\n\n/**\n * Checks whether the given PML2 page table entry (PTE) is valid.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to check.\n *\n * @return Returns TRUE if the entry is valid, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMap::PteValid(IN PMMPTE PtePointer)\n{\n    /* Check if PTE is valid */\n    return (BOOLEAN)PtePointer->Hardware.Valid;\n}\n\n/**\n * Sets the next entry in a PTE list.\n *\n * @param Pte\n *        The PTE pointer to modify.\n *\n * @param Value\n *        The value to set as the next entry.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMap::SetNextEntry(IN PMMPTE Pte,\n                          IN ULONG_PTR Value)\n{\n    /* Set next entry in PTE list */\n    Pte->List.NextEntry = Value;\n}\n\n/**\n * Sets the flag indicating whether a PTE list contains only one entry.\n *\n * @param Pte\n *        The PTE pointer to modify.\n *\n * @param Value\n *        The value to set. TRUE if the list has only one entry, FALSE otherwise.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMap::SetOneEntry(IN PMMPTE Pte,\n                         IN BOOLEAN Value)\n{\n    /* Set one entry status */\n    Pte->List.OneEntry = Value;\n}\n\n/**\n * Sets a Page Table Entry (PTE) with the specified physical page and access flags.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to set.\n *\n * @param PageFrameNumber\n *        Physical frame number to map.\n *\n * @param AttributesMask\n *        Specifies the attributes mask to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMap::SetPte(IN PMMPTE PtePointer,\n                    IN PFN_NUMBER PageFrameNumber,\n                    IN ULONGLONG AttributesMask)\n{\n    /* Set PTE */\n    PtePointer->Hardware.PageFrameNumber = PageFrameNumber;\n    PtePointer->Hardware.Valid = 1;\n    PtePointer->Long |= AttributesMask;\n}\n\n/**\n * Sets a Page Table Entry (PTE) with the specified attributes.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to set.\n *\n * @param Attributes\n *        Specifies the attributes to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMap::SetPte(IN PMMPTE PtePointer,\n                    IN ULONGLONG Attributes)\n{\n    PtePointer->Long = Attributes;\n}\n\n/**\n * Sets caching attributes for a PML2 page table entry (PTE).\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to modify.\n *\n * @param CacheDisable\n *        Indicates whether caching should be disabled for this page.\n *\n * @param WriteThrough\n *        Indicates whether write-through caching should be enabled.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMap::SetPteCaching(IN PMMPTE PtePointer,\n                           IN BOOLEAN CacheDisable,\n                           IN BOOLEAN WriteThrough)\n{\n    /* Set caching attributes */\n    PtePointer->Hardware.CacheDisable = CacheDisable;\n    PtePointer->Hardware.WriteThrough = WriteThrough;\n}\n\n/**\n * Transitions a Page Table Entry (PTE) to invalid state\n *\n * @param PointerPte\n *        Pointer to the page table entry (PTE) to transition.\n *\n * @param Protection\n *        Specifies the protection attribute to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMap::TransitionPte(IN PMMPTE PointerPte,\n                           IN ULONG_PTR Protection)\n{\n    MMPTE TempPte;\n\n    /* Set transition PTE */\n    TempPte = *PointerPte;\n    TempPte.Software.Protection = Protection;\n    TempPte.Software.Prototype = 0;\n    TempPte.Software.Transition = 1;\n    TempPte.Software.Valid = 0;\n\n    /* Write PTE value */\n    *PointerPte = TempPte;\n}\n\n/**\n * Writes a Page Table Entry (PTE) with the specified value.\n *\n * @param Pte\n *        Pointer to the page table entry (PTE) to write.\n *\n * @param Value\n *        The value to write to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMap::WritePte(IN PMMPTE Pte,\n                      IN MMPTE Value)\n{\n    /* Write PTE value */\n    Pte->Long = Value.Long;\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Entry (PML4).\n *\n * @param PdePointer\n *        Specifies the address of the PDE.\n *\n * @return This routine returns the virtual address mapped by the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapBasic::GetPdeVirtualAddress(IN PMMPDE PdePointer)\n{\n    /* Return PDE virtual address */\n    return (PVOID)(((LONGLONG)PdePointer << 34) >> 16);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry (PML4).\n *\n * @param PpePointer\n *        Specifies the address of the PPE.\n *\n * @return This routine returns the virtual address mapped by the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapBasic::GetPpeVirtualAddress(IN PMMPPE PpePointer)\n{\n    /* Return PPE virtual address */\n    return (PVOID)(((LONGLONG)PpePointer << 43) >> 16);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Table Entry (PML4).\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the virtual address mapped by the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapBasic::GetPteVirtualAddress(IN PMMPTE PtePointer)\n{\n    /* Return PTE virtual address */\n    return (PVOID)(((LONGLONG)PtePointer << 25) >> 16);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Extended Page Entry (PML4).\n *\n * @param PxePointer\n *        Specifies the address of the PXE.\n *\n * @return This routine returns the virtual address mapped by the PXE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapBasic::GetPxeVirtualAddress(IN PMMPXE PxePointer)\n{\n    /* Return PXE virtual address */\n    return (PVOID)(((LONGLONG)PxePointer << 52) >> 16);\n}\n\n/**\n * Initializes page map information for basic paging (PML4).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::InitializePageMapInfo(VOID)\n{\n    /* Set PML4 page map information */\n    PageMapInfo.Xpa = FALSE;\n\n    /* Set PML4 base addresses */\n    PageMapInfo.PteBase = MM_PTE_BASE;\n    PageMapInfo.PdeBase = MM_PDE_BASE;\n    PageMapInfo.PpeBase = MM_PPE_BASE;\n    PageMapInfo.PxeBase = MM_PXE_BASE;\n    PageMapInfo.P5eBase = 0x0;\n\n    /* PML use 48-bit virtual addresses */\n    PageMapInfo.VaBits = 48;\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Entry (PML5).\n *\n * @param PdePointer\n *        Specifies the address of the PDE.\n *\n * @return This routine returns the virtual address mapped by the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapXpa::GetPdeVirtualAddress(IN PMMPDE PdePointer)\n{\n    /* Return PDE virtual address */\n    return (PVOID)(((LONGLONG)PdePointer << 25) >> 7);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry (PML5).\n *\n * @param PpePointer\n *        Specifies the address of the PPE.\n *\n * @return This routine returns the virtual address mapped by the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapXpa::GetPpeVirtualAddress(IN PMMPPE PpePointer)\n{\n    /* Return PPE virtual address */\n    return (PVOID)(((LONGLONG)PpePointer << 34) >> 7);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Table Entry (PML5).\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the virtual address mapped by the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapXpa::GetPteVirtualAddress(IN PMMPTE PtePointer)\n{\n    /* Return PTE virtual address */\n    return (PVOID)(((LONGLONG)PtePointer << 16) >> 7);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Extended Page Entry (PML5).\n *\n * @param PxePointer\n *        Specifies the address of the PXE.\n *\n * @return This routine returns the virtual address mapped by the PXE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapXpa::GetPxeVirtualAddress(IN PMMPXE PxePointer)\n{\n    /* Return PXE virtual address */\n    return (PVOID)(((LONGLONG)PxePointer << 43) >> 7);\n}\n\n/**\n * Initializes page map information for XPA paging (PML5).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::InitializePageMapInfo(VOID)\n{\n    /* Set PML5 page map information */\n    PageMapInfo.Xpa = TRUE;\n\n    /* Set PML5 base addresses */\n    PageMapInfo.PteBase = MM_PTE_LA57_BASE;\n    PageMapInfo.PdeBase = MM_PDE_LA57_BASE;\n    PageMapInfo.PpeBase = MM_PPE_LA57_BASE;\n    PageMapInfo.PxeBase = MM_PXE_LA57_BASE;\n    PageMapInfo.P5eBase = MM_P5E_LA57_BASE;\n\n    /* PML5 use 57-bit virtual addresses */\n    PageMapInfo.VaBits = 57;\n}\n"
  },
  {
    "path": "xtoskrnl/mm/amd64/paging.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/amd64/paging.cc\n * DESCRIPTION:     Architecture dependent paging support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Checks if eXtended Physical Addressing (XPA) is enabled.\n *\n * @return This routine returns TRUE if LA57 is enabled, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Paging::GetExtendedPhysicalAddressingStatus(VOID)\n{\n    /* Check if LA57 is enabled */\n    return ((AR::CpuFunctions::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE;\n}\n\n/**\n * Gets the address of the P5E (Page Map Level 5 Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding P5E.\n *\n * @return This routine returns the address of the P5E, or NULLPTR if LA57 is not enabled.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMP5E\nMM::Paging::GetP5eAddress(IN PVOID Address)\n{\n    /* Return PDE address */\n    return PmlRoutines->GetP5eAddress(Address);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Map Level 5 Entry.\n *\n * @param P5ePointer\n *        Specifies the address of the P5E.\n *\n * @return This routine returns the virtual address mapped by the P5E, or NULLPTR if LA57 is not enabled.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::Paging::GetP5eVirtualAddress(IN PMMP5E P5ePointer)\n{\n    /* Return PTE virtual address */\n    return PmlRoutines->GetP5eVirtualAddress(P5ePointer);\n}\n\n/**\n * Gets the address of the PXE (Extended Page Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PXE.\n *\n * @return This routine returns the address of the PXE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPXE\nMM::Paging::GetPxeAddress(IN PVOID Address)\n{\n    /* Return PXE address */\n    return PmlRoutines->GetPxeAddress(Address);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Extended Page Entry.\n *\n * @param PxePointer\n *        Specifies the address of the PXE.\n *\n * @return This routine returns the virtual address mapped by the PXE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::Paging::GetPxeVirtualAddress(IN PMMPXE PxePointer)\n{\n    /* Return PXE virtual address */\n    return PmlRoutines->GetPxeVirtualAddress(PxePointer);\n}\n\n/**\n * Maps a specific virtual address to a specific physical page frame.\n *\n * @param VirtualAddress\n *        The virtual address to map.\n *\n * @param PageFrameNumber\n *        The physical frame number to back the virtual address.\n *\n * @param Attributes\n *        Specifies the attributes (protections, caching) to apply to the PTE.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Paging::MapVirtualAddress(IN PVOID VirtualAddress,\n                              IN PFN_NUMBER PageFrameNumber,\n                              IN ULONGLONG Attributes)\n{\n    MMPTE TemplatePte;\n    PMMPTE PointerPte;\n\n    /* Initialize the template PTE */\n    MM::Paging::ClearPte(&TemplatePte);\n    MM::Paging::SetPte(&TemplatePte, 0, Attributes | MM_PTE_CACHE_ENABLE);\n\n    /* Check if XPA is enabled */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* Map Page 5-level Entry*/\n        MM::Pte::MapP5E(VirtualAddress, VirtualAddress, (PMMP5E)&TemplatePte);\n    }\n\n    /* Map PXE, PPE and PDE for the corresponding virtual address */\n    MM::Pte::MapPXE(VirtualAddress, VirtualAddress, (PMMPXE)&TemplatePte);\n    MM::Pte::MapPPE(VirtualAddress, VirtualAddress, (PMMPPE)&TemplatePte);\n    MM::Pte::MapPDE(VirtualAddress, VirtualAddress, (PMMPDE)&TemplatePte);\n\n    /* Get PTE address */\n    PointerPte = MM::Paging::GetPteAddress(VirtualAddress);\n\n    /* Initialize the template PTE */\n    MM::Paging::ClearPte(&TemplatePte);\n    MM::Paging::SetPte(&TemplatePte, PageFrameNumber, Attributes);\n\n    /* Write the PTE */\n    MM::Paging::WritePte(PointerPte, TemplatePte);\n\n    /* Flush the TLB to reflect the changes */\n    MM::Paging::FlushTlb();\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way.\n *\n * @param Address\n *        Supplies an address of the page to be filled with zeroes.\n *\n * @param Size\n *        Number of bytes to be filled with zeros. This always should be a multiply of page size.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nMM::Paging::ZeroPages(IN PVOID Address,\n                      IN ULONG Size)\n{\n    __asm__ volatile(\"xor %%rax, %%rax\\n\"\n                     \"mov %0, %%rdi\\n\"\n                     \"mov %1, %%ecx\\n\"\n                     \"shr $3, %%ecx\\n\"\n                     \"rep stosq\\n\"\n                     :\n                     : \"m\" (Address),\n                       \"m\" (Size)\n                     : \"rax\",\n                       \"rdi\",\n                       \"ecx\",\n                       \"memory\");\n}\n"
  },
  {
    "path": "xtoskrnl/mm/amd64/pfault.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/amd64/pfault.cc\n * DESCRIPTION:     Page fault support for AMD64 architecture\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Evaluates the PDE for for paged pool and per-session mappings.\n *\n * @param VirtualAddress\n *        Specifies the virtual address to verify.\n *\n * @return This routine returns ACCESS_VIOLATION regardless PML4 or PML5 is used.\n */\nXTFASTCALL\nXTSTATUS\nMM::PageFault::CheckPdeForPagedPool(IN PVOID VirtualAddress)\n{\n    /* Return access violation */\n    return STATUS_ACCESS_VIOLATION;\n}\n"
  },
  {
    "path": "xtoskrnl/mm/amd64/pfn.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/amd64/pfn.cc\n * DESCRIPTION:     Physical Frame Number for AMD64 support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n *                  Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Allocates and initializes page directory structures for a range of PDEs.\n *\n * @param StartingPde\n *        Supplies a pointer to the first PDE in the range to initialize.\n *\n * @param EndingPde\n *        Supplies a pointer to the last PDE in the range to initialize.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::InitializePageDirectory(IN PMMPDE StartingPde,\n                                 IN PMMPDE EndingPde)\n{\n    PMMPTE ParentPte, ValidPte;\n    BOOLEAN PteValidated;\n\n    /* Get a template PTE for mapping the PFN database pages */\n    ValidPte = MM::Pte::GetValidPte();\n\n    /* Initialize validation flag */\n    PteValidated = FALSE;\n\n    /* Iterate through the range of PDEs to ensure the paging hierarchy is fully mapped */\n    while(StartingPde <= EndingPde)\n    {\n        /* Check if there is a need to validate upper-level page table entries */\n        if(!PteValidated || ((ULONG_PTR)StartingPde & (MM_PAGE_SIZE - 1)) == 0)\n        {\n            /* For LA57, ensure PML5 entry exists */\n            if(MM::Paging::GetXpaStatus())\n            {\n                /* Get the P5E that maps the PXE page containing this hierarchy */\n                ParentPte = MM::Paging::GetPpeAddress(StartingPde);\n\n                /* Check if P5E entry is valid */\n                if(!MM::Paging::PteValid(ParentPte))\n                {\n                    /* Allocate a new PML4 page and map P5E to it */\n                    MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);\n                    *ParentPte = *ValidPte;\n\n                    /* Clear the newly created page */\n                    RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);\n                }\n            }\n\n            /* Get the PXE that maps the PPE page containing PDE */\n            ParentPte = MM::Paging::GetPdeAddress(StartingPde);\n\n            /* Check if PXE entry is valid */\n            if(!MM::Paging::PteValid(ParentPte))\n            {\n                /* Allocate a new PPE page and map PXE to it */\n                MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);\n                *ParentPte = *ValidPte;\n\n                /* Clear the newly created page */\n                RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);\n            }\n\n            /* Get the PPE that maps the PDE page containing PTE */\n            ParentPte = MM::Paging::GetPteAddress(StartingPde);\n\n            /* Check if PPE entry is valid */\n            if(!MM::Paging::PteValid(ParentPte))\n            {\n                /* Allocate a new PDE page and map PPE to it */\n                MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);\n                *ParentPte = *ValidPte;\n\n                /* Clear the newly created page */\n                RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(ParentPte), MM_PAGE_SIZE);\n            }\n\n            /* Upper levels for this PDE have been validated */\n            PteValidated = TRUE;\n        }\n\n        /* Ensure the PDE has a PTE page allocated */\n        if(!MM::Paging::PteValid(StartingPde))\n        {\n            /* Allocate a new PTE page and map PDE to it */\n            MM::Paging::SetPte(ValidPte, AllocateBootstrapPages(1), 0);\n            *StartingPde = *ValidPte;\n\n            /* Clear the newly created page */\n            RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(StartingPde), MM_PAGE_SIZE);\n        }\n\n        /* Move to the next PDE */\n        StartingPde = MM::Paging::GetNextPte(StartingPde);\n    }\n}\n\n/**\n * Initializes the PFN database by mapping virtual memory and populating entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::InitializePfnDatabase(VOID)\n{\n    PKERNEL_INITIALIZATION_BLOCK InitializationBlock;\n    PLIST_ENTRY ListEntry;\n    PLOADER_MEMORY_DESCRIPTOR Descriptor;\n    PUCHAR PfnDatabaseEnd;\n    PMMMEMORY_LAYOUT MemoryLayout;\n    PMMPTE ValidPte;\n\n    /* Raise runlevel and acquire the PFN lock */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);\n\n    /* Get the kernel initialization block */\n    InitializationBlock = KE::BootInformation::GetInitializationBlock();\n\n    /* Get the memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Get the PFN database size and calculate the end of the PFN database virtual address space */\n    PfnDatabaseEnd = (PUCHAR)MemoryLayout->PfnDatabase + (MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE) - 1;\n\n    /* Get a template PTE for mapping the PFN database pages */\n    ValidPte = MM::Pte::GetValidPte();\n\n    /* Map the Page Directory and Page Directory Pointer tables for the PFN database */\n    MM::Pte::MapPPE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);\n    MM::Pte::MapPDE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);\n    MM::Pte::MapPTE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);\n\n    /* Zero PFN database virtual space */\n    RTL::Memory::ZeroMemory(MemoryLayout->PfnDatabase, MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE);\n\n    /* Initialize the color tables */\n    MM::Colors::InitializeColorTables();\n\n    /* Iterate over memory descriptors to map the PFN database and initialize entries */\n    ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;\n    while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)\n    {\n        /* Get the descriptor */\n        Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);\n\n        /* Skip invisible memory regions */\n        if(MM::Manager::VerifyMemoryTypeInvisible(Descriptor->MemoryType))\n        {\n            /* Move to the next descriptor and continue */\n            ListEntry = ListEntry->Flink;\n            continue;\n        }\n\n        /* Check if this is the modified free descriptor */\n        if(Descriptor == FreeDescriptor)\n        {\n            /* Switch to the original descriptor */\n            Descriptor = &OriginalFreeDescriptor;\n        }\n\n        /* Check if the free memory block that was split is being processed */\n        if(Descriptor == &OriginalFreeDescriptor)\n        {\n            /* Skip loop processing, free memory is initialized separately */\n            ListEntry = ListEntry->Flink;\n            continue;\n        }\n\n        /* Initialize PFNs for this memory range */\n        ProcessMemoryDescriptor(Descriptor->BasePage, Descriptor->PageCount, Descriptor->MemoryType);\n\n        /* Move to the next descriptor */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Initialize PFNs for the free memory */\n    ProcessMemoryDescriptor(FreeDescriptor->BasePage, FreeDescriptor->PageCount, LoaderFree);\n\n    /* Initialize PFNs for the physical pages backing the PFN database */\n    ProcessMemoryDescriptor(OriginalFreeDescriptor.BasePage,\n                            FreeDescriptor->BasePage - OriginalFreeDescriptor.BasePage,\n                            LoaderMemoryData);\n\n    /* Restore original free descriptor */\n    *FreeDescriptor = OriginalFreeDescriptor;\n\n    /* Initialize PFNs backing page tables */\n    InitializePageTablePfns();\n}\n\n/**\n * Initializes PFN database entries for the system page tables.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::InitializePageTablePfns(VOID)\n{\n    PFN_NUMBER PageFrameIndex;\n    PMMPFN Pfn;\n    ULONG RootLevel;\n    PMMPTE RootPte;\n\n    /* Determine root structure based on paging mode */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* XPA enabled, 5-level paging (LA57) */\n        RootLevel = 5;\n\n        /* Retrieve the PFN of the PML5 table and its virtual base address */\n        PageFrameIndex = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress((PVOID)MM_P5E_LA57_BASE));\n        RootPte = (PMMPTE)MM::Paging::GetP5eAddress(NULLPTR);\n    }\n    else\n    {\n        /* XPA disabled, 4-level paging */\n        RootLevel = 4;\n\n        /* Retrieve the PFN of the PML4 table and its virtual base address */\n        PageFrameIndex = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress((PVOID)MM_PXE_BASE));\n        RootPte = (PMMPTE)MM::Paging::GetPxeAddress(NULLPTR);\n    }\n\n    /* Initialize the PFN entry for the root page table itself */\n    Pfn = GetPfnEntry(PageFrameIndex);\n    if(Pfn)\n    {\n        /* Initialize the PFN entry */\n        Pfn->PteAddress = NULLPTR;\n        Pfn->u1.WsIndex = 0;\n        Pfn->u2.ShareCount = 1;\n        Pfn->u3.e1.CacheAttribute = PfnNonCached;\n        Pfn->u3.e2.ReferenceCount = 1;\n        Pfn->u4.PteFrame = 0;\n    }\n\n    /* Start recursive scan from the top level */\n    if(RootPte)\n    {\n        /* Scan the root page table */\n        ScanPageTable(RootPte, RootLevel);\n    }\n}\n\n/**\n * Recursively scans a page table to initialize PFN database entries for active pages.\n *\n * @param PointerPte\n *        Pointer to the base of the page table to scan.\n *\n * @param Level\n *        The paging level of the table being scanned.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::ScanPageTable(IN PMMPTE PointerPte,\n                       IN ULONG Level)\n{\n    PVOID Address;\n    ULONG Index;\n    PMMPTE NextLevelPte;\n    ULONG PtesPerPage;\n\n    /* Get the number of PTEs per page */\n    PtesPerPage = MM::Pte::GetPtesPerPage();\n\n    /* Iterate through all entries in the current page table */\n    for(Index = 0; Index < PtesPerPage; Index++)\n    {\n        /* Check if the page table entry is present */\n        if(MM::Paging::PteValid(PointerPte))\n        {\n            /* Mark the PFN pointed to by this entry as active */\n            LinkPfnForPageTable(MM::Paging::GetPageFrameNumber(PointerPte), PointerPte);\n\n            /* Recurse to the next level, if this is not a leaf node (PTE) */\n            if(Level > 1)\n            {\n                /* Calculate the virtual address mapped by this entry to find the next table */\n                switch(Level)\n                {\n                    case 5:\n                        /* Calculate PXE */\n                        Address = MM::Paging::GetP5eVirtualAddress((PMMP5E)PointerPte);\n                        NextLevelPte = (PMMPTE)MM::Paging::GetPxeAddress(Address);\n                        break;\n                    case 4:\n                        /* Calculate PPE */\n                        Address = MM::Paging::GetPxeVirtualAddress((PMMPXE)PointerPte);\n                        NextLevelPte = (PMMPTE)MM::Paging::GetPpeAddress(Address);\n                        break;\n                    case 3:\n                        /* Calculate PDE */\n                        Address = MM::Paging::GetPpeVirtualAddress((PMMPPE)PointerPte);\n                        NextLevelPte = (PMMPTE)MM::Paging::GetPdeAddress(Address);\n                        break;\n                    case 2:\n                        /* Calculate PTE */\n                        Address = MM::Paging::GetPdeVirtualAddress((PMMPDE)PointerPte);\n                        NextLevelPte = MM::Paging::GetPteAddress(Address);\n                        break;\n                    default:\n                        /* Nothing to calculate, return NULLPTR */\n                        NextLevelPte = NULLPTR;\n                        break;\n                }\n\n                /* Recurse deeper if not at the bottom level (PTE) already */\n                if(NextLevelPte)\n                {\n                    /* Recursively scan the next level page table */\n                    ScanPageTable(NextLevelPte, Level - 1);\n                }\n            }\n        }\n\n        /* Move to the next entry in the current table */\n        PointerPte = MM::Paging::GetNextPte(PointerPte);\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/mm/amd64/pool.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/amd64/pool.cc\n * DESCRIPTION:     AMD64 Memory Manager pool manager\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Maps the PTE for the base of the non-paged pool.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::MapNonPagedPool(VOID)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Retrieve memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Map PPE and PDE for whole non-paged pool */\n    MM::Pte::MapPPE(MemoryLayout->NonPagedPoolStart, MemoryLayout->NonPagedExpansionPoolEnd, MM::Pte::GetValidPte());\n    MM::Pte::MapPDE(MemoryLayout->NonPagedPoolStart, MemoryLayout->NonPagedExpansionPoolEnd, MM::Pte::GetValidPte());\n\n    /* Map PTE only for the base of the non-paged pool */\n    MM::Pte::MapPTE(MemoryLayout->NonPagedPoolStart, (PCHAR)MemoryLayout->NonPagedPoolEnd - 1, MM::Pte::GetValidPte());\n}\n"
  },
  {
    "path": "xtoskrnl/mm/amd64/pte.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/amd64/pte.cc\n * DESCRIPTION:     Page Table Entry (PTE) for AMD64 support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Checks if the virtual address is valid and mapped in the page tables.\n *\n * @param VirtualAddress\n *        The virtual address to check.\n *\n * @return This routine returns TRUE if the address is valid, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Pte::AddressValid(IN PVOID VirtualAddress)\n{\n    /* Check XPA status */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* Check if the P5E is valid */\n        if(!MM::Paging::PteValid(MM::Paging::GetP5eAddress(VirtualAddress)))\n        {\n            /* Invalid P5E, return FALSE */\n            return FALSE;\n        }\n    }\n\n    /* Check if PXE, PPE, PDE and PTE are valid */\n    if(!MM::Paging::PteValid(MM::Paging::GetPxeAddress(VirtualAddress)) ||\n       !MM::Paging::PteValid(MM::Paging::GetPpeAddress(VirtualAddress)) ||\n       !MM::Paging::PteValid(MM::Paging::GetPdeAddress(VirtualAddress)) ||\n       !MM::Paging::PteValid(MM::Paging::GetPteAddress(VirtualAddress)))\n    {\n        /* Invalid PXE, PPE, PDE or PTE, return FALSE */\n        return FALSE;\n    }\n\n    /* Address is valid, return TRUE */\n    return TRUE;\n}\n\n/**\n * Retrieves the base virtual address of the system PTEs.\n *\n * @return This routine returns a pointer to the first PTE in the system PTE space.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::Pte::GetSystemPteBaseAddress(VOID)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Retrieve the system's memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Determine the base address for system PTEs based on the paging mode */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* For 5-level paging, system PTEs start at the beginning of system space */\n        return MM::Paging::GetPteAddress((PVOID)MemoryLayout->NonPagedSystemPoolStart);\n    }\n    else\n    {\n        /* For 4-level paging, system PTEs start at the legacy KSEG0_BASE */\n        return MM::Paging::GetPteAddress((PVOID)KSEG0_BASE);\n    }\n}\n\n/**\n * Performs the initial setup of the system's page table hierarchy.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::InitializePageTable(VOID)\n{\n    PMMPTE EndSpacePte, PointerPte;\n    PMMMEMORY_LAYOUT MemoryLayout;\n    PVOID MappingRange;\n    MMPTE TemplatePte;\n    BOOLEAN Xpa;\n\n    /* Retrieve current paging mode and memory layout */\n    Xpa = MM::Paging::GetXpaStatus();\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Enable the Global Paging (PGE) feature */\n    AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_PGE);\n\n    /* Check XPA status */\n    if(Xpa)\n    {\n        /* Get the PML5 user-space range if 5-level paging is active */\n        PointerPte = MM::Paging::GetP5eAddress(0);\n        EndSpacePte = MM::Paging::GetP5eAddress(MemoryLayout->UserSpaceEnd);\n    }\n    else\n    {\n        /* Otherwise, get the PML4 user-space range for 4-level paging */\n        PointerPte = MM::Paging::GetPxeAddress(0);\n        EndSpacePte = MM::Paging::GetPxeAddress(MemoryLayout->UserSpaceEnd);\n    }\n\n    /* Clear all top-level entries mapping the user address space */\n    while(PointerPte <= EndSpacePte)\n    {\n        MM::Paging::ClearPte(PointerPte);\n        PointerPte = MM::Paging::GetNextPte(PointerPte);\n    }\n\n    /* Flush the TLB to invalidate all non-global entries */\n    AR::CpuFunctions::FlushTlb();\n\n    /* Create a template PTE for mapping kernel pages */\n    MM::Paging::ClearPte(&TemplatePte);\n    MM::Paging::SetPte(&TemplatePte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);\n\n    /* Check XPA status */\n    if(Xpa)\n    {\n        /* Map the kernel's PML5 entries if 5-level paging is active */\n        MM::Pte::MapP5E(MemoryLayout->HyperSpaceStart, (PVOID)MM_HIGHEST_SYSTEM_ADDRESS, &TemplatePte);\n    }\n\n    /* Map the kernel's PML4 entries */\n    MM::Pte::MapPXE(MemoryLayout->HyperSpaceStart, (PVOID)MM_HIGHEST_SYSTEM_ADDRESS, &TemplatePte);\n\n    /* Calculate the end address of the hyperspace working set mapping */\n    MappingRange = (PVOID)((ULONG_PTR)MemoryLayout->HyperSpaceStart + MM_HYPERSPACE_PAGE_COUNT * MM_PAGE_SIZE);\n\n    /* Map the PDPT entries for paged pool and hyperspace */\n    MM::Pte::MapPPE(MemoryLayout->PagedPoolStart, MemoryLayout->PagedPoolEnd, &ValidPte);\n    MM::Pte::MapPPE(MemoryLayout->HyperSpaceStart, MemoryLayout->HyperSpaceEnd, &ValidPte);\n\n    /* Map the PDEs for the hyperspace working set */\n    MM::Pte::MapPDE(MemoryLayout->HyperSpaceStart, MappingRange, &ValidPte);\n\n    /* Set the hyperspace working set's PTE with the total PTE count */\n    MM::Paging::SetPte(MM::Paging::GetPteAddress((PVOID)MemoryLayout->HyperSpaceStart), MM_HYPERSPACE_PAGE_COUNT, 0);\n}\n\n/**\n * Maps a range of virtual addresses at the P5E (PML5) level.\n *\n * @param StartAddress\n *        The beginning of the virtual address range to map.\n *\n * @param EndAddress\n *        The end of the virtual address range to map.\n *\n * @param TemplateP5e\n *        A template P5E to use for creating new entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::MapP5E(IN PVOID StartAddress,\n                IN PVOID EndAddress,\n                IN PMMP5E TemplateP5e)\n{\n    PMMP5E EndSpace, PointerP5e;\n\n    /* Get P5E addresses */\n    PointerP5e = MM::Paging::GetP5eAddress(StartAddress);\n    EndSpace = MM::Paging::GetP5eAddress(EndAddress);\n\n    /* Iterate over all P5Es */\n    while(PointerP5e <= EndSpace)\n    {\n        /* Check if P5E is already mapped */\n        if(!MM::Paging::PteValid(PointerP5e))\n        {\n            /* Map P5E */\n            MM::Paging::SetPte(TemplateP5e, MM::Pfn::AllocateBootstrapPages(1), 0);\n            *PointerP5e = *TemplateP5e;\n\n            /* Clear the page table */\n            RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerP5e), MM_PAGE_SIZE);\n        }\n\n        /* Get next table entry */\n        PointerP5e = MM::Paging::GetNextPte(PointerP5e);\n    }\n}\n\n/**\n * Maps a range of virtual addresses at the PPE (Page Directory Pointer Entry) level.\n *\n * @param StartAddress\n *        The beginning of the virtual address range to map.\n *\n * @param EndAddress\n *        The end of the virtual address range to map.\n *\n * @param TemplatePpe\n *        A template PPE to use for creating new entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::MapPPE(IN PVOID StartAddress,\n                IN PVOID EndAddress,\n                IN PMMPPE TemplatePpe)\n{\n    PMMPPE EndSpace, PointerPpe;\n\n    /* Get PPE addresses */\n    PointerPpe = MM::Paging::GetPpeAddress(StartAddress);\n    EndSpace = MM::Paging::GetPpeAddress(EndAddress);\n\n    /* Iterate over all PPEs */\n    while(PointerPpe <= EndSpace)\n    {\n        /* Check if PPE is already mapped */\n        if(!MM::Paging::PteValid(PointerPpe))\n        {\n            /* Map PPE */\n            MM::Paging::SetPte(TemplatePpe, MM::Pfn::AllocateBootstrapPages(1), 0);\n            *PointerPpe = *TemplatePpe;\n\n            /* Clear the page table */\n            RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPpe), MM_PAGE_SIZE);\n        }\n\n        /* Get next table entry */\n        PointerPpe = MM::Paging::GetNextPte(PointerPpe);\n    }\n}\n\n/**\n * Maps a range of virtual addresses at the PXE (PML4) level.\n *\n * @param StartAddress\n *        The beginning of the virtual address range to map.\n *\n * @param EndAddress\n *        The end of the virtual address range to map.\n *\n * @param TemplatePxe\n *        A template PXE to use for creating new entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::MapPXE(IN PVOID StartAddress,\n                IN PVOID EndAddress,\n                IN PMMPXE TemplatePxe)\n{\n    PMMPXE EndSpace, PointerPxe;\n\n    /* Get PXE addresses */\n    PointerPxe = MM::Paging::GetPxeAddress(StartAddress);\n    EndSpace = MM::Paging::GetPxeAddress(EndAddress);\n\n    /* Iterate over all PTEs */\n    while(PointerPxe <= EndSpace)\n    {\n        /* Check if PTE is already mapped */\n        if(!MM::Paging::PteValid(PointerPxe))\n        {\n            /* Map PTE */\n            MM::Paging::SetPte(TemplatePxe, MM::Pfn::AllocateBootstrapPages(1), 0);\n            *PointerPxe = *TemplatePxe;\n\n            /* Clear the page table */\n            RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPxe), MM_PAGE_SIZE);\n        }\n\n        /* Get next table entry */\n        PointerPxe = MM::Paging::GetNextPte(PointerPxe);\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/mm/colors.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/colors.cc\n * DESCRIPTION:     Memory manager page coloring subsystem\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Computes & initializes the system's page coloring.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Colors::ComputePageColoring(VOID)\n{\n    UNIMPLEMENTED;\n\n    /* Compute L2 paging colors and mask */\n    PagingColors = MM_PAGING_COLORS;\n    PagingColorsMask = PagingColors - 1;\n}\n\n/**\n * Retrieves a pointer to the color table for a specific page list and color.\n *\n * @param PageList\n *        The page list type (e.g., FreePageList, ZeroedPageList).\n *\n * @param Color\n *        Supplies the specific color index.\n *\n * @return This routine returns a pointer to the corresponding MMCOLOR_TABLES structure.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMCOLOR_TABLES\nMM::Colors::GetFreePages(IN MMPAGELISTS PageList,\n                         IN ULONG Color)\n{\n    /* Return a pointer to the requested color table entry */\n    return &FreePages[PageList][Color];\n}\n\n/**\n * Retrieves a pointer to the modified pages list for a specific color.\n *\n * @param Color\n *        Supplies the specific color index.\n *\n * @return This routine returns a pointer to the corresponding MMPFNLIST structure.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPFNLIST\nMM::Colors::GetModifiedPages(IN ULONG Color)\n{\n    return &ModifiedPages[Color];\n}\n\n/**\n * Retrieves the next available color for page coloring.\n *\n * @return This routine returns the next color value, ensuring it stays within the valid color range.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Colors::GetNextColor(VOID)\n{\n    /* Increment the color counter and wrap it around using the mask */\n    return ((++PagingColors) & PagingColorsMask);\n}\n\n/**\n * Retrieves the total number of page colors configured in the system.\n *\n * @return This routine returns the number of page colors.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Colors::GetPagingColors(VOID)\n{\n    /* Return the total number of page colors */\n    return PagingColors;\n}\n\n/**\n * Retrieves the bitmask used for calculating a page's color.\n *\n * @return This routine returns the page color mask.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Colors::GetPagingColorsMask(VOID)\n{\n    /* Return the mask used for page coloring calculations */\n    return PagingColorsMask;\n}\n\n/**\n * Initializes the data structures for page coloring.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Colors::InitializeColorTables(VOID)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n    PMMPTE PointerPte, LastPte;\n    ULONG Color;\n    PMMPTE ValidPte;\n\n    /* Get the memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Set the base address of the color tables to start right after the PFN database */\n    FreePages[0] = (PMMCOLOR_TABLES)&((PMMPFN)MemoryLayout->PfnDatabase)[MM::Pfn::GetHighestPhysicalPage() + 1];\n\n    /* Calculate the virtual address range for both color tables */\n    PointerPte = MM::Paging::GetPteAddress(&FreePages[0][0]);\n    LastPte = MM::Paging::GetPteAddress((PVOID)((ULONG_PTR)FreePages[0] +\n                                        (2 * PagingColors * sizeof(MMCOLOR_TABLES)) - 1));\n\n    /* Get a pointer to a PTE template */\n    ValidPte = MM::Pte::GetValidPte();\n\n    /* Ensure the entire virtual address range for the color tables is mapped */\n    while(PointerPte <= LastPte)\n    {\n        /* Check if a page in the range is not mapped */\n        if(!MM::Paging::PteValid(PointerPte))\n        {\n            /* Use the bootstrap allocator to get a physical page */\n            MM::Paging::SetPte(ValidPte, MM::Pfn::AllocateBootstrapPages(1), 0);\n            *PointerPte = *ValidPte;\n\n            /* Zero out the newly mapped page */\n            RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPte), MM_PAGE_SIZE);\n        }\n\n        /* Move to the next PTE in the range */\n        PointerPte = MM::Paging::GetNextPte(PointerPte);\n    }\n\n    /* Set the pointer for the second list */\n    FreePages[1] = &FreePages[0][PagingColors];\n\n    /* Initialize all entries in both color tables */\n    for(Color = 0; Color < PagingColors; Color++)\n    {\n        /* Initialize the FreePageList entry for the current color */\n        FreePages[FreePageList][Color].Flink = MAXULONG_PTR;\n        FreePages[FreePageList][Color].Blink = (PVOID)MAXULONG_PTR;\n        FreePages[FreePageList][Color].Count = 0;\n\n        /* Initialize the ZeroedPageList entry for the current color */\n        FreePages[ZeroedPageList][Color].Flink = MAXULONG_PTR;\n        FreePages[ZeroedPageList][Color].Blink = (PVOID)MAXULONG_PTR;\n        FreePages[ZeroedPageList][Color].Count = 0;\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/mm/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/data.cc\n * DESCRIPTION:     Memory Manager global and static data\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/* Expansion table used to track pool memory allocations */\nPPOOL_TRACKING_TABLE MM::Allocator::AllocationsTrackingExpansionTable;\n\n/* Total number of entries in the expansion allocations tracking table */\nSIZE_T MM::Allocator::AllocationsTrackingExpansionTableSize;\n\n/* Global table used to track pool memory allocations */\nPPOOL_TRACKING_TABLE MM::Allocator::AllocationsTrackingTable;\n\n/* Spinlock protecting the allocations table */\nKSPIN_LOCK MM::Allocator::AllocationsTrackingTableLock;\n\n/* Bitmask used during the hashing process */\nSIZE_T MM::Allocator::AllocationsTrackingTableMask;\n\n/* Total number of entries in the global allocations tracking table */\nSIZE_T MM::Allocator::AllocationsTrackingTableSize;\n\n/* Active number of big allocations to trigger table expansion */\nULONG MM::Allocator::BigAllocationsInUse;\n\n/* Pointer to the hash table for tracking page-aligned memory */\nPPOOL_TRACKING_BIG_ALLOCATIONS MM::Allocator::BigAllocationsTrackingTable;\n\n/* Bitmask used for fast modulo arithmetic during hash bucket lookups */\nSIZE_T MM::Allocator::BigAllocationsTrackingTableHash;\n\n/* Spinlock protecting the big allocations table */\nKSPIN_LOCK MM::Allocator::BigAllocationsTrackingTableLock;\n\n/* Maximum capacity of the tracking hash table */\nSIZE_T MM::Allocator::BigAllocationsTrackingTableSize;\n\n/* Array of CPU-local tracking tables */\nPPOOL_TRACKING_TABLE MM::Allocator::TagTables[MM_POOL_TRACKING_TABLES];\n\n/* Array of free page lists segregated by cache color */\nPMMCOLOR_TABLES MM::Colors::FreePages[FreePageList + 1];\n\n/* Array of modified pages segregated by cache color */\nMMPFNLIST MM::Colors::ModifiedPages[MM_PAGING_COLORS] = {{0, ModifiedPageList, MAXULONG_PTR, MAXULONG_PTR}};\n\n/* Number of supported page colors */\nULONG MM::Colors::PagingColors;\n\n/* Bitmask used to calculate the cache color index */\nULONG MM::Colors::PagingColorsMask;\n\n/* Allocation descriptors dedicated for hardware layer */\nLOADER_MEMORY_DESCRIPTOR MM::HardwarePool::HardwareAllocationDescriptors[MM_HARDWARE_ALLOCATION_DESCRIPTORS];\n\n/* Live address of kernel's hardware heap */\nPVOID MM::HardwarePool::HardwareHeapStart = MM_HARDWARE_HEAP_START_ADDRESS;\n\n/* Number of used hardware allocation descriptors */\nULONG MM::HardwarePool::UsedHardwareAllocationDescriptors = 0;\n\n/* Global structure describing the virtual memory layout of the system */\nMMMEMORY_LAYOUT MM::Manager::MemoryLayout;\n\n/* Total number of PTEs reserved for system space mapping */\nPFN_NUMBER MM::Manager::NumberOfSystemPtes;\n\n/* Physical memory block descriptor */\nPPHYSICAL_MEMORY_DESCRIPTOR MM::Manager::PhysicalMemoryBlock;\n\n/* Instance of the page map routines for the current PML level */\nMM::PPAGEMAP MM::Paging::PmlRoutines;\n\n/* Total number of physical pages available for allocation */\nPFN_NUMBER MM::Pfn::AvailablePages;\n\n/* Head of the list containing physical pages marked as defective */\nMMPFNLIST MM::Pfn::BadPagesList = {0, BadPageList, MAXULONG_PTR, MAXULONG_PTR};\n\n/* Biggest free memory descriptor */\nPLOADER_MEMORY_DESCRIPTOR MM::Pfn::FreeDescriptor;\n\n/* List containing free physical pages */\nMMPFNLIST MM::Pfn::FreePagesList = {0, FreePageList, MAXULONG_PTR, MAXULONG_PTR};\n\n/* Highest physical page number */\nULONG_PTR MM::Pfn::HighestPhysicalPage;\n\n/* Lowest physical page number */\nULONG_PTR MM::Pfn::LowestPhysicalPage;\n\n/* List containing modified pages */\nMMPFNLIST MM::Pfn::ModifiedPagesList = {0, ModifiedPageList, MAXULONG_PTR, MAXULONG_PTR};\n\n/* List containing modified pages mapped as read-only */\nMMPFNLIST MM::Pfn::ModifiedReadOnlyPagesList = {0, ModifiedReadOnlyPageList, MAXULONG_PTR, MAXULONG_PTR};\n\n/* Number of physical pages */\nULONGLONG MM::Pfn::NumberOfPhysicalPages;\n\n/* Old biggest free memory descriptor */\nLOADER_MEMORY_DESCRIPTOR MM::Pfn::OriginalFreeDescriptor;\n\n/* Array of pointers to PFN lists */\nPMMPFNLIST MM::Pfn::PageLocationList[] = {&ZeroedPagesList,\n                                          &FreePagesList,\n                                          &StandbyPagesList,\n                                          &ModifiedPagesList,\n                                          &ModifiedReadOnlyPagesList,\n                                          &BadPagesList,\n                                          NULLPTR,\n                                          NULLPTR};\n\n/* Bitmap used to track physical pages */\nRTL_BITMAP MM::Pfn::PfnBitMap;\n\n/* List containing pages mapped as Read-Only (ROM) */\nMMPFNLIST MM::Pfn::RomPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULONG_PTR};\n\n/* List containing standby pages (clean, can be reclaimed or repurposed) */\nMMPFNLIST MM::Pfn::StandbyPagesList = {0, StandbyPageList, MAXULONG_PTR, MAXULONG_PTR};\n\n/* List containing free physical pages that have been zeroed out */\nMMPFNLIST MM::Pfn::ZeroedPagesList = {0, ZeroedPageList, MAXULONG_PTR, MAXULONG_PTR};\n\n/* Non-paged pool descriptor */\nPOOL_DESCRIPTOR MM::Pool::NonPagedPoolDescriptor;\n\n/* PFN marking the initial non-paged pool end boundary */\nPFN_NUMBER MM::Pool::NonPagedPoolFrameEnd;\n\n/* PFN marking the initial non-paged pool start boundary */\nPFN_NUMBER MM::Pool::NonPagedPoolFrameStart;\n\n/* Array of non-paged pool free list heads */\nLIST_ENTRY MM::Pool::NonPagedPoolFreeList[MM_MAX_FREE_PAGE_LIST_HEADS];\n\n/* Random cookie used to obfuscate pool links */\nULONG MM::Pool::PoolSecureCookie;\n\n/* Array of pool descriptors */\nPPOOL_DESCRIPTOR MM::Pool::PoolVector[2];\n\n/* Array of lists for available System PTEs, separated by pool type */\nMMPTE MM::Pte::FirstSystemFreePte[MaximumPtePoolTypes];\n\n/* Virtual base address of the System PTE space */\nPMMPTE MM::Pte::SystemPteBase;\n\n/* End addresses for the System PTE ranges */\nPMMPTE MM::Pte::SystemPtesEnd[MaximumPtePoolTypes];\n\n/* Start addresses for the System PTE ranges */\nPMMPTE MM::Pte::SystemPtesStart[MaximumPtePoolTypes];\n\n/* Total count of available System PTEs */\nPFN_COUNT MM::Pte::TotalSystemFreePtes[MaximumPtePoolTypes];\n\n/* Template PTE entry containing standard flags for a valid, present kernel page */\nMMPTE MM::Pte::ValidPte;\n"
  },
  {
    "path": "xtoskrnl/mm/exports.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/exports.cc\n * DESCRIPTION:     C-compatible API wrappers for exported kernel functions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Allocates a block of memory from the specified pool type.\n *\n * @param PoolType\n *        Specifies the type of pool to allocate from.\n *\n * @param Bytes\n *        Specifies the number of bytes to allocate.\n *\n * @param Memory\n *        Supplies a pointer to the allocated memory.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMmAllocatePool(IN MMPOOL_TYPE PoolType,\n               IN SIZE_T Bytes,\n               OUT PVOID *Memory)\n{\n    return MM::Allocator::AllocatePool(PoolType, Bytes, Memory);\n}\n\n/**\n * Allocates a block of memory from the specified pool type.\n *\n * @param PoolType\n *        Specifies the type of pool to allocate from.\n *\n * @param Bytes\n *        Specifies the number of bytes to allocate.\n *\n * @param Memory\n *        Supplies a pointer to the allocated memory.\n *\n * @param Tag\n *        Specifies the allocation identifying tag.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMmAllocatePoolWithTag(IN MMPOOL_TYPE PoolType,\n                      IN SIZE_T Bytes,\n                      OUT PVOID *Memory,\n                      IN ULONG Tag)\n{\n    return MM::Allocator::AllocatePool(PoolType, Bytes, Memory, Tag);\n}\n\n/**\n * Frees a previously allocated memory pool.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address of the pool allocation to free.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMmFreePool(IN PVOID VirtualAddress)\n{\n    return MM::Allocator::FreePool(VirtualAddress);\n}\n\n/**\n * Frees a previously allocated memory pool.\n *\n * @param VirtualAddress\n *        Supplies the base virtual address of the pool allocation to free.\n *\n * @param Tag\n *        Specifies the allocation identifying tag.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMmFreePoolWithTag(IN PVOID VirtualAddress,\n                  IN ULONG Tag)\n{\n    return MM::Allocator::FreePool(VirtualAddress, Tag);\n}\n"
  },
  {
    "path": "xtoskrnl/mm/hlpool.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/hlpool.cc\n * DESCRIPTION:     Hardware layer pool memory management\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Allocates physical memory for kernel hardware layer before memory manager gets initialized.\n *\n * @param PageCount\n *        Supplies the number of pages to be allocated.\n *\n * @param Aligned\n *        Specifies whether allocated memory should be aligned to 64k boundary or not.\n *\n * @param MaximumAddress\n *        Supplies the maximum acceptable physical address for the allocation.\n *\n * @param Buffer\n *        Supplies a buffer that receives the physical address.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::HardwarePool::AllocateHardwareMemory(IN PFN_NUMBER PageCount,\n                                         IN BOOLEAN Aligned,\n                                         IN ULONGLONG MaximumAddress,\n                                         OUT PPHYSICAL_ADDRESS Buffer)\n{\n    PLOADER_MEMORY_DESCRIPTOR Descriptor, ExtraDescriptor, HardwareDescriptor;\n    PLIST_ENTRY ListEntry, LoaderMemoryDescriptors;\n    PFN_NUMBER Alignment, MaxPage;\n    ULONGLONG PhysicalAddress;\n\n    /* Assume failure */\n    (*Buffer).QuadPart = 0;\n\n    /* Calculate maximum page address based on the requested limit */\n    MaxPage = MaximumAddress >> MM_PAGE_SHIFT;\n\n    /* Make sure there are at least 2 descriptors available */\n    if((UsedHardwareAllocationDescriptors + 2) > MM_HARDWARE_ALLOCATION_DESCRIPTORS)\n    {\n        /* Not enough descriptors, return error */\n        return STATUS_INSUFFICIENT_RESOURCES;\n    }\n\n    /* Get a list of memory descriptors provided by the boot loader */\n    LoaderMemoryDescriptors = KE::BootInformation::GetMemoryDescriptors();\n\n    /* Scan memory descriptors provided by the boot loader */\n    ListEntry = LoaderMemoryDescriptors->Blink;\n    while(ListEntry != LoaderMemoryDescriptors)\n    {\n        Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);\n\n        /* Align memory to 64KB if needed */\n        Alignment = Aligned ? (((Descriptor->BasePage + 0x0F) & ~0x0F) - Descriptor->BasePage) : 0;\n\n        /* Ensure that memory type is free for this descriptor */\n        if(Descriptor->MemoryType == LoaderFree)\n        {\n            /* Check if descriptor is big enough and if it fits under the maximum physical address */\n            if(Descriptor->BasePage &&\n               ((Descriptor->BasePage + PageCount + Alignment) < MaxPage) &&\n               (Descriptor->PageCount >= (PageCount + Alignment)))\n            {\n                /* Set physical address */\n                PhysicalAddress = (Descriptor->BasePage + Alignment) << MM_PAGE_SHIFT;\n                break;\n            }\n        }\n\n        /* Move to previous descriptor */\n        ListEntry = ListEntry->Blink;\n    }\n\n    /* Make sure we found a descriptor */\n    if(ListEntry == LoaderMemoryDescriptors)\n    {\n        /* Descriptor not found, return error */\n        return STATUS_INSUFFICIENT_RESOURCES;\n    }\n\n    /* Allocate new descriptor */\n    HardwareDescriptor = &HardwareAllocationDescriptors[UsedHardwareAllocationDescriptors];\n    HardwareDescriptor->BasePage = Descriptor->BasePage + Alignment;\n    HardwareDescriptor->MemoryType = LoaderHardwareCachedMemory;\n    HardwareDescriptor->PageCount = PageCount;\n\n    /* Update hardware allocation descriptors count */\n    UsedHardwareAllocationDescriptors++;\n\n    /* Check if alignment was done */\n    if(Alignment)\n    {\n        /* Check if extra descriptor is needed to describe the allocation */\n        if(Descriptor->PageCount > (PageCount + Alignment))\n        {\n            /* Initialize extra descriptor */\n            ExtraDescriptor = &HardwareAllocationDescriptors[UsedHardwareAllocationDescriptors];\n            ExtraDescriptor->BasePage = Descriptor->BasePage + Alignment + (ULONG)PageCount;\n            ExtraDescriptor->MemoryType = LoaderFree;\n            ExtraDescriptor->PageCount = Descriptor->PageCount - (Alignment + (ULONG)PageCount);\n\n            /* Update hardware allocation descriptors count */\n            UsedHardwareAllocationDescriptors++;\n\n            /* Insert extra descriptor in the list */\n            RTL::LinkedList::InsertHeadList(&Descriptor->ListEntry, &ExtraDescriptor->ListEntry);\n        }\n\n        /* Trim source descriptor to the alignment */\n        Descriptor->PageCount = Alignment;\n\n        /* Insert new descriptor in the list */\n        RTL::LinkedList::InsertHeadList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry);\n    }\n    else\n    {\n        /* Consume pages from the source descriptor */\n        Descriptor->BasePage += (ULONG)PageCount;\n        Descriptor->PageCount -= (ULONG)PageCount;\n\n        /* Insert new descriptor in the list */\n        RTL::LinkedList::InsertTailList(&Descriptor->ListEntry, &HardwareDescriptor->ListEntry);\n\n        /* Check if source descriptor is fully consumed */\n        if(Descriptor->PageCount == 0)\n        {\n            /* Remove descriptor from the list */\n            RTL::LinkedList::RemoveEntryList(&Descriptor->ListEntry);\n        }\n    }\n\n    /* Return physical address */\n    (*Buffer).QuadPart = PhysicalAddress;\n    return STATUS_SUCCESS;\n}\n\n/**\n * Allocates a physical page in low memory (addressable in real-mode) and maps it into the virtual address space.\n *\n * @param MemoryAddress\n *        Supplies a pointer to a variable that receives the identity-mapped virtual address of the allocated memory.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::HardwarePool::AllocateRealModeMemory(IN PFN_NUMBER PageCount,\n                                         OUT PVOID *MemoryAddress)\n{\n    PHYSICAL_ADDRESS PhysicalAddress;\n    PFN_NUMBER PageFrameNumber;\n    PVOID VirtualAddress;\n    XTSTATUS Status;\n\n    /* Allocate physical memory in first 1MB */\n    Status = AllocateHardwareMemory(PageCount, TRUE, 0x100000, &PhysicalAddress);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to allocate memory, return error */\n        return Status;\n    }\n\n    /* Calculate virtual address and page frame number */\n    VirtualAddress = (PVOID)(ULONG_PTR)PhysicalAddress.QuadPart;\n    PageFrameNumber = PhysicalAddress.QuadPart >> MM_PAGE_SHIFT;\n\n    /* Identity map the memory to the virtual address */\n    Status = MM::Paging::MapVirtualAddress(VirtualAddress, PageFrameNumber, MM_PTE_EXECUTE_READWRITE);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to map memory, return error */\n        return Status;\n    }\n\n    /* Set the trampoline virtual address and return success */\n    *MemoryAddress = VirtualAddress;\n    return STATUS_SUCCESS;\n}\n\n/**\n * Maps physical address to the virtual memory area used by kernel hardware layer.\n *\n * @param PhysicalAddress\n *        Supplies the physical address to map.\n *\n * @param PageCount\n *        Supplies the number of pages to be mapped.\n *\n * @param FlushTlb\n *        Specifies whether to flush the TLB or not.\n *\n * @param VirtualAddress\n *        Supplies a buffer that receives the virtual address of the mapped pages.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::HardwarePool::MapHardwareMemory(IN PHYSICAL_ADDRESS PhysicalAddress,\n                                    IN PFN_NUMBER PageCount,\n                                    IN BOOLEAN FlushTlb,\n                                    OUT PVOID *VirtualAddress)\n{\n    PVOID BaseAddress, ReturnAddress;\n    PFN_NUMBER MappedPages;\n    PMMPTE PtePointer;\n\n    /* Initialize variables */\n    BaseAddress = HardwareHeapStart;\n    MappedPages = 0;\n    ReturnAddress = BaseAddress;\n    *VirtualAddress = NULLPTR;\n\n    /* Iterate through all pages */\n    while(MappedPages < PageCount)\n    {\n        /* Check if address overflows */\n        if(BaseAddress == NULLPTR)\n        {\n            /* Not enough free pages, return error */\n            return STATUS_INSUFFICIENT_RESOURCES;\n        }\n\n        /* Get PTE pointer and advance to next page */\n        PtePointer = MM::Paging::GetPteAddress(ReturnAddress);\n        ReturnAddress = (PVOID)((ULONG_PTR)ReturnAddress + MM_PAGE_SIZE);\n\n        /* Check if PTE is valid */\n        if(MM::Paging::PteValid(PtePointer))\n        {\n            /* PTE is not available, go to the next one */\n            BaseAddress = ReturnAddress;\n            MappedPages = 0;\n            continue;\n        }\n\n        /* Increase number of mapped pages */\n        MappedPages++;\n    }\n\n    /* Take the actual base address with an offset */\n    ReturnAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_OFFSET(PhysicalAddress.LowPart));\n\n    /* Check if base address starts at the beginning of the heap */\n    if(BaseAddress == HardwareHeapStart)\n    {\n        /* Move heap beyond base address */\n        HardwareHeapStart = (PVOID)((ULONG_PTR)BaseAddress + ((ULONG_PTR)PageCount << MM_PAGE_SHIFT));\n    }\n\n    /* Iterate through mapped pages */\n    while(MappedPages--)\n    {\n        /* Get PTE pointer */\n        PtePointer = MM::Paging::GetPteAddress(BaseAddress);\n\n        /* Fill the PTE */\n        MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), MM_PTE_READWRITE);\n\n        /* Advance to the next address */\n        PhysicalAddress.QuadPart += MM_PAGE_SIZE;\n        BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + MM_PAGE_SIZE);\n    }\n\n    /* Check if TLB needs to be flushed */\n    if(FlushTlb)\n    {\n        /* Flush the TLB */\n        MM::Paging::FlushTlb();\n    }\n\n    /* Return virtual address */\n    *VirtualAddress = ReturnAddress;\n    return STATUS_SUCCESS;\n}\n\n/**\n * Marks existing mapping as CD/WT to avoid delays in write-back cache.\n *\n * @param VirtualAddress\n *        Supplies the virtual address region to mark as CD/WT.\n *\n * @param PageCount\n *        Supplies the number of mapped pages.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::HardwarePool::MarkHardwareMemoryWriteThrough(IN PVOID VirtualAddress,\n                                                 IN PFN_NUMBER PageCount)\n{\n    PMMPTE PtePointer;\n    PFN_NUMBER Page;\n\n    /* Get PTE address from virtual address */\n    PtePointer = MM::Paging::GetPteAddress(VirtualAddress);\n\n    /* Iterate through mapped pages */\n    for(Page = 0; Page < PageCount; Page++)\n    {\n        /* Mark pages as CD/WT */\n        MM::Paging::SetPteCaching(PtePointer, TRUE, TRUE);\n        MM::Paging::GetNextEntry(PtePointer);\n    }\n}\n\n/**\n * Remaps the PTE to new physical address.\n *\n * @param VirtualAddress\n *        Supplies the virtual address to remap.\n *\n * @param PhysicalAddress\n *        Supplies a new physical address.\n *\n * @param FlushTlb\n *        Specifies whether to flush the TLB or not.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::HardwarePool::RemapHardwareMemory(IN PVOID VirtualAddress,\n                                      IN PHYSICAL_ADDRESS PhysicalAddress,\n                                      IN BOOLEAN FlushTlb)\n{\n    PMMPTE PtePointer;\n\n    /* Get PTE address from virtual address */\n    PtePointer = MM::Paging::GetPteAddress(VirtualAddress);\n\n    /* Remap the PTE */\n    MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysicalAddress.QuadPart >> MM_PAGE_SHIFT), MM_PTE_READWRITE);\n\n    /* Check if TLB needs to be flushed */\n    if(FlushTlb)\n    {\n        /* Flush the TLB */\n        MM::Paging::FlushTlb();\n    }\n}\n\n/**\n * Unmaps a Page Table Entry corresponding to the given virtual address.\n *\n * @param VirtualAddress\n *        Supplies the virtual address to unmap.\n *\n * @param PageCount\n *        Supplies the number of mapped pages.\n *\n * @param FlushTlb\n *        Specifies whether to flush the TLB or not.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::HardwarePool::UnmapHardwareMemory(IN PVOID VirtualAddress,\n                                      IN PFN_NUMBER PageCount,\n                                      IN BOOLEAN FlushTlb)\n{\n    PMMPTE PtePointer;\n    PFN_NUMBER Page;\n\n    /* Check if address is valid hardware memory */\n    if(VirtualAddress < (PVOID)MM_HARDWARE_VA_START)\n    {\n        /* Invalid address, return error */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Align virtual address down to page boundary */\n    VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(MM_PAGE_SIZE - 1));\n\n    /* Get PTE address from virtual address */\n    PtePointer = MM::Paging::GetPteAddress(VirtualAddress);\n\n    /* Iterate through mapped pages */\n    for(Page = 0; Page < PageCount; Page++)\n    {\n        /* Unmap the PTE and get the next one */\n        MM::Paging::ClearPte(PtePointer);\n        PtePointer++;\n    }\n\n    /* Check if TLB needs to be flushed */\n    if(FlushTlb)\n    {\n        /* Flush the TLB */\n        MM::Paging::FlushTlb();\n    }\n\n    /* Check if heap can be reused */\n    if(HardwareHeapStart > VirtualAddress)\n    {\n        /* Free VA space */\n        HardwareHeapStart = VirtualAddress;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "xtoskrnl/mm/i686/mmgr.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/i686/mmgr.cc\n * DESCRIPTION:     Memory Manager\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Calculates the maximum possible size of the non-paged pool.\n *\n * @param PoolSize\n *        A pointer to a variable that will receive the number of pages available for the non-paged pool.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeMaximumNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)\n{\n    ULONG_PTR MaximumNonPagedPoolSize;\n    ULONGLONG PhysicalPages;\n\n    /* Get number of physical pages */\n    PhysicalPages = MM::Pfn::GetNumberOfPhysicalPages();\n\n    /* Start with 1MiB and reserve space for PFN database */\n    MaximumNonPagedPoolSize = 1048576;\n\n    /* Check if system has at least 512MiB of physical memory */\n    if(PhysicalPages >= 126976)\n    {\n        /* Add 200KiB for each MiB above 4MiB */\n        MaximumNonPagedPoolSize += ((PhysicalPages - 1024)/256) * 204800;\n\n        /* Check if non-paged pool has at least 128MiB */\n        if(MaximumNonPagedPoolSize < 134217728)\n        {\n            /* Expand non-paged pool size to 128MiB */\n            MaximumNonPagedPoolSize = 134217728;\n        }\n    }\n    else\n    {\n        /* Add 400KiB for each MiB above 4MiB */\n        MaximumNonPagedPoolSize += ((PhysicalPages - 1024)/256) * 409600;\n    }\n\n    /* Check if non-paged pool does not exceed 256MiB */\n    if(MaximumNonPagedPoolSize > 268435456)\n    {\n        /* Limit non-paged pool size to 256MiB */\n        MaximumNonPagedPoolSize = 268435456;\n    }\n\n    /* Return maximum non-paged pool size in pages */\n    *PoolSize = SIZE_TO_PAGES(MaximumNonPagedPoolSize);\n}\n\n/**\n * Calculates the size of the non-paged pool.\n *\n * @param PoolSize\n *        A pointer to a variable that will receive the number of pages available for the non-paged pool.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeNonPagedPoolSize(OUT PPFN_NUMBER PoolSize)\n{\n    ULONG_PTR NonPagedPoolSize;\n    ULONGLONG PhysicalPages;\n\n    /* Get number of physical pages */\n    PhysicalPages = MM::Pfn::GetNumberOfPhysicalPages();\n\n    /* Verify if system has less than 256MiB of physical memory */\n    if(PhysicalPages <= 65536)\n    {\n        /* Reduce initial non-paged pool size to 2MiB to save memory */\n        NonPagedPoolSize = 2097152;\n    }\n    else\n    {\n        /* Start with 256KiB and add 32KiB for each MiB above 4MiB */\n        NonPagedPoolSize = 262144 + (((PhysicalPages - 1024) / 256) * 32768);\n\n        if(NonPagedPoolSize > 134217728)\n        {\n            /* Limit non-paged pool size to 128MiB */\n            NonPagedPoolSize = 134217728;\n        }\n    }\n\n    /* Return non-paged pool size in pages, aligned down to page size boundary */\n    *PoolSize = SIZE_TO_PAGES(ROUND_DOWN(NonPagedPoolSize, MM_PAGE_SIZE));\n}\n\n/**\n * Calculates the size of the paged pool.\n *\n * @param PoolSize\n *        A pointer to a variable that will receive the number of pages available for the paged pool.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputePagedPoolSize(OUT PPFN_NUMBER PoolSize)\n{\n    ULONG_PTR PagedPoolSize, PteCount;\n    ULONG PtesPerPage;\n\n    /* Start with maximum non-paged pool size */\n    ComputeMaximumNonPagedPoolSize(&PagedPoolSize);\n    PagedPoolSize *= MM_PAGE_SIZE;\n\n    /* Check XPA status */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* Four times the non-paged pool size on PAE-enabled systems */\n        PagedPoolSize *= 4;\n    }\n    else\n    {\n        /* Double the non-paged pool size on PAE-disabled systems */\n        PagedPoolSize *= 2;\n    }\n\n    /* Check if paged pool does not overlap non-paged pool */\n    if(PagedPoolSize > (ULONG_PTR)MemoryLayout.NonPagedSystemPoolStart - (ULONG_PTR)MemoryLayout.PagedPoolStart)\n    {\n        /* Limit paged pool size to maximum possible */\n        PagedPoolSize = (ULONG_PTR)MemoryLayout.NonPagedSystemPoolStart - (ULONG_PTR)MemoryLayout.PagedPoolStart;\n    }\n\n    /* Ensure that paged pool size is at least 32MiB */\n    if(PagedPoolSize < 33554432)\n    {\n        /* Increase paged pool size to at least 32MiB */\n        PagedPoolSize = 33554432;\n    }\n\n    /* Get the number of PTEs per page and calculate size of paged pool */\n    PtesPerPage = MM::Pte::GetPtesPerPage();\n    PteCount = ((SIZE_TO_PAGES(PagedPoolSize) + (PtesPerPage - 1)) / PtesPerPage);\n\n    /* Return paged pool size */\n    *PoolSize = (PFN_NUMBER)(PteCount * PtesPerPage);\n}\n\n/**\n * Calculates the size of the session space.\n *\n * @param SpaceSize\n *        A pointer to a variable that will receive the number of pages available by the session space.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeSessionSpaceSize(OUT PPFN_NUMBER SpaceSize)\n{\n    PFN_NUMBER SessionSpaceSize;\n\n    /* Session Pool, Session View, Session Image, Session Working Set and System View takes 108MiB */\n    SessionSpaceSize = 113246208;\n\n    /* Return number of pages used by the session space */\n    *SpaceSize = SessionSpaceSize / MM_PAGE_SIZE;\n}\n\n/**\n * Calculates the size of the system PTEs.\n *\n * @param PteSize\n *        A pointer to a variable that will receive the number of system PTEs.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeSystemPteSize(OUT PPFN_NUMBER PteSize)\n{\n    PFN_NUMBER SystemPteSize;\n\n    /* Check if system has less than 19MiB of physical memory */\n    if(MM::Pfn::GetNumberOfPhysicalPages() < 4864)\n    {\n        /* Set minimal system PTE size */\n        SystemPteSize = 7000;\n    }\n    else\n    {\n        /* Use standard system PTE size */\n        SystemPteSize = 11000;\n\n        /* Check if system has more than 32MiB of physical memory */\n        if(MM::Pfn::GetNumberOfPhysicalPages() > 8192)\n        {\n            /* Double system PTE size */\n            SystemPteSize *= 2;\n\n            /* Check if system has more than 256MiB of physical memory */\n            if(MM::Pfn::GetNumberOfPhysicalPages() > 65536)\n            {\n                /* Double system PTE size */\n                SystemPteSize *= 2;\n            }\n        }\n    }\n\n    /* Return system PTE size */\n    *PteSize = SystemPteSize;\n}\n\n/**\n * Dumps the kernel's memory layout.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::DumpMemoryLayout(VOID)\n{\n    /* Dump memory layout */\n    DebugPrint(L\"System with %zu MiB of installed memory:\\n\"\n               L\"User Space:               %.8P - %.8P\\n\"\n               L\"Loader Mappings:          %.8P - %.8P\\n\"\n               L\"PFN Database:             %.8P - %.8P\\n\"\n               L\"Non-Paged Pool:           %.8P - %.8P\\n\"\n               L\"Session Space:            %.8P - %.8P\\n\"\n               L\"PTE Space:                %.8P - %.8P\\n\"\n               L\"Hyper Space:              %.8P - %.8P\\n\"\n               L\"System Working Set:       %.8P - %.8P\\n\"\n               L\"System Cache:             %.8P - %.8P\\n\"\n               L\"Paged Pool:               %.8P - %.8P\\n\"\n               L\"Non-Paged System Pool:    %.8P - %.8P\\n\"\n               L\"Non-Paged Expansion Pool: %.8P - %.8P\\n\"\n               L\"Shared System Page:       %.8P - %.8P\\n\"\n               L\"Hardware Pool:            %.8P - %.8P\\n\",\n               GetInstalledMemorySize(),\n               MemoryLayout.UserSpaceStart,\n               MemoryLayout.UserSpaceEnd,\n               MemoryLayout.LoaderMappingsStart,\n               MemoryLayout.LoaderMappingsEnd,\n               MemoryLayout.PfnDatabase,\n               (PVOID)((ULONG_PTR)MemoryLayout.PfnDatabase + (ULONG_PTR)MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE),\n               MemoryLayout.NonPagedPoolStart,\n               MemoryLayout.NonPagedPoolEnd,\n               MemoryLayout.SessionSpaceStart,\n               MemoryLayout.SessionSpaceEnd,\n               MemoryLayout.PteSpaceStart,\n               MemoryLayout.PteSpaceEnd,\n               MemoryLayout.HyperSpaceStart,\n               MemoryLayout.HyperSpaceEnd,\n               MemoryLayout.SystemWorkingSetStart,\n               MemoryLayout.SystemWorkingSetEnd,\n               MemoryLayout.SystemCacheStart,\n               MemoryLayout.SystemCacheEnd,\n               MemoryLayout.PagedPoolStart,\n               MemoryLayout.PagedPoolEnd,\n               MemoryLayout.NonPagedSystemPoolStart,\n               MemoryLayout.NonPagedSystemPoolEnd,\n               MemoryLayout.NonPagedExpansionPoolStart,\n               MemoryLayout.NonPagedExpansionPoolEnd,\n               MemoryLayout.SharedSystemPageStart,\n               MemoryLayout.SharedSystemPageEnd,\n               MemoryLayout.HardwarePoolStart,\n               MemoryLayout.HardwarePoolEnd);\n}\n\n/**\n * Initializes the kernel's virtual memory layout.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::InitializeMemoryLayout(VOID)\n{\n    PFN_NUMBER MaximumNonPagedPoolSize;\n    ULONG_PTR PfnDatabaseEnd;\n\n    /* Check if 3-level paging (PAE) is enabled */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* Set PML3 base address */\n        MemoryLayout.SelfMapAddress = (PVOID)MM_PTE_BASE;\n\n        /* Define memory layout for 3-level paging */\n        MemoryLayout.NonCanonicalStart = (PVOID)0x00000000;\n        MemoryLayout.NonCanonicalEnd = (PVOID)0x00000000;\n        MemoryLayout.ReservedSystemPoolStart = (PVOID)0x00000000;\n        MemoryLayout.ReservedSystemPoolEnd = (PVOID)0x00000000;\n        MemoryLayout.UserSpaceStart = (PVOID)0x00010000;\n        MemoryLayout.UserSpaceEnd = (PVOID)0x7FFEFFFF;\n        MemoryLayout.LoaderMappingsStart = (PVOID)0x80000000;\n        MemoryLayout.LoaderMappingsEnd = (PVOID)0x90000000;\n        MemoryLayout.NonPagedPoolStart = (PVOID)0x90000000;\n        MemoryLayout.NonPagedPoolEnd = (PVOID)0xB0000000;\n        MemoryLayout.SessionSpaceStart = (PVOID)0xB0000000;\n        MemoryLayout.SessionSpaceEnd = (PVOID)0xC0000000;\n        MemoryLayout.PteSpaceStart = (PVOID)0xC0000000;\n        MemoryLayout.PteSpaceEnd = (PVOID)0xC07FFFFF;\n        MemoryLayout.HyperSpaceStart = (PVOID)0xC0800000;\n        MemoryLayout.HyperSpaceEnd = (PVOID)0xC0BFFFFF;\n        MemoryLayout.SystemWorkingSetStart = (PVOID)0xC0C00000;\n        MemoryLayout.SystemWorkingSetEnd = (PVOID)0xC0FFFFFF;\n        MemoryLayout.SystemCacheStart = (PVOID)0xC1000000;\n        MemoryLayout.SystemCacheEnd = (PVOID)0xE0FFFFFF;\n        MemoryLayout.PagedPoolStart = (PVOID)0xE1000000;\n        MemoryLayout.PagedPoolEnd = (PVOID)0xECC00000;\n        MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xECC00000;\n        MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xF7BE0000;\n        MemoryLayout.NonPagedExpansionPoolStart = (PVOID)0xF7BE0000;\n        MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)0xFFBFF000;\n        MemoryLayout.SharedSystemPageStart = (PVOID)0xFFBFF000;\n        MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFC00000;\n        MemoryLayout.HardwarePoolStart = (PVOID)0xFFC00000;\n        MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFF;\n    }\n    else\n    {\n        /* Set PML2 base address */\n        MemoryLayout.SelfMapAddress = (PVOID)MM_PTE_BASE;\n\n        /* Define memory layout for 2-level paging */\n        MemoryLayout.NonCanonicalStart = (PVOID)0x00000000;\n        MemoryLayout.NonCanonicalEnd = (PVOID)0x00000000;\n        MemoryLayout.ReservedSystemPoolStart = (PVOID)0x00000000;\n        MemoryLayout.ReservedSystemPoolEnd = (PVOID)0x00000000;\n        MemoryLayout.UserSpaceStart = (PVOID)0x00010000;\n        MemoryLayout.UserSpaceEnd = (PVOID)0x7FFEFFFF;\n        MemoryLayout.LoaderMappingsStart = (PVOID)0x80000000;\n        MemoryLayout.LoaderMappingsEnd = (PVOID)0x90000000;\n        MemoryLayout.NonPagedPoolStart = (PVOID)0x90000000;\n        MemoryLayout.NonPagedPoolEnd = (PVOID)0xB0000000;\n        MemoryLayout.SessionSpaceStart = (PVOID)0xB0000000;\n        MemoryLayout.SessionSpaceEnd = (PVOID)0xC0000000;\n        MemoryLayout.PteSpaceStart = (PVOID)0xC0000000;\n        MemoryLayout.PteSpaceEnd = (PVOID)0xC03FFFFF;\n        MemoryLayout.HyperSpaceStart = (PVOID)0xC0400000;\n        MemoryLayout.HyperSpaceEnd = (PVOID)0xC07FFFFF;\n        MemoryLayout.SystemWorkingSetStart = (PVOID)0xC0C00000;\n        MemoryLayout.SystemWorkingSetEnd = (PVOID)0xC0FFFFFF;\n        MemoryLayout.SystemCacheStart = (PVOID)0xC1000000;\n        MemoryLayout.SystemCacheEnd = (PVOID)0xE0FFFFFF;\n        MemoryLayout.PagedPoolStart = (PVOID)0xE1000000;\n        MemoryLayout.PagedPoolEnd = (PVOID)0xECC00000;\n        MemoryLayout.NonPagedSystemPoolStart = (PVOID)0xECC00000;\n        MemoryLayout.NonPagedSystemPoolEnd = (PVOID)0xF7BE0000;\n        MemoryLayout.NonPagedExpansionPoolStart = (PVOID)0xF7BE0000;\n        MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)0xFFBFF000;\n        MemoryLayout.SharedSystemPageStart = (PVOID)0xFFBFF000;\n        MemoryLayout.SharedSystemPageEnd = (PVOID)0xFFC00000;\n        MemoryLayout.HardwarePoolStart = (PVOID)0xFFC00000;\n        MemoryLayout.HardwarePoolEnd = (PVOID)0xFFFFFFFF;\n    }\n\n    /* Compute allocation size for the PFN database */\n    MM::Pfn::ComputePfnDatabaseSize(&MemoryLayout.PfnDatabaseSize);\n\n    /* Compute boot image size */\n    ComputeBootImageSize(&MemoryLayout.LoaderMappingsSize);\n\n    /* Compute session space size */\n    ComputeSessionSpaceSize(&MemoryLayout.SessionSpaceSize);\n\n    /* Update loader mappings space end address */\n    MemoryLayout.LoaderMappingsEnd = (PVOID)((ULONG_PTR)MemoryLayout.LoaderMappingsStart +\n                                             MemoryLayout.LoaderMappingsSize * MM_PAGE_SIZE);\n\n    /* Update session space start address */\n    MemoryLayout.SessionSpaceStart = (PVOID)((ULONGLONG)MemoryLayout.SessionSpaceEnd -\n                                             MemoryLayout.SessionSpaceSize * MM_PAGE_SIZE);\n\n    /* Compute system PTE size */\n    ComputeSystemPteSize(&NumberOfSystemPtes);\n\n    /* Compute the initial and maximum non-paged pool sizes */\n    ComputeNonPagedPoolSize(&MemoryLayout.NonPagedPoolSize);\n    ComputeMaximumNonPagedPoolSize(&MaximumNonPagedPoolSize);\n\n    /* Compute paged pool size */\n    ComputePagedPoolSize(&MemoryLayout.PagedPoolSize);\n\n    /* Position the PFN database right after the loader mappings */\n    MemoryLayout.PfnDatabase = (PMMPFN)MemoryLayout.LoaderMappingsEnd;\n\n    /* Compute the PFN database end address */\n    PfnDatabaseEnd = (ULONG_PTR)MemoryLayout.PfnDatabase + (MemoryLayout.PfnDatabaseSize * MM_PAGE_SIZE);\n\n    /* Position the initial non-paged pool immediately after the PFN database */\n    MemoryLayout.NonPagedPoolStart = (PVOID)PfnDatabaseEnd;\n\n    /* Check if the calculated non-paged pool size fits in the KVA */\n    if((MemoryLayout.NonPagedPoolSize * MM_PAGE_SIZE) >\n       ((ULONG_PTR)MemoryLayout.SessionSpaceStart - (ULONG_PTR)MemoryLayout.NonPagedPoolStart))\n    {\n        /* Set the final size for the non-paged pool */\n        MemoryLayout.NonPagedPoolSize = ((ULONG_PTR)MemoryLayout.NonPagedPoolEnd -\n                                        (ULONG_PTR)MemoryLayout.NonPagedPoolStart) / MM_PAGE_SIZE;\n    }\n\n    /* Set the final non-paged pool end address */\n    MemoryLayout.NonPagedPoolEnd = (PVOID)((ULONG_PTR)MemoryLayout.NonPagedPoolStart +\n                                           MemoryLayout.NonPagedPoolSize * MM_PAGE_SIZE);\n\n    /* Check if non-paged expansion pool overflows */\n    if((ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart + MaximumNonPagedPoolSize *\n        MM_PAGE_SIZE >= (ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart)\n    {\n        /* Check if non-paged expansion pool fits */\n        if((ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart + MaximumNonPagedPoolSize *\n            MM_PAGE_SIZE <= (ULONG_PTR)MemoryLayout.NonPagedExpansionPoolEnd)\n        {\n            /* Set new non-paged expansion pool end address */\n            MemoryLayout.NonPagedExpansionPoolEnd = (PVOID)((ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart +\n                                                            MaximumNonPagedPoolSize * MM_PAGE_SIZE);\n        }\n    }\n\n    /* Compute non-paged expansion pool size */\n    MemoryLayout.NonPagedExpansionPoolSize = ((ULONG_PTR)MemoryLayout.NonPagedExpansionPoolEnd -\n                                                (ULONG_PTR)MemoryLayout.NonPagedExpansionPoolStart) / MM_PAGE_SIZE;\n}\n"
  },
  {
    "path": "xtoskrnl/mm/i686/pagemap.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/i686/pagemap.cc\n * DESCRIPTION:     Low-level support for i686 page map manipulation\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Checks if the given address is canonical.\n *\n * @param VirtualAddress\n *        Specifies the virtual address to check.\n *\n * @return This routine returns TRUE, as all addresses in i686 are canonical.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMap::CanonicalAddress(IN PVOID VirtualAddress)\n{\n    /* All addresses in i686 are canonical */\n    return TRUE;\n}\n\n/**\n * Gets Page Map Level (PML) for current paging mode.\n *\n * @return This routine returns the page map level.\n *\n * @since XT 1.0\n */\nXTAPI\nUSHORT\nMM::PageMap::GetPageMapLevel()\n{\n    return PageMapInfo.Xpa ? 3 : 2;\n}\n\n/**\n * Gets the address of the PDE (Page Directory Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PDE.\n *\n * @return This routine returns the address of the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPDE\nMM::PageMap::GetPdeAddress(IN PVOID Address)\n{\n    ULONG Offset;\n\n    /* Calculate offset and return PDE address */\n    Offset = ((((ULONG_PTR)(Address)) >> PageMapInfo.PdiShift) << PageMapInfo.PteShift);\n    return (PMMPDE)(PageMapInfo.PdeBase + Offset);\n}\n\n/**\n * Gets the Offset of the PDE (Page Directory Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PDE.\n *\n * @return This routine returns the Offset of the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPdeOffset(IN PVOID Address)\n{\n    /* Return PDE Offset */\n    return ((((ULONG_PTR)(Address)) >> PageMapInfo.PdiShift) & (PageMapInfo.Xpa ? 0x1FF : 0x3FF));\n}\n\n/**\n * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PDE.\n *\n * @return This routine returns the address of the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPPE\nMM::PageMap::GetPpeAddress(IN PVOID Address)\n{\n    /* Return zero */\n    return (PMMPPE)0;\n}\n\n/**\n * Gets the offset of the PPE (Page Directory Pointer Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PPE.\n *\n * @return This routine returns the offset of the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPpeOffset(IN PVOID Address)\n{\n    /* Return zero */\n    return 0;\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry.\n *\n * @param PpePointer\n *        Specifies the virtual address of the PPE.\n *\n * @return This routine returns the virtual address mapped by the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMap::GetPpeVirtualAddress(IN PMMPPE PpePointer)\n{\n    /* Return zero */\n    return (PVOID)0;\n}\n\n/**\n * Gets the address of the PTE (Page Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PTE.\n *\n * @return This routine returns the address of the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::PageMap::GetPteAddress(IN PVOID Address)\n{\n    ULONG Offset;\n\n    /* Calculate offset and return PTE address */\n    Offset = ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) << PageMapInfo.PteShift);\n    return (PMMPTE)(PageMapInfo.PteBase + Offset);\n}\n\n/**\n * Gets the Offset of the PTE (Page Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PTE.\n *\n * @return This routine returns the Offset of the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMap::GetPteOffset(IN PVOID Address)\n{\n    /* Return PTE Offset */\n    return ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) & (PageMapInfo.Xpa ? 0x1FF : 0x3FF));\n}\n\n/**\n * Gets the status of Extended Paging Address (XPA) mode.\n *\n * @return This routine returns TRUE if XPA is enabled, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMap::GetXpaStatus()\n{\n    return PageMapInfo.Xpa;\n}\n\n/**\n * Advances a PTE pointer by a given number of entries, considering the actual PTE size for PML2.\n *\n * @param Pte\n *        The PTE pointer to advance.\n *\n * @param Count\n *        The number of PTE entries to advance by.\n *\n * @return This routine returns the advanced PTE pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::PageMapBasic::AdvancePte(IN PMMPTE Pte,\n                             IN ULONG Count)\n{\n    /* Return advanced PTE pointer */\n    return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPML2_PTE)));\n}\n\n/**\n * Clears the contents of a page table entry (PTE).\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to be cleared.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::ClearPte(IN PMMPTE PtePointer)\n{\n    /* Clear PTE */\n    PtePointer->Pml2.Long = 0;\n}\n\n/**\n * Gets the next entry in a PTE list.\n *\n * @param Pte\n *        The PTE pointer to get the next entry from.\n *\n * @return This routine returns the next entry in the PTE list.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nMM::PageMapBasic::GetNextEntry(IN PMMPTE Pte)\n{\n    /* Return next entry in PTE list, translating the hardware limit (0xFFFFF) to the logical sentinel (MAXULONG) */\n    return (Pte->Pml2.List.NextEntry == 0xFFFFF) ? MAXULONG : Pte->Pml2.List.NextEntry;\n}\n\n/**\n * Advances a PTE pointer, considering the actual PTE size for PML2.\n *\n * @param Pte\n *        The PTE pointer to advance.\n *\n * @return The advanced PTE pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::PageMapBasic::GetNextPte(IN PMMPTE Pte)\n{\n    /* Return advanced PTE pointer */\n    return AdvancePte(Pte, 1);\n}\n\n/**\n * Checks if a PTE list contains only one entry.\n *\n * @param Pte\n *        The PTE pointer to check.\n *\n * @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMapBasic::GetOneEntry(IN PMMPTE Pte)\n{\n    /* Return one entry status */\n    return Pte->Pml2.List.OneEntry;\n}\n\n/**\n * Gets the page frame number from a corresponding PTE.\n *\n * @param Pte\n *        The PTE pointer to get the page frame number from.\n *\n * @return This routine returns the page frame number.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_NUMBER\nMM::PageMapBasic::GetPageFrameNumber(IN PMMPTE Pte)\n{\n    return Pte->Pml2.Hardware.PageFrameNumber;\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Entry.\n *\n * @param PdePointer\n *        Specifies the address of the PDE.\n *\n * @return This routine returns the virtual address mapped by the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapBasic::GetPdeVirtualAddress(IN PMMPDE PdePointer)\n{\n    /* Return PDE virtual address */\n    return ((PVOID)((ULONG)(PdePointer) << 20));\n}\n\n/**\n * Gets the entire contents of a PML2 Page Table Entry (PTE) as a single value.\n *\n * @param PtePointer\n *        Pointer to the Page Table Entry (PTE) to read.\n *\n * @return This routine returns the contents of the PTE as a single value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nMM::PageMapBasic::GetPte(IN PMMPTE PtePointer)\n{\n    /* Return PTE value */\n    return (ULONGLONG)PtePointer->Pml2.Long;\n}\n\n/**\n * Calculates the distance between two PTE pointers.\n *\n * @param EndPte\n *        Pointer to the ending Page Table Entry.\n *\n * @param StartPte\n *        Pointer to the starting Page Table Entry.\n *\n * @return This routine returns a signed value representing the number of PTEs between EndPte and StartPte.\n *\n * @since XT 1.0\n */\nXTAPI\nLONG\nMM::PageMapBasic::GetPteDistance(PMMPTE EndPte,\n                                 PMMPTE StartPte)\n{\n    /* Return distance between PTE pointers */\n    return ((ULONG_PTR)EndPte - (ULONG_PTR)StartPte) / sizeof(MMPML2_PTE);\n}\n\n/**\n * Gets the size of a PTE for basic paging (PML2).\n *\n * @return This routine returns the size of a PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMapBasic::GetPteSize(VOID)\n{\n    /* Return the size of MMPTE */\n    return sizeof(MMPML2_PTE);\n}\n\n/**\n * Gets the software protection value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software protection value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMapBasic::GetPteSoftwareProtection(IN PMMPTE PtePointer)\n{\n    /* Return PTE software protection value */\n    return (ULONG)PtePointer->Pml2.Software.Protection;\n}\n\n/**\n * Gets the software prototype value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software prototype value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMapBasic::GetPteSoftwarePrototype(IN PMMPTE PtePointer)\n{\n    /* Return PTE software prototype value */\n    return (ULONG)PtePointer->Pml2.Software.Prototype;\n}\n\n/**\n * Gets the software transition value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software transition value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMapBasic::GetPteSoftwareTransition(IN PMMPTE PtePointer)\n{\n    /* Return PTE software transition value */\n    return (ULONG)PtePointer->Pml2.Software.Transition;\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the virtual address of the PTE.\n *\n * @return This routine returns the virtual address mapped by the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapBasic::GetPteVirtualAddress(IN PMMPTE PtePointer)\n{\n    /* Return PTE virtual address */\n    return ((PVOID)((ULONG)(PtePointer) << 10));\n}\n\n/**\n * Initializes page map information for basic paging (PML2).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::InitializePageMapInfo(VOID)\n{\n    /* Set PML2 page map information */\n    PageMapInfo.Xpa = FALSE;\n\n    /* Set PML2 base addresses */\n    PageMapInfo.PteBase = MM_PTE_BASE;\n    PageMapInfo.PdeBase = MM_PDE_LEGACY_BASE;\n\n    /* Set PML2 shift values */\n    PageMapInfo.PdiShift = MM_PDI_LEGACY_SHIFT;\n    PageMapInfo.PteShift = MM_PTE_LEGACY_SHIFT;\n}\n\n/**\n * Checks whether the given PML2 page table entry (PTE) is valid.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to check.\n *\n * @return Returns TRUE if the entry is valid, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMapBasic::PteValid(IN PMMPTE PtePointer)\n{\n    /* Check if PTE is valid */\n    return (BOOLEAN)PtePointer->Pml2.Hardware.Valid;\n}\n\n/**\n * Sets the next entry in a PTE list.\n *\n * @param Pte\n *        The PTE pointer to modify.\n *\n * @param Value\n *        The value to set as the next entry.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::SetNextEntry(IN PMMPTE Pte,\n                               IN ULONG_PTR Value)\n{\n    /* Set next entry in PTE list, translating the logical sentinel (MAXULONG) to the 20-bit hardware limit (0xFFFFF) */\n    Pte->Pml2.List.NextEntry = (Value == MAXULONG) ? 0xFFFFF : Value;\n}\n\n/**\n * Sets the flag indicating whether a PTE list contains only one entry.\n *\n * @param Pte\n *        The PTE pointer to modify.\n *\n * @param Value\n *        The value to set. TRUE if the list has only one entry, FALSE otherwise.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::SetOneEntry(IN PMMPTE Pte,\n                              IN BOOLEAN Value)\n{\n    /* Set one entry status */\n    Pte->Pml2.List.OneEntry = Value;\n}\n\n/**\n * Sets a PML2 page table entry (PTE) with the specified physical page and access flags.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to set.\n *\n * @param PageFrameNumber\n *        Physical frame number to map.\n *\n * @param AttributesMask\n *        Specifies the attributes mask to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::SetPte(IN PMMPTE PtePointer,\n                         IN PFN_NUMBER PageFrameNumber,\n                         IN ULONGLONG AttributesMask)\n{\n    /* Set PTE */\n    PtePointer->Pml2.Hardware.PageFrameNumber = PageFrameNumber;\n    PtePointer->Pml2.Hardware.Valid = 1;\n    PtePointer->Pml2.Long |= (ULONG)AttributesMask;\n}\n\n/**\n * Sets a PML2 page table entry (PTE) with the specified attributes.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to set.\n *\n * @param Attributes\n *        Specifies the attributes to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::SetPte(IN PMMPTE PtePointer,\n                         IN ULONGLONG Attributes)\n{\n    PtePointer->Pml2.Long = (ULONG)Attributes;\n}\n\n/**\n * Sets caching attributes for a PML2 page table entry (PTE).\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to modify.\n *\n * @param CacheDisable\n *        Indicates whether caching should be disabled for this page.\n *\n * @param WriteThrough\n *        Indicates whether write-through caching should be enabled.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::SetPteCaching(IN PMMPTE PtePointer,\n                                IN BOOLEAN CacheDisable,\n                                IN BOOLEAN WriteThrough)\n{\n    /* Set caching attributes */\n    PtePointer->Pml2.Hardware.CacheDisable = CacheDisable;\n    PtePointer->Pml2.Hardware.WriteThrough = WriteThrough;\n}\n\n/**\n * Transitions a Page Table Entry (PTE) to invalid state\n *\n * @param PointerPte\n *        Pointer to the page table entry (PTE) to transition.\n *\n * @param Protection\n *        Specifies the protection attribute to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::TransitionPte(IN PMMPTE PointerPte,\n                                IN ULONG_PTR Protection)\n{\n    MMPTE TempPte;\n\n    /* Set transition PTE */\n    TempPte.Pml2.Long = PointerPte->Pml2.Long;\n    TempPte.Pml2.Software.Protection = Protection;\n    TempPte.Pml2.Software.Prototype = 0;\n    TempPte.Pml2.Software.Transition = 1;\n    TempPte.Pml2.Software.Valid = 0;\n\n    /* Write PTE value */\n    PointerPte->Pml2.Long = TempPte.Pml2.Long;\n}\n\n/**\n * Writes a PML2 page table entry (PTE) with the specified value.\n *\n * @param Pte\n *        Pointer to the page table entry (PTE) to write.\n *\n * @param Value\n *        The value to write to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapBasic::WritePte(IN PMMPTE Pte,\n                           IN MMPTE Value)\n{\n    /* Write PTE value */\n    Pte->Pml2.Long = Value.Pml2.Long;\n}\n\n/**\n * Advances a PTE pointer by a given number of entries, considering the actual PTE size for PML3.\n *\n * @param Pte\n *        The PTE pointer to advance.\n *\n * @param Count\n *        The number of PTE entries to advance by.\n *\n * @return The advanced PTE pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::PageMapXpa::AdvancePte(IN PMMPTE Pte,\n                           IN ULONG Count)\n{\n    /* Return advanced PTE pointer */\n    return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPML3_PTE)));\n}\n\n/**\n * Clears the contents of a page table entry (PTE).\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to be cleared.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::ClearPte(IN PMMPTE PtePointer)\n{\n    /* Clear PTE */\n    PtePointer->Pml3.Long = 0;\n}\n\n/**\n * Gets the next entry in a PTE list.\n *\n * @param Pte\n *        The PTE pointer to get the next entry from.\n *\n * @return This routine returns the next entry in the PTE list.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nMM::PageMapXpa::GetNextEntry(IN PMMPTE Pte)\n{\n    /* Return next entry in PTE list */\n    return Pte->Pml3.List.NextEntry;\n}\n\n/**\n * Advances a PTE pointer, considering the actual PTE size for PML3.\n *\n * @param Pte\n *        The PTE pointer to advance.\n *\n * @return The advanced PTE pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::PageMapXpa::GetNextPte(IN PMMPTE Pte)\n{\n    /* Return advanced PTE pointer */\n    return AdvancePte(Pte, 1);\n}\n\n/**\n * Checks if a PTE list contains only one entry.\n *\n * @param Pte\n *        The PTE pointer to check.\n *\n * @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMapXpa::GetOneEntry(IN PMMPTE Pte)\n{\n    /* Return one entry status */\n    return Pte->Pml3.List.OneEntry;\n}\n\n/**\n * Gets the page frame number from a corresponding PTE.\n *\n * @param Pte\n *        The PTE pointer to get the page frame number from.\n *\n * @return This routine returns the page frame number.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_NUMBER\nMM::PageMapXpa::GetPageFrameNumber(IN PMMPTE Pte)\n{\n    return Pte->Pml3.Hardware.PageFrameNumber;\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Entry.\n *\n * @param PdePointer\n *        Specifies the address of the PDE.\n *\n * @return This routine returns the virtual address mapped by the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapXpa::GetPdeVirtualAddress(IN PMMPDE PdePointer)\n{\n    /* Return PDE virtual address */\n    return ((PVOID)((ULONG)(PdePointer) << 18));\n}\n\n /**\n * Gets the entire contents of a PML3 Page Table Entry (PTE) as a single value.\n *\n * @param PtePointer\n *        Pointer to the Page Table Entry (PTE) to read.\n *\n * @return This routine returns the contents of the PTE as a single value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nMM::PageMapXpa::GetPte(IN PMMPTE PtePointer)\n{\n    /* Return PTE value */\n    return PtePointer->Pml3.Long;\n}\n\n/**\n * Calculates the distance between two PTE pointers.\n *\n * @param EndPte\n *        Pointer to the ending Page Table Entry.\n *\n * @param StartPte\n *        Pointer to the starting Page Table Entry.\n *\n * @return This routine returns a signed value representing the number of PTEs between EndPte and StartPte.\n *\n * @since XT 1.0\n */\nXTAPI\nLONG\nMM::PageMapXpa::GetPteDistance(PMMPTE EndPte,\n                               PMMPTE StartPte)\n{\n    /* Return distance between PTE pointers */\n    return ((ULONG_PTR)EndPte - (ULONG_PTR)StartPte) / sizeof(MMPML3_PTE);\n}\n\n/**\n * Gets the size of a PTE for XPA paging (PML3).\n *\n * @return This routine returns the size of a PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMapXpa::GetPteSize(VOID)\n{\n    /* Return the size of MMPTE */\n    return sizeof(MMPML3_PTE);\n}\n\n/**\n * Gets the software protection value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software protection value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMapXpa::GetPteSoftwareProtection(IN PMMPTE PtePointer)\n{\n    /* Return PTE software protection value */\n    return (ULONG)PtePointer->Pml3.Software.Protection;\n}\n\n/**\n * Gets the software prototype value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software prototype value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMapXpa::GetPteSoftwarePrototype(IN PMMPTE PtePointer)\n{\n    /* Return PTE software prototype value */\n    return (ULONG)PtePointer->Pml3.Software.Prototype;\n}\n\n/**\n * Gets the software transition value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software transition value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::PageMapXpa::GetPteSoftwareTransition(IN PMMPTE PtePointer)\n{\n    /* Return PTE software transition value */\n    return (ULONG)PtePointer->Pml3.Software.Transition;\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the virtual address of the PTE.\n *\n * @return This routine returns the virtual address mapped by the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::PageMapXpa::GetPteVirtualAddress(IN PMMPTE PtePointer)\n{\n    /* Return PTE virtual address */\n    return ((PVOID)((ULONG)(PtePointer) << 9));\n}\n\n/**\n * Initializes page map information for basic paging (PML3).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::InitializePageMapInfo(VOID)\n{\n    /* Set PML3 page map information */\n    PageMapInfo.Xpa = TRUE;\n\n    /* Set PML3 base addresses */\n    PageMapInfo.PteBase = MM_PTE_BASE;\n    PageMapInfo.PdeBase = MM_PDE_BASE;\n\n    /* Set PML3 shift values */\n    PageMapInfo.PdiShift = MM_PDI_SHIFT;\n    PageMapInfo.PteShift = MM_PTE_SHIFT;\n}\n\n/**\n * Checks whether the given PML3 page table entry (PTE) is valid.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to check.\n *\n * @return Returns TRUE if the entry is valid, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::PageMapXpa::PteValid(IN PMMPTE PtePointer)\n{\n    return (BOOLEAN)PtePointer->Pml3.Hardware.Valid;\n}\n\n/**\n * Sets the next entry in a PTE list.\n *\n * @param Pte\n *        The PTE pointer to modify.\n *\n * @param Value\n *        The value to set as the next entry.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::SetNextEntry(IN PMMPTE Pte,\n                             IN ULONG_PTR Value)\n{\n    /* Set next entry in PTE list */\n    Pte->Pml3.List.NextEntry = Value;\n}\n\n/**\n * Sets the flag indicating whether a PTE list contains only one entry.\n *\n * @param Pte\n *        The PTE pointer to modify.\n *\n * @param Value\n *        The value to set. TRUE if the list has only one entry, FALSE otherwise.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::SetOneEntry(IN PMMPTE Pte,\n                            IN BOOLEAN Value)\n{\n    /* Set one entry status */\n    Pte->Pml3.List.OneEntry = Value;\n}\n\n/**\n * Sets a PML3 page table entry (PTE) with the specified physical page and access flags.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to set.\n *\n * @param PageFrameNumber\n *        Physical frame number to map.\n *\n * @param AttributesMask\n *        Specifies the attributes mask to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::SetPte(IN PMMPTE PtePointer,\n                       IN PFN_NUMBER PageFrameNumber,\n                       IN ULONGLONG AttributesMask)\n{\n    /* Set PTE */\n    PtePointer->Pml3.Hardware.PageFrameNumber = PageFrameNumber;\n    PtePointer->Pml3.Hardware.Valid = 1;\n    PtePointer->Pml3.Long |= AttributesMask;\n}\n\n/**\n * Sets a PML3 page table entry (PTE) with the specified attributes.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to set.\n *\n * @param Attributes\n *        Specifies the attributes to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::SetPte(IN PMMPTE PtePointer,\n                       IN ULONGLONG Attributes)\n{\n    PtePointer->Pml3.Long = Attributes;\n}\n\n/**\n * Sets caching attributes for a PML3 page table entry (PTE).\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to modify.\n *\n * @param CacheDisable\n *        Indicates whether caching should be disabled for this page.\n *\n * @param WriteThrough\n *        Indicates whether write-through caching should be enabled.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::SetPteCaching(IN PMMPTE PtePointer,\n                              IN BOOLEAN CacheDisable,\n                              IN BOOLEAN WriteThrough)\n{\n    /* Set caching attributes */\n    PtePointer->Pml3.Hardware.CacheDisable = CacheDisable;\n    PtePointer->Pml3.Hardware.WriteThrough = WriteThrough;\n}\n\n/**\n * Transitions a Page Table Entry (PTE) to invalid state\n *\n * @param PointerPte\n *        Pointer to the page table entry (PTE) to transition.\n *\n * @param Protection\n *        Specifies the protection attribute to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::TransitionPte(IN PMMPTE PointerPte,\n                              IN ULONG_PTR Protection)\n{\n    MMPTE TempPte;\n\n    /* Set transition PTE */\n    TempPte.Pml3.Long = PointerPte->Pml3.Long;\n    TempPte.Pml3.Software.Protection = Protection;\n    TempPte.Pml3.Software.Prototype = 0;\n    TempPte.Pml3.Software.Transition = 1;\n    TempPte.Pml3.Software.Valid = 0;\n\n    /* Write PTE value */\n    PointerPte->Pml3.Long = TempPte.Pml3.Long;\n}\n\n/**\n * Writes a PML3 page table entry (PTE) with the specified value.\n *\n * @param Pte\n *        Pointer to the page table entry (PTE) to write.\n *\n * @param Value\n *        The value to write to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::PageMapXpa::WritePte(IN PMMPTE Pte,\n                         IN MMPTE Value)\n{\n    /* Write PTE value */\n    Pte->Pml3.Long = Value.Pml3.Long;\n}\n"
  },
  {
    "path": "xtoskrnl/mm/i686/paging.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/i686/paging.cc\n * DESCRIPTION:     Architecture dependent paging support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Checks if eXtended Physical Addressing (XPA) is enabled.\n *\n * @return This routine returns TRUE if PAE is enabled, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Paging::GetExtendedPhysicalAddressingStatus(VOID)\n{\n    /* Check if PAE is enabled */\n    return ((AR::CpuFunctions::ReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE;\n}\n\n/**\n * Maps a specific virtual address to a specific physical page frame (i686 specific).\n *\n * @param VirtualAddress\n *        The virtual address to map.\n *\n * @param PageFrameNumber\n *        The physical frame number to back the virtual address.\n *\n * @param Attributes\n *        Specifies the attributes (protections, caching) to apply to the PTE.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Paging::MapVirtualAddress(IN PVOID VirtualAddress,\n                              IN PFN_NUMBER PageFrameNumber,\n                              IN ULONGLONG Attributes)\n{\n    MMPTE TemplatePte;\n    PMMPTE PointerPte;\n\n    /* Initialize the template PTE */\n    MM::Paging::ClearPte(&TemplatePte);\n    MM::Paging::SetPte(&TemplatePte, 0, Attributes | MM_PTE_CACHE_ENABLE);\n\n    /* Check if XPA is enabled */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* Map Page Directory Pointer Table */\n        MM::Pte::MapPPE(VirtualAddress, VirtualAddress, (PMMPPE)&TemplatePte);\n    }\n\n    /* Map Page Directory Entry */\n    MM::Pte::MapPDE(VirtualAddress, VirtualAddress, (PMMPDE)&TemplatePte);\n\n    /* Get PTE address */\n    PointerPte = MM::Paging::GetPteAddress(VirtualAddress);\n\n    /* Initialize the template PTE */\n    MM::Paging::ClearPte(&TemplatePte);\n    MM::Paging::SetPte(&TemplatePte, PageFrameNumber, Attributes);\n\n    /* Write the PTE */\n    MM::Paging::WritePte(PointerPte, TemplatePte);\n\n    /* Flush the TLB to reflect the changes */\n    MM::Paging::FlushTlb();\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Fills a section of memory with zeroes like RtlZeroMemory(), but in more efficient way.\n *\n * @param Address\n *        Supplies an address of the page to be filled with zeroes.\n *\n * @param Size\n *        Number of bytes to be filled with zeros. This always should be a multiply of page size.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nMM::Paging::ZeroPages(IN PVOID Address,\n                      IN ULONG Size)\n{\n    __asm__ volatile(\"xor %%eax, %%eax\\n\"\n                     \"rep stosb\"\n                     : \"=D\"(Address),\n                       \"=c\"(Size)\n                     : \"0\"(Address),\n                       \"1\"(Size),\n                       \"a\"(0)\n                     : \"memory\");\n}\n"
  },
  {
    "path": "xtoskrnl/mm/i686/pfault.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/i686/pfault.cc\n * DESCRIPTION:     Page fault support for i686 architecture\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Evaluates the PDE for for paged pool and per-session mappings.\n *\n * @param VirtualAddress\n *        Specifies the virtual address to verify.\n *\n * @return This routine returns ACCESS_VIOLATION on PML3 or status code on PML2.\n */\nXTFASTCALL\nXTSTATUS\nMM::PageFault::CheckPdeForPagedPool(IN PVOID VirtualAddress)\n{\n    /* Check if XPA is enabled */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* Access violation for PML3 */\n        return STATUS_ACCESS_VIOLATION;\n    }\n\n    /* Unimplemented path for PML2 */\n    UNIMPLEMENTED;\n\n    /* Temporarily, just return access violation */\n    return STATUS_ACCESS_VIOLATION;\n}\n"
  },
  {
    "path": "xtoskrnl/mm/i686/pfn.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/i686/pfn.cc\n * DESCRIPTION:     Physical Frame Number for i686 support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n *                  Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Allocates and initializes page directory structures for a range of PDEs.\n *\n * @param StartingPde\n *        Supplies a pointer to the first PDE in the range to initialize.\n *\n * @param EndingPde\n *        Supplies a pointer to the last PDE in the range to initialize.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::InitializePageDirectory(IN PMMPDE StartingPde,\n                                 IN PMMPDE EndingPde)\n{\n    /* Nothing to do */\n}\n\n/**\n * Initializes the PFN database by mapping virtual memory and populating entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::InitializePfnDatabase(VOID)\n{\n    PLOADER_MEMORY_DESCRIPTOR Descriptor;\n    PKERNEL_INITIALIZATION_BLOCK InitializationBlock;\n    PLIST_ENTRY ListEntry;\n    PMMMEMORY_LAYOUT MemoryLayout;\n    PUCHAR PfnDatabaseEnd;\n    PMMPTE ValidPte;\n\n    /* Raise runlevel and acquire PFN lock */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);\n\n    /* Get the kernel initialization block */\n    InitializationBlock = KE::BootInformation::GetInitializationBlock();\n\n    /* Get memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Get the PFN database size and calculate the end of the PFN database virtual address space */\n    PfnDatabaseEnd = (PUCHAR)MemoryLayout->PfnDatabase + (MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE) - 1;\n\n    /* Get a template PTE for mapping the PFN database pages */\n    ValidPte = MM::Pte::GetValidPte();\n\n    /* Map the Page Directory and Page Directory Pointer tables for the PFN database */\n    MM::Pte::MapPDE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);\n    MM::Pte::MapPTE(MemoryLayout->PfnDatabase, PfnDatabaseEnd, ValidPte);\n\n    /* Zero PFN database virtual space */\n    RTL::Memory::ZeroMemory(MemoryLayout->PfnDatabase, MemoryLayout->PfnDatabaseSize * MM_PAGE_SIZE);\n\n    /* Initialize the color tables */\n    MM::Colors::InitializeColorTables();\n\n    /* Iterate over memory descriptors to map the PFN database and initialize entries */\n    ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;\n    while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)\n    {\n        /* Get the descriptor */\n        Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);\n\n        /* Skip invisible memory regions */\n        if(MM::Manager::VerifyMemoryTypeInvisible(Descriptor->MemoryType))\n        {\n            /* Move to the next descriptor and continue */\n            ListEntry = ListEntry->Flink;\n            continue;\n        }\n\n        /* Check if this is the modified free descriptor */\n        if(Descriptor == FreeDescriptor)\n        {\n            /* Switch to the original descriptor */\n            Descriptor = &OriginalFreeDescriptor;\n        }\n\n        /* Check if the free memory block that was split is being processed */\n        if(Descriptor == &OriginalFreeDescriptor)\n        {\n            /* Skip loop processing, free memory is initialized separately */\n            ListEntry = ListEntry->Flink;\n            continue;\n        }\n\n        /* Initialize PFNs for this memory range */\n        ProcessMemoryDescriptor(Descriptor->BasePage, Descriptor->PageCount, Descriptor->MemoryType);\n\n        /* Move to the next descriptor */\n        ListEntry = ListEntry->Flink;\n    }\n\n    /* Initialize PFNs for the free memory */\n    ProcessMemoryDescriptor(FreeDescriptor->BasePage, FreeDescriptor->PageCount, LoaderFree);\n\n    /* Initialize PFNs for the physical pages backing the PFN database */\n    ProcessMemoryDescriptor(OriginalFreeDescriptor.BasePage,\n                            FreeDescriptor->BasePage - OriginalFreeDescriptor.BasePage,\n                            LoaderMemoryData);\n\n    /* Restore original free descriptor */\n    *FreeDescriptor = OriginalFreeDescriptor;\n\n    /* Initialize PFNs backing page tables */\n    InitializePageTablePfns();\n}\n\n/**\n * Initializes PFN database entries for the system page tables.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::InitializePageTablePfns(VOID)\n{\n    PFN_NUMBER PageFrameIndex;\n    PMMPFN Pfn;\n    ULONG RootLevel;\n    PMMPTE RootPte;\n\n    /* Determine root structure based on paging mode */\n    if(MM::Paging::GetXpaStatus())\n    {\n        /* XPA enabled, 3-level paging (PAE) */\n        RootLevel = 3;\n\n        /* Retrieve the PFN of the PML3 table and its virtual base address */\n        PageFrameIndex = AR::CpuFunctions::ReadControlRegister(3) >> MM_PAGE_SHIFT;\n        RootPte = (PMMPTE)MM::Paging::GetPpeAddress(NULLPTR);\n    }\n    else\n    {\n        /* XPA disabled, 2-level paging */\n        RootLevel = 2;\n\n        /* Retrieve the PFN of the PML2 table and its virtual base address */\n        PageFrameIndex = AR::CpuFunctions::ReadControlRegister(3) >> MM_PAGE_SHIFT;\n        RootPte = (PMMPTE)MM::Paging::GetPdeAddress(NULLPTR);\n    }\n\n    /* Initialize the PFN entry for the root page table itself */\n    Pfn = GetPfnEntry(PageFrameIndex);\n    if(Pfn)\n    {\n        /* Initialize the PFN entry */\n        Pfn->PteAddress = NULLPTR;\n        Pfn->u1.WsIndex = 0;\n        Pfn->u2.ShareCount = 1;\n        Pfn->u3.e1.CacheAttribute = PfnNonCached;\n        Pfn->u3.e1.PageLocation = ActiveAndValid;\n        Pfn->u3.e2.ReferenceCount = 1;\n        Pfn->u4.PteFrame = 0;\n    }\n\n    /* Start recursive scan from the top level */\n    if(RootPte)\n    {\n        /* Scan the root page table */\n        ScanPageTable(RootPte, RootLevel);\n    }\n}\n\n/**\n * Recursively scans a page table to initialize PFN database entries for active pages.\n *\n * @param PointerPte\n *        Pointer to the base of the page table to scan.\n *\n * @param Level\n *        The paging level of the table being scanned.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::ScanPageTable(IN PMMPTE PointerPte,\n                       IN ULONG Level)\n{\n    PVOID Address;\n    ULONG Index;\n    PMMPTE NextLevelPte;\n    ULONG PtesPerPage;\n\n    /* Get the number of PTEs per page */\n    PtesPerPage = MM::Pte::GetPtesPerPage();\n\n    /* Check if PML3 is enabled and current level is PDPT */\n    if(Level == 3)\n    {\n        /* PAE PDPT has only 4 entries */\n        PtesPerPage = 4;\n    }\n\n    /* Iterate through all entries in the current page table */\n    for(Index = 0; Index < PtesPerPage; Index++)\n    {\n        /* Check if the page table entry is present */\n        if(MM::Paging::PteValid(PointerPte))\n        {\n            /* Mark the PFN pointed to by this entry as active */\n            LinkPfnForPageTable(MM::Paging::GetPageFrameNumber(PointerPte), PointerPte);\n\n            /* Recurse to the next level, if this is not a leaf node (PTE) */\n            if(Level > 1)\n            {\n                /* Calculate the virtual address mapped by this entry to find the next table */\n                switch(Level)\n                {\n                    case 3:\n                        /* Calculate PDE */\n                        Address = MM::Paging::GetPpeVirtualAddress(PointerPte);\n                        NextLevelPte = (PMMPTE)MM::Paging::GetPdeAddress(Address);\n                        break;\n                    case 2:\n                        /* Calculate PTE */\n                        Address = MM::Paging::GetPdeVirtualAddress(PointerPte);\n                        NextLevelPte = (PMMPTE)MM::Paging::GetPteAddress(Address);\n                        break;\n                    default:\n                        /* Nothing to calculate, return NULLPTR */\n                        NextLevelPte = NULLPTR;\n                        break;\n                }\n\n                /* Recurse deeper if not at the bottom level (PTE) already */\n                if(NextLevelPte)\n                {\n                    /* Recursively scan the next level page table */\n                    ScanPageTable(NextLevelPte, Level - 1);\n                }\n            }\n        }\n\n        /* Move to the next entry in the current table */\n        PointerPte = MM::Paging::GetNextPte(PointerPte);\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/mm/i686/pool.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/i686/pool.cc\n * DESCRIPTION:     I686 Memory Manager pool manager\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Maps the PTE for the base of the non-paged pool.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::MapNonPagedPool(VOID)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Retrieve memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Map PDE and PTE for the base of the non-paged pool */\n    MM::Pte::MapPDE(MemoryLayout->NonPagedPoolStart, (PCHAR)MemoryLayout->NonPagedPoolEnd - 1, MM::Pte::GetValidPte());\n    MM::Pte::MapPTE(MemoryLayout->NonPagedPoolStart, (PCHAR)MemoryLayout->NonPagedPoolEnd - 1, MM::Pte::GetValidPte());\n}\n"
  },
  {
    "path": "xtoskrnl/mm/i686/pte.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/i686/pte.cc\n * DESCRIPTION:     Page Table Entry (PTE) for i686 support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Checks if the virtual address is valid and mapped in the page tables.\n *\n * @param VirtualAddress\n *        The virtual address to check.\n *\n * @return This routine returns TRUE if the address is valid, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Pte::AddressValid(IN PVOID VirtualAddress)\n{\n    /* Check if PDE and PTE are valid */\n    if(!MM::Paging::PteValid(MM::Paging::GetPdeAddress(VirtualAddress)) ||\n       !MM::Paging::PteValid(MM::Paging::GetPteAddress(VirtualAddress)))\n    {\n        /* Invalid PDE or PTE, return FALSE */\n        return FALSE;\n    }\n\n    /* Address is valid, return TRUE */\n    return TRUE;\n}\n\n/**\n * Retrieves the base virtual address of the system PTEs.\n *\n * @return This routine returns a pointer to the first PTE in the system PTE space.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::Pte::GetSystemPteBaseAddress(VOID)\n{\n    return MM::Paging::GetPteAddress(NULLPTR);\n}\n\n/**\n * Performs the initial setup of the system's page table hierarchy.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::InitializePageTable(VOID)\n{\n    PMMPTE EndSpacePte, PointerPte;\n    PMMMEMORY_LAYOUT MemoryLayout;\n    CPUID_REGISTERS CpuRegisters;\n    MMPTE TemplatePte;\n\n    /* Retrieve current paging mode and memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Get CPU features */\n    CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n\n    /* Check if Paging Global Extensions (PGE) is supported */\n    if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE)\n    {\n        /* Enable the Global Paging (PGE) feature */\n        AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_PGE);\n    }\n\n    /* Get the PD user-space range for both legacy and PAE paging */\n    PointerPte = (PMMPTE)MM::Paging::GetPdeAddress(0);\n    EndSpacePte = (PMMPTE)MM::Paging::GetPdeAddress(MemoryLayout->UserSpaceEnd);\n\n    /* Clear all top-level entries mapping the user address space */\n    while(PointerPte <= EndSpacePte)\n    {\n        MM::Paging::ClearPte(PointerPte);\n        PointerPte = MM::Paging::GetNextPte(PointerPte);\n    }\n\n    /* Flush the TLB to invalidate all non-global entries */\n    AR::CpuFunctions::FlushTlb();\n\n    /* Create a template PTE for mapping kernel pages */\n    MM::Paging::ClearPte(&TemplatePte);\n    MM::Paging::SetPte(&TemplatePte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);\n\n    /* Map the kernel's PD entries */\n    MM::Pte::MapPDE(MemoryLayout->NonPagedSystemPoolStart, (PVOID)MM_HIGHEST_SYSTEM_ADDRESS, &TemplatePte);\n}\n\n/**\n * Maps a range of virtual addresses at the PPE (Page Directory Pointer Entry) level.\n *\n * @param StartAddress\n *        The beginning of the virtual address range to map.\n *\n * @param EndAddress\n *        The end of the virtual address range to map.\n *\n * @param TemplatePpe\n *        A template PPE to use for creating new entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::MapPPE(IN PVOID StartAddress,\n                IN PVOID EndAddress,\n                IN PMMPPE TemplatePpe)\n{\n    /* Just a stub on i686 platform */\n    return;\n}\n"
  },
  {
    "path": "xtoskrnl/mm/kpool.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/kpool.cc\n * DESCRIPTION:     Kernel pool memory management\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Allocates a new kernel stack.\n *\n * @param Stack\n *        Supplies a pointer to the memory area that will contain a new kernel stack.\n *\n * @param StackSize\n *        Supplies the size of the stack to be allocated, in bytes.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::KernelPool::AllocateKernelStack(OUT PVOID *Stack,\n                                    IN ULONG StackSize)\n{\n    PFN_COUNT StackPages;\n    PMMPTE PointerPte, StackPte;\n    MMPTE TempPte, InvalidPte;\n    PFN_NUMBER PageFrameIndex;\n    ULONG Index;\n\n    /* Initialize the output stack pointer to NULLPTR */\n    *Stack = NULLPTR;\n\n    /* Convert the requested stack size into a page count */\n    StackPages = SIZE_TO_PAGES(StackSize);\n\n    /* Reserve PTEs for the stack pages, plus a guard page */\n    StackPte = MM::Pte::ReserveSystemPtes(StackPages + 1, SystemPteSpace);\n    if(!StackPte)\n    {\n        /* Failed to reserve PTEs for the new kernel stack */\n        return STATUS_INSUFFICIENT_RESOURCES;\n    }\n\n    /* Set up a template for an invalid PTE */\n    MM::Paging::SetPte(&InvalidPte, 0, MM_PTE_GUARDED);\n\n    /* Set up a template for a valid, writable stack PTE */\n    MM::Paging::ClearPte(&TempPte);\n    MM::Paging::SetPte(&TempPte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);\n\n    /* Acquire the PFN database lock and raise runlevel to DISPATCH_LEVEL */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);\n\n    /* Start iterating from the base of the reserved PTE block */\n    PointerPte = StackPte;\n\n    /* Loop through each page of the stack that needs to be allocated */\n    for(Index = 0; Index < StackPages; Index++)\n    {\n        /* Advance to the next PTE */\n        PointerPte = MM::Paging::GetNextPte(PointerPte);\n\n        /* Allocate a physical page and temporarily mark the PTE as invalid */\n        PageFrameIndex = MM::Pfn::AllocatePhysicalPage(MM::Colors::GetNextColor());\n        *PointerPte = InvalidPte;\n\n        /* Associate the physical page with its corresponding PTE in the PFN database */\n        MM::Pfn::LinkPfn(PageFrameIndex, PointerPte, TRUE);\n\n        /* Make the PTE valid, mapping the virtual address to the physical page */\n        MM::Paging::SetPte(&TempPte, PageFrameIndex, 0);\n        *PointerPte = TempPte;\n    }\n\n    /* Zero the newly allocated stack memory, skipping the guard page */\n    RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(MM::Paging::GetNextPte(StackPte)),\n                            MM_PAGE_SIZE * StackPages);\n\n    /* Return a pointer to the top of the new stack */\n    *Stack = MM::Paging::GetPteVirtualAddress(MM::Paging::AdvancePte(StackPte, StackPages + 1));\n    return STATUS_SUCCESS;\n}\n\n/**\n * Allocates a buffer for structures needed by a processor and assigns it to a corresponding CPU.\n *\n * @param StructuresData\n *        Supplies a pointer to the memory area that will contain the allocated buffer.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::KernelPool::AllocateProcessorStructures(OUT PVOID *StructuresData)\n{\n    PVOID ProcessorStructures;\n    XTSTATUS Status;\n\n    /* Assign memory for processor structures */\n    Status = MM::Allocator::AllocatePool(NonPagedPool, KPROCESSOR_STRUCTURES_SIZE, &ProcessorStructures);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to allocate memory, return status code */\n        return Status;\n    }\n\n    /* Make sure all structures are zeroed */\n    RTL::Memory::ZeroMemory(ProcessorStructures, KPROCESSOR_STRUCTURES_SIZE);\n\n    /* Return pointer to the processor structures */\n    *StructuresData = ProcessorStructures;\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Destroys a kernel stack and frees page table entry.\n *\n * @param Stack\n *        Supplies a pointer to the memory area containing a kernel stack.\n *\n * @param StackSize\n *        Supplies the size of the stack to be freed, in bytes.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::KernelPool::FreeKernelStack(IN PVOID Stack,\n                                IN ULONG StackSize)\n{\n    PFN_COUNT StackPages;\n    PMMPTE PointerPte;\n    ULONG Index;\n\n    /* Get the PTE for the top of the stack, including the guard page */\n    PointerPte = MM::Paging::AdvancePte(MM::Paging::GetPteAddress(Stack), -1);\n\n    /* Convert the stack size into a page count */\n    StackPages = SIZE_TO_PAGES(StackSize);\n\n    /* Start a guarded code block */\n    {\n        /* Acquire the PFN database lock */\n        KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);\n\n        /* Loop through each page of the stack that needs to be freed */\n        for(Index = 0; Index < StackPages; Index++)\n        {\n            /* Ensure the PTE is valid */\n            if(MM::Paging::PteValid(PointerPte))\n            {\n                /* Free the physical page */\n                MM::Pfn::FreePhysicalPage(PointerPte);\n            }\n\n            /* Advance to the next PTE */\n            PointerPte = MM::Paging::AdvancePte(PointerPte, -1);\n        }\n    }\n\n    /* Release all system PTEs used by the stack, including the guard page */\n    MM::Pte::ReleaseSystemPtes(PointerPte, StackPages + 1, SystemPteSpace);\n}\n\n/**\n * Destroys an unused set of processor structures.\n *\n * @param StructuresData\n *        Supplies a pointer to the memory area containing the allocated buffer.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::KernelPool::FreeProcessorStructures(IN PVOID StructuresData)\n{\n    /* Check if the provided pointer is valid */\n    if(StructuresData != NULLPTR)\n    {\n        /* Release the contiguous memory block back */\n        MM::Allocator::FreePool(StructuresData);\n    }\n}\n"
  },
  {
    "path": "xtoskrnl/mm/mmgr.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/mmgr.cc\n * DESCRIPTION:     Memory Manager\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Computes the size of the boot image.\n *\n * @param BootImageSize\n *        Supplies a pointer to a variable that will receive the size of the boot image in pages.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::ComputeBootImageSize(OUT PPFN_NUMBER BootImageSize)\n{\n    PKERNEL_INITIALIZATION_BLOCK InitializationBlock;\n    PFN_NUMBER ImageSize;\n    ULONG_PTR Alignment;\n\n    /* Get the kernel initialization block */\n    InitializationBlock = KE::BootInformation::GetInitializationBlock();\n\n    /* Calculate the alignment based on the PTE size */\n    Alignment = ((MM_PAGE_SIZE / MM::Paging::GetPteSize()) * MM_PAGE_SIZE);\n\n    /* Calculate the size of the boot image */\n    ImageSize = InitializationBlock->BootImageSize * MM_PAGE_SIZE;\n    ImageSize = (ImageSize + Alignment - 1) & ~(Alignment - 1);\n\n    /* Return number of pages used by the boot image */\n    *BootImageSize = ImageSize / MM_PAGE_SIZE;\n}\n\n/**\n * Retrieves the amount of total available memory in the system.\n *\n * @return This routine returns the amount of available memory in the system in megabytes.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nMM::Manager::GetInstalledMemorySize(VOID)\n{\n    /* Return the amount of installed memory */\n    return (MM::Pfn::GetNumberOfPhysicalPages() * MM_PAGE_SIZE) / 1048576;\n}\n\n/**\n * Retrieves a pointer to the system's virtual memory layout structure.\n *\n * @return This routine returns a pointer to the memory layout structure.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMMEMORY_LAYOUT\nMM::Manager::GetMemoryLayout(VOID)\n{\n    /* Return a pointer to the global memory layout structure */\n    return &MemoryLayout;\n}\n\n/**\n * Retrieves the number of system PTEs.\n *\n * @return This routine returns the number of system PTEs.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_NUMBER\nMM::Manager::GetNumberOfSystemPtes(VOID)\n{\n    return NumberOfSystemPtes;\n}\n\n/**\n * Initializes and returns the system physical memory descriptor block.\n *\n * @return This routine returns a pointer to the structure representing the system usable physical memory block.\n *\n * @since XT 1.0\n */\nXTAPI\nPPHYSICAL_MEMORY_DESCRIPTOR\nMM::Manager::GetPhysicalMemoryBlock(VOID)\n{\n    PPHYSICAL_MEMORY_DESCRIPTOR PrimaryBuffer, SecondaryBuffer;\n    PKERNEL_INITIALIZATION_BLOCK InitializationBlock;\n    PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor;\n    PFN_NUMBER PageFrameNumer, NumberOfPages;\n    ULONG DescriptorCount, RunCount;\n    PLIST_ENTRY ListEntry;\n    XTSTATUS Status;\n\n    /* Check if the physical memory block has already been initialized */\n    if(!PhysicalMemoryBlock)\n    {\n        /* Reset local tracking variables */\n        DescriptorCount = 0;\n        NumberOfPages = 0;\n        PageFrameNumer = -1;\n        RunCount = 0;\n\n        /* Retrieve the kernel initialization block */\n        InitializationBlock = KE::BootInformation::GetInitializationBlock();\n\n        /* Iterate through the loader memory descriptor list to determine its size */\n        ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;\n        while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)\n        {\n            /* Count this descriptor */\n            DescriptorCount++;\n\n            /* Go to the next descriptor */\n            ListEntry = ListEntry->Flink;\n        }\n\n        /* Ensure the memory descriptor list is not empty */\n        if(DescriptorCount == 0)\n        {\n            /* Fail gracefully if no memory descriptors were found, by returning NULLPTR */\n            return NULLPTR;\n        }\n\n        /* Allocate a primary buffer sized for the maximum possible number of runs */\n        Status = MM::Allocator::AllocatePool(NonPagedPool,\n                                             sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +\n                                             sizeof(PHYSICAL_MEMORY_RUN) *\n                                             (DescriptorCount - 1),\n                                             (PVOID*)&PrimaryBuffer,\n                                             SIGNATURE32('M', 'M', 'g', 'r'));\n        if(Status != STATUS_SUCCESS || !PrimaryBuffer)\n        {\n            /* Primary pool allocation failed, return NULLPTR */\n            return NULLPTR;\n        }\n\n        /* Traverse the memory descriptor list a second time to build the map */\n        ListEntry = InitializationBlock->MemoryDescriptorListHead.Flink;\n        while(ListEntry != &InitializationBlock->MemoryDescriptorListHead)\n        {\n            /* Resolve the memory descriptor record from the current list entry */\n            MemoryDescriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);\n\n            /* Filter out bad, reserved, or invisible memory types */\n            if((MemoryDescriptor->MemoryType < LoaderMaximum) &&\n               (MemoryDescriptor->MemoryType != LoaderBad) &&\n               !VerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType))\n            {\n                /* Accumulate the total number of usable physical pages */\n                NumberOfPages += MemoryDescriptor->PageCount;\n\n                /* Check if the current descriptor is contiguous with the previous run */\n                if(RunCount > 0 && MemoryDescriptor->BasePage == PageFrameNumer)\n                {\n                    /* Coalesce the contiguous descriptor into the existing physical run */\n                    PrimaryBuffer->Run[RunCount - 1].PageCount += MemoryDescriptor->PageCount;\n                    PageFrameNumer += MemoryDescriptor->PageCount;\n                }\n                else\n                {\n                    /* Start a new physical run with the new descriptor's boundaries */\n                    PrimaryBuffer->Run[RunCount].BasePage = MemoryDescriptor->BasePage;\n                    PrimaryBuffer->Run[RunCount].PageCount = MemoryDescriptor->PageCount;\n\n                    /* Update the expected next page frame number for future contiguity checks */\n                    PageFrameNumer = PrimaryBuffer->Run[RunCount].BasePage + PrimaryBuffer->Run[RunCount].PageCount;\n\n                    /* Increment the total number of distinct physical memory runs */\n                    RunCount++;\n                }\n            }\n\n            /* Go to the next descriptor */\n            ListEntry = ListEntry->Flink;\n        }\n\n        /* Check if the buffer can be shrunk due to coalesced memory runs */\n        if(DescriptorCount > RunCount)\n        {\n            /* Allocate a secondary, more tightly sized buffer to reduce memory footprint */\n            Status = MM::Allocator::AllocatePool(NonPagedPool,\n                                                 sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +\n                                                 sizeof(PHYSICAL_MEMORY_RUN) *\n                                                 (RunCount - 1),\n                                                 (PVOID*)&SecondaryBuffer,\n                                                 SIGNATURE32('M', 'M', 'g', 'r'));\n            if(Status == STATUS_SUCCESS && SecondaryBuffer)\n            {\n                /* Copy the coalesced runs from the oversized primary buffer */\n                RtlCopyMemory(SecondaryBuffer->Run, PrimaryBuffer->Run, sizeof(PHYSICAL_MEMORY_RUN) * RunCount);\n\n                /* Free the primary buffer */\n                MM::Allocator::FreePool(PrimaryBuffer, SIGNATURE32('M', 'M', 'g', 'r'));\n\n                /* Update the primary buffer pointer */\n                PrimaryBuffer = SecondaryBuffer;\n            }\n        }\n\n        /* Populate the final metadata and save the physical memory block globally */\n        PrimaryBuffer->NumberOfRuns = RunCount;\n        PrimaryBuffer->NumberOfPages = NumberOfPages;\n        PhysicalMemoryBlock = PrimaryBuffer;\n    }\n\n    /* Return a pointer to the physical memory block */\n    return PhysicalMemoryBlock;\n}\n\n/**\n * Performs an early initialization of the XTOS Memory Manager.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Manager::InitializeMemoryManager(VOID)\n{\n    /* Scan memory descriptors provided by the boot loader */\n    MM::Pfn::ScanMemoryDescriptors();\n\n    /* Check if there are enough physical pages */\n    if(MM::Pfn::GetNumberOfPhysicalPages() < MM_MINIMUM_PHYSICAL_PAGES)\n    {\n        /* Insufficient physical pages, kernel panic */\n        DebugPrint(L\"Insufficient physical pages! Install additional memory\\n\");\n        KE::Crash::Panic(0x7D, MM::Pfn::GetNumberOfPhysicalPages(), MM_MINIMUM_PHYSICAL_PAGES, 0x0, 0x2);\n    }\n\n    /* Compute page colors to reduce CPU cache conflicts */\n    MM::Colors::ComputePageColoring();\n\n    /* Initialize and dump memory layout */\n    InitializeMemoryLayout();\n    DumpMemoryLayout();\n\n    /* Initialize PTE template */\n    MM::Pte::InitializeSystemPte();\n\n    /* Initialize page table */\n    MM::Pte::InitializePageTable();\n\n    /* Initialize system PTE space */\n    MM::Pte::InitializeSystemPteSpace();\n\n    /* Initialize memory pool security */\n    MM::Pool::InitializePoolSecurity();\n\n    /* Initialize non-paged pool */\n    MM::Pool::InitializeNonPagedPool();\n\n    /* Initialize PFN database */\n    MM::Pfn::InitializePfnDatabase();\n\n    /* Initialize allocations tracking tables */\n    MM::Allocator::InitializeAllocationsTracking();\n    MM::Allocator::InitializeBigAllocationsTracking();\n\n    /* Initialize PFN bitmap */\n    MM::Pfn::InitializePfnBitmap();\n\n    /* Initialize paged pool */\n    MM::Pool::InitializePagedPool();\n\n    /* Flush TLB */\n    AR::CpuFunctions::FlushTlb();\n}\n\n/**\n * Allocates and maps the Kernel Shared Data page to its hardcoded virtual address.\n *\n * @return This routine returns status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nMM::Manager::MapKernelSharedData(VOID)\n{\n    PHYSICAL_ADDRESS PhysAddr;\n    PMMPTE PtePointer;\n    XTSTATUS Status;\n\n    /* Allocate one physical page from the hardware pool for the shared data */\n    Status = MM::HardwarePool::AllocateHardwareMemory(1, FALSE, MM_MAXIMUM_PHYSICAL_ADDRESS, &PhysAddr);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Memory allocation failed, return error code */\n        return Status;\n    }\n\n    /* Retrieve the Page Table Entry (PTE) corresponding to the KSD virtual address */\n    PtePointer = MM::Paging::GetPteAddress((PVOID)MM_KERNEL_SHARED_DATA_ADDRESS);\n\n    /* Manually map the corresponding PTE */\n    MM::Paging::SetPte(PtePointer, (PFN_NUMBER)(PhysAddr.QuadPart >> MM_PAGE_SHIFT), MM_PTE_READWRITE);\n\n    /* Flush the Translation Lookaside Buffer (TLB) */\n    MM::Paging::FlushTlb();\n\n    /* Zero the page content */\n    RTL::Memory::ZeroMemory((PVOID)MM_KERNEL_SHARED_DATA_ADDRESS, MM_PAGE_SIZE);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Checks whether the specified memory type should be considered as free.\n *\n * @param MemoryType\n *        Specifies the memory type to verify.\n *\n * @return This routine returns TRUE if the specified memory type should be considered as free, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Manager::VerifyMemoryTypeFree(LOADER_MEMORY_TYPE MemoryType)\n{\n    return ((MemoryType == LoaderFirmwareTemporary) ||\n            (MemoryType == LoaderFree) ||\n            (MemoryType == LoaderLoadedProgram) ||\n            (MemoryType == LoaderOsloaderStack));\n}\n\n/**\n * Checks whether the specified memory type should be considered as invisible for the memory manager.\n *\n * @param MemoryType\n *        Specifies the memory type to verify.\n *\n * @return This routine returns TRUE if the specified memory type should be considered as invisible, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Manager::VerifyMemoryTypeInvisible(LOADER_MEMORY_TYPE MemoryType)\n{\n    return ((MemoryType == LoaderBBTMemory) ||\n            (MemoryType == LoaderFirmwarePermanent) ||\n            (MemoryType == LoaderSpecialMemory));\n}\n"
  },
  {
    "path": "xtoskrnl/mm/paging.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/paging.cc\n * DESCRIPTION:     Low level page management support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Advances a PTE pointer by a given number of entries, considering the actual PTE size.\n *\n * @param Pte\n *        The PTE pointer to advance.\n *\n * @param Count\n *        The number of PTE entries to advance by.\n *\n * @return The advanced PTE pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::Paging::AdvancePte(IN PMMPTE Pte,\n                       IN LONG Count)\n{\n    /* Return advanced PTE pointer */\n    return PmlRoutines->AdvancePte(Pte, Count);\n}\n\n/**\n * Checks if the given address is canonical.\n *\n * @param VirtualAddress\n *        Specifies the virtual address to check.\n *\n * @return This routine returns TRUE if the address is canonical, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Paging::CanonicalAddress(IN PVOID VirtualAddress)\n{\n    /* Return canonical address status */\n    return PmlRoutines->CanonicalAddress(VirtualAddress);\n}\n\n/**\n * Clears the contents of a page table entry (PTE).\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to be cleared.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::ClearPte(IN PMMPTE PtePointer)\n{\n    /* Clear PTE */\n    PmlRoutines->ClearPte(PtePointer);\n}\n\n/**\n * Flushes the entire Translation Lookaside Buffer (TLB) on all processors.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::FlushEntireTlb(VOID)\n{\n    /* Temporarily fallback to FlushTlb() as SMP is not supported yet */\n    FlushTlb();\n}\n\n/**\n * Flushes current Translation Lookaside Buffer (TLB).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::FlushTlb(VOID)\n{\n    CPUID_REGISTERS CpuRegisters;\n    BOOLEAN Interrupts;\n    ULONG_PTR Cr4;\n\n    /* Save interrupts state and disable them */\n    Interrupts = AR::CpuFunctions::InterruptsEnabled();\n    AR::CpuFunctions::ClearInterruptFlag();\n\n    /* Get CPU features */\n    CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;\n    AR::CpuFunctions::CpuId(&CpuRegisters);\n\n    /* Check if Paging Global Extensions (PGE) is supported */\n    if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE)\n    {\n        /* Read CR4 */\n        Cr4 = AR::CpuFunctions::ReadControlRegister(4);\n\n        /* Disable PGE */\n        AR::CpuFunctions::WriteControlRegister(4, Cr4 & ~CR4_PGE);\n\n        /* Flush the TLB */\n        AR::CpuFunctions::FlushTlb();\n\n        /* Restore CR4 */\n        AR::CpuFunctions::WriteControlRegister(4, Cr4);\n    }\n    else\n    {\n        /* Simply flush the TLB */\n        AR::CpuFunctions::FlushTlb();\n    }\n\n    /* Check if interrupts should be enabled */\n    if(Interrupts)\n    {\n        /* Re-enable interrupts */\n        AR::CpuFunctions::SetInterruptFlag();\n    }\n}\n\n/**\n * Gets the next entry in a PTE list.\n *\n * @param Pte\n *        The PTE pointer to get the next entry from.\n *\n * @return This routine returns the next entry in the PTE list.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nMM::Paging::GetNextEntry(IN PMMPTE Pte)\n{\n    /* Return next entry in PTE list */\n    return PmlRoutines->GetNextEntry(Pte);\n}\n\n/**\n * Advances a PTE pointer, considering the actual PTE size.\n *\n * @param Pte\n *        The PTE pointer to advance.\n *\n * @return The advanced PTE pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::Paging::GetNextPte(IN PMMPTE Pte)\n{\n    /* Return advanced PTE pointer */\n    return PmlRoutines->GetNextPte(Pte);\n}\n\n/**\n * Checks if a PTE list contains only one entry.\n *\n * @param Pte\n *        The PTE pointer to check.\n *\n * @return This routine returns TRUE if the PTE list has only one entry, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Paging::GetOneEntry(IN PMMPTE Pte)\n{\n    /* Return one entry status */\n    return PmlRoutines->GetOneEntry(Pte);\n}\n\n/**\n * Gets the page frame number from a corresponding PTE.\n *\n * @param Pte\n *        The PTE pointer to get the page frame number from.\n *\n * @return This routine returns the page frame number.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_NUMBER\nMM::Paging::GetPageFrameNumber(IN PMMPTE Pte)\n{\n    return PmlRoutines->GetPageFrameNumber(Pte);\n}\n\n/**\n * Gets the page map routines for basic paging mode (non-XPA).\n *\n * @return This routine returns the address of the object containing non-XPA page map routines.\n *\n * @since XT 1.0\n */\nXTAPI\nMM::PPAGEMAP\nMM::Paging::GetPageMapBasicRoutines(VOID)\n{\n    static MM::PageMapBasic PageMapBasicRoutines;\n\n    /* Return non-XPA page map routines */\n    return &PageMapBasicRoutines;\n}\n\n/**\n * Gets Page Map Level (PML) for current paging mode.\n *\n * @return This routine returns the page map level.\n *\n * @since XT 1.0\n */\nXTAPI\nUSHORT\nMM::Paging::GetPageMapLevel()\n{\n    return PmlRoutines->GetPageMapLevel();\n}\n\n/**\n * Gets the page map routines for eXtended Physical Addressing (XPA) mode.\n *\n * @return This routine returns the address of the object containing XPA page map routines.\n *\n * @since XT 1.0\n */\nXTAPI\nMM::PPAGEMAP\nMM::Paging::GetPageMapXpaRoutines(VOID)\n{\n    static MM::PageMapXpa PageMapXpaRoutines;\n\n    /* Return XPA page map routines */\n    return &PageMapXpaRoutines;\n}\n\n/**\n * Gets the address of the PDE (Page Directory Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PDE.\n *\n * @return This routine returns the address of the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPDE\nMM::Paging::GetPdeAddress(IN PVOID Address)\n{\n    /* Return PDE address */\n    return PmlRoutines->GetPdeAddress(Address);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Entry.\n *\n * @param PdePointer\n *        Specifies the address of the PDE.\n *\n * @return This routine returns the virtual address mapped by the PDE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::Paging::GetPdeVirtualAddress(IN PMMPDE PdePointer)\n{\n    /* Return PTE virtual address */\n    return PmlRoutines->GetPdeVirtualAddress(PdePointer);\n}\n\n/**\n * Gets the address of the PPE (Page Directory Pointer Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PDE.\n *\n * @return This routine returns the address of the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPPE\nMM::Paging::GetPpeAddress(IN PVOID Address)\n{\n    /* Return PPE address */\n    return PmlRoutines->GetPpeAddress(Address);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Directory Pointer Table Entry.\n *\n * @param PpePointer\n *        Specifies the address of the PPE.\n *\n * @return This routine returns the virtual address mapped by the PPE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::Paging::GetPpeVirtualAddress(IN PMMPPE PpePointer)\n{\n    /* Return PTE virtual address */\n    return PmlRoutines->GetPpeVirtualAddress(PpePointer);\n}\n\n /**\n * Gets the entire contents of a Page Table Entry (PTE) as a single value.\n *\n * @param PtePointer\n *        Pointer to the Page Table Entry (PTE) to read.\n *\n * @return This routine returns the contents of the PTE as a single value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nMM::Paging::GetPte(IN PMMPTE PtePointer)\n{\n    /* Return PTE value */\n    return PmlRoutines->GetPte(PtePointer);\n}\n\n/**\n * Gets the address of the PTE (Page Table Entry), that maps given address.\n *\n * @param Address\n *        Specifies the virtual address for which to retrieve the corresponding PTE.\n *\n * @return This routine returns the address of the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::Paging::GetPteAddress(IN PVOID Address)\n{\n    /* Return PTE address */\n    return PmlRoutines->GetPteAddress(Address);\n}\n\n/**\n * Calculates the distance between two PTE pointers.\n *\n * @param EndPte\n *        Pointer to the ending Page Table Entry.\n *\n * @param StartPte\n *        Pointer to the starting Page Table Entry.\n *\n * @return This routine returns a signed value representing the number of PTEs between EndPte and StartPte.\n *\n * @since XT 1.0\n */\nXTAPI\nLONG\nMM::Paging::GetPteDistance(PMMPTE EndPte,\n                           PMMPTE StartPte)\n{\n    /* Return distance between PTE pointers */\n    return PmlRoutines->GetPteDistance(EndPte, StartPte);\n}\n\n/**\n * Gets the size of a PTE.\n *\n * @return This routine returns the size of a PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Paging::GetPteSize(VOID)\n{\n    /* Return the size of MMPTE */\n    return PmlRoutines->GetPteSize();\n}\n\n/**\n * Gets the software protection value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software protection value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Paging::GetPteSoftwareProtection(IN PMMPTE PtePointer)\n{\n    /* Return PTE software protection value */\n    return PmlRoutines->GetPteSoftwareProtection(PtePointer);\n}\n\n/**\n * Gets the software prototype value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software prototype value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Paging::GetPteSoftwarePrototype(IN PMMPTE PtePointer)\n{\n    /* Return PTE software prototype value */\n    return PmlRoutines->GetPteSoftwarePrototype(PtePointer);\n}\n\n/**\n * Gets the software transition value of the corresponding Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the PTE software transition value.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Paging::GetPteSoftwareTransition(IN PMMPTE PtePointer)\n{\n    /* Return PTE software transition value */\n    return PmlRoutines->GetPteSoftwareTransition(PtePointer);\n}\n\n/**\n * Gets the virtual address that is mapped by a given Page Table Entry.\n *\n * @param PtePointer\n *        Specifies the address of the PTE.\n *\n * @return This routine returns the virtual address mapped by the PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPVOID\nMM::Paging::GetPteVirtualAddress(IN PMMPTE PtePointer)\n{\n    /* Return PTE virtual address */\n    return PmlRoutines->GetPteVirtualAddress(PtePointer);\n}\n\n/**\n * Gets current status of eXtended Physical Addressing (XPA).\n *\n * @return This routine returns TRUE if PAE or LA57 (XPA) is enabled, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Paging::GetXpaStatus()\n{\n    return PmlRoutines->GetXpaStatus();\n}\n\n/**\n * Detects if eXtended Physical Addressing (XPA) is enabled and initializes page map support.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::InitializePageMapSupport(VOID)\n{\n    /* Check if XPA is enabled */\n    if(GetExtendedPhysicalAddressingStatus())\n    {\n        /* XPA enabled, use modern paging (PAE / LA57) */\n        PmlRoutines = GetPageMapXpaRoutines();\n    }\n    else\n    {\n        /* XPA disabled, use basic paging (PML2 / PML4) */\n        PmlRoutines = GetPageMapBasicRoutines();\n    }\n\n    /* Set page map information */\n    PmlRoutines->InitializePageMapInfo();\n}\n\n/**\n * Checks whether the given PML2 page table entry (PTE) is valid.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to check.\n *\n * @return Returns TRUE if the entry is valid, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Paging::PteValid(IN PMMPTE PtePointer)\n{\n    /* Check if PTE is valid */\n    return PmlRoutines->PteValid(PtePointer);\n}\n\n/**\n * Sets the next entry in a PTE list.\n *\n * @param Pte\n *        The PTE pointer to modify.\n *\n * @param Value\n *        The value to set as the next entry.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::SetNextEntry(IN PMMPTE Pte,\n                         IN ULONG_PTR Value)\n{\n    /* Set next entry in PTE list */\n    PmlRoutines->SetNextEntry(Pte, Value);\n}\n\n/**\n * Sets the flag indicating whether a PTE list contains only one entry.\n *\n * @param Pte\n *        The PTE pointer to modify.\n *\n * @param Value\n *        The value to set. TRUE if the list has only one entry, FALSE otherwise.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::SetOneEntry(IN PMMPTE Pte,\n                        IN BOOLEAN Value)\n{\n    /* Set one entry status */\n    PmlRoutines->SetOneEntry(Pte, Value);\n}\n\n/**\n * Sets a Page Table Entry (PTE) with the specified physical page and access flags.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to set.\n *\n * @param PageFrameNumber\n *        Physical frame number to map.\n *\n * @param AttributesMask\n *        Specifies the attributes mask to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::SetPte(IN PMMPTE PtePointer,\n                   IN PFN_NUMBER PageFrameNumber,\n                   IN ULONGLONG AttributesMask)\n{\n    /* Set PTE */\n    PmlRoutines->SetPte(PtePointer, PageFrameNumber, AttributesMask);\n}\n\n/**\n * Sets a Page Table Entry (PTE) with the specified attributes.\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to set.\n *\n * @param Attributes\n *        Specifies the attributes to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::SetPte(IN PMMPTE PtePointer,\n                   IN ULONGLONG Attributes)\n{\n    PmlRoutines->SetPte(PtePointer, Attributes);\n}\n\n/**\n * Sets caching attributes for a PML2 page table entry (PTE).\n *\n * @param PtePointer\n *        Pointer to the page table entry (PTE) to modify.\n *\n * @param CacheDisable\n *        Indicates whether caching should be disabled for this page.\n *\n * @param WriteThrough\n *        Indicates whether write-through caching should be enabled.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::SetPteCaching(IN PMMPTE PtePointer,\n                          IN BOOLEAN CacheDisable,\n                          IN BOOLEAN WriteThrough)\n{\n    /* Set caching attributes */\n    PmlRoutines->SetPteCaching(PtePointer, CacheDisable, WriteThrough);\n}\n\n/**\n * Transitions a Page Table Entry (PTE) to invalid state\n *\n * @param PointerPte\n *        Pointer to the page table entry (PTE) to transition.\n *\n * @param Protection\n *        Specifies the protection attribute to apply to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::TransitionPte(IN PMMPTE PointerPte,\n                          IN ULONG_PTR Protection)\n{\n    /* Transition PTE */\n    PmlRoutines->TransitionPte(PointerPte, Protection);\n}\n\n/**\n * Writes a Page Table Entry (PTE) with the specified value.\n *\n * @param Pte\n *        Pointer to the page table entry (PTE) to write.\n *\n * @param Value\n *        The value to write to the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Paging::WritePte(IN PMMPTE Pte,\n                     IN MMPTE Value)\n{\n    /* Assign PTE value */\n    PmlRoutines->WritePte(Pte, Value);\n}\n"
  },
  {
    "path": "xtoskrnl/mm/pfn.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/pfn.cc\n * DESCRIPTION:     Physical Frame Number (PFN) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n *                  Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Allocates a block of physical pages for early kernel initialization.\n *\n * @param NumberOfPages\n *        The number of physical pages to allocate.\n *\n * @return This routine returns the base page frame number (PFN) of the allocated block.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_NUMBER\nMM::Pfn::AllocateBootstrapPages(IN PFN_NUMBER NumberOfPages)\n{\n    PFN_NUMBER Pfn;\n\n    /* Check if the largest free memory block has enough pages */\n    if(NumberOfPages > FreeDescriptor->PageCount)\n    {\n        /* Not enough physical memory available, kernel panic */\n        DebugPrint(L\"Insufficient physical pages! Install additional memory\\n\");\n        KE::Crash::Panic(0x7D,\n                         NumberOfPhysicalPages,\n                         FreeDescriptor->PageCount,\n                         OriginalFreeDescriptor.PageCount,\n                         NumberOfPages);\n    }\n\n    /* Allocate pages from the beginning of the free descriptor */\n    Pfn = FreeDescriptor->BasePage;\n    FreeDescriptor->BasePage += NumberOfPages;\n    FreeDescriptor->PageCount -= NumberOfPages;\n\n    /* Return the base page frame number of the allocated block */\n    return Pfn;\n}\n\n/**\n * Allocates a physical page frame (PFN) from one of the system's free page lists.\n *\n * @param Color\n *        The preferred page color, used to optimize CPU cache alignment and reduce cache contention.\n *\n * @return This routine returns the Page Frame Number (PFN) of the allocated page.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_NUMBER\nMM::Pfn::AllocatePhysicalPage(IN ULONG Color)\n{\n    PFN_NUMBER PageNumber;\n    ULONG PagingColorsMask;\n\n    /* Check if any physical pages are available in the system */\n    if(!AvailablePages)\n    {\n        /* No physical pages are available in the system, return 0 */\n        return 0;\n    }\n\n    /* Retrieve the bitmask used for calculating a page's color */\n    PagingColorsMask = MM::Colors::GetPagingColorsMask();\n\n    /* Attempt to retrieve a page from the colored free page list */\n    PageNumber = MM::Colors::GetFreePages(FreePageList, Color)->Flink;\n    if(PageNumber == MAXULONG_PTR)\n    {\n        /* No page was found in the colored free page list, check the colored zero page list */\n        PageNumber = MM::Colors::GetFreePages(ZeroedPageList, Color)->Flink;\n    }\n\n    /* Attempt to retrieve a page from the colored zero list */\n    if(PageNumber == MAXULONG_PTR)\n    {\n        /* No page was found in the colored zero page list, check the global free page list */\n        PageNumber = FreePagesList.Flink;\n    }\n\n    /* Attempt to retrieve a page from the global free page list */\n    if(PageNumber == MAXULONG_PTR)\n    {\n        /* No page was found in the global free page list, check the global zero page list */\n        PageNumber = ZeroedPagesList.Flink;\n    }\n\n    /* Remove the page from its list and return its PFN */\n    return UnlinkFreePage(PageNumber, PageNumber & PagingColorsMask);\n}\n\n/**\n * Calculates the total number of pages required for the PFN database and its associated color tables.\n *\n * @param DatabaseSize\n *        A pointer to a variable that will receive the number of pages required for the PFN database.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::ComputePfnDatabaseSize(OUT PPFN_NUMBER DatabaseSize)\n{\n    PFN_NUMBER PfnDatabaseSize;\n\n    /* Calculate the total number of pages required for the PFN database */\n    PfnDatabaseSize = (HighestPhysicalPage + 1) * sizeof(MMPFN);\n    PfnDatabaseSize += (MM::Colors::GetPagingColors() * sizeof(MMCOLOR_TABLES) * 2);\n    PfnDatabaseSize = ROUND_UP(PfnDatabaseSize, MM_PAGE_SIZE);\n    PfnDatabaseSize >>= MM_PAGE_SHIFT;\n\n    /* Return the PFN database size */\n    *DatabaseSize = PfnDatabaseSize;\n}\n\n/**\n * Decrements the global count of available pages.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::DecrementAvailablePages(VOID)\n{\n    /* Decrement the global count of available pages */\n    AvailablePages--;\n}\n\n/**\n * Decrements the reference count of a PFN entry.\n *\n * @param PageFrameNumber\n *        A pointer to the PFN database entry for the physical page.\n *\n * @param PageFrameIndex\n *        The page frame number of the physical page.\n *\n * @param BeginStandbyList\n *        Determines whether the page should be added to the beginning of the standby list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::DecrementReferenceCount(IN PMMPFN PageFrameNumber,\n                                 IN PFN_NUMBER PageFrameIndex,\n                                 IN BOOLEAN BeginStandbyList)\n{\n    /* Decrement the PFN reference count */\n    PageFrameNumber->u3.e2.ReferenceCount--;\n\n    /* If other references exist, no further action is needed */\n    if(PageFrameNumber->u3.e2.ReferenceCount)\n    {\n        /* No further action can be taken */\n        return;\n    }\n\n    /* If the reference count is zero, the share count should also be zero */\n    if(PageFrameNumber->u2.ShareCount)\n    {\n        /* This indicates a bug; crash the system */\n        KE::Crash::Panic(0x4E,\n                         0x07,\n                         PageFrameIndex,\n                         PageFrameNumber->u2.ShareCount,\n                         0);\n    }\n\n    /* Check if the PTE is marked as being ready for removal */\n    if((ULONG_PTR)PageFrameNumber->PteAddress & 0x1)\n    {\n        /* Check the page's cache attribute */\n        if((PageFrameNumber->u3.e1.CacheAttribute != PfnCached) &&\n           (PageFrameNumber->u3.e1.CacheAttribute != PfnNotMapped))\n        {\n            /* Flush the TLB to prevent cache attribute conflicts from stale non-cached mappings */\n            MM::Paging::FlushEntireTlb();\n        }\n\n        /* The page is no longer needed, free it by linking it to the free list */\n        LinkFreePage(PageFrameIndex);\n\n        /* No further action is needed */\n        return;\n    }\n\n    /* The page is unreferenced and unmapped, so place it on the appropriate list */\n    if(PageFrameNumber->u3.e1.Modified == 1)\n    {\n        /* Link dirty page to the modified list */\n        LinkPage(&ModifiedPagesList, PageFrameIndex);\n    }\n    else\n    {\n        /* Check if the page has been marked for removal */\n        if(PageFrameNumber->u3.e1.RemovalRequested == 1)\n        {\n            /* Update the page location and move it to the bad pages list */\n            PageFrameNumber->u3.e1.PageLocation = StandbyPageList;\n            LinkPage(&BadPagesList, PageFrameIndex);\n        }\n        else\n        {\n            /* Link clean page to the standby list */\n            if(BeginStandbyList)\n            {\n                /* Link clean page to the beginning of the standby list */\n                LinkStandbyPage(PageFrameIndex);\n            }\n            else\n            {\n                /* Link clean page to the end of the standby list */\n                LinkPage(&StandbyPagesList, PageFrameIndex);\n            }\n        }\n    }\n}\n\n/**\n * Decrements the share count of a PFN entry, which represents the number of PTEs mapping the page.\n *\n * @param PageFrameNumber\n *        A pointer to the PFN database entry for the physical page.\n *\n * @param PageFrameIndex\n *        The page frame number of the physical page.\n *\n * @param BeginStandbyList\n *        Determines whether the page should be added to the beginning of the standby list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::DecrementShareCount(IN PMMPFN PageFrameNumber,\n                             IN PFN_NUMBER PageFrameIndex,\n                             IN BOOLEAN BeginStandbyList)\n{\n    /* Ensure the page is in a valid state */\n    if((PageFrameNumber->u3.e1.PageLocation != ActiveAndValid) &&\n       (PageFrameNumber->u3.e1.PageLocation != StandbyPageList))\n    {\n        /* This indicates a bug; crash the system */\n        KE::Crash::Panic(0x4E,\n                         0x99,\n                         PageFrameIndex,\n                         PageFrameNumber->u3.e1.PageLocation,\n                         0);\n    }\n\n    /* Decrement the PFN share count */\n    PageFrameNumber->u2.ShareCount--;\n\n    /* Check if the share count has dropped to zero */\n    if(!PageFrameNumber->u2.ShareCount)\n    {\n        /* Check if this is a prototype PTE */\n        if(PageFrameNumber->u3.e1.PrototypePte)\n        {\n            /* Transition the PTE to invalid state */\n            MM::Paging::TransitionPte(PageFrameNumber->PteAddress,\n                                      MM::Paging::GetPteSoftwareProtection(&PageFrameNumber->OriginalPte));\n        }\n\n        /* Mark the page as being in a transition state */\n        PageFrameNumber->u3.e1.PageLocation = TransitionPage;\n\n        /* Check if there are still outstanding references */\n        if(PageFrameNumber->u3.e2.ReferenceCount == 1)\n        {\n            /* Check if the PTE is marked as being ready for removal */\n            if((ULONG_PTR)PageFrameNumber->PteAddress & 0x1)\n            {\n                /* Reset the reference count */\n                PageFrameNumber->u3.e2.ReferenceCount = 0;\n\n                /* Check the page's cache attribute */\n                if((PageFrameNumber->u3.e1.CacheAttribute != PfnCached) &&\n                   (PageFrameNumber->u3.e1.CacheAttribute != PfnNotMapped))\n                {\n                    /* Flush the TLB to prevent cache attribute conflicts from stale non-cached mappings */\n                    MM::Paging::FlushEntireTlb();\n                }\n\n                /* Mark the page as active and valid again */\n                PageFrameNumber->u3.e1.PageLocation = ActiveAndValid;\n\n                /* The page is no longer needed, free it by linking it to the free list */\n                MM::Pfn::LinkFreePage(PageFrameIndex);\n            }\n            else\n            {\n                /* The PTE can not be removed yet, decrement the reference count */\n                DecrementReferenceCount(PageFrameNumber, PageFrameIndex, BeginStandbyList);\n            }\n        }\n        else\n        {\n            /* There are still some outstanding references, decrement the reference count */\n            PageFrameNumber->u3.e2.ReferenceCount--;\n        }\n    }\n}\n\n/**\n * Frees a physical page that is mapped by a given PTE.\n *\n * @param PointerPte\n *        A pointer to the Page Table Entry (PTE) that maps the physical page to be freed.\n *\n * @return This routine does not return a value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::FreePhysicalPage(IN PMMPTE PointerPte)\n{\n    PFN_COUNT PageFrameNumber, PageTableFrameNumber;\n    PMMPFN PageFrame, PageTableFrame;\n\n    /* Get the page frame number from the PTE */\n    PageFrameNumber = MM::Paging::GetPageFrameNumber(PointerPte);\n    PageFrame = MM::Pfn::GetPfnEntry(PageFrameNumber);\n\n    /* Get the page table frame number corresponding to the PTE */\n    PageTableFrameNumber = PageFrame->u4.PteFrame;\n    PageTableFrame = MM::Pfn::GetPfnEntry(PageTableFrameNumber);\n\n    /* Decrement the share count of the page table */\n    MM::Pfn::DecrementShareCount(PageTableFrame, PageTableFrameNumber, FALSE);\n\n    /* Mark the PTE as being ready for removal */\n    MM::Paging::SetPte(PageFrame->PteAddress, MM::Paging::GetPte(PageFrame->PteAddress) | 1);\n\n    /* Decrement the share count of the page */\n    MM::Pfn::DecrementShareCount(PageFrame, PageFrameNumber, FALSE);\n}\n\n/**\n * Retrieves the number of available physical pages.\n *\n * @return This routine returns the number of available physical pages.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_NUMBER\nMM::Pfn::GetAvailablePages(VOID)\n{\n    /* Return the number of available pages */\n    return AvailablePages;\n}\n\n/**\n * Retrieves the highest physical page number (PFN) detected in the system.\n *\n * @return This routine returns the highest physical page number.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nMM::Pfn::GetHighestPhysicalPage(VOID)\n{\n    /* Return the highest physical page number */\n    return HighestPhysicalPage;\n}\n\n/**\n * Retrieves the total number of physical pages managed by the system.\n *\n * @return Returns the total count of physical memory pages.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nMM::Pfn::GetNumberOfPhysicalPages(VOID)\n{\n    /* Return the number of physical pages */\n    return NumberOfPhysicalPages;\n}\n\n/**\n * Retrieves a pointer to the PFN database entry for a given physical page.\n *\n * @param Pfn\n *        The Page Frame Number (PFN) to look up.\n *\n * @return This routine returns a pointer to the MMPFN structure for the given PFN, or NULLPTR if the PFN is invalid.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPFN\nMM::Pfn::GetPfnEntry(IN PFN_NUMBER Pfn)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Validate that the PFN is within the range of managed physical memory */\n    if(Pfn > HighestPhysicalPage)\n    {\n        /* The requested page number is outside the bounds, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Make sure this page has a PFN entry set */\n    if(PfnBitMap.Buffer && !RTL::BitMap::TestBit(&PfnBitMap, Pfn))\n    {\n        /* The requested page number is not set in the bitmap, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Get the memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Calculate the address of the PFN entry by indexing into the PFN database array and return it */\n    return &((PMMPFN)MemoryLayout->PfnDatabase)[Pfn];\n}\n\n/**\n * Increments the global count of available pages.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::IncrementAvailablePages(VOID)\n{\n    /* Increment the global count of available pages */\n    AvailablePages++;\n}\n\n/**\n * Initializes the PFN bitmap to track available physical memory.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::InitializePfnBitmap(VOID)\n{\n    PPHYSICAL_MEMORY_DESCRIPTOR PhysicalMemoryBlock;\n    XTSTATUS Status;\n    PVOID BitMap;\n    ULONG Index;\n\n    /* Retrieve the global physical memory descriptor block */\n    PhysicalMemoryBlock = MM::Manager::GetPhysicalMemoryBlock();\n    if(!PhysicalMemoryBlock)\n    {\n        /* Physical memory layout unavailable, kernel panic */\n        KE::Crash::Panic(0x7D, NumberOfPhysicalPages, LowestPhysicalPage, HighestPhysicalPage, 0x100);\n    }\n\n    /* Calculate the required bitmap size and allocate memory */\n    Status = MM::Allocator::AllocatePool(NonPagedPool,\n                                         (((HighestPhysicalPage + 1) + 31) / 32) * 4,\n                                         (PVOID *)&BitMap,\n                                         SIGNATURE32('M', 'M', 'g', 'r'));\n    if(Status != STATUS_SUCCESS || !BitMap)\n    {\n        /* Memory allocation failed, kernel panic */\n        DebugPrint(L\"Insufficient physical pages! Install additional memory\\n\");\n        KE::Crash::Panic(0x7D, NumberOfPhysicalPages, LowestPhysicalPage, HighestPhysicalPage, 0x101);\n    }\n\n    /* Initialize the PFN bitmap structure and clear all bits by default */\n    RTL::BitMap::InitializeBitMap(&PfnBitMap, (PULONG_PTR)BitMap, (ULONG)HighestPhysicalPage + 1);\n    RTL::BitMap::ClearAllBits(&PfnBitMap);\n\n    /* Iterate through all contiguous physical memory runs to populate the availability map */\n    for(Index = 0; Index < PhysicalMemoryBlock->NumberOfRuns; Index++)\n    {\n        /* Ensure the current memory run contains at least one valid page frame */\n        if((&PhysicalMemoryBlock->Run[Index])->PageCount)\n        {\n            /* Set the corresponding bits to mark these physical pages as available for allocation */\n            RtlSetBits(&PfnBitMap,\n                       (ULONG)(&PhysicalMemoryBlock->Run[Index])->BasePage,\n                       (ULONG)(&PhysicalMemoryBlock->Run[Index])->PageCount);\n        }\n    }\n}\n\n/**\n * Links a physical page to the appropriate free lists.\n *\n * @param PageFrameIndex\n *        The Page Frame Number (PFN) of the page to link.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::LinkFreePage(IN PFN_NUMBER PageFrameIndex)\n{\n    ULONG Color;\n    PMMPFNLIST ListHead;\n    PFN_NUMBER LastPage;\n    PMMPFN ColoredPfn, PfnEntry;\n    PMMCOLOR_TABLES ColorTable;\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Get the PFN database entry for the page */\n    PfnEntry = GetPfnEntry(PageFrameIndex);\n\n    /* Check if the page is part of a ROM image */\n    if(PfnEntry->u3.e1.Rom == 1)\n    {\n        /* Mark the page as inactive and clear its links */\n        PfnEntry->u1.Flink = 0;\n        PfnEntry->u3.e1.PageLocation = 0;\n\n        /* Do not free ROM pages */\n        return;\n    }\n\n    /* Check if the page is marked for removal */\n    if(PfnEntry->u3.e1.RemovalRequested == 1)\n    {\n        /* Update cache attribute to not mapped */\n        PfnEntry->u3.e1.CacheAttribute = PfnNotMapped;\n\n        /* Insert the page into the bad page list instead */\n        LinkPage(&BadPagesList, PageFrameIndex);\n\n        /* Do not add it to the free list */\n        return;\n    }\n\n    /* Insert the page into the global free list */\n    ListHead = &FreePagesList;\n    ListHead->Total++;\n\n    /* Get the current last page on the list */\n    LastPage = ListHead->Blink;\n\n    /* Check if the list is not empty */\n    if(LastPage != MAXULONG_PTR)\n    {\n        /* Link with the previous last page */\n        GetPfnEntry(LastPage)->u1.Flink = PageFrameIndex;\n    }\n    else\n    {\n        /* Put the page as the first entry */\n        ListHead->Flink = PageFrameIndex;\n    }\n\n    /* Set the page as the new tail of the list */\n    ListHead->Blink = PageFrameIndex;\n    PfnEntry->u1.Flink = MAXULONG_PTR;\n    PfnEntry->u2.Blink = LastPage;\n    PfnEntry->u3.e1.CacheAttribute = PfnNotMapped;\n    PfnEntry->u3.e1.PageLocation = FreePageList;\n    PfnEntry->u4.AweAllocation = 0;\n    PfnEntry->u4.InPageError = 0;\n    PfnEntry->u4.Priority = 3;\n\n    /* Insert the page into the colored free list */\n    Color = PageFrameIndex & MM::Colors::GetPagingColorsMask();\n    ColorTable = MM::Colors::GetFreePages(FreePageList, Color);\n\n    /* Get the memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Check if the colored list is empty */\n    if(ColorTable->Flink == MAXULONG_PTR)\n    {\n        /* Put the page as the first entry */\n        ColorTable->Flink = PageFrameIndex;\n        PfnEntry->u4.PteFrame = MM_PFN_PTE_FRAME;\n    }\n    else\n    {\n        /* Get the current last page on the colored list */\n        ColoredPfn = (PMMPFN)ColorTable->Blink;\n\n        /* Link with the previous last page */\n        MM::Paging::SetPte(&ColoredPfn->OriginalPte, PageFrameIndex);\n        PfnEntry->u4.PteFrame = ColoredPfn - (PMMPFN)MemoryLayout->PfnDatabase;\n    }\n\n    /* Set the page as the new tail of the colored list */\n    ColorTable->Blink = PfnEntry;\n    ColorTable->Count++;\n    MM::Paging::SetPte(&PfnEntry->OriginalPte, MAXULONG_PTR);\n\n    /* Increment number of available pages */\n    IncrementAvailablePages();\n}\n\n\n/**\n * Links a physical page to the appropriate list.\n *\n * @param ListHead\n *        Pointer to the list head.\n *\n * @param PageFrameIndex\n *        The Page Frame Number (PFN) of the page to link.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::LinkPage(IN PMMPFNLIST ListHead,\n                  IN PFN_NUMBER PageFrameIndex)\n{\n    PMMCOLOR_TABLES ColorHead;\n    MMPAGELISTS ListName;\n    PMMPFN PageFrame;\n\n    /* Get the memory layout */\n    PMMMEMORY_LAYOUT MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Get the PFN database entry for the target page */\n    PageFrame = &((PMMPFN)MemoryLayout->PfnDatabase)[PageFrameIndex];\n\n    /* Get the list name */\n    ListName = ListHead->ListName;\n\n    /* Handle pages being linked to the modified or standby lists */\n    if(ListName == ModifiedPageList || ListName == StandbyPageList)\n    {\n        /* Detect an invalid prototype/transition PTE state */\n        if(!MM::Paging::GetPteSoftwarePrototype(&PageFrame->OriginalPte) &&\n           MM::Paging::GetPteSoftwareTransition(&PageFrame->OriginalPte))\n        {\n            /* Crash system due to corrupted PFN/PTE state */\n            KE::Crash::Panic(0x1A, 0x8888, 0, 0, 0);\n        }\n    }\n\n    /* Check if the page is ROM */\n    if(PageFrame->u3.e1.Rom == 1)\n    {\n        /* Link the page to the ROM list */\n        ListHead = &RomPagesList;\n        ListHead->Total++;\n\n        /* Append the page to the end of the ROM list */\n        if(ListHead->Blink != MAXULONG_PTR)\n        {\n            /* Update the previous tail to point to this page */\n            (&((PMMPFN)MemoryLayout->PfnDatabase)[ListHead->Blink])->u1.Flink = PageFrameIndex;\n        }\n        else\n        {\n            /* Initialize the list if it was empty */\n            ListHead->Flink = PageFrameIndex;\n        }\n\n        /* Update list tail and PFN linkage */\n        ListHead->Blink = PageFrameIndex;\n        PageFrame->u1.Flink = MAXULONG_PTR;\n        PageFrame->u2.Blink = ListHead->Blink;\n        PageFrame->u3.e1.PageLocation = ListName;\n\n        /* ROM pages require no further processing */\n        return;\n    }\n\n    /* Account for the page being inserted into the target list */\n    ListHead->Total++;\n\n    /* Redirect modified pages to the per-color modified list */\n    if(ListHead == &ModifiedPagesList)\n    {\n        /* Select the modified list matching the page color */\n        ListHead = MM::Colors::GetModifiedPages(PageFrame->u3.e1.PageColor);\n        ListHead->Total++;\n    }\n    else if((PageFrame->u3.e1.RemovalRequested == 1) && (ListName <= StandbyPageList))\n    {\n        /* Undo the insertion into the current list */\n        ListHead->Total--;\n\n        /* Preserve the standby location for removed pages */\n        if(ListName == StandbyPageList)\n        {\n            /* Keep the page marked as standby */\n            PageFrame->u3.e1.PageLocation = StandbyPageList;\n        }\n\n        /* Mark the page as no longer cache-mapped */\n        PageFrame->u3.e1.CacheAttribute = PfnNotMapped;\n\n        /* Move the page to the bad page list */\n        ListHead = &BadPagesList;\n        ListHead->Total++;\n        ListName = BadPageList;\n    }\n\n    /* Insert zeroed pages at the head of the list */\n    if(ListName == ZeroedPageList)\n    {\n        /* Link the page as the new list head */\n        ListHead->Flink = PageFrameIndex;\n\n        /* Initialize PFN forward and backward links */\n        PageFrame->u1.Flink = ListHead->Flink;\n        PageFrame->u2.Blink = MAXULONG_PTR;\n\n        /* Update the previous head if it exists */\n        if(ListHead->Flink != MAXULONG_PTR)\n        {\n            /* Fix up the backward link of the old head */\n            (&((PMMPFN)MemoryLayout->PfnDatabase)[ListHead->Flink])->u2.Blink = PageFrameIndex;\n        }\n        else\n        {\n            /* Set the tail if the list was empty */\n            ListHead->Blink = PageFrameIndex;\n        }\n    }\n    else\n    {\n        /* Append the page to the tail of the list */\n        if(ListHead->Blink != MAXULONG_PTR)\n        {\n            /* Link the current tail to the new page */\n            (&((PMMPFN)MemoryLayout->PfnDatabase)[ListHead->Blink])->u1.Flink = PageFrameIndex;\n        }\n        else\n        {\n            /* Initialize the list if it was empty */\n            ListHead->Flink = PageFrameIndex;\n        }\n\n        /* Update list tail */\n        ListHead->Blink = PageFrameIndex;\n\n        /* Terminate PFN forward link and set backward link */\n        PageFrame->u1.Flink = MAXULONG_PTR;\n        PageFrame->u2.Blink = ListHead->Blink;\n    }\n\n    /* Record the page's current location */\n    PageFrame->u3.e1.PageLocation = ListName;\n\n    /* Handle pages that contribute to the available page count */\n    if(ListName <= StandbyPageList)\n    {\n        /* Increment the system-wide available page counter */\n        MM::Pfn::IncrementAvailablePages();\n\n        /* Select the free list matching the page color */\n        ColorHead = MM::Colors::GetFreePages(ZeroedPageList, PageFrameIndex & MM::Colors::GetPagingColorsMask());\n\n        /* Store the color list linkage in the original PTE */\n        MM::Paging::SetPte(&PageFrame->OriginalPte, ColorHead->Flink);\n        PageFrame->u4.PteFrame = MM_PFN_PTE_FRAME;\n\n        /* Insert the page into the color free list */\n        ColorHead->Flink = PageFrameIndex;\n\n        /* Update the previous head or initialize the tail */\n        if(ColorHead->Flink != MAXULONG_PTR)\n        {\n            /* Fix up the PTE frame of the previous entry */\n            (&((PMMPFN)MemoryLayout->PfnDatabase)[ColorHead->Flink])->u4.PteFrame = PageFrameIndex;\n        }\n        else\n        {\n            /* Set the tail for an empty color list */\n            ColorHead->Blink = (PVOID)PageFrame;\n        }\n\n        /* Increment the color list page count */\n        ColorHead->Count++;\n    }\n    else if(ListName == ModifiedPageList)\n    {\n        /* Modified page insertion logic not implemented yet */\n        UNIMPLEMENTED;\n    }\n    else if(ListName == ModifiedReadOnlyPageList)\n    {\n        /* Modified read-only page handling not implemented yet */\n        UNIMPLEMENTED;\n    }\n}\n\n/**\n * Links a PFN entry to its corresponding PTE and ensures the page table that contains the PTE is resident in memory.\n *\n * @param PageFrameIndex\n *        Supplies the index into the PFN database for the page being initialized.\n *\n * @param PointerPte\n *        Supplies the pointer to the PTE which maps the physical page.\n *\n * @param Modified\n *        Supplies a flag indicating if the page's initial state is modified.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::LinkPfn(IN PFN_NUMBER PageFrameIndex,\n                 IN PMMPTE PointerPte,\n                 IN BOOLEAN Modified)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n    XTSTATUS Status;\n    PMMPFN Pfn;\n    PMMPTE Pte;\n\n    /* Get the memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Point the PFN to its PTE */\n    Pfn = &((PMMPFN)MemoryLayout->PfnDatabase)[PageFrameIndex];\n    Pfn->PteAddress = PointerPte;\n\n    /* Check if the page is already mapped and in use */\n    if(MM::Paging::PteValid(PointerPte))\n    {\n        /* Clear the original PTE information */\n        MM::Paging::SetPte(&Pfn->OriginalPte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE);\n    }\n    else\n    {\n        /* Page is not resident, so save the PTE contents for later use */\n        Pfn->OriginalPte = *PointerPte;\n    }\n\n    /* Initialize the PFN database entry for this page */\n    Pfn->u2.ShareCount = 1;\n    Pfn->u3.e1.Modified = Modified;\n    Pfn->u3.e1.PageLocation = ActiveAndValid;\n    Pfn->u3.e2.ReferenceCount = 1;\n\n    /* Get the PDE that maps the page table containing this PTE */\n    Pte = MM::Paging::GetPteAddress(PointerPte);\n    if(!MM::Paging::PteValid(Pte))\n    {\n        /* Check if page table is resident */\n        Status = MM::PageFault::CheckPdeForPagedPool(PointerPte);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Could not make the page table resident, crash system */\n            KE::Crash::Panic(0x1A,\n                            (ULONG_PTR)0x61940,\n                            (ULONG_PTR)PointerPte,\n                            MM::Paging::GetPageFrameNumber(PointerPte),\n                            (ULONG_PTR)MM::Paging::GetPteVirtualAddress(PointerPte));\n        }\n    }\n\n    /* Record the page frame of the page table itself */\n    PageFrameIndex = MM::Paging::GetPageFrameNumber(Pte);\n    Pfn->u4.PteFrame = PageFrameIndex;\n\n    /* Pin the page table in memory by incrementing its PFN share count */\n    Pfn = &((PMMPFN)MemoryLayout->PfnDatabase)[PageFrameIndex];\n    Pfn->u2.ShareCount++;\n}\n\n/**\n * Initializes the PFN database entry for a physical page that is used as a page table.\n *\n * @param PageFrameIndex\n *        The page frame number of the physical page being used as a page table.\n *\n * @param PointerPte\n *        A pointer to the higher-level PTE that maps this page table page.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::LinkPfnForPageTable(IN PFN_NUMBER PageFrameIndex,\n                             IN PMMPTE PointerPte)\n{\n    PMMPFN Pfn;\n    PMMPDE PointerPde;\n    PVOID EndAddress;\n\n    /* Retrieve the PFN database entry for the physical page of the page table */\n    Pfn = GetPfnEntry(PageFrameIndex);\n\n    /* Calculate the end address of the PFN entry to ensure it's mapped */\n    EndAddress = (PUCHAR)(Pfn + 1) - 1;\n\n    /* Validate that the PFN entry corresponds to a valid, active physical page */\n    if((PageFrameIndex <= HighestPhysicalPage) && (MM::Pte::AddressValid(Pfn)) &&\n       (MM::Pte::AddressValid(EndAddress)) && (Pfn->u3.e1.PageLocation == ActiveAndValid))\n    {\n        /* Initialize the PFN entry for this page table page */\n        MM::Paging::SetPte(&Pfn->OriginalPte, MM::Paging::GetPte(PointerPte));\n        Pfn->PteAddress = PointerPte;\n        Pfn->u1.WsIndex = 0;\n        Pfn->u2.ShareCount++;\n        Pfn->u3.e1.CacheAttribute = PfnNonCached;\n        Pfn->u3.e1.PageLocation = ActiveAndValid;\n        Pfn->u3.e2.ReferenceCount = 1;\n        Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress(PointerPte));\n    }\n\n    /* Increment the share count of the parent page table that contains the mapping */\n    PointerPde = MM::Paging::GetPdeAddress(MM::Paging::GetPteVirtualAddress(PointerPte));\n    Pfn = GetPfnEntry(MM::Paging::GetPageFrameNumber(PointerPde));\n    Pfn->u2.ShareCount++;\n}\n\n/**\n * Links a PFN entry to its corresponding PTE and ensures the page table that contains the PTE is resident in memory.\n *\n * @param PageFrameIndex\n *        Supplies the index into the PFN database for the page being initialized.\n *\n * @param PointerPte\n *        Supplies the pointer to the PTE which maps the physical page.\n *\n * @param ParentFrame\n *        Supplies the page frame number of the page table that contains the PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::LinkPfnWithParent(IN PFN_NUMBER PageFrameIndex,\n                           IN PMMPTE PointerPte,\n                           IN PFN_NUMBER ParentFrame)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n    PMMPFN Pfn;\n\n    /* Get the memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Point the PFN to its PTE */\n    Pfn = &((PMMPFN)MemoryLayout->PfnDatabase)[PageFrameIndex];\n    Pfn->PteAddress = PointerPte;\n\n    /* Initialize the PTE */\n    MM::Paging::SetPte(&Pfn->OriginalPte, 0, MM_PTE_GUARDED);\n\n    /* Initialize the PFN entry */\n    Pfn->u2.ShareCount++;\n    Pfn->u3.e1.CacheAttribute = PfnCached;\n    Pfn->u3.e1.Modified = TRUE;\n    Pfn->u3.e1.PageLocation = ActiveAndValid;\n    Pfn->u3.e2.ReferenceCount++;\n    Pfn->u4.InPageError = FALSE;\n\n    /* Check if parent PTE frame exists */\n    if(ParentFrame)\n    {\n        /* Link the page table to its parent */\n        Pfn->u4.PteFrame = ParentFrame;\n\n        /* Get the PFN entry for parent PTE and increment share count */\n        Pfn = &((PMMPFN)MemoryLayout->PfnDatabase)[ParentFrame];\n        Pfn->u2.ShareCount++;\n    }\n}\n\n/**\n * Links a page to the beginning of the appropriate standby or ROM list.\n *\n * @param PageFrameIndex\n *        The Page Frame Number (PFN) of the page to link.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\n\nXTFASTCALL\nVOID\nMM::Pfn::LinkStandbyPage(IN PFN_NUMBER PageFrameIndex)\n{\n    PMMPFN AdjacentPageFrame, CurrentPageFrame;\n    PMMMEMORY_LAYOUT MemoryLayout;\n    PFN_NUMBER Flink;\n\n    /* Get the memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Get the PFN database entry for the target page */\n    CurrentPageFrame = &((PMMPFN)MemoryLayout->PfnDatabase)[PageFrameIndex];\n\n    /* Check if the page is part of a ROM image */\n    if(CurrentPageFrame->u3.e1.Rom == 1)\n    {\n        /* Increment the total number of ROM pages */\n        RomPagesList.Total++;\n\n        /* If the ROM list is not empty, link the new page */\n        if(RomPagesList.Blink != (ULONG_PTR)-1)\n        {\n            /* Update the old tail to point to the new page */\n            AdjacentPageFrame = &((PMMPFN)MemoryLayout->PfnDatabase)[RomPagesList.Blink];\n            AdjacentPageFrame->u1.Flink = PageFrameIndex;\n        }\n        else\n        {\n            /* Otherwise, this page is now the head of the list */\n            RomPagesList.Flink = PageFrameIndex;\n        }\n\n        /* Set the new page as the tail and update its links */\n        RomPagesList.Blink = PageFrameIndex;\n        CurrentPageFrame->u1.Flink = (ULONG_PTR)-1;\n        CurrentPageFrame->u2.Blink = RomPagesList.Blink;\n        CurrentPageFrame->u3.e1.PageLocation = StandbyPageList;\n\n        /* ROM pages require no further processing */\n        return;\n    }\n\n    /* Increment the count of pages on the standby list */\n    StandbyPagesList.Total++;\n\n    /* Save the old head and set the current page as the new head */\n    Flink = StandbyPagesList.Flink;\n    StandbyPagesList.Flink = PageFrameIndex;\n\n    /* Point the new head to the old one, marking it as the list front */\n    CurrentPageFrame->u1.Flink = Flink;\n    CurrentPageFrame->u2.Blink = MAXULONG_PTR;\n\n    /* If the ROM list is not empty, link the new page */\n    if(Flink != MAXULONG_PTR)\n    {\n        /* Update the old head to point to the new page */\n        AdjacentPageFrame = &((PMMPFN)MemoryLayout->PfnDatabase)[Flink];\n        AdjacentPageFrame->u2.Blink = PageFrameIndex;\n    }\n    else\n    {\n        /* Otherwise, this page is now the tail of the list */\n        StandbyPagesList.Blink = PageFrameIndex;\n    }\n\n    /* Update the page's location to the standby list */\n    CurrentPageFrame->u3.e1.PageLocation = StandbyPageList;\n\n    /* Increment number of available pages */\n    IncrementAvailablePages();\n}\n\n/**\n * Processes a memory descriptor and initializes the corresponding PFN database entries.\n *\n * @param BasePage\n *        The starting physical page number of the memory run.\n *\n * @param PageCount\n *        The number of pages in the memory run.\n *\n * @param MemoryType\n *        The type of memory as reported by the bootloader (e.g., free, ROM, in-use).\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::ProcessMemoryDescriptor(IN PFN_NUMBER BasePage,\n                                 IN PFN_NUMBER PageCount,\n                                 IN LOADER_MEMORY_TYPE MemoryType)\n{\n    PVOID VirtualAddress, VirtualRangeStart, VirtualRangeEnd;\n    PFN_NUMBER PageNumber;\n    PMMPDE PointerPde;\n    PMMPFN Pfn;\n\n    /* Check if the memory descriptor describes a free memory region */\n    if(MM::Manager::VerifyMemoryTypeFree(MemoryType))\n    {\n        /* Iterate over each page in this free memory run */\n        for(PageNumber = 0; PageNumber < PageCount; PageNumber++)\n        {\n            /* Get the PFN entry for the current page and ensure it is not referenced */\n            Pfn = GetPfnEntry(BasePage + PageNumber);\n            if(Pfn->u3.e2.ReferenceCount == 0)\n            {\n                /* Add the page to the free list to make it available for allocation */\n                LinkFreePage(BasePage + PageNumber);\n            }\n        }\n    }\n    else\n    {\n        /* Calculate the virtual address range for this physical memory region */\n        VirtualRangeStart = (PVOID)(KSEG0_BASE + (BasePage << MM_PAGE_SHIFT));\n        VirtualRangeEnd = (PVOID)(KSEG0_BASE + ((BasePage + PageCount) << MM_PAGE_SHIFT));\n\n        /* Handle all other (non-free) memory types */\n        switch(MemoryType)\n        {\n            case LoaderBad:\n                /* This memory is marked as bad and should not be used */\n                for(PageNumber = 0; PageNumber < PageCount; PageNumber++)\n                {\n                    /* Link the page to the bad pages list */\n                    LinkPage(&BadPagesList, BasePage + PageNumber);\n                }\n                break;\n            case LoaderXIPRom:\n                /* Get the page directory entry for the current page */\n                PointerPde = MM::Paging::GetPdeAddress(VirtualRangeStart);\n\n                /* Initialize the page directory entries covering this memory range */\n                InitializePageDirectory(PointerPde, MM::Paging::GetPdeAddress(VirtualRangeEnd));\n\n                /* This memory range contains Read-Only Memory (ROM) */\n                for(PageNumber = 0; PageNumber < PageCount; PageNumber++)\n                {\n                    /* Get the PFN entry for the current ROM page */\n                    Pfn = GetPfnEntry(BasePage + PageNumber);\n\n                    /* Ensure that the page is not already in-use */\n                    if(Pfn->u3.e2.ReferenceCount == 0)\n                    {\n                        /* Calculate the virtual address for this page */\n                        VirtualAddress = (PVOID)(KSEG0_BASE + ((BasePage + PageNumber) << MM_PAGE_SHIFT));\n                        PointerPde = MM::Paging::GetPdeAddress(VirtualAddress);\n\n                        /* Initialize the PFN entry to represent a ROM page */\n                        Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualAddress);\n                        Pfn->u1.Flink = 0;\n                        Pfn->u2.ShareCount = 0;\n                        Pfn->u3.e1.CacheAttribute = PfnCached;\n                        Pfn->u3.e1.PageLocation = 0;\n                        Pfn->u3.e1.PrototypePte = 1;\n                        Pfn->u3.e1.Rom = 1;\n                        Pfn->u3.e2.ReferenceCount = 0;\n                        Pfn->u4.InPageError = 0;\n                        Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(PointerPde);\n                    }\n                }\n                break;\n            default:\n                /* Get the page directory entry for the current page */\n                PointerPde = MM::Paging::GetPdeAddress(VirtualRangeStart);\n\n                /* Initialize the page directory entries covering this memory range */\n                InitializePageDirectory(PointerPde, MM::Paging::GetPdeAddress(VirtualRangeEnd));\n\n                /* All other types are considered in-use (ie, by the kernel, ACPI, etc) */\n                for(PageNumber = 0; PageNumber < PageCount; PageNumber++)\n                {\n                    /* Get the PFN entry for the current in-use page */\n                    Pfn = GetPfnEntry(BasePage + PageNumber);\n\n                    /* Ensure that the page is not already in-use */\n                    if(Pfn->u3.e2.ReferenceCount == 0)\n                    {\n                        /* Calculate the virtual address for this page */\n                        VirtualAddress = (PVOID)(KSEG0_BASE + ((BasePage + PageNumber) << MM_PAGE_SHIFT));\n                        PointerPde = MM::Paging::GetPdeAddress(VirtualAddress);\n\n                        /* Initialize the PFN entry to represent an in-use page and prevent it from being allocated */\n                        Pfn->PteAddress = MM::Paging::GetPteAddress(VirtualAddress);\n                        Pfn->u2.ShareCount++;\n                        Pfn->u3.e1.CacheAttribute = PfnCached;\n                        Pfn->u3.e1.PageLocation = ActiveAndValid;\n                        Pfn->u3.e2.ReferenceCount = 1;\n                        Pfn->u4.PteFrame = MM::Paging::GetPageFrameNumber(PointerPde);\n                    }\n                }\n                break;\n        }\n    }\n}\n\n/**\n * Scans memory descriptors provided by the boot loader.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pfn::ScanMemoryDescriptors(VOID)\n{\n    PLIST_ENTRY LoaderMemoryDescriptors, MemoryMappings;\n    PLOADER_MEMORY_DESCRIPTOR MemoryDescriptor;\n    PFN_NUMBER FreePages;\n\n    /* Initialize the highest and lowest physical page numbers */\n    HighestPhysicalPage = (ULONG_PTR)0;\n    LowestPhysicalPage = (ULONG_PTR)~0;\n\n    /* Initially, set number of free pages to 0 */\n    FreePages = 0;\n\n    /* Get the list head of memory descriptors */\n    LoaderMemoryDescriptors = KE::BootInformation::GetMemoryDescriptors();\n\n    /* Iterate through the memory descriptors */\n    MemoryMappings = LoaderMemoryDescriptors->Flink;\n    while(MemoryMappings != LoaderMemoryDescriptors)\n    {\n        /* Get the memory descriptor */\n        MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry);\n\n        /* Skip invisible or hardware cached memory regions */\n        if(MM::Manager::VerifyMemoryTypeInvisible(MemoryDescriptor->MemoryType) ||\n            (MemoryDescriptor->MemoryType == LoaderHardwareCachedMemory))\n        {\n            /* Move to the next descriptor and skip further processing */\n            MemoryMappings = MemoryMappings->Flink;\n            continue;\n        }\n\n        /* Count the number of physical pages, excluding bad memory */\n        if(MemoryDescriptor->MemoryType != LoaderBad)\n        {\n            /* Add the pages from this descriptor to the total count */\n            NumberOfPhysicalPages += MemoryDescriptor->PageCount;\n        }\n\n        /* Check if this physical page is the lowest one yet */\n        if(MemoryDescriptor->BasePage < LowestPhysicalPage)\n        {\n            /* Update the lowest physical page number found so far */\n            LowestPhysicalPage = MemoryDescriptor->BasePage;\n        }\n\n        /* Check if this physical page is the highest one yet */\n        if((MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) > HighestPhysicalPage)\n        {\n            /* Update the highest physical page number found so far */\n            HighestPhysicalPage = (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) - 1;\n        }\n\n        /* Identify the largest block of free memory */\n        if(MM::Manager::VerifyMemoryTypeFree(MemoryDescriptor->MemoryType))\n        {\n            /* Check if this free memory block is the largest one yet */\n            if(MemoryDescriptor->PageCount >= FreePages)\n            {\n                /* Update the largest free block size and save the descriptor */\n                FreePages = MemoryDescriptor->PageCount;\n                FreeDescriptor = MemoryDescriptor;\n            }\n        }\n\n        /* Get next memory descriptor */\n        MemoryMappings = MemoryMappings->Flink;\n    }\n\n    /* Ensure a free memory descriptor was found */\n    if(!FreeDescriptor)\n    {\n        /* No free memory available to bootstrap the system */\n        KE::Crash::Panic(0x7D, LowestPhysicalPage, HighestPhysicalPage, FreePages, 0x1);\n    }\n\n    /* Save a copy of the original free descriptor before it gets modified */\n    RTL::Memory::CopyMemory(&OriginalFreeDescriptor, FreeDescriptor, sizeof(LOADER_MEMORY_DESCRIPTOR));\n}\n\n/**\n * Unlinks a physical page from its corresponding list.\n *\n * @param PageIndex\n *        The Page Frame Number (PFN) of the page to unlink.\n *\n * @param Color\n *        The color of the page, used to find the correct colored list.\n *\n * @return This routine returns the PFN of the page that was unlinked.\n */\nXTAPI\nPFN_NUMBER\nMM::Pfn::UnlinkFreePage(IN PFN_NUMBER PageFrameIndex,\n                        IN ULONG Color)\n{\n    PMMPFN Pfn;\n    PMMPFNLIST PfnList;\n    MMPAGELISTS PageList;\n    ULONG NodeColor;\n    PMMCOLOR_TABLES ColorTable;\n    PFN_NUMBER NextPage, PrevPage;\n\n    /* Get the PFN database entry for the target page */\n    Pfn = GetPfnEntry(PageFrameIndex);\n\n    /* Identify which list the page belongs to (FreePageList or ZeroedPageList) */\n    PfnList = PageLocationList[Pfn->u3.e1.PageLocation];\n    PageList = PfnList->ListName;\n\n    /* Update the forward link of the previous page */\n    if(Pfn->u2.Blink != MAXULONG_PTR)\n    {\n        /* The page is not the head of the list; update the previous page's Flink */\n        GetPfnEntry(Pfn->u2.Blink)->u1.Flink = Pfn->u1.Flink;\n    }\n    else\n    {\n        /* This is the first page in the list; update the list head's Flink */\n        PfnList->Flink = Pfn->u1.Flink;\n    }\n\n    /* Update the backward link of the next page */\n    if(Pfn->u1.Flink != MAXULONG_PTR)\n    {\n        /* The page is not the tail of the list; update the next page's Blink */\n        GetPfnEntry(Pfn->u1.Flink)->u2.Blink = Pfn->u2.Blink;\n    }\n    else\n    {\n        /* This is the last page in the list; update the list head's Blink */\n        PfnList->Blink = Pfn->u2.Blink;\n    }\n\n    /* Get the first page on the color list */\n    ColorTable = MM::Colors::GetFreePages(PageList, Color);\n    NodeColor = Pfn->u3.e1.PageColor;\n    PrevPage = Pfn->u4.PteFrame;\n    NextPage = MM::Paging::GetPte(&Pfn->OriginalPte);\n\n    /* Decrement the count of pages for this specific color and total page count for this list */\n    ColorTable->Count--;\n    PfnList->Total--;\n\n    /* Update the forward link of the previous colored page */\n    if(PrevPage != MM_PFN_PTE_FRAME)\n    {\n        /* This is not the first page; update the previous page's Flink */\n        MM::Paging::SetPte(&GetPfnEntry(PrevPage)->OriginalPte, NextPage);\n    }\n    else\n    {\n        /* This was the first page; update the color table's Flink */\n        ColorTable->Flink = NextPage;\n    }\n\n    /* Update the backward link of the next colored page */\n    if (NextPage != MAXULONG_PTR)\n    {\n        /* This is not the last page; update the next page's Blink */\n        GetPfnEntry(NextPage)->u4.PteFrame = PrevPage;\n    }\n    else\n    {\n        /* This was the last page; update the color table's Blink */\n        ColorTable->Blink = (PVOID)PrevPage;\n    }\n\n    /* Clear the list pointers and flags, but preserve the color and cache attributes */\n    Pfn->u1.Flink = 0;\n    Pfn->u2.Blink = 0;\n    Pfn->u3.e1.CacheAttribute = PfnNotMapped;\n    Pfn->u3.e1.PageColor = NodeColor;\n    Pfn->u3.e2.ShortFlags = 0;\n\n    /* Decrement the global count of available pages */\n    DecrementAvailablePages();\n\n    /* Return the page that was just unlinked */\n    return PageFrameIndex;\n}\n"
  },
  {
    "path": "xtoskrnl/mm/pool.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/pool.cc\n * DESCRIPTION:     Memory Manager pool manager\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Decodes an obfuscated doubly-linked pool list pointer.\n *\n * @param Link\n *        Supplies the encoded list entry pointer to be decoded.\n *\n * @return This routine returns the valid, properly aligned list entry pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPLIST_ENTRY\nMM::Pool::DecodePoolLink(IN PLIST_ENTRY PoolLink)\n{\n    /* XOR the obfuscated pointer with the global pool cookie to reveal the true address */\n    return (PLIST_ENTRY)((ULONG_PTR)PoolLink ^ PoolSecureCookie);\n}\n\n/**\n * Determines the pool type for a given memory address.\n *\n * @param VirtualAddress\n *        Supplies a virtual address to determine the pool type for.\n *\n * @return This routine returns the determined pool type for the specified address.\n *\n * @since XT 1.0\n */\nXTAPI\nMMPOOL_TYPE\nMM::Pool::DeterminePoolType(IN PVOID VirtualAddress)\n{\n    PMMMEMORY_LAYOUT MemoryLayout;\n\n    /* Retrieve the memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Evaluate the virtual address against known pool boundaries */\n    if((VirtualAddress >= MemoryLayout->NonPagedPoolStart) &&\n       (VirtualAddress <= MemoryLayout->NonPagedPoolEnd))\n    {\n        /* Address belongs to the non-paged pool */\n        return NonPagedPool;\n    }\n    else if((VirtualAddress >= MemoryLayout->NonPagedExpansionPoolStart) &&\n            (VirtualAddress <= MemoryLayout->NonPagedExpansionPoolEnd))\n    {\n        /* Address belongs to the non-paged expansion pool */\n        return NonPagedPool;\n    }\n    else if((VirtualAddress >= MemoryLayout->PagedPoolStart) &&\n            (VirtualAddress <= MemoryLayout->PagedPoolEnd))\n    {\n        /* Address belongs to the paged pool */\n        return PagedPool;\n    }\n\n    /* Address does not belong to any known pool, kernel panic */\n    KE::Crash::Panic(0xC2, 0x42, (ULONG_PTR)VirtualAddress, 0, 0);\n\n    /* Return an invalid pool type to satisfy the compiler */\n    return (MMPOOL_TYPE)-1;\n}\n\n/**\n * Encodes a doubly-linked pool list pointer to mitigate pool corruption.\n *\n * @param Link\n *        Supplies the raw list entry pointer to be encoded.\n *\n * @return This routine returns the obfuscated list entry pointer.\n *\n * @since XT 1.0\n */\nXTAPI\nPLIST_ENTRY\nMM::Pool::EncodePoolLink(IN PLIST_ENTRY PoolLink)\n{\n    /* XOR the raw pointer with the global pool cookie to securely obfuscate it */\n    return (PLIST_ENTRY)((ULONG_PTR)PoolLink ^ PoolSecureCookie);\n}\n\n/**\n * Calculates the address of a pool block at a specific relative index.\n *\n * @param Header\n *        Supplies a pointer to the base pool header.\n *\n * @param Index\n *        Supplies the block index offset. This value can be negative to traverse backwards.\n *\n * @return This routine returns a pointer to the calculated pool header.\n *\n * @since XT 1.0\n */\nXTAPI\nPPOOL_HEADER\nMM::Pool::GetPoolBlock(IN PPOOL_HEADER Header, IN SSIZE_T Index)\n{\n    /* The destination block is located by advancing the base address by the specified index */\n    return (PPOOL_HEADER)((ULONG_PTR)Header + (Index * MM_POOL_BLOCK_SIZE));\n}\n\n/**\n * Retrieves the pool header associated with a given pool memory address.\n *\n * @param Memory\n *        Supplies a pointer to the allocated memory region of a pool block.\n *\n * @return This routine returns a pointer to the originating pool header.\n *\n * @since XT 1.0\n */\nXTAPI\nPPOOL_HEADER\nMM::Pool::GetPoolEntry(IN PVOID Memory)\n{\n    /* The structural header logically precedes the allocated memory region */\n    return (PPOOL_HEADER)((ULONG_PTR)Memory - sizeof(POOL_HEADER));\n}\n\n/**\n * Resolves the list entry structure embedded within a free pool block.\n *\n * @param Header\n *        Supplies a pointer to the pool header.\n *\n * @return This routine returns a pointer to the list entry directly following the header.\n *\n * @since XT 1.0\n */\nXTAPI\nPLIST_ENTRY\nMM::Pool::GetPoolFreeBlock(IN PPOOL_HEADER Header)\n{\n    /* Return the list entry pointer */\n    return (PLIST_ENTRY)((ULONG_PTR)Header + sizeof(POOL_HEADER));\n}\n\n/**\n * Retrieves a pointer to the adjacent contiguous pool block following the specified header.\n *\n * @param Header\n *        Supplies a pointer to the current pool header.\n *\n * @return This routine returns a pointer to the next pool header in memory.\n *\n * @since XT 1.0\n */\nXTAPI\nPPOOL_HEADER\nMM::Pool::GetPoolNextBlock(IN PPOOL_HEADER Header)\n{\n    /* The adjacent forward header is located exactly 'BlockSize' units ahead of the current block */\n    return (PPOOL_HEADER)((ULONG_PTR)Header + (Header->BlockSize * MM_POOL_BLOCK_SIZE));\n}\n\n/**\n * Retrieves a pointer to the adjacent contiguous pool block preceding the specified header.\n *\n * @param Header\n *        Supplies a pointer to the current pool header.\n *\n * @return This routine returns a pointer to the previous pool header in memory.\n *\n * @since XT 1.0\n */\nXTAPI\nPPOOL_HEADER\nMM::Pool::GetPoolPreviousBlock(IN PPOOL_HEADER Header)\n{\n    /* The adjacent backward header is located exactly 'PreviousSize' units behind the current block */\n    return (PPOOL_HEADER)((ULONG_PTR)Header - (Header->PreviousSize * MM_POOL_BLOCK_SIZE));\n}\n\n/**\n * Initializes the non-paged pool for memory allocator.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::InitializeNonPagedPool(VOID)\n{\n    PMMFREE_POOL_ENTRY FreePage, SetupPage;\n    PMMMEMORY_LAYOUT MemoryLayout;\n    ULONG Index;\n\n    /* Retrieve memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    /* Map PTEs for the non-paged pool */\n    MapNonPagedPool();\n\n    /* Iterate over the free page list heads */\n    for(Index = 0; Index < MM_MAX_FREE_PAGE_LIST_HEADS; Index++)\n    {\n        /* Initialize a free page list head */\n        RTL::LinkedList::InitializeListHead(&NonPagedPoolFreeList[Index]);\n    }\n\n    /* Take the first free page from the pool and set its size */\n    FreePage = (PMMFREE_POOL_ENTRY)MemoryLayout->NonPagedPoolStart;\n    FreePage->Size = MemoryLayout->NonPagedPoolSize;\n\n    /* Take number of pages in the pool */\n    Index = (ULONG)(MemoryLayout->NonPagedPoolSize - 1);\n    if(Index >= MM_MAX_FREE_PAGE_LIST_HEADS)\n    {\n        /* Number of pages exceeds the number of free page list heads */\n        Index = MM_MAX_FREE_PAGE_LIST_HEADS - 1;\n    }\n\n    /* Insert the first free page into the free page list */\n    RTL::LinkedList::InsertHeadList(&NonPagedPoolFreeList[Index], &FreePage->List);\n\n    /* Create a free page for each page in the pool */\n    SetupPage = FreePage;\n    for(Index = 0; Index < MemoryLayout->NonPagedPoolSize; Index++)\n    {\n        /* Initialize the owner for each page */\n        SetupPage->Owner = FreePage;\n        SetupPage = (PMMFREE_POOL_ENTRY)((ULONG_PTR)SetupPage + MM_PAGE_SIZE);\n    }\n\n    /* Store first and last allocated non-paged pool page */\n    NonPagedPoolFrameStart = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress(MemoryLayout->NonPagedPoolStart));\n    NonPagedPoolFrameEnd = MM::Paging::GetPageFrameNumber(MM::Paging::GetPteAddress(MemoryLayout->NonPagedPoolEnd));\n\n    /* Initialize system PTE pool for the non-paged expansion pool */\n    Pte::InitializeSystemPtePool(Paging::GetNextPte(Paging::GetPteAddress(MemoryLayout->NonPagedExpansionPoolStart)),\n                                                                          MemoryLayout->NonPagedExpansionPoolSize - 2,\n                                                                          NonPagedPoolExpansion);\n\n    /* Store non-paged pool descriptor in the pool vector and initialize it */\n    PoolVector[NonPagedPool] = &NonPagedPoolDescriptor;\n    InitializePoolDescriptor(PoolVector[NonPagedPool], NonPagedPool, 0, 0, NULLPTR);\n}\n\n/**\n * Initializes the non-paged pool for memory allocator.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::InitializePagedPool(VOID)\n{\n    UNIMPLEMENTED;\n}\n\n/**\n * Initializes a pool descriptor used by the memory manager.\n *\n * @param Descriptor\n *        Supplies a pointer to the pool descriptor structure to be initialized.\n *\n * @param PoolType\n *        Specifies the type of memory pool that will be managed by the descriptor.\n *\n * @param Index\n *        Supplies the zero-based index of the descriptor within the pool vector.\n *\n * @param Threshold\n *        Specifies the allocation threshold that dictates when the pool should expand.\n *\n * @param LockAddress\n *        Supplies a pointer to the synchronization primitive that will serialize access to this descriptor. *\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::InitializePoolDescriptor(IN PPOOL_DESCRIPTOR Descriptor,\n                                   IN MMPOOL_TYPE PoolType,\n                                   IN ULONG Index,\n                                   IN ULONG Threshold,\n                                   IN PVOID LockAddress)\n{\n    PLIST_ENTRY LastEntry, ListEntry;\n\n    /* Populate the core attributes of the descriptor */\n    Descriptor->LockAddress = LockAddress;\n    Descriptor->PoolIndex = Index;\n    Descriptor->PoolType = PoolType;\n    Descriptor->Threshold = Threshold;\n\n    /* Clear the deferred free list */\n    Descriptor->PendingFrees = NULLPTR;\n    Descriptor->PendingFreeDepth = 0;\n\n    /* Zero out the runtime accounting and statistical tracking counters */\n    Descriptor->RunningAllocations = 0;\n    Descriptor->RunningFrees = 0;\n    Descriptor->TotalBigAllocations = 0;\n    Descriptor->TotalBytes = 0;\n    Descriptor->TotalPages = 0;\n\n    /* Establish the iteration boundaries */\n    ListEntry = Descriptor->ListHeads;\n    LastEntry = ListEntry + MM_POOL_LISTS_PER_PAGE;\n\n    /* Traverse and initialize all block list heads */\n    while(ListEntry < LastEntry)\n    {\n        /* Initialize the empty list head */\n        InitializePoolListHead(ListEntry);\n        ListEntry++;\n    }\n}\n\n/**\n * Initializes a doubly-linked pool list head with encoded pointers.\n *\n * @param ListHead\n *        Supplies a pointer to the pool list head that is to be initialized.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::InitializePoolListHead(IN PLIST_ENTRY ListHead)\n{\n    PLIST_ENTRY ListEntry;\n\n    /* Obfuscate the list head address and establish the empty circular linkage */\n    ListEntry = EncodePoolLink(ListHead);\n    ListHead->Flink = ListEntry;\n    ListHead->Blink = ListEntry;\n}\n\n/**\n * Initializes the memory pool security mechanisms.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::InitializePoolSecurity(VOID)\n{\n    UNIMPLEMENTED;\n\n    /* Initialize the global pool cookie using a hard-coded value */\n    PoolSecureCookie = 0xDEADC0DE;\n}\n\n/**\n * Inserts a pool entry at the head of a doubly-linked pool list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the pool list.\n *\n * @param Entry\n *        Supplies a pointer to the pool list entry to be inserted.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::InsertPoolHeadList(IN PLIST_ENTRY ListHead,\n                             IN PLIST_ENTRY Entry)\n{\n    PLIST_ENTRY Flink;\n\n    /* Validate the pool list structure */\n    VerifyPoolLinks(ListHead);\n\n    /* Resolve the current forward link of the list head */\n    Flink = DecodePoolLink(ListHead->Flink);\n\n    /* Securely insert the new entry at the beginning of the pool list */\n    Entry->Blink = EncodePoolLink(ListHead);\n    Entry->Flink = EncodePoolLink(Flink);\n    Flink->Blink = EncodePoolLink(Entry);\n    ListHead->Flink = EncodePoolLink(Entry);\n\n    /* Re-validate the pool list structure */\n    VerifyPoolLinks(ListHead);\n}\n\n/**\n * Inserts a pool entry at the tail of a doubly-linked pool list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the pool list.\n *\n * @param Entry\n *        Supplies a pointer to the pool list entry to be inserted.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::InsertPoolTailList(IN PLIST_ENTRY ListHead,\n                             IN PLIST_ENTRY Entry)\n{\n    PLIST_ENTRY Blink;\n\n    /* Validate the pool list structure */\n    VerifyPoolLinks(ListHead);\n\n    /* Securely link the new entry at the end of the pool list */\n    Blink = DecodePoolLink(ListHead->Blink);\n    Blink->Flink = EncodePoolLink(Entry);\n    Entry->Blink = EncodePoolLink(Blink);\n    Entry->Flink = EncodePoolLink(ListHead);\n    ListHead->Blink = EncodePoolLink(Entry);\n\n    /* Re-validate the pool list structure */\n    VerifyPoolLinks(ListHead);\n}\n\n/**\n * Determines whether a given doubly-linked pool list is empty.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the pool list to be evaluated.\n *\n * @return This routine returns TRUE if the pool list is empty, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Pool::PoolListEmpty(IN PLIST_ENTRY ListHead)\n{\n    /* Evaluate whether the pool list contains no valid entries */\n    return (DecodePoolLink(ListHead->Flink) == ListHead);\n}\n\n/**\n * Removes a specific pool entry from a doubly-linked pool list.\n *\n * @param Entry\n *        Supplies a pointer to the pool list entry to be removed.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::RemovePoolEntryList(IN PLIST_ENTRY Entry)\n{\n    PLIST_ENTRY Blink, Flink;\n\n    /* Resolve the adjacent forward and backward links */\n    Blink = DecodePoolLink(Entry->Blink);\n    Flink = DecodePoolLink(Entry->Flink);\n\n    /* Securely link the adjacent nodes together */\n    Blink->Flink = EncodePoolLink(Flink);\n    Flink->Blink = EncodePoolLink(Blink);\n}\n\n/**\n * Removes the first entry from a doubly-linked pool list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the pool list.\n *\n * @return This routine returns a pointer to the removed pool list entry.\n *\n * @since XT 1.0\n */\nXTAPI\nPLIST_ENTRY\nMM::Pool::RemovePoolHeadList(IN PLIST_ENTRY ListHead)\n{\n    PLIST_ENTRY Entry, Flink;\n\n    /* Securely unlink the first entry from the pool list */\n    Entry = DecodePoolLink(ListHead->Flink);\n    Flink = DecodePoolLink(Entry->Flink);\n    Flink->Blink = EncodePoolLink(ListHead);\n    ListHead->Flink = EncodePoolLink(Flink);\n\n    /* Return the removed pool list entry */\n    return Entry;\n}\n\n/**\n * Removes the last entry from a doubly-linked pool list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the pool list.\n *\n * @return This routine returns a pointer to the removed pool list entry.\n *\n * @since XT 1.0\n */\nPLIST_ENTRY\nXTAPI\nMM::Pool::RemovePoolTailList(IN PLIST_ENTRY ListHead)\n{\n    PLIST_ENTRY Blink, Entry;\n\n    /* Securely unlink the last entry from the pool list */\n    Entry = DecodePoolLink(ListHead->Blink);\n    Blink = DecodePoolLink(Entry->Blink);\n    Blink->Flink = EncodePoolLink(ListHead);\n    ListHead->Blink = EncodePoolLink(Blink);\n\n    /* Return the removed pool list entry */\n    return Entry;\n}\n\n/**\n * Verifies the structural integrity of all pool blocks residing on a specific page.\n *\n * @param Block\n *        Supplies a pointer to the specific pool block.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::VerifyPoolBlocks(IN PVOID Block)\n{\n    PPOOL_HEADER Entry;\n    BOOLEAN FoundBlock;\n    SIZE_T Size;\n\n    /* Initialize tracking variables */\n    FoundBlock = FALSE;\n    Size = 0;\n\n    /* Resolve the first pool header */\n    Entry = (PPOOL_HEADER)PAGE_ALIGN(Block);\n\n    /* Iterate through all contiguous pool allocations */\n    do\n    {\n        /* Validate the current pool header */\n        VerifyPoolHeader(Entry);\n\n        /* Check if the current header corresponds to the target block */\n        if(Entry == Block)\n        {\n            /* Mark the block as found */\n            FoundBlock = TRUE;\n        }\n\n        /* Accumulate the total block size and advance to the next entry */\n        Size += Entry->BlockSize;\n        Entry = GetPoolNextBlock(Entry);\n    }\n    while((Size < (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)) && (PAGE_ALIGN(Entry) != Entry));\n\n    /* Ensure the block was found and the total size is aligned with the page */\n    if(!FoundBlock || (PAGE_ALIGN(Entry) != Entry) || (Size != (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)))\n    {\n        /* Pool blocks corruption detected, kernel panic */\n        KE::Crash::Panic(0x19, 10, (ULONG_PTR)Block, (ULONG_PTR)Entry, FoundBlock);\n    }\n}\n\n/**\n * Verifies the structural and spatial invariants of a specific pool header.\n *\n * @param Entry\n *        Supplies a pointer to the pool header to be verified.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::VerifyPoolHeader(IN PPOOL_HEADER Entry)\n{\n    PPOOL_HEADER PreviousEntry, NextEntry;\n\n    /* Verify that the current block header is valid */\n    if(!Entry->BlockSize)\n    {\n        /* Invalid block header size, kernel panic */\n        KE::Crash::Panic(0x19, 8, (ULONG_PTR)Entry->PreviousSize, Entry->BlockSize, (ULONG_PTR)Entry);\n    }\n\n    /* Verify that the previous block header is valid */\n    if(Entry->PreviousSize)\n    {\n        /* Resolve the previous block header */\n        PreviousEntry = GetPoolPreviousBlock(Entry);\n\n        /* Check if both adjacent blocks are within the same memory page */\n        if(PAGE_ALIGN(Entry) != PAGE_ALIGN(PreviousEntry))\n        {\n            /* Adjacent blocks are not on the same page, kernel panic */\n            KE::Crash::Panic(0x19, 6, (ULONG_PTR)PreviousEntry, (ULONG_PTR)PAGE_ALIGN(Entry), (ULONG_PTR)Entry);\n        }\n\n        /* Check the actual size of the previous block */\n        if(PreviousEntry->BlockSize != Entry->PreviousSize)\n        {\n            /* Block size mismatch, kernel panic */\n            KE::Crash::Panic(0x19, 5, (ULONG_PTR)PreviousEntry, (ULONG_PTR)Entry->PreviousSize, (ULONG_PTR)Entry);\n        }\n    }\n    else if(PAGE_ALIGN(Entry) != Entry)\n    {\n        /* Not aligned to a page boundary, kernel panic */\n        KE::Crash::Panic(0x19, 7, 0, (ULONG_PTR)PAGE_ALIGN(Entry), (ULONG_PTR)Entry);\n    }\n\n    /* Resolve the next block header */\n    NextEntry = GetPoolNextBlock(Entry);\n\n    /* Verify the next block header */\n    if(PAGE_ALIGN(NextEntry) != NextEntry)\n    {\n        /* Check if both adjacent blocks are within the same memory page */\n        if(PAGE_ALIGN(Entry) != PAGE_ALIGN(NextEntry))\n        {\n            /* Adjacent blocks are not on the same page, kernel panic */\n            KE::Crash::Panic(0x19, 9, (ULONG_PTR)NextEntry, (ULONG_PTR)PAGE_ALIGN(Entry), (ULONG_PTR)Entry);\n        }\n\n        /* Check the previous block size */\n        if(NextEntry->PreviousSize != Entry->BlockSize)\n        {\n            /* Block size mismatch, kernel panic */\n            KE::Crash::Panic(0x19, 5, (ULONG_PTR)NextEntry, NextEntry->PreviousSize, (ULONG_PTR)Entry);\n        }\n    }\n}\n\n/**\n * Validates the structural integrity of a doubly-linked pool list.\n *\n * @param ListHead\n *        Supplies a pointer to the pool list head that is to be validated.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::VerifyPoolLinks(IN PLIST_ENTRY ListHead)\n{\n    /* Validate the doubly-linked list invariants */\n    if((DecodePoolLink(DecodePoolLink(ListHead->Blink)->Flink) != ListHead) ||\n       (DecodePoolLink(DecodePoolLink(ListHead->Flink)->Blink) != ListHead))\n    {\n        /* Pool corruption detected, raise kernel panic */\n        KE::Crash::Panic(0x19,\n                         3,\n                         (ULONG_PTR)ListHead,\n                         (ULONG_PTR)DecodePoolLink(DecodePoolLink(ListHead->Blink)->Flink),\n                         (ULONG_PTR)DecodePoolLink(DecodePoolLink(ListHead->Flink)->Blink));\n    }\n}\n\n/**\n * Validates the run level for the specified pool. If the run level is invalid, the kernel panics.\n *\n * @param PoolType\n *        Supplies the pool type.\n *\n * @param Bytes\n *        Supplies the size of the allocation.\n *\n * @param Entry\n *        Supplies a pointer to the allocation entry.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pool::VerifyRunLevel(IN MMPOOL_TYPE PoolType,\n                         IN SIZE_T Bytes,\n                         IN PVOID Entry)\n{\n    KRUNLEVEL RunLevel;\n\n    /* Get current run level */\n    RunLevel = KE::RunLevel::GetCurrentRunLevel();\n\n    /* Validate run level */\n    if((PoolType & MM_POOL_TYPE_MASK) == PagedPool)\n    {\n        /* Paged pool runs up to APC level */\n        if(RunLevel <= APC_LEVEL)\n        {\n            /* Run level is valid */\n            return;\n        }\n    }\n    else\n    {\n        /* Non-paged pool runs up to DISPATCH_LEVEL */\n        if(RunLevel <= DISPATCH_LEVEL)\n        {\n            /* Run level is valid */\n            return;\n        }\n    }\n\n    /* Invalid run level for specified pool, raise kernel panic */\n    KE::Crash::Panic(0xC2,\n                     (Entry ? MM_POOL_INVALID_FREE_RUNLEVEL : MM_POOL_INVALID_ALLOC_RUNLEVEL),\n                     RunLevel,\n                     PoolType,\n                     (Entry ? (ULONG_PTR)Entry : Bytes));\n}\n"
  },
  {
    "path": "xtoskrnl/mm/pte.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/mm/pte.cc\n * DESCRIPTION:     Page Table Entry (PTE) support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Finds a free cluster of system PTEs that can satisfy a given size.\n *\n * @param NumberOfPtes\n *        The number of contiguous PTEs required.\n *\n * @param SystemPtePoolType\n *        Specifies the system PTE pool to search within.\n *\n * @param FoundCluster\n *        On success, receives a pointer to the first PTE of the found cluster.\n *\n * @param PreviousClusterNode\n *        On success, receives a pointer to the list node that precedes the found cluster.\n *\n * @return This routine returns TRUE if a suitable cluster was found, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nMM::Pte::FindFreeCluster(IN PFN_COUNT NumberOfPtes,\n                         IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,\n                         OUT PMMPTE *FoundCluster,\n                         OUT PMMPTE *PreviousClusterNode)\n{\n    PMMPTE CurrentCluster;\n    PMMPTE PreviousNode = &FirstSystemFreePte[SystemPtePoolType];\n    ULONG ClusterSize;\n\n    /* Find a free PTE cluster large enough for the request */\n    while(MM::Paging::GetNextEntry(PreviousNode) != MAXULONG)\n    {\n        /* Retrieve the cluster and its size */\n        CurrentCluster = MM::Paging::AdvancePte(SystemPteBase, MM::Paging::GetNextEntry(PreviousNode));\n        ClusterSize = GetClusterSize(CurrentCluster);\n\n        /* Check if this cluster is large enough */\n        if(NumberOfPtes <= ClusterSize)\n        {\n            /* Found a suitable cluster */\n            *FoundCluster = CurrentCluster;\n            *PreviousClusterNode = PreviousNode;\n            return TRUE;\n        }\n\n        /* This cluster is too small, check the next one */\n        PreviousNode = CurrentCluster;\n    }\n\n    /* No suitable cluster was found */\n    return FALSE;\n}\n\n/**\n * Decodes and returns the size of a free PTE cluster.\n *\n * @param Pte\n *        Supplies a pointer to the first PTE of the free cluster to inspect.\n *\n * @return This routine returns the total number of contiguous PTEs in the free cluster.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nMM::Pte::GetClusterSize(IN PMMPTE Pte)\n{\n    /* A special flag in the first PTE indicates a free cluster of size one */\n    if(MM::Paging::GetOneEntry(Pte))\n    {\n        /* Flag is set, so the cluster size is 1 by definition */\n        return 1;\n    }\n\n    /* For larger clusters, the size is encoded in the second PTE of the block */\n    Pte = MM::Paging::GetNextPte(Pte);\n    return MM::Paging::GetNextEntry(Pte);\n}\n\n/**\n * Calculates the number of Page Table Entries (PTEs) that fit within a single page.\n *\n * @return This routine returns the number of PTEs per page.\n *\n * @since XT 1.0\n */\nXTAPI\nPFN_COUNT\nMM::Pte::GetPtesPerPage(VOID)\n{\n    /* Calculate and return the number of PTEs per page */\n    return MM_PAGE_SIZE / MM::Paging::GetPteSize();\n}\n\n/**\n * Returns a pointer to the valid PTE.\n *\n * @return This routine returns a pointer to the valid PTE.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::Pte::GetValidPte()\n{\n    /* Return a pointer to the valid PTE */\n    return &ValidPte;\n}\n\n/**\n * Initializes the system's PTE.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::InitializeSystemPte(VOID)\n{\n    /* Initialize the PTE template */\n    MM::Paging::SetPte(&ValidPte, MM_PTE_VALID | MM_PTE_EXECUTE_READWRITE | MM_PTE_DIRTY | MM_PTE_ACCESSED);\n}\n\n/**\n * Formats a range of PTEs into a freelist-based pool for system allocations.\n *\n * @param StartingPte\n *        Supplies a pointer to the start of the PTE range to be formatted.\n *\n * @param NumberOfPtes\n *        Supplies the total number of PTEs in the contiguous range.\n *\n * @param PoolType\n *        The system PTE pool type that this range will be used for.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::InitializeSystemPtePool(IN PMMPTE StartingPte,\n                                 IN PFN_COUNT NumberOfPtes,\n                                 IN MMSYSTEM_PTE_POOL_TYPE PoolType)\n{\n    /* Set the system PTE base address */\n    SystemPteBase = GetSystemPteBaseAddress();\n\n    /* Record the boundaries of this new PTE pool */\n    SystemPtesStart[PoolType] = StartingPte;\n    SystemPtesEnd[PoolType] = MM::Paging::AdvancePte(StartingPte, NumberOfPtes - 1);\n\n    /* Zero the memory for the new PTE pool before use */\n    RTL::Memory::ZeroMemory(StartingPte, NumberOfPtes * MM::Paging::GetPteSize());\n\n    /* Build the free list head to point to the start of the pool */\n    MM::Paging::SetNextEntry(StartingPte, MAXULONG);\n    MM::Paging::ClearPte(&FirstSystemFreePte[PoolType]);\n    MM::Paging::SetNextEntry(&FirstSystemFreePte[PoolType], MM::Paging::GetPteDistance(StartingPte, SystemPteBase));\n\n    /* Use the second PTE slot to store the total size of this pool */\n    StartingPte = MM::Paging::GetNextPte(StartingPte);\n    MM::Paging::ClearPte(StartingPte);\n    MM::Paging::SetNextEntry(StartingPte, NumberOfPtes);\n\n    /* Record the total number of free PTEs in this pool */\n    TotalSystemFreePtes[PoolType] = NumberOfPtes;\n}\n\n/**\n * Sets up the entire system PTE address space.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::InitializeSystemPteSpace(VOID)\n{\n    PMMPTE PointerPte;\n    PMMPTE FirstZeroingPte;\n    PMMMEMORY_LAYOUT MemoryLayout;\n    ULONGLONG NonPagedSystemPoolEnd;\n\n    /* Retrieve the system's memory layout */\n    MemoryLayout = MM::Manager::GetMemoryLayout();\n\n    NonPagedSystemPoolEnd = ((ULONGLONG)MemoryLayout->NonPagedSystemPoolStart +\n                             MM::Manager::GetNumberOfSystemPtes() * MM_PAGE_SIZE);\n\n    /* Map the page table hierarchy for the entire system PTE space */\n    MM::Pte::MapPPE(MemoryLayout->NonPagedSystemPoolStart, (PVOID)NonPagedSystemPoolEnd, &ValidPte);\n    MM::Pte::MapPDE(MemoryLayout->NonPagedSystemPoolStart, (PVOID)NonPagedSystemPoolEnd, &ValidPte);\n\n    /* Format the main block of system PTEs into a free list pool */\n    PointerPte = MM::Paging::GetPteAddress(MemoryLayout->NonPagedSystemPoolStart);\n\n    InitializeSystemPtePool(PointerPte, MM::Manager::GetNumberOfSystemPtes(), SystemPteSpace);\n\n    /* Reserve and zero a dedicated block of system PTEs */\n    FirstZeroingPte = ReserveSystemPtes(MM_RESERVED_ZERO_PTES + 1, SystemPteSpace);\n    RTL::Memory::ZeroMemory(FirstZeroingPte, (MM_RESERVED_ZERO_PTES + 1) * MM::Paging::GetPteSize());\n\n    /* Use the first PTE of this block as a counter for available zeroing PTEs */\n    MM::Paging::SetPte(FirstZeroingPte, MM_RESERVED_ZERO_PTES, 0);\n}\n\n/**\n * Maps a range of virtual addresses at the PDE (Page Directory Entry) level.\n *\n * @param StartAddress\n *        The beginning of the virtual address range to map.\n *\n * @param EndAddress\n *        The end of the virtual address range to map.\n *\n * @param TemplatePde\n *        A template PDE to use for creating new entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::MapPDE(IN PVOID StartAddress,\n                IN PVOID EndAddress,\n                IN PMMPDE TemplatePde)\n{\n    PMMPDE EndSpace, PointerPde;\n\n    /* Get PDE addresses */\n    PointerPde = MM::Paging::GetPdeAddress(StartAddress);\n    EndSpace = MM::Paging::GetPdeAddress(EndAddress);\n\n    /* Iterate over all PDEs */\n    while(PointerPde <= EndSpace)\n    {\n        /* Check if PDE is already mapped */\n        if(!MM::Paging::PteValid(PointerPde))\n        {\n            /* Map PDE */\n            MM::Paging::SetPte(TemplatePde, MM::Pfn::AllocateBootstrapPages(1), 0);\n            MM::Paging::WritePte(PointerPde, *TemplatePde);\n\n            /* Clear the page table */\n            RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPde), MM_PAGE_SIZE);\n        }\n\n        /* Get next table entry */\n        PointerPde = MM::Paging::GetNextPte(PointerPde);\n    }\n}\n\n/**\n * Maps a range of virtual addresses at the PTE (Page Table Entry) level.\n *\n * @param StartAddress\n *        The beginning of the virtual address range to map.\n *\n * @param EndAddress\n *        The end of the virtual address range to map.\n *\n * @param TemplatePte\n *        A template PTE to use for creating new entries.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::MapPTE(IN PVOID StartAddress,\n                IN PVOID EndAddress,\n                IN PMMPTE TemplatePte)\n{\n    PMMPTE EndSpace, PointerPte;\n\n    /* Get PTE addresses */\n    PointerPte = MM::Paging::GetPteAddress(StartAddress);\n    EndSpace = MM::Paging::GetPteAddress(EndAddress);\n\n    /* Iterate over all PTEs */\n    while(PointerPte <= EndSpace)\n    {\n        /* Check if PTE is already mapped */\n        if(!MM::Paging::PteValid(PointerPte))\n        {\n            /* Map PTE */\n            MM::Paging::SetPte(TemplatePte, MM::Pfn::AllocateBootstrapPages(1), 0);\n            MM::Paging::WritePte(PointerPte, *TemplatePte);\n\n            /* Clear the page table */\n            RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(PointerPte), MM_PAGE_SIZE);\n        }\n\n        /* Get next table entry */\n        PointerPte = MM::Paging::GetNextPte(PointerPte);\n    }\n}\n\n\n/**\n * Releases a block of system PTEs into a specified pool.\n *\n * @param StartingPte\n *        A pointer to the first PTE to release.\n *\n * @param NumberOfPtes\n *        The number of contiguous PTEs to release.\n *\n * @param SystemPtePoolType\n *        Specifies the system PTE pool to release into.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nMM::Pte::ReleaseSystemPtes(IN PMMPTE StartingPte,\n                           IN PFN_COUNT NumberOfPtes,\n                           IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)\n{\n    PMMPTE NextPte, PreviousPte, ReleasedPte;\n    ULONG ClusterSize;\n\n    /* Clear the PTEs before releasing them */\n    RtlZeroMemory(StartingPte, NumberOfPtes * MM::Paging::GetPteSize());\n\n    /* Raise runlevel and acquire lock to protect the PTE pool */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);\n\n    /* Increment the total number of available PTEs in this pool */\n    TotalSystemFreePtes[SystemPtePoolType] += NumberOfPtes;\n\n    /* Start at the head of the free list for this pool */\n    PreviousPte = &FirstSystemFreePte[SystemPtePoolType];\n    ReleasedPte = NULLPTR;\n\n    /* Iterate through the free list to find adjacent blocks */\n    while(MM::Paging::GetNextEntry(PreviousPte) != MAXULONG)\n    {\n        /* Get the next free cluster to check its size */\n        NextPte = MM::Paging::AdvancePte(SystemPteBase, MM::Paging::GetNextEntry(PreviousPte));\n        ClusterSize = GetClusterSize(NextPte);\n\n        /* Check if the released block is adjacent to the current free block */\n        if((MM::Paging::AdvancePte(NextPte, ClusterSize) == StartingPte) ||\n           (MM::Paging::AdvancePte(StartingPte, NumberOfPtes) == NextPte))\n        {\n            /* Merge the blocks by adding their sizes */\n            NumberOfPtes += ClusterSize;\n\n            /* Check if the current free block is before the released block */\n            if(NextPte < StartingPte)\n            {\n                /* The new merged block starts at the current free block's address */\n                StartingPte = NextPte;\n            }\n\n            /* Unlink the current free block as it is being merged */\n            MM::Paging::SetNextEntry(PreviousPte, MM::Paging::GetNextEntry(NextPte));\n\n            /* Check if the block represents more than one PTE */\n            if(!MM::Paging::GetOneEntry(NextPte))\n            {\n                /* Clear block header and move to the size PTE */\n                MM::Paging::ClearPte(NextPte);\n                NextPte = MM::Paging::GetNextPte(NextPte);\n            }\n\n            /* Clear the merged block */\n            MM::Paging::ClearPte(NextPte);\n\n            /* Reset insertion point since block size/address changed due to merge */\n            ReleasedPte = NULLPTR;\n        }\n        else\n        {\n            /* Select the first free block large enough as insertion point */\n            if((ReleasedPte == NULLPTR) && (NumberOfPtes <= ClusterSize))\n            {\n                /* Mark this as the insertion point */\n                ReleasedPte = PreviousPte;\n            }\n\n            /* Advance to the next free block */\n            PreviousPte = NextPte;\n        }\n    }\n\n    /* Check if there is only one PTE to release */\n    if(NumberOfPtes == 1)\n    {\n        /* Mark it as a single-PTE block */\n        MM::Paging::SetOneEntry(StartingPte, 1);\n    }\n    else\n    {\n        /* Otherwise, mark it as a multi-PTE block */\n        MM::Paging::SetOneEntry(StartingPte, 0);\n\n        /* The next PTE stores the size of the block */\n        NextPte = MM::Paging::GetNextPte(StartingPte);\n        MM::Paging::SetNextEntry(NextPte, NumberOfPtes);\n    }\n\n    /* Check if no suitable insertion point was found */\n    if(ReleasedPte == NULLPTR)\n    {\n        /* Insert at the end of the list */\n        ReleasedPte = PreviousPte;\n    }\n\n    /* Link the new block into the free list */\n    MM::Paging::SetNextEntry(StartingPte, MM::Paging::GetNextEntry(ReleasedPte));\n    MM::Paging::SetNextEntry(ReleasedPte, MM::Paging::GetPteDistance(StartingPte, SystemPteBase));\n}\n\n/**\n * Reserves a contiguous block of system PTEs from a specified pool.\n *\n * @param NumberOfPtes\n *        The number of contiguous PTEs to reserve.\n *\n * @param SystemPtePoolType\n *        Specifies the system PTE pool from which to allocate.\n *\n * @return This routine returns a pointer to the beginning of the reserved block,\n *         or NULLPTR if not enough contiguous PTEs are available.\n *\n * @since XT 1.0\n */\nXTAPI\nPMMPTE\nMM::Pte::ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,\n                           IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)\n{\n    PMMPTE NextPte, PreviousPte, ReservedPte;\n    ULONG ClusterSize;\n\n    /* Raise runlevel and acquire lock to protect the PTE pool */\n    KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);\n    KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock);\n\n    /* Find a free PTE cluster large enough for the request */\n    if(!FindFreeCluster(NumberOfPtes, SystemPtePoolType, &NextPte, &PreviousPte))\n    {\n        /* Out of system PTEs for this pool, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* We have the cluster, now get its size for the allocation logic below */\n    ClusterSize = GetClusterSize(NextPte);\n\n    /* Unlink the found cluster from the free list for processing */\n    MM::Paging::SetNextEntry(PreviousPte, MM::Paging::GetNextEntry(NextPte));\n\n    /* Handle the allocation based on whether the cluster size is an exact match */\n    if(ClusterSize == NumberOfPtes)\n    {\n        /* Exact match, allocate the entire cluster */\n        ReservedPte = NextPte;\n\n        /* Handle metadata cleanup for a single-PTE cluster */\n        if(MM::Paging::GetOneEntry(NextPte))\n        {\n            /* Clear the PTE that held the list metadata */\n            MM::Paging::ClearPte(NextPte);\n            NextPte = MM::Paging::GetNextPte(NextPte);\n        }\n\n        /* Clear the PTE that held the cluster size */\n        MM::Paging::ClearPte(NextPte);\n    }\n    else\n    {\n        /* Cluster is larger than needed, so it will be split */\n        ClusterSize -= NumberOfPtes;\n        ReservedPte = MM::Paging::AdvancePte(NextPte, ClusterSize);\n\n        /* Update metadata for the new, smaller leftover cluster */\n        if(ClusterSize == 1)\n        {\n            /* The leftover fragment is a single PTE */\n            MM::Paging::SetOneEntry(NextPte, 1);\n            MM::Paging::ClearPte(ReservedPte);\n        }\n        else\n        {\n            /* The leftover fragment is larger than one PTE */\n            NextPte = MM::Paging::GetNextPte(NextPte);\n            MM::Paging::SetNextEntry(NextPte, ClusterSize);\n        }\n\n        /* Find the correct sorted position to re-insert the leftover fragment */\n        PreviousPte = &FirstSystemFreePte[SystemPtePoolType];\n        while(MM::Paging::GetNextEntry(PreviousPte) != MAXULONG)\n        {\n            /* Get the next free cluster to check its size */\n            NextPte = MM::Paging::AdvancePte(SystemPteBase, MM::Paging::GetNextEntry(PreviousPte));\n\n            /* Check if the leftover fragment should be inserted here */\n            if(ClusterSize <= GetClusterSize(NextPte))\n            {\n                /* Found the correct sorted position */\n                break;\n            }\n\n            /* Advance to the next entry */\n            PreviousPte = NextPte;\n        }\n\n        /* Get a pointer to the start of the leftover fragment */\n        NextPte = MM::Paging::AdvancePte(ReservedPte, -ClusterSize);\n\n        /* Insert the leftover fragment back into the free list at its sorted position */\n        MM::Paging::SetNextEntry(NextPte, MM::Paging::GetNextEntry(PreviousPte));\n        MM::Paging::SetNextEntry(PreviousPte, MM::Paging::GetPteDistance(NextPte, SystemPteBase));\n    }\n\n    /* Decrement the total number of available PTEs in this pool */\n    TotalSystemFreePtes[SystemPtePoolType] -= NumberOfPtes;\n\n    /* Flush the TLB to ensure address translation consistency */\n    AR::CpuFunctions::FlushTlb();\n\n    /* Return a pointer to the start of the reserved PTE block */\n    return ReservedPte;\n}\n"
  },
  {
    "path": "xtoskrnl/po/idle.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/po/idle.cc\n * DESCRIPTION:     Processor idle functionality support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Initializes Processor Control Block's (PRCB) power state structures.\n *\n * @param Prcb\n *        Supplies a pointer to the PRCB being initialized.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nPO::Idle::InitializeProcessorIdleState(IN OUT PKPROCESSOR_CONTROL_BLOCK Prcb)\n{\n    /* Zero memory */\n    RTL::Memory::ZeroMemory(&Prcb->PowerState, sizeof(Prcb->PowerState));\n\n    /* Initialize default power state */\n    Prcb->PowerState.Idle0TimeLimit = 0xFFFFFFFF;\n    Prcb->PowerState.CurrentThrottle = 100;\n    Prcb->PowerState.CurrentThrottleIndex = 0;\n    Prcb->PowerState.IdleFunction = Idle0Function;\n\n    /* Initialize DPC and Timer */\n    KE::Dpc::InitializeDpc(&Prcb->PowerState.PerfDpc, PerfIdleDpc, Prcb);\n    KE::Dpc::SetTargetProcessor(&Prcb->PowerState.PerfDpc, Prcb->CpuNumber);\n    KE::Timer::InitializeTimer(&Prcb->PowerState.PerfTimer, SynchronizationTimer);\n}\n\n/**\n * Processor idle loop routine.\n *\n * @param PowerState\n *        Supplies a pointer to the structere containing current processor power state.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nVOID\nPO::Idle::Idle0Function(IN PPROCESSOR_POWER_STATE PowerState)\n{\n    UNIMPLEMENTED;\n}\n\n/**\n * Switches CPU between different performance levels.\n *\n * @param PowerState\n *        Supplies a pointer to the structure containing IDLE processor power state.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTAPI\nVOID\nPO::Idle::PerfIdle(PPROCESSOR_POWER_STATE PowerState)\n{\n    UNIMPLEMENTED;\n}\n\n/**\n * Checks if CPU is running at the maximum (performance) frequency.\n *\n * @param Dpc\n *        Supplies a pointer to the DPC object.\n *\n * @param DeferredContext\n *        Supplies a pointer to memory area containing current CPU's PRCB.\n *\n * @param SystemArgument1\n *        Supplies a pointer to an unused system argument.\n *\n * @param SystemArgument2\n *        Supplies a pointer to an unused system argument.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTAPI\nVOID\nPO::Idle::PerfIdleDpc(IN PKDPC Dpc,\n                      IN PVOID DeferredContext,\n                      IN PVOID SystemArgument1,\n                      IN PVOID SystemArgument2)\n{\n    UNIMPLEMENTED;\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/amd64/dispatch.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/amd64/dispatch.cc\n * DESCRIPTION:     Dispatching support for AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Returns the stack limits for the current thread.\n *\n * @param StackBase\n *        Supplies a pointer to memory area, where the stack base will be stored.\n *\n * @param StackLimit\n *        Suppliws a pointer to memory area, where the stack limit will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::Dispatcher::GetStackLimits(OUT PULONG_PTR StackBase,\n                                OUT PULONG_PTR StackLimit)\n{\n    PKTHREAD Thread = KE::Processor::GetCurrentThread();\n    *StackBase = (ULONG_PTR)Thread->StackBase;\n    *StackLimit = (ULONG_PTR)Thread->StackLimit;\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/amd64/exsup.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/amd64/exsup.cc\n * DESCRIPTION:     Exception handling for AMD64 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Handles SEH structured exception frames.\n *\n * @param ExceptionRecord\n *        A pointer to the exception record.\n *\n * @param EstablisherFrame\n *        The address of the base of the fixed stack allocation.\n *\n * @param ContextRecord\n *       A pointer to the context record at the time the exception was raised.\n *\n * @param DispatcherContext\n *      A pointer to the dispatcher context for the function.\n *\n * @return This routine returns an exception disposition value if the exception was not handled by any filter.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nEXCEPTION_DISPOSITION\n__C_specific_handler(IN PEXCEPTION_RECORD ExceptionRecord,\n                     IN PVOID EstablisherFrame,\n                     IN OUT PCONTEXT ContextRecord,\n                     IN OUT PVOID DispatcherContext)\n{\n    UNIMPLEMENTED;\n\n    /* Continue execution */\n    return ExceptionContinueExecution;\n}\n\n/**\n * Handles C++ structured exception frames. This implementation displays a panic screen and halts the system.\n *\n * @param ExceptionRecord\n *        A pointer to the exception record that is passed to the possible catch statements.\n *\n * @param EstablisherFrame\n *        A pointer to the stack frame that is used to handle the exception.\n *\n * @param ContextRecord\n *       A pointer to the context record (not used on Intel CPUs).\n *\n * @param DispatcherContext\n *      A pointer to the dispatcher provding information about function entry and stack frame (not used on Intel CPUs).\n *\n * @return This routine returns an exception disposition value if the exception was not handled by any filter.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nEXCEPTION_DISPOSITION\n__CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,\n                   IN PVOID EstablisherFrame,\n                   IN OUT PCONTEXT ContextRecord,\n                   IN OUT PVOID DispatcherContext)\n{\n    UNIMPLEMENTED;\n\n    /* Disable interrupts and hang */\n    AR::CpuFunctions::ClearInterruptFlag();\n    KE::Crash::Panic(0);\n\n    /* Continue search */\n    return ExceptionContinueSearch;\n}\n\n/**\n * Finds the appropriate exception handler to process the current exception.\n *\n * @param ExceptionRecord\n *        A pointer to the exception record providing information about the specific exception.\n *\n * @param Registration\n *        A pointer to the record that indicates which scope table should be used to find the exception handler.\n *\n * @param Context\n *        Reserved.\n *\n * @param Dispatcher\n *        Reserved.\n *\n * @return This routine returns DISPOSITION_DISMISS or DISPOSITION_CONTINUE_SEARCH.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nINT\n_except_handler3(IN PEXCEPTION_RECORD ExceptionRecord,\n                 IN PVOID Registration,\n                 IN PCONTEXT Context,\n                 IN PVOID Dispatcher)\n{\n    UNIMPLEMENTED;\n\n    /* Handler not found */\n    return 0;\n}\n\n/**\n * Handles pure virtual function call error. This implementation displays a panic screen and halts the system.\n *\n * @return This function does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\n_purecall(VOID)\n{\n    UNIMPLEMENTED;\n\n    /* Disable interrupts and hang */\n    AR::CpuFunctions::ClearInterruptFlag();\n    KE::Crash::Panic(0);\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/amd64/intrin.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/amd64/intrin.cc\n * DESCRIPTION:     Compiler intrinsic support routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n"
  },
  {
    "path": "xtoskrnl/rtl/atomic.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/atomic.cc\n * DESCRIPTION:     Atomic operations support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Performs an atomic bitwise AND operation on the 8-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise AND operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise AND operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nCHAR\nRTL::Atomic::And8(IN PCHAR Address,\n                  IN CHAR Mask)\n{\n    return __sync_fetch_and_and(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise AND operation on the 16-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise AND operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise AND operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nSHORT\nRTL::Atomic::And16(IN PSHORT Address,\n                   IN SHORT Mask)\n{\n    return __sync_fetch_and_and(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise AND operation on the 32-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise AND operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise AND operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG\nRTL::Atomic::And32(IN PLONG Address,\n                   IN LONG Mask)\n{\n    return __sync_fetch_and_and(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise AND operation on the 32-bit or 64-bit value depending or architecture.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise AND operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise AND operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG_PTR\nRTL::Atomic::And64(IN PLONG_PTR Address,\n                   IN LONG_PTR Mask)\n{\n    return __sync_fetch_and_and(Address, Mask);\n}\n\n/**\n * Performs an atomic test of the specified bit of the specified long value and sets it to 1.\n *\n * @param Base\n *        Specifies a pointer to the variable.\n *\n * @param Offset\n *        Specifies the bit position to be tested.\n *\n * @return Returns a value of the specified bit.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nUCHAR\nRTL::Atomic::BitTestAndSet(IN PLONG Base,\n                           IN LONG Offset)\n{\n    return (__atomic_fetch_or(Base, 1l << Offset, __ATOMIC_SEQ_CST) >> Offset) & 1;\n}\n\n/**\n * Performs an atomic test of the specified bit of the specified 64-bit long value and sets it to 1.\n *\n * @param Base\n *        Specifies a pointer to the variable.\n *\n * @param Offset\n *        Specifies the bit position to be tested.\n *\n * @return Returns a value of the specified bit.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nUCHAR\nRTL::Atomic::BitTestAndSet64(IN PLONGLONG Base,\n                             IN LONGLONG Offset)\n{\n    return (__atomic_fetch_or(Base, 1ll << Offset, __ATOMIC_SEQ_CST) >> Offset) & 1;\n}\n\n/**\n * Performs atomically compare exchange operation on the 8-bit value.\n *\n * @param Address\n *        Supplies the address of the value to compare and potentially exchange.\n *\n * @param Comperand\n *        Supplies the value to compare against.\n *\n * @param Exchange\n *        Supplies the value to write if the comparison returns equality.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nCHAR\nRTL::Atomic::CompareExchange8(IN PCHAR Address,\n                              IN CHAR Comperand,\n                              IN CHAR Exchange)\n{\n    return __sync_val_compare_and_swap(Address, Comperand, Exchange);\n}\n\n/**\n * Performs atomically compare exchange operation on the 16-bit value.\n *\n * @param Address\n *        Supplies the address of the value to compare and potentially exchange.\n *\n * @param Comperand\n *        Supplies the value to compare against.\n *\n * @param Exchange\n *        Supplies the value to write if the comparison returns equality.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nSHORT\nRTL::Atomic::CompareExchange16(IN PSHORT Address,\n                               IN SHORT Comperand,\n                               IN SHORT Exchange)\n{\n    return __sync_val_compare_and_swap(Address, Comperand, Exchange);\n}\n\n/**\n * Performs atomically compare exchange operation on the 32-bit value.\n *\n * @param Address\n *        Supplies the address of the value to compare and potentially exchange.\n *\n * @param Comperand\n *        Supplies the value to compare against.\n *\n * @param Exchange\n *        Supplies the value to write if the comparison returns equality.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG\nRTL::Atomic::CompareExchange32(IN PLONG Address,\n                               IN LONG Comperand,\n                               IN LONG Exchange)\n{\n    return __sync_val_compare_and_swap(Address, Comperand, Exchange);\n}\n\n/**\n * Performs atomically compare exchange operation on the 32-bit or 64-bit value depending or architecture.\n *\n * @param Address\n *        Supplies the address of the value to compare and potentially exchange.\n *\n * @param Comperand\n *        Supplies the value to compare against.\n *\n * @param Exchange\n *        Supplies the value to write if the comparison returns equality.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG_PTR\nRTL::Atomic::CompareExchange64(IN PLONG_PTR Address,\n                               IN LONG_PTR Comperand,\n                               IN LONG_PTR Exchange)\n{\n    return __sync_val_compare_and_swap(Address, Comperand, Exchange);\n}\n\n/**\n * Performs atomically compare exchange operation.\n *\n * @param Address\n *        Supplies the address of the value to compare and potentially exchange.\n *\n * @param Comperand\n *        Supplies a pointer to the value to compare against.\n *\n * @param Exchange\n *        Supplies a pointer to the value to write if the comparison returns equality.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nPVOID\nRTL::Atomic::CompareExchangePointer(IN PVOID *Address,\n                                    IN PVOID Comperand,\n                                    IN PVOID Exchange)\n{\n    return (PVOID)__sync_val_compare_and_swap(Address, Comperand, Exchange);\n}\n\n/**\n * Performs atomically decrement of the 8-bit value.\n *\n * @param Address\n *        Supplies the address of the value to decrement.\n *\n * @return This routine returns the decremented value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nCHAR\nRTL::Atomic::Decrement8(IN PCHAR Address)\n{\n    return __sync_sub_and_fetch(Address, 1);\n}\n\n/**\n * Performs atomically decrement of the 16-bit value.\n *\n * @param Address\n *        Supplies the address of the value to decrement.\n *\n * @return This routine returns the decremented value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nSHORT\nRTL::Atomic::Decrement16(IN PSHORT Address)\n{\n    return __sync_sub_and_fetch(Address, 1);\n}\n\n/**\n * Performs atomically decrement of the 32-bit value.\n *\n * @param Address\n *        Supplies the address of the value to decrement.\n *\n * @return This routine returns the decremented value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG\nRTL::Atomic::Decrement32(IN PLONG Address)\n{\n    return __sync_sub_and_fetch(Address, 1);\n}\n\n/**\n * Performs atomically decrement of the 32-bit or 64-bit value depending or architecture.\n *\n * @param Address\n *        Supplies the address of the value to decrement.\n *\n * @return This routine returns the decremented value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG_PTR\nRTL::Atomic::Decrement64(IN PLONG_PTR Address)\n{\n    return __sync_sub_and_fetch(Address, 1);\n}\n\n/**\n * Performs atomically operation on the 8-bit value.\n *\n * @param Address\n *        Supplies the address of the value to exchange with.\n *\n * @param Exchange\n *        Supplies the value to write to the address.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nCHAR\nRTL::Atomic::Exchange8(IN PCHAR Address,\n                       IN CHAR Exchange)\n{\n    return __sync_lock_test_and_set(Address, Exchange);\n}\n\n/**\n * Performs atomically operation on the 16-bit value.\n *\n * @param Address\n *        Supplies the address of the value to exchange with.\n *\n * @param Exchange\n *        Supplies the value to write to the address.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nSHORT\nRTL::Atomic::Exchange16(IN PSHORT Address,\n                        IN SHORT Exchange)\n{\n    return __sync_lock_test_and_set(Address, Exchange);\n}\n\n/**\n * Performs atomically operation on the 32-bit value.\n *\n * @param Address\n *        Supplies the address of the value to exchange with.\n *\n * @param Exchange\n *        Supplies the value to write to the address.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG\nRTL::Atomic::Exchange32(IN PLONG Address,\n                        IN LONG Exchange)\n{\n    return __sync_lock_test_and_set(Address, Exchange);\n}\n\n/**\n * Performs atomically operation on the 32-bit or 64-bit value depending or architecture.\n *\n * @param Address\n *        Supplies the address of the value to exchange with.\n *\n * @param Exchange\n *        Supplies the value to write to the address.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG_PTR\nRTL::Atomic::Exchange64(IN PLONG_PTR Address,\n                        IN LONG_PTR Exchange)\n{\n    return __sync_lock_test_and_set(Address, Exchange);\n}\n\n/**\n * Performs atomically addition of the 8-bit value.\n *\n * @param Address\n *        Supplies the address of the original value.\n *\n * @param Value\n *        Supplies a value, to be add to variable found at specified address.\n *\n * @return Returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nCHAR\nRTL::Atomic::ExchangeAdd8(IN PCHAR Address,\n                          IN CHAR Value)\n{\n    return __sync_fetch_and_add(Address, Value);\n}\n\n/**\n * Performs atomically addition of the 16-bit value.\n *\n * @param Address\n *        Supplies the address of the original value.\n *\n * @param Value\n *        Supplies a value, to be add to variable found at specified address.\n *\n * @return Returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nSHORT\nRTL::Atomic::ExchangeAdd16(IN PSHORT Address,\n                           IN SHORT Value)\n{\n    return __sync_fetch_and_add(Address, Value);\n}\n\n/**\n * Performs atomically addition of the 32-bit value.\n *\n * @param Address\n *        Supplies the address of the original value.\n *\n * @param Value\n *        Supplies a value, to be add to variable found at specified address.\n *\n * @return Returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG\nRTL::Atomic::ExchangeAdd32(IN PLONG Address,\n                           IN LONG Value)\n{\n    return __sync_fetch_and_add(Address, Value);\n}\n\n/**\n * Performs atomically addition of the 32-bit or 64-bit value depending or architecture.\n *\n * @param Address\n *        Supplies the address of the original value.\n *\n * @param Value\n *        Supplies a value, to be add to variable found at specified address.\n *\n * @return Returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG_PTR\nRTL::Atomic::ExchangeAdd64(IN PLONG_PTR Address,\n                           IN LONG_PTR Value)\n{\n    return __sync_fetch_and_add(Address, Value);\n}\n\n/**\n * Performs atomically exchange operation.\n *\n * @param Address\n *        Supplies the address of the value to exchange with.\n *\n * @param Exchange\n *        Supplies a pointer to the value to write to the address.\n *\n * @return This routine returns the original value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nPVOID\nRTL::Atomic::ExchangePointer(IN PVOID *Address,\n                             IN PVOID Exchange)\n{\n    __sync_synchronize();\n    return (PVOID)__sync_lock_test_and_set(Address, Exchange);\n}\n\n/**\n * Removes all entries from single linked list.\n *\n * @param Header\n *        Supplies a pointer to the header of linked list.\n *\n * @return This routine returns a pointer to the original list, or NULLPTR if the list was already empty.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nPSINGLE_LIST_ENTRY\nRTL::Atomic::FlushSingleList(IN PSINGLE_LIST_HEADER Header)\n{\n    return (PSINGLE_LIST_ENTRY)Exchange64((PLONG_PTR)&Header->Alignment, (LONGLONG)NULLPTR);\n}\n\n/**\n * Performs atomically increment of the 8-bit value.\n *\n * @param Address\n *        Supplies the address of the value to increment.\n *\n * @return This routine returns the incremented value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nCHAR\nRTL::Atomic::Increment8(IN PCHAR Address)\n{\n    return __sync_add_and_fetch(Address, 1);\n}\n\n/**\n * Performs atomically increment of the 16-bit value.\n *\n * @param Address\n *        Supplies the address of the value to increment.\n *\n * @return This routine returns the incremented value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nSHORT\nRTL::Atomic::Increment16(IN PSHORT Address)\n{\n    return __sync_add_and_fetch(Address, 1);\n}\n\n/**\n * Performs atomically increment of the 32-bit value.\n *\n * @param Address\n *        Supplies the address of the value to increment.\n *\n * @return This routine returns the incremented value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG\nRTL::Atomic::Increment32(IN PLONG Address)\n{\n    return __sync_add_and_fetch(Address, 1);\n}\n\n/**\n * Performs atomically increment of the 32-bit or 64-bit value depending or architecture.\n *\n * @param Address\n *        Supplies the address of the value to increment.\n *\n * @return This routine returns the incremented value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG_PTR\nRTL::Atomic::Increment64(IN PLONG_PTR Address)\n{\n    return __sync_add_and_fetch(Address, 1);\n}\n\n/**\n * Performs an atomic bitwise OR operation on the 8-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise OR operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise OR operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nCHAR\nRTL::Atomic::Or8(IN PCHAR Address,\n                 IN CHAR Mask)\n{\n    return __sync_fetch_and_or(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise OR operation on the 16-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise OR operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise OR operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nSHORT\nRTL::Atomic::Or16(IN PSHORT Address,\n                  IN SHORT Mask)\n{\n    return __sync_fetch_and_or(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise OR operation on the 32-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise OR operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise OR operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG\nRTL::Atomic::Or32(IN PLONG Address,\n                  IN LONG Mask)\n{\n    return __sync_fetch_and_or(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise OR operation on the 32-bit or 64-bit value depending or architecture.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise OR operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise OR operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG_PTR\nRTL::Atomic::Or64(IN PLONG_PTR Address,\n                  IN LONG_PTR Mask)\n{\n    return __sync_fetch_and_or(Address, Mask);\n}\n\n/**\n * Removes and returns the first entry from single linked list.\n *\n * @param Header\n *        Supplies a pointer to the header of a single linked list.\n *\n * @return This routine returns a pointer to the removed element, or NULLPTR if the list was empty.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nPSINGLE_LIST_ENTRY\nRTL::Atomic::PopEntrySingleList(IN PSINGLE_LIST_HEADER Header)\n{\n    PSINGLE_LIST_ENTRY ListHead, FirstEntry, NextEntry;\n\n    /* Save header and first entry */\n    ListHead = (PSINGLE_LIST_ENTRY)Header;\n    FirstEntry = ListHead->Next;\n    do\n    {\n        /* Check if list is not empty */\n        if(!FirstEntry)\n        {\n            /* Empty list */\n            return NULLPTR;\n        }\n\n        /* Update link */\n        NextEntry = FirstEntry;\n\n        /* Compare and exchange */\n        FirstEntry = (PSINGLE_LIST_ENTRY)CompareExchange64((PLONG_PTR)ListHead,\n                                                           (LONG_PTR)FirstEntry->Next,\n                                                           (LONG_PTR)FirstEntry);\n    } while(FirstEntry != NextEntry);\n\n    /* Return removed element */\n    return FirstEntry;\n}\n\n/**\n * Inserts new entry at the beginning of single linked list.\n *\n * @param Header\n *        Supplies a pointer to the header of linked list.\n *\n * @param Entry\n *        Supplies a pointer to entry, that will be inserted into linked list.\n *\n * @return This routine returns a pointer to original heading, or NULLPTR if the list was originally empty.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nPSINGLE_LIST_ENTRY\nRTL::Atomic::PushEntrySingleList(IN PSINGLE_LIST_HEADER Header,\n                                 IN PSINGLE_LIST_ENTRY Entry)\n{\n    PSINGLE_LIST_ENTRY ListHead, ListEntry, FirstEntry, NextEntry;\n\n    /* Save header and new entry */\n    ListHead = (PSINGLE_LIST_ENTRY)Header;\n    ListEntry = Entry;\n\n    /* Save next link in new first element */\n    FirstEntry = ListHead->Next;\n    do\n    {\n        /* Update links */\n        ListEntry->Next = FirstEntry;\n        NextEntry = FirstEntry;\n\n        /* Compare and exchange */\n        FirstEntry = (PSINGLE_LIST_ENTRY)CompareExchange64((PLONG_PTR)ListHead,\n                                                           (LONG_PTR)ListEntry,\n                                                           (LONG_PTR)FirstEntry);\n    } while(FirstEntry != NextEntry);\n\n    /* Return original first element */\n    return FirstEntry;\n}\n\n/**\n * Performs an atomic bitwise XOR operation on the 8-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise XOR operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise XOR operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nCHAR\nRTL::Atomic::Xor8(IN PCHAR Address,\n                  IN CHAR Mask)\n{\n    return __sync_fetch_and_xor(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise XOR operation on the 16-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise XOR operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise XOR operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nSHORT\nRTL::Atomic::Xor16(IN PSHORT Address,\n                   IN SHORT Mask)\n{\n    return __sync_fetch_and_xor(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise XOR operation on the 32-bit value.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise XOR operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise XOR operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG\nRTL::Atomic::Xor32(IN PLONG Address,\n                   IN LONG Mask)\n{\n    return __sync_fetch_and_xor(Address, Mask);\n}\n\n/**\n * Performs an atomic bitwise XOR operation on the 32-bit or 64-bit value depending or architecture.\n *\n * @param Address\n *        Supplies the address of the value on which the bitwise XOR operation is to be performed.\n *\n * @param Mask\n *        Supplies the mask with which the bitwise XOR operation is to be performed\n *\n * @return This routine returns the initial value at the given address.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nLONG_PTR\nRTL::Atomic::Xor64(IN PLONG_PTR Address,\n                   IN LONG_PTR Mask)\n{\n    return __sync_fetch_and_xor(Address, Mask);\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/bitmap.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/bitmap.cc\n * DESCRIPTION:     Bit maps support related routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Clears all bits in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nRTL::BitMap::ClearAllBits(IN PRTL_BITMAP BitMap)\n{\n    /* Clear all bits */\n    RTL::Memory::SetMemory(BitMap->Buffer, 0, ((BitMap->Size + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof(ULONG_PTR));\n}\n\n/**\n * Clears a single bit in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Bit\n *        Specifies the number of the bit to be cleared.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTAPI\nVOID\nRTL::BitMap::ClearBit(IN PRTL_BITMAP BitMap,\n                      IN ULONG_PTR Bit)\n{\n    /* Check if bit is in range */\n    if(Bit >= BitMap->Size)\n    {\n        /* Supplied bit exceeds bit map size */\n        return;\n    }\n\n    /* Clear specified bit */\n    BitMap->Buffer[Bit / BITS_PER_LONG] &= ~(1 << (Bit & (BITS_PER_LONG - 1)));\n}\n\n/**\n * Clears a specified set of bits within a bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param StartingIndex\n *        Supplies the starting index of the first bit to clear.\n *\n * @param Length\n *        Supplies the length (number of bits) to clear.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nRTL::BitMap::ClearBits(IN PRTL_BITMAP BitMap,\n                       IN ULONG_PTR StartingIndex,\n                       IN ULONG_PTR Length)\n{\n    ULONG_PTR BitOffset, Mask;\n    PULONG_PTR Buffer;\n\n    /* Make sure there is anything to clear */\n    if(!Length)\n    {\n        /* No bits to clear */\n        return;\n    }\n\n    /* Get pointer to first byte to clear and calculate bit offset */\n    Buffer = &BitMap->Buffer[StartingIndex / BITS_PER_LONG];\n    BitOffset = StartingIndex & (BITS_PER_LONG - 1);\n\n    /* Check if bit offset is not zero */\n    if(BitOffset)\n    {\n        /* Get mask and calculate new bit offset */\n        Mask = MAXULONG_PTR << BitOffset;\n        BitOffset = BITS_PER_LONG - BitOffset;\n\n        /* Check if there are enough bits to clear */\n        if(Length < BitOffset)\n        {\n            /* Recalculate bit offset and fixup the mask */\n            BitOffset -= Length;\n            Mask = Mask << BitOffset >> BitOffset;\n\n            /* Clear bits and return */\n            *Buffer &= ~Mask;\n            return;\n        }\n\n        /* Clear bits, recalculate length and advance buffer pointer */\n        *Buffer &= ~Mask;\n        Length -= BitOffset;\n        Buffer++;\n    }\n\n    /* Clear remaining bits */\n    RTL::Memory::SetMemory(Buffer, 0, Length >> 3);\n\n    /* Look for any remaining bits to clear */\n    Buffer += Length / BITS_PER_LONG;\n    Length &= BITS_PER_LONG - 1;\n    if(Length)\n    {\n        /* Clear what's left */\n        *Buffer &= MAXULONG_PTR << Length;\n    }\n}\n\n/**\n * Searches the bit map for a contiguous region of set bits and clears them.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length of contiguous region (number of set bits) to look for.\n *\n * @param Index\n *        Supplies the index of the first bit to start the search at a given position.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nRTL::BitMap::ClearSetBits(IN PRTL_BITMAP BitMap,\n                          IN ULONG_PTR Length,\n                          IN ULONG_PTR Index)\n{\n    ULONG_PTR StartingIndex;\n\n    /* Find set bits */\n    StartingIndex = FindSetBits(BitMap, Length, Index);\n\n    /* Check if set bits were found */\n    if(StartingIndex != MAXULONG_PTR)\n    {\n        /* Clear bits */\n        ClearBits(BitMap, StartingIndex, Length);\n    }\n\n    /* Return position of bits found */\n    return StartingIndex;\n}\n\n/**\n * Counts the number of either set or clear bits in the contiguous region of the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the maximum length (number of bits) to count.\n *\n * @param StartingIndex\n *        Supplies the starting index of the first bit to count.\n *\n * @param SetBits\n *        Specifies whether count bits that are set or clear.\n *\n * @return This routine returns the number of equal bits found in the contiguous region.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nRTL::BitMap::CountBits(IN PRTL_BITMAP BitMap,\n                       IN ULONG_PTR Length,\n                       IN ULONG_PTR StartingIndex,\n                       IN BOOLEAN SetBits)\n{\n    PULONG_PTR Buffer, BufferEnd;\n    ULONG_PTR BitOffset, Size;\n    ULONGLONG Value;\n\n    /* Get pointers to first and last bytes to check */\n    Buffer = &BitMap->Buffer[StartingIndex / BITS_PER_LONG];\n    BufferEnd = Buffer + ((Length + BITS_PER_LONG - 1) / BITS_PER_LONG);\n\n    /* Get offset and value */\n    BitOffset = StartingIndex & (BITS_PER_LONG - 1);\n    Value = (SetBits ? ~*Buffer : *Buffer) >> BitOffset << BitOffset;\n\n    /* Find first bit set until the end of the buffer */\n    while(!Value && Buffer + 1 < BufferEnd)\n    {\n        /* Advance buffer pointer and get value */\n        Value = SetBits ? ~*(++Buffer) : *(++Buffer);\n    }\n\n    /* Check if value found */\n    if(!Value)\n    {\n        /* No bits found, return length */\n        return Length;\n    }\n\n    /* Calculate size */\n    Size = ((Buffer - BitMap->Buffer) * BITS_PER_LONG) - StartingIndex + (ULONG_PTR)RTL::Math::CountTrailingZeroes64(Value);\n\n    /* Return whatever is smaller */\n    return Size > Length ? Length : Size;\n}\n\n/**\n * Dumps the contents of the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::BitMap::DumpBitMap(IN PRTL_BITMAP BitMap)\n{\n    ULONG_PTR Index;\n\n    /* Dump bit map buffer information */\n    DebugPrint(L\"BitMap Buffer: 0x%zX (%lu bytes)\\n\", BitMap->Buffer, BitMap->Size);\n\n    /* Dump bit map buffer content */\n    for(Index = 0; Index < (BitMap->Size + BITS_PER_LONG - 1) / BITS_PER_LONG; Index++)\n    {\n        DebugPrint(L\"  %8zu: %08lx\\n\", Index, BitMap->Buffer[Index]);\n    }\n}\n\n/**\n * Searches the bit map for a contiguous region of either set or clear bits.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length (number of equal bits) to look for.\n *\n * @param StartingIndex\n *        Supplies the starting index of the first bit to start the search at a given position.\n *\n * @param SetBits\n *        Specifies whether count bits that are set or clear.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG_PTR\nRTL::BitMap::FindBits(IN PRTL_BITMAP BitMap,\n                      IN ULONG_PTR Length,\n                      IN ULONG_PTR StartingIndex,\n                      IN BOOLEAN SetBits)\n{\n    ULONG_PTR BitMapEnd, BitOffset, Size;\n    ULONG Tries;\n\n    /* Validate length */\n    if(Length > BitMap->Size)\n    {\n        /* Length exceeds bit map size, return MAXULONG_PTR */\n        return (ULONG_PTR)-1;\n    }\n    else if(!Length)\n    {\n        /* Length not specified, return starting index */\n        return StartingIndex;\n    }\n\n    /* Check if starting index is in range of bit map size */\n    if(StartingIndex >= BitMap->Size)\n    {\n        /* Starting index exceeds bit map size, start from the beginning */\n        StartingIndex = 0;\n    }\n\n    /* Try from starting index */\n    BitOffset = StartingIndex;\n    BitMapEnd = BitMap->Size;\n\n    /* At least two tries are required */\n    Tries = (StartingIndex != 0) + 2;\n    while(Tries)\n    {\n        /* Find until the end of the bit map */\n        while(BitOffset + Length < BitMapEnd)\n        {\n            /* Increment offset */\n            BitOffset += CountBits(BitMap, BitMap->Size - BitOffset, BitOffset, !SetBits);\n            if(BitOffset + Length > BitMapEnd)\n            {\n                /* No match found, break loop execution */\n                break;\n            }\n\n            /* Count bits in the contiguous region and check if match found */\n            Size = CountBits(BitMap, Length, BitOffset, SetBits);\n            if(Size >= Length)\n            {\n                /* Match found, return offset */\n                return BitOffset;\n            }\n\n            /* Increment offset */\n            BitOffset += Size;\n        }\n\n        /* Try again if possible */\n        Tries--;\n        if(Tries)\n        {\n            /* Restart from the beginning up to the starting index */\n            BitOffset = 0;\n            BitMapEnd = StartingIndex;\n        }\n    }\n\n    /* No match found, return MAXULONG_PTR */\n    return (ULONG_PTR)-1;\n}\n\n/**\n * Searches the bit map for a contiguous region of clear bits.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length of contiguous region (number of clear bits) to look for.\n *\n * @param Index\n *        Supplies the index of the first bit to start the search at a given position.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since NT 3.5\n */\nXTAPI\nULONG_PTR\nRTL::BitMap::FindClearBits(IN PRTL_BITMAP BitMap,\n                           IN ULONG_PTR Length,\n                           IN ULONG_PTR Index)\n{\n    /* Find clear bits */\n    return FindBits(BitMap, Length, Index, FALSE);\n}\n\n/**\n * Searches the bit map for a contiguous region of set bits.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length of contiguous region (number of set bits) to look for.\n *\n * @param Index\n *        Supplies the index of the first bit to start the search at a given position.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since NT 3.5\n */\nXTAPI\nULONG_PTR\nRTL::BitMap::FindSetBits(IN PRTL_BITMAP BitMap,\n                         IN ULONG_PTR Length,\n                         IN ULONG_PTR Index)\n{\n    /* Find set bits */\n    return FindBits(BitMap, Length, Index, TRUE);\n}\n\n/**\n * Initializes a bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map to initialize.\n *\n * @param Buffer\n *        Supplies a pointer to the buffer that will be used as a bit map.\n *\n * @param Size\n *        Supplies a size of the bit map.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nRTL::BitMap::InitializeBitMap(IN PRTL_BITMAP BitMap,\n                              IN PULONG_PTR Buffer,\n                              IN ULONG Size)\n{\n    /* Initialize bit map */\n    BitMap->Buffer = Buffer;\n    BitMap->Size = Size;\n}\n\n/**\n * Sets all bits in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nRTL::BitMap::SetAllBits(IN PRTL_BITMAP BitMap)\n{\n    /* Set all bits */\n    RTL::Memory::SetMemory(BitMap->Buffer, 0xFF, ((BitMap->Size + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof(ULONG_PTR));\n}\n\n/**\n * Sets a single bit in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Bit\n *        Specifies the number of the bit to be set.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTAPI\nVOID\nRTL::BitMap::SetBit(IN PRTL_BITMAP BitMap,\n                    IN ULONG_PTR Bit)\n{\n    /* Check if bit is in range */\n    if(Bit >= BitMap->Size)\n    {\n        /* Supplied bit exceeds bit map size */\n        return;\n    }\n\n    /* Set specified bit */\n    BitMap->Buffer[Bit / BITS_PER_LONG] |= 1 << (Bit & (BITS_PER_LONG - 1));\n}\n\n/**\n * Sets a specified set of bits within a bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param StartingIndex\n *        Supplies the starting index of the first bit to set.\n *\n * @param Length\n *        Supplies the length (number of bits) to set.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nRTL::BitMap::SetBits(IN PRTL_BITMAP BitMap,\n                     IN ULONG_PTR StartingIndex,\n                     IN ULONG_PTR Length)\n{\n    ULONG_PTR BitOffset, Mask;\n    PULONG_PTR Buffer;\n\n    /* Make sure there is anything to set */\n    if(!Length)\n    {\n        /* No bits to set */\n        return;\n    }\n\n    /* Get pointer to first byte to clear and calculate bit offset */\n    Buffer = &BitMap->Buffer[StartingIndex / BITS_PER_LONG];\n    BitOffset = StartingIndex & (BITS_PER_LONG - 1);\n\n    /* Check if bit offset is not zero */\n    if(BitOffset)\n    {\n        /* Get mask and calculate new bit offset */\n        Mask = MAXULONG_PTR << BitOffset;\n        BitOffset = BITS_PER_LONG - BitOffset;\n\n        /* Check if there are enough bits to set */\n        if(Length < BitOffset)\n        {\n            /* Recalculate bit offset and fixup the mask */\n            BitOffset -= Length;\n            Mask = Mask << BitOffset >> BitOffset;\n\n            /* Set bits and return */\n            *Buffer |= Mask;\n            return;\n        }\n\n        /* Set bits, recalculate length and advance buffer pointer */\n        *Buffer |= Mask;\n        Buffer++;\n        Length -= BitOffset;\n    }\n\n    /* Set remaining bits */\n    RTL::Memory::SetMemory(Buffer, 0xFF, Length >> 3);\n\n    /* Look for any remaining bits to set */\n    Buffer += Length / BITS_PER_LONG;\n    Length &= BITS_PER_LONG - 1;\n    if(Length)\n    {\n        /* Set what's left */\n        *Buffer |= ~(MAXULONG_PTR << Length);\n    }\n}\n\n/**\n * Searches the bit map for a contiguous region of clear bits and sets them.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length of contiguous region (number of clear bits) to look for.\n *\n * @param Index\n *        Supplies the index of the first bit to start the search at a given position.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since XT 1.0\n */\nXTAPI\nULONG\nRTL::BitMap::SetClearBits(IN PRTL_BITMAP BitMap,\n                          IN ULONG_PTR Length,\n                          IN ULONG_PTR Index)\n{\n    ULONG_PTR StartingIndex;\n\n    /* Find clear bits */\n    StartingIndex = FindClearBits(BitMap, Length, Index);\n\n    /* Check if clear bits were found */\n    if(StartingIndex != MAXULONG_PTR)\n    {\n        /* Set bits */\n        SetBits(BitMap, StartingIndex, Length);\n    }\n\n    /* Return position of bits found */\n    return StartingIndex;\n}\n\n/**\n * Tests a state of a single bit in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Bit\n *        Specifies the number of the bit to be tested.\n *\n * @return This routine returns TRUE when bit is set, or FALSE otherwise.\n *\n * @since NT 5.1\n */\nXTAPI\nBOOLEAN\nRTL::BitMap::TestBit(IN PRTL_BITMAP BitMap,\n                     IN ULONG_PTR Bit)\n{\n    /* Check if bit is in range */\n    if(Bit >= BitMap->Size)\n    {\n        /* Supplied bit exceeds bit map size, return FALSE */\n        return FALSE;\n    }\n\n    /* Test specified bit and return result */\n    return ((BitMap->Buffer[Bit / BITS_PER_LONG] >> (Bit & (BITS_PER_LONG - 1))) & 1) ? TRUE : FALSE;\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/data.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/data.cc\n * DESCRIPTION:     Runtime Library global and static data\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/* This is required for floating numbers to keep LLVM happy */\nXTCLINK INT _fltused = 0xFEEDBULL;\n\n/* Lookup table for days in a month, Index 0 is normal year, Index 1 is leap year */\nCUSHORT RTL::Time::DaysInMonth[2][12] = {\n    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},\n    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}\n};\n"
  },
  {
    "path": "xtoskrnl/rtl/endian.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/endian.cc\n * DESCRIPTION:     Endian conversion routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * This routine converts endianness on 16bit value.\n *\n * @param Source\n *        Supplies a value to swap bytes.\n *\n * @return Swapped 16bit value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nUSHORT\nRTL::Endianness::SwapByte16(IN USHORT Source)\n{\n    return (USHORT)(((Source >> 8) & 0x00FF) |\n                    ((Source << 8) & 0xFF00));\n}\n\n/**\n * This routine converts endianness on 32bit value.\n *\n * @param Source\n *        Supplies a value to swap bytes.\n *\n * @return Swapped 32bit value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nULONG\nRTL::Endianness::SwapByte32(IN ULONG Source)\n{\n    return (ULONG)(((Source >> 24) & 0x000000FF) |\n                   ((Source >> 8)  & 0x0000FF00) |\n                   ((Source << 8)  & 0x00FF0000) |\n                   ((Source << 24) & 0xFF000000));\n}\n\n/**\n * This routine converts endianness on 64bit value.\n *\n * @param Source\n *        Supplies a value to swap bytes.\n *\n * @return Swapped 64bit value.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nULONGLONG\nRTL::Endianness::SwapByte64(IN ULONGLONG Source)\n{\n    return (ULONGLONG)(((Source >> 56) & 0x00000000000000FF) |\n                       ((Source >> 40) & 0x000000000000FF00) |\n                       ((Source >> 24) & 0x0000000000FF0000) |\n                       ((Source >> 8)  & 0x00000000FF000000) |\n                       ((Source << 8)  & 0x000000FF00000000) |\n                       ((Source << 24) & 0x0000FF0000000000) |\n                       ((Source << 40) & 0x00FF000000000000) |\n                       ((Source << 56) & 0xFF00000000000000));\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/exports.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/exports.cc\n * DESCRIPTION:     C-compatible API wrappers for exported kernel functions\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Clears all bits in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlClearAllBits(IN PRTL_BITMAP BitMap)\n{\n    RTL::BitMap::ClearAllBits(BitMap);\n}\n\n/**\n * Clears a single bit in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Bit\n *        Specifies the number of the bit to be cleared.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTCLINK\nXTAPI\nVOID\nRtlClearBit(IN PRTL_BITMAP BitMap,\n            IN ULONG_PTR Bit)\n{\n    RTL::BitMap::ClearBit(BitMap, Bit);\n}\n\n/**\n * Clears a specified set of bits within a bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param StartingIndex\n *        Supplies the starting index of the first bit to clear.\n *\n * @param Length\n *        Supplies the length (number of bits) to clear.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlClearBits(IN PRTL_BITMAP BitMap,\n             IN ULONG_PTR StartingIndex,\n             IN ULONG_PTR Length)\n{\n    RTL::BitMap::ClearBits(BitMap, StartingIndex, Length);\n}\n\n/**\n * Searches the bit map for a contiguous region of set bits and clears them.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length of contiguous region (number of set bits) to look for.\n *\n * @param Index\n *        Supplies the index of the first bit to start the search at a given position.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nULONG\nRtlClearSetBits(IN PRTL_BITMAP BitMap,\n                IN ULONG_PTR Length,\n                IN ULONG_PTR Index)\n{\n    return RTL::BitMap::ClearSetBits(BitMap, Length, Index);\n}\n\n/**\n * Compares two GUIDs (Globally Unique Identifiers).\n *\n * @param Guid1\n *        Supplies the first GUID to compare.\n *\n * @param Guid2\n *        Supplies the second GUID to compare.\n *\n * @return This routine returns TRUE if the provided GUIDs are equal, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nRtlCompareGuids(IN PGUID Guid1,\n                IN PGUID Guid2)\n{\n    return RTL::Guid::CompareGuids(Guid1, Guid2);\n}\n\n/**\n * This routine compares the first bytes of the specified memory buffers.\n *\n * @param LeftBuffer\n *        Supplies a pointer to the first block of memory to compare.\n *\n * @param RightBuffer\n *        Supplies a pointer to the second block of memory to compare.\n *\n * @param Length\n *        Specifies a number of bytes to compare.\n *\n * @return This routine returns a number of bytes that are equal in both memory blocks.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareMemory(IN PCVOID LeftBuffer,\n                 IN PCVOID RightBuffer,\n                 IN SIZE_T Length)\n{\n    return RTL::Memory::CompareMemory(LeftBuffer, RightBuffer, Length);\n}\n\n/**\n * Compares at most specified number of characters of two C strings.\n *\n * @param String1\n *        String to be compared.\n *\n * @param String2\n *        String to be compared.\n *\n * @param Length\n *        Maximum number of characters to compare. If no limit set, it compares whole strings.\n *\n * @return Integral value indicating the relationship between the strings.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareString(IN PCSTR String1,\n                 IN PCSTR String2,\n                 IN SIZE_T Length)\n{\n    return RTL::String::CompareString(String1, String2, Length);\n}\n\n/**\n * Compares at most specified number of characters of two C strings, while ignoring differences in case.\n *\n * @param String1\n *        String to be compared.\n *\n * @param String2\n *        String to be compared.\n *\n * @param Length\n *        Maximum number of characters to compare. If no limit set, it compares whole strings.\n *\n * @return Integral value indicating the relationship between the strings.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareStringInsensitive(IN PCSTR String1,\n                            IN PCSTR String2,\n                            IN SIZE_T Length)\n{\n    return RTL::String::CompareStringInsensitive(String1, String2, Length);\n}\n\n/**\n * Compares at most specified number of characters of two C wide strings.\n *\n * @param String1\n *        Wide string to be compared.\n *\n * @param String2\n *        Wide string to be compared.\n *\n * @param Length\n *        Maximum number of characters to compare. If no limit set, it compares whole wide strings.\n *\n * @return Integral value indicating the relationship between the wide strings.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareWideString(IN PCWSTR String1,\n                     IN PCWSTR String2,\n                     IN SIZE_T Length)\n{\n    return RTL::WideString::CompareWideString(String1, String2, Length);\n}\n\n/**\n * Compares at most specified number of characters of two C wide strings, while ignoring differences in case.\n *\n * @param String1\n *        Wide string to be compared.\n *\n * @param String2\n *        Wide string to be compared.\n *\n * @param Length\n *        Maximum number of characters to compare. If no limit set, it compares whole wide strings.\n *\n * @return Integral value indicating the relationship between the wide strings.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nSIZE_T\nRtlCompareWideStringInsensitive(IN PCWSTR String1,\n                                IN PCWSTR String2,\n                                IN SIZE_T Length)\n{\n    return RTL::WideString::CompareWideStringInsensitive(String1, String2, Length);\n}\n\n/**\n * Appends a copy of the source string to the end of the destination string.\n *\n * @param Destination\n *        Supplies a pointer to the NULL-terminated string to append to.\n *\n * @param Source\n *        Supplies a pointer to the NULL-terminated string to copy from.\n *\n * @param Count\n *        Sets a maximum number of characters to copy. If no limit set, appends whole string.\n *\n * @return This routine returns a copy of a destination string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPCHAR\nRtlConcatenateString(OUT PCHAR Destination,\n                               IN PCHAR Source,\n                               IN SIZE_T Count)\n{\n    return RTL::String::ConcatenateString(Destination, Source, Count);\n}\n\n/**\n * Appends a copy of the source wide string to the end of the destination wide string.\n *\n * @param Destination\n *        Supplies a pointer to the NULL-terminated wide string to append to.\n *\n * @param Source\n *        Supplies a pointer to the NULL-terminated wide string to copy from.\n *\n * @param Count\n *        Sets a maximum number of wide characters to copy. If no limit set, appends whole wide string.\n *\n * @return This routine returns a copy of a destination wide string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPWCHAR\nRtlConcatenateWideString(OUT PWCHAR Destination,\n                         IN PWCHAR Source,\n                         IN SIZE_T Count)\n{\n    return RTL::WideString::ConcatenateWideString(Destination, Source, Count);\n}\n\n/**\n * Converts the 32-bit signed value to a large integer.\n *\n * @param Value\n *        Supplies the value to convert.\n *\n * @return This routine returns the large integer representation of the given value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLARGE_INTEGER\nRtlConvertToLargeInteger32(IN LONG Value)\n{\n    return RTL::Math::ConvertToLargeInteger32(Value);\n}\n\n/**\n * Converts the 32-bit unsigned value to a large integer.\n *\n * @param Value\n *        Supplies the value to convert.\n *\n * @return This routine returns the large integer representation of the given value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLARGE_INTEGER\nRtlConvertToLargeIntegerUnsigned32(IN ULONG Value)\n{\n    return RTL::Math::ConvertToLargeIntegerUnsigned32(Value);\n}\n\n/**\n * This routine copies a block of memory.\n *\n * @param Destination\n *        Supplies a pointer to the buffer where data will be copied to.\n *\n * @param Source\n *        Supplies a pointer to the source buffer that will be copied.\n *\n * @param Length\n *        Specifies the number of bytes to copy.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlCopyMemory(OUT PVOID Destination,\n              IN PCVOID Source,\n              IN SIZE_T Length)\n{\n    RTL::Memory::CopyMemory(Destination, Source, Length);\n}\n\n/**\n * Copies a string from a buffer into another buffer, ensuring that the destination string is NULL-terminated.\n *\n * @param Destination\n *        Supplies a pointer to the destination buffer.\n *\n * @param Source\n *        Supplies a pointer to the source buffer.\n *\n * @param Length\n *        Supplies the length of the string to copy.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nRtlCopyString(IN PCHAR Destination,\n              IN PCSTR Source,\n              IN ULONG Length)\n{\n    RTL::String::CopyString(Destination, Source, Length);\n}\n\n/**\n * Copies a wide string from a buffer into another buffer, ensuring that the destination string is NULL-terminated.\n *\n * @param Destination\n *        Supplies a pointer to the destination buffer.\n *\n * @param Source\n *        Supplies a pointer to the source buffer.\n *\n * @param Length\n *        Supplies the length of the wide string to copy.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nRtlCopyWideString(IN PWCHAR Destination,\n                  IN PCWSTR Source,\n                  IN ULONG Length)\n{\n    RTL::WideString::CopyWideString(Destination, Source, Length);\n}\n\n/**\n * Divides a signed large integer by a 32-bit divisor.\n *\n * @param Dividend\n *        Supplies a large integer to be divided.\n *\n * @param Divisor\n *        Supplies a 32-bit divisor.\n *\n * @param Remainder\n *        Supplies a pointer that receives the divide remainder.\n *\n * @return This routine returns the quotient.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLARGE_INTEGER\nRtlDivideLargeInteger(IN LARGE_INTEGER Dividend,\n                      IN ULONG Divisor,\n                      OUT PULONG Remainder)\n{\n    return RTL::Math::DivideLargeInteger(Dividend, Divisor, Remainder);\n}\n\n/**\n * Searches the bit map for a contiguous region of clear bits.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length of contiguous region (number of clear bits) to look for.\n *\n * @param Index\n *        Supplies the index of the first bit to start the search at a given position.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nULONG_PTR\nRtlFindClearBits(IN PRTL_BITMAP BitMap,\n                 IN ULONG_PTR Length,\n                 IN ULONG_PTR Index)\n{\n    return RTL::BitMap::FindClearBits(BitMap, Length, Index);\n}\n\n/**\n * Searches the bit map for a contiguous region of set bits.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length of contiguous region (number of set bits) to look for.\n *\n * @param Index\n *        Supplies the index of the first bit to start the search at a given position.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nULONG_PTR\nRtlFindSetBits(IN PRTL_BITMAP BitMap,\n               IN ULONG_PTR Length,\n               IN ULONG_PTR Index)\n{\n    return RTL::BitMap::FindSetBits(BitMap, Length, Index);\n}\n\n/**\n * Finds the first occurrence of the search string in the source string.\n *\n * @param Source\n *        Supplies a pointer to the source string.\n *\n * @param Search\n *        Supplies a pointer to the search string.\n *\n * @return This routine returns a pointer to the first occurrence of the search string in the source string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPCSTR\nRtlFindString(IN PCSTR Source,\n              IN PCSTR Search)\n{\n    return RTL::String::FindString(Source, Search);\n}\n\n/**\n * Finds the first case-insensitive occurrence of the search string in the source string.\n *\n * @param Source\n *        Supplies a pointer to the source string.\n *\n * @param Search\n *        Supplies a pointer to the search string.\n *\n * @return This routine returns a pointer to the first occurrence of the search string in the source string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPCSTR\nRtlFindStringInsensitive(IN PCSTR Source,\n                         IN PCSTR Search)\n{\n    return RTL::String::FindStringInsensitive(Source, Search);\n}\n\n/**\n * Finds the first occurrence of the search wide string in the source wide string.\n *\n * @param Source\n *        Supplies a pointer to the source wide string.\n *\n * @param Search\n *        Supplies a pointer to the search wide string.\n *\n * @return This routine returns a pointer to the first occurrence of the search wide string in the source wide string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPCWSTR\nRtlFindWideString(IN PCWSTR Source,\n               IN PCWSTR Search)\n{\n    return RTL::WideString::FindWideString(Source, Search);\n}\n\n/**\n * Finds the first case-insensitive occurrence of the search wide string in the source wide string.\n *\n * @param Source\n *        Supplies a pointer to the source wide string.\n *\n * @param Search\n *        Supplies a pointer to the search wide string.\n *\n * @return This routine returns a pointer to the first occurrence of the search wide string in the source wide string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPCWSTR\nRtlFindWideStringInsensitive(IN PCWSTR Source,\n                             IN PCWSTR Search)\n{\n    return RTL::WideString::FindWideStringInsensitive(Source, Search);\n}\n\n/**\n * Initializes a bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map to initialize.\n *\n * @param Buffer\n *        Supplies a pointer to the buffer that will be used as a bit map.\n *\n * @param Size\n *        Supplies a size of the bit map.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlInitializeBitMap(IN PRTL_BITMAP BitMap,\n                    IN PULONG_PTR Buffer,\n                    IN ULONG Size)\n{\n    RTL::BitMap::InitializeBitMap(BitMap, Buffer, Size);\n}\n\n/**\n * This routine initializes a structure representing the head of a double-linked list.\n *\n * @param ListHead\n *        Pointer to a structure that serves as the list header.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\nRtlInitializeListHead(IN PLIST_ENTRY ListHead)\n{\n    RTL::LinkedList::InitializeListHead(ListHead);\n}\n\n/**\n * This routine inserts an entry at the head of a doubly linked list.\n *\n * @param ListHead\n *        Pointer to the head of the list.\n *\n * @param Entry\n *        Pointer to the entry that will be inserted in the list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\nRtlInsertHeadList(IN OUT PLIST_ENTRY ListHead,\n                  IN PLIST_ENTRY Entry)\n{\n    RTL::LinkedList::InsertHeadList(ListHead, Entry);\n}\n\n/**\n * This routine inserts an entry at the tail of a doubly linked list.\n *\n * @param ListHead\n *        Pointer to the head of the list.\n *\n * @param Entry\n *        Pointer to the entry that will be inserted in the list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\nRtlInsertTailList(IN OUT PLIST_ENTRY ListHead,\n                  IN PLIST_ENTRY Entry)\n{\n    RTL::LinkedList::InsertTailList(ListHead, Entry);\n}\n\n/**\n * Indicates whether a doubly linked list structure is empty, or not initialized at all.\n *\n * @param ListHead\n *        Pointer to a structure that represents the head of the list.\n *\n * @return TRUE if there are currently no entries in the list or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nBOOLEAN\nRtlListEmpty(IN PLIST_ENTRY ListHead)\n{\n    return RTL::LinkedList::ListEmpty(ListHead);\n}\n\n/**\n * This routine detects a loop in a doubly linked list.\n *\n * @param ListHead\n *        Pointer to a structure that represents the head of the list.\n *\n * @return TRUE if linked list contains a loop or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nBOOLEAN\nRtlListLoop(IN PLIST_ENTRY ListHead)\n{\n    return RTL::LinkedList::ListLoop(ListHead);\n}\n\n/**\n * This routine copies a block of memory either forward of backward, depeding\n * if source and destination buffers overlap or not.\n *\n * @param Destination\n *        Supplies a pointer to the buffer where data will be copied to.\n *\n * @param Source\n *        Supplies a pointer to the source buffer that will be copied.\n *\n * @param Length\n *        Specifies the number of bytes to copy.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlMoveMemory(OUT PVOID Destination,\n              IN PCVOID Source,\n              IN SIZE_T Length)\n{\n    RTL::Memory::MoveMemory(Destination, Source, Length);\n}\n\n/**\n * Multiplies a signed large integer by a signed integer.\n *\n * @param Multiplicand\n *        Supplies a large integer to be multiplied.\n *\n * @param Multiplier\n *        Supplies an integer by which the large integer is multiplied.\n *\n * @return This routine returns the result of the multiplication.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLARGE_INTEGER\nRtlMultiplyLargeInteger(IN LARGE_INTEGER Multiplicand,\n                                IN LONG Multiplier)\n{\n    return RTL::Math::MultiplyLargeInteger(Multiplicand, Multiplier);\n}\n\n/**\n * This routine removes an entry from a doubly linked list.\n *\n * @param Entry\n *        Pointer to the entry that will be removed from the list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\nRtlRemoveEntryList(IN PLIST_ENTRY Entry)\n{\n    RTL::LinkedList::RemoveEntryList(Entry);\n}\n\n/**\n * Reverses a characters order in a string. It modifies the original, input variable.\n *\n * @param String\n *        Supplies a pointer to the string to reverse.\n *\n * @param Length\n *        Supplies the length of the string to reverse.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nRtlReverseString(IN OUT PCHAR String,\n                 IN ULONG Length)\n{\n    RTL::String::ReverseString(String, Length);\n}\n\n/**\n * Reverses a characters order in a wide string. It modifies the original, input variable.\n *\n * @param String\n *        Supplies a pointer to the wide string to reverse.\n *\n * @param Length\n *        Supplies the length of the wide string to reverse.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nRtlReverseWideString(IN OUT PWCHAR String,\n                     IN ULONG Length)\n{\n    RTL::WideString::ReverseWideString(String, Length);\n}\n\n/**\n * This routine compares the first bytes of the specified memory buffers.\n *\n * @param LeftBuffer\n *        Supplies a pointer to the first block of memory to compare.\n *\n * @param RightBuffer\n *        Supplies a pointer to the second block of memory to compare.\n *\n * @param Length\n *        Specifies a number of bytes to compare.\n *\n * @return Returns TRUE if both buffers are equal up to the specified length, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nBOOLEAN\nRtlSameMemory(IN PCVOID LeftBuffer,\n              IN PCVOID RightBuffer,\n              IN SIZE_T Length)\n{\n    return RTL::Memory::SameMemory(LeftBuffer, RightBuffer, Length);\n}\n\n/**\n * Sets all bits in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlSetAllBits(IN PRTL_BITMAP BitMap)\n{\n    RTL::BitMap::SetAllBits(BitMap);\n}\n\n/**\n * Sets a single bit in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Bit\n *        Specifies the number of the bit to be set.\n *\n * @return This routine does not return any value.\n *\n * @since NT 5.1\n */\nXTCLINK\nXTAPI\nVOID\nRtlSetBit(IN PRTL_BITMAP BitMap,\n          IN ULONG_PTR Bit)\n{\n    RTL::BitMap::SetBit(BitMap, Bit);\n}\n\n/**\n * Sets a specified set of bits within a bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param StartingIndex\n *        Supplies the starting index of the first bit to set.\n *\n * @param Length\n *        Supplies the length (number of bits) to set.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlSetBits(IN PRTL_BITMAP BitMap,\n           IN ULONG_PTR StartingIndex,\n           IN ULONG_PTR Length)\n{\n    RTL::BitMap::SetBits(BitMap, StartingIndex, Length);\n}\n\n/**\n * Searches the bit map for a contiguous region of clear bits and sets them.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Length\n *        Supplies the length of contiguous region (number of clear bits) to look for.\n *\n * @param Index\n *        Supplies the index of the first bit to start the search at a given position.\n *\n * @return This routine returns the bit map index position of the contiguous region found, or MAXULONG_PTR if not found.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nULONG\nRtlSetClearBits(IN PRTL_BITMAP BitMap,\n                IN ULONG_PTR Length,\n                IN ULONG_PTR Index)\n{\n    return RTL::BitMap::SetClearBits(BitMap, Length, Index);\n}\n\n/**\n * This routine fills a section of memory with a specified byte.\n *\n * @param Destination\n *        Supplies a pointer to the buffer to fill.\n *\n * @param Byte\n *        Supplies a pattern to fill memory.\n *\n * @param Length\n *        Specifies a number of bytes to store in memory.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nVOID\nRtlSetMemory(OUT PVOID Destination,\n             IN UCHAR Byte,\n             IN SIZE_T Length)\n{\n    RTL::Memory::SetMemory(Destination, Byte, Length);\n}\n\n/**\n * Calculates the length of a given string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to be examined.\n *\n * @param MaxLength\n *        Maximum number of characters to examine. If no limit set, it examines whole string.\n *\n * @return The length of the NULL-terminated string.\n *\n * @since: XT 1.0\n */\nXTCLINK\nXTAPI\nSIZE_T\nRtlStringLength(IN PCSTR String,\n                IN SIZE_T MaxLength)\n{\n    return RTL::String::StringLength(String, MaxLength);\n}\n\n/**\n * Converts a multibyte character string to its wide character representation.\n *\n * @param Destination\n *        Pointer to wide character array where the wide string will be stored\n *\n * @param Source\n *        Pointer to the first element of a multibyte string to convert.\n *\n * @param Length\n *        Number of characters in the source string.\n *\n * @return Returns the number of wide characters written to the destination array on success, or -1 on error.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nSIZE_T\nRtlStringToWideString(OUT PWCHAR Destination,\n                      IN PCSTR *Source,\n                      IN SIZE_T Length)\n{\n    return RTL::String::StringToWideString(Destination, Source, Length);\n}\n\n/**\n * Tests a state of a single bit in the bit map.\n *\n * @param BitMap\n *        Supplies a pointer to the bit map.\n *\n * @param Bit\n *        Specifies the number of the bit to be tested.\n *\n * @return This routine returns TRUE when bit is set, or FALSE otherwise.\n *\n * @since NT 5.1\n */\nXTCLINK\nXTAPI\nBOOLEAN\nRtlTestBit(IN PRTL_BITMAP BitMap,\n                     IN ULONG_PTR Bit)\n{\n    return RTL::BitMap::TestBit(BitMap, Bit);\n}\n\n/**\n * Converts a TIME_FIELDS calendar structure to a 64-bit Unix timestamp.\n *\n * @param TimeFields\n *        Supplies a pointer to a fully populated TIME_FIELDS structure.\n *\n * @param UnixTime\n *        Supplies a pointer to a 64-bit integer that receives the number of\n *        seconds elapsed since January 1, 1970.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nXTSTATUS\nRtlTimeFieldsToUnixEpoch(IN PTIME_FIELDS TimeFields,\n                         OUT PLONGLONG UnixTime)\n{\n    return RTL::Time::TimeFieldsToUnixEpoch(TimeFields, UnixTime);\n}\n\n/**\n * Converts a TIME_FIELDS calendar structure to a 64-bit XT timestamp.\n *\n * @param TimeFields\n *        Supplies a pointer to a fully populated TIME_FIELDS structure.\n *\n * @param Time\n *        Supplies a pointer to variable that receives the converted time value in 100-nanosecond\n *        intervals since January 1, 1601.\n *\n * @return This routine returns the status code.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nXTSTATUS\nRtlTimeFieldsToXtEpoch(IN PTIME_FIELDS TimeFields,\n                       OUT PLARGE_INTEGER XtTime)\n{\n    return RTL::Time::TimeFieldsToXtEpoch(TimeFields, XtTime);\n}\n\n/**\n * Finds the next token in a NULL-terminated string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to tokenize.\n *\n * @param Delimiter\n *        Pointer to the NULL-terminated string identifying delimiters.\n *\n * @param SavePtr\n *        Pointer to an object used to store routine internal state.\n *\n * @return Pointer to the beginning of the next token or NULL if there are no more tokens.\n *\n * @since: XT 1.0\n */\nXTCLINK\nXTAPI\nPCHAR\nRtlTokenizeString(IN PCHAR String,\n                  IN PCSTR Delimiter,\n                  IN OUT PCHAR *SavePtr)\n{\n    return RTL::String::TokenizeString(String, Delimiter, SavePtr);\n}\n\n/**\n * Finds the next token in a NULL-terminated wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to tokenize.\n *\n * @param Delimiter\n *        Pointer to the NULL-terminated wide string identifying delimiters.\n *\n * @param SavePtr\n *        Pointer to an object used to store routine internal state.\n *\n * @return Pointer to the beginning of the next token or NULLPTR if there are no more tokens.\n *\n * @since: XT 1.0\n */\nXTCLINK\nXTAPI\nPWCHAR\nRtlTokenizeWideString(IN PWCHAR String,\n                      IN PCWSTR Delimiter,\n                      IN OUT PWCHAR *SavePtr)\n{\n    return RTL::WideString::TokenizeWideString(String, Delimiter, SavePtr);\n}\n\n/**\n * Converts a character to lowercase.\n *\n * @param Character\n *        Character to be converted.\n *\n * @return Converted character or original character if it was not uppercase.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nCHAR\nRtlToLowerCharacter(IN CHAR Character)\n{\n    return RTL::String::ToLowerCharacter(Character);\n}\n\n/**\n * Converts a wide character to lowercase.\n *\n * @param Character\n *        Wide character to be converted.\n *\n * @return Converted wide character or original character if it was not uppercase.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nWCHAR\nRtlToLowerWideCharacter(IN WCHAR Character)\n{\n    return RTL::WideString::ToLowerWideCharacter(Character);\n}\n\n/**\n * Converts a character to uppercase.\n *\n * @param Character\n *        Character to be converted.\n *\n * @return Converted character or original character if it was not lowercase.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nCHAR\nRtlToUpperCharacter(IN CHAR Character)\n{\n    return RTL::String::ToUpperCharacter(Character);\n}\n\n/**\n * Converts a wide character to uppercase.\n *\n * @param Character\n *        Wide character to be converted.\n *\n * @return Converted wide character or original character if it was not lowercase.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nWCHAR\nRtlToUpperWideCharacter(IN WCHAR Character)\n{\n    return RTL::WideString::ToUpperWideCharacter(Character);\n}\n\n/**\n * Removes certain characters from a beginning of the string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to be trimmed.\n *\n * @return This routine returns a pointer to the left-trimmed string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPCHAR\nRtlTrimLeftString(IN PCHAR String)\n{\n    return RTL::String::TrimLeftString(String);\n}\n\n/**\n * Removes certain characters from a beginning of the wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to be trimmed.\n *\n * @return This routine returns a pointer to the left-trimmed wide string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPWCHAR\nRtlTrimLeftWideString(IN PWCHAR String)\n{\n    return RTL::WideString::TrimLeftWideString(String);\n}\n\n/**\n * Removes certain characters from the end of the string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to be trimmed.\n *\n * @return This routine returns a pointer to the right-trimmed string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPCHAR\nRtlTrimRightString(IN PCHAR String)\n{\n    return RTL::String::TrimRightString(String);\n}\n\n/**\n * Removes certain characters from the end of the wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to be trimmed.\n *\n * @return This routine returns a pointer to the right-trimmed wide string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPWCHAR\nRtlTrimRightWideString(IN PWCHAR String)\n{\n    return RTL::WideString::TrimRightWideString(String);\n}\n\n/**\n * Removes certain characters from the beginning and the end of the string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to be trimmed.\n *\n * @return This routine returns a pointer to the trimmed string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPCHAR\nRtlTrimString(IN PCHAR String)\n{\n    return RTL::String::TrimLeftString(RTL::String::TrimRightString(String));\n}\n\n/**\n * Removes certain characters from the beginning and the end of the wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to be trimmed.\n *\n * @return This routine returns a pointer to the trimmed wide string.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nPWCHAR\nRtlTrimWideString(IN PWCHAR String)\n{\n    return RTL::WideString::TrimWideString(String);\n}\n\n/**\n * Calculates the length of a given wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to be examined.\n *\n * @param MaxLength\n *        Maximum number of wide characters to examine. If no limit set, it examines whole string.\n *\n * @return The length of the NULL-terminated wide string.\n *\n * @since: XT 1.0\n */\nXTCLINK\nXTAPI\nSIZE_T\nRtlWideStringLength(IN PCWSTR String,\n                    IN SIZE_T MaxLength)\n{\n    return RTL::WideString::WideStringLength(String, MaxLength);\n}\n\n/**\n * This routine fills a section of memory with zeroes.\n *\n * @param Destination\n *        Supplies a pointer to the buffer to fill.\n *\n * @param Length\n *        Specifies a number of bytes to be filled with zeroes.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTCLINK\nXTAPI\nVOID\nRtlZeroMemory(OUT PVOID Destination,\n              IN SIZE_T Length)\n{\n    RTL::Memory::ZeroMemory(Destination, Length);\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/guid.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/guid.cc\n * DESCRIPTION:     GUID manipulation routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Compares two GUIDs (Globally Unique Identifiers).\n *\n * @param Guid1\n *        Supplies the first GUID to compare.\n *\n * @param Guid2\n *        Supplies the second GUID to compare.\n *\n * @return This routine returns TRUE if the provided GUIDs are equal, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nRTL::Guid::CompareGuids(IN PGUID Guid1,\n                        IN PGUID Guid2)\n{\n    PUINT Guid1Ptr, Guid2Ptr;\n\n    /* Cast GUIDs to UINT to compare 32-bits at a time */\n    Guid1Ptr = (PUINT)Guid1;\n    Guid2Ptr = (PUINT)Guid2;\n\n    /* Compare GUIDs */\n    return (Guid1Ptr[0] == Guid2Ptr[0] && Guid1Ptr[1] == Guid2Ptr[1] &&\n            Guid1Ptr[2] == Guid2Ptr[2] && Guid1Ptr[3] == Guid2Ptr[3]);\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/i686/dispatch.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/i686/dispatch.cc\n * DESCRIPTION:     Dispatching support for i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Returns the stack limits for the current thread.\n *\n * @param StackBase\n *        Supplies a pointer to memory area, where the stack base will be stored.\n *\n * @param StackLimit\n *        Suppliws a pointer to memory area, where the stack limit will be stored.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::Dispatcher::GetStackLimits(OUT PULONG_PTR StackBase,\n                                OUT PULONG_PTR StackLimit)\n{\n    PKTHREAD Thread = KE::Processor::GetCurrentThread();\n    *StackBase = (ULONG_PTR)Thread->StackBase - sizeof(FX_SAVE_AREA);\n    *StackLimit = (ULONG_PTR)Thread->StackLimit;\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/i686/exsup.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/i686/exsup.cc\n * DESCRIPTION:     Exception handling for i686 architecture\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n *                  Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Handles SEH structured exception frames.\n *\n * @param ExceptionRecord\n *        A pointer to the exception record.\n *\n * @param EstablisherFrame\n *        The address of the base of the fixed stack allocation.\n *\n * @param ContextRecord\n *       A pointer to the context record at the time the exception was raised.\n *\n * @param DispatcherContext\n *      A pointer to the dispatcher context for the function.\n *\n * @return This routine returns an exception disposition value if the exception was not handled by any filter.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nEXCEPTION_DISPOSITION\n__C_specific_handler(IN PEXCEPTION_RECORD ExceptionRecord,\n                     IN PVOID EstablisherFrame,\n                     IN OUT PCONTEXT ContextRecord,\n                     IN OUT PVOID DispatcherContext)\n{\n    UNIMPLEMENTED;\n\n    /* Continue execution */\n    return ExceptionContinueExecution;\n}\n\n/**\n * Handles C++ structured exception frames. This implementation displays a panic screen and halts the system.\n *\n * @param ExceptionRecord\n *        A pointer to the exception record that is passed to the possible catch statements.\n *\n * @param EstablisherFrame\n *        A pointer to the stack frame that is used to handle the exception.\n *\n * @param ContextRecord\n *       A pointer to the context record (not used on Intel CPUs).\n *\n * @param DispatcherContext\n *      A pointer to the dispatcher provding information about function entry and stack frame (not used on Intel CPUs).\n *\n * @return This routine returns an exception disposition value if the exception was not handled by any filter.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nEXCEPTION_DISPOSITION\n__CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,\n                   IN PVOID EstablisherFrame,\n                   IN OUT PCONTEXT ContextRecord,\n                   IN OUT PVOID DispatcherContext)\n{\n    UNIMPLEMENTED;\n\n    /* Disable interrupts and hang */\n    AR::CpuFunctions::ClearInterruptFlag();\n    KE::Crash::Panic(0);\n\n    /* Continue search */\n    return ExceptionContinueSearch;\n}\n\n/**\n * Finds the appropriate exception handler to process the current exception.\n *\n * @param ExceptionRecord\n *        A pointer to the exception record providing information about the specific exception.\n *\n * @param Registration\n *        A pointer to the record that indicates which scope table should be used to find the exception handler.\n *\n * @param Context\n *        Reserved.\n *\n * @param Dispatcher\n *        Reserved.\n *\n * @return This routine returns DISPOSITION_DISMISS or DISPOSITION_CONTINUE_SEARCH.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nINT\n_except_handler3(IN PEXCEPTION_RECORD ExceptionRecord,\n                 IN PVOID Registration,\n                 IN PCONTEXT Context,\n                 IN PVOID Dispatcher)\n{\n    UNIMPLEMENTED;\n\n    /* Handler not found */\n    return 0;\n}\n\n/**\n * Handles pure virtual function call error. This implementation displays a panic screen and halts the system.\n *\n * @return This function does not return any value.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTCDECL\nVOID\n_purecall(VOID)\n{\n    UNIMPLEMENTED;\n\n    /* Disable interrupts and hang */\n    AR::CpuFunctions::ClearInterruptFlag();\n    KE::Crash::Panic(0);\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/i686/intrin.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/i686/intrin.cc\n * DESCRIPTION:     Compiler intrinsic support routines\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Divides a 64-bit signed integer by a 64-bit signed integer.\n *\n * @param Dividend\n *        Supplies the 64-bit signed dividend.\n *\n * @param Divisor\n *        Supplies the 64-bit signed divisor.\n *\n * @return This routine returns the 64-bit signed quotient.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLONGLONG\n_alldiv(IN LONGLONG Dividend,\n        IN LONGLONG Divisor)\n{\n    /* Call the internal signed division routine and return the quotient */\n    return RTL::Math::Divide64(Dividend, Divisor, NULLPTR);\n}\n\n/**\n * Divides a 64-bit signed integer by a 64-bit signed integer and retrieves the remainder.\n *\n * @param Dividend\n *        Supplies the 64-bit signed dividend.\n *\n * @param Divisor\n *        Supplies the 64-bit signed divisor.\n *\n * @param Remainder\n *        Supplies a pointer to a variable that receives the 64-bit signed remainder.\n *\n * @return This routine returns the 64-bit signed quotient.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLONGLONG\n_alldvrm(IN LONGLONG Dividend,\n         IN LONGLONG Divisor,\n         OUT PLONGLONG Remainder)\n{\n    /* Call the internal signed division routine to compute both quotient and remainder */\n    return RTL::Math::Divide64(Dividend, Divisor, Remainder);\n}\n/**\n * Calculates the remainder of a 64-bit signed integer division.\n *\n * @param Dividend\n *        Supplies the 64-bit signed dividend.\n *\n * @param Divisor\n *        Supplies the 64-bit signed divisor.\n *\n * @return This routine returns the 64-bit signed remainder.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nLONGLONG\n_allrem(IN LONGLONG Dividend,\n        IN LONGLONG Divisor)\n{\n    LONGLONG Remainder;\n\n    /* Call the internal signed division routine and return the computed remainder */\n    RTL::Math::Divide64(Dividend, Divisor, &Remainder);\n    return Remainder;\n}\n\n/**\n * Divides a 64-bit unsigned integer by a 64-bit unsigned integer.\n *\n * @param Dividend\n *        Supplies the 64-bit unsigned dividend.\n *\n * @param Divisor\n *        Supplies the 64-bit unsigned divisor.\n *\n * @return This routine returns the 64-bit unsigned quotient.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nULONGLONG\n_aulldiv(IN ULONGLONG Dividend,\n         IN ULONGLONG Divisor)\n{\n    /* Call the internal unsigned division routine and return the quotient */\n    return RTL::Math::DivideUnsigned64(Dividend, Divisor, NULLPTR);\n}\n\n/**\n * Divides a 64-bit unsigned integer by a 64-bit unsigned integer and retrieves the remainder.\n *\n * @param Dividend\n *        Supplies the 64-bit unsigned dividend.\n *\n * @param Divisor\n *        Supplies the 64-bit unsigned divisor.\n *\n * @param Remainder\n *        Supplies a pointer to a variable that receives the 64-bit unsigned remainder.\n *\n * @return This routine returns the 64-bit unsigned quotient.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nULONGLONG\n_aulldvrm(IN ULONGLONG Dividend,\n          IN ULONGLONG Divisor,\n          OUT PULONGLONG Remainder)\n{\n    /* Call the internal unsigned division routine to compute both quotient and remainder */\n    return RTL::Math::DivideUnsigned64(Dividend, Divisor, Remainder);\n}\n\n/**\n * Calculates the remainder of a 64-bit unsigned integer division.\n *\n * @param Dividend\n *        Supplies the 64-bit unsigned dividend.\n *\n * @param Divisor\n *        Supplies the 64-bit unsigned divisor.\n *\n * @return This routine returns the 64-bit unsigned remainder.\n *\n * @since XT 1.0\n */\nXTCLINK\nXTAPI\nULONGLONG\n_aullrem(IN ULONGLONG Dividend,\n         IN ULONGLONG Divisor)\n{\n    ULONGLONG Remainder;\n\n    /* Call the internal unsigned division routine and return the computed remainder */\n    RTL::Math::DivideUnsigned64(Dividend, Divisor, &Remainder);\n    return Remainder;\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/llist.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/llist.cc\n * DESCRIPTION:     Doubly linked list manipulation routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Retrieves the first entry from a doubly linked list without removing it from the list.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that serves as the list header.\n *\n * @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.\n *\n * @since XT 1.0\n */\nXTCDECL\nPLIST_ENTRY\nRTL::LinkedList::GetFirstEntry(IN PLIST_ENTRY ListHead)\n{\n    /* Check if the list is empty */\n    if(ListEmpty(ListHead))\n    {\n        /* Empty list, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Return first entry in the list */\n    return ListHead->Flink;\n}\n\n/**\n * Initializes a structure representing the head of a doubly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that serves as the list header.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::LinkedList::InitializeListHead(IN PLIST_ENTRY ListHead)\n{\n    /* Initialize list head */\n    ListHead->Blink = ListHead;\n    ListHead->Flink = ListHead;\n}\n\n/**\n * Initializes a structure representing the head of a 32bit doubly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that serves as the list header.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::LinkedList::InitializeListHead32(IN PLIST_ENTRY32 ListHead)\n{\n    /* Initialize list head */\n    ListHead->Blink = PtrToUlong(ListHead);\n    ListHead->Flink = PtrToUlong(ListHead);\n}\n\n/**\n * Inserts an entry at the head of a doubly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the list.\n *\n * @param Entry\n *        Supplies a pointer to the entry that will be inserted in the list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,\n                                IN PLIST_ENTRY Entry)\n{\n    /* Insert entry at the head of the list */\n    Entry->Flink = ListHead->Flink;\n    Entry->Blink = ListHead;\n    ListHead->Flink->Blink = Entry;\n    ListHead->Flink = Entry;\n}\n\n/**\n * Inserts an entry at the tail of a doubly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the list.\n *\n * @param Entry\n *        Supplies a pointer to the entry that will be inserted in the list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,\n                                IN PLIST_ENTRY Entry)\n{\n    /* Insert entry at the tail of the list */\n    Entry->Flink = ListHead;\n    Entry->Blink = ListHead->Blink;\n    ListHead->Blink->Flink = Entry;\n    ListHead->Blink = Entry;\n}\n\n/**\n * Indicates whether a doubly linked list structure is empty, or not initialized at all.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that represents the head of the list.\n *\n * @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nRTL::LinkedList::ListEmpty(IN PLIST_ENTRY ListHead)\n{\n    /* Check if the list is empty */\n    return (((ListHead->Flink == NULLPTR) && (ListHead->Blink == NULLPTR)) || (ListHead->Flink == ListHead));\n}\n\n/**\n * Detects a loop in a doubly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that represents the head of the list.\n *\n * @return TRUE if linked list contains a loop or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nRTL::LinkedList::ListLoop(IN PLIST_ENTRY ListHead)\n{\n    PLIST_ENTRY SlowEntry, FastEntry;\n\n    /* Check if list exists */\n    if(ListHead == NULLPTR)\n    {\n        /* No loop in non-existen list */\n        return FALSE;\n    }\n\n    /* Make both references pointing to the start of the list */\n    FastEntry = ListHead;\n    SlowEntry = ListHead;\n\n    /* Iterate through the linked list to find a loop */\n    while(SlowEntry != NULLPTR && FastEntry != NULLPTR && FastEntry->Flink != NULLPTR)\n    {\n        /* Move slow and fast pointers by one and two positions accordingly */\n        SlowEntry = SlowEntry->Flink;\n        FastEntry = FastEntry->Flink->Flink;\n\n        /* Compare both pointers */\n        if(SlowEntry == FastEntry)\n        {\n            /* Loop found */\n            return TRUE;\n        }\n    }\n\n    /* No loop found */\n    return FALSE;\n}\n\n/**\n * Removes an entry from a doubly linked list.\n *\n * @param Entry\n *        Supplies a pointer to the entry that will be removed from the list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::LinkedList::RemoveEntryList(IN PLIST_ENTRY Entry)\n{\n    /* Remove entry from the list */\n    Entry->Flink->Blink = Entry->Blink;\n    Entry->Blink->Flink = Entry->Flink;\n}\n\n/**\n * Splices a doubly linked list at the head of another list. The source list is reinitialized to empty.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that represents the head of the list.\n *\n * @param SpliceList\n *        Supplies a pointer to a structure that represents the head of the list that will be spliced.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::LinkedList::SpliceHeadList(IN OUT PLIST_ENTRY ListHead,\n                                IN OUT PLIST_ENTRY SpliceList)\n{\n    PLIST_ENTRY FirstEntry, LastEntry;\n\n    /* Check if the list to splice is empty */\n    if(SpliceList->Flink == SpliceList)\n    {\n        /* Nothing to splice, return */\n        return;\n    }\n\n    /* Get first and last entries of the list to splice */\n    FirstEntry = SpliceList->Flink;\n    LastEntry = SpliceList->Blink;\n\n    /* Splice the list at the head of destination */\n    FirstEntry->Blink = ListHead;\n    LastEntry->Flink = ListHead->Flink;\n    ListHead->Flink->Blink = LastEntry;\n    ListHead->Flink = FirstEntry;\n\n    /* Reinitialize the source list to empty */\n    SpliceList->Blink = SpliceList;\n    SpliceList->Flink = SpliceList;\n}\n\n/**\n * Splices a doubly linked list at the tail of another list. The source list is reinitialized to empty.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the destination list.\n *\n * @param SpliceList\n *        Supplies a pointer to the head of the list that will be spliced.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::LinkedList::SpliceTailList(IN OUT PLIST_ENTRY ListHead,\n                                IN OUT PLIST_ENTRY SpliceList)\n{\n    PLIST_ENTRY FirstEntry, LastEntry;\n\n    /* Check if the list to splice is empty */\n    if(SpliceList->Flink == SpliceList)\n    {\n        /* Nothing to splice, return */\n        return;\n    }\n\n    /* Get first and last entries of the list to splice */\n    FirstEntry = SpliceList->Flink;\n    LastEntry = SpliceList->Blink;\n\n    /* Splice the list at the tail of destination */\n    FirstEntry->Blink = ListHead->Blink;\n    LastEntry->Flink = ListHead;\n    ListHead->Blink->Flink = FirstEntry;\n    ListHead->Blink = LastEntry;\n\n    /* Reinitialize the source list to empty */\n    SpliceList->Blink = SpliceList;\n    SpliceList->Flink = SpliceList;\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/math.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/math.cc\n * DESCRIPTION:     Kernel math support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Converts the 32-bit signed value to a large integer.\n *\n * @param Value\n *        Supplies the value to convert.\n *\n * @return This routine returns the large integer representation of the given value.\n *\n * @since XT 1.0\n */\nXTAPI\nLARGE_INTEGER\nRTL::Math::ConvertToLargeInteger32(IN LONG Value)\n{\n    LARGE_INTEGER LargeInt;\n\n    /* Convert the value to a large integer and return it */\n    LargeInt.QuadPart = Value;\n    return LargeInt;\n}\n\n/**\n * Converts the 32-bit unsigned value to a large integer.\n *\n * @param Value\n *        Supplies the value to convert.\n *\n * @return This routine returns the large integer representation of the given value.\n *\n * @since XT 1.0\n */\nXTAPI\nLARGE_INTEGER\nRTL::Math::ConvertToLargeIntegerUnsigned32(IN ULONG Value)\n{\n    LARGE_INTEGER LargeInt;\n\n    /* Convert the value to a large integer and return it */\n    LargeInt.QuadPart = Value;\n    return LargeInt;\n}\n\n/**\n * Determines the number of leading zero bits in a 32-bit unsigned value.\n *\n * @param Value\n *        Supplies the value whose leading zero bits are to be counted.\n *\n * @return This routine returns the number of leading zero bits in the given value.\n *\n * @since XT 1.0\n */\nXTAPI\nINT\nRTL::Math::CountLeadingZeroes32(IN ULONG Value)\n{\n    /* Return a number of leading zero bits */\n    return __builtin_clzl(Value);\n}\n\n/**\n * Determines the number of leading zero bits in a 64-bit unsigned value.\n *\n * @param Value\n *        Supplies the value whose leading zero bits are to be counted.\n *\n * @return This routine returns the number of leading zero bits in the given value.\n *\n * @since XT 1.0\n */\nXTAPI\nINT\nRTL::Math::CountLeadingZeroes64(IN ULONGLONG Value)\n{\n    /* Return a number of leading zero bits */\n    return __builtin_clzll(Value);\n}\n\n/**\n * Determines the number of trailing zero bits in a 32-bit unsigned value.\n *\n * @param Value\n *        Supplies the value whose trailing zero bits are to be counted.\n *\n * @return This routine returns the number of trailing zero bits in the given value.\n *\n * @since XT 1.0\n */\nXTAPI\nINT\nRTL::Math::CountTrailingZeroes32(IN ULONG Value)\n{\n    /* Return a number of trailing zero bits */\n    return __builtin_ctzl(Value);\n}\n\n/**\n * Determines the number of trailing zero bits in a 64-bit unsigned value.\n *\n * @param Value\n *        Supplies the value whose trailing zero bits are to be counted.\n *\n * @return This routine returns the number of trailing zero bits in the given value.\n *\n * @since XT 1.0\n */\nXTAPI\nINT\nRTL::Math::CountTrailingZeroes64(IN ULONGLONG Value)\n{\n    /* Return a number of trailing zero bits */\n    return __builtin_ctzll(Value);\n}\n\n/**\n * Performs a 32-bit divide operation on signed integer numbers.\n *\n * @param Dividend\n *        Supplies a number that is going to be divided.\n *\n * @param Divisor\n *        Supplies a number by which the dividend is divided.\n *\n * @param Remainder\n *        Supplies a pointer that receives the divide remainder.\n *\n * @return This routine returns the quotient.\n *\n * @since XT 1.0\n */\nXTAPI\nLONGLONG\nRTL::Math::Divide32(IN LONG Dividend,\n                    IN LONG Divisor,\n                    OUT PLONG Remainder)\n{\n    LONG Quotient;\n\n    /* Calculate the quotient */\n    Quotient = Dividend / Divisor;\n\n    /* Make sure a pointer to remainder provided */\n    if(Remainder)\n    {\n        /* Calculate remainder */\n        *Remainder = Dividend - (Quotient * Divisor);\n    }\n\n    /* Return the quotient */\n    return Quotient;\n}\n\n/**\n * Performs a 64-bit divide operation on signed integer numbers.\n *\n * @param Dividend\n *        Supplies a number that is going to be divided.\n *\n * @param Divisor\n *        Supplies a number by which the dividend is divided.\n *\n * @param Remainder\n *        Supplies a pointer that receives the divide remainder.\n *\n * @return This routine returns the quotient.\n *\n * @since XT 1.0\n */\nXTAPI\nLONGLONG\nRTL::Math::Divide64(IN LONGLONG Dividend,\n                    IN LONGLONG Divisor,\n                    OUT PLONGLONG Remainder)\n{\n    LONGLONG DividendSign, DivisorSign, Quotient, UDividend, UDivisor;\n\n    /* Remove the sign bit from dividend and divisor if present */\n    DividendSign = Dividend >> ((sizeof(LONGLONG) * BITS_PER_BYTE) - 1);\n    DivisorSign = Divisor >> ((sizeof(LONGLONG) * BITS_PER_BYTE) - 1);\n    UDividend = (Dividend ^ DividendSign) - DividendSign;\n    UDivisor = (Divisor ^ DivisorSign) - DivisorSign;\n\n    /* Calculate the quotient */\n    DividendSign ^= DivisorSign;\n    Quotient = (DivideUnsigned64(UDividend, UDivisor, NULLPTR) ^ DividendSign) - DividendSign;\n\n    /* Make sure a pointer to remainder provided */\n    if(Remainder)\n    {\n        /* Calculate remainder */\n        *Remainder = Dividend - (Quotient * Divisor);\n    }\n\n    /* Return the quotient */\n    return Quotient;\n}\n\n/**\n * Performs a 32-bit divide operation on unsigned integer numbers.\n *\n * @param Dividend\n *        Supplies an unsigned number that is going to be divided.\n *\n * @param Divisor\n *        Supplies an unsigned number by which the dividend is divided.\n *\n * @param Remainder\n *        Supplies a pointer that receives the unsigned divide remainder.\n *\n * @return This routine returns the quotient.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nRTL::Math::DivideUnsigned32(IN ULONG Dividend,\n                            IN ULONG Divisor,\n                            OUT PULONG Remainder)\n{\n    /* Make sure a pointer to remainder provided */\n    if(Remainder)\n    {\n        /* Calculate remainder */\n        *Remainder = Dividend % Divisor;\n    }\n\n    /* Return the quotient */\n    return Dividend / Divisor;\n}\n\n/**\n * Performs a 64-bit divide operation on unsigned integer numbers.\n *\n * @param Dividend\n *        Supplies an unsigned number that is going to be divided.\n *\n * @param Divisor\n *        Supplies an unsigned number by which the dividend is divided.\n *\n * @param Remainder\n *        Supplies a pointer that receives the unsigned divide remainder.\n *\n * @return This routine returns the quotient.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nRTL::Math::DivideUnsigned64(IN ULONGLONG Dividend,\n                            IN ULONGLONG Divisor,\n                            OUT PULONGLONG Remainder)\n{\n    ULARGE_INTEGER DividendParts, DivisorParts, QuotientParts, RemainderParts;\n    LONGLONG Difference;\n    ULONGLONG Shift;\n    ULONG Carry;\n\n    /* Make sure divisor is not 0 */\n    if(Divisor == 0)\n    {\n        /* Cannot divide by 0 */\n        return 0;\n    }\n\n    /* Assign dividend and divisor to large integer representations */\n    DividendParts.QuadPart = Dividend;\n    DivisorParts.QuadPart = Divisor;\n\n    /* Check if dividend is 32-bit value */\n    if(DividendParts.u.HighPart == 0)\n    {\n        /* Check if devisor is 32-bit value */\n        if(DivisorParts.u.HighPart == 0)\n        {\n            /* 32-bit divide operation, check if remainder provided */\n            if(Remainder != NULLPTR)\n            {\n                /* Calculate remainder */\n                *Remainder = DividendParts.u.LowPart % DivisorParts.u.LowPart;\n            }\n\n            /* Return the quotient */\n            return DividendParts.u.LowPart / DivisorParts.u.LowPart;\n        }\n\n        /* 32-bit value divided by a 64-bit value, check if remainder provided */\n        if(Remainder != NULLPTR)\n        {\n            /* Calculate remainder */\n            *Remainder = DividendParts.u.LowPart;\n        }\n\n        /* Return zero as quotient */\n        return 0;\n    }\n\n    /* Dividend is a 64-bit value, check if divisor has a low part */\n    if(DivisorParts.u.LowPart != 0)\n    {\n        /* Divisor has a non-zero low part, check if divisor has a high part */\n        if(DivisorParts.u.HighPart != 0)\n        {\n            /* Divisor is 64-bit value, calculate the shift count */\n            Shift = CountLeadingZeroes32(DivisorParts.u.HighPart) - CountLeadingZeroes32(DividendParts.u.HighPart);\n\n            /* Check if shift count exceeds 32-bits */\n            if(Shift > ((sizeof(ULONG) * BITS_PER_BYTE) - 1))\n            {\n                /* Check if remainder provided */\n                if(Remainder != NULLPTR)\n                {\n                    /* Calculate remainder */\n                    *Remainder = DividendParts.QuadPart;\n                }\n\n                return 0;\n            }\n\n            /* Increase shift and clear quotient low part */\n            Shift++;\n            QuotientParts.u.LowPart = 0;\n\n            /* Check if shift is 32-bits */\n            if(Shift == (sizeof(ULONG) * BITS_PER_BYTE)) {\n                /* Get the quotient high part and remainder */\n                QuotientParts.u.HighPart = DividendParts.u.LowPart;\n                RemainderParts.u.LowPart = DividendParts.u.HighPart;\n                RemainderParts.u.HighPart = 0;\n            } else {\n                /* Get the quotient high part and remainder */\n                QuotientParts.u.HighPart = DividendParts.u.LowPart << ((sizeof(ULONG) * BITS_PER_BYTE) - Shift);\n                RemainderParts.u.LowPart = (DividendParts.u.HighPart << ((sizeof(ULONG) * BITS_PER_BYTE) - Shift)) |\n                                           (DividendParts.u.LowPart >> Shift);\n                RemainderParts.u.HighPart = DividendParts.u.HighPart >> Shift;\n            }\n        }\n        else\n        {\n            /* Divisor is 32-bit value, calculate the shift count */\n            Shift = (sizeof(ULONG) * BITS_PER_BYTE) + 1 +\n                    CountLeadingZeroes32(DivisorParts.u.LowPart) -\n                    CountLeadingZeroes32(DividendParts.u.HighPart);\n\n            /* Check if shift is 32-bit */\n            if(Shift == (sizeof(ULONG) * BITS_PER_BYTE))\n            {\n                /* Get the quotient and remainder */\n                QuotientParts.u.LowPart = 0;\n                QuotientParts.u.HighPart = DividendParts.u.LowPart;\n                RemainderParts.u.LowPart = DividendParts.u.HighPart;\n                RemainderParts.u.HighPart = 0;\n            }\n            else if(Shift < (sizeof(ULONG) * BITS_PER_BYTE))\n            {\n                /* Shift is smaller, get the quotient and remainder */\n                QuotientParts.u.LowPart = 0;\n                QuotientParts.u.HighPart = DividendParts.u.LowPart << ((sizeof(ULONG) * BITS_PER_BYTE) - Shift);\n                RemainderParts.u.LowPart = (DividendParts.u.HighPart <<\n                                           ((sizeof(ULONG) * BITS_PER_BYTE) - Shift)) |\n                                           (DividendParts.u.LowPart >> Shift);\n                RemainderParts.u.HighPart = DividendParts.u.HighPart >> Shift;\n            }\n            else\n            {\n                /* Shift is larger, get the quotient and remainder */\n                QuotientParts.u.LowPart = DividendParts.u.LowPart << ((sizeof(ULONGLONG) * BITS_PER_BYTE) - Shift);\n                QuotientParts.u.HighPart = (DividendParts.u.HighPart << ((sizeof(ULONGLONG) * BITS_PER_BYTE) - Shift)) |\n                                           (DividendParts.u.LowPart >> (Shift - (sizeof(ULONG) * BITS_PER_BYTE)));\n                RemainderParts.u.LowPart = DividendParts.u.HighPart >> (Shift - (sizeof(ULONG) * BITS_PER_BYTE));\n                RemainderParts.u.HighPart = 0;\n            }\n        }\n    }\n    else\n    {\n        /* Divisor is 64-bit value, check if dividend has low part set */\n        if(DividendParts.u.LowPart == 0)\n        {\n            /* Check if remainder provided */\n            if(Remainder != NULLPTR)\n            {\n                /* Calculate the remainder */\n                RemainderParts.u.HighPart = DividendParts.u.HighPart % DivisorParts.u.HighPart;\n                RemainderParts.u.LowPart = 0;\n                *Remainder = RemainderParts.QuadPart;\n            }\n\n            /* Return the quotient */\n            return DividendParts.u.HighPart / DivisorParts.u.HighPart;\n        }\n\n        /* Calculate the shift count */\n        Shift = CountLeadingZeroes32(DivisorParts.u.HighPart) - CountLeadingZeroes32(DividendParts.u.HighPart);\n\n        /* Check if shift exceeds 32-bits */\n        if(Shift > ((sizeof(ULONG) * BITS_PER_BYTE) - 2))\n        {\n            /* Check if remainder provided */\n            if(Remainder != NULLPTR)\n            {\n                /* Calculate the remainder */\n                *Remainder = DividendParts.QuadPart;\n            }\n\n            /* Return 0 */\n            return 0;\n        }\n\n        /* Increase shift and clear quotient low part */\n        Shift++;\n        QuotientParts.u.LowPart = 0;\n\n        /* Get the quotient high part and remainder */\n        QuotientParts.u.HighPart = DividendParts.u.LowPart << ((sizeof(ULONG) * BITS_PER_BYTE) - Shift);\n        RemainderParts.u.HighPart = DividendParts.u.HighPart >> Shift;\n        RemainderParts.u.LowPart = (DividendParts.u.HighPart <<\n                                   ((sizeof(ULONG) * BITS_PER_BYTE) - Shift)) |\n                                   (DividendParts.u.LowPart >> Shift);\n    }\n\n    /* Perform the division until shift is zero */\n    Carry = 0;\n    while(Shift > 0)\n    {\n        /* Shift the remainder and the quotient */\n        RemainderParts.u.HighPart = (RemainderParts.u.HighPart << 1) |\n                                    (RemainderParts.u.LowPart >>\n                                    ((sizeof(ULONG) * BITS_PER_BYTE) - 1));\n        RemainderParts.u.LowPart = (RemainderParts.u.LowPart << 1) |\n                                   (QuotientParts.u.HighPart >>\n                                   ((sizeof(ULONG) * BITS_PER_BYTE) - 1));\n        QuotientParts.u.HighPart = (QuotientParts.u.HighPart << 1) |\n                                   (QuotientParts.u.LowPart >>\n                                   ((sizeof(ULONG) * BITS_PER_BYTE) - 1));\n        QuotientParts.u.LowPart = (QuotientParts.u.LowPart << 1) | Carry;\n\n        /* Set the carry and subtract the divisor */\n        Difference = (LONGLONG)(DivisorParts.QuadPart - RemainderParts.QuadPart - 1) >>\n                     ((sizeof(ULONGLONG) * BITS_PER_BYTE) - 1);\n        Carry = Difference & 0x1;\n        RemainderParts.QuadPart -= DivisorParts.QuadPart & Difference;\n        Shift -= 1;\n    }\n\n    /* Add the carry to the quotient */\n    QuotientParts.QuadPart = (QuotientParts.QuadPart << 1) | Carry;\n\n    /* Check if remainder provided */\n    if(Remainder != NULLPTR)\n    {\n        /* Calculate the remainder */\n        *Remainder = RemainderParts.QuadPart;\n    }\n\n    /* Return the quotient */\n    return QuotientParts.QuadPart;\n}\n\n/**\n * Divides a signed large integer by a 32-bit divisor.\n *\n * @param Dividend\n *        Supplies a large integer to be divided.\n *\n * @param Divisor\n *        Supplies a 32-bit divisor.\n *\n * @param Remainder\n *        Supplies a pointer that receives the divide remainder.\n *\n * @return This routine returns the quotient.\n *\n * @since XT 1.0\n */\nXTAPI\nLARGE_INTEGER\nRTL::Math::DivideLargeInteger(IN LARGE_INTEGER Dividend,\n                              IN ULONG Divisor,\n                              OUT PULONG Remainder)\n{\n    LONGLONG DividendSign, UDividend;\n    LARGE_INTEGER LargeInt;\n\n    /* Remove the sign bit from dividend if present */\n    DividendSign = Dividend.QuadPart >> ((sizeof(LONGLONG) * BITS_PER_BYTE) - 1);\n    UDividend = (Dividend.QuadPart ^ DividendSign) - DividendSign;\n\n    /* Calculate the quotient */\n    LargeInt.QuadPart = (DivideUnsigned64(UDividend, Divisor, NULLPTR) ^ DividendSign) - DividendSign;\n\n    /* Make sure a pointer to remainder provided */\n    if(Remainder)\n    {\n        /* Calculate remainder */\n        *Remainder = Dividend.QuadPart - (LargeInt.QuadPart * Divisor);\n    }\n\n    /* Return the quotient */\n    return LargeInt;\n}\n\n/**\n * Gets the base exponent of a given floating point value.\n *\n * @param Value\n *        Supplies the floating point value to get the base exponent of.\n *\n * @param PowerOfTen\n *        Supplies a pointer that receives the power of ten associated with the base exponent.\n *\n * @return This routine returns the base exponent value.\n *\n * @since XT 1.0\n */\nXTAPI\nLONG\nRTL::Math::GetBaseExponent(IN DOUBLE Value,\n                           OUT PDOUBLE PowerOfTen)\n{\n    LONG BaseExponent, CurrentExponent, Exponent;\n    ULONG ExponentShift, ExponentMask;\n    LARGE_DOUBLE Parts;\n    DOUBLE Power;\n\n    /* Calculate the exponent mask and shift */\n    ExponentMask = DOUBLE_EXPONENT_MASK >> (sizeof(ULONG) * BITS_PER_BYTE);\n    ExponentShift = DOUBLE_EXPONENT_SHIFT - (sizeof(ULONG) * BITS_PER_BYTE);\n\n    /* Check if value is zero */\n    if(Value == 0.0)\n    {\n        /* Return the power of ten and the exponent */\n        *PowerOfTen = 1.0;\n        return 0;\n    }\n\n    /* Get the parts of the value and calculate the exponent by multiplying by log10(2) */\n    Parts.DoublePart = Value;\n    BaseExponent = ((Parts.u.HighPart & ExponentMask) >> ExponentShift) - DOUBLE_EXPONENT_BIAS;\n    Exponent = (LONG)((DOUBLE)BaseExponent * 0.30102999566) + 1;\n\n    /* Set the initial values and calculate the exponent */\n    CurrentExponent = 0;\n    Power = 1.0;\n    if(Exponent > 0)\n    {\n        /* Calculate the exponent */\n        while(CurrentExponent + 10 <= Exponent)\n        {\n            Power *= 0.0000000001;\n            CurrentExponent += 10;\n        }\n\n        while(CurrentExponent + 1 <= Exponent)\n        {\n            Power *= 0.1;\n            CurrentExponent += 1;\n        }\n    }\n    else\n    {\n        /* Calculate the exponent */\n        while(CurrentExponent - 10 >= Exponent)\n        {\n            Power *= 10000000000;\n            CurrentExponent -= 10;\n        }\n\n        while(CurrentExponent - 1 >= Exponent)\n        {\n            Power *= 10.0;\n            CurrentExponent -= 1;\n        }\n    }\n\n    /* Normalize input value */\n    Value *= Power;\n\n    /* Remove all leading zeros, if any */\n    while((Value != 0.0) && ((LONG)Value == 0))\n    {\n        Value *= 10.0;\n        Exponent -= 1;\n        Power *= 10.0;\n    }\n\n    /* Return the power of ten and the exponent */\n    *PowerOfTen = Power;\n    return Exponent;\n}\n\n/**\n * Determines whether a floating-point number is infinite.\n *\n * @param Value\n *        Supplies the floating-point value to test.\n *\n * @return This routine returns TRUE if the argument is infinite or a NaN, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nRTL::Math::InfiniteDouble(IN DOUBLE Value)\n{\n    /* DOUBLE argument in IEEE 754 standard format */\n    union\n    {\n        PDOUBLE Double;\n        struct\n        {\n            UINT MantissaLow:32;\n            UINT MantissaHigh:20;\n            UINT Exponent:11;\n            UINT Sign:1;\n        } *DoubleS;\n    } Var;\n\n    /* Convert input double value to IEEE 754 format */\n    Var.Double = &Value;\n\n    /* Return TRUE if it is infinite, or FALSE otherwise */\n    return ((Var.DoubleS->Exponent & 0x7FF) == 0x7FF);\n}\n\n/**\n * Multiplies a signed large integer by a signed integer.\n *\n * @param Multiplicand\n *        Supplies a large integer to be multiplied.\n *\n * @param Multiplier\n *        Supplies an integer by which the large integer is multiplied.\n *\n * @return This routine returns the result of the multiplication.\n *\n * @since XT 1.0\n */\nXTAPI\nLARGE_INTEGER\nRTL::Math::MultiplyLargeInteger(IN LARGE_INTEGER Multiplicand,\n                                IN LONG Multiplier)\n{\n    LARGE_INTEGER LargeInt;\n\n    /* Perform multiplication and return the result */\n    LargeInt.QuadPart = (LONGLONG) Multiplicand.QuadPart * Multiplier;\n    return LargeInt;\n}\n\n/**\n * Determines whether a floating-point number is a NaN (\"Not a Number\").\n *\n * @param Value\n *        Supplies the floating-point value to test.\n *\n * @return This routine returns TRUE if the argument is a NaN, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nRTL::Math::NanDouble(IN DOUBLE Value)\n{\n    /* DOUBLE argument in IEEE 754 standard format */\n    union\n    {\n        PDOUBLE Double;\n        struct\n        {\n            UINT MantissaLow:32;\n            UINT MantissaHigh:20;\n            UINT Exponent:11;\n            UINT Sign:1;\n        } *DoubleS;\n    } Var;\n\n    /* Convert input double value to IEEE 754 format */\n    Var.Double = &Value;\n\n    /* Return TRUE if it is NaN, or FALSE otherwise */\n    return (Var.DoubleS->Exponent == 0x7FF && (Var.DoubleS->MantissaHigh != 0 || Var.DoubleS->MantissaLow != 0));\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/memory.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/memory.cc\n * DESCRIPTION:     Memory related routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * This routine compares the first bytes of the specified memory buffers.\n *\n * @param LeftBuffer\n *        Supplies a pointer to the first block of memory to compare.\n *\n * @param RightBuffer\n *        Supplies a pointer to the second block of memory to compare.\n *\n * @param Length\n *        Specifies a number of bytes to compare.\n *\n * @return This routine returns a number of bytes that are equal in both memory blocks.\n *\n * @since NT 3.5\n */\nXTAPI\nSIZE_T\nRTL::Memory::CompareMemory(IN PCVOID LeftBuffer,\n                           IN PCVOID RightBuffer,\n                           IN SIZE_T Length)\n{\n    SIZE_T Bytes = 0;\n\n    /* Check if there is anything to compare */\n    if(Length)\n    {\n        /* Iterate through whole buffer length */\n        while(Bytes < Length)\n        {\n            /* Compare bytes from both bufers */\n            if(((CONST PBYTE)LeftBuffer)[Bytes] != ((CONST PBYTE)RightBuffer)[Bytes])\n            {\n                /* Buffers are different */\n                break;\n            }\n\n            /* Increase number of common bytes */\n            Bytes++;\n        }\n    }\n\n    /* Return number of equal characters */\n    return Bytes;\n}\n\n/**\n * This routine copies a block of memory.\n *\n * @param Destination\n *        Supplies a pointer to the buffer where data will be copied to.\n *\n * @param Source\n *        Supplies a pointer to the source buffer that will be copied.\n *\n * @param Length\n *        Specifies the number of bytes to copy.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nRTL::Memory::CopyMemory(OUT PVOID Destination,\n                        IN PCVOID Source,\n                        IN SIZE_T Length)\n{\n    PCHAR DestinationBytes = (PCHAR)Destination;\n    PCCHAR SourceBytes = (PCHAR)Source;\n\n    /* Forward buffer copy */\n    while(Length--)\n    {\n        *DestinationBytes++ = *SourceBytes++;\n    }\n}\n\n/**\n * This routine copies a block of memory either forward of backward, depeding\n * if source and destination buffers overlap or not.\n *\n * @param Destination\n *        Supplies a pointer to the buffer where data will be copied to.\n *\n * @param Source\n *        Supplies a pointer to the source buffer that will be copied.\n *\n * @param Length\n *        Specifies the number of bytes to copy.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nRTL::Memory::MoveMemory(OUT PVOID Destination,\n                        IN PCVOID Source,\n                        IN SIZE_T Length)\n{\n    PCHAR DestinationBytes = (PCHAR)Destination;\n    PCHAR SourceBytes = (PCHAR)Source;\n\n    /* Make sure there is anything to copy */\n    if((!SourceBytes) && (!DestinationBytes))\n    {\n        return;\n    }\n\n    /* Check if source and destination overlaps */\n    if((DestinationBytes > SourceBytes) && (SourceBytes + Length > DestinationBytes))\n    {\n        /* Backward buffer copy */\n        while(Length)\n        {\n            DestinationBytes[Length - 1] = SourceBytes[Length - 1];\n            Length--;\n        }\n    }\n    else\n    {\n        /* Forward buffer copy */\n        CopyMemory(Destination, Source, Length);\n    }\n}\n\n/**\n * This routine compares the first bytes of the specified memory buffers.\n *\n * @param LeftBuffer\n *        Supplies a pointer to the first block of memory to compare.\n *\n * @param RightBuffer\n *        Supplies a pointer to the second block of memory to compare.\n *\n * @param Length\n *        Specifies a number of bytes to compare.\n *\n * @return Returns TRUE if both buffers are equal up to the specified length, or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTAPI\nBOOLEAN\nRTL::Memory::SameMemory(IN PCVOID LeftBuffer,\n                        IN PCVOID RightBuffer,\n                        IN SIZE_T Length)\n{\n    return (CompareMemory(LeftBuffer, RightBuffer, Length) == Length) ? TRUE : FALSE;\n}\n\n/**\n * This routine fills a section of memory with a specified byte.\n *\n * @param Destination\n *        Supplies a pointer to the buffer to fill.\n *\n * @param Byte\n *        Supplies a pattern to fill memory.\n *\n * @param Length\n *        Specifies a number of bytes to store in memory.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::Memory::SetMemory(OUT PVOID Destination,\n                       IN UCHAR Byte,\n                       IN SIZE_T Length)\n{\n    PCHAR DestinationBytes = (PCHAR)Destination;\n\n    /* Fill the buffer with specified byte */\n    while(Length--)\n    {\n        *DestinationBytes++ = Byte;\n    }\n}\n\n/**\n * This routine fills a section of memory with zeroes.\n *\n * @param Destination\n *        Supplies a pointer to the buffer to fill.\n *\n * @param Length\n *        Specifies a number of bytes to be filled with zeroes.\n *\n * @return This routine does not return any value.\n *\n * @since NT 3.5\n */\nXTAPI\nVOID\nRTL::Memory::ZeroMemory(OUT PVOID Destination,\n                        IN SIZE_T Length)\n{\n    /* Fill the buffer with zeroes */\n    SetMemory(Destination, 0, Length);\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/sha1.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/sha1.cc\n * DESCRIPTION:     SHA1 computation support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Computes the SHA-1 hash of a buffer in a single step.\n *\n * @param Buffer\n *        Supplies a pointer to the buffer containing the data to be hashed.\n *\n * @param BufferSize\n *        Specifies the size of the buffer in bytes.\n *\n * @param Digest\n *        Supplies a pointer to the buffer that receives the 20-byte SHA-1 hash digest.\n *\n * @return This routine returns STATUS_SUCCESS if the hash was computed successfully,\n *         or STATUS_INVALID_PARAMETER if an invalid parameter was supplied.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::SHA1::ComputeDigest(IN PCUCHAR Buffer,\n                         IN SIZE_T BufferSize,\n                         OUT PUCHAR Digest)\n{\n    RTL_SHA1_CONTEXT Context;\n    XTSTATUS Status;\n\n    /* Validate input parameters */\n    if(!Digest || (!Buffer && BufferSize > 0))\n    {\n        /* Invalid parameters, return error */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Initialize SHA-1 context */\n    Status = InitializeContext(&Context);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to initialize SHA-1 context, return error */\n        return Status;\n    }\n\n    /* Hash data and compute SHA-1 digest */\n    HashData(&Context, Buffer, BufferSize);\n    ComputeHash(&Context, Digest);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Finalizes the SHA-1 hash computation and provides the digest.\n *\n * @param Context\n *        Supplies a pointer to the SHA-1 context structure.\n *\n * @param Digest\n *        Supplies a pointer to a buffer that receives the 20-byte SHA-1 hash digest.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::SHA1::ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,\n                       OUT PUCHAR Digest)\n{\n    ULONG Index, PaddingLength;\n    UCHAR Padding[64];\n    UCHAR Bits[8];\n\n    /* Zero padding and append 0x80 to it */\n    RTL::Memory::ZeroMemory(Padding, 64);\n    Padding[0] = 0x80;\n\n    /* Encode the total message length in bits as a Big Endian 64-bit integer */\n    *(PULONG)(Bits) = RTL::Endianness::SwapByte32(Context->Count[1]);\n    *(PULONG)(Bits + 4) = RTL::Endianness::SwapByte32(Context->Count[0]);\n\n    /* Calculate padding length needed to align the message to 56 bytes */\n    Index = (Context->Count[0] >> 3) & 0x3F;\n    PaddingLength = (Index < 56) ? (56 - Index) : (120 - Index);\n\n    /* Append the padding bytes to the message stream to satisfy the block boundary */\n    HashData(Context, Padding, PaddingLength);\n\n    /* Append bits before final transformation */\n    HashData(Context, Bits, 8);\n\n    /* Store hash to output in Big Endian format */\n    Digest[0] = (UCHAR)((Context->State[0] >> 24) & 0xFF);\n    Digest[1] = (UCHAR)((Context->State[0] >> 16) & 0xFF);\n    Digest[2] = (UCHAR)((Context->State[0] >> 8) & 0xFF);\n    Digest[3] = (UCHAR)(Context->State[0] & 0xFF);\n    Digest[4] = (UCHAR)((Context->State[1] >> 24) & 0xFF);\n    Digest[5] = (UCHAR)((Context->State[1] >> 16) & 0xFF);\n    Digest[6] = (UCHAR)((Context->State[1] >> 8) & 0xFF);\n    Digest[7] = (UCHAR)(Context->State[1] & 0xFF);\n    Digest[8] = (UCHAR)((Context->State[2] >> 24) & 0xFF);\n    Digest[9] = (UCHAR)((Context->State[2] >> 16) & 0xFF);\n    Digest[10] = (UCHAR)((Context->State[2] >> 8) & 0xFF);\n    Digest[11] = (UCHAR)(Context->State[2] & 0xFF);\n    Digest[12] = (UCHAR)((Context->State[3] >> 24) & 0xFF);\n    Digest[13] = (UCHAR)((Context->State[3] >> 16) & 0xFF);\n    Digest[14] = (UCHAR)((Context->State[3] >> 8) & 0xFF);\n    Digest[15] = (UCHAR)(Context->State[3] & 0xFF);\n    Digest[16] = (UCHAR)((Context->State[4] >> 24) & 0xFF);\n    Digest[17] = (UCHAR)((Context->State[4] >> 16) & 0xFF);\n    Digest[18] = (UCHAR)((Context->State[4] >> 8) & 0xFF);\n    Digest[19] = (UCHAR)(Context->State[4] & 0xFF);\n\n    /* Clear context memory for security */\n    RTL::Memory::ZeroMemory(Context, sizeof(RTL_SHA1_CONTEXT));\n}\n\n/**\n * Updates the SHA-1 context with the provided data buffer.\n *\n * @param Context\n *        Supplies a pointer to the SHA-1 context structure.\n *\n * @param Data\n *        Supplies a pointer to the buffer containing the data to be hashed.\n *\n * @param Length\n *        Specifies the length of the data buffer in bytes.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::SHA1::HashData(IN OUT PRTL_SHA1_CONTEXT Context,\n                    IN PCUCHAR Data,\n                    IN ULONG Length)\n{\n    ULONG Index, Input, PartialLength;\n\n    /* Calculate byte offset within the 64-byte block buffer */\n    Index = (Context->Count[0] >> 3) & 0x3F;\n\n    /* Update the total bit count, handling overflow from low to high word */\n    if((Context->Count[0] += (Length << 3)) < (Length << 3))\n    {\n        /* Increment high 32-bit counter on low counter overflow */\n        Context->Count[1]++;\n    }\n\n    /* Add the high-order bits of the length (bytes -> bits overflow) to the high counter */\n    Context->Count[1] += (Length >> 29);\n\n    /* Calculate the number of bytes required to fill the remaining buffer space */\n    PartialLength = 64 - Index;\n\n    /* Transform as many times as possible */\n    if(Length >= PartialLength)\n    {\n        /* Fill the buffer partially and transform */\n        RTL::Memory::CopyMemory(&Context->Buffer[Index], Data, PartialLength);\n        TransformData(Context->State, Context->Buffer);\n\n        /* Process remaining full 64-byte blocks directly from the input pointer */\n        for(Input = PartialLength; Input + 63 < Length; Input += 64)\n        {\n            /* Transform the full block without copying to the internal buffer */\n            TransformData(Context->State, &Data[Input]);\n        }\n\n        /* Reset buffer index to indicate the buffer is now empty */\n        Index = 0;\n    }\n    else\n    {\n        /* No full block was formed, begin copying from the start of input */\n        Input = 0;\n    }\n\n    /* Buffer remaining input */\n    RTL::Memory::CopyMemory(&Context->Buffer[Index], &Data[Input], Length - Input);\n}\n\n/**\n * Initializes a SHA-1 context structure with the standard initial hash values.\n *\n * @param Context\n *        Supplies a pointer to the SHA-1 context structure to initialize.\n *\n * @return This routine returns STATUS_SUCCESS if the context was initialized successfully,\n *         or STATUS_INVALID_PARAMETER if the pointer is NULLPTR.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::SHA1::InitializeContext(OUT PRTL_SHA1_CONTEXT Context)\n{\n    /* Validate input parameter */\n    if(!Context)\n    {\n        /* Invalid parameter, return error */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Initialize hash constants defined by FIPS 180-4 */\n    Context->State[0] = 0x67452301;\n    Context->State[1] = 0xEFCDAB89;\n    Context->State[2] = 0x98BADCFE;\n    Context->State[3] = 0x10325476;\n    Context->State[4] = 0xC3D2E1F0;\n    Context->Count[0] = 0;\n    Context->Count[1] = 0;\n\n    /* Clear buffer */\n    RTL::Memory::ZeroMemory(Context->Buffer, SHA1_BLOCK_SIZE);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Transforms a single 64-byte block using the SHA-1 compression function.\n *\n * @param State\n *        Supplies a pointer to the array containing the current hash state variables.\n *\n * @param Buffer\n *        Supplies a pointer to the 64-byte input buffer to be transformed.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::SHA1::TransformData(IN OUT PULONG State,\n                         IN PCUCHAR Buffer)\n{\n    ULONG Constant, Function, Index, TempHash;\n    ULONG TempState[5];\n    ULONG Stack[80];\n\n    /* Initialize working variables with current state */\n    TempState[0] = State[0];\n    TempState[1] = State[1];\n    TempState[2] = State[2];\n    TempState[3] = State[3];\n    TempState[4] = State[4];\n\n    /* Initialize the first 16 words of the message schedule from the input buffer */\n    for(Index = 0; Index < 16; Index++)\n    {\n        /* Convert input words from Little Endian to Big Endian required by SHA-1 */\n        Stack[Index] = RTL::Endianness::SwapByte32(((const PULONG)Buffer)[Index]);\n    }\n\n    /* Expand the message to 80 words using the SHA-1 algorithm */\n    for(Index = 16; Index < 80; Index++)\n    {\n        /* Compute the next word value based on XOR and left rotation */\n        Stack[Index] = ROTATE_LEFT((Stack[Index - 3] ^ Stack[Index - 8] ^ Stack[Index - 14] ^ Stack[Index - 16]), 1);\n    }\n\n    /* Execute the main compression loop for 80 rounds */\n    for(Index = 0; Index < 80; Index++)\n    {\n        /* Determine the logical function and constant based on the current round */\n        if(Index < 20)\n        {\n            /* Set the constant defined by FIPS 180-4 for rounds 0-19 and calculate the logical function */\n            Constant = 0x5A827999;\n            Function = (TempState[1] & TempState[2]) | ((~TempState[1]) & TempState[3]);\n        }\n        else if(Index < 40)\n        {\n            /* Set the constant defined by FIPS 180-4 for rounds 20-39 and calculate the logical function */\n            Constant = 0x6ED9EBA1;\n            Function = TempState[1] ^ TempState[2] ^ TempState[3];\n        }\n        else if(Index < 60)\n        {\n            /* Set the constant defined by FIPS 180-4 for rounds 40-59 and calculate the logical function */\n            Constant = 0x8F1BBCDC;\n            Function = (TempState[1] & TempState[2]) | (TempState[1] & TempState[3]) | (TempState[2] & TempState[3]);\n        }\n        else\n        {\n            /* Set the constant defined by FIPS 180-4 for rounds 60-79 and calculate the logical function */\n            Constant = 0xCA62C1D6;\n            Function = TempState[1] ^ TempState[2] ^ TempState[3];\n        }\n\n        /* Calculate the temporary hash value for this round */\n        TempHash = ROTATE_LEFT(TempState[0], 5) + Function + TempState[4] + Constant + Stack[Index];\n        TempState[4] = TempState[3];\n        TempState[3] = TempState[2];\n        TempState[2] = ROTATE_LEFT(TempState[1], 30);\n        TempState[1] = TempState[0];\n        TempState[0] = TempHash;\n    }\n\n    /* Add the compressed chunk to the current hash value */\n    State[0] += TempState[0];\n    State[1] += TempState[1];\n    State[2] += TempState[2];\n    State[3] += TempState[3];\n    State[4] += TempState[4];\n\n    /* Clear sensitive data from stack */\n    RTL::Memory::ZeroMemory(Stack, sizeof(Stack));\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/slist.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/slist.cc\n * DESCRIPTION:     Singly linked list manipulation routines\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Retrieves the first entry from a singly linked list without removing it from the list.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that serves as the list header.\n *\n * @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.\n *\n * @since XT 1.0\n */\nXTCDECL\nPSINGLE_LIST_ENTRY\nRTL::SinglyList::GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead)\n{\n    /* Check if the list is empty */\n    if(ListEmpty(ListHead))\n    {\n        /* Empty list, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Return first entry in the list */\n    return ListHead->Next.Next;\n}\n\n/**\n * Initializes a structure representing the head of a singly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that serves as the list header.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::SinglyList::InitializeListHead(IN PSINGLE_LIST_HEADER ListHead)\n{\n    /* Initialize the singly linked list head */\n    ListHead->Alignment = 0;\n}\n\n/**\n * Inserts an entry at the head of a singly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the list.\n *\n * @param Entry\n *        Supplies a pointer to the entry that will be inserted in the list.\n *\n * @return This routine returns a pointer to the original first entry in the list.\n *\n * @since XT 1.0\n */\nXTCDECL\nPSINGLE_LIST_ENTRY\nRTL::SinglyList::InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,\n                                IN PSINGLE_LIST_ENTRY Entry)\n{\n    PSINGLE_LIST_ENTRY OriginalEntry;\n\n    /* Store the original first entry */\n    OriginalEntry = ListHead->Next.Next;\n\n    /* Insert entry at the head of the list and increment depth and sequence */\n    Entry->Next = ListHead->Next.Next;\n    ListHead->Next.Next = Entry;\n    ListHead->Depth++;\n    ListHead->Sequence++;\n\n    /* Return original first entry */\n    return OriginalEntry;\n}\n\n/**\n * Inserts an entry at the tail of a singly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the list.\n *\n * @param Entry\n *        Supplies a pointer to the entry that will be inserted in the list.\n *\n * @return This routine returns a pointer to the original last entry in the list.\n *\n * @since XT 1.0\n */\nXTCDECL\nPSINGLE_LIST_ENTRY\nRTL::SinglyList::InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,\n                                IN PSINGLE_LIST_ENTRY Entry)\n{\n    PSINGLE_LIST_ENTRY CurrentEntry, OriginalEntry;\n\n    /* Set Next pointer of the new entry to NULLPTR */\n    Entry->Next = NULLPTR;\n\n    /* Check if the list is empty */\n    if(ListEmpty(ListHead))\n    {\n        /* Store the original last entry */\n        OriginalEntry = ListHead->Next.Next;\n\n        /* Insert entry at the head */\n        ListHead->Next.Next = Entry;\n    }\n    else\n    {\n        /* Traverse the list to find the last entry */\n        CurrentEntry = ListHead->Next.Next;\n        while(CurrentEntry->Next != NULLPTR)\n        {\n            /* Move to the next entry */\n            CurrentEntry = CurrentEntry->Next;\n        }\n\n        /* Store the original last entry */\n        OriginalEntry = CurrentEntry;\n\n        /* Insert entry at the tail */\n        CurrentEntry->Next = Entry;\n    }\n\n    /* Increment list depth and sequence */\n    ListHead->Depth++;\n    ListHead->Sequence++;\n\n    /* Return original last entry */\n    return OriginalEntry;\n}\n\n/**\n * Indicates whether a singly linked list structure is empty, or not initialized at all.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that represents the head of the list.\n *\n * @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTCDECL\nBOOLEAN\nRTL::SinglyList::ListEmpty(IN PSINGLE_LIST_HEADER ListHead)\n{\n    /* Check if the list is empty */\n    return (ListHead == NULLPTR || ListHead->Next.Next == NULLPTR);\n}\n\n/**\n * Queries the current depth (number of entries) of a singly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that represents the head of the singly linked list.\n *\n * @return This routine returns the number of entries currently in the list, or zero if the list head is NULLPTR.\n *\n * @since XT 1.0\n */\nXTAPI\nUSHORT\nRTL::SinglyList::QueryListDepth(IN PSINGLE_LIST_HEADER ListHead)\n{\n    /* Check if the list head is initialized and valid */\n    if(ListHead == NULLPTR)\n    {\n        /* Return zero */\n        return 0;\n    }\n\n    /* Return the list depth */\n    return ListHead->Depth;\n}\n\n/**\n * Removes an entry from a singly linked list.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the list.\n *\n * @param Entry\n *        Supplies a pointer to the entry that will be removed from the list.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTCDECL\nVOID\nRTL::SinglyList::RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,\n                                 IN PSINGLE_LIST_ENTRY Entry)\n{\n    PSINGLE_LIST_ENTRY PreviousEntry;\n\n    /* Check if the list is empty */\n    if(ListEmpty(ListHead))\n    {\n        /* List is empty, nothing to remove, return */\n        return;\n    }\n\n    /* Check if the entry is the first one */\n    if(ListHead->Next.Next == Entry)\n    {\n        /* Remove the first entry and decrement depth */\n        ListHead->Next.Next = Entry->Next;\n        ListHead->Depth--;\n\n        /* Nothing else to do, return */\n        return;\n    }\n\n    /* Find the previous entry */\n    PreviousEntry = ListHead->Next.Next;\n    while(PreviousEntry->Next != Entry)\n    {\n        /* Move to the next entry */\n        PreviousEntry = PreviousEntry->Next;\n\n        /* Check if we reached the end of the list */\n        if(PreviousEntry == NULLPTR)\n        {\n            /* Entry not found, return */\n            return;\n        }\n    }\n\n    /* Remove the entry and decrement depth */\n    PreviousEntry->Next = Entry->Next;\n    ListHead->Depth--;\n}\n\n/**\n * Splices a singly linked list at the head of another list. The source list is reinitialized to empty.\n *\n * @param ListHead\n *        Supplies a pointer to a structure that represents the head of the list.\n *\n * @param SpliceList\n *        Supplies a pointer to a structure that represents the head of the list that will be spliced.\n *\n * @return This routine returns a pointer to the original first entry in the list.\n *\n * @since XT 1.0\n */\nXTCDECL\nPSINGLE_LIST_ENTRY\nRTL::SinglyList::SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,\n                                IN OUT PSINGLE_LIST_HEADER SpliceList)\n{\n    PSINGLE_LIST_ENTRY LastEntry, OriginalEntry;\n\n    /* Store the original last entry */\n    OriginalEntry = ListHead->Next.Next;\n\n    /* Check if the list to splice is empty */\n    if(ListEmpty(SpliceList))\n    {\n        /* Nothing to splice, return original first entry */\n        return OriginalEntry;\n    }\n\n    /* Find the last entry of the list to splice */\n    LastEntry = SpliceList->Next.Next;\n    while(LastEntry->Next != NULLPTR)\n    {\n        /* Move to the next entry */\n        LastEntry = LastEntry->Next;\n    }\n\n    /* Splice the list at the head of destination */\n    LastEntry->Next = ListHead->Next.Next;\n    ListHead->Next.Next = SpliceList->Next.Next;\n\n    /* Update depth and sequence of the destination list */\n    ListHead->Depth += SpliceList->Depth;\n    ListHead->Sequence++;\n\n    /* Reinitialize the source list to empty */\n    SpliceList->Next.Next = NULLPTR;\n    SpliceList->Depth = 0;\n\n    /* Return the original last entry */\n    return OriginalEntry;\n}\n\n/**\n * Splices a singly linked list at the tail of another list. The source list is reinitialized to empty.\n *\n * @param ListHead\n *        Supplies a pointer to the head of the destination list.\n *\n * @param SpliceList\n *        Supplies a pointer to the head of the list that will be spliced.\n *\n * @return This routine returns a pointer to the original last entry in the list.\n *\n * @since XT 1.0\n */\nXTCDECL\nPSINGLE_LIST_ENTRY\nRTL::SinglyList::SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,\n                                IN OUT PSINGLE_LIST_HEADER SpliceList)\n{\n    PSINGLE_LIST_ENTRY LastEntry, OriginalEntry;\n\n    /* Check if the destination list is empty */\n    if(ListEmpty(ListHead))\n    {\n        /* Destination is empty, original last entry is NULLPTR */\n        OriginalEntry = NULLPTR;\n\n        /* Move the splice list to the destination head */\n        ListHead->Next.Next = SpliceList->Next.Next;\n    }\n    else\n    {\n        /* Find the last entry of the destination list */\n        LastEntry = ListHead->Next.Next;\n        while(LastEntry->Next != NULLPTR)\n        {\n            /* Move to the next entry */\n            LastEntry = LastEntry->Next;\n        }\n\n        /* Store the original last entry */\n        OriginalEntry = LastEntry;\n\n        /* Splice the list at the tail of destination */\n        LastEntry->Next = SpliceList->Next.Next;\n    }\n\n    /* Update depth and sequence of the destination list */\n    ListHead->Depth += SpliceList->Depth;\n    ListHead->Sequence++;\n\n    /* Reinitialize the source list to empty */\n    SpliceList->Next.Next = NULLPTR;\n    SpliceList->Depth = 0;\n\n    /* Return the original last entry */\n    return OriginalEntry;\n}\n\n/**\n * Retrieves the first entry from a singly linked list and removes it from the list.\n *\n * @param ListHead\n *        Pointer to a structure that serves as the list header.\n *\n * @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.\n *\n * @since XT 1.0\n */\nXTCDECL\nPSINGLE_LIST_ENTRY\nRTL::SinglyList::TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead)\n{\n    PSINGLE_LIST_ENTRY Entry;\n\n    /* Check if the list is empty */\n    if(ListEmpty(ListHead))\n    {\n        /* List is empty, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Get the first entry */\n    Entry = ListHead->Next.Next;\n\n    /* Remove entry from the list */\n    ListHead->Next.Next = Entry->Next;\n    ListHead->Depth--;\n\n    /* Return the first entry */\n    return Entry;\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/string.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/string.cc\n * DESCRIPTION:     String support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Compares at most specified number of characters of two C strings.\n *\n * @param String1\n *        String to be compared.\n *\n * @param String2\n *        String to be compared.\n *\n * @param Length\n *        Maximum number of characters to compare. If no limit set, it compares whole strings.\n *\n * @return Integral value indicating the relationship between the strings.\n *\n * @since XT 1.0\n */\nXTAPI\nSIZE_T\nRTL::String::CompareString(IN PCSTR String1,\n                           IN PCSTR String2,\n                           IN SIZE_T Length)\n{\n    SIZE_T Index;\n\n    /* Iterate through the strings */\n    for(Index = 0; ; Index++) {\n        /* Check if length limit reached */\n        if(Index != 0 && Index == Length)\n        {\n            /* Skip checking next characters */\n            break;\n        }\n\n        /* Check if string characters are equal */\n        if(String1[Index] != String2[Index])\n        {\n            /* Different characters found */\n            return String1[Index] < String2[Index] ? -1 : 1;\n        }\n\n        /* Check if end of string reached */\n        if(!String1[Index] || !String2[Index])\n        {\n            /* Equal strings until the end of one of them */\n            return 0;\n        }\n    }\n\n    /* Strings are equal */\n    return 0;\n}\n\n/**\n * Compares at most specified number of characters of two C strings, while ignoring differences in case.\n *\n * @param String1\n *        String to be compared.\n *\n * @param String2\n *        String to be compared.\n *\n * @param Length\n *        Maximum number of characters to compare. If no limit set, it compares whole strings.\n *\n * @return Integral value indicating the relationship between the strings.\n *\n * @since XT 1.0\n */\nXTAPI\nSIZE_T\nRTL::String::CompareStringInsensitive(IN PCSTR String1,\n                                      IN PCSTR String2,\n                                      IN SIZE_T Length)\n{\n    CHAR Character1;\n    CHAR Character2;\n    ULONG Index = 0;\n\n    /* Iterate through the strings */\n    while(String1[Index] != '\\0' && String2[Index] != '\\0')\n    {\n        /* Check if length limit reached */\n        if(Index != 0 && Index == Length)\n        {\n            /* Skip checking next characters */\n            break;\n        }\n\n        /* Get the characters */\n        Character1 = String1[Index];\n        Character2 = String2[Index];\n\n        /* Lowercase string1 character if needed */\n        if(String1[Index] >= 'A' && String1[Index] <= 'Z')\n        {\n            Character1 = String1[Index] - 'A' + 'a';\n        }\n\n        /* Lowercase string2 character if needed */\n        if(String2[Index] >= 'A' && String2[Index] <= 'Z')\n        {\n            Character2 = String2[Index] - 'A' + 'a';\n        }\n\n        /* Compare the characters */\n        if(Character1 != Character2)\n        {\n            /* Strings are not equal */\n            return Character1 > Character2 ? 1 : -1;\n        }\n\n        /* Get next character */\n        Index++;\n    }\n\n    /* Strings are equal */\n    return 0;\n}\n\n/**\n * Appends a copy of the source string to the end of the destination string.\n *\n * @param Destination\n *        Supplies a pointer to the NULL-terminated string to append to.\n *\n * @param Source\n *        Supplies a pointer to the NULL-terminated string to copy from.\n *\n * @param Count\n *        Sets a maximum number of characters to copy. If no limit set, appends whole string.\n *\n * @return This routine returns a copy of a destination string.\n *\n * @since XT 1.0\n */\nXTAPI\nPCHAR\nRTL::String::ConcatenateString(OUT PCHAR Destination,\n                               IN PCHAR Source,\n                               IN SIZE_T Count)\n{\n    PCHAR DestString = Destination;\n\n    /* Go to the end of destination string */\n    while(*Destination)\n    {\n        Destination++;\n    }\n\n    /* Check if copy limit set */\n    if(Count > 0)\n    {\n        /* Copy character-by-character */\n        do\n        {\n            /* Check if NULL-terminated character found */\n            if((*Destination = *Source++) == '\\0')\n            {\n                /* Break on '\\0' character */\n                break;\n            }\n            Destination++;\n        }\n        while(--Count != 0);\n\n        /* Add NULL-termination character to the end of destination string */\n        *Destination = '\\0';\n    }\n    else\n    {\n        /* No limit set, copy all characters */\n        while((*Destination++ = *Source++) != 0);\n    }\n\n    /* Return copy of the destination string */\n    return DestString;\n}\n\n/**\n * Copies a string from a buffer into another buffer, ensuring that the destination string is NULL-terminated.\n *\n * @param Destination\n *        Supplies a pointer to the destination buffer.\n *\n * @param Source\n *        Supplies a pointer to the source buffer.\n *\n * @param Length\n *        Supplies the length of the string to copy.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::String::CopyString(IN PCHAR Destination,\n                        IN PCSTR Source,\n                        IN ULONG Length)\n{\n    ULONG Index;\n\n    /* Copy characters */\n    for(Index = 0; Index < Length; Index++)\n    {\n        /* Copy source character */\n        Destination[Index] = Source[Index];\n\n        /* Check if NULL-terminated character found */\n        if(Source[Index] == '\\0')\n        {\n            /* End of source string reached */\n            break;\n        }\n    }\n\n    /* Make sure the destination string is terminated properly */\n    Destination[Index] = '\\0';\n}\n\n/**\n * Finds the first occurrence of the search string in the source string.\n *\n * @param Source\n *        Supplies a pointer to the source string.\n *\n * @param Search\n *        Supplies a pointer to the search string.\n *\n * @return This routine returns a pointer to the first occurrence of the search string in the source string.\n *\n * @since XT 1.0\n */\nXTAPI\nPCSTR\nRTL::String::FindString(IN PCSTR Source,\n                        IN PCSTR Search)\n{\n    PCSTR CurrentSource;\n    PCSTR CurrentSearch;\n\n    /* Validate input parameters */\n    if(!Source || !Search)\n    {\n        /* Invalid input parameters, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Check if search string is empty */\n    if(*Search == '\\0')\n    {\n        /* Return the source string */\n        return Source;\n    }\n\n    /* Iterate through the source string */\n    for(; *Source != '\\0'; Source++) {\n\n        /* Initialize pointers */\n        CurrentSource = Source;\n        CurrentSearch = Search;\n\n        /* Check if the substring matches starting at the current position */\n        while(*CurrentSource != '\\0' && *CurrentSearch != '\\0' && *CurrentSource == *CurrentSearch)\n        {\n            /* Go to the next character */\n            CurrentSource++;\n            CurrentSearch++;\n        }\n\n        /* If we reached the end of Search string, it is a match */\n        if(*CurrentSearch == '\\0')\n        {\n            /* Return the source position */\n            return Source;\n        }\n    }\n\n    /* No match found, return NULLPTR */\n    return NULLPTR;\n}\n\n/**\n * Finds the first case-insensitive occurrence of the search string in the source string.\n *\n * @param Source\n *        Supplies a pointer to the source string.\n *\n * @param Search\n *        Supplies a pointer to the search string.\n *\n * @return This routine returns a pointer to the first occurrence of the search string in the source string.\n *\n * @since XT 1.0\n */\nXTAPI\nPCSTR\nRTL::String::FindStringInsensitive(IN PCSTR Source,\n                                   IN PCSTR Search)\n{\n    PCSTR CurrentSource;\n    PCSTR CurrentSearch;\n\n    /* Validate input parameters */\n    if(!Source || !Search)\n    {\n        /* Invalid input parameters, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Check if search string is empty */\n    if(*Search == '\\0')\n    {\n        /* Return the source string */\n        return Source;\n    }\n\n    /* Iterate through the source string */\n    for(; *Source != '\\0'; Source++) {\n\n        /* Initialize pointers */\n        CurrentSource = Source;\n        CurrentSearch = Search;\n\n        /* Check if the substring matches starting at the current position */\n        while(*CurrentSource != '\\0' && *CurrentSearch != '\\0' &&\n              ToLowerCharacter(*CurrentSource) == ToLowerCharacter(*CurrentSearch))\n        {\n            /* Go to the next character */\n            CurrentSource++;\n            CurrentSearch++;\n        }\n\n        /* If we reached the end of Search string, it is a match */\n        if(*CurrentSearch == '\\0')\n        {\n            /* Return the source position */\n            return Source;\n        }\n    }\n\n    /* No match found, return NULLPTR */\n    return NULLPTR;\n}\n\n/**\n * Reverses a characters order in a string. It modifies the original, input variable.\n *\n * @param String\n *        Supplies a pointer to the string to reverse.\n *\n * @param Length\n *        Supplies the length of the string to reverse.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::String::ReverseString(IN OUT PCHAR String,\n                           IN ULONG Length)\n{\n    UCHAR TempChar;\n    ULONG Index;\n\n    /* Iterate through the string */\n    for(Index = 0; Index < (Length / 2); Index++)\n    {\n        /* Swap characters */\n        TempChar = String[Index];\n        String[Index] = String[Length - Index - 1];\n        String[Length - Index - 1] = TempChar;\n    }\n}\n\n/**\n * Calculates the length of a given string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to be examined.\n *\n * @param MaxLength\n *        Maximum number of characters to examine. If no limit set, it examines whole string.\n *\n * @return The length of the NULL-terminated string.\n *\n * @since: XT 1.0\n */\nXTAPI\nSIZE_T\nRTL::String::StringLength(IN PCSTR String,\n                          IN SIZE_T MaxLength)\n{\n    SIZE_T Length;\n\n    /* Check if NULL pointer passed */\n    if(String == NULLPTR)\n    {\n        return 0;\n    }\n\n    /* Iterate through the wide string */\n    for(Length = 0; ; Length++)\n    {\n\n        /* Check if NULL found or max length limit reached */\n        if((Length != 0 && Length == MaxLength) || !String[Length])\n        {\n            /* Finish examination */\n            break;\n        }\n    }\n\n    /* Return string length */\n    return Length;\n}\n\n/**\n * Converts a string to a number.\n *\n * @param String\n *        Supplies a pointer to the NULL-terminated string to convert.\n *\n * @param Base\n *        Supplies the optional numerical base for the conversion (2, 8, 10, or 16).\n *\n * @param Value\n *        Supplies a pointer to a variable that receives the converted numeric value.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::String::StringToNumber(IN PCSTR String,\n                            IN ULONG Base,\n                            OUT PULONG Value)\n{\n    BOOLEAN NegativeValue;\n    ULONG Digit, Result;\n\n    /* Validate input parameters */\n    if(!String || !Value)\n    {\n        /* Invalid input parameters, return error code */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Initialize local variables */\n    NegativeValue = FALSE;\n    Result = 0;\n\n    /* Skip leading whitespaces and control characters */\n    while(*String != '\\0' && *String <= ' ')\n    {\n        /* Advance to the next character */\n        String++;\n    }\n\n    /* Consume and record sign */\n    if(*String == '-')\n    {\n        /* Set negative value flag and advance to the next character */\n        NegativeValue = TRUE;\n        String++;\n    }\n    else if(*String == '+')\n    {\n        /* Advance to the next character */\n        String++;\n    }\n\n    /* Autodetect and validate the base */\n    if(Base == 0)\n    {\n        /* Autodetect base based on prefix */\n        if(String[0] == '0')\n        {\n            /* Validate prefix */\n            if(String[1] == 'x' || String[1] == 'X')\n            {\n                /* Hexadecimal base */\n                Base = 16;\n                String += 2;\n            }\n            else if(String[1] == 'o' || String[1] == 'O')\n            {\n                /* Octal base */\n                Base = 8;\n                String += 2;\n            }\n            else if(String[1] == 'b' || String[1] == 'B')\n            {\n                /* Binary base */\n                Base = 2;\n                String += 2;\n            }\n            else\n            {\n                /* Starts with 0 but no known prefix, treat as decimal */\n                Base = 10;\n            }\n        }\n        else\n        {\n            /* Default to decimal base */\n            Base = 10;\n        }\n    }\n    else\n    {\n        /* Validate explicitly provided base */\n        if(Base != 2 && Base != 8 && Base != 10 && Base != 16)\n        {\n            /* Invalid base, return error code */\n            return STATUS_INVALID_PARAMETER;\n        }\n\n        /* Check if number starts with 0 */\n        if(String[0] == '0')\n        {\n            /* Check for prefix */\n            if(Base == 16 && (String[1] == 'x' || String[1] == 'X'))\n            {\n                /* Skip hexadecimal prefix */\n                String += 2;\n            }\n            else if(Base == 8 && (String[1] == 'o' || String[1] == 'O'))\n            {\n                /* Skip octal prefix */\n                String += 2;\n            }\n            else if(Base == 2 && (String[1] == 'b' || String[1] == 'B'))\n            {\n                /* Skip binary prefix */\n                String += 2;\n            }\n        }\n    }\n\n    /* Parse string character by character */\n    while(*String != '\\0')\n    {\n        /* Convert character to numeric digit */\n        if(*String >= '0' && *String <= '9')\n        {\n            /* Convert decimal digit */\n            Digit = *String - '0';\n        }\n        else if(*String >= 'A' && *String <= 'F')\n        {\n            /* Convert hexadecimal digit */\n            Digit = *String - 'A' + 10;\n        }\n        else if(*String >= 'a' && *String <= 'f')\n        {\n            /* Convert hexadecimal digit */\n            Digit = *String - 'a' + 10;\n        }\n        else\n        {\n            /* Invalid character for a number encountered, stop parsing */\n            break;\n        }\n\n        /* Check if digit is valid for the current base */\n        if(Digit >= Base)\n        {\n            /* Digit out of range for this base, stop parsing */\n            break;\n        }\n\n        /* Check for integer overflow */\n        if((Result > (MAXULONG / Base)) || ((Result * Base) > (MAXULONG - Digit)))\n        {\n            /* Integer overflow, return error code */\n            return STATUS_INTEGER_OVERFLOW;\n        }\n\n        /* Accumulate result */\n        Result = (Result * Base) + Digit;\n\n        /* Advance to the next character */\n        String++;\n    }\n\n    /* Check for negative value */\n    if(NegativeValue)\n    {\n        /* Apply sign and return the result */\n        *Value = (ULONG)(-(LONG)Result);\n    }\n    else\n    {\n        /* Return the result */\n        *Value = Result;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Converts a multibyte character string to its wide character representation.\n *\n * @param Destination\n *        Pointer to wide character array where the wide string will be stored\n *\n * @param Source\n *        Pointer to the first element of a multibyte string to convert.\n *\n * @param Length\n *        Number of characters in the source string.\n *\n * @return Returns the number of wide characters written to the destination array on success, or -1 on error.\n *\n * @since XT 1.0\n */\nXTAPI\nSIZE_T\nRTL::String::StringToWideString(OUT PWCHAR Destination,\n                                IN PCSTR *Source,\n                                IN SIZE_T Length)\n{\n    PCSTR LocalSource = *Source;\n    SIZE_T Count = Length;\n\n    /* Check if NULL pointer passed */\n    if(Destination == NULLPTR)\n    {\n        /* No wide characters written */\n        return 0;\n    }\n\n    /* Iterate through the string */\n    while(Count)\n    {\n        /* Copy character */\n        if((*Destination = *LocalSource) == 0)\n        {\n            /* End of string reached */\n            LocalSource = NULLPTR;\n            break;\n        }\n\n        /* Check if character is valid */\n        if(*Destination >= 0x80)\n        {\n            /* Invalid character, return error */\n            return -1;\n        }\n\n        /* Advance pointers */\n        LocalSource++;\n        Destination++;\n        Count--;\n    }\n\n    /* Return number of wide characters written */\n    return Length - Count;\n}\n\n/**\n * Finds the next token in a NULL-terminated string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to tokenize.\n *\n * @param Delimiter\n *        Pointer to the NULL-terminated string identifying delimiters.\n *\n * @param SavePtr\n *        Pointer to an object used to store routine internal state.\n *\n * @return Pointer to the beginning of the next token or NULL if there are no more tokens.\n *\n * @since: XT 1.0\n */\nXTAPI\nPCHAR\nRTL::String::TokenizeString(IN PCHAR String,\n                            IN PCSTR Delimiter,\n                            IN OUT PCHAR *SavePtr)\n{\n    PCHAR Span, Token;\n    CHAR Char, SpanChar;\n\n    /* Check if there is anything to tokenize */\n    if(String == NULLPTR && (String = *SavePtr) == NULLPTR)\n    {\n        /* Empty string given */\n        return NULLPTR;\n    }\n\n    /* Check non-delimiter characters */\n    Char = *String++;\n    if(Char == '\\0')\n    {\n        *SavePtr = NULLPTR;\n        return NULLPTR;\n    }\n    Token = String - 1;\n\n    /* Scan token for delimiters */\n    for(;;)\n    {\n        Char = *String++;\n        Span = (PCHAR)Delimiter;\n        do\n        {\n            /* Check if delimiter found */\n            if((SpanChar = *Span++) == Char)\n            {\n                /* Check if end of string reached */\n                if(Char == '\\0')\n                {\n                    /* End of string reached, no more tokens */\n                    String = NULLPTR;\n                }\n                else\n                {\n                    /* Terminate token */\n                    String[-1] = '\\0';\n                }\n\n                /* Store pointer to the next token */\n                *SavePtr = String;\n\n                /* Return token */\n                return Token;\n            }\n        }\n        while(SpanChar != '\\0');\n    }\n}\n\n/**\n * Converts a character to lowercase.\n *\n * @param Character\n *        Character to be converted.\n *\n * @return Converted character or original character if it was not uppercase.\n *\n * @since XT 1.0\n */\nXTAPI\nCHAR\nRTL::String::ToLowerCharacter(IN CHAR Character)\n{\n    /* Check if character is uppercase */\n    if(Character >= 'A' && Character <= 'Z')\n    {\n        /* Convert character to lowercase */\n        return (CHAR)(Character + ('a' - 'A'));\n    }\n\n    /* Return original character */\n    return Character;\n}\n\n/**\n * Converts a character to uppercase.\n *\n * @param Character\n *        Character to be converted.\n *\n * @return Converted character or original character if it was not lowercase.\n *\n * @since XT 1.0\n */\nXTAPI\nCHAR\nRTL::String::ToUpperCharacter(IN CHAR Character)\n{\n    /* Check if character is lowercase */\n    if(Character >= 'a' && Character <= 'z')\n    {\n        /* Convert character to uppercase */\n        return (CHAR)(Character - ('a' - 'A'));\n    }\n\n    /* Return original character */\n    return Character;\n}\n\n/**\n * Removes certain characters from a beginning of the string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to be trimmed.\n *\n * @return This routine returns a pointer to the left-trimmed string.\n *\n * @since XT 1.0\n */\nXTAPI\nPCHAR\nRTL::String::TrimLeftString(IN PCHAR String)\n{\n    PCHAR Start;\n\n    /* Initialize pointer */\n    Start = String;\n\n    /* Skip all leading whitespaces */\n    while(*Start == ' ' || *Start == '\\n' || *Start == '\\t' || *Start == '\\r' || *Start == '\\v' || *Start == '\\f')\n    {\n        /* Advance to the next character */\n        Start++;\n    }\n\n    /* Return left-trimmed string */\n    return Start;\n}\n\n/**\n * Removes certain characters from the end of the string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to be trimmed.\n *\n * @return This routine returns a pointer to the right-trimmed string.\n *\n * @since XT 1.0\n */\nXTAPI\nPCHAR\nRTL::String::TrimRightString(IN PCHAR String)\n{\n    PCHAR End;\n\n    /* Find end of the string */\n    End = String + StringLength(String, 0);\n\n    /* Skip all trailing whitespaces */\n    while((End != String) && (*End == ' ' || *End == '\\n' || *End == '\\t' || *End == '\\r' || *End == '\\v' || *End == '\\f'))\n    {\n        /* Move to the previous character */\n        End--;\n    }\n\n    /* Terminate the string */\n    *End = 0;\n\n    /* Return right-trimmed string */\n    return String;\n}\n\n/**\n * Removes certain characters from the beginning and the end of the string.\n *\n * @param String\n *        Pointer to the NULL-terminated string to be trimmed.\n *\n * @return This routine returns a pointer to the trimmed string.\n *\n * @since XT 1.0\n */\nXTAPI\nPCHAR\nRTL::String::TrimString(IN PCHAR String)\n{\n    return TrimLeftString(TrimRightString(String));\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/time.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/time.cc\n * DESCRIPTION:     Time conversion support\n * DEVELOPERS:      Aiken Harris <harraiken91@gmail.com>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Determines if a given year is a leap year in the Gregorian calendar.\n *\n * @param Year\n *        Supplies the year to be checked.\n *\n * @return This routine returns TRUE if the year is a leap year, FALSE otherwise.\n *\n * @since XT 1.0\n */\nXTFASTCALL\nBOOLEAN\nRTL::Time::LeapYear(SHORT Year)\n{\n    return ((Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0)) ? TRUE : FALSE;\n}\n\n/**\n * Converts a TIME_FIELDS calendar structure to a 64-bit Unix timestamp.\n *\n * @param TimeFields\n *        Supplies a pointer to a fully populated TIME_FIELDS structure.\n *\n * @param UnixTime\n *        Supplies a pointer to a 64-bit integer that receives the number of\n *        seconds elapsed since January 1, 1970.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::Time::TimeFieldsToUnixEpoch(IN PTIME_FIELDS TimeFields,\n                                 OUT PLONGLONG UnixTime)\n{\n    LONGLONG ElapsedDays, TotalSeconds;\n    LONG Month, Year;\n    ULONG Leap;\n\n    /* Check leap year */\n    Leap = LeapYear(TimeFields->Year) ? 1 : 0;\n\n    /* 2. Validate input data */\n    if(TimeFields->Hour < 0 || TimeFields->Hour > 23 ||\n       TimeFields->Minute < 0 || TimeFields->Minute > 59 ||\n       TimeFields->Second < 0 || TimeFields->Second > 59 ||\n       TimeFields->Year < 0 || TimeFields->Year > 30827 ||\n       TimeFields->Month < 1 || TimeFields->Month > 12 ||\n       TimeFields->Day < 1 || TimeFields->Day > DaysInMonth[Leap][TimeFields->Month - 1])\n    {\n        /* Invalid input data, return error code */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Copy year and month */\n    Year = (LONG)TimeFields->Year;\n    Month = (LONG)TimeFields->Month;\n\n    /* Put February at the end of the calculation cycle, making leap day handling implicit in the year division */\n    if(0 >= (LONG)(Month -= 2))\n    {\n        /* Adjust month and year */\n        Month += 12;\n        Year -= 1;\n    }\n\n    /* Calculate absolute elapsed days */\n    ElapsedDays = (LONGLONG)(Year/4 - Year/100 + Year/400 + 367*Month/12 + TimeFields->Day) +\n                  (LONGLONG)Year*365 - 719499LL;\n\n    /* Calculate total seconds */\n    TotalSeconds = (ElapsedDays * TIME_SECONDS_PER_DAY) +\n                   ((LONGLONG)TimeFields->Hour * TIME_SECONDS_PER_HOUR) +\n                   ((LONGLONG)TimeFields->Minute * TIME_SECONDS_PER_MINUTE) +\n                   (LONGLONG)TimeFields->Second;\n\n    /* Output the final Unix timestamp */\n    *UnixTime = TotalSeconds;\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Converts a TIME_FIELDS calendar structure to a 64-bit XT timestamp.\n *\n * @param TimeFields\n *        Supplies a pointer to a fully populated TIME_FIELDS structure.\n *\n * @param Time\n *        Supplies a pointer to variable that receives the converted time value in 100-nanosecond\n *        intervals since January 1, 1601.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::Time::TimeFieldsToXtEpoch(IN PTIME_FIELDS TimeFields,\n                               OUT PLARGE_INTEGER XtTime)\n{\n    LONGLONG ElapsedDays, TotalSeconds;\n    LONG Month, Year;\n    ULONG Leap;\n\n    /* Check leap year */\n    Leap = LeapYear(TimeFields->Year) ? 1 : 0;\n\n    /* Validate input data */\n    if(TimeFields->Hour < 0 || TimeFields->Hour > 23 ||\n       TimeFields->Minute < 0 || TimeFields->Minute > 59 ||\n       TimeFields->Second < 0 || TimeFields->Second > 59 ||\n       TimeFields->Milliseconds < 0 || TimeFields->Milliseconds > 999 ||\n       TimeFields->Year < 1601 || TimeFields->Year > 30827 ||\n       TimeFields->Month < 1 || TimeFields->Month > 12 ||\n       TimeFields->Day < 1 || TimeFields->Day > DaysInMonth[Leap][TimeFields->Month - 1])\n    {\n        /* Invalid input data, return error code */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Copy year and month */\n    Year = (LONG)TimeFields->Year;\n    Month = (LONG)TimeFields->Month;\n\n    /* Put February at the end of the calculation cycle, making leap day handling implicit in the year division */\n    if(0 >= (LONG)(Month -= 2))\n    {\n        /* Adjust month and year */\n        Month += 12;\n        Year -= 1;\n    }\n\n    /* Calculate absolute elapsed days */\n    ElapsedDays = (LONGLONG)(Year/4 - Year/100 + Year/400 + 367*Month/12 + TimeFields->Day) +\n                  (LONGLONG)Year*365 - 584725LL;\n\n    /* Calculate total seconds */\n    TotalSeconds = (ElapsedDays * TIME_SECONDS_PER_DAY) +\n                   ((LONGLONG)TimeFields->Hour * TIME_SECONDS_PER_HOUR) +\n                   ((LONGLONG)TimeFields->Minute * TIME_SECONDS_PER_MINUTE) +\n                   (LONGLONG)TimeFields->Second;\n\n    /* Convert to 100-ns intervals and slap milliseconds on top */\n    XtTime->QuadPart = (TotalSeconds * TIME_TICKS_PER_SECOND) +\n                       ((LONGLONG)TimeFields->Milliseconds * TIME_TICKS_PER_MILLISECOND);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Converts a 64-bit Unix timestamp into a TIME_FIELDS calendar structure.\n *\n * @param UnixTime\n *        Supplies a pointer to a 64-bit integer that contains the number of\n *        seconds elapsed since January 1, 1970.\n *\n * @param TimeFields\n *        Supplies a pointer to a TIME_FIELDS structure that receives the converted calendar data.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::Time::UnixEpochToTimeFields(IN PLONGLONG UnixTime,\n                                 OUT PTIME_FIELDS TimeFields)\n{\n    LONG CalculatedDay, CalculatedMonth, CalculatedYear;\n    LONGLONG Era, SecondsOfDay, TotalSeconds, UnixDays;\n    ULONG DayOfEra, DayOfYear, YearOfEra;\n\n    /* Validate pointers */\n    if(UnixTime == NULLPTR || TimeFields == NULLPTR)\n    {\n        /* Invalid pointers provided, return error code */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Extract total seconds */\n    TotalSeconds = *UnixTime;\n\n    /* Check sign */\n    if(TotalSeconds >= 0)\n    {\n        /* Divide TotalSeconds by seconds per day and compute the remainder */\n        UnixDays = TotalSeconds / TIME_SECONDS_PER_DAY;\n        SecondsOfDay = TotalSeconds % TIME_SECONDS_PER_DAY;\n    }\n    else\n    {\n        /* Subtract seconds per day minus one from TotalSeconds and divide by seconds per day */\n        UnixDays = (TotalSeconds - (TIME_SECONDS_PER_DAY - 1)) / TIME_SECONDS_PER_DAY;\n        SecondsOfDay = TotalSeconds % TIME_SECONDS_PER_DAY;\n\n        /* Check if SecondsOfDay is less than zero */\n        if(SecondsOfDay < 0)\n        {\n            /* Add seconds per day to SecondsOfDay */\n            SecondsOfDay += TIME_SECONDS_PER_DAY;\n        }\n    }\n\n    /* Unix timestamps do not natively support milliseconds */\n    TimeFields->Milliseconds = 0;\n\n    /* Shift epoch from 1970-01-01 to 0000-03-01 to align with leap year cycles */\n    UnixDays += 719468LL;\n\n    /* Calculate the 400-year era */\n    Era = (UnixDays >= 0 ? UnixDays : UnixDays - 146096) / 146097;\n\n    /* Calculate the day within the current era */\n    DayOfEra = (ULONG)(UnixDays - Era * 146097);\n\n    /* Calculate the year within the current era */\n    YearOfEra = (DayOfEra - (DayOfEra / 1460) + (DayOfEra / 36524) - (DayOfEra / 146096)) / 365;\n\n    /* Combine era and year-of-era to get the absolute year */\n    CalculatedYear = (LONG)(YearOfEra + Era * 400);\n\n    /* Calculate the day of the year */\n    DayOfYear = DayOfEra - (365 * YearOfEra + (YearOfEra / 4) - (YearOfEra / 100));\n\n    /* Calculate the month */\n    CalculatedMonth = (5 * DayOfYear + 2) / 153;\n\n    /* Calculate the exact day of the month */\n    CalculatedDay = DayOfYear - (153 * CalculatedMonth + 2) / 5 + 1;\n\n    /* Shift the month back to the standard Gregorian calendar */\n    CalculatedMonth += (CalculatedMonth < 10 ? 3 : -9);\n\n    /* If the month is January or February, it belongs to the next computational year */\n    CalculatedYear += (CalculatedMonth <= 2 ? 1 : 0);\n\n    /* Validate computed year */\n    if(CalculatedYear < 0 || CalculatedYear > 30827)\n    {\n        /* Year is out of bounds, return error code */\n        return STATUS_NOT_SUPPORTED;\n    }\n\n    /* Populate the output structure */\n    TimeFields->Day = (SHORT)CalculatedDay;\n    TimeFields->Month = (SHORT)CalculatedMonth;\n    TimeFields->Year = (SHORT)CalculatedYear;\n    TimeFields->Hour = (SHORT)(SecondsOfDay / TIME_SECONDS_PER_HOUR);\n    TimeFields->Minute = (SHORT)((SecondsOfDay % TIME_SECONDS_PER_HOUR) / TIME_SECONDS_PER_MINUTE);\n    TimeFields->Second = (SHORT)(SecondsOfDay % TIME_SECONDS_PER_MINUTE);\n    TimeFields->Milliseconds = 0;\n    TimeFields->Weekday = (SHORT)(((UnixDays + 4) % 7 + 7) % 7);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Converts a 64-bit XT timestamp into a TIME_FIELDS calendar structure.\n *\n * @param XtTime\n *        Supplies a pointer to a variable that contains the time value in\n *        100-nanosecond intervals since January 1, 1601.\n *\n * @param TimeFields\n *        Supplies a pointer to a TIME_FIELDS structure that receives the converted calendar data.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::Time::XtEpochToTimeFields(IN PLARGE_INTEGER XtTime,\n                               OUT PTIME_FIELDS TimeFields)\n{\n    ULONG CurrentYear, Days, Leap, Periods1Year, Periods4Years, Periods100Years, Periods400Years;\n    ULONGLONG TotalSeconds, ElapsedDays, TotalSecondsOfDay;\n\n    /* Validate pointers */\n    if(XtTime == NULLPTR || TimeFields == NULLPTR)\n    {\n        /* Invalid pointers provided, return error code */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* The XT Epoch starts at 1601, negative absolute system time is not supported */\n    if(XtTime->QuadPart < 0)\n    {\n        /* Invalid time value, return error code */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Extract ticks into whole seconds and remaining milliseconds */\n    TotalSeconds = XtTime->QuadPart / TIME_TICKS_PER_SECOND;\n    TimeFields->Milliseconds = (SHORT)((XtTime->QuadPart % TIME_TICKS_PER_SECOND) / TIME_TICKS_PER_MILLISECOND);\n\n    /* Split total seconds into absolute elapsed days and time of the current day */\n    ElapsedDays = TotalSeconds / TIME_SECONDS_PER_DAY;\n    TotalSecondsOfDay = TotalSeconds % TIME_SECONDS_PER_DAY;\n\n    /* Calculate hour, minute, and second */\n    TimeFields->Hour = (SHORT)(TotalSecondsOfDay / TIME_SECONDS_PER_HOUR);\n    TimeFields->Minute = (SHORT)((TotalSecondsOfDay % TIME_SECONDS_PER_HOUR) / TIME_SECONDS_PER_MINUTE);\n    TimeFields->Second = (SHORT)(TotalSecondsOfDay % TIME_SECONDS_PER_MINUTE);\n\n    /* Calculate weekday */\n    TimeFields->Weekday = (SHORT)((ElapsedDays + 1) % 7);\n\n    /* Calculate the year using the Gregorian leap year cycles */\n    Days = (ULONG)ElapsedDays;\n    CurrentYear = 1601;\n\n    /* Calculate completed 400-year periods */\n    Periods400Years = Days / 146097;\n    CurrentYear += Periods400Years * 400;\n    Days %= 146097;\n\n    /* Calculate completed 100-year periods */\n    Periods100Years = Days / 36524;\n    if(Periods100Years == 4)\n    {\n        /* The leap year at the very end of a 400-year cycle */\n        Periods100Years = 3;\n    }\n\n    /* Update the current year and remaining days */\n    CurrentYear += Periods100Years * 100;\n    Days -= Periods100Years * 36524;\n\n    /* Calculate completed 4-year periods */\n    Periods4Years = Days / 1461;\n    CurrentYear += Periods4Years * 4;\n    Days %= 1461;\n\n    /* Calculate completed 1-year periods */\n    Periods1Year = Days / 365;\n    if(Periods1Year == 4)\n    {\n        /* The leap year at the end of a normal 4-year cycle */\n        Periods1Year = 3;\n    }\n\n    /* Update the current year and remaining days */\n    CurrentYear += Periods1Year;\n    Days -= Periods1Year * 365;\n\n    /* Set the calculated year */\n    TimeFields->Year = (SHORT)CurrentYear;\n\n    /* Check if the calculated year is a leap year */\n    Leap = LeapYear(TimeFields->Year) ? 1 : 0;\n    TimeFields->Month = 1;\n\n    /* Subtract days of each month to find the current month */\n    while(Days >= DaysInMonth[Leap][TimeFields->Month - 1])\n    {\n        /* Calculate the days of the current month and advance the month index */\n        Days -= DaysInMonth[Leap][TimeFields->Month - 1];\n        TimeFields->Month++;\n    }\n\n    /* Store the remainder as the 1-based day of the month */\n    TimeFields->Day = (SHORT)(Days + 1);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "xtoskrnl/rtl/widestr.cc",
    "content": "/**\n * PROJECT:         ExectOS\n * COPYRIGHT:       See COPYING.md in the top level directory\n * FILE:            xtoskrnl/rtl/widestr.cc\n * DESCRIPTION:     Wide string support\n * DEVELOPERS:      Rafal Kupiec <belliash@codingworkshop.eu.org>\n */\n\n#include <xtos.hh>\n\n\n/**\n * Compares at most specified number of characters of two C wide strings.\n *\n * @param String1\n *        Wide string to be compared.\n *\n * @param String2\n *        Wide string to be compared.\n *\n * @param Length\n *        Maximum number of characters to compare. If no limit set, it compares whole wide strings.\n *\n * @return Integral value indicating the relationship between the wide strings.\n *\n * @since XT 1.0\n */\nXTAPI\nSIZE_T\nRTL::WideString::CompareWideString(IN PCWSTR String1,\n                                   IN PCWSTR String2,\n                                   IN SIZE_T Length)\n{\n    SIZE_T Index;\n\n    /* Iterate through the strings */\n    for(Index = 0; ; Index++) {\n        /* Check if length limit reached */\n        if(Index != 0 && Index == Length)\n        {\n            /* Skip checking next characters */\n            break;\n        }\n\n        /* Check if wide string characters are equal */\n        if(String1[Index] != String2[Index])\n        {\n            /* Different characters found */\n            return String1[Index] < String2[Index] ? -1 : 1;\n        }\n\n        /* Check if end of wide string reached */\n        if(!String1[Index] || !String2[Index])\n        {\n            /* Equal wide strings until the end of one of them */\n            return 0;\n        }\n    }\n\n    /* Wide strings are equal */\n    return 0;\n}\n\n/**\n * Compares at most specified number of characters of two C wide strings, while ignoring differences in case.\n *\n * @param String1\n *        Wide string to be compared.\n *\n * @param String2\n *        Wide string to be compared.\n *\n * @param Length\n *        Maximum number of characters to compare. If no limit set, it compares whole wide strings.\n *\n * @return Integral value indicating the relationship between the wide strings.\n *\n * @since XT 1.0\n */\nXTAPI\nSIZE_T\nRTL::WideString::CompareWideStringInsensitive(IN PCWSTR String1,\n                                              IN PCWSTR String2,\n                                              IN SIZE_T Length)\n{\n    WCHAR Character1;\n    WCHAR Character2;\n    ULONG Index = 0;\n\n    /* Iterate through the wide strings */\n    while(String1[Index] != L'\\0' && String2[Index] != L'\\0')\n    {\n        /* Check if length limit reached */\n        if(Index != 0 && Index == Length)\n        {\n            /* Skip checking next characters */\n            break;\n        }\n\n        /* Get the characters */\n        Character1 = String1[Index];\n        Character2 = String2[Index];\n\n        /* Lowercase wide string1 character if needed */\n        if(String1[Index] >= L'A' && String1[Index] <= L'Z')\n        {\n            Character1 = String1[Index] - L'A' + L'a';\n        }\n\n        /* Lowercase wide string2 character if needed */\n        if(String2[Index] >= L'A' && String2[Index] <= L'Z')\n        {\n            Character2 = String2[Index] - L'A' + L'a';\n        }\n\n        /* Compare the characters */\n        if(Character1 != Character2)\n        {\n            /* Wide strings are not equal */\n            return Character1 > Character2 ? 1 : -1;\n        }\n\n        /* Get next character */\n        Index++;\n    }\n\n    /* Strings are equal */\n    return 0;\n}\n\n/**\n * Appends a copy of the source wide string to the end of the destination wide string.\n *\n * @param Destination\n *        Supplies a pointer to the NULL-terminated wide string to append to.\n *\n * @param Source\n *        Supplies a pointer to the NULL-terminated wide string to copy from.\n *\n * @param Count\n *        Sets a maximum number of wide characters to copy. If no limit set, appends whole wide string.\n *\n * @return This routine returns a copy of a destination wide string.\n *\n * @since XT 1.0\n */\nXTAPI\nPWCHAR\nRTL::WideString::ConcatenateWideString(OUT PWCHAR Destination,\n                                       IN PWCHAR Source,\n                                       IN SIZE_T Count)\n{\n    PWCHAR DestString = Destination;\n\n    /* Go to the end of destination wide string */\n    while(*Destination)\n    {\n        Destination++;\n    }\n\n    /* Check if copy limit set */\n    if(Count > 0)\n    {\n        /* Copy character-by-character */\n        do\n        {\n            /* Check if NULL terminated character found */\n            if((*Destination = *Source++) == L'\\0')\n            {\n                /* Break on '\\0' character */\n                break;\n            }\n            Destination++;\n        }\n        while(--Count != 0);\n\n        /* Add NULL termination character to the end of destination wide string */\n        *Destination = L'\\0';\n    }\n    else\n    {\n        /* No limit set, copy all wide characters */\n        while((*Destination++ = *Source++) != 0);\n    }\n\n    /* Return copy of the destination wide string */\n    return DestString;\n}\n\n/**\n * Copies a wide string from a buffer into another buffer, ensuring that the destination string is NULL-terminated.\n *\n * @param Destination\n *        Supplies a pointer to the destination buffer.\n *\n * @param Source\n *        Supplies a pointer to the source buffer.\n *\n * @param Length\n *        Supplies the length of the wide string to copy.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::WideString::CopyWideString(IN PWCHAR Destination,\n                                IN PCWSTR Source,\n                                IN ULONG Length)\n{\n    ULONG Index;\n\n    /* Copy characters */\n    for(Index = 0; Index < Length; Index++)\n    {\n        /* Copy source character */\n        Destination[Index] = Source[Index];\n\n        /* Check if NULL terminated character found */\n        if(Source[Index] == L'\\0')\n        {\n            /* End of source string reached */\n            break;\n        }\n    }\n\n    /* Make sure the destination string is terminated properly */\n    Destination[Index] = L'\\0';\n}\n\n/**\n * Finds the first occurrence of the search wide string in the source wide string.\n *\n * @param Source\n *        Supplies a pointer to the source wide string.\n *\n * @param Search\n *        Supplies a pointer to the search wide string.\n *\n * @return This routine returns a pointer to the first occurrence of the search wide string in the source wide string.\n *\n * @since XT 1.0\n */\nXTAPI\nPCWSTR\nRTL::WideString::FindWideString(IN PCWSTR Source,\n                                IN PCWSTR Search)\n{\n    PCWSTR CurrentSource;\n    PCWSTR CurrentSearch;\n\n    /* Validate input parameters */\n    if(!Source || !Search)\n    {\n        /* Invalid input parameters, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Check if search string is empty */\n    if(*Search == L'\\0')\n    {\n        /* Return the source string */\n        return Source;\n    }\n\n    /* Iterate through the source string */\n    for(; *Source != L'\\0'; Source++) {\n\n        /* Initialize pointers */\n        CurrentSource = Source;\n        CurrentSearch = Search;\n\n        /* Check if the substring matches starting at the current position */\n        while(*CurrentSource != L'\\0' && *CurrentSearch != L'\\0' && *CurrentSource == *CurrentSearch)\n        {\n            /* Go to the next character */\n            CurrentSource++;\n            CurrentSearch++;\n        }\n\n        /* If we reached the end of Search string, it is a match */\n        if(*CurrentSearch == L'\\0')\n        {\n            /* Return the source position */\n            return Source;\n        }\n    }\n\n    /* No match found, return NULLPTR */\n    return NULLPTR;\n}\n\n/**\n * Finds the first case-insensitive occurrence of the search wide string in the source wide string.\n *\n * @param Source\n *        Supplies a pointer to the source wide string.\n *\n * @param Search\n *        Supplies a pointer to the search wide string.\n *\n * @return This routine returns a pointer to the first occurrence of the search wide string in the source wide string.\n *\n * @since XT 1.0\n */\nXTAPI\nPCWSTR\nRTL::WideString::FindWideStringInsensitive(IN PCWSTR Source,\n                                           IN PCWSTR Search)\n{\n    PCWSTR CurrentSource;\n    PCWSTR CurrentSearch;\n\n    /* Validate input parameters */\n    if(!Source || !Search)\n    {\n        /* Invalid input parameters, return NULLPTR */\n        return NULLPTR;\n    }\n\n    /* Check if search string is empty */\n    if(*Search == L'\\0')\n    {\n        /* Return the source string */\n        return Source;\n    }\n\n    /* Iterate through the source string */\n    for(; *Source != L'\\0'; Source++) {\n\n        /* Initialize pointers */\n        CurrentSource = Source;\n        CurrentSearch = Search;\n\n        /* Check if the substring matches starting at the current position */\n        while(*CurrentSource != L'\\0' && *CurrentSearch != L'\\0' &&\n              ToLowerWideCharacter(*CurrentSource) == ToLowerWideCharacter(*CurrentSearch))\n        {\n            /* Go to the next character */\n            CurrentSource++;\n            CurrentSearch++;\n        }\n\n        /* If we reached the end of Search string, it is a match */\n        if(*CurrentSearch == L'\\0')\n        {\n            /* Return the source position */\n            return Source;\n        }\n    }\n\n    /* No match found, return NULLPTR */\n    return NULLPTR;\n}\n\n/**\n * Formats a wide string according to the given printf-alike format string and a list of arguments.\n *\n * @param Context\n *        Supplies a pointer to the print context structure.\n *\n * @param Format\n *        Supplies a pointer to the printf-alike format string.\n *\n * @param ArgumentList\n *        Supplies a list of arguments to the format string.\n *\n * @param Index\n *        Supplies a pointer to the position of the current format specifier, that will be advanced beyond the specifier.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::WideString::FormatArgumentSpecifier(IN PRTL_PRINT_CONTEXT Context,\n                                         IN PCWSTR Format,\n                                         IN PVA_LIST ArgumentList,\n                                         IN OUT PULONG Index)\n{\n    RTL_PRINT_FORMAT_PROPERTIES FormatProperties;\n    PUNICODE_STRING UnicodeStrArg;\n    WCHAR Specifier, WideCharArg;\n    PANSI_STRING AnsiStrArg;\n    LONGLONG SpecifierValue;\n    VA_LIST ArgumentsCopy;\n    LARGE_DOUBLE FloatArg;\n    PCWSTR FormatIndex;\n    ULONG ArgPosition;\n    PCWSTR WideStrArg;\n    ULONGLONG IntArg;\n    XTSTATUS Status;\n    PGUID GuidArg;\n    PCHAR StrArg;\n    CHAR CharArg;\n\n    /* Set current format specifier index and custom argument position */\n    FormatIndex = Format + *Index + 1;\n    ArgPosition = 0;\n\n    /* Initialize format properties */\n    RTL::Memory::ZeroMemory(&FormatProperties, sizeof(RTL_PRINT_FORMAT_PROPERTIES));\n    FormatProperties.IntegerSize = sizeof(INT);\n    FormatProperties.Precision = -1;\n\n\n    /* Make a copy of the argument list */\n    VA_COPY(ArgumentsCopy, *ArgumentList);\n\n    /* Lookup parameter field */\n    if((*FormatIndex >= L'1') && (*FormatIndex <= L'9'))\n    {\n        /* POSIX extension found, read its value */\n        SpecifierValue = GetSpecifierValue((PWSTR*)&FormatIndex);\n\n        /* Make sure parameter field ends with '$' character */\n        if(*FormatIndex == L'$')\n        {\n            /* Store number of parameter and increment index */\n            ArgPosition = (ULONG)SpecifierValue;\n            FormatIndex++;\n        }\n        else\n        {\n            /* Field not ended with '$' character, treat it as width field */\n            FormatProperties.FieldWidth = (ULONG)SpecifierValue;\n        }\n    }\n\n    /* Lookup flags field */\n    while(TRUE)\n    {\n        /* Look for a valid flag and set properties */\n        if(*FormatIndex == L'\\'')\n        {\n            /* Thousands grouping separator applied */\n            FormatProperties.Flags |= PFL_THOUSANDS_GROUPING;\n        }\n        else if(*FormatIndex == L'-')\n        {\n            /* Left-align the output */\n            FormatProperties.Flags |= PFL_LEFT_JUSTIFIED;\n        }\n        else if(*FormatIndex == L' ')\n        {\n            /* Prepend a space for positive signed-numeric types */\n            FormatProperties.Flags |= PFL_SPACE_FOR_PLUS;\n        }\n        else if(*FormatIndex == L'+')\n        {\n            /* Prepend a plus for positive signed-numeric types */\n            FormatProperties.Flags |= PFL_ALWAYS_PRINT_SIGN;\n        }\n        else if(*FormatIndex == L'#')\n        {\n            /* Convert to an alternate form */\n            FormatProperties.Flags |= PFL_PRINT_RADIX;\n        }\n        else if(*FormatIndex == L'0')\n        {\n            /* Prepend zeros for numeric types */\n            FormatProperties.Flags |= PFL_LEADING_ZEROES;\n        }\n        else\n        {\n            /* No more flags to read */\n            break;\n        }\n\n        /* Move to the next character */\n        FormatIndex++;\n    }\n\n    /* Check if output is left-justified */\n    if(FormatProperties.Flags & PFL_LEFT_JUSTIFIED)\n    {\n        /* Left justified output can't have leading zeros */\n        FormatProperties.Flags &= ~PFL_LEADING_ZEROES;\n    }\n\n    /* Check if plus for positive signed-numeric types is enabled */\n    if(FormatProperties.Flags & PFL_ALWAYS_PRINT_SIGN)\n    {\n        /* Do not append a space when plus character is enabled */\n        FormatProperties.Flags &= ~PFL_SPACE_FOR_PLUS;\n    }\n\n    /* Lookup width field */\n    if(*FormatIndex == L'*')\n    {\n        /* Skip dynamic width field indicator */\n        FormatIndex++;\n\n        /* Read dynamic width value from the argument list */\n        FormatProperties.FieldWidth = VA_ARG(*ArgumentList, INT);\n    }\n    else if((*FormatIndex >= L'1') && (*FormatIndex <= L'9'))\n    {\n        /* Read a numeric width value */\n        FormatProperties.FieldWidth = GetSpecifierValue((PWSTR*)&FormatIndex);\n    }\n\n    /* Check if field width is set to negative value */\n    if(FormatProperties.FieldWidth < 0)\n    {\n        /* Force left-aligned output and turn field width into positive value */\n        FormatProperties.Flags |= PFL_LEFT_JUSTIFIED;\n        FormatProperties.FieldWidth *= -1;\n    }\n\n    /* Lookup precision field */\n    if(*FormatIndex == L'.')\n    {\n        /* Skip precision field indicator */\n        FormatIndex++;\n\n        /* Look for a dynamic precision value indicator */\n        if(*FormatIndex == L'*')\n        {\n            /* Read dynamic precision value from the argument list */\n            FormatIndex++;\n            FormatProperties.Precision = VA_ARG(*ArgumentList, INT);\n        }\n        else if((*FormatIndex >= L'0') && (*FormatIndex <= L'9'))\n        {\n            /* Read a numeric precision value */\n            FormatProperties.Precision = GetSpecifierValue((PWSTR*)&FormatIndex);\n        }\n        else\n        {\n            /* Set default precision */\n            FormatProperties.Precision = 0;\n        }\n    }\n\n    /* Check if precision is set to negative value */\n    if(FormatProperties.Precision < 0)\n    {\n        /* Disable precision */\n        FormatProperties.Precision = -1;\n    }\n\n    /* Lookup argument length modifier */\n    Specifier = *FormatIndex;\n    switch(Specifier)\n    {\n        case L'h':\n            /* SHORT-sized integer argument */\n            FormatIndex++;\n            FormatProperties.IntegerSize = sizeof(SHORT);\n            FormatProperties.Flags |= PFL_SHORT_VALUE;\n            if(*FormatIndex == L'h')\n            {\n                /* CHAR-sized integer argument */\n                FormatIndex++;\n                FormatProperties.IntegerSize = sizeof(CHAR);\n                FormatProperties.Flags &= ~PFL_SHORT_VALUE;\n            }\n            break;\n        case L'j':\n            /* INTMAX-sized integer argument */\n            FormatIndex++;\n            FormatProperties.IntegerSize = sizeof(LONG_PTR);\n            break;\n        case L'l':\n            /* LONG-sized double/integer argument */\n            FormatIndex++;\n            FormatProperties.IntegerSize = sizeof(LONG);\n            FormatProperties.Flags |= PFL_LONG_DOUBLE | PFL_LONG_INTEGER | PFL_WIDE_CHARACTER;\n            if(*FormatIndex == L'l')\n            {\n                /* LONGLONG-sized integer argument */\n                FormatIndex++;\n                FormatProperties.IntegerSize = sizeof(LONGLONG);\n                FormatProperties.Flags &= ~(PFL_LONG_DOUBLE | PFL_LONG_INTEGER | PFL_WIDE_CHARACTER);\n            }\n            break;\n        case L'q':\n            /* BSD extension: 64-bit (quad word) integer argument */\n            FormatIndex++;\n            FormatProperties.IntegerSize = sizeof(LONGLONG);\n            break;\n        case L't':\n            /* PTRDIFF-sized integer argument */\n            FormatIndex++;\n            FormatProperties.IntegerSize = sizeof(PVOID);\n            break;\n        case L'w':\n            /* MSVC extension: wide character or wide string argument */\n            FormatIndex++;\n            FormatProperties.Flags |= PFL_WIDE_CHARACTER;\n            break;\n        case L'z':\n            /* SIZE_T-sized integer argument */\n            FormatIndex++;\n            FormatProperties.IntegerSize = sizeof(SIZE_T);\n            break;\n        case L'I':\n            /* MSVC extension: SIZE_T-sized integer argument */\n            FormatIndex++;\n            FormatProperties.IntegerSize = sizeof(SIZE_T);\n            if((*FormatIndex == L'3') && (*(FormatIndex + 1) == L'2'))\n            {\n                /* MSVC extension: 32-bit (double word) integer argument */\n                FormatIndex += 2;\n                FormatProperties.IntegerSize = sizeof(LONG);\n                FormatProperties.Flags |= PFL_LONG_INTEGER;\n            }\n            else if((*FormatIndex == L'6') && (*(FormatIndex + 1) == L'4'))\n            {\n                /* MSVC extension: 64-bit (quad word) integer argument */\n                FormatIndex += 2;\n                FormatProperties.IntegerSize = sizeof(LONGLONG);\n            }\n            break;\n        case L'L':\n            /* LONG-sized double argument */\n            FormatIndex++;\n            FormatProperties.IntegerSize = sizeof(LDOUBLE);\n            FormatProperties.Flags |= PFL_LONG_DOUBLE;\n            break;\n    }\n\n    /* Lookup format specifier */\n    Specifier = *FormatIndex++;\n\n    /* Handle char and string modifiers */\n    if(FormatProperties.Flags & PFL_WIDE_CHARACTER)\n    {\n        if(Specifier == L'c')\n        {\n            /* Wide character argument */\n            Specifier = L'C';\n        }\n        else if(Specifier == L's')\n        {\n            /* Wide string argument */\n            Specifier = L'S';\n        }\n    }\n\n    /* Lookup format specifier */\n    FormatProperties.Flags |= PFL_UNSIGNED;\n    switch(Specifier)\n    {\n        case L'a':\n            /* Double argument as hexadecimal number (lowercase) */\n            FormatProperties.VariableType = TypeFloat;\n            FormatProperties.Flags |= PFL_SCI_FORMAT;\n            FormatProperties.Radix = 16;\n            break;\n        case L'A':\n            /* Double argument as hexadecimal number (uppercase) */\n            FormatProperties.VariableType = TypeFloat;\n            FormatProperties.Flags |= PFL_SCI_FORMAT | PFL_UPPERCASE;\n            FormatProperties.Radix = 16;\n            break;\n        case L'b':\n            /* XTOS extension: Boolean argument (lowercase) */\n            FormatProperties.VariableType = TypeBoolean;\n            break;\n        case L'B':\n            /* XTOS extension: Boolean argument (uppercase) */\n            FormatProperties.VariableType = TypeBoolean;\n            FormatProperties.Flags |= PFL_UPPERCASE;\n            break;\n        case L'c':\n            /* Character argument */\n            FormatProperties.VariableType = TypeChar;\n            break;\n        case L'C':\n            /* Wide character argument */\n            FormatProperties.VariableType = TypeWideChar;\n            break;\n        case L'd':\n        case L'i':\n            /* Signed integer argument as decimal number */\n            FormatProperties.VariableType = TypeInteger;\n            FormatProperties.Flags &= ~PFL_UNSIGNED;\n            FormatProperties.Radix = 10;\n            break;\n        case L'e':\n            /* Double argument in scientific notation (lowercase) */\n            FormatProperties.VariableType = TypeFloat;\n            FormatProperties.Flags |= PFL_SCI_FORMAT;\n            break;\n        case L'E':\n            /* Double argument in scientific notation (uppercase) */\n            FormatProperties.VariableType = TypeFloat;\n            FormatProperties.Flags |= PFL_SCI_FORMAT | PFL_UPPERCASE;\n            break;\n        case L'f':\n            /* Double argument as floating point number (lowercase) */\n            FormatProperties.VariableType = TypeFloat;\n            FormatProperties.Flags |= PFL_FLOAT_FORMAT;\n            break;\n        case L'F':\n            /* Double argument as floating point number (uppercase) */\n            FormatProperties.VariableType = TypeFloat;\n            FormatProperties.Flags |= PFL_FLOAT_FORMAT | PFL_UPPERCASE;\n            break;\n        case L'g':\n            /* Double argument as either floating point number or in scientific notation (lowercase) */\n            FormatProperties.VariableType = TypeFloat;\n            FormatProperties.Flags |= PFL_DIGIT_PRECISION;\n            break;\n        case L'G':\n            /* Double argument as either floating point number or in scientific notation (uppercase) */\n            FormatProperties.VariableType = TypeFloat;\n            FormatProperties.Flags |= PFL_DIGIT_PRECISION | PFL_UPPERCASE;\n            break;\n        case L'n':\n            /* Write number of characters written so far into an integer pointer parameter */\n            FormatProperties.VariableType = TypeInteger;\n            FormatProperties.IntegerSize = sizeof(PVOID);\n            break;\n        case L'o':\n            /* Unsigned integer argument as octal number */\n            FormatProperties.VariableType = TypeInteger;\n            FormatProperties.Radix = 8;\n            break;\n        case L'p':\n            /* Pointer argument as hexadecimal number (lowercase) */\n            FormatProperties.VariableType = TypeInteger;\n            FormatProperties.IntegerSize = sizeof(UINT_PTR);\n            FormatProperties.Flags |= PFL_PRINT_RADIX;\n            FormatProperties.Radix = 16;\n            break;\n        case L'P':\n            /* XTOS extension: Pointer argument as hexadecimal number (uppercase) */\n            FormatProperties.VariableType = TypeInteger;\n            FormatProperties.IntegerSize = sizeof(UINT_PTR);\n            FormatProperties.Flags |= PFL_PRINT_RADIX | PFL_UPPERCASE;\n            FormatProperties.Radix = 16;\n            break;\n        case L's':\n            /* String argument */\n            FormatProperties.VariableType = TypeString;\n            break;\n        case L'S':\n            /* Wide string argument */\n            FormatProperties.VariableType = TypeWideString;\n            break;\n        case L'u':\n            /* Unsigned integer argument as decimal number */\n            FormatProperties.VariableType = TypeInteger;\n            FormatProperties.Radix = 10;\n            break;\n        case L'v':\n            /* XTOS extension: UUID/GUID argument (lowercase) */\n            FormatProperties.VariableType = TypeGuid;\n            break;\n        case L'V':\n            /* XTOS extension: UUID/GUID argument (uppercase) */\n            FormatProperties.VariableType = TypeGuid;\n            FormatProperties.Flags |= PFL_UPPERCASE;\n            break;\n        case L'x':\n            /* Unsigned integer argument as hexadecimal number (lowercase) */\n            FormatProperties.VariableType = TypeInteger;\n            FormatProperties.Radix = 16;\n            break;\n        case L'X':\n            /* Unsigned integer argument as hexadecimal number (uppercase) */\n            FormatProperties.VariableType = TypeInteger;\n            FormatProperties.Flags |= PFL_UPPERCASE;\n            FormatProperties.Radix = 16;\n            break;\n        case L'Z':\n            /* MSVC extension: ANSI/Unicode string argument */\n            FormatProperties.VariableType = (FormatProperties.Flags & PFL_WIDE_CHARACTER) ? TypeUnicodeString\n                                                                                          : TypeAnsiString;\n            break;\n        case L'%':\n            /* Print '%' character */\n            FormatProperties.VariableType = TypeUnknown;\n            WideCharArg = L'%';\n            break;\n        default:\n            /* Unknown format specifier, print '?' character */\n            FormatProperties.VariableType = TypeUnknown;\n            WideCharArg = L'?';\n            break;\n    }\n\n    /* Finally, write the formatted argument */\n    if(FormatProperties.VariableType == TypeUnknown)\n    {\n        /* Write defined wide character */\n        Status = WriteValue(Context, &FormatProperties, &WideCharArg, 1);\n    }\n    if(FormatProperties.VariableType == TypeBoolean)\n    {\n        /* Boolean type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            IntArg = GetArgument(&ArgumentsCopy, ArgPosition, FormatProperties.IntegerSize);\n        }\n        else\n        {\n            /* Get argument value from the next argument */\n            IntArg = VA_ARG(*ArgumentList, ULONGLONG);\n        }\n\n        /* Check if using uppercase format */\n        if(FormatProperties.Flags & PFL_UPPERCASE)\n        {\n            /* Set uppercase boolean string depending on argument value */\n            WideStrArg = IntArg ? L\"TRUE\" : L\"FALSE\";\n        }\n        else\n        {\n            /* Set lowercase boolean string depending on argument value */\n            WideStrArg = IntArg ? L\"true\" : L\"false\";\n        }\n\n        /* Write formatted boolean string */\n        Status = WriteValue(Context, &FormatProperties, WideStrArg, WideStringLength(WideStrArg, 0));\n    }\n    else if(FormatProperties.VariableType == TypeGuid)\n    {\n        /* GUID type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PGUID));\n            GuidArg = (PGUID)(UINT_PTR)IntArg;\n        }\n        else\n        {\n            /* Get argument value from the next argument */\n            GuidArg = VA_ARG(*ArgumentList, PGUID);\n        }\n\n        /* Make sure a pointer to GUID is not NULL pointer */\n        if(GuidArg != NULLPTR)\n        {\n            /* Check if using uppercase format */\n            if(FormatProperties.Flags & PFL_UPPERCASE)\n            {\n                /* Use uppercase GUID format string */\n                WideStrArg = L\"%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\";\n            }\n            else\n            {\n                /* Use lowercase GUID format string */\n                WideStrArg = L\"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\";\n            }\n            /* Write formatted GUID string */\n            Status = WriteCustomValue(Context, WideStrArg, GuidArg->Data1, GuidArg->Data2, GuidArg->Data3,\n                                      GuidArg->Data4[0], GuidArg->Data4[1], GuidArg->Data4[2],\n                                      GuidArg->Data4[3], GuidArg->Data4[4], GuidArg->Data4[5],\n                                      GuidArg->Data4[6], GuidArg->Data4[7]);\n        }\n    }\n    else if(FormatProperties.VariableType == TypeChar)\n    {\n        /* Character type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            CharArg = (UCHAR)GetArgument(&ArgumentsCopy, ArgPosition, sizeof(UCHAR));\n        }\n        else\n        {\n            /* Get argument value from the next argument */\n            CharArg = VA_ARG(*ArgumentList, INT);\n        }\n\n        /* Write formatted character */\n        Status = WriteStringValue(Context, &FormatProperties, &CharArg, 1);\n    }\n    else if(FormatProperties.VariableType == TypeWideChar)\n    {\n        /* Wide character type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            WideCharArg = (WCHAR)GetArgument(&ArgumentsCopy, ArgPosition, sizeof(WCHAR));\n        }\n        else\n        {\n            /* Get argument value from the next argument */\n            WideCharArg = VA_ARG(*ArgumentList, INT);\n        }\n\n        /* Write formatted wide character */\n        Status = WriteValue(Context, &FormatProperties, &WideCharArg, 1);\n    }\n    else if(FormatProperties.VariableType == TypeFloat)\n    {\n        /* Float/Double type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            FloatArg.QuadPart = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(ULONGLONG));\n        }\n        else\n        {\n            /* Get argument value from the next argument, depending on its size */\n            if(FormatProperties.Flags & PFL_LONG_DOUBLE)\n            {\n                FloatArg.DoublePart = VA_ARG(*ArgumentList, LDOUBLE);\n            }\n            else\n            {\n                FloatArg.DoublePart = VA_ARG(*ArgumentList, DOUBLE);\n            }\n        }\n\n        /* Write formatted double value */\n        Status = WriteDoubleValue(Context, &FormatProperties, FloatArg.DoublePart);\n    }\n    else if(FormatProperties.VariableType == TypeInteger)\n    {\n        /* Integer type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            IntArg = GetArgument(&ArgumentsCopy, ArgPosition, FormatProperties.IntegerSize);\n\n            /* Convert to required integer size */\n            switch(FormatProperties.IntegerSize)\n            {\n                case sizeof(CHAR):\n                    IntArg = (UCHAR)IntArg;\n                    break;\n                case sizeof(SHORT):\n                    IntArg = (USHORT)IntArg;\n                    break;\n                case sizeof(LONG):\n                    IntArg = (ULONG)IntArg;\n                    break;\n                case sizeof(LONGLONG):\n                    IntArg = (ULONGLONG)IntArg;\n                    break;\n                default:\n                    return STATUS_INVALID_PARAMETER;\n            }\n        }\n        else\n        {\n            /* Get argument value from the next argument, depending on its size */\n            switch(FormatProperties.IntegerSize)\n            {\n                case sizeof(CHAR):\n                    IntArg = (CHAR)VA_ARG(*ArgumentList, UINT);\n                    break;\n                case sizeof(SHORT):\n                    IntArg = (SHORT)VA_ARG(*ArgumentList, UINT);\n                    break;\n                case sizeof(LONG):\n                    IntArg = VA_ARG(*ArgumentList, ULONG);\n                    break;\n                case sizeof(LONGLONG):\n                    IntArg = VA_ARG(*ArgumentList, ULONGLONG);\n                    break;\n                default:\n                    return STATUS_INVALID_PARAMETER;\n            }\n        }\n\n        /* Check if using 'n' specifier */\n        if(Specifier == L'n')\n        {\n            /* Make sure, that integer pointer parameter is not NULL */\n            if(IntArg != (UINT_PTR)NULLPTR)\n            {\n                /* Store number of characters written in integer pointer parameter */\n                *((PINT)(UINT_PTR)IntArg) = Context->CharactersWritten;\n            }\n        }\n        else\n        {\n            /* Write formatted integer value */\n            Status = WriteIntegerValue(Context, &FormatProperties, IntArg);\n        }\n    }\n    else if(FormatProperties.VariableType == TypeString)\n    {\n        /* String type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PCHAR));\n            StrArg = (PCHAR)(UINT_PTR)IntArg;\n        }\n        else\n        {\n            /* Get argument value from the next argument */\n            StrArg = VA_ARG(*ArgumentList, PCHAR);\n        }\n\n        /* Write formatted string value */\n        Status = WriteStringValue(Context, &FormatProperties, StrArg, RTL::String::StringLength(StrArg, 0));\n    }\n    else if(FormatProperties.VariableType == TypeWideString)\n    {\n        /* Wide string type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PWCHAR));\n            WideStrArg = (PCWSTR)(UINT_PTR)IntArg;\n        }\n        else\n        {\n            /* Get argument value from the next argument */\n            WideStrArg = VA_ARG(*ArgumentList, PWCHAR);\n        }\n\n        /* Write formatted wide string value */\n        Status = WriteValue(Context, &FormatProperties, WideStrArg, RtlWideStringLength(WideStrArg, 0));\n    }\n    else if(FormatProperties.VariableType == TypeAnsiString )\n    {\n        /* ANSI string type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PANSI_STRING));\n            AnsiStrArg = (PANSI_STRING)(UINT_PTR)IntArg;\n        }\n        else\n        {\n            /* Get argument value from the next argument */\n            AnsiStrArg = VA_ARG(*ArgumentList, PANSI_STRING);\n        }\n\n        /* Make sure a pointer to ANSI_STRING is not NULL */\n        if(AnsiStrArg != NULLPTR)\n        {\n            /* Write formatted ANSI string value */\n            Status = WriteStringValue(Context, &FormatProperties, AnsiStrArg->Buffer, AnsiStrArg->Length);\n        }\n    }\n    else if(FormatProperties.VariableType == TypeUnicodeString)\n    {\n        /* Unicode string type */\n        if(ArgPosition != 0)\n        {\n            /* Get argument value from specified argument position */\n            IntArg = GetArgument(&ArgumentsCopy, ArgPosition, sizeof(PUNICODE_STRING));\n            UnicodeStrArg = (PUNICODE_STRING)(UINT_PTR)IntArg;\n        }\n        else\n        {\n            /* Get argument value from the next argument */\n            UnicodeStrArg = VA_ARG(*ArgumentList, PUNICODE_STRING);\n        }\n\n        /* Make sure a pointer to UNICODE_STRING is not NULL */\n        if(UnicodeStrArg != NULLPTR)\n        {\n            /* Write formatted UNICODE string value */\n            Status = WriteValue(Context, &FormatProperties, UnicodeStrArg->Buffer, UnicodeStrArg->Length);\n        }\n    }\n\n    /* Cleanup ArgumentsCopy object */\n    VA_END(ArgumentsCopy);\n\n    /* Increase index position according to number of characters consumed */\n    *Index += ((UINT_PTR)FormatIndex - (UINT_PTR)(Format + *Index)) / sizeof(WCHAR);\n\n    /* Return status code */\n    return Status;\n}\n\n/**\n * Formats a wide string according to the given printf-alike format string.\n *\n * @param Context\n *        Supplies a pointer to the print context structure.\n *\n * @param Format\n *        Supplies a pointer to the printf-alike format string.\n *\n * @param ArgumentList\n *        Supplies a list of arguments to the format string.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::WideString::FormatWideString(IN PRTL_PRINT_CONTEXT Context,\n                                  IN PCWSTR Format,\n                                  IN VA_LIST ArgumentList)\n{\n    VA_LIST LocalArgumentList;\n    XTSTATUS Status;\n    ULONG Index;\n\n    /* Make sure, that we have valid context and write routine */\n    if(Context == NULLPTR || Context->WriteWideCharacter == NULLPTR)\n    {\n        /* Invalid context or write routine not set */\n        return FALSE;\n    }\n\n    /* Check format string pointer */\n    if(Format == NULLPTR)\n    {\n        /* Write null string */\n        Format = L\"(null)\";\n    }\n\n    /* Make a copy of the argument list */\n    VA_COPY(LocalArgumentList, ArgumentList);\n\n    /* Iterate through format string */\n    Index = 0;\n    while(Format[Index] != L'\\0')\n    {\n        /* Look for format specifier */\n        if(Format[Index] == L'%')\n        {\n            /* Handle format along with arguments */\n            Status = FormatArgumentSpecifier(Context, Format, &LocalArgumentList, &Index);\n        }\n        else\n        {\n            /* Write wide character and increase string index */\n            Status = WriteWideCharacter(Context, Format[Index]);\n            Index++;\n        }\n\n        /* Make sure character written successfully */\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Return status code */\n            return Status;\n        }\n    }\n\n    /* Clean up the argument list */\n    VA_END(LocalArgumentList);\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Gets the positional argument by scanning the argument list.\n *\n * @param ArgumentList\n *        Supplies a pointer to the argument list.\n *\n * @param ArgumentNumber\n *        Supplies the argument number.\n *\n * @param ArgumentSize\n *        Supplies the expected size of the argument.\n */\nXTAPI\nULONGLONG\nRTL::WideString::GetArgument(IN PVA_LIST ArgumentList,\n                             IN ULONG ArgumentNumber,\n                             IN LONG ArgumentSize)\n{\n    VA_LIST ArgumentsCopy;\n    ULONGLONG Value;\n    ULONG Index;\n\n    /* Make a copy of the argument list */\n    VA_COPY(ArgumentsCopy, *ArgumentList);\n\n    /* Skip all arguments before the specified one */\n    for(Index = 1; Index < ArgumentNumber; Index += 1)\n    {\n        /* Skip the argument */\n        Value = VA_ARG(ArgumentsCopy, LONGLONG);\n    }\n\n    /* Set default value */\n    Value = 0;\n\n    /* Get the argument value depending on its declared size */\n    switch(ArgumentSize)\n    {\n        case sizeof(CHAR):\n            Value = (UCHAR)VA_ARG(ArgumentsCopy, INT);\n            break;\n        case sizeof(SHORT):\n            Value = (USHORT)VA_ARG(ArgumentsCopy, INT);\n            break;\n        case sizeof(LONG):\n            Value = VA_ARG(ArgumentsCopy, LONG);\n            break;\n        case sizeof(LONGLONG):\n            Value = VA_ARG(ArgumentsCopy, LONGLONG);\n            break;\n        default:\n            Value = 0;\n            break;\n    }\n\n    /* Cleanup ArgumentsCopy object and return the argument value */\n    VA_END(ArgumentsCopy);\n    return Value;\n}\n\n/**\n * Gets the specifier integer value from the wide string advancing the pointer.\n *\n * @param Format\n *        Supplies a pointer to the wide string format, at integer value position.\n *\n * @return This routine returns a specifier integer value read from wide string format, or zero if no valid value found.\n *\n * @since XT 1.0\n */\nXTAPI\nULONGLONG\nRTL::WideString::GetSpecifierValue(IN PWCHAR *Format)\n{\n    ULONG Count;\n    PWCHAR Fmt;\n\n    /* Initialize variables */\n    Fmt = *Format;\n    Count = 0;\n\n    /* Read the specifier value */\n    for(;; Fmt++)\n    {\n        switch(*Fmt)\n        {\n            case L'0' ... L'9':\n                /* Read the number from wide string */\n                Count = Count * 10 + *Fmt - L'0';\n                break;\n            default:\n                /* No more numbers, return count */\n                *Format = Fmt;\n                return Count;\n        }\n    }\n\n    /* Return zero if no value specified */\n    return 0;\n}\n\n/**\n * Reverses a characters order in a wide string. It modifies the original, input variable.\n *\n * @param String\n *        Supplies a pointer to the wide string to reverse.\n *\n * @param Length\n *        Supplies the length of the wide string to reverse.\n *\n * @return This routine does not return any value.\n *\n * @since XT 1.0\n */\nXTAPI\nVOID\nRTL::WideString::ReverseWideString(IN OUT PWCHAR String,\n                                   IN ULONG Length)\n{\n    WCHAR TempChar;\n    ULONG Index;\n\n    /* Iterate through the string */\n    for(Index = 0; Index < (Length / 2); Index++)\n    {\n        /* Swap characters */\n        TempChar = String[Index];\n        String[Index] = String[Length - Index - 1];\n        String[Length - Index - 1] = TempChar;\n    }\n}\n\n/**\n * Finds the next token in a NULL-terminated wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to tokenize.\n *\n * @param Delimiter\n *        Pointer to the NULL-terminated wide string identifying delimiters.\n *\n * @param SavePtr\n *        Pointer to an object used to store routine internal state.\n *\n * @return Pointer to the beginning of the next token or NULLPTR if there are no more tokens.\n *\n * @since: XT 1.0\n */\nXTAPI\nPWCHAR\nRTL::WideString::TokenizeWideString(IN PWCHAR String,\n                                    IN PCWSTR Delimiter,\n                                    IN OUT PWCHAR *SavePtr)\n{\n    PWCHAR Span, Token;\n    WCHAR Char, SpanChar;\n\n    /* Check if there is anything to tokenize */\n    if(String == NULLPTR && (String = *SavePtr) == NULLPTR)\n    {\n        /* Empty string given */\n        return NULLPTR;\n    }\n\n    /* Check non-delimiter characters */\n    Char = *String++;\n    if(Char == L'\\0')\n    {\n        *SavePtr = NULLPTR;\n        return NULLPTR;\n    }\n    Token = String - 1;\n\n    /* Scan token for delimiters */\n    for(;;)\n    {\n        Char = *String++;\n        Span = (PWCHAR)Delimiter;\n        do\n        {\n            /* Check if delimiter found */\n            if((SpanChar = *Span++) == Char)\n            {\n                /* Check if end of string reached */\n                if(Char == L'\\0')\n                {\n                    /* End of string reached, no more tokens */\n                    String = NULLPTR;\n                }\n                else\n                {\n                    /* Terminate token */\n                    String[-1] = L'\\0';\n                }\n\n                /* Store pointer to the next token */\n                *SavePtr = String;\n\n                /* Return token */\n                return Token;\n            }\n        }\n        while(SpanChar != L'\\0');\n    }\n}\n\n/**\n * Converts a wide character to lowercase.\n *\n * @param Character\n *        Wide character to be converted.\n *\n * @return Converted wide character or original character if it was not uppercase.\n *\n * @since XT 1.0\n */\nXTAPI\nWCHAR\nRTL::WideString::ToLowerWideCharacter(IN WCHAR Character)\n{\n    /* Check if wide character is uppercase */\n    if(Character >= L'A' && Character <= L'Z')\n    {\n        /* Convert wide character to lowercase */\n        return (WCHAR)(Character + (L'a' - L'A'));\n    }\n\n    /* Return original wide character */\n    return Character;\n}\n\n/**\n * Converts a wide character to uppercase.\n *\n * @param Character\n *        Wide character to be converted.\n *\n * @return Converted wide character or original character if it was not lowercase.\n *\n * @since XT 1.0\n */\nXTAPI\nWCHAR\nRTL::WideString::ToUpperWideCharacter(IN WCHAR Character)\n{\n    /* Check if wide character is lowercase */\n    if(Character >= L'a' && Character <= L'z')\n    {\n        /* Convert wide character to uppercase */\n        return (WCHAR)(Character - (L'a' - L'A'));\n    }\n\n    /* Return original wide character */\n    return Character;\n}\n\n/**\n * Removes certain characters from a beginning of the wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to be trimmed.\n *\n * @return This routine returns a pointer to the left-trimmed wide string.\n *\n * @since XT 1.0\n */\nXTAPI\nPWCHAR\nRTL::WideString::TrimLeftWideString(IN PWCHAR String)\n{\n    PWCHAR Start;\n\n    /* Initialize pointer */\n    Start = String;\n\n    /* Skip all leading whitespaces */\n    while(*Start == L' ' || *Start == L'\\n' || *Start == L'\\t' || *Start == L'\\r' || *Start == L'\\v' || *Start == L'\\f')\n    {\n        /* Advance to the next character */\n        Start++;\n    }\n\n    /* Return left-trimmed string */\n    return Start;\n}\n\n/**\n * Removes certain characters from the end of the wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to be trimmed.\n *\n * @return This routine returns a pointer to the right-trimmed wide string.\n *\n * @since XT 1.0\n */\nXTAPI\nPWCHAR\nRTL::WideString::TrimRightWideString(IN PWCHAR String)\n{\n    PWCHAR End;\n\n    /* Find end of the string */\n    End = String + RtlWideStringLength(String, 0);\n\n    /* Skip all trailing whitespaces */\n    while((End != String) && (*End == L' ' || *End == L'\\n' || *End == L'\\t' ||\n                              *End == L'\\r' || *End == L'\\v' || *End == L'\\f'))\n    {\n        /* Move to the previous character */\n        End--;\n    }\n\n    /* Terminate the string */\n    *End = 0;\n\n    /* Return right-trimmed string */\n    return String;\n}\n\n/**\n * Removes certain characters from the beginning and the end of the wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to be trimmed.\n *\n * @return This routine returns a pointer to the trimmed wide string.\n *\n * @since XT 1.0\n */\nXTAPI\nPWCHAR\nRTL::WideString::TrimWideString(IN PWCHAR String)\n{\n    return RtlTrimLeftWideString(RtlTrimRightWideString(String));\n}\n\n/**\n * Calculates the length of a given wide string.\n *\n * @param String\n *        Pointer to the NULL-terminated wide string to be examined.\n *\n * @param MaxLength\n *        Maximum number of wide characters to examine. If no limit set, it examines whole string.\n *\n * @return The length of the NULL-terminated wide string.\n *\n * @since: XT 1.0\n */\nXTAPI\nSIZE_T\nRTL::WideString::WideStringLength(IN PCWSTR String,\n                                  IN SIZE_T MaxLength)\n{\n    SIZE_T Length;\n\n    /* Check if NULL pointer passed */\n    if(String == NULLPTR)\n    {\n        return 0;\n    }\n\n    /* Iterate through the wide string */\n    for(Length = 0; ; Length++)\n    {\n\n        /* Check if NULL found or max length limit reached */\n        if((Length != 0 && Length == MaxLength) || !String[Length])\n        {\n            /* Finish examination */\n            break;\n        }\n    }\n\n    /* Return wide string length */\n    return Length;\n}\n\n/**\n * Converts a wide string to a number.\n *\n * @param String\n *        Supplies a pointer to the NULL-terminated wide string to convert.\n *\n * @param Base\n *        Supplies the optional numerical base for the conversion (2, 8, 10, or 16).\n *\n * @param Value\n *        Supplies a pointer to a variable that receives the converted numeric value.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::WideString::WideStringToNumber(IN PCWSTR String,\n                                    IN ULONG Base,\n                                    OUT PULONG Value)\n{\n    BOOLEAN NegativeValue;\n    ULONG Digit, Result;\n\n    /* Validate input parameters */\n    if(!String || !Value)\n    {\n        /* Invalid input parameters, return error code */\n        return STATUS_INVALID_PARAMETER;\n    }\n\n    /* Initialize local variables */\n    NegativeValue = FALSE;\n    Result = 0;\n\n    /* Skip leading whitespaces and control characters */\n    while(*String != L'\\0' && *String <= L' ')\n    {\n        /* Advance to the next character */\n        String++;\n    }\n\n    /* Consume and record sign */\n    if(*String == L'-')\n    {\n        /* Set negative value flag and advance to the next character */\n        NegativeValue = TRUE;\n        String++;\n    }\n    else if(*String == L'+')\n    {\n        /* Advance to the next character */\n        String++;\n    }\n\n    /* Autodetect and validate the base */\n    if(Base == 0)\n    {\n        /* Autodetect base based on prefix */\n        if(String[0] == L'0')\n        {\n            /* Validate prefix */\n            if(String[1] == L'x' || String[1] == L'X')\n            {\n                /* Hexadecimal base */\n                Base = 16;\n                String += 2;\n            }\n            else if(String[1] == L'o' || String[1] == L'O')\n            {\n                /* Octal base */\n                Base = 8;\n                String += 2;\n            }\n            else if(String[1] == L'b' || String[1] == L'B')\n            {\n                /* Binary base */\n                Base = 2;\n                String += 2;\n            }\n            else\n            {\n                /* Starts with 0 but no known prefix, treat as decimal */\n                Base = 10;\n            }\n        }\n        else\n        {\n            /* Default to decimal base */\n            Base = 10;\n        }\n    }\n    else\n    {\n        /* Validate explicitly provided base */\n        if(Base != 2 && Base != 8 && Base != 10 && Base != 16)\n        {\n            /* Invalid base, return error code */\n            return STATUS_INVALID_PARAMETER;\n        }\n\n        /* Check if number starts with 0 */\n        if(String[0] == L'0')\n        {\n            /* Check for prefix */\n            if(Base == 16 && (String[1] == L'x' || String[1] == L'X'))\n            {\n                /* Skip hexadecimal prefix */\n                String += 2;\n            }\n            else if(Base == 8 && (String[1] == L'o' || String[1] == L'O'))\n            {\n                /* Skip octal prefix */\n                String += 2;\n            }\n            else if(Base == 2 && (String[1] == L'b' || String[1] == L'B'))\n            {\n                /* Skip binary prefix */\n                String += 2;\n            }\n        }\n    }\n\n    /* Parse string character by character */\n    while(*String != L'\\0')\n    {\n        /* Convert wide character to numeric digit */\n        if(*String >= L'0' && *String <= L'9')\n        {\n            /* Convert decimal digit */\n            Digit = *String - L'0';\n        }\n        else if(*String >= L'A' && *String <= L'F')\n        {\n            /* Convert hexadecimal digit */\n            Digit = *String - L'A' + 10;\n        }\n        else if(*String >= L'a' && *String <= L'f')\n        {\n            /* Convert hexadecimal digit */\n            Digit = *String - L'a' + 10;\n        }\n        else\n        {\n            /* Invalid character for a number encountered, stop parsing */\n            break;\n        }\n\n        /* Check if digit is valid for the current base */\n        if(Digit >= Base)\n        {\n            /* Digit out of range for this base, stop parsing */\n            break;\n        }\n\n        /* Check for integer overflow */\n        if((Result > (MAXULONG / Base)) || ((Result * Base) > (MAXULONG - Digit)))\n        {\n            /* Integer overflow, return error code */\n            return STATUS_INTEGER_OVERFLOW;\n        }\n\n        /* Accumulate result */\n        Result = (Result * Base) + Digit;\n\n        /* Advance to the next character */\n        String++;\n    }\n\n    /* Check for negative value */\n    if(NegativeValue)\n    {\n        /* Apply sign and return the result */\n        *Value = (ULONG)(-(LONG)Result);\n    }\n    else\n    {\n        /* Return the result */\n        *Value = Result;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Writes a wide character to the destination provided by the print context.\n *\n * @param Context\n *        Supplies a pointer to the print context structure.\n *\n * @param Character\n *        Supplies the wide character to write.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::WideString::WriteWideCharacter(IN PRTL_PRINT_CONTEXT Context,\n                                    IN WCHAR Character)\n{\n    XTSTATUS Status;\n\n    /* Write wide character and increment number of characters written so far */\n    Status = Context->WriteWideCharacter(Character);\n    Context->CharactersWritten++;\n\n    /* Return status code */\n    return Status;\n}\n\n/**\n * Writes a wide string custom-formatted value to the destination provided by the print context.\n *\n * @param Context\n *        Supplies a pointer to the print context structure.\n *\n * @param Format\n *        Supplies a pointer to the printf-alike format string.\n *\n * @param ...\n *        Depending on the format string, this routine might expect a sequence of additional arguments.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTCDECL\nXTSTATUS\nRTL::WideString::WriteCustomValue(IN PRTL_PRINT_CONTEXT Context,\n                                  IN PCWSTR Format,\n                                  IN ...)\n{\n    VA_LIST Arguments;\n    XTSTATUS Status;\n\n    /* Initialise the va_list */\n    VA_START(Arguments, Format);\n\n    /* Format and print the string to the desired output */\n    Status = FormatWideString(Context, Format, Arguments);\n\n    /* Clean up the va_list */\n    VA_END(Arguments);\n\n    /* Return status code */\n    return Status;\n}\n\nXTAPI\nXTSTATUS\nRTL::WideString::WriteDoubleValue(IN PRTL_PRINT_CONTEXT Context,\n                                  IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                  IN DOUBLE Value)\n{\n    LONG CurrentExponent, DigitCount, Exponent, Precision, PrecisionIndex, SignificantDigits;\n    WCHAR Character, Digit, ExponentCharacter, SignCharacter;\n    ULONG FieldCount, FieldIndex, Index, NumberLength;\n    WCHAR Buffer[MAX_DOUBLE_STRING_SIZE];\n    BOOLEAN NegativeValue, WriteExponent;\n    DOUBLE RoundingAmount, TenPower;\n    PCWSTR NonNumberString;\n    LARGE_DOUBLE Parts;\n    XTSTATUS Status;\n\n    /* Initialize variables */\n    NegativeValue = FALSE;\n    NumberLength = 0;\n    Parts.DoublePart = Value;\n    Precision = FormatProperties->Precision;\n    SignCharacter = 0;\n\n    /* Check if the precision is specified */\n    if(Precision == -1)\n    {\n        /* Set default precision */\n        Precision = DOUBLE_PRECISION;\n    }\n\n    /* Check if the precision is zero */\n    if((FormatProperties->Flags & PFL_DIGIT_PRECISION) && (Precision == 0))\n    {\n        /* Display at least one digit */\n        Precision = 1;\n    }\n\n    /* Determine whether the value is infinite or nan */\n    if(RTL::Math::InfiniteDouble(Value))\n    {\n        /* Check if the value is nan */\n        if(RTL::Math::NanDouble(Value))\n        {\n            /* Set non-number string depending on the selection of upper or lowercase */\n            if(FormatProperties->Flags & PFL_UPPERCASE)\n            {\n                NonNumberString = L\"#NAN\";\n            }\n            else\n            {\n                NonNumberString = L\"#nan\";\n            }\n        }\n        else\n        {\n            /* Otherwise it is infinite, set proper string depending on the selection of upper or lowercase */\n            if(FormatProperties->Flags & PFL_UPPERCASE)\n            {\n                NonNumberString = L\"#INF\";\n            }\n            else\n            {\n                NonNumberString = L\"#inf\";\n            }\n\n            /* Check if the value is negative */\n            if(Value < 0)\n            {\n                NegativeValue = TRUE;\n            }\n        }\n\n        /* Set index to 0 and add sign if needed */\n        Index = 0;\n        if(NegativeValue != FALSE)\n        {\n            /* Add negative (-) sign */\n            Buffer[Index] = L'-';\n            Index++;\n        }\n        else if(FormatProperties->Flags & PFL_ALWAYS_PRINT_SIGN)\n        {\n            /* Add positive (+) sign */\n            Buffer[Index] = L'+';\n            Index++;\n        }\n        else if(FormatProperties->Flags & PFL_SPACE_FOR_PLUS)\n        {\n            /* Add space for positive value */\n            Buffer[Index] = L' ';\n            Index++;\n        }\n\n        /* Copy string to buffer and write it to wide string context */\n        CopyWideString(Buffer + Index, NonNumberString, sizeof(Buffer) - Index);\n        return WriteValue(Context, FormatProperties, Buffer, WideStringLength(Buffer, 0));\n    }\n\n    /* Check whether we need to handle hexadecimal format */\n    if(FormatProperties->Radix == 16)\n    {\n        /* Handle it as hex value */\n        return WriteHexDoubleValue(Context, FormatProperties, Value);\n    }\n\n    /* Check if the value is negative */\n    if((Parts.u.HighPart & (DOUBLE_SIGN_BIT >> DOUBLE_HIGH_VALUE_SHIFT)) != 0)\n    {\n        /* Turn the negative value into a positive value */\n        Value *= -1;\n        NegativeValue = TRUE;\n    }\n\n    /* Calculate the exponent */\n    Exponent = RTL::Math::GetBaseExponent(Value, &TenPower);\n    RoundingAmount = 0.5;\n\n    /* Determine whether or not to write the exponent */\n    WriteExponent = (BOOLEAN)(FormatProperties->Flags & PFL_SCI_FORMAT);\n    if((WriteExponent == FALSE) && !(FormatProperties->Flags & PFL_FLOAT_FORMAT))\n    {\n        if((Exponent < DOUBLE_SCIENTIFIC_PRECISION) || (Exponent >= Precision))\n        {\n            /* Write the exponent */\n            WriteExponent = TRUE;\n        }\n    }\n\n    /* Make sure the value is not zero */\n    DigitCount = 0;\n    if(Value != 0.0)\n    {\n        /* Adjust rounding if needed */\n        if((WriteExponent != FALSE) || (FormatProperties->Flags & PFL_DIGIT_PRECISION))\n        {\n            /* Calculate the rounding */\n            RoundingAmount /= TenPower;\n\n            /* Check if the precision is specified */\n            if(FormatProperties->Flags & PFL_DIGIT_PRECISION)\n            {\n                /* Increase rounding amount */\n                RoundingAmount *= 10.0;\n            }\n        }\n\n        /* Handle the rounding precision */\n        for(PrecisionIndex = 0; PrecisionIndex < Precision; PrecisionIndex++)\n        {\n            RoundingAmount *= 0.1;\n        }\n\n        /* Normalize the value */\n        Value += RoundingAmount;\n        Value *= TenPower;\n\n        /* Adjust the value if it is greater than 9 */\n        if((LONG)Value > 9)\n        {\n            Value *= 0.1;\n            Exponent += 1;\n        }\n\n        /* Turn numbers into characters */\n        while((Value != 0.0) && (DigitCount < MAX_DOUBLE_STRING_SIZE))\n        {\n            Buffer[DigitCount] = (LONG)Value + L'0';\n            DigitCount += 1;\n            Value = (Value - (double)(LONG)Value) * 10.0;\n        }\n\n        /* Check if precision matters */\n        if(FormatProperties->Flags & PFL_DIGIT_PRECISION)\n        {\n            /* Make sure precision is greater than 0 */\n            if(Precision > 0)\n            {\n                /* Check if number of digit exceeds the precision */\n                if(DigitCount > Precision)\n                {\n                    /* Decrease the number of digits to fit the precision */\n                    DigitCount = Precision;\n                }\n            }\n        }\n\n        /* Remove zero characters from the end of the string */\n        while((DigitCount > 1) && (Buffer[DigitCount - 1] == L'0'))\n        {\n            /* Decrease buffer length */\n            DigitCount -= 1;\n        }\n    }\n\n    /* Handle the sign character */\n    if(NegativeValue)\n    {\n        /* Negative value, add the '-' character */\n        SignCharacter = L'-';\n    }\n    else if(FormatProperties->Flags & PFL_ALWAYS_PRINT_SIGN)\n    {\n        /* Positive value, add the '+' character */\n        SignCharacter = L'+';\n    }\n    else if(FormatProperties->Flags & PFL_SPACE_FOR_PLUS)\n    {\n        /* Positive value, add the ' ' character */\n        SignCharacter = L' ';\n    }\n\n    /* Handle the significant digit precision */\n    SignificantDigits = DigitCount;\n    if(FormatProperties->Flags & PFL_DIGIT_PRECISION)\n    {\n        /* Check if number of digit exceeds the precision */\n        if(SignificantDigits > Precision)\n        {\n            /* Cap the number of significant digits */\n            SignificantDigits = Precision;\n        }\n        else if(Precision > SignificantDigits)\n        {\n            /* Cap the precision */\n            Precision = SignificantDigits;\n\n            /* Check if an exponent is going to be written and if precision needs to be adjusted for it */\n            if(!WriteExponent && ((Exponent + 1) > Precision))\n            {\n                /* Adjust the precision */\n                Precision = Exponent + 1;\n            }\n\n            /* Make sure precision is greater than 0 */\n            if(Precision == 0)\n            {\n                /* Adjust the precision */\n                Precision = 1;\n            }\n        }\n    }\n\n    /* Check whether to print a radix */\n    NumberLength = Precision;\n    if(FormatProperties->Flags & PFL_PRINT_RADIX)\n    {\n        /* Include the radix character */\n        NumberLength += 1;\n    }\n    else if(FormatProperties->Flags & PFL_DIGIT_PRECISION)\n    {\n        /* Check if an exponent is going to be written */\n        if(WriteExponent)\n        {\n            /* Make sure precision is greater than 1 */\n            if(Precision > 1)\n            {\n                /* Include radix character */\n                NumberLength += 1;\n            }\n        }\n        else\n        {\n            /* Still check if radix character should be written */\n            if((Exponent < 0) || ((Exponent + 1) - SignificantDigits < 0))\n            {\n                /* Reserve space for radix character */\n                NumberLength += 1;\n            }\n        }\n    }\n    else if(Precision != 0)\n    {\n        /* Include the radix character */\n        NumberLength += 1;\n    }\n\n    /* Check if an exponent is going to be written */\n    if(WriteExponent)\n    {\n        /* Ensure there is enough room for the exponent character, sign and digits */\n        NumberLength += 4;\n\n        /* Check if precision represents the fractional part only */\n        if(!(FormatProperties->Flags & PFL_DIGIT_PRECISION))\n        {\n            /* Add space for one more digit */\n            NumberLength += 1;\n        }\n\n        /* Check if the exponent is negative */\n        if(Exponent < 0)\n        {\n            /* Check if the exponent is less than -100 */\n            if(Exponent <= -100)\n            {\n                /* Add space for one more digit */\n                NumberLength += 1;\n\n                /* Check if the exponent is less than -1000 */\n                if(Exponent <= -1000)\n                {\n                    /* Add space for one more digit */\n                    NumberLength += 1;\n                }\n            }\n        }\n        else\n        {\n            /* Check if the exponent is greater than 100 */\n            if(Exponent >= 100)\n            {\n                /* Add space for one more digit */\n                NumberLength += 1;\n\n                /* Check if the exponent is greater than 1000 */\n                if(Exponent >= 1000)\n                {\n                    /* Add space for one more digit */\n                    NumberLength += 1;\n                }\n            }\n        }\n    }\n    else\n    {\n        if(Exponent >= 0)\n        {\n            /* Not negative */\n            if(!(FormatProperties->Flags & PFL_DIGIT_PRECISION))\n            {\n                /*Adjust number length */\n                NumberLength += Exponent + 1;\n            }\n        }\n        else\n        {\n            /* Negative, add space for additional '0' character*/\n            NumberLength += 1;\n\n            /* Check if precision is number of significant digits */\n            if(FormatProperties->Flags & PFL_DIGIT_PRECISION)\n            {\n                /* Add exponent to the precision */\n                Precision += (-Exponent) - 1;\n                NumberLength += (-Exponent) - 1;\n            }\n        }\n    }\n\n    /* Make a room for sign character if any */\n    if(SignCharacter != 0)\n    {\n        NumberLength += 1;\n    }\n\n    /* Check if field width is bigger than integer */\n    FieldCount = 0;\n    if(NumberLength < FormatProperties->FieldWidth)\n    {\n        /* Add field spacing characters */\n        FieldCount = FormatProperties->FieldWidth - NumberLength;\n    }\n\n    /* Check if prefix will be written */\n    if((FormatProperties->Flags & PFL_LEFT_JUSTIFIED) || (FormatProperties->Flags & PFL_LEADING_ZEROES))\n    {\n        /* Check for a sign character */\n        if(SignCharacter != 0)\n        {\n            /* Write the sign character */\n            Status = WriteWideCharacter(Context, SignCharacter);\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write the character, return status code */\n                return Status;\n            }\n        }\n\n        /* Reset the sign character */\n        SignCharacter = 0;\n    }\n\n    /* Check if leading zero padding is required and if field is left aligned */\n    if(!(FormatProperties->Flags & PFL_LEFT_JUSTIFIED) || (FormatProperties->Flags & PFL_LEADING_ZEROES))\n    {\n        /* Check if leading zero padding is required */\n        if(FormatProperties->Flags & PFL_LEADING_ZEROES)\n        {\n            /* Write leading zeros */\n            Character = L'0';\n        }\n        else\n        {\n            /* Write leading spaces */\n            Character = L' ';\n        }\n\n        /* Fill up with leading characters */\n        for(FieldIndex = 0; FieldIndex < FieldCount; FieldIndex++)\n        {\n            /* Write the leading character */\n            Status = WriteWideCharacter(Context, Character);\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write the character, return status code */\n                return Status;\n            }\n        }\n\n        /* Reset the field count */\n        FieldCount = 0;\n    }\n\n    /* Check if a sign character has already been written */\n    if(SignCharacter != 0)\n    {\n        /* Write the sign character */\n        Status = WriteWideCharacter(Context, SignCharacter);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write the character, return status code */\n            return Status;\n        }\n    }\n\n    /* Check if exponent is to be written */\n    Index = 0;\n    if(WriteExponent)\n    {\n        /* Check if there is anything to write */\n        if(DigitCount == 0)\n        {\n            /* No digits, write '0' */\n            Digit = L'0';\n        }\n        else\n        {\n            /* Write the first digit */\n            Digit = Buffer[Index];\n            Index++;\n        }\n\n        /* Write the digit */\n        Status = WriteWideCharacter(Context, Digit);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write the character, return status code */\n            return Status;\n        }\n\n        /* Check if precision is number of significant digits */\n        if((FormatProperties->Flags & PFL_DIGIT_PRECISION) && (Precision != 0))\n        {\n            /* Adjust the precision */\n            Precision--;\n        }\n\n        /* Check if radix character should be written */\n        if((Precision != 0) || (FormatProperties->Flags & PFL_PRINT_RADIX))\n        {\n            /* Write the radix character */\n            Status = WriteWideCharacter(Context, L'.');\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write the character, return status code */\n                return Status;\n            }\n        }\n\n        /* Write more digits up to the precision limit */\n        for(PrecisionIndex = 0; PrecisionIndex < Precision; PrecisionIndex++)\n        {\n            /* Check if there is anything to write */\n            if(Index < DigitCount)\n            {\n                /* Write the next digit */\n                Digit = Buffer[Index];\n                Index++;\n            }\n            else\n            {\n                /* No more digits, write '0' */\n                Digit = L'0';\n            }\n\n            /* Write the digit */\n            Status = WriteWideCharacter(Context, Digit);\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write the character, return status code */\n                return Status;\n            }\n        }\n\n        /* Check if exponent should be in uppercase */\n        if(FormatProperties->Flags & PFL_UPPERCASE)\n        {\n            /* Use uppercase exponent character */\n            ExponentCharacter = L'E';\n        }\n        else\n        {\n            /* Use lowercase exponent character */\n            ExponentCharacter = L'e';\n        }\n\n        /* Write the exponent string */\n        Status = WriteCustomValue(Context, L\"%C%+0.2d\", ExponentCharacter, Exponent);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write the characters, return status code */\n            return Status;\n        }\n    }\n    else\n    {\n        /* Non scientific format, check if exponent is positive value */\n        if(Exponent >= 0)\n        {\n            /* Write integral part */\n            CurrentExponent = Exponent;\n            while(CurrentExponent >= 0)\n            {\n                /* Check if there is anything to write */\n                if(Index < DigitCount)\n                {\n                    /* Write the next digit */\n                    Digit = Buffer[Index];\n                    Index++;\n                }\n                else\n                {\n                    /* No more digits, write '0' */\n                    Digit = L'0';\n                }\n\n                /* Write the digit */\n                Status = WriteWideCharacter(Context, Digit);\n                if(Status != STATUS_SUCCESS)\n                {\n                    /* Failed to write the character, return status code */\n                    return Status;\n                }\n\n                /* Check if presition is number of significant digits */\n                if((FormatProperties->Flags & PFL_DIGIT_PRECISION) && (Precision != 0))\n                {\n                    /* Adjust the precision */\n                    Precision--;\n                }\n\n                /* Get next exponent character */\n                CurrentExponent--;\n            }\n        }\n        else\n        {\n            /* Exponent is negative, write '0' */\n            Status = WriteWideCharacter(Context, L'0');\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write the character, return status code */\n                return Status;\n            }\n\n            /* Nothing more to do with the exponent */\n            CurrentExponent = -1;\n        }\n\n        /* Check if radix character should be written */\n        if((Precision != 0) || (FormatProperties->Flags & PFL_PRINT_RADIX))\n        {\n            /* Write the radix character */\n            Status = WriteWideCharacter(Context, L'.');\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write the character, return status code */\n                return Status;\n            }\n        }\n\n        /* Write more digits, until precision limit is reached */\n        for(PrecisionIndex = 0; PrecisionIndex < Precision; PrecisionIndex++)\n        {\n            /* Check if there is anything to write */\n            if(CurrentExponent > Exponent)\n            {\n                /* Write the next digit */\n                Digit = L'0';\n            }\n            else if(Index < DigitCount)\n            {\n                /* Write the next digit */\n                Digit = Buffer[Index];\n                Index++;\n            }\n            else\n            {\n                /* Whenever reached this, write '0' character */\n                Digit = L'0';\n            }\n\n            /* Write the digit */\n            Status = WriteWideCharacter(Context, Digit);\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write the character, return status code */\n                return Status;\n            }\n\n            /* Get next exponent character */\n            CurrentExponent--;\n        }\n    }\n\n    /* Iterate through the field characters */\n    for(FieldIndex = 0; FieldIndex < FieldCount; FieldIndex++)\n    {\n        /* Fill the remaining space with spaces */\n        Status = WriteWideCharacter(Context, L' ');\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write the character, return status code */\n            return Status;\n        }\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Writes a wide string double value in the hexadecimal format to the destination provided by the print context.\n *\n * @param Context\n *        Supplies a pointer to the print context structure.\n *\n * @param FormatProperties\n *        Supplies a pointer to the print format properties structure, describing the style characteristics.\n *\n * @param Double\n *        Supplies the double/float value to write as a wide string in a hexadecimal format.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::WideString::WriteHexDoubleValue(IN PRTL_PRINT_CONTEXT Context,\n                                     IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                     IN DOUBLE Double)\n{\n    LONG AbsoluteExponent, Exponent, FieldCount, Index, NumberLength;\n    WCHAR Character, Digit, ExponentCharacter, IntegerValue;\n    LONG Precision, PrecisionIndex, PrefixIndex, PrefixSize;\n    ULONGLONG HalfWay, RoundingValue, Significand;\n    WCHAR Buffer[MAX_DOUBLE_STRING_SIZE];\n    BOOLEAN NegativeValue;\n    LARGE_DOUBLE Parts;\n    WCHAR Prefix[4];\n    XTSTATUS Status;\n\n    /* Initialize variables */\n    NegativeValue = FALSE;\n    Parts.DoublePart = Double;\n    Precision = FormatProperties->Precision;\n\n    /* Check if the value is zero */\n    if(Double == 0.0)\n    {\n        AbsoluteExponent = 0;\n        Exponent = 0;\n        IntegerValue = L'0';\n        Significand = 0;\n\n        /* Check if the precision is specified */\n        if(Precision == -1)\n        {\n            /* Set the precision to 0 */\n            Precision = 0;\n        }\n\n        /* Fill the significand hex digits buffer */\n        for(Index = 0; Index < DOUBLE_HEX_PRECISION; Index++)\n        {\n            /* Fill the buffer with zero */\n            Buffer[Index] = L'0';\n        }\n    }\n    else\n    {\n        /* Value is not zero, check if it is negative */\n        if((Parts.u.HighPart & (DOUBLE_SIGN_BIT >> DOUBLE_HIGH_VALUE_SHIFT)) != 0)\n        {\n            /* Turn the negative value into a positive one */\n            NegativeValue = TRUE;\n            Parts.DoublePart *= -1;\n        }\n\n        /* Calculate exponent */\n        Exponent = (Parts.u.HighPart &\n                   (DOUBLE_EXPONENT_MASK >> DOUBLE_HIGH_VALUE_SHIFT)) >>\n                   (DOUBLE_EXPONENT_SHIFT - DOUBLE_HIGH_VALUE_SHIFT);\n        Exponent -= DOUBLE_EXPONENT_BIAS;\n\n        /* Get absolute exponent and check if it is negative */\n        AbsoluteExponent = Exponent;\n        if(AbsoluteExponent < 0)\n        {\n            /* Turn the absolute exponent into a positive value */\n            AbsoluteExponent *= -1;\n        }\n\n        /* Calculate significand */\n        Significand = Parts.u.LowPart |\n                      ((ULONGLONG)(Parts.u.HighPart & DOUBLE_HIGH_VALUE_MASK) <<\n                      (sizeof(ULONG) * BITS_PER_BYTE));\n\n        /* Check if the precision is specified */\n        IntegerValue = L'1';\n        if(Precision != -1)\n        {\n            /* Calculate the half way point and rounding value */\n            HalfWay = 1ULL << (DOUBLE_EXPONENT_SHIFT - 1);\n            RoundingValue = HalfWay;\n            if((Precision * 4) > (sizeof(ULONGLONG) * BITS_PER_BYTE))\n            {\n                /* Set the rounding value to zero */\n                RoundingValue = 0;\n            }\n            else\n            {\n                /* Calculate the rounding value */\n                RoundingValue = RoundingValue >> (Precision * 4);\n            }\n\n            /* Add the rounding value to the significand */\n            Significand += RoundingValue;\n            if(Significand >= (1ULL << DOUBLE_EXPONENT_SHIFT))\n            {\n                /* Adjust the significand and increment the integer portion */\n                Significand -= (1ULL << DOUBLE_EXPONENT_SHIFT);\n                IntegerValue++;\n            }\n        }\n\n        /* Convert the significand into a hex string value */\n        for(Index = 0; Index < DOUBLE_HEX_PRECISION; Index++)\n        {\n            /* Get the digit value */\n            Digit = (Significand >> (Index * 4)) & 0xF;\n\n            /* Check if the digit is less than 10 (hex A) */\n            if(Digit < 10)\n            {\n                /* Convert the digit value to a character */\n                Character = Digit + L'0';\n            }\n            else if(FormatProperties->Flags & PFL_UPPERCASE)\n            {\n                /* Convert the digit value to an uppercase character */\n                Character = Digit + L'A' - 10;\n            }\n            else\n            {\n                /* Convert the digit value to a lowercase character */\n                Character = Digit + L'a' - 10;\n            }\n\n            /* Put the character in the buffer */\n            Buffer[DOUBLE_HEX_PRECISION - Index - 1] = Character;\n        }\n\n        /* Check if the precision is specified */\n        if(Precision == -1)\n        {\n            /* Set the precision to the number of significant digits */\n            Precision = DOUBLE_HEX_PRECISION;\n\n            /* Find the first non-zero character */\n            while((Precision - 1 >= 0) && (Buffer[Precision - 1] == L'0'))\n            {\n                /* Decrement the precision */\n                Precision--;\n            }\n        }\n    }\n\n    /* Handle the sign character */\n    PrefixSize = 0;\n    if(NegativeValue)\n    {\n        /* Negative value, add the '-' character */\n        Prefix[PrefixSize] = L'-';\n        PrefixSize += 1;\n    }\n    else if(FormatProperties->Flags & PFL_ALWAYS_PRINT_SIGN)\n    {\n        /* Positive value, add the '+' character */\n        Prefix[PrefixSize] = L'+';\n        PrefixSize += 1;\n    }\n    else if(FormatProperties->Flags & PFL_SPACE_FOR_PLUS)\n    {\n        /* Positive value, add the ' ' character */\n        Prefix[PrefixSize] = L' ';\n        PrefixSize += 1;\n    }\n\n    /* Handle the radix characters */\n    Prefix[PrefixSize] = L'0';\n    Prefix[PrefixSize + 1] = L'x';\n    PrefixSize += 2;\n\n    /* Get the initial number length */\n    NumberLength = Precision + 1;\n\n    /* Check if radix is specified */\n    if((FormatProperties->Flags & PFL_PRINT_RADIX) || (Precision != 0))\n    {\n        /* Reserve space for the radix character */\n        NumberLength += 1;\n    }\n\n    /* Check if uppercase characters are required */\n    if(FormatProperties->Flags & PFL_UPPERCASE)\n    {\n        /* Use uppercase 'P' character for the exponent */\n        ExponentCharacter = L'P';\n    }\n    else\n    {\n        /* Use lowercase 'p' character for the exponent */\n        ExponentCharacter = L'p';\n    }\n\n    /* Reserve space for exponent character, sign and digits */\n    NumberLength += 3;\n    if(AbsoluteExponent > 10)\n    {\n        NumberLength += 1;\n        if(AbsoluteExponent > 100)\n        {\n            NumberLength += 1;\n            if(AbsoluteExponent > 1000)\n            {\n                NumberLength += 1;\n            }\n        }\n    }\n\n    /* Check if any field spacing characters are needed */\n    FieldCount = 0;\n    if(NumberLength + PrefixSize < FormatProperties->FieldWidth)\n    {\n        /* Field width is larger than the integer part, calculate the field count */\n        FieldCount = FormatProperties->FieldWidth - (NumberLength + PrefixSize);\n    }\n\n    /* Check for leading zero padding and left alignment */\n    if(!(FormatProperties->Flags & PFL_LEFT_JUSTIFIED) || (FormatProperties->Flags & PFL_LEADING_ZEROES))\n    {\n        /* Check if leading zeros are required */\n        if(FormatProperties->Flags & PFL_LEADING_ZEROES)\n        {\n            /* Write the prefix first */\n            Character = L'0';\n            PrefixIndex = 0;\n            while(PrefixSize--)\n            {\n                /* Write the prefix character */\n                Status = WriteWideCharacter(Context, Prefix[PrefixIndex]);\n                if(Status != STATUS_SUCCESS)\n                {\n                    /* Failed to write character, return error code */\n                    return Status;\n                }\n\n                /* Increment the prefix index */\n                PrefixIndex++;\n            }\n        }\n        else\n        {\n            /* No leading zeros are required */\n            Character = L' ';\n        }\n\n        /* Write the field characters */\n        while(FieldCount)\n        {\n            /* Write the field character */\n            Status = WriteWideCharacter(Context, Character);\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write character, return error code */\n                return Status;\n            }\n\n            /* Decrement the field count number */\n            FieldCount--;\n        }\n    }\n\n    /* Write the prefix characters */\n    for(PrefixIndex = 0; PrefixIndex < PrefixSize; PrefixIndex++)\n    {\n        /* Write the prefix character */\n        Status = WriteWideCharacter(Context, Prefix[PrefixIndex]);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return error code */\n            return Status;\n        }\n    }\n\n    /* Write the integer value */\n    Status = WriteWideCharacter(Context, IntegerValue);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to write character, return error code */\n        return Status;\n    }\n\n    /* Check if radix character is required */\n    if((FormatProperties->Flags & PFL_PRINT_RADIX) || (Precision != 0))\n    {\n        /* Write the radix character */\n        Status = WriteWideCharacter(Context, L'.');\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return error code */\n            return Status;\n        }\n    }\n\n    /* Write the precision characters */\n    for(PrecisionIndex = 0; PrecisionIndex < Precision; PrecisionIndex++)\n    {\n        /* Check if precision index exceeds the number of significant digits */\n        if(PrecisionIndex >= DOUBLE_HEX_PRECISION)\n        {\n            /* Just write a L'0' character */\n            Digit = L'0';\n        }\n        else\n        {\n            /* Write the precision character */\n            Digit = Buffer[PrecisionIndex];\n        }\n\n        /* Write the precision character */\n        Status = WriteWideCharacter(Context, Digit);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return error code */\n            return Status;\n        }\n    }\n\n    /* Write the exponent characters */\n    Status = WriteCustomValue(Context, L\"%C%+d\", ExponentCharacter, Exponent);\n    if(Status != STATUS_SUCCESS)\n    {\n        /* Failed to write character, return error code */\n        return Status;\n    }\n\n    /* Write the field characters if any left */\n    while(FieldCount)\n    {\n        /* Write the field character */\n        Status = WriteWideCharacter(Context, L' ');\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return error code */\n            return Status;\n        }\n\n        /* Decrement the field count number */\n        FieldCount--;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Writes a wide string integer value to the destination provided by the print context.\n *\n * @param Context\n *        Supplies a pointer to the print context structure.\n *\n * @param FormatProperties\n *        Supplies a pointer to the print format properties structure, describing the style characteristics.\n *\n * @param Integer\n *        Supplies the integer value to write as a wide string.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::WideString::WriteIntegerValue(IN PRTL_PRINT_CONTEXT Context,\n                                   IN PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                   IN ULONGLONG Integer)\n{\n    LONG BufferIndex, FieldLength, IntegerLength, PrecisionLength, PrefixIndex, PrefixLength;\n    WCHAR Buffer[MAX_INTEGER_STRING_SIZE];\n    ULONGLONG NextInteger, Remainder;\n    BOOLEAN Negative;\n    WCHAR Prefix[4];\n    WCHAR Character;\n    XTSTATUS Status;\n\n    /* Set default values */\n    IntegerLength = 0;\n    Negative = FALSE;\n\n    /* Check if this is signed integer */\n    if(!(FormatProperties->Flags & PFL_UNSIGNED))\n    {\n        /* Check integer size and extend to signed value */\n        switch(FormatProperties->IntegerSize)\n        {\n            case sizeof(CHAR):\n                Integer = (CHAR)Integer;\n                break;\n            case sizeof(SHORT):\n                Integer = (SHORT)Integer;\n                break;\n            case sizeof(LONG):\n                Integer = (LONG)Integer;\n                break;\n        }\n    }\n\n    /* Check if the integer value is zero */\n    if(Integer == 0)\n    {\n        /* Cannot print radix if integer is zero */\n        FormatProperties->Flags &= ~PFL_PRINT_RADIX;\n    }\n\n    /* Check if any of the integer value or precision is non-zero */\n    if(Integer != 0 || FormatProperties->Precision != 0)\n    {\n        /* Check if the integer is negative */\n        if(!(FormatProperties->Flags & PFL_UNSIGNED) && (LONGLONG)Integer < 0)\n        {\n            /* Mark the integer as negative and turn it positive */\n            Negative = TRUE;\n            Integer *= -1;\n        }\n\n        /* Initialize the buffer */\n        RTL::Memory::ZeroMemory(Buffer, sizeof(Buffer));\n\n        /* Convert the integer into a reversed wide string */\n        do\n        {\n            /* Get the next digit */\n            NextInteger = RTL::Math::DivideUnsigned64(Integer, FormatProperties->Radix, &Remainder);\n\n            /* Convert the digit into a character */\n            Character = (WCHAR)Remainder;\n            if(Character > 9)\n            {\n                /* Check if the character should be upper case */\n                if(FormatProperties->Flags & PFL_UPPERCASE)\n                {\n                    /* Get the uppercase character */\n                    Character = Character - 10 + L'A';\n                }\n                else\n                {\n                    /* Get the lowercase character */\n                    Character = Character - 10 + L'a';\n                }\n            }\n            else\n            {\n                /* Get the numeric character */\n                Character += L'0';\n            }\n\n            /* Store the character in the buffer */\n            Buffer[IntegerLength] = Character;\n            IntegerLength += 1;\n\n            /* Get next signed digit */\n            Integer = NextInteger;\n        }\n        while(Integer > 0);\n\n        /* Reverse the string representation of the integer */\n        ReverseWideString(Buffer, IntegerLength);\n    }\n\n    /* Handle the sign decoration */\n    PrefixLength = 0;\n    if(!(FormatProperties->Flags & PFL_UNSIGNED) && Negative)\n    {\n        /* Signed negative value, write '-' character */\n        Prefix[PrefixLength] = L'-';\n        PrefixLength += 1;\n    }\n    else if(FormatProperties->Flags & PFL_ALWAYS_PRINT_SIGN)\n    {\n        /* Write '+' character for positive value */\n        Prefix[PrefixLength] = L'+';\n        PrefixLength += 1;\n    }\n    else if(FormatProperties->Flags & PFL_SPACE_FOR_PLUS)\n    {\n        /* Write ' ' character for positive value */\n        Prefix[PrefixLength] = L' ';\n        PrefixLength += 1;\n    }\n\n    /* Handle the radix decoration */\n    if(FormatProperties->Flags & PFL_PRINT_RADIX)\n    {\n        if(FormatProperties->Radix == 8)\n        {\n            /* Check if leading zero is required */\n            if(Buffer[0] != L'0')\n            {\n                /* Write '0' character */\n                Prefix[PrefixLength] = L'0';\n                PrefixLength += 1;\n            }\n        }\n        else if(FormatProperties->Radix == 16)\n        {\n            /* Write '0x' characters */\n            Prefix[PrefixLength] = L'0';\n            PrefixLength += 1;\n\n            /* Write lowercase 'x' character */\n            Prefix[PrefixLength] = L'x';\n\n            PrefixLength += 1;\n        }\n    }\n\n    /* Calculate the precision */\n    PrecisionLength = 0;\n    if(IntegerLength < FormatProperties->Precision)\n    {\n        PrecisionLength = FormatProperties->Precision - IntegerLength;\n    }\n\n    /* Calculate the field length */\n    FieldLength = 0;\n    if(IntegerLength + PrefixLength + PrecisionLength < FormatProperties->FieldWidth)\n    {\n        FieldLength = FormatProperties->FieldWidth - (IntegerLength + PrefixLength + PrecisionLength);\n    }\n\n    /* Check if leading zero padding is required and if field is left aligned */\n    if(!(FormatProperties->Flags & PFL_LEFT_JUSTIFIED) || (FormatProperties->Flags & PFL_LEADING_ZEROES))\n    {\n        Character = L' ';\n        if(FormatProperties->Flags & PFL_LEADING_ZEROES)\n        {\n            /* Write leading zero padding characters */\n            Character = L'0';\n            for(PrefixIndex = 0; PrefixIndex < PrefixLength; PrefixIndex++)\n            {\n                Status = WriteWideCharacter(Context, Prefix[PrefixIndex]);\n                if(Status != STATUS_SUCCESS)\n                {\n                    /* Failed to write character, return status code */\n                    return Status;\n                }\n            }\n\n            /* Clear prefix */\n            PrefixLength = 0;\n        }\n\n        /* Write additional field width characters */\n        while(FieldLength > 0)\n        {\n            Status = WriteWideCharacter(Context, Character);\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write character, return status code */\n                return Status;\n            }\n\n            /* Decrement field length */\n            FieldLength--;\n        }\n    }\n\n    /* Write the prefix characters */\n    for(PrefixIndex = 0; PrefixIndex < PrefixLength; PrefixIndex++)\n    {\n        Status = WriteWideCharacter(Context, Prefix[PrefixIndex]);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return status code */\n            return Status;\n        }\n    }\n\n    /* Fill the precision characters with '0' */\n    while(PrecisionLength > 0)\n    {\n        Status = WriteWideCharacter(Context, L'0');\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return status code */\n            return Status;\n        }\n\n        /* Decrement precision length */\n        PrecisionLength--;\n    }\n\n    /* Write the actual integer value */\n    for(BufferIndex = 0; BufferIndex < IntegerLength; BufferIndex++)\n    {\n        Status = WriteWideCharacter(Context, Buffer[BufferIndex]);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return status code */\n            return Status;\n        }\n    }\n\n    /* Write additional field width with ' ' characters */\n    while(FieldLength > 0)\n    {\n        Status = WriteWideCharacter(Context, L' ');\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return status code */\n            return Status;\n        }\n\n        /* Decrement field length */\n        FieldLength--;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Writes a string value to the destination provided by the print context.\n *\n * @param Context\n *        Supplies a pointer to the print context structure.\n *\n * @param FormatProperties\n *        Supplies a pointer to the print format properties structure, describing the style characteristics.\n *\n * @param String\n *        Supplies the string value to write as a wide string.\n *\n * @param Character\n *        Specifies whether the string value is expected to be a single character or not.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::WideString::WriteStringValue(PRTL_PRINT_CONTEXT Context,\n                                  PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                                  PCSTR String,\n                                  SIZE_T StringLength)\n{\n    WCHAR WideCharacter[2];\n    ULONG PaddingLength;\n    XTSTATUS Status;\n\n    /* Check for NULL string */\n    if(String == NULLPTR)\n    {\n        /* Print '(null)' instead */\n        String = \"(null)\";\n        StringLength = 6;\n    }\n\n    /* Check if string length exceeds precision limit */\n    if((FormatProperties->Precision >= 0) && (StringLength > FormatProperties->Precision))\n    {\n        /* Limit string length to precision number */\n        StringLength = FormatProperties->Precision;\n    }\n\n    /* Calculate padding */\n    PaddingLength = 0;\n    if(FormatProperties->FieldWidth > StringLength)\n    {\n        PaddingLength = FormatProperties->FieldWidth - StringLength;\n    }\n\n    /* Check is left side padding is required */\n    if(!(FormatProperties->Flags & PFL_LEFT_JUSTIFIED))\n    {\n        /* Pad left */\n        while(PaddingLength > 0)\n        {\n            /* Write space */\n            Status = WriteWideCharacter(Context, L' ');\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write character, return status code */\n                return Status;\n            }\n\n            /* Decrement padding length */\n            PaddingLength--;\n        }\n    }\n\n    /* Write string character by character */\n    while(StringLength)\n    {\n        /* Prepare wide character to write */\n        WideCharacter[0] = *String;\n        WideCharacter[1] = 0;\n\n        /* Write wide character */\n        Status = WriteWideCharacter(Context, *WideCharacter);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return status code */\n            return Status;\n        }\n\n        /* Get next character */\n        StringLength--;\n        String++;\n    }\n\n    /* Pad right, if required */\n    while(PaddingLength > 0)\n    {\n        /* Write space */\n        Status = WriteWideCharacter(Context, L' ');\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return status code */\n            return Status;\n        }\n\n        /* Decrement padding length */\n        PaddingLength--;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n\n/**\n * Writes a wide string value to the destination provided by the print context.\n *\n * @param Context\n *        Supplies a pointer to the print context structure.\n *\n * @param FormatProperties\n *        Supplies a pointer to the print format properties structure, describing the style characteristics.\n *\n * @param String\n *        Supplies the wide string value to write.\n *\n * @param Character\n *        Specifies whether the string value is expected to be a single character or not.\n *\n * @return This routine returns a status code.\n *\n * @since XT 1.0\n */\nXTAPI\nXTSTATUS\nRTL::WideString::WriteValue(PRTL_PRINT_CONTEXT Context,\n                            PRTL_PRINT_FORMAT_PROPERTIES FormatProperties,\n                            PCWSTR String,\n                            SIZE_T StringLength)\n{\n    ULONG PaddingLength;\n    XTSTATUS Status;\n\n    /* Check for NULL string */\n    if(String == NULLPTR)\n    {\n        /* Print '(null)' instead */\n        String = L\"(null)\";\n        StringLength = 6;\n    }\n\n    /* Check if string length exceeds precision limit */\n    if((FormatProperties->Precision >= 0) && (StringLength > FormatProperties->Precision))\n    {\n        /* Limit string length to precision number */\n        StringLength = FormatProperties->Precision;\n    }\n\n    /* Calculate padding */\n    PaddingLength = 0;\n    if(FormatProperties->FieldWidth > StringLength)\n    {\n        PaddingLength = FormatProperties->FieldWidth - StringLength;\n    }\n\n\n    /* Check is left side padding is required */\n    if(!(FormatProperties->Flags & PFL_LEFT_JUSTIFIED))\n    {\n        /* Pad left */\n        while(PaddingLength > 0)\n        {\n            /* Write space */\n            Status = WriteWideCharacter(Context, L' ');\n            if(Status != STATUS_SUCCESS)\n            {\n                /* Failed to write character, return status code */\n                return Status;\n            }\n\n            /* Decrement padding length */\n            PaddingLength--;\n        }\n    }\n\n    /* Write string character by character */\n    while(StringLength != 0)\n    {\n        /* Write wide character */\n        Status = WriteWideCharacter(Context, *String);\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return status code */\n            return Status;\n        }\n\n        /* Get next character */\n        StringLength--;\n        String++;\n    }\n\n    /* Pad right, if required */\n    while(PaddingLength > 0)\n    {\n        /* Write space */\n        Status = WriteWideCharacter(Context, L' ');\n        if(Status != STATUS_SUCCESS)\n        {\n            /* Failed to write character, return status code */\n            return Status;\n        }\n\n        /* Decrement padding length */\n        PaddingLength--;\n    }\n\n    /* Return success */\n    return STATUS_SUCCESS;\n}\n"
  },
  {
    "path": "xtoskrnl/xtoskrnl.spec",
    "content": "# XTOS kernel exports\n@ cdecl DbgPrint(wstr)\n@ fastcall ExAcquireRundownProtection(ptr)\n@ fastcall ExCompleteRundownProtection(ptr)\n@ fastcall ExInitializeRundownProtection(ptr)\n@ fastcall ExReInitializeRundownProtection(ptr)\n@ fastcall ExReleaseRundownProtection(ptr)\n@ fastcall ExWaitForRundownProtectionRelease(ptr)\n@ stdcall HlQueryPerformanceCounter(ptr)\n@ cdecl HlReadPort8(ptr)\n@ cdecl HlReadPort16(ptr)\n@ cdecl HlReadPort32(ptr)\n@ stdcall HlReadRegister8(ptr)\n@ stdcall HlReadRegister16(ptr)\n@ stdcall HlReadRegister32(ptr)\n@ stdcall HlSetClockRate(long)\n@ cdecl HlWritePort8(ptr long)\n@ cdecl HlWritePort16(ptr long)\n@ cdecl HlWritePort32(ptr long)\n@ stdcall HlWriteRegister8(ptr long)\n@ stdcall HlWriteRegister16(ptr long)\n@ stdcall HlWriteRegister32(ptr long)\n@ fastcall KeAcquireQueuedSpinLock(long)\n@ fastcall KeAcquireSpinLock(ptr)\n@ stdcall KeAcquireSystemResource(long ptr)\n@ stdcall KeCancelTimer(ptr)\n@ fastcall KeGetCurrentRunLevel()\n@ stdcall KeGetTimerState(ptr)\n@ stdcall KeGetSystemResource(long ptr)\n@ stdcall KeInitializeApc(ptr ptr long ptr ptr ptr long ptr)\n@ stdcall KeInitializeDpc(ptr ptr ptr)\n@ stdcall KeInitializeSemaphore(ptr long long)\n@ stdcall KeInitializeSpinLock(ptr)\n@ stdcall KeInitializeThreadedDpc(ptr ptr ptr)\n@ stdcall KeInitializeTimer(ptr long)\n@ fastcall KeLowerRunLevel(long)\n@ fastcall KeRaiseRunLevel(long)\n@ stdcall KeReadSemaphoreState(ptr)\n@ stdcall KeReleaseSemaphore(ptr long long long)\n@ fastcall KeReleaseQueuedSpinLock(long)\n@ fastcall KeReleaseSpinLock(ptr)\n@ stdcall KeReleaseSystemResource(ptr)\n@ stdcall KeSetTargetProcessorDpc(ptr long)\n@ stdcall KeSetTimeIncrement(long long)\n@ stdcall KeSetTimer(ptr long long long ptr)\n@ stdcall KeSignalCallDpcDone(ptr)\n@ stdcall KeSignalCallDpcSynchronize(ptr)\n@ stdcall MmAllocatePool(long long ptr)\n@ stdcall MmAllocatePoolWithTag(long long ptr long)\n@ stdcall MmFreePool(ptr)\n@ stdcall MmFreePoolWithTag(ptr long)\n@ stdcall RtlClearAllBits(ptr)\n@ stdcall RtlClearBit(ptr long)\n@ stdcall RtlClearBits(ptr long long)\n@ stdcall RtlClearSetBits(ptr long long)\n@ stdcall RtlCompareGuids(ptr ptr)\n@ stdcall RtlCompareMemory(ptr ptr long)\n@ stdcall RtlCompareString(str str long)\n@ stdcall RtlCompareStringInsensitive(str str long)\n@ stdcall RtlCompareWideString(wstr wstr long)\n@ stdcall RtlCompareWideStringInsensitive(wstr wstr long)\n@ stdcall RtlConcatenateString(str str long)\n@ stdcall RtlConcatenateWideString(wstr wstr long)\n@ stdcall RtlConvertToLargeInteger32(long)\n@ stdcall RtlConvertToLargeIntegerUnsigned32(long)\n@ stdcall RtlCopyMemory(ptr ptr long)\n@ stdcall RtlCopyString(ptr ptr long)\n@ stdcall RtlCopyWideString(ptr ptr long)\n@ stdcall RtlDivideLargeInteger(long long long ptr)\n@ stdcall RtlFindClearBits(ptr long long)\n@ stdcall RtlFindSetBits(ptr long long)\n@ stdcall RtlFindString(str str)\n@ stdcall RtlFindStringInsensitive(str str)\n@ stdcall RtlFindWideString(wstr wstr)\n@ stdcall RtlFindWideStringInsensitive(wstr wstr)\n@ stdcall RtlInitializeBitMap(ptr ptr long)\n@ stdcall RtlInitializeListHead(ptr)\n@ stdcall RtlInsertHeadList(ptr ptr)\n@ stdcall RtlInsertTailList(ptr ptr)\n@ stdcall RtlListEmpty(ptr)\n@ stdcall RtlListLoop(ptr)\n@ stdcall RtlMoveMemory(ptr ptr long)\n@ stdcall RtlMultiplyLargeInteger(long long long)\n@ stdcall RtlRemoveEntryList(ptr)\n@ stdcall RtlReverseString(str long)\n@ stdcall RtlReverseWideString(wstr long)\n@ stdcall RtlSameMemory(ptr ptr long)\n@ stdcall RtlSetAllBits(ptr)\n@ stdcall RtlSetBit(ptr long)\n@ stdcall RtlSetBits(ptr long long)\n@ stdcall RtlSetClearBits(ptr long long)\n@ stdcall RtlSetMemory(ptr long long)\n@ stdcall RtlStringLength(str long)\n@ stdcall RtlStringToWideString(wstr str long)\n@ stdcall RtlTestBit(ptr long)\n@ stdcall RtlTimeFieldsToUnixEpoch(ptr ptr)\n@ stdcall RtlTimeFieldsToXtEpoch(ptr ptr)\n@ stdcall RtlTokenizeString(str str str)\n@ stdcall RtlTokenizeWideString(wstr wstr wstr)\n@ stdcall RtlToLowerCharacter(long)\n@ stdcall RtlToLowerWideCharacter(long)\n@ stdcall RtlToUpperCharacter(long)\n@ stdcall RtlToUpperWideCharacter(long)\n@ stdcall RtlTrimLeftString(str)\n@ stdcall RtlTrimLeftWideString(wstr)\n@ stdcall RtlTrimRightString(str)\n@ stdcall RtlTrimRightWideString(wstr)\n@ stdcall RtlTrimString(str)\n@ stdcall RtlTrimWideString(wstr)\n@ stdcall RtlWideStringLength(wstr long)\n@ stdcall RtlZeroMemory(ptr long)\n"
  }
]