Deprecate obsolete repository

Change-Id: I232458fe31f25388f36a52448f7dd3665cca7976
Reviewed-on: https://fuchsia-review.googlesource.com/c/zircon/+/418718
Reviewed-by: Mahesh Saripalli <maheshsr@google.com>
Reviewed-by: Travis Geiselbrecht <travisg@google.com>
API-Review: Dale Sather <dalesat@google.com>
diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index e53befc..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,16 +0,0 @@
-Language: Cpp
-ColumnLimit: 0
-UseTab: Never
-IndentWidth: 4
-IndentCaseLabels: false
-AlignAfterOpenBracket: Align
-SpacesBeforeTrailingComments: 1
-BreakBeforeBraces: Attach
-AccessModifierOffset: -4
-DerivePointerAlignment: false
-PointerAlignment: Left
-AllowShortFunctionsOnASingleLine: Inline
-AllowShortIfStatementsOnASingleLine: false
-KeepEmptyLinesAtTheStartOfBlocks: true
-AlignEscapedNewlinesLeft: false
-ForEachMacros: ['list_for_every_entry','list_for_every_entry_safe']
diff --git a/.clang-tidy b/.clang-tidy
deleted file mode 100644
index 1933052..0000000
--- a/.clang-tidy
+++ /dev/null
@@ -1,28 +0,0 @@
-
-Checks:          '-*,fuchsia-*'
-HeaderFilterRegex: '.*'
-CheckOptions:
-  - key:             google-readability-braces-around-statements.ShortStatementLines
-    value:           '2'
-  - key:             google-readability-function-size.StatementThreshold
-    value:           '800'
-  - key:             google-readability-namespace-comments.ShortNamespaceLines
-    value:           '10'
-  - key:             google-readability-namespace-comments.SpacesBeforeComments
-    value:           '2'
-  - key:             modernize-loop-convert.MaxCopySize
-    value:           '16'
-  - key:             modernize-loop-convert.MinConfidence
-    value:           reasonable
-  - key:             modernize-loop-convert.NamingStyle
-    value:           CamelCase
-  - key:             modernize-pass-by-value.IncludeStyle
-    value:           llvm
-  - key:             modernize-replace-auto-ptr.IncludeStyle
-    value:           llvm
-  - key:             modernize-use-default-member-init.UseAssignment
-    value:           '1'
-  - key:             modernize-use-nullptr.NullMacros
-    value:           'NULL'
-  - key:             readability-braces-around-statements.ShortStatementLines
-    value:           '2'
diff --git a/.dir-locals.el b/.dir-locals.el
deleted file mode 100644
index 66c2eaf..0000000
--- a/.dir-locals.el
+++ /dev/null
@@ -1,9 +0,0 @@
-;; Emacs settings.
-;; Copyright (C) 2016 Google, Inc.
-
-(
- (c-mode . ((c-file-style . "stroustrup")
-	    (indent-tabs-mode . nil)))
- (c++-mode . ((c-file-style . "stroustrup")
-	      (indent-tabs-mode . nil)))
-)
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index ad6780d..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,39 +0,0 @@
-.DS_Store
-build-*/
-*.swp
-*.swo
-*~
-tags
-TAGS
-local.mk
-*.orig
-cscope.*
-doit
-t
-blk.bin
-*.dSYM
-scripts/toolpaths.local
-compile_commands.json
-.vscode
-*_BACKUP_*
-*_REMOTE_*
-*_LOCAL_*
-*_BASE_*
-*.sublime-*
-json_generator_tests_*.txt
-/benchmarks/
-/infra/.recipe_deps
-/out*
-/prebuilt/downloads/
-/prebuilt/config.mk
-/prebuilt/config.mk.bak
-/AnalysisResult/
-/public/banjo/
-/public/config/
-/public/fidl/
-/public/lib/
-/public/sysroot/
-/public/tool/
-.idea/
-CMakeLists.txt
-cmake-build-debug/
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index c2a4eac..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,8 +0,0 @@
-# This is the list of Fuchsia Authors.
-
-# Names should be added to this file as one of
-#     Organization's name
-#     Individual's name <submission email address>
-#     Individual's name <submission email address> <email2> <emailN>
-
-Google Inc.
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 3e8057e..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,16 +0,0 @@
-The Zircon Kernel (kernel/...) and the Zircon Scripts (scripts/...)
-are under an MIT-style license, copies of which may be found in
-kernel/LICENSE and scripts/LICENSE.
-
-The Third Party Components (third_party/...) are under various
-licenses (of the BSD, MIT, or Zlib style), which may be found in the
-root directory of each component, respectively.
-
-All other components and materials, including the Zircon System
-(system/...) and Bootloader (bootloader/...), are under a BSD-style
-license, copies of which may be found in system/LICENSE and
-bootloader/LICENSE.
-
-The PATENTS file, which may be found in the same directories as the
-LICENSE files, provides additional license rights and conditions
-relating to patents.
diff --git a/MAINTAINERS b/MAINTAINERS
deleted file mode 100644
index 2928b48..0000000
--- a/MAINTAINERS
+++ /dev/null
@@ -1,5 +0,0 @@
-cpu@google.com
-swetland@google.com
-teisenbe@google.com
-travisg@google.com
-voydanoff@google.com
diff --git a/PATENTS b/PATENTS
deleted file mode 100644
index 2746e78..0000000
--- a/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Fuchsia project.
-
-Google hereby grants to you a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this
-section) patent license to make, have made, use, offer to sell, sell,
-import, transfer, and otherwise run, modify and propagate the contents
-of this implementation of Fuchsia, where such license applies only to
-those patent claims, both currently owned by Google and acquired in
-the future, licensable by Google that are necessarily infringed by
-this implementation. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute
-or order or agree to the institution of patent litigation or any other
-patent enforcement activity against any entity (including a
-cross-claim or counterclaim in a lawsuit) alleging that this
-implementation of Fuchsia constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of
-Fuchsia shall terminate as of the date such litigation is filed.
diff --git a/README.md b/README.md
index 643ae34..05218ef 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,5 @@
-# Zircon
+# Obsolete
 
-Zircon is the core platform that powers the Fuchsia OS.  Zircon is
-composed of a microkernel (source in kernel/...) as well as a small
-set of userspace services, drivers, and libraries (source in system/...)
-necessary for the system to boot, talk to hardware, load userspace
-processes and run them, etc.  Fuchsia builds a much larger OS on top
-of this foundation.
+This repository has moved into Fuchsia's main repository:
+https://fuchsia.googlesource.com/fuchsia/+/master/zircon
 
-The canonical Zircon Git repository is located
-at: https://fuchsia.googlesource.com/zircon
-
-The Zircon Kernel provides syscalls to manage processes, threads,
-virtual memory, inter-process communication, waiting on object state
-changes, and locking (via futexes).
-
-Currently there are some temporary syscalls that have been used for early
-bringup work, which will be going away in the future as the long term
-syscall API/ABI surface is finalized.  The expectation is that there will
-be about 100 syscalls.
-
-Zircon syscalls are generally non-blocking.  The wait_one, wait_many
-port_wait and thread sleep being the notable exceptions.
-
-This page is a non-comprehensive index of the zircon documentation.
-
-+ [Getting Started](docs/getting_started.md)
-+ [Contributing Patches](docs/contributing.md)
-
-+ [Concepts Overview](docs/concepts.md)
-+ [Kernel Objects](docs/objects.md)
-+ [Kernel Scheduling](docs/kernel_scheduling.md)
-+ [Process Objects](docs/objects/process.md)
-+ [Thread Objects](docs/objects/thread.md)
-+ [Handles](docs/handles.md)
-+ [System Calls](docs/syscalls.md)
-
-+ [Driver Development Kit](docs/ddk/overview.md)
-
-+ [Testing](docs/testing.md)
-+ [Hacking notes](docs/hacking.md)
-+ [Memory usage analysis tools](docs/memory.md)
-+ [Relationship with LK](docs/zx_and_lk.md)
-+ [Micro-benchmarks](docs/benchmarks/microbenchmarks.md)
diff --git a/bootloader/LICENSE b/bootloader/LICENSE
deleted file mode 100644
index 294047c..0000000
--- a/bootloader/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright 2017 The Fuchsia Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-     copyright notice, this list of conditions and the following
-     disclaimer in the documentation and/or other materials provided
-     with the distribution.
-   * Neither the name of Google Inc. nor the names of its
-     contributors may be used to endorse or promote products derived
-     from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/bootloader/MAINTAINERS b/bootloader/MAINTAINERS
deleted file mode 100644
index cf3c3cd..0000000
--- a/bootloader/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-swetland@google.com
-tkilbourn@google.com
diff --git a/bootloader/NOTES.txt b/bootloader/NOTES.txt
deleted file mode 100644
index 9155e5f..0000000
--- a/bootloader/NOTES.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-Intel Visual BIOS (on NUC) and netboot
---------------------------------------
-This will netboot EFI apps, provided you have a DHCP server which is
-setup to give the BIOS the IP of a tftp server and a filename to grab
-from there.
-
-You must disable legacy boot for the EFI netboot option to appear.  If
-you check the "keep retrying forever" option, when your app exits, the
-BIOS will try to download it from the tftp server again, making for a
-quick build/download/test cycle
-
-
-Making tftpd work on Ubuntu with IPv4
--------------------------------------
-sudo apt-get install tftpd-hpa
-
-Optionally make it easy to copy files to the server without sudo:
-sudo chown `who` /var/lib/tftpdboot 
-
-Edit /etc/default/tftpd-hpa so it looks more like:
-TFTP_USERNAME="tftp"
-TFTP_DIRECTORY="/var/lib/tftpboot"
-TFTP_ADDRESS=":69"
-TFTP_OPTIONS="--secure -4 -v -v -v"
-
-Removing the [::] and adding the -4 make it work reliably on IPv4 for me.
-The several -v's make it chattier in syslog which is handy if you're not
-sure the test machine is actually trying to grab files.
-
-QEMU Tips
--------------------------------------
-USB-ETH Adapters:
-- For ASIX chipset usb adapters if you have permission issues copy the udev rules in scripts/ to /etc/udev/rules.d/
-
-E1000 local networking bridge:
-- You can create a network interface using the Linux tun/tap network device named “qemu” for the
-  qemu-e1000 target. Qemu does not need to be run with any special privileges for this, but you need
-  to create a persistent tun/tap device ahead of time (which does require you be root):
-
-  sudo apt-get install uml-utilities
-  sudo tunctl -u $USER -t qemu
-  sudo ifconfig qemu up
diff --git a/bootloader/README.txt b/bootloader/README.txt
deleted file mode 100644
index a922149..0000000
--- a/bootloader/README.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-What is This?
--------------
-
-This project contains some experiments in software that runs on UEFI
-firmware for the purpose of exploring UEFI development and bootloader
-development.
-
-Since UEFI images are in PE32+ file format, we require that our binaries be
-position independent executables with no relocations. For the most part this
-does not require any extra effort on x86-64, but it does mean that you cannot
-statically initialize any variables that hold an address. (These addresses may
-be assigned at runtime however.)
-
-
-External Dependencies
----------------------
-
-qemu-system-x86_64 is needed to test in emulation
-gnu parted and mtools are needed to generate the disk.img for Qemu
-
-
-Useful Resources & Documentation
---------------------------------
-
-ACPI & UEFI Specifications
-http://www.uefi.org/specifications
-
-Intel 64 and IA-32 Architecture Manuals
-http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
-
-Tianocore UEFI Open Source Community
-(Source for OVMF, EDK II Dev Environment, etc)
-http://www.tianocore.org/
-https://github.com/tianocore
-
diff --git a/bootloader/build.mk b/bootloader/build.mk
deleted file mode 100644
index ac7a7ce..0000000
--- a/bootloader/build.mk
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-EFI_LIBDIRS := system/ulib/tftp
-
-EFI_CFLAGS += -I$(LOCAL_DIR)/include -I$(LOCAL_DIR)/src
-EFI_CFLAGS += -Isystem/public -Isystem/private
-EFI_CFLAGS += $(foreach LIBDIR,$(EFI_LIBDIRS),-I$(LIBDIR)/include)
-
-ifeq ($(call TOBOOL,$(USE_CLANG)),true)
-EFI_LDFLAGS := /subsystem:efi_application /entry:efi_main /libpath:out
-else
-EFI_LINKSCRIPT := $(LOCAL_DIR)/build/efi-x86-64.lds
-EFI_LDFLAGS := -nostdlib -T $(EFI_LINKSCRIPT) -pie -Lout
-endif
-
-EFI_SECTIONS := .text .data .reloc
-EFI_SECTIONS := $(patsubst %,-j %,$(EFI_SECTIONS))
-
-ifeq ($(EFI_ARCH),x86_64)
-EFI_SO          := $(BUILDDIR)/bootloader/bootx64.so
-EFI_BOOTLOADER  := $(BUILDDIR)/bootloader/bootx64.efi
-else ifeq ($(EFI_ARCH),aarch64)
-EFI_SO          := $(BUILDDIR)/bootloader/bootaa64.so
-EFI_BOOTLOADER  := $(BUILDDIR)/bootloader/bootaa64.efi
-endif
-
-# Bootloader sources
-EFI_SOURCES := \
-    $(LOCAL_DIR)/src/osboot.c \
-    $(LOCAL_DIR)/src/diskio.c \
-    $(LOCAL_DIR)/src/cmdline.c \
-    $(LOCAL_DIR)/src/zircon.c \
-    $(LOCAL_DIR)/src/misc.c \
-    $(LOCAL_DIR)/src/netboot.c \
-    $(LOCAL_DIR)/src/netifc.c \
-    $(LOCAL_DIR)/src/inet6.c \
-    $(LOCAL_DIR)/src/pci.c \
-    $(LOCAL_DIR)/src/framebuffer.c \
-    $(LOCAL_DIR)/src/device_id.c \
-
-# libxefi sources
-EFI_SOURCES += \
-    $(LOCAL_DIR)/lib/efi/guids.c \
-    $(LOCAL_DIR)/lib/xefi.c \
-    $(LOCAL_DIR)/lib/loadfile.c \
-    $(LOCAL_DIR)/lib/console-printf.c \
-    $(LOCAL_DIR)/lib/ctype.c \
-    $(LOCAL_DIR)/lib/printf.c \
-    $(LOCAL_DIR)/lib/stdlib.c \
-    $(LOCAL_DIR)/lib/string.c \
-    $(LOCAL_DIR)/lib/strings.c \
-    $(LOCAL_DIR)/lib/inet.c \
-
-EFI_OBJS := $(patsubst $(LOCAL_DIR)/%.c,$(BUILDDIR)/bootloader/%.o,$(EFI_SOURCES))
-EFI_DEPS := $(patsubst %.o,%.d,$(EFI_OBJS))
-EFI_LIBS := $(foreach LIBDIR,$(EFI_LIBDIRS), \
-                 $(BUILDDIR)/EFI_libs/lib$(notdir $(LIBDIR)).a)
-
-$(BUILDDIR)/bootloader/%.o : $(LOCAL_DIR)/%.c
-	@$(MKDIR)
-	$(call BUILDECHO,compiling $<)
-	$(NOECHO)$(EFI_CC) -MMD -MP -o $@ -c $(EFI_OPTFLAGS) $(EFI_COMPILEFLAGS) $(EFI_CFLAGS) $<
-
-ifeq ($(call TOBOOL,$(USE_CLANG)),true)
-
-$(EFI_BOOTLOADER): $(EFI_OBJS) $(EFI_LIBS)
-	@$(MKDIR)
-	$(call BUILDECHO,linking $@)
-	$(NOECHO)$(EFI_LD) /out:$@ $(EFI_LDFLAGS) $^
-
-else
-
-$(EFI_SO): $(EFI_OBJS) $(EFI_LIBS)
-	@$(MKDIR)
-	$(call BUILDECHO,linking $@)
-	$(NOECHO)$(EFI_LD) -o $@ $(EFI_LDFLAGS) $^
-	$(NOECHO)if ! $(READELF) -r $@ | grep -q 'no relocations'; then \
-	    echo "error: $@ has relocations"; \
-	    $(READELF) -r $@; \
-	    rm $@; \
-	    exit 1;\
-	fi
-
-# TODO: update this to build other ARCHes
-$(EFI_BOOTLOADER): $(EFI_SO)
-	@$(MKDIR)
-	$(call BUILDECHO,building $@)
-	$(NOECHO)$(OBJCOPY) --target=pei-x86-64 --subsystem 10 $(EFI_SECTIONS) $< $@
-	$(NOECHO)if [ "`$(NM) $< | grep ' U '`" != "" ]; then echo "error: $<: undefined symbols"; $(NM) $< | grep ' U '; rm $<; exit 1; fi
-
-endif
-
-GENERATED += $(EFI_BOOTLOADER)
-
-.PHONY: gigaboot
-gigaboot: $(EFI_BOOTLOADER)
-
-ifeq ($(call TOBOOL,$(ENABLE_ULIB_ONLY)),false)
-# x86 only by default for now
-ifeq ($(ARCH),x86)
-bootloader: gigaboot
-all:: bootloader
-endif
-endif
-
--include $(EFI_DEPS)
diff --git a/bootloader/build/efi-x86-64.lds b/bootloader/build/efi-x86-64.lds
deleted file mode 100644
index 7d25bb2..0000000
--- a/bootloader/build/efi-x86-64.lds
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Copyright 2016 The Fuchsia Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
-OUTPUT_ARCH(i386:x86-64)
-ENTRY(efi_main)
-SECTIONS
-{
-    . = 0x2000;
-    . = ALIGN(4096);
-    .text :
-    {
-       *(.text)
-       *(.text.*)
-       . = ALIGN(16);
-    }
-
-    . = ALIGN(4096);
-    .data :
-    {
-        *(.rodata*)
-        *(.got.plt)
-        *(.got)
-        *(.data*)
-        *(.sdata)
-        /* TODO: figure out how to move .bss in such a way that the PE32+ loader
-         * doesn't complain.
-         */
-        *(.sbss)
-        *(.scommon)
-        *(.dynbss)
-        *(.bss)
-        *(COMMON)
-        *(.rel.local)
-    }
-
-    . = ALIGN(4096);
-
-    /* A .reloc section is required to flag the final PE32+ file as relocatable.
-     * Here we hardcode one block with one entry to keep the PE32+ loader happy.
-     */
-    _a = .;
-    . = ALIGN(4096);
-    .reloc :
-    {
-        LONG(. - _a);
-        LONG(10);
-        SHORT(0);
-    }
-}
diff --git a/bootloader/build/mkdiskimg.sh b/bootloader/build/mkdiskimg.sh
deleted file mode 100755
index 8c7145c..0000000
--- a/bootloader/build/mkdiskimg.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash -e
-
-# Copyright 2016 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-if [ -z "$1" ]; then
-	echo usage: $0 "<diskimg>"
-	exit 1
-fi
-
-if [[ ! -f $1 ]]; then
-	echo creating: $1
-	dd if=/dev/zero of="$1" bs=512 count=93750
-
-	parted "$1" -s -a minimal mklabel gpt
-	parted "$1" -s -a minimal mkpart EFI FAT16 2048s 93716s
-	parted "$1" -s -a minimal toggle 1 boot
-
-	mformat -i "$1"@@1024K -h 32 -t 32 -n 64 -c 1
-    mmd -i "$1"@@1024K ::EFI
-    mmd -i "$1"@@1024K ::EFI/BOOT
-fi
-
diff --git a/bootloader/include/arpa/inet.h b/bootloader/include/arpa/inet.h
deleted file mode 100644
index e060889..0000000
--- a/bootloader/include/arpa/inet.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stdint.h>
-
-uint16_t htons(uint16_t val);
-uint16_t ntohs(uint16_t val);
-uint32_t htonl(uint32_t val);
-uint32_t ntohl(uint32_t val);
diff --git a/bootloader/include/assert.h b/bootloader/include/assert.h
deleted file mode 100644
index 9e00561..0000000
--- a/bootloader/include/assert.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#define static_assert(e, msg) _Static_assert(e, msg)
-
diff --git a/bootloader/include/ctype.h b/bootloader/include/ctype.h
deleted file mode 100644
index 7772ce5..0000000
--- a/bootloader/include/ctype.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-int isdigit(int c);
-int isspace(int c);
-int tolower(int c);
diff --git a/bootloader/include/inttypes.h b/bootloader/include/inttypes.h
deleted file mode 100644
index 36ae92d..0000000
--- a/bootloader/include/inttypes.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stdint.h>
-
-#define PRId8 "d"
-#define PRId16 "d"
-#define PRId32 "d"
-
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-
-#define PRIx8 "x"
-#define PRIx16 "x"
-#define PRIx32 "x"
-
-#ifdef __clang__
-#define PRIx64 "llx"
-#else
-#define PRIx64 "lx"
-#endif
diff --git a/bootloader/include/printf.h b/bootloader/include/printf.h
deleted file mode 100644
index 721ccde..0000000
--- a/bootloader/include/printf.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2008 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#ifndef __LIB_PRINTF_H
-#define __LIB_PRINTF_H
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <uchar.h>
-
-#include <zircon/compiler.h>
-
-__BEGIN_CDECLS
-
-#if !DISABLE_DEBUG_OUTPUT
-#define printf(x...) _printf(x)
-#else
-static inline int __PRINTFLIKE(1, 2) printf(const char *fmt, ...) { return 0; }
-#endif
-
-int _printf(const char *fmt, ...) __PRINTFLIKE(1, 2);
-int sprintf(char *str, const char *fmt, ...) __PRINTFLIKE(2, 3);
-int snprintf(char *str, size_t len, const char *fmt, ...) __PRINTFLIKE(3, 4);
-int vsprintf(char *str, const char *fmt, va_list ap);
-int vsnprintf(char *str, size_t len, const char *fmt, va_list ap);
-
-/* printf engine that parses the format string and generates output */
-
-/* function pointer to pass the printf engine, called back during the formatting.
- * input is a string to output, length bytes to output (or null on string),
- * return code is number of characters that would have been written, or error code (if negative)
- */
-typedef int (*_printf_engine_output_func)(const char *str, size_t len, void *state);
-
-int _printf_engine(_printf_engine_output_func out, void *state, const char *fmt, va_list ap);
-
-// Print a wide string to console
-int puts16(char16_t *str);
-
-__END_CDECLS
-
-#endif
diff --git a/bootloader/include/reg.h b/bootloader/include/reg.h
deleted file mode 100644
index 9b00a79..0000000
--- a/bootloader/include/reg.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stdint.h>
-
-#define REG8(addr) ((volatile uint8_t *)(uintptr_t)(addr))
-#define REG16(addr) ((volatile uint16_t *)(uintptr_t)(addr))
-#define REG32(addr) ((volatile uint32_t *)(uintptr_t)(addr))
-#define REG64(addr) ((volatile uint64_t *)(uintptr_t)(addr))
-
-#define writeb(v, a) (*REG8(a) = (v))
-#define readb(a) (*REG8(a))
-#define writew(v, a) (*REG16(a) = (v))
-#define readw(a) (*REG16(a))
-#define writel(v, a) (*REG32(a) = (v))
-#define readl(a) (*REG32(a))
-#define writell(v, a) (*REG64(a) = (v))
-#define readll(a) (*REG64(a))
-
diff --git a/bootloader/include/stdio.h b/bootloader/include/stdio.h
deleted file mode 100644
index 9f58e6a..0000000
--- a/bootloader/include/stdio.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#ifndef NULL
-#define NULL ((void*)0)
-#endif
-
-#include <stdint.h>
-#include <printf.h>
-#include <stddef.h>
-
-int puts16(char16_t* str);
diff --git a/bootloader/include/stdlib.h b/bootloader/include/stdlib.h
deleted file mode 100644
index f42ab4a..0000000
--- a/bootloader/include/stdlib.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stddef.h>
-
-int atoi(const char* nptr);
-long atol(const char* nptr);
-long long atoll(const char* nptr);
diff --git a/bootloader/include/string.h b/bootloader/include/string.h
deleted file mode 100644
index ef18db5..0000000
--- a/bootloader/include/string.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stddef.h>
-
-void* memset(void* dst, int c, size_t n);
-void* memcpy(void* dst, const void* src, size_t n);
-int memcmp(const void* a, const void* b, size_t n);
-size_t strlen(const char* s);
-size_t strnlen(const char* s, size_t max);
-char* strchr(const char* s, int c);
-char* strcpy(char* dst, const char* src);
-char* strncpy(char* dst, const char* src, size_t len);
-int strcmp(const char* s1, const char* s2);
-int strncmp(const char* s1, const char* s2, size_t len);
diff --git a/bootloader/include/strings.h b/bootloader/include/strings.h
deleted file mode 100644
index d48a5c3..0000000
--- a/bootloader/include/strings.h
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stddef.h>
-
-int strcasecmp(const char* s1, const char* s2);
-int strncasecmp(const char* s1, const char* s2, size_t len);
diff --git a/bootloader/include/sys/types.h b/bootloader/include/sys/types.h
deleted file mode 100644
index d460402..0000000
--- a/bootloader/include/sys/types.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stddef.h>
-
-typedef size_t off_t;
-
-typedef int ssize_t;
diff --git a/bootloader/include/uchar.h b/bootloader/include/uchar.h
deleted file mode 100644
index ed275d7..0000000
--- a/bootloader/include/uchar.h
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-typedef __CHAR16_TYPE__ char16_t;
diff --git a/bootloader/include/unistd.h b/bootloader/include/unistd.h
deleted file mode 100644
index 9f9266e..0000000
--- a/bootloader/include/unistd.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <sys/types.h>
-
diff --git a/bootloader/include/xefi.h b/bootloader/include/xefi.h
deleted file mode 100644
index 1fbe723..0000000
--- a/bootloader/include/xefi.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <efi/boot-services.h>
-#include <efi/system-table.h>
-#include <efi/types.h>
-#include <efi/protocol/device-path.h>
-#include <efi/protocol/file.h>
-#include <efi/protocol/simple-text-output.h>
-
-void xefi_init(efi_handle img, efi_system_table* sys);
-
-void xefi_wait_any_key(void);
-void xefi_fatal(const char* msg, efi_status status);
-char16_t* xefi_handle_to_str(efi_handle handle);
-const char *xefi_strerror(efi_status status);
-const char16_t* xefi_wstrerror(efi_status status);
-size_t strlen_16(char16_t* str);
-
-char16_t* xefi_devpath_to_str(efi_device_path_protocol* path);
-
-int xefi_cmp_guid(efi_guid* guid1, efi_guid* guid2);
-
-// Convenience wrappers for Open/Close protocol for use by
-// UEFI app code that's not a driver model participant
-efi_status xefi_open_protocol(efi_handle h, efi_guid* guid, void** ifc);
-efi_status xefi_close_protocol(efi_handle h, efi_guid* guid);
-
-efi_file_protocol* xefi_open_file(const char16_t* filename);
-void* xefi_read_file(efi_file_protocol* file, size_t* _sz, size_t front_bytes);
-void* xefi_load_file(const char16_t* filename, size_t* size_out,
-                     size_t front_bytes);
-
-efi_status xefi_find_pci_mmio(efi_boot_services* bs, uint8_t cls, uint8_t sub, uint8_t ifc, uint64_t* mmio);
-
-// GUIDs
-extern efi_guid SimpleFileSystemProtocol;
-extern efi_guid FileInfoGUID;
-
-typedef struct {
-    efi_handle img;
-    efi_system_table* sys;
-    efi_boot_services* bs;
-    efi_simple_text_output_protocol* conout;
-} xefi_global;
-
-extern xefi_global xefi_global_state;
-
-// Global Context
-#define gImg (xefi_global_state.img)
-#define gSys (xefi_global_state.sys)
-#define gBS (xefi_global_state.bs)
-#define gConOut (xefi_global_state.conout)
diff --git a/bootloader/lib/console-printf.c b/bootloader/lib/console-printf.c
deleted file mode 100644
index 37b57ec..0000000
--- a/bootloader/lib/console-printf.c
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <printf.h>
-#include <xefi.h>
-
-#define PCBUFMAX 126
-// buffer is two larger to leave room for a \0 and room
-// for a \r that may be added after a \n
-
-typedef struct {
-    int off;
-    char16_t buf[PCBUFMAX + 2];
-} _pcstate;
-
-static int _printf_console_out(const char* str, size_t len, void* _state) {
-    _pcstate* state = _state;
-    char16_t* buf = state->buf;
-    int i = state->off;
-    int n = len;
-    while (n > 0) {
-        if (*str == '\n') {
-            buf[i++] = '\r';
-        }
-        buf[i++] = *str++;
-        if (i >= PCBUFMAX) {
-            buf[i] = 0;
-            gConOut->OutputString(gConOut, buf);
-            i = 0;
-        }
-        n--;
-    }
-    state->off = i;
-    return len;
-}
-
-int _printf(const char* fmt, ...) {
-    va_list ap;
-    _pcstate state;
-    int r;
-    state.off = 0;
-    va_start(ap, fmt);
-    r = _printf_engine(_printf_console_out, &state, fmt, ap);
-    va_end(ap);
-    if (state.off) {
-        state.buf[state.off] = 0;
-        gConOut->OutputString(gConOut, state.buf);
-    }
-    return r;
-}
-
-int puts16(char16_t* str) {
-    return gConOut->OutputString(gConOut, str) == EFI_SUCCESS ? 0 : -1;
-}
diff --git a/bootloader/lib/ctype.c b/bootloader/lib/ctype.c
deleted file mode 100644
index 2035daf..0000000
--- a/bootloader/lib/ctype.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <ctype.h>
-
-int isdigit(int c) {
-    return (c >= '0') && (c <= '9');
-}
-
-int isspace(int c) {
-    return (c == ' ')  ||
-           (c == '\f') ||
-           (c == '\n') ||
-           (c == '\r') ||
-           (c == '\t') ||
-           (c == '\v');
-}
-
-int tolower(int c) {
-    if (c >= 'A' && c <= 'Z') {
-        return c + ('a' - 'A');
-    }
-    return c;
-}
-
diff --git a/bootloader/lib/efi/guids.c b/bootloader/lib/efi/guids.c
deleted file mode 100644
index 847f454..0000000
--- a/bootloader/lib/efi/guids.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <efi/protocol/block-io.h>
-#include <efi/protocol/device-path.h>
-#include <efi/protocol/device-path-to-text.h>
-#include <efi/protocol/disk-io.h>
-#include <efi/protocol/driver-binding.h>
-#include <efi/protocol/file.h>
-#include <efi/protocol/graphics-output.h>
-#include <efi/protocol/loaded-image.h>
-#include <efi/protocol/managed-network.h>
-#include <efi/protocol/pci-root-bridge-io.h>
-#include <efi/protocol/simple-file-system.h>
-#include <efi/protocol/simple-network.h>
-#include <efi/protocol/simple-text-input.h>
-#include <efi/protocol/simple-text-output.h>
-#include <efi/protocol/usb-io.h>
-
-efi_guid BlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID;
-efi_guid DevicePathProtocol = EFI_DEVICE_PATH_PROTOCOL_GUID;
-efi_guid DevicePathToTextProtocol = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
-efi_guid DiskIoProtocol = EFI_DISK_IO_PROTOCOL_GUID;
-efi_guid DriverBindingProtocol = EFI_DRIVER_BINDING_PROTOCOL_GUID;
-efi_guid FileInfoGuid = EFI_FILE_INFO_GUID;
-efi_guid FileSystemInfoGuid = EFI_FILE_SYSTEM_INFO_GUID;
-efi_guid GraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
-efi_guid LoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
-efi_guid ManagedNetworkProtocol = EFI_MANAGED_NETWORK_PROTOCOL_GUID;
-efi_guid PciRootBridgeIoProtocol = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
-efi_guid SimpleFileSystemProtocol = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
-efi_guid SimpleNetworkProtocol = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
-efi_guid SimpleTextInputProtocol = EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
-efi_guid SimpleTextOutputProtocol = EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
-efi_guid UsbIoProtocol = EFI_USB_IO_PROTOCOL_GUID;
diff --git a/bootloader/lib/inet.c b/bootloader/lib/inet.c
deleted file mode 100644
index 83fc2de..0000000
--- a/bootloader/lib/inet.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdint.h>
-
-#ifndef __BYTE_ORDER__
-#error __BYTE_ORDER__ not defined!
-#endif
-
-#ifndef __ORDER_LITTLE_ENDIAN__
-#error __ORDER_LITTLE_ENDIAN__ not defined!
-#endif
-
-uint16_t htons(uint16_t val) {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-    return __builtin_bswap16(val);
-#else
-    return val;
-#endif
-}
-
-uint16_t ntohs(uint16_t val) {
-    return htons(val);
-}
-
-uint32_t htonl(uint32_t val) {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-    return __builtin_bswap32(val);
-#else
-    return val;
-#endif
-}
-
-uint32_t ntohl(uint32_t val) {
-    return htonl(val);
-}
-
diff --git a/bootloader/lib/loadfile.c b/bootloader/lib/loadfile.c
deleted file mode 100644
index 26462d4..0000000
--- a/bootloader/lib/loadfile.c
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <efi/protocol/loaded-image.h>
-#include <efi/protocol/simple-file-system.h>
-
-#include <xefi.h>
-#include <stdio.h>
-
-#ifndef VERBOSE
-#define xprintf(...) do {} while (0);
-#else
-#define xprintf(fmt...) printf(fmt)
-#endif
-
-efi_file_protocol* xefi_open_file(const char16_t* filename) {
-    efi_loaded_image_protocol* loaded;
-    efi_status r;
-    efi_file_protocol* file = NULL;
-
-    r = xefi_open_protocol(gImg, &LoadedImageProtocol, (void**)&loaded);
-    if (r) {
-        xprintf("LoadFile: Cannot open LoadedImageProtocol (%s)\n", xefi_strerror(r));
-        goto exit0;
-    }
-
-#if 0
-    printf("Img DeviceHandle='%s'\n", HandleToString(loaded->DeviceHandle));
-    printf("Img FilePath='%s'\n", DevicePathToStr(loaded->FilePath));
-    printf("Img Base=%lx Size=%lx\n", loaded->ImageBase, loaded->ImageSize);
-#endif
-
-    efi_simple_file_system_protocol* sfs;
-    r = xefi_open_protocol(loaded->DeviceHandle, &SimpleFileSystemProtocol, (void**)&sfs);
-    if (r) {
-        xprintf("LoadFile: Cannot open SimpleFileSystemProtocol (%s)\n", xefi_strerror(r));
-        goto exit1;
-    }
-
-    efi_file_protocol* root;
-    r = sfs->OpenVolume(sfs, &root);
-    if (r) {
-        xprintf("LoadFile: Cannot open root volume (%s)\n", xefi_strerror(r));
-        goto exit2;
-    }
-
-    r = root->Open(root, &file, filename, EFI_FILE_MODE_READ, 0);
-    if (r) {
-        xprintf("LoadFile: Cannot open file (%s)\n", xefi_strerror(r));
-        goto exit3;
-    }
-
-exit3:
-    root->Close(root);
-exit2:
-    xefi_close_protocol(loaded->DeviceHandle, &SimpleFileSystemProtocol);
-exit1:
-    xefi_close_protocol(gImg, &LoadedImageProtocol);
-exit0:
-    return file;
-}
-
-void* xefi_read_file(efi_file_protocol* file, size_t* _sz, size_t front_bytes) {
-    efi_status r;
-    size_t pages = 0;
-    void* data = NULL;
-
-    char buf[512];
-    size_t sz = sizeof(buf);
-    efi_file_info* finfo = (void*)buf;
-    r = file->GetInfo(file, &FileInfoGuid, &sz, finfo);
-    if (r) {
-        xprintf("LoadFile: Cannot get FileInfo (%s)\n", xefi_strerror(r));
-        return NULL;
-    }
-
-    pages = (finfo->FileSize + front_bytes + 4095) / 4096;
-    r = gBS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages, (efi_physical_addr *)&data);
-    if (r) {
-        xprintf("LoadFile: Cannot allocate buffer (%s)\n", xefi_strerror(r));
-        return NULL;
-    }
-
-    sz = finfo->FileSize;
-    r = file->Read(file, &sz, data + front_bytes);
-    if (r) {
-        xprintf("LoadFile: Error reading file (%s)\n", xefi_strerror(r));
-        gBS->FreePages((efi_physical_addr)data, pages);
-        return NULL;
-    }
-    if (sz != finfo->FileSize) {
-        xprintf("LoadFile: Short read\n");
-        gBS->FreePages((efi_physical_addr)data, pages);
-        return NULL;
-    }
-    *_sz = finfo->FileSize;
-
-    return data + front_bytes;
-}
-
-void* xefi_load_file(const char16_t* filename, size_t* _sz,
-                     size_t front_bytes) {
-    efi_file_protocol* file = xefi_open_file(filename);
-    if (!file) {
-        return NULL;
-    }
-    void* data = xefi_read_file(file, _sz, front_bytes);
-    file->Close(file);
-    return data;
-}
diff --git a/bootloader/lib/printf.c b/bootloader/lib/printf.c
deleted file mode 100644
index 533a6ef..0000000
--- a/bootloader/lib/printf.c
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2008-2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <limits.h>
-#include <printf.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/types.h>
-
-int sprintf(char *str, const char *fmt, ...)
-{
-    int err;
-
-    va_list ap;
-    va_start(ap, fmt);
-    err = vsprintf(str, fmt, ap);
-    va_end(ap);
-
-    return err;
-}
-
-int snprintf(char *str, size_t len, const char *fmt, ...)
-{
-    int err;
-
-    va_list ap;
-    va_start(ap, fmt);
-    err = vsnprintf(str, len, fmt, ap);
-    va_end(ap);
-
-    return err;
-}
-
-
-#define LONGFLAG       0x00000001
-#define LONGLONGFLAG   0x00000002
-#define HALFFLAG       0x00000004
-#define HALFHALFFLAG   0x00000008
-#define SIZETFLAG      0x00000010
-#define INTMAXFLAG     0x00000020
-#define PTRDIFFFLAG    0x00000040
-#define ALTFLAG        0x00000080
-#define CAPSFLAG       0x00000100
-#define SHOWSIGNFLAG   0x00000200
-#define SIGNEDFLAG     0x00000400
-#define LEFTFORMATFLAG 0x00000800
-#define LEADZEROFLAG   0x00001000
-#define BLANKPOSFLAG   0x00002000
-
-__NO_INLINE static char *longlong_to_string(char *buf, unsigned long long n, size_t len, unsigned int flag, char *signchar)
-{
-    size_t pos = len;
-    int negative = 0;
-
-    if ((flag & SIGNEDFLAG) && (long long)n < 0) {
-        negative = 1;
-        n = -n;
-    }
-
-    buf[--pos] = 0;
-
-    /* only do the math if the number is >= 10 */
-    while (n >= 10) {
-        int digit = n % 10;
-
-        n /= 10;
-
-        buf[--pos] = digit + '0';
-    }
-    buf[--pos] = n + '0';
-
-    if (negative)
-        *signchar = '-';
-    else if ((flag & SHOWSIGNFLAG))
-        *signchar = '+';
-    else if ((flag & BLANKPOSFLAG))
-        *signchar = ' ';
-    else
-        *signchar = '\0';
-
-    return &buf[pos];
-}
-
-static const char hextable[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-static const char hextable_caps[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
-__NO_INLINE static char *longlong_to_hexstring(char *buf, unsigned long long u, size_t len, unsigned int flag)
-{
-    size_t pos = len;
-    const char *table = (flag & CAPSFLAG) ? hextable_caps : hextable;
-
-    buf[--pos] = 0;
-    do {
-        unsigned int digit = u % 16;
-        u /= 16;
-
-        buf[--pos] = table[digit];
-    } while (u != 0);
-
-    return &buf[pos];
-}
-
-int vsprintf(char *str, const char *fmt, va_list ap)
-{
-    return vsnprintf(str, INT_MAX, fmt, ap);
-}
-
-struct _output_args {
-    char *outstr;
-    size_t len;
-    size_t pos;
-};
-
-static int _vsnprintf_output(const char *str, size_t len, void *state)
-{
-    struct _output_args *args = state;
-
-    size_t count = 0;
-    while (count < len) {
-        if (args->pos < args->len) {
-            args->outstr[args->pos++] = *str;
-        }
-
-        str++;
-        count++;
-    }
-
-    return count;
-}
-
-int vsnprintf(char *str, size_t len, const char *fmt, va_list ap)
-{
-    struct _output_args args;
-    int wlen;
-
-    args.outstr = str;
-    args.len = len;
-    args.pos = 0;
-
-    wlen = _printf_engine(&_vsnprintf_output, (void *)&args, fmt, ap);
-    if (args.pos >= len)
-        str[len-1] = '\0';
-    else
-        str[wlen] = '\0';
-    return wlen;
-}
-
-int _printf_engine(_printf_engine_output_func out, void *state, const char *fmt, va_list ap)
-{
-    int err = 0;
-    char c;
-    unsigned char uc;
-    const char *s;
-    size_t string_len;
-    unsigned long long n;
-    void *ptr;
-    int flags;
-    unsigned int format_num;
-    char signchar;
-    size_t chars_written = 0;
-    char num_buffer[32];
-
-#define OUTPUT_STRING(str, len) do { err = out(str, len, state); if (err < 0) { goto exit; } else { chars_written += err; } } while(0)
-#define OUTPUT_CHAR(c) do { char __temp[1] = { c }; OUTPUT_STRING(__temp, 1); } while (0)
-
-    for (;;) {
-        /* reset the format state */
-        flags = 0;
-        format_num = 0;
-        signchar = '\0';
-
-        /* handle regular chars that aren't format related */
-        s = fmt;
-        string_len = 0;
-        while ((c = *fmt++) != 0) {
-            if (c == '%')
-                break; /* we saw a '%', break and start parsing format */
-            string_len++;
-        }
-
-        /* output the string we've accumulated */
-        OUTPUT_STRING(s, string_len);
-
-        /* make sure we haven't just hit the end of the string */
-        if (c == 0)
-            break;
-
-next_format:
-        /* grab the next format character */
-        c = *fmt++;
-        if (c == 0)
-            break;
-
-        switch (c) {
-            case '0'...'9':
-                if (c == '0' && format_num == 0)
-                    flags |= LEADZEROFLAG;
-                format_num *= 10;
-                format_num += c - '0';
-                goto next_format;
-            case '.':
-                /* XXX for now eat numeric formatting */
-                goto next_format;
-            case '%':
-                OUTPUT_CHAR('%');
-                break;
-            case 'c':
-                uc = va_arg(ap, unsigned int);
-                OUTPUT_CHAR(uc);
-                break;
-            case 's':
-                s = va_arg(ap, const char *);
-                if (s == 0)
-                    s = "<null>";
-                flags &= ~LEADZEROFLAG; /* doesn't make sense for strings */
-                goto _output_string;
-            case '-':
-                flags |= LEFTFORMATFLAG;
-                goto next_format;
-            case '+':
-                flags |= SHOWSIGNFLAG;
-                goto next_format;
-            case ' ':
-                flags |= BLANKPOSFLAG;
-                goto next_format;
-            case '#':
-                flags |= ALTFLAG;
-                goto next_format;
-            case 'l':
-                if (flags & LONGFLAG)
-                    flags |= LONGLONGFLAG;
-                flags |= LONGFLAG;
-                goto next_format;
-            case 'h':
-                if (flags & HALFFLAG)
-                    flags |= HALFHALFFLAG;
-                flags |= HALFFLAG;
-                goto next_format;
-            case 'z':
-                flags |= SIZETFLAG;
-                goto next_format;
-            case 'j':
-                flags |= INTMAXFLAG;
-                goto next_format;
-            case 't':
-                flags |= PTRDIFFFLAG;
-                goto next_format;
-            case 'i':
-            case 'd':
-                n = (flags & LONGLONGFLAG) ? va_arg(ap, long long) :
-                    (flags & LONGFLAG) ? va_arg(ap, long) :
-                    (flags & HALFHALFFLAG) ? (signed char)va_arg(ap, int) :
-                    (flags & HALFFLAG) ? (short)va_arg(ap, int) :
-                    (flags & SIZETFLAG) ? va_arg(ap, ssize_t) :
-                    (flags & INTMAXFLAG) ? va_arg(ap, intmax_t) :
-                    (flags & PTRDIFFFLAG) ? va_arg(ap, ptrdiff_t) :
-                    va_arg(ap, int);
-                flags |= SIGNEDFLAG;
-                s = longlong_to_string(num_buffer, n, sizeof(num_buffer), flags, &signchar);
-                goto _output_string;
-            case 'u':
-                n = (flags & LONGLONGFLAG) ? va_arg(ap, unsigned long long) :
-                    (flags & LONGFLAG) ? va_arg(ap, unsigned long) :
-                    (flags & HALFHALFFLAG) ? (unsigned char)va_arg(ap, unsigned int) :
-                    (flags & HALFFLAG) ? (unsigned short)va_arg(ap, unsigned int) :
-                    (flags & SIZETFLAG) ? va_arg(ap, size_t) :
-                    (flags & INTMAXFLAG) ? va_arg(ap, uintmax_t) :
-                    (flags & PTRDIFFFLAG) ? (uintptr_t)va_arg(ap, ptrdiff_t) :
-                    va_arg(ap, unsigned int);
-                s = longlong_to_string(num_buffer, n, sizeof(num_buffer), flags, &signchar);
-                goto _output_string;
-            case 'p':
-                flags |= LONGFLAG | ALTFLAG;
-                goto hex;
-            case 'X':
-                flags |= CAPSFLAG;
-                /* fallthrough */
-hex:
-            case 'x':
-                n = (flags & LONGLONGFLAG) ? va_arg(ap, unsigned long long) :
-                    (flags & LONGFLAG) ? va_arg(ap, unsigned long) :
-                    (flags & HALFHALFFLAG) ? (unsigned char)va_arg(ap, unsigned int) :
-                    (flags & HALFFLAG) ? (unsigned short)va_arg(ap, unsigned int) :
-                    (flags & SIZETFLAG) ? va_arg(ap, size_t) :
-                    (flags & INTMAXFLAG) ? va_arg(ap, uintmax_t) :
-                    (flags & PTRDIFFFLAG) ? (uintptr_t)va_arg(ap, ptrdiff_t) :
-                    va_arg(ap, unsigned int);
-                s = longlong_to_hexstring(num_buffer, n, sizeof(num_buffer), flags);
-                if (flags & ALTFLAG) {
-                    OUTPUT_CHAR('0');
-                    OUTPUT_CHAR((flags & CAPSFLAG) ? 'X': 'x');
-                }
-                goto _output_string;
-            case 'n':
-                ptr = va_arg(ap, void *);
-                if (flags & LONGLONGFLAG)
-                    *(long long *)ptr = chars_written;
-                else if (flags & LONGFLAG)
-                    *(long *)ptr = chars_written;
-                else if (flags & HALFHALFFLAG)
-                    *(signed char *)ptr = chars_written;
-                else if (flags & HALFFLAG)
-                    *(short *)ptr = chars_written;
-                else if (flags & SIZETFLAG)
-                    *(size_t *)ptr = chars_written;
-                else
-                    *(int *)ptr = chars_written;
-                break;
-            default:
-                OUTPUT_CHAR('%');
-                OUTPUT_CHAR(c);
-                break;
-        }
-
-        /* move on to the next field */
-        continue;
-
-        /* shared output code */
-_output_string:
-        string_len = strlen(s);
-
-        if (flags & LEFTFORMATFLAG) {
-            /* left justify the text */
-            OUTPUT_STRING(s, string_len);
-            unsigned int written = err;
-
-            /* pad to the right (if necessary) */
-            for (; format_num > written; format_num--)
-                OUTPUT_CHAR(' ');
-        } else {
-            /* right justify the text (digits) */
-
-            /* if we're going to print a sign digit,
-               it'll chew up one byte of the format size */
-            if (signchar != '\0' && format_num > 0)
-                format_num--;
-
-            /* output the sign char before the leading zeros */
-            if (flags & LEADZEROFLAG && signchar != '\0')
-                OUTPUT_CHAR(signchar);
-
-            /* pad according to the format string */
-            for (; format_num > string_len; format_num--)
-                OUTPUT_CHAR(flags & LEADZEROFLAG ? '0' : ' ');
-
-            /* if not leading zeros, output the sign char just before the number */
-            if (!(flags & LEADZEROFLAG) && signchar != '\0')
-                OUTPUT_CHAR(signchar);
-
-            /* output the string */
-            OUTPUT_STRING(s, string_len);
-        }
-        continue;
-    }
-
-#undef OUTPUT_STRING
-#undef OUTPUT_CHAR
-
-exit:
-    return (err < 0) ? err : (int)chars_written;
-}
diff --git a/bootloader/lib/stdlib.c b/bootloader/lib/stdlib.c
deleted file mode 100644
index 89a6fe6..0000000
--- a/bootloader/lib/stdlib.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdlib.h>
-
-#include <ctype.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#define ATOx(T, fn)             \
-T fn(const char* nptr) {            \
-    while (nptr && isspace(*nptr)) {  \
-        nptr++;                       \
-    }                                 \
-                                      \
-    bool neg = false;                 \
-    if (*nptr == '-') {               \
-        neg = true;                   \
-        nptr++;                       \
-    }                                 \
-                                      \
-    T ret = 0;                        \
-    for (; nptr; nptr++) {            \
-        if (!isdigit(*nptr)) break;   \
-        ret = 10*ret + (*nptr - '0'); \
-    }                                 \
-                                      \
-    if (neg) ret = -ret;              \
-    return ret;                       \
-}
-
-
-ATOx(int, atoi)
-ATOx(long, atol)
-ATOx(long long, atoll)
diff --git a/bootloader/lib/string.c b/bootloader/lib/string.c
deleted file mode 100644
index 53f09e7..0000000
--- a/bootloader/lib/string.c
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string.h>
-
-#include <stdint.h>
-
-void* memset(void* _dst, int c, size_t n) {
-    uint8_t* dst = _dst;
-    while (n-- > 0) {
-        *dst++ = c;
-    }
-    return _dst;
-}
-
-void* memcpy(void* _dst, const void* _src, size_t n) {
-    uint8_t* dst = _dst;
-    const uint8_t* src = _src;
-    while (n-- > 0) {
-        *dst++ = *src++;
-    }
-    return _dst;
-}
-
-int memcmp(const void* _a, const void* _b, size_t n) {
-    const uint8_t* a = _a;
-    const uint8_t* b = _b;
-    while (n-- > 0) {
-        int x = *a++ - *b++;
-        if (x != 0) {
-            return x;
-        }
-    }
-    return 0;
-}
-
-size_t strlen(const char* s) {
-    size_t len = 0;
-    while (*s++)
-        len++;
-    return len;
-}
-
-size_t strnlen(const char* s, size_t max) {
-    size_t len = 0;
-    while (len < max && *s++)
-        len++;
-    return len;
-}
-
-char* strchr(const char* s, int c) {
-    while (*s != c && *s++) ;
-    if (*s != c) return 0;
-    return (char*)s;
-}
-
-char* strcpy(char* dst, const char* src) {
-    while (*src != 0) {
-        *dst++ = *src++;
-    }
-    return dst;
-}
-
-char* strncpy(char* dst, const char* src, size_t len) {
-    while (len-- > 0 && *src != 0) {
-        *dst++ = *src++;
-    }
-    return dst;
-}
-
-int strcmp(const char* s1, const char* s2) {
-    while (*s1 && (*s1 == *s2)) {
-        s1++;
-        s2++;
-    }
-    return *s1 - *s2;
-}
-
-int strncmp(const char* s1, const char* s2, size_t len) {
-    while (len-- > 0) {
-        int diff = *s1 - *s2;
-        if (diff != 0 || *s1 == '\0') {
-            return diff;
-        }
-        s1++;
-        s2++;
-    }
-    return 0;
-}
diff --git a/bootloader/lib/strings.c b/bootloader/lib/strings.c
deleted file mode 100644
index f1d07c3..0000000
--- a/bootloader/lib/strings.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <ctype.h>
-#include <strings.h>
-
-int strcasecmp(const char* s1, const char* s2) {
-    while (1) {
-        int diff = tolower(*s1) - tolower(*s2);
-        if (diff != 0 || *s1 == '\0') {
-            return diff;
-        }
-        s1++;
-        s2++;
-    }
-}
-
-int strncasecmp(const char* s1, const char* s2, size_t len) {
-    while (len-- > 0) {
-        int diff = tolower(*s1) - tolower(*s2);
-        if (diff != 0 || *s1 == '\0') {
-            return diff;
-        }
-        s1++;
-        s2++;
-    }
-    return 0;
-}
diff --git a/bootloader/lib/xefi.c b/bootloader/lib/xefi.c
deleted file mode 100644
index 3d98059..0000000
--- a/bootloader/lib/xefi.c
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <efi/types.h>
-#include <efi/protocol/device-path-to-text.h>
-#include <efi/protocol/file.h>
-#include <efi/protocol/simple-file-system.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <printf.h>
-#include <xefi.h>
-
-xefi_global xefi_global_state;
-
-void xefi_init(efi_handle img, efi_system_table* sys) {
-    gSys = sys;
-    gImg = img;
-    gBS = sys->BootServices;
-    gConOut = sys->ConOut;
-}
-
-void xefi_wait_any_key(void) {
-    efi_simple_text_input_protocol* sii = gSys->ConIn;
-    efi_input_key key;
-    while (sii->ReadKeyStroke(sii, &key) != EFI_SUCCESS)
-        ;
-}
-
-void xefi_fatal(const char* msg, efi_status status) {
-    printf("\nERROR: %s (%s)\n", msg, xefi_strerror(status));
-    xefi_wait_any_key();
-    gBS->Exit(gImg, 1, 0, NULL);
-}
-
-char16_t* xefi_devpath_to_str(efi_device_path_protocol* path) {
-    efi_device_path_to_text_protocol* prot;
-    efi_status status = gBS->LocateProtocol(&DevicePathToTextProtocol, NULL, (void**)&prot);
-    if (EFI_ERROR(status)) {
-        return NULL;
-    }
-    return prot->ConvertDevicePathToText(path, false, false);
-}
-
-int xefi_cmp_guid(efi_guid* guid1, efi_guid* guid2) {
-    return memcmp(guid1, guid2, sizeof(efi_guid));
-}
-
-char16_t* xefi_handle_to_str(efi_handle h) {
-    efi_device_path_protocol* path;
-    efi_status status = gBS->HandleProtocol(h, &DevicePathProtocol, (void*)&path);
-    if (EFI_ERROR(status)) {
-        char16_t* err;
-        status = gBS->AllocatePool(EfiLoaderData, sizeof(L"<NoPath>"), (void**)&err);
-        if (EFI_ERROR(status)) {
-            return NULL;
-        }
-        gBS->CopyMem(err, L"<NoPath>", sizeof(L"<NoPath>"));
-        return err;
-    }
-    char16_t* str = xefi_devpath_to_str(path);
-    if (str == NULL) {
-        char16_t* err;
-        status = gBS->AllocatePool(EfiLoaderData, sizeof(L"<NoString>"), (void**)&err);
-        if (EFI_ERROR(status)) {
-            return NULL;
-        }
-        gBS->CopyMem(err, L"<NoString>", sizeof(L"<NoString>"));
-        return err;
-    }
-    return str;
-}
-
-efi_status xefi_open_protocol(efi_handle h, efi_guid* guid, void** ifc) {
-    return gBS->OpenProtocol(h, guid, ifc, gImg, NULL,
-                             EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
-}
-
-efi_status xefi_close_protocol(efi_handle h, efi_guid* guid) {
-    return gBS->CloseProtocol(h, guid, gImg, NULL);
-}
-
-const char *xefi_strerror(efi_status status) {
-    switch (status) {
-#define ERR_ENTRY(x) \
-    case x: {        \
-        return #x;   \
-    }
-        ERR_ENTRY(EFI_SUCCESS);
-        ERR_ENTRY(EFI_LOAD_ERROR);
-        ERR_ENTRY(EFI_INVALID_PARAMETER);
-        ERR_ENTRY(EFI_UNSUPPORTED);
-        ERR_ENTRY(EFI_BAD_BUFFER_SIZE);
-        ERR_ENTRY(EFI_BUFFER_TOO_SMALL);
-        ERR_ENTRY(EFI_NOT_READY);
-        ERR_ENTRY(EFI_DEVICE_ERROR);
-        ERR_ENTRY(EFI_WRITE_PROTECTED);
-        ERR_ENTRY(EFI_OUT_OF_RESOURCES);
-        ERR_ENTRY(EFI_VOLUME_CORRUPTED);
-        ERR_ENTRY(EFI_VOLUME_FULL);
-        ERR_ENTRY(EFI_NO_MEDIA);
-        ERR_ENTRY(EFI_MEDIA_CHANGED);
-        ERR_ENTRY(EFI_NOT_FOUND);
-        ERR_ENTRY(EFI_ACCESS_DENIED);
-        ERR_ENTRY(EFI_NO_RESPONSE);
-        ERR_ENTRY(EFI_NO_MAPPING);
-        ERR_ENTRY(EFI_TIMEOUT);
-        ERR_ENTRY(EFI_NOT_STARTED);
-        ERR_ENTRY(EFI_ALREADY_STARTED);
-        ERR_ENTRY(EFI_ABORTED);
-        ERR_ENTRY(EFI_ICMP_ERROR);
-        ERR_ENTRY(EFI_TFTP_ERROR);
-        ERR_ENTRY(EFI_PROTOCOL_ERROR);
-        ERR_ENTRY(EFI_INCOMPATIBLE_VERSION);
-        ERR_ENTRY(EFI_SECURITY_VIOLATION);
-        ERR_ENTRY(EFI_CRC_ERROR);
-        ERR_ENTRY(EFI_END_OF_MEDIA);
-        ERR_ENTRY(EFI_END_OF_FILE);
-        ERR_ENTRY(EFI_INVALID_LANGUAGE);
-        ERR_ENTRY(EFI_COMPROMISED_DATA);
-        ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT);
-        ERR_ENTRY(EFI_HTTP_ERROR);
-#undef ERR_ENTRY
-    }
-
-    return "<Unknown error>";
-}
-
-const char16_t* xefi_wstrerror(efi_status status) {
-    switch (status) {
-#define ERR_ENTRY(x)     \
-    case x: {            \
-        return L"" #x;   \
-    }
-        ERR_ENTRY(EFI_SUCCESS);
-        ERR_ENTRY(EFI_LOAD_ERROR);
-        ERR_ENTRY(EFI_INVALID_PARAMETER);
-        ERR_ENTRY(EFI_UNSUPPORTED);
-        ERR_ENTRY(EFI_BAD_BUFFER_SIZE);
-        ERR_ENTRY(EFI_BUFFER_TOO_SMALL);
-        ERR_ENTRY(EFI_NOT_READY);
-        ERR_ENTRY(EFI_DEVICE_ERROR);
-        ERR_ENTRY(EFI_WRITE_PROTECTED);
-        ERR_ENTRY(EFI_OUT_OF_RESOURCES);
-        ERR_ENTRY(EFI_VOLUME_CORRUPTED);
-        ERR_ENTRY(EFI_VOLUME_FULL);
-        ERR_ENTRY(EFI_NO_MEDIA);
-        ERR_ENTRY(EFI_MEDIA_CHANGED);
-        ERR_ENTRY(EFI_NOT_FOUND);
-        ERR_ENTRY(EFI_ACCESS_DENIED);
-        ERR_ENTRY(EFI_NO_RESPONSE);
-        ERR_ENTRY(EFI_NO_MAPPING);
-        ERR_ENTRY(EFI_TIMEOUT);
-        ERR_ENTRY(EFI_NOT_STARTED);
-        ERR_ENTRY(EFI_ALREADY_STARTED);
-        ERR_ENTRY(EFI_ABORTED);
-        ERR_ENTRY(EFI_ICMP_ERROR);
-        ERR_ENTRY(EFI_TFTP_ERROR);
-        ERR_ENTRY(EFI_PROTOCOL_ERROR);
-        ERR_ENTRY(EFI_INCOMPATIBLE_VERSION);
-        ERR_ENTRY(EFI_SECURITY_VIOLATION);
-        ERR_ENTRY(EFI_CRC_ERROR);
-        ERR_ENTRY(EFI_END_OF_MEDIA);
-        ERR_ENTRY(EFI_END_OF_FILE);
-        ERR_ENTRY(EFI_INVALID_LANGUAGE);
-        ERR_ENTRY(EFI_COMPROMISED_DATA);
-        ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT);
-        ERR_ENTRY(EFI_HTTP_ERROR);
-#undef ERR_ENTRY
-    }
-
-    return L"<Unknown error>";
-}
-
-size_t strlen_16(char16_t* str) {
-    size_t len = 0;
-    while (*(str + len) != '\0') {
-        len++;
-    }
-
-    return len;
-}
diff --git a/bootloader/scripts/99-asix.rules b/bootloader/scripts/99-asix.rules
deleted file mode 100644
index db51758..0000000
--- a/bootloader/scripts/99-asix.rules
+++ /dev/null
@@ -1,10 +0,0 @@
-# ASIX USB-ETH dongles.
-#
-
-# AX88772B
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0b95", ATTR{idProduct}=="772b", MODE="0666"
-# AX88772
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="0b95", ATTR{idProduct}=="7720", MODE="0666"
-# Apple USB ETH dongle AX88772
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="05ac", ATTR{idProduct}=="1402", MODE="0666"
-
diff --git a/bootloader/scripts/bootzircon b/bootloader/scripts/bootzircon
deleted file mode 100755
index ef32e10..0000000
--- a/bootloader/scripts/bootzircon
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-make && mcopy -o -i out/disk.img@@1024K ../build-x86/zircon.bin ::zircon.bin && make qemu
diff --git a/bootloader/src/cmdline.c b/bootloader/src/cmdline.c
deleted file mode 100644
index 6f2cfb6..0000000
--- a/bootloader/src/cmdline.c
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <cmdline.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "osboot.h"
-
-#include <stdio.h>
-
-#define CMDLINE_MAX_ITEMS 128
-#define CMDLINE_MAX_STRINGDATA (PAGE_SIZE * 3)
-
-static char buffer[CMDLINE_MAX_STRINGDATA];
-static size_t buffer_next = 0;
-
-typedef struct {
-    char* key;
-    char* val;
-    size_t klen;
-    size_t vlen;
-} kv_t;
-
-static kv_t entry[CMDLINE_MAX_ITEMS];
-static size_t entry_count;
-
-size_t cmdline_to_string(char* ptr, size_t max) {
-    char* start = ptr;
-
-    if (max == 0) {
-        return 0;
-    }
-
-    for (size_t n = 0; n < entry_count; n++) {
-        if ((entry[n].klen + entry[n].vlen + 3) > max) {
-            // require space for: space + key + equal + value + null
-            break;
-        }
-        if (n > 0) {
-            *ptr++ = ' ';
-            max--;
-        }
-        memcpy(ptr, entry[n].key, entry[n].klen);
-        ptr += entry[n].klen;
-        max -= entry[n].klen;
-        if (entry[n].vlen) {
-            *ptr++ = '=';
-            max--;
-            memcpy(ptr, entry[n].val, entry[n].vlen);
-            ptr += entry[n].vlen;
-            max -= entry[n].vlen;
-        }
-    }
-    *ptr++ = 0;
-    return ptr - start;
-}
-
-static void entry_add(const char* key, size_t klen, const char* val, size_t vlen) {
-    if (klen == 0) {
-        // empty keys are not allowed
-        return;
-    }
-
-    if ((klen > 1024) || (vlen > 1024)) {
-        // huge keys and values are not allowed
-        return;
-    }
-
-    if ((sizeof(buffer) - buffer_next) < (klen + vlen + 2)) {
-        // give up if it won't fit
-        return;
-    }
-
-    size_t n;
-    for (n = 0; n < entry_count; n++) {
-        if ((entry[n].klen == klen) && !memcmp(key, entry[n].key, klen)) {
-            goto write_value;
-        }
-    }
-    if (n == CMDLINE_MAX_ITEMS) {
-        // no space in table
-        return;
-    }
-
-    // new entry
-    entry_count++;
-    entry[n].key = buffer + buffer_next;
-    entry[n].klen = klen;
-    memcpy(entry[n].key, key, klen);
-    entry[n].key[klen] = 0;
-    buffer_next += klen + 1;
-
-write_value:
-    entry[n].val = buffer + buffer_next;
-    entry[n].vlen = vlen;
-    memcpy(entry[n].val, val, vlen);
-    entry[n].val[vlen] = 0;
-    buffer_next += vlen + 1;
-}
-
-void cmdline_set(const char* key, const char* val) {
-    entry_add(key, strlen(key), val, strlen(val));
-}
-
-void cmdline_append(const char* ptr, size_t len) {
-    const char* key;
-    const char* val;
-
-restart:
-    while (len > 0) {
-        if (isspace(*ptr)) {
-            ptr++;
-            len--;
-            continue;
-        }
-        key = ptr;
-        while (len > 0) {
-            if (*ptr == '=') {
-                size_t klen = ptr - key;
-                ptr++;
-                len--;
-                val = ptr;
-                while ((len > 0) && !isspace(*ptr)) {
-                    len--;
-                    ptr++;
-                }
-                size_t vlen = ptr - val;
-                entry_add(key, klen, val, vlen);
-                goto restart;
-            }
-            if (isspace(*ptr)) {
-                break;
-            }
-            ptr++;
-            len--;
-        }
-        size_t klen = ptr - key;
-        entry_add(key, klen, NULL, 0);
-    }
-}
-
-const char* cmdline_get(const char* key, const char* _default) {
-    size_t klen = strlen(key);
-    for (size_t n = 0; n < entry_count; n++) {
-        if ((entry[n].klen == klen) && !memcmp(key, entry[n].key, klen)) {
-            return entry[n].val;
-        }
-    }
-    return _default;
-}
-
-uint32_t cmdline_get_uint32(const char* key, uint32_t _default) {
-    const char* val = cmdline_get(key, NULL);
-    if (val == NULL) {
-        return _default;
-    }
-    return atol(val);
-}
diff --git a/bootloader/src/cmdline.h b/bootloader/src/cmdline.h
deleted file mode 100644
index 320ae44..0000000
--- a/bootloader/src/cmdline.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-
-// append a commandline string to the commandline
-void cmdline_append(const char* str, size_t len);
-
-// add a commandline item to the commandline
-// (replaces items with the same name)
-void cmdline_set(const char* key, const char* val);
-
-// look up an item in the commandline
-const char* cmdline_get(const char* key, const char* _default);
-uint32_t cmdline_get_uint32(const char* key, uint32_t _default);
-
-// obtain the entire commandline as a string
-size_t cmdline_to_string(char* ptr, size_t max);
diff --git a/bootloader/src/device_id.c b/bootloader/src/device_id.c
deleted file mode 100644
index e213b6c..0000000
--- a/bootloader/src/device_id.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "device_id.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include "eff_short_wordlist_1.h"
-
-#define APPEND_WORD(NUM, SEP)         \
-    word = dictionary[(NUM) % 1296];  \
-    memcpy(dest, word, strlen(word)); \
-    dest += strlen(word);             \
-    *dest = SEP;                      \
-    dest++;
-
-void device_id(mac_addr addr, char out[DEVICE_ID_MAX]) {
-    const char* word;
-    char* dest = out;
-    APPEND_WORD(addr.x[0] | ((addr.x[4] << 8) & 0xF00), '-');
-    APPEND_WORD(addr.x[1] | ((addr.x[5] << 8) & 0xF00), '-');
-    APPEND_WORD(addr.x[2] | ((addr.x[4] << 4) & 0xF00), '-');
-    APPEND_WORD(addr.x[3] | ((addr.x[5] << 4) & 0xF00), 0);
-}
diff --git a/bootloader/src/device_id.h b/bootloader/src/device_id.h
deleted file mode 100644
index c6c006e..0000000
--- a/bootloader/src/device_id.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <inet6.h>
-
-#define DEVICE_ID_MAX 24
-
-void device_id(mac_addr addr, char out[DEVICE_ID_MAX]);
diff --git a/bootloader/src/diskio.c b/bootloader/src/diskio.c
deleted file mode 100644
index 6100ae0..0000000
--- a/bootloader/src/diskio.c
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdio.h>
-#include <string.h>
-
-#include <efi/protocol/block-io.h>
-#include <efi/protocol/disk-io.h>
-#include <efi/protocol/loaded-image.h>
-#include <efi/protocol/device-path.h>
-#include <efi/protocol/device-path-to-text.h>
-
-#include <zircon/hw/gpt.h>
-
-#include "osboot.h"
-
-static bool path_node_match(efi_device_path_protocol* a,
-                            efi_device_path_protocol* b) {
-    size_t alen = a->Length[0] | (a->Length[1] << 8);
-    size_t blen = b->Length[0] | (b->Length[1] << 8);
-    if (alen != blen) {
-        return false;
-    }
-    if (memcmp(a, b, alen)) {
-        return false;
-    }
-    return true;
-}
-
-static efi_device_path_protocol* path_node_next(efi_device_path_protocol* node) {
-    if (node->Type == DEVICE_PATH_END) {
-        return NULL;
-    }
-    return ((void*) node) + (node->Length[0] | (node->Length[1] << 8));
-}
-
-static bool path_prefix_match(efi_device_path_protocol* path,
-                              efi_device_path_protocol* prefix) {
-    if ((path == NULL) || (prefix == NULL)) {
-        return false;
-    }
-    for (;;) {
-        if (prefix->Type == DEVICE_PATH_END) {
-            return true;
-        }
-        if (!path_node_match(path, prefix)) {
-            return false;
-        }
-        if ((path = path_node_next(path)) == NULL) {
-            return false;
-        }
-        prefix = path_node_next(prefix);
-    }
-}
-
-static void print_path(efi_boot_services* bs, efi_device_path_protocol* path) {
-    efi_device_path_to_text_protocol* ptt;
-    efi_status status = bs->LocateProtocol(&DevicePathToTextProtocol, NULL, (void**) &ptt);
-    if (status != EFI_SUCCESS) {
-        printf("<cannot print path>");
-        return;
-    }
-    char16_t* txt = ptt->ConvertDevicePathToText(path, false, false);
-    if (txt == NULL) {
-        printf("<cannot print path>");
-        return;
-    }
-    puts16(txt);
-    printf("\n");
-    bs->FreePool(txt);
-}
-
-typedef struct {
-    efi_disk_io_protocol* io;
-    efi_handle h;
-    efi_boot_services* bs;
-    efi_handle img;
-    uint64_t first;
-    uint64_t last;
-    uint32_t blksz;
-    uint32_t id;
-} disk_t;
-
-static efi_status disk_read(disk_t* disk, size_t offset, void* data, size_t length) {
-    uint64_t size = (disk->last - disk->first) * disk->blksz;
-
-    if ((offset > size) || ((size - offset) < length)) {
-        return EFI_INVALID_PARAMETER;
-    }
-
-    return disk->io->ReadDisk(disk->io, disk->id, (disk->first * disk->blksz) + offset, length, data);
-}
-
-static void disk_close(disk_t* disk) {
-    disk->bs->CloseProtocol(disk->h, &DiskIoProtocol, disk->img, NULL);
-}
-
-static int disk_find_boot(efi_handle img, efi_system_table* sys,
-                          bool verbose, disk_t* disk) {
-    bool found = false;
-    efi_boot_services* bs = sys->BootServices;
-    efi_handle* list;
-    size_t count;
-    efi_status status;
-    efi_loaded_image_protocol* li;
-
-    status = bs->OpenProtocol(img, &LoadedImageProtocol, (void**) &li, img, NULL,
-                              EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
-    if (status != EFI_SUCCESS) {
-        return -1;
-    }
-
-    efi_device_path_protocol* imgdevpath;
-    status = bs->OpenProtocol(li->DeviceHandle, &DevicePathProtocol,
-                              (void**) &imgdevpath, img, NULL,
-                              EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
-    if (status != EFI_SUCCESS) {
-        goto fail_open_devpath;
-    }
-
-    if (verbose) {
-        printf("BootLoader Path: ");
-        print_path(bs, li->FilePath);
-        printf("BootLoader Device: ");
-        print_path(bs, imgdevpath);
-    }
-
-    status = bs->LocateHandleBuffer(ByProtocol, &BlockIoProtocol, NULL, &count, &list);
-    if (status != EFI_SUCCESS) {
-        printf("find_boot_disk() - no block io devices found\n");
-        goto fail_get_list;
-    }
-
-    for (size_t n = 0; n < count; n++) {
-        efi_block_io_protocol* bio;
-        status = bs->OpenProtocol(list[n], &BlockIoProtocol, (void**) &bio, img, NULL,
-                                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
-        if (status != EFI_SUCCESS) {
-            continue;
-        }
-
-        efi_device_path_protocol* path;
-        status = bs->OpenProtocol(list[n], &DevicePathProtocol, (void**) &path, img, NULL,
-                                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
-        if (status != EFI_SUCCESS) {
-            bs->CloseProtocol(list[n], &BlockIoProtocol, img, NULL);
-            continue;
-        }
-
-        bool match = false;
-
-        // if a non-logical partition, check for match
-        if (!bio->Media->LogicalPartition && bio->Media->MediaPresent) {
-            match = path_prefix_match(imgdevpath, path);
-        }
-
-        if (verbose) {
-            printf("BlockIO Device: ");
-            print_path(bs, path);
-            printf("              : #%zu, %zuMB%s%s%s%s%s%s\n", n,
-                bio->Media->LastBlock * bio->Media->BlockSize / 1024 / 1024,
-                bio->Media->RemovableMedia ? " Removable" : "",
-                bio->Media->MediaPresent ? " Present" : "",
-                bio->Media->LogicalPartition ? " Logical" : "",
-                bio->Media->ReadOnly ? " RO" : "",
-                bio->Media->WriteCaching ? " WC" : "",
-                match ? " BootDevice" : "");
-        }
-
-        if (match && !found) {
-            status = bs->OpenProtocol(list[n], &DiskIoProtocol, (void**) &disk->io, img, NULL,
-                                      EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
-            if (status != EFI_SUCCESS) {
-                printf("find_boot_disk() - cannot get disk io protocol\n");
-            } else {
-                disk->first = 0;
-                disk->last = bio->Media->LastBlock;
-                disk->id = bio->Media->MediaId;
-                disk->blksz = bio->Media->BlockSize;
-                disk->h = list[n];
-                disk->img = img;
-                disk->bs = bs;
-                found = true;
-            }
-        }
-
-        bs->CloseProtocol(list[n], &BlockIoProtocol, img, NULL);
-        bs->CloseProtocol(list[n], &DevicePathProtocol, img, NULL);
-    }
-
-    bs->FreePool(list);
-
-fail_get_list:
-    bs->CloseProtocol(li->DeviceHandle, &DevicePathProtocol, img, NULL);
-
-fail_open_devpath:
-    bs->CloseProtocol(img, &LoadedImageProtocol, img, NULL);
-
-    return found ? 0 : -1;
-}
-
-static uint8_t GUID_ZIRCON_A[] = GUID_ZIRCON_A_VALUE;
-static uint8_t GUID_ZIRCON_B[] = GUID_ZIRCON_B_VALUE;
-
-static int disk_find_kernel(disk_t* disk, bool verbose) {
-    gpt_header_t gpt;
-    efi_status status = disk_read(disk, disk->blksz, &gpt, sizeof(gpt));
-    if (status != EFI_SUCCESS) {
-        return -1;
-    }
-
-    if (gpt.magic != GPT_MAGIC) {
-        printf("gpt - bad magic!\n");
-        return -1;
-    }
-
-    if (verbose) {
-        printf("gpt: size:    %u\n", gpt.size);
-        printf("gpt: current: %zu\n", gpt.current);
-        printf("gpt: backup:  %zu\n", gpt.backup);
-        printf("gpt: first:   %zu\n", gpt.first);
-        printf("gpt: last:    %zu\n", gpt.last);
-        printf("gpt: entries: %zu\n", gpt.entries);
-        printf("gpt: e.count: %u\n", gpt.entries_count);
-        printf("gpt: e.size:  %u\n", gpt.entries_size);
-    }
-
-    if ((gpt.magic != GPT_MAGIC) ||
-        (gpt.size != GPT_HEADER_SIZE) ||
-        (gpt.entries_size != GPT_ENTRY_SIZE) ||
-        (gpt.entries_count > 256)) {
-        printf("gpt - malformed header\n");
-        return -1;
-    }
-
-    gpt_entry_t* table;
-    size_t tsize = gpt.entries_count * gpt.entries_size;
-
-    status = disk->bs->AllocatePool(EfiLoaderData, tsize, (void**) &table);
-    if (status != EFI_SUCCESS) {
-        printf("gpt - allocation failure\n");
-        return -1;
-    }
-
-    status = disk_read(disk, disk->blksz * gpt.entries, table, tsize);
-    if (status != EFI_SUCCESS) {
-        disk->bs->FreePool(table);
-        printf("gpt - io error\n");
-        return -1;
-    }
-
-    bool found = false;
-    for (unsigned n = 0; n < gpt.entries_count; n++) {
-        if ((table[n].first == 0) ||
-            (table[n].last == 0) ||
-            (table[n].last < table[n].first)) {
-            // ignore empty or bogus entries
-            continue;
-        }
-
-        const char* type;
-        if (!memcmp(table[n].type, GUID_ZIRCON_A, sizeof(GUID_ZIRCON_A))) {
-            type = "zircon-a";
-            disk->first = table[n].first;
-            disk->last = table[n].last;
-            found = true;
-        } else if (!memcmp(table[n].type, GUID_ZIRCON_B, sizeof(GUID_ZIRCON_B))) {
-            type = "zircon-b";
-        } else {
-            type = "unknown";
-        }
-
-        if (verbose) {
-            char name[GPT_NAME_LEN/2];
-            for (unsigned i = 0; i < GPT_NAME_LEN/2 ; i++) {
-                unsigned c = table[n].name[i*2 + 0] | (table[n].name[i*2 + 1] << 8);
-                if ((c != 0) && ((c < ' ') || (c > 127))) {
-                    c = '.';
-                }
-                name[i] = c;
-            }
-            name[GPT_NAME_LEN/2 - 1] = 0;
-            printf("#%03d %zu..%zu %zx name='%s' type='%s'\n",
-                   n, table[n].first, table[n].last, table[n].flags, name, type);
-        }
-    }
-    disk->bs->FreePool(table);
-
-    return found ? 0 : -1;
-}
-
-void* image_load_from_disk(efi_handle img, efi_system_table* sys, size_t* _sz) {
-    static bool verbose = false;
-    static uint8_t sector[512];
-    efi_boot_services* bs = sys->BootServices;
-    disk_t disk;
-
-    if (disk_find_boot(img, sys, verbose, &disk) < 0) {
-        printf("Cannot find bootloader disk.\n");
-        return NULL;
-    }
-
-    if (disk_find_kernel(&disk, verbose)) {
-        printf("Cannot find ZIRCON partition on bootloader disk.\n");
-        goto fail0;
-    }
-
-    efi_status status = disk_read(&disk, 0, sector, 512);
-    if (status != EFI_SUCCESS) {
-        goto fail0;
-    }
-
-    size_t sz = image_getsize(sector, 512);
-    if (sz == 0) {
-        printf("ZIRCON partition has no valid header\n");
-        goto fail0;
-    }
-
-    size_t pages = (sz + 4095) / 4096;
-    void* image;
-    status = bs->AllocatePages(AllocateAnyPages, EfiLoaderData, pages, (efi_physical_addr*) &image);
-    if (status != EFI_SUCCESS) {
-        printf("Failed to allocate %zu bytes to load ZIRCON image\n", sz);
-        goto fail0;
-    }
-
-    status = disk_read(&disk, 0, image, sz);
-    if (status != EFI_SUCCESS) {
-        printf("Failed to read image from ZIRCON partition\n");
-        goto fail1;
-    }
-
-    if (identify_image(image, sz) != IMAGE_COMBO) {
-        printf("ZIRCON partition has no valid image\n");
-        goto fail1;
-    }
-
-    *_sz = sz;
-    return image;
-
-fail1:
-    bs->FreePages((efi_physical_addr) image, pages);
-fail0:
-    disk_close(&disk);
-    return NULL;
-}
diff --git a/bootloader/src/eff_short_wordlist_1.h b/bootloader/src/eff_short_wordlist_1.h
deleted file mode 100644
index d0592f6..0000000
--- a/bootloader/src/eff_short_wordlist_1.h
+++ /dev/null
@@ -1,1302 +0,0 @@
-#pragma once
-
-// This list must be consistent with
-// garnet/go/src/netstack/deviceid/eff_short_wordlist.go.
-const char dictionary[1296][6] = {
-    "acid",
-    "acorn",
-    "acre",
-    "acts",
-    "afar",
-    "affix",
-    "aged",
-    "agent",
-    "agile",
-    "aging",
-    "agony",
-    "ahead",
-    "aide",
-    "aids",
-    "aim",
-    "ajar",
-    "alarm",
-    "alias",
-    "alibi",
-    "alien",
-    "alike",
-    "alive",
-    "aloe",
-    "aloft",
-    "aloha",
-    "alone",
-    "amend",
-    "amino",
-    "ample",
-    "amuse",
-    "angel",
-    "anger",
-    "angle",
-    "ankle",
-    "apple",
-    "april",
-    "apron",
-    "aqua",
-    "area",
-    "arena",
-    "argue",
-    "arise",
-    "armed",
-    "armor",
-    "army",
-    "aroma",
-    "array",
-    "arson",
-    "art",
-    "ashen",
-    "ashes",
-    "atlas",
-    "atom",
-    "attic",
-    "audio",
-    "avert",
-    "avoid",
-    "awake",
-    "award",
-    "awoke",
-    "axis",
-    "bacon",
-    "badge",
-    "bagel",
-    "baggy",
-    "baked",
-    "baker",
-    "balmy",
-    "banjo",
-    "barge",
-    "barn",
-    "bash",
-    "basil",
-    "bask",
-    "batch",
-    "bath",
-    "baton",
-    "bats",
-    "blade",
-    "blank",
-    "blast",
-    "blaze",
-    "bleak",
-    "blend",
-    "bless",
-    "blimp",
-    "blink",
-    "bloat",
-    "blob",
-    "blog",
-    "blot",
-    "blunt",
-    "blurt",
-    "blush",
-    "boast",
-    "boat",
-    "body",
-    "boil",
-    "bok",
-    "bolt",
-    "boned",
-    "boney",
-    "bonus",
-    "bony",
-    "book",
-    "booth",
-    "boots",
-    "boss",
-    "botch",
-    "both",
-    "boxer",
-    "breed",
-    "bribe",
-    "brick",
-    "bride",
-    "brim",
-    "bring",
-    "brink",
-    "brisk",
-    "broad",
-    "broil",
-    "broke",
-    "brook",
-    "broom",
-    "brush",
-    "buck",
-    "bud",
-    "buggy",
-    "bulge",
-    "bulk",
-    "bully",
-    "bunch",
-    "bunny",
-    "bunt",
-    "bush",
-    "bust",
-    "busy",
-    "buzz",
-    "cable",
-    "cache",
-    "cadet",
-    "cage",
-    "cake",
-    "calm",
-    "cameo",
-    "canal",
-    "candy",
-    "cane",
-    "canon",
-    "cape",
-    "card",
-    "cargo",
-    "carol",
-    "carry",
-    "carve",
-    "case",
-    "cash",
-    "cause",
-    "cedar",
-    "chain",
-    "chair",
-    "chant",
-    "chaos",
-    "charm",
-    "chase",
-    "cheek",
-    "cheer",
-    "chef",
-    "chess",
-    "chest",
-    "chew",
-    "chief",
-    "chili",
-    "chill",
-    "chip",
-    "chomp",
-    "chop",
-    "chow",
-    "chuck",
-    "chump",
-    "chunk",
-    "churn",
-    "chute",
-    "cider",
-    "cinch",
-    "city",
-    "civic",
-    "civil",
-    "clad",
-    "claim",
-    "clamp",
-    "clap",
-    "clash",
-    "clasp",
-    "class",
-    "claw",
-    "clay",
-    "clean",
-    "clear",
-    "cleat",
-    "cleft",
-    "clerk",
-    "click",
-    "cling",
-    "clink",
-    "clip",
-    "cloak",
-    "clock",
-    "clone",
-    "cloth",
-    "cloud",
-    "clump",
-    "coach",
-    "coast",
-    "coat",
-    "cod",
-    "coil",
-    "coke",
-    "cola",
-    "cold",
-    "colt",
-    "coma",
-    "come",
-    "comic",
-    "comma",
-    "cone",
-    "cope",
-    "copy",
-    "coral",
-    "cork",
-    "cost",
-    "cot",
-    "couch",
-    "cough",
-    "cover",
-    "cozy",
-    "craft",
-    "cramp",
-    "crane",
-    "crank",
-    "crate",
-    "crave",
-    "crawl",
-    "crazy",
-    "creme",
-    "crepe",
-    "crept",
-    "crib",
-    "cried",
-    "crisp",
-    "crook",
-    "crop",
-    "cross",
-    "crowd",
-    "crown",
-    "crumb",
-    "crush",
-    "crust",
-    "cub",
-    "cult",
-    "cupid",
-    "cure",
-    "curl",
-    "curry",
-    "curse",
-    "curve",
-    "curvy",
-    "cushy",
-    "cut",
-    "cycle",
-    "dab",
-    "dad",
-    "daily",
-    "dairy",
-    "daisy",
-    "dance",
-    "dandy",
-    "darn",
-    "dart",
-    "dash",
-    "data",
-    "date",
-    "dawn",
-    "deaf",
-    "deal",
-    "dean",
-    "debit",
-    "debt",
-    "debug",
-    "decaf",
-    "decal",
-    "decay",
-    "deck",
-    "decor",
-    "decoy",
-    "deed",
-    "delay",
-    "denim",
-    "dense",
-    "dent",
-    "depth",
-    "derby",
-    "desk",
-    "dial",
-    "diary",
-    "dice",
-    "dig",
-    "dill",
-    "dime",
-    "dimly",
-    "diner",
-    "dingy",
-    "disco",
-    "dish",
-    "disk",
-    "ditch",
-    "ditzy",
-    "dizzy",
-    "dock",
-    "dodge",
-    "doing",
-    "doll",
-    "dome",
-    "donor",
-    "donut",
-    "dose",
-    "dot",
-    "dove",
-    "down",
-    "dowry",
-    "doze",
-    "drab",
-    "drama",
-    "drank",
-    "draw",
-    "dress",
-    "dried",
-    "drift",
-    "drill",
-    "drive",
-    "drone",
-    "droop",
-    "drove",
-    "drown",
-    "drum",
-    "dry",
-    "duck",
-    "duct",
-    "dude",
-    "dug",
-    "duke",
-    "duo",
-    "dusk",
-    "dust",
-    "duty",
-    "dwarf",
-    "dwell",
-    "eagle",
-    "early",
-    "earth",
-    "easel",
-    "east",
-    "eaten",
-    "eats",
-    "ebay",
-    "ebony",
-    "ebook",
-    "echo",
-    "edge",
-    "eel",
-    "eject",
-    "elbow",
-    "elder",
-    "elf",
-    "elk",
-    "elm",
-    "elope",
-    "elude",
-    "elves",
-    "email",
-    "emit",
-    "empty",
-    "emu",
-    "enter",
-    "entry",
-    "envoy",
-    "equal",
-    "erase",
-    "error",
-    "erupt",
-    "essay",
-    "etch",
-    "evade",
-    "even",
-    "evict",
-    "evil",
-    "evoke",
-    "exact",
-    "exit",
-    "fable",
-    "faced",
-    "fact",
-    "fade",
-    "fall",
-    "false",
-    "fancy",
-    "fang",
-    "fax",
-    "feast",
-    "feed",
-    "femur",
-    "fence",
-    "fend",
-    "ferry",
-    "feta",
-    "fetch",
-    "fever",
-    "fiber",
-    "fifth",
-    "fifty",
-    "film",
-    "filth",
-    "final",
-    "finch",
-    "fit",
-    "five",
-    "flag",
-    "flaky",
-    "flame",
-    "flap",
-    "flask",
-    "fled",
-    "flick",
-    "fling",
-    "flint",
-    "flip",
-    "flirt",
-    "float",
-    "flock",
-    "flop",
-    "floss",
-    "flyer",
-    "foam",
-    "foe",
-    "fog",
-    "foil",
-    "folic",
-    "folk",
-    "food",
-    "fool",
-    "found",
-    "fox",
-    "foyer",
-    "frail",
-    "frame",
-    "fray",
-    "fresh",
-    "fried",
-    "frill",
-    "frisk",
-    "from",
-    "front",
-    "frost",
-    "froth",
-    "frown",
-    "froze",
-    "fruit",
-    "gag",
-    "gains",
-    "gala",
-    "game",
-    "gap",
-    "gas",
-    "gave",
-    "gear",
-    "gecko",
-    "geek",
-    "gem",
-    "genre",
-    "gift",
-    "gig",
-    "gills",
-    "given",
-    "giver",
-    "glad",
-    "glass",
-    "glide",
-    "gloss",
-    "glove",
-    "glow",
-    "glue",
-    "goal",
-    "going",
-    "golf",
-    "gong",
-    "good",
-    "gooey",
-    "goofy",
-    "gore",
-    "gown",
-    "grab",
-    "grain",
-    "grant",
-    "grape",
-    "graph",
-    "grasp",
-    "grass",
-    "grave",
-    "gravy",
-    "gray",
-    "green",
-    "greet",
-    "grew",
-    "grid",
-    "grief",
-    "grill",
-    "grip",
-    "grit",
-    "groom",
-    "grope",
-    "growl",
-    "grub",
-    "grunt",
-    "guide",
-    "gulf",
-    "gulp",
-    "gummy",
-    "guru",
-    "gush",
-    "gut",
-    "guy",
-    "habit",
-    "half",
-    "halo",
-    "halt",
-    "happy",
-    "harm",
-    "hash",
-    "hasty",
-    "hatch",
-    "hate",
-    "haven",
-    "hazel",
-    "hazy",
-    "heap",
-    "heat",
-    "heave",
-    "hedge",
-    "hefty",
-    "help",
-    "herbs",
-    "hers",
-    "hub",
-    "hug",
-    "hula",
-    "hull",
-    "human",
-    "humid",
-    "hump",
-    "hung",
-    "hunk",
-    "hunt",
-    "hurry",
-    "hurt",
-    "hush",
-    "hut",
-    "ice",
-    "icing",
-    "icon",
-    "icy",
-    "igloo",
-    "image",
-    "ion",
-    "iron",
-    "islam",
-    "issue",
-    "item",
-    "ivory",
-    "ivy",
-    "jab",
-    "jam",
-    "jaws",
-    "jazz",
-    "jeep",
-    "jelly",
-    "jet",
-    "jiffy",
-    "job",
-    "jog",
-    "jolly",
-    "jolt",
-    "jot",
-    "joy",
-    "judge",
-    "juice",
-    "juicy",
-    "july",
-    "jumbo",
-    "jump",
-    "junky",
-    "juror",
-    "jury",
-    "keep",
-    "keg",
-    "kept",
-    "kick",
-    "kilt",
-    "king",
-    "kite",
-    "kitty",
-    "kiwi",
-    "knee",
-    "knelt",
-    "koala",
-    "kung",
-    "ladle",
-    "lady",
-    "lair",
-    "lake",
-    "lance",
-    "land",
-    "lapel",
-    "large",
-    "lash",
-    "lasso",
-    "last",
-    "latch",
-    "late",
-    "lazy",
-    "left",
-    "legal",
-    "lemon",
-    "lend",
-    "lens",
-    "lent",
-    "level",
-    "lever",
-    "lid",
-    "life",
-    "lift",
-    "lilac",
-    "lily",
-    "limb",
-    "limes",
-    "line",
-    "lint",
-    "lion",
-    "lip",
-    "list",
-    "lived",
-    "liver",
-    "lunar",
-    "lunch",
-    "lung",
-    "lurch",
-    "lure",
-    "lurk",
-    "lying",
-    "lyric",
-    "mace",
-    "maker",
-    "malt",
-    "mama",
-    "mango",
-    "manor",
-    "many",
-    "map",
-    "march",
-    "mardi",
-    "marry",
-    "mash",
-    "match",
-    "mate",
-    "math",
-    "moan",
-    "mocha",
-    "moist",
-    "mold",
-    "mom",
-    "moody",
-    "mop",
-    "morse",
-    "most",
-    "motor",
-    "motto",
-    "mount",
-    "mouse",
-    "mousy",
-    "mouth",
-    "move",
-    "movie",
-    "mower",
-    "mud",
-    "mug",
-    "mulch",
-    "mule",
-    "mull",
-    "mumbo",
-    "mummy",
-    "mural",
-    "muse",
-    "music",
-    "musky",
-    "mute",
-    "nacho",
-    "nag",
-    "nail",
-    "name",
-    "nanny",
-    "nap",
-    "navy",
-    "near",
-    "neat",
-    "neon",
-    "nerd",
-    "nest",
-    "net",
-    "next",
-    "niece",
-    "ninth",
-    "nutty",
-    "oak",
-    "oasis",
-    "oat",
-    "ocean",
-    "oil",
-    "old",
-    "olive",
-    "omen",
-    "onion",
-    "only",
-    "ooze",
-    "opal",
-    "open",
-    "opera",
-    "opt",
-    "otter",
-    "ouch",
-    "ounce",
-    "outer",
-    "oval",
-    "oven",
-    "owl",
-    "ozone",
-    "pace",
-    "pagan",
-    "pager",
-    "palm",
-    "panda",
-    "panic",
-    "pants",
-    "panty",
-    "paper",
-    "park",
-    "party",
-    "pasta",
-    "patch",
-    "path",
-    "patio",
-    "payer",
-    "pecan",
-    "penny",
-    "pep",
-    "perch",
-    "perky",
-    "perm",
-    "pest",
-    "petal",
-    "petri",
-    "petty",
-    "photo",
-    "plank",
-    "plant",
-    "plaza",
-    "plead",
-    "plot",
-    "plow",
-    "pluck",
-    "plug",
-    "plus",
-    "poach",
-    "pod",
-    "poem",
-    "poet",
-    "pogo",
-    "point",
-    "poise",
-    "poker",
-    "polar",
-    "polio",
-    "polka",
-    "polo",
-    "pond",
-    "pony",
-    "poppy",
-    "pork",
-    "poser",
-    "pouch",
-    "pound",
-    "pout",
-    "power",
-    "prank",
-    "press",
-    "print",
-    "prior",
-    "prism",
-    "prize",
-    "probe",
-    "prong",
-    "proof",
-    "props",
-    "prude",
-    "prune",
-    "pry",
-    "pug",
-    "pull",
-    "pulp",
-    "pulse",
-    "puma",
-    "punch",
-    "punk",
-    "pupil",
-    "puppy",
-    "purr",
-    "purse",
-    "push",
-    "putt",
-    "quack",
-    "quake",
-    "query",
-    "quiet",
-    "quill",
-    "quilt",
-    "quit",
-    "quota",
-    "quote",
-    "rabid",
-    "race",
-    "rack",
-    "radar",
-    "radio",
-    "raft",
-    "rage",
-    "raid",
-    "rail",
-    "rake",
-    "rally",
-    "ramp",
-    "ranch",
-    "range",
-    "rank",
-    "rant",
-    "rash",
-    "raven",
-    "reach",
-    "react",
-    "ream",
-    "rebel",
-    "recap",
-    "relax",
-    "relay",
-    "relic",
-    "remix",
-    "repay",
-    "repel",
-    "reply",
-    "rerun",
-    "reset",
-    "rhyme",
-    "rice",
-    "rich",
-    "ride",
-    "rigid",
-    "rigor",
-    "rinse",
-    "riot",
-    "ripen",
-    "rise",
-    "risk",
-    "ritzy",
-    "rival",
-    "river",
-    "roast",
-    "robe",
-    "robin",
-    "rock",
-    "rogue",
-    "roman",
-    "romp",
-    "rope",
-    "rover",
-    "royal",
-    "ruby",
-    "rug",
-    "ruin",
-    "rule",
-    "runny",
-    "rush",
-    "rust",
-    "rut",
-    "sadly",
-    "sage",
-    "said",
-    "saint",
-    "salad",
-    "salon",
-    "salsa",
-    "salt",
-    "same",
-    "sandy",
-    "santa",
-    "satin",
-    "sauna",
-    "saved",
-    "savor",
-    "sax",
-    "say",
-    "scale",
-    "scam",
-    "scan",
-    "scare",
-    "scarf",
-    "scary",
-    "scoff",
-    "scold",
-    "scoop",
-    "scoot",
-    "scope",
-    "score",
-    "scorn",
-    "scout",
-    "scowl",
-    "scrap",
-    "scrub",
-    "scuba",
-    "scuff",
-    "sect",
-    "sedan",
-    "self",
-    "send",
-    "sepia",
-    "serve",
-    "set",
-    "seven",
-    "shack",
-    "shade",
-    "shady",
-    "shaft",
-    "shaky",
-    "sham",
-    "shape",
-    "share",
-    "sharp",
-    "shed",
-    "sheep",
-    "sheet",
-    "shelf",
-    "shell",
-    "shine",
-    "shiny",
-    "ship",
-    "shirt",
-    "shock",
-    "shop",
-    "shore",
-    "shout",
-    "shove",
-    "shown",
-    "showy",
-    "shred",
-    "shrug",
-    "shun",
-    "shush",
-    "shut",
-    "shy",
-    "sift",
-    "silk",
-    "silly",
-    "silo",
-    "sip",
-    "siren",
-    "sixth",
-    "size",
-    "skate",
-    "skew",
-    "skid",
-    "skier",
-    "skies",
-    "skip",
-    "skirt",
-    "skit",
-    "sky",
-    "slab",
-    "slack",
-    "slain",
-    "slam",
-    "slang",
-    "slash",
-    "slate",
-    "slaw",
-    "sled",
-    "sleek",
-    "sleep",
-    "sleet",
-    "slept",
-    "slice",
-    "slick",
-    "slimy",
-    "sling",
-    "slip",
-    "slit",
-    "slob",
-    "slot",
-    "slug",
-    "slum",
-    "slurp",
-    "slush",
-    "small",
-    "smash",
-    "smell",
-    "smile",
-    "smirk",
-    "smog",
-    "snack",
-    "snap",
-    "snare",
-    "snarl",
-    "sneak",
-    "sneer",
-    "sniff",
-    "snore",
-    "snort",
-    "snout",
-    "snowy",
-    "snub",
-    "snuff",
-    "speak",
-    "speed",
-    "spend",
-    "spent",
-    "spew",
-    "spied",
-    "spill",
-    "spiny",
-    "spoil",
-    "spoke",
-    "spoof",
-    "spool",
-    "spoon",
-    "sport",
-    "spot",
-    "spout",
-    "spray",
-    "spree",
-    "spur",
-    "squad",
-    "squat",
-    "squid",
-    "stack",
-    "staff",
-    "stage",
-    "stain",
-    "stall",
-    "stamp",
-    "stand",
-    "stank",
-    "stark",
-    "start",
-    "stash",
-    "state",
-    "stays",
-    "steam",
-    "steep",
-    "stem",
-    "step",
-    "stew",
-    "stick",
-    "sting",
-    "stir",
-    "stock",
-    "stole",
-    "stomp",
-    "stony",
-    "stood",
-    "stool",
-    "stoop",
-    "stop",
-    "storm",
-    "stout",
-    "stove",
-    "straw",
-    "stray",
-    "strut",
-    "stuck",
-    "stud",
-    "stuff",
-    "stump",
-    "stung",
-    "stunt",
-    "suds",
-    "sugar",
-    "sulk",
-    "surf",
-    "sushi",
-    "swab",
-    "swan",
-    "swarm",
-    "sway",
-    "swear",
-    "sweat",
-    "sweep",
-    "swell",
-    "swept",
-    "swim",
-    "swing",
-    "swipe",
-    "swirl",
-    "swoop",
-    "swore",
-    "syrup",
-    "tacky",
-    "taco",
-    "tag",
-    "take",
-    "tall",
-    "talon",
-    "tamer",
-    "tank",
-    "taper",
-    "taps",
-    "tarot",
-    "tart",
-    "task",
-    "taste",
-    "tasty",
-    "taunt",
-    "thank",
-    "thaw",
-    "theft",
-    "theme",
-    "thigh",
-    "thing",
-    "think",
-    "third",
-    "thorn",
-    "those",
-    "throb",
-    "thud",
-    "thumb",
-    "thump",
-    "thus",
-    "tiara",
-    "tidal",
-    "tidy",
-    "tiger",
-    "tile",
-    "tilt",
-    "tint",
-    "tiny",
-    "trace",
-    "track",
-    "trade",
-    "train",
-    "trait",
-    "trap",
-    "trash",
-    "tray",
-    "treat",
-    "tree",
-    "trek",
-    "trend",
-    "trial",
-    "tribe",
-    "trick",
-    "trio",
-    "trout",
-    "truce",
-    "truck",
-    "trump",
-    "trunk",
-    "try",
-    "tug",
-    "tulip",
-    "tummy",
-    "turf",
-    "tusk",
-    "tutor",
-    "tutu",
-    "tux",
-    "tweak",
-    "tweet",
-    "twice",
-    "twine",
-    "twins",
-    "twirl",
-    "twist",
-    "uncle",
-    "uncut",
-    "undo",
-    "unify",
-    "union",
-    "unit",
-    "untie",
-    "upon",
-    "upper",
-    "urban",
-    "used",
-    "user",
-    "usher",
-    "utter",
-    "value",
-    "vapor",
-    "vegan",
-    "venue",
-    "verse",
-    "vest",
-    "veto",
-    "vice",
-    "video",
-    "view",
-    "viral",
-    "virus",
-    "visa",
-    "visor",
-    "vixen",
-    "vocal",
-    "voice",
-    "void",
-    "volt",
-    "voter",
-    "vowel",
-    "wad",
-    "wafer",
-    "wager",
-    "wages",
-    "wagon",
-    "wake",
-    "walk",
-    "wand",
-    "wasp",
-    "watch",
-    "water",
-    "wavy",
-    "wheat",
-    "whiff",
-    "whole",
-    "whoop",
-    "wick",
-    "widen",
-    "widow",
-    "width",
-    "wife",
-    "wifi",
-    "wilt",
-    "wimp",
-    "wind",
-    "wing",
-    "wink",
-    "wipe",
-    "wired",
-    "wiry",
-    "wise",
-    "wish",
-    "wispy",
-    "wok",
-    "wolf",
-    "womb",
-    "wool",
-    "woozy",
-    "word",
-    "work",
-    "worry",
-    "wound",
-    "woven",
-    "wrath",
-    "wreck",
-    "wrist",
-    "xerox",
-    "yahoo",
-    "yam",
-    "yard",
-    "year",
-    "yeast",
-    "yelp",
-    "yield",
-    "yo-yo",
-    "yodel",
-    "yoga",
-    "yoyo",
-    "yummy",
-    "zebra",
-    "zero",
-    "zesty",
-    "zippy",
-    "zone",
-    "zoom",
-};
diff --git a/bootloader/src/fileio.c b/bootloader/src/fileio.c
deleted file mode 100644
index d4c96a7..0000000
--- a/bootloader/src/fileio.c
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <efi/system-table.h>
-#include <efi/types.h>
-#include <efi/protocol/loaded-image.h>
-#include <efi/protocol/simple-file-system.h>
-
-#include <stdio.h>
-#include <xefi.h>
-
-EFIAPI efi_status efi_main(efi_handle img, efi_system_table* sys) {
-    efi_loaded_image_protocol* loaded;
-    efi_status r;
-
-    xefi_init(img, sys);
-
-    printf("Hello, EFI World\n");
-
-    r = xefi_open_protocol(img, &LoadedImageProtocol, (void**)&loaded);
-    if (r)
-        xefi_fatal("LoadedImageProtocol", r);
-
-    printf("Img DeviceHandle='%ls'\n", xefi_handle_to_str(loaded->DeviceHandle));
-    printf("Img FilePath='%ls'\n", xefi_devpath_to_str(loaded->FilePath));
-    printf("Img Base=%p Size=%lx\n", loaded->ImageBase, loaded->ImageSize);
-
-    efi_simple_file_system_protocol* sfs;
-    r = xefi_open_protocol(loaded->DeviceHandle, &SimpleFileSystemProtocol, (void**)&sfs);
-    if (r)
-        xefi_fatal("SimpleFileSystemProtocol", r);
-
-    efi_file_protocol* root;
-    r = sfs->OpenVolume(sfs, &root);
-    if (r)
-        xefi_fatal("OpenVolume", r);
-
-    efi_file_protocol* file;
-    r = root->Open(root, &file, L"README.txt", EFI_FILE_MODE_READ, 0);
-
-    if (r == EFI_SUCCESS) {
-        char buf[512];
-        size_t sz = sizeof(buf);
-        efi_file_info* finfo = (void*)buf;
-        r = file->GetInfo(file, &FileInfoGuid, &sz, finfo);
-        if (r)
-            xefi_fatal("GetInfo", r);
-        printf("FileSize %ld\n", finfo->FileSize);
-
-        sz = sizeof(buf) - 1;
-        r = file->Read(file, &sz, buf);
-        if (r)
-            xefi_fatal("Read", r);
-
-        char* x = buf;
-        while (sz-- > 0)
-            printf("%c", *x++);
-
-        file->Close(file);
-    }
-
-    root->Close(root);
-    xefi_close_protocol(loaded->DeviceHandle, &SimpleFileSystemProtocol);
-    xefi_close_protocol(img, &LoadedImageProtocol);
-
-    xefi_wait_any_key();
-
-    return EFI_SUCCESS;
-}
diff --git a/bootloader/src/framebuffer.c b/bootloader/src/framebuffer.c
deleted file mode 100644
index 9b3bcae..0000000
--- a/bootloader/src/framebuffer.c
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <framebuffer.h>
-#include <xefi.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static efi_graphics_output_protocol* fb_get_gop() {
-    static efi_graphics_output_protocol* gop = NULL;
-    if (!gop) {
-        gBS->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop);
-    }
-    return gop;
-}
-
-uint32_t get_gfx_mode() {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    return gop->Mode->Mode;
-}
-
-uint32_t get_gfx_max_mode() {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    return gop->Mode->MaxMode;
-}
-
-uint32_t get_gfx_hres() {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    efi_graphics_output_mode_information* mode_info;
-    size_t info_size = 0;
-    efi_status status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
-    if (EFI_ERROR(status)) {
-        return 0;
-    }
-    return mode_info->HorizontalResolution;
-}
-
-uint32_t get_gfx_vres() {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    efi_graphics_output_mode_information* mode_info;
-    size_t info_size = 0;
-    efi_status status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
-    if (EFI_ERROR(status)) {
-        return 0;
-    }
-    return mode_info->VerticalResolution;
-}
-
-void set_gfx_mode(uint32_t mode) {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    if (!gop)
-        return;
-    if (mode >= gop->Mode->MaxMode) {
-        printf("invalid framebuffer mode: %u\n", mode);
-        return;
-    }
-    efi_status s = gop->SetMode(gop, mode);
-    if (EFI_ERROR(s)) {
-        printf("could not set mode: %s\n", xefi_strerror(s));
-    }
-    gBS->Stall(1000);
-    gSys->ConOut->SetCursorPosition(gSys->ConOut, 0, 0);
-}
-
-void set_gfx_mode_from_cmdline(const char* fbres) {
-    if (!fbres)
-        return;
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    if (!gop)
-        return;
-
-    uint32_t hres = 0;
-    hres = atol(fbres);
-
-    char* x = strchr(fbres, 'x');
-    if (!x)
-        return;
-    x++;
-
-    uint32_t vres = 0;
-    vres = atol(x);
-    if (!hres || !vres)
-        return;
-
-    uint32_t max_mode = gop->Mode->MaxMode;
-
-    for (uint32_t i = 0; i < max_mode; i++) {
-        efi_graphics_output_mode_information* mode_info;
-        size_t info_size = 0;
-        efi_status status = gop->QueryMode(gop, i, &info_size, &mode_info);
-        if (EFI_ERROR(status)) {
-            printf("Could not retrieve mode %d: %s\n", i, xefi_strerror(status));
-            continue;
-        }
-
-        if (mode_info->HorizontalResolution == hres &&
-            mode_info->VerticalResolution == vres) {
-            set_gfx_mode(i);
-            return;
-        }
-    }
-    printf("Could not find framebuffer mode %ux%u; using default mode = %ux%u\n",
-           hres, vres, gop->Mode->Info->HorizontalResolution, gop->Mode->Info->VerticalResolution);
-    gBS->Stall(5000000);
-}
-
-void print_fb_modes() {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    uint32_t max_mode = gop->Mode->MaxMode;
-    uint32_t cur_mode = gop->Mode->Mode;
-    for (uint32_t i = 0; i < max_mode; i++) {
-        efi_graphics_output_mode_information* mode_info;
-        size_t info_size = 0;
-        efi_status status = gop->QueryMode(gop, i, &info_size, &mode_info);
-        if (EFI_ERROR(status))
-            continue;
-        printf(" (%u) %u x %u%s\n", i, mode_info->HorizontalResolution,
-               mode_info->VerticalResolution, i == cur_mode ? " (current)" : "");
-    }
-}
-
-#include "logo.h"
-
-static efi_graphics_output_blt_pixel font_white = {
-    .Red = 0xFF,
-    .Green = 0xFF,
-    .Blue = 0xFF,
-};
-
-static efi_graphics_output_blt_pixel font_black = {
-    .Red = 0x0,
-    .Green = 0x0,
-    .Blue = 0x0,
-};
-
-static efi_graphics_output_blt_pixel font_fuchsia = {
-    .Red = 0xFF,
-    .Green = 0x0,
-    .Blue = 0x80,
-};
-
-void draw_logo() {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    if (!gop)
-        return;
-
-    const uint32_t h_res = gop->Mode->Info->HorizontalResolution;
-    const uint32_t v_res = gop->Mode->Info->VerticalResolution;
-
-    // Blank the screen, removing vendor UEFI logos
-    gop->Blt(gop, &font_black, EfiBltVideoFill, 0, 0, 0, 0, h_res, v_res, 0);
-
-    efi_graphics_output_blt_pixel* tmp;
-    unsigned sz = sizeof(efi_graphics_output_blt_pixel) * logo_width * logo_height;
-    if (EFI_ERROR(gBS->AllocatePool(EfiLoaderData, sz, (void*)&tmp))) {
-        // Draw the Fuchsia stripe on the top of the screen
-        gop->Blt(gop, &font_fuchsia, EfiBltVideoFill, 0, 0, 0, 0, h_res, v_res / 100, 0);
-        return;
-    }
-
-    // Un-RLE the logo
-    unsigned char* iptr = logo_rle;
-    efi_graphics_output_blt_pixel* optr = tmp;
-    unsigned entries = sizeof(logo_rle) / 2;
-    while (entries-- > 0) {
-        unsigned count = *iptr++;
-        unsigned alpha = *iptr++;
-        efi_graphics_output_blt_pixel px = {
-            .Red = (alpha * 0xFF) / 255,
-            .Green = 0,
-            .Blue = (alpha * 0x80) / 255,
-        };
-        while (count-- > 0) {
-            *optr++ = px;
-        }
-    }
-
-    gop->Blt(gop, tmp, EfiBltBufferToVideo, 0, 0,
-             h_res - logo_width - (h_res / 75), v_res - logo_height - (v_res / 75),
-             logo_width, logo_height, 0);
-}
-
-#include <zircon/font/font-9x16.h>
-#include <zircon/font/font-18x32.h>
-
-static void putchar(efi_graphics_output_protocol* gop, fb_font* font, unsigned ch, unsigned x, unsigned y, unsigned scale_x, unsigned scale_y, efi_graphics_output_blt_pixel* fg, efi_graphics_output_blt_pixel* bg) {
-    const uint16_t* cdata = font->data + ch * font->height;
-    unsigned fw = font->width;
-    for (unsigned i = 0; i <= font->height; i++) {
-        uint16_t xdata = *cdata++;
-        for (unsigned j = 0; j < fw; j++) {
-            gop->Blt(gop, (xdata & 1) ? fg : bg, EfiBltVideoFill, 0, 0, x + scale_x * j, y + scale_y * i, scale_x, scale_y, 0);
-            xdata >>= 1;
-        }
-    }
-}
-
-void draw_text(const char* text, size_t length, fb_font* font, int x, int y) {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    efi_graphics_output_blt_pixel* fg_color = &font_white;
-    if (!gop)
-        return;
-
-    if (font->color != NULL) {
-        fg_color = font->color;
-    }
-
-    size_t offset = 0;
-    size_t scale = 1;
-    for (size_t i = 0; i < length; ++i) {
-        unsigned char c = text[i];
-        if (c > 127)
-            continue;
-        putchar(gop, font, c, x + offset, y, scale, scale, fg_color, &font_black);
-        offset += font->width * scale;
-    }
-}
-
-void draw_nodename(const char* nodename) {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    if (!gop)
-        return;
-
-    fb_font font = {
-        .data = FONT18X32,
-        .width = FONT18X32_WIDTH,
-        .height = FONT18X32_HEIGHT,
-        .color = &font_white,
-    };
-
-    const uint32_t h_res = gop->Mode->Info->HorizontalResolution;
-    const uint32_t v_res = gop->Mode->Info->VerticalResolution;
-    size_t length = strlen(nodename);
-    draw_text(nodename, length, &font, h_res - (length + 1) * font.width, v_res / 100 + font.height);
-}
-
-void draw_version(const char* version) {
-    efi_graphics_output_protocol* gop = fb_get_gop();
-    if (!gop)
-        return;
-
-    const char* prefix = "GigaBoot 20X6 - Version";
-    size_t prefix_len = strlen(prefix);
-    size_t version_len = strlen(version);
-
-    fb_font font = {
-        .data = FONT9X16,
-        .width = FONT9X16_WIDTH,
-        .height = FONT9X16_HEIGHT,
-        .color = &font_fuchsia,
-    };
-
-    draw_text(prefix, prefix_len, &font, 0, 0);
-    draw_text(version, version_len, &font, (prefix_len + 1) * font.width, 0);
-}
diff --git a/bootloader/src/framebuffer.h b/bootloader/src/framebuffer.h
deleted file mode 100644
index 0410039..0000000
--- a/bootloader/src/framebuffer.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <efi/protocol/graphics-output.h>
-#include <efi/system-table.h>
-
-// Gets the current framebuffer graphics mode.
-uint32_t get_gfx_mode(void);
-
-// Gets the maximum framebuffer graphics mode index.
-uint32_t get_gfx_max_mode(void);
-
-// Returns the horizontal or vertical resolution of the current mode.
-uint32_t get_gfx_hres(void);
-uint32_t get_gfx_vres(void);
-
-// Sets the framebuffer graphics mode.
-void set_gfx_mode(uint32_t mode);
-
-// Sets the graphics mode based on a string of the form "WxH" where W and H are
-// integers representing width and height of the mode. This is usually obtained
-// from the bootloader.fbres commandline argument.
-void set_gfx_mode_from_cmdline(const char* fbres);
-
-// Print all the supported framebuffer modes to the system console.
-void print_fb_modes(void);
-
-// Clears the screen and draws the Fuchsia logo.
-void draw_logo(void);
-
-typedef struct font_t {
-    const uint16_t* data;
-    unsigned width;
-    unsigned height;
-    efi_graphics_output_blt_pixel* color;
-} fb_font;
-
-// Draws provided text at coordinate x and y of the framebuffer.
-void draw_text(const char* text, size_t length, fb_font* font, int x, int y);
-void draw_version(const char*);
-
-// Draws nodename in appropriate location based on mode.
-void draw_nodename(const char* text);
diff --git a/bootloader/src/inet6.c b/bootloader/src/inet6.c
deleted file mode 100644
index f2f0549..0000000
--- a/bootloader/src/inet6.c
+++ /dev/null
@@ -1,465 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <inet6.h>
-#include <zircon/boot/netboot.h>
-
-// Enable at your own risk. Some of these packet errors can be fairly
-// common when the buffers start to overflow.
-#if 0
-#define BAD(n, ...)                 \
-    do {                            \
-        printf("error: ");          \
-        printf(n, ##__VA_ARGS__);   \
-        printf("\n");               \
-        return;                     \
-    } while (0)
-#else
-#define BAD(n, ...)  \
-    do {             \
-        return;      \
-    } while (0)
-#endif
-
-// useful addresses
-const ip6_addr ip6_ll_all_nodes = {
-    .x = {0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
-};
-const ip6_addr ip6_ll_all_routers = {
-    .x = {0xFF, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2},
-};
-
-// Convert MAC Address to IPv6 Link Local Address
-// aa:bb:cc:dd:ee:ff => FF80::aabb:ccFF:FEdd:eeff
-// bit 2 (U/L) of the mac is inverted
-void ll6addr_from_mac(ip6_addr* _ip, const mac_addr* _mac) {
-    uint8_t* ip = _ip->x;
-    const uint8_t* mac = _mac->x;
-    memset(ip, 0, IP6_ADDR_LEN);
-    ip[0] = 0xFE;
-    ip[1] = 0x80;
-    memset(ip + 2, 0, 6);
-    ip[8] = mac[0] ^ 2;
-    ip[9] = mac[1];
-    ip[10] = mac[2];
-    ip[11] = 0xFF;
-    ip[12] = 0xFE;
-    ip[13] = mac[3];
-    ip[14] = mac[4];
-    ip[15] = mac[5];
-}
-
-// Convert MAC Address to IPv6 Solicit Neighbor Multicast Address
-// aa:bb:cc:dd:ee:ff -> FF02::1:FFdd:eeff
-void snmaddr_from_mac(ip6_addr* _ip, const mac_addr* _mac) {
-    uint8_t* ip = _ip->x;
-    const uint8_t* mac = _mac->x;
-    ip[0] = 0xFF;
-    ip[1] = 0x02;
-    memset(ip + 2, 0, 9);
-    ip[11] = 0x01;
-    ip[12] = 0xFF;
-    ip[13] = mac[3];
-    ip[14] = mac[4];
-    ip[15] = mac[5];
-}
-
-// Convert IPv6 Multicast Address to Ethernet Multicast Address
-void multicast_from_ip6(mac_addr* _mac, const ip6_addr* _ip6) {
-    const uint8_t* ip = _ip6->x;
-    uint8_t* mac = _mac->x;
-    mac[0] = 0x33;
-    mac[1] = 0x33;
-    mac[2] = ip[12];
-    mac[3] = ip[13];
-    mac[4] = ip[14];
-    mac[5] = ip[15];
-}
-
-// ip6 stack configuration
-mac_addr ll_mac_addr;
-ip6_addr ll_ip6_addr;
-mac_addr snm_mac_addr;
-ip6_addr snm_ip6_addr;
-
-// cache for the last source addresses we've seen
-static mac_addr rx_mac_addr;
-static ip6_addr rx_ip6_addr;
-
-void ip6_init(void* macaddr) {
-    char tmp[IP6TOAMAX];
-    mac_addr all;
-
-    // save our ethernet MAC and synthesize link layer addresses
-    memcpy(&ll_mac_addr, macaddr, 6);
-    ll6addr_from_mac(&ll_ip6_addr, &ll_mac_addr);
-    snmaddr_from_mac(&snm_ip6_addr, &ll_mac_addr);
-    multicast_from_ip6(&snm_mac_addr, &snm_ip6_addr);
-
-    eth_add_mcast_filter(&snm_mac_addr);
-
-    multicast_from_ip6(&all, &ip6_ll_all_nodes);
-    eth_add_mcast_filter(&all);
-
-    printf("macaddr: %02x:%02x:%02x:%02x:%02x:%02x\n",
-           ll_mac_addr.x[0], ll_mac_addr.x[1], ll_mac_addr.x[2],
-           ll_mac_addr.x[3], ll_mac_addr.x[4], ll_mac_addr.x[5]);
-    printf("ip6addr: %s\n", ip6toa(tmp, &ll_ip6_addr));
-    printf("snmaddr: %s\n", ip6toa(tmp, &snm_ip6_addr));
-}
-
-mac_addr eth_addr(void) {
-    return ll_mac_addr;
-}
-
-static int resolve_ip6(mac_addr* _mac, const ip6_addr* _ip) {
-    const uint8_t* ip = _ip->x;
-
-    // Multicast addresses are a simple transform
-    if (ip[0] == 0xFF) {
-        multicast_from_ip6(_mac, _ip);
-        return 0;
-    }
-
-    // Trying to send to the IP that we last received a packet from?
-    // Assume their mac address has not changed
-    if (memcmp(_ip, &rx_ip6_addr, sizeof(rx_ip6_addr)) == 0) {
-        memcpy(_mac, &rx_mac_addr, sizeof(rx_mac_addr));
-        return 0;
-    }
-
-    // We don't know how to find peers or routers yet, so give up...
-    return -1;
-}
-
-static uint16_t checksum(const void* _data, size_t len, uint16_t _sum) {
-    uint32_t sum = _sum;
-    const uint16_t* data = _data;
-    while (len > 1) {
-        sum += *data++;
-        len -= 2;
-    }
-    if (len) {
-        sum += (*data & 0xFF);
-    }
-    while (sum > 0xFFFF) {
-        sum = (sum & 0xFFFF) + (sum >> 16);
-    }
-    return sum;
-}
-
-typedef struct {
-    uint8_t eth[16];
-    ip6_hdr ip6;
-    uint8_t data[0];
-} ip6_pkt;
-
-typedef struct {
-    uint8_t eth[16];
-    ip6_hdr ip6;
-    udp_hdr udp;
-    uint8_t data[0];
-} udp_pkt;
-
-static unsigned ip6_checksum(ip6_hdr* ip, unsigned type, size_t length) {
-    uint16_t sum;
-
-    // length and protocol field for pseudo-header
-    sum = checksum(&ip->length, 2, htons(type));
-    // src/dst for pseudo-header + payload
-    sum = checksum(ip->src, 32 + length, sum);
-
-    // 0 is illegal, so 0xffff remains 0xffff
-    if (sum != 0xffff) {
-        return ~sum;
-    } else {
-        return sum;
-    }
-}
-
-static int ip6_setup(ip6_pkt* p, const ip6_addr* daddr, size_t length, uint8_t type) {
-    mac_addr dmac;
-
-    if (resolve_ip6(&dmac, daddr))
-        return -1;
-
-    // ethernet header
-    memcpy(p->eth + 2, &dmac, ETH_ADDR_LEN);
-    memcpy(p->eth + 8, &ll_mac_addr, ETH_ADDR_LEN);
-    p->eth[14] = (ETH_IP6 >> 8) & 0xFF;
-    p->eth[15] = ETH_IP6 & 0xFF;
-
-    // ip6 header
-    p->ip6.ver_tc_flow = 0x60; // v=6, tc=0, flow=0
-    p->ip6.length = htons(length);
-    p->ip6.next_header = type;
-    p->ip6.hop_limit = 255;
-    memcpy(p->ip6.src, &ll_ip6_addr, sizeof(ip6_addr));
-    memcpy(p->ip6.dst, daddr, sizeof(ip6_addr));
-
-    return 0;
-}
-
-#define UDP6_MAX_PAYLOAD (ETH_MTU - ETH_HDR_LEN - IP6_HDR_LEN - UDP_HDR_LEN)
-
-int udp6_send(const void* data, size_t dlen, const ip6_addr* daddr, uint16_t dport, uint16_t sport) {
-    size_t length = dlen + UDP_HDR_LEN;
-    udp_pkt* p = eth_get_buffer(ETH_MTU + 2);
-
-    if (p == NULL)
-        return -1;
-    if (dlen > UDP6_MAX_PAYLOAD) {
-        printf("Internal error: UDP write request is too long\n");
-        goto fail;
-    }
-    if (ip6_setup((void*)p, daddr, length, HDR_UDP)) {
-        printf("Error: ip6_setup failed!\n");
-        goto fail;
-    }
-
-    // udp header
-    p->udp.src_port = htons(sport);
-    p->udp.dst_port = htons(dport);
-    p->udp.length = htons(length);
-    p->udp.checksum = 0;
-
-    memcpy(p->data, data, dlen);
-    p->udp.checksum = ip6_checksum(&p->ip6, HDR_UDP, length);
-    return eth_send(p->eth + 2, ETH_HDR_LEN + IP6_HDR_LEN + length);
-
-fail:
-    eth_put_buffer(p);
-    return -1;
-}
-
-#define ICMP6_MAX_PAYLOAD (ETH_MTU - ETH_HDR_LEN - IP6_HDR_LEN)
-
-static int icmp6_send(const void* data, size_t length, const ip6_addr* daddr) {
-    ip6_pkt* p;
-    icmp6_hdr* icmp;
-
-    p = eth_get_buffer(ETH_MTU + 2);
-    if (p == NULL)
-        return -1;
-    if (length > ICMP6_MAX_PAYLOAD) {
-        printf("Internal error: ICMP write request is too long\n");
-        goto fail;
-    }
-    if (ip6_setup(p, daddr, length, HDR_ICMP6)) {
-        printf("Error: ip6_setup failed!\n");
-        goto fail;
-    }
-
-    icmp = (void*)p->data;
-    memcpy(icmp, data, length);
-    icmp->checksum = ip6_checksum(&p->ip6, HDR_ICMP6, length);
-    return eth_send(p->eth + 2, ETH_HDR_LEN + IP6_HDR_LEN + length);
-
-fail:
-    eth_put_buffer(p);
-    return -1;
-}
-
-void udp6_recv(ip6_hdr* ip, void* _data, size_t len) {
-    udp_hdr* udp = _data;
-    uint16_t sum, n;
-
-    if (len < UDP_HDR_LEN)
-        BAD("Bogus Header Len");
-
-    if (udp->checksum == 0)
-        BAD("Missing checksum");
-
-    if (udp->checksum == 0xFFFF)
-        udp->checksum = 0;
-
-    sum = checksum(&ip->length, 2, htons(HDR_UDP));
-    sum = checksum(ip->src, 32 + len, sum);
-    if (sum != 0xFFFF)
-        BAD("Checksum Incorrect");
-
-    n = ntohs(udp->length);
-    if (n < UDP_HDR_LEN)
-        BAD("Bogus Header Len");
-    if (n > len)
-        BAD("Packet Too Short");
-    len = n - UDP_HDR_LEN;
-
-    uint16_t dport = ntohs(udp->dst_port);
-    uint16_t sport = ntohs(udp->src_port);
-
-    switch (dport) {
-    case NB_SERVER_PORT:
-        netboot_recv((uint8_t*)_data + UDP_HDR_LEN, len, (void*)ip->src, sport);
-        break;
-    case NB_TFTP_INCOMING_PORT:
-    case NB_TFTP_OUTGOING_PORT:
-        tftp_recv((uint8_t*)_data + UDP_HDR_LEN, len, (void*)ip->dst, dport, (void*)ip->src, sport);
-        break;
-    default:
-        // Ignore
-        return;
-    }
-}
-
-void icmp6_recv(ip6_hdr* ip, void* _data, size_t len) {
-    icmp6_hdr* icmp = _data;
-    uint16_t sum;
-
-    if (icmp->checksum == 0)
-        BAD("Checksum Invalid");
-    if (icmp->checksum == 0xFFFF)
-        icmp->checksum = 0;
-
-    sum = checksum(&ip->length, 2, htons(HDR_ICMP6));
-    sum = checksum(ip->src, 32 + len, sum);
-    if (sum != 0xFFFF)
-        BAD("Checksum Incorrect");
-
-    if (icmp->type == ICMP6_NDP_N_SOLICIT) {
-        ndp_n_hdr* ndp = _data;
-        struct {
-            ndp_n_hdr hdr;
-            uint8_t opt[8];
-        } msg;
-
-        if (len < sizeof(ndp_n_hdr))
-            BAD("Bogus NDP Message");
-        if (ndp->code != 0)
-            BAD("Bogus NDP Code");
-        if (memcmp(ndp->target, &ll_ip6_addr, IP6_ADDR_LEN))
-            BAD("NDP Not For Me");
-
-        msg.hdr.type = ICMP6_NDP_N_ADVERTISE;
-        msg.hdr.code = 0;
-        msg.hdr.checksum = 0;
-        msg.hdr.flags = 0x60; // (S)olicited and (O)verride flags
-        memcpy(msg.hdr.target, &ll_ip6_addr, IP6_ADDR_LEN);
-        msg.opt[0] = NDP_N_TGT_LL_ADDR;
-        msg.opt[1] = 1;
-        memcpy(msg.opt + 2, &ll_mac_addr, ETH_ADDR_LEN);
-
-        icmp6_send(&msg, sizeof(msg), (void*)ip->src);
-        return;
-    }
-
-    if (icmp->type == ICMP6_ECHO_REQUEST) {
-        icmp->checksum = 0;
-        icmp->type = ICMP6_ECHO_REPLY;
-        icmp6_send(_data, len, (void*)ip->src);
-        return;
-    }
-
-    BAD("ICMP6 Unhandled %d", icmp->type);
-}
-
-void eth_recv(void* _data, size_t len) {
-    uint8_t* data = _data;
-    ip6_hdr* ip;
-    uint32_t n;
-
-    if (len < (ETH_HDR_LEN + IP6_HDR_LEN))
-        BAD("Bogus Header Len");
-    if (data[12] != (ETH_IP6 >> 8) || data[13] != (ETH_IP6 & 0xFF))
-        BAD("Not IP6");
-
-    ip = (void*)(data + ETH_HDR_LEN);
-    data += (ETH_HDR_LEN + IP6_HDR_LEN);
-    len -= (ETH_HDR_LEN + IP6_HDR_LEN);
-
-    // require v6
-    if ((ip->ver_tc_flow & 0xF0) != 0x60)
-        BAD("Unknown IP6 Version");
-
-    // ensure length is sane
-    n = ntohs(ip->length);
-    if (n > len)
-        BAD("IP6 Length Mismatch %d %zu", n, len);
-
-    // ignore any trailing data in the ethernet frame
-    len = n;
-
-    // require that we are the destination
-    if (memcmp(&ll_ip6_addr, ip->dst, IP6_ADDR_LEN) &&
-        memcmp(&snm_ip6_addr, ip->dst, IP6_ADDR_LEN) &&
-        memcmp(&ip6_ll_all_nodes, ip->dst, IP6_ADDR_LEN)) {
-        return;
-    }
-
-    // stash the sender's info to simplify replies
-    memcpy(&rx_mac_addr, (uint8_t*)_data + 6, ETH_ADDR_LEN);
-    memcpy(&rx_ip6_addr, ip->src, IP6_ADDR_LEN);
-
-    if (ip->next_header == HDR_ICMP6) {
-        icmp6_recv(ip, data, len);
-        return;
-    }
-
-    if (ip->next_header == HDR_UDP) {
-        udp6_recv(ip, data, len);
-        return;
-    }
-
-    BAD("Unhandled IP6 %d", ip->next_header);
-}
-
-char* ip6toa(char* _out, void* ip6addr) {
-    const uint8_t* x = ip6addr;
-    const uint8_t* end = x + 16;
-    char* out = _out;
-    uint16_t n;
-
-    n = (x[0] << 8) | x[1];
-    while ((n == 0) && (x < end)) {
-        x += 2;
-        n = (x[0] << 8) | x[1];
-    }
-
-    if ((end - x) < 16) {
-        if (end == x) {
-            // all 0s - special case
-            sprintf(out, "::");
-            return _out;
-        }
-        // we consumed some number of leading 0s
-        out += sprintf(out, ":");
-        while (x < end) {
-            out += sprintf(out, ":%x", n);
-            x += 2;
-            n = (x[0] << 8) | x[1];
-        }
-        return _out;
-    }
-
-    while (x < (end - 2)) {
-        out += sprintf(out, "%x:", n);
-        x += 2;
-        n = (x[0] << 8) | x[1];
-        if (n == 0)
-            goto middle_zeros;
-    }
-    out += sprintf(out, "%x", n);
-    return _out;
-
-middle_zeros:
-    while ((n == 0) && (x < end)) {
-        x += 2;
-        n = (x[0] << 8) | x[1];
-    }
-    if (x == end) {
-        out += sprintf(out, ":");
-        return _out;
-    }
-    out += sprintf(out, ":%x", n);
-    while (x < (end - 2)) {
-        x += 2;
-        n = (x[0] << 8) | x[1];
-        out += sprintf(out, ":%x", n);
-    }
-    return _out;
-}
diff --git a/bootloader/src/inet6.h b/bootloader/src/inet6.h
deleted file mode 100644
index 43de05e..0000000
--- a/bootloader/src/inet6.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-
-typedef struct mac_addr_t mac_addr;
-typedef struct ip6_addr_t ip6_addr;
-typedef struct ip6_hdr_t ip6_hdr;
-typedef struct udp_hdr_t udp_hdr;
-typedef struct icmp6_hdr_t icmp6_hdr;
-typedef struct ndp_n_hdr_t ndp_n_hdr;
-
-#define ETH_ADDR_LEN 6
-#define ETH_HDR_LEN 14
-#define ETH_MTU 1514
-
-#define IP6_ADDR_LEN 16
-#define IP6_HDR_LEN 40
-
-#define IP6_MIN_MTU 1280
-
-#define UDP_HDR_LEN 8
-
-struct mac_addr_t {
-    uint8_t x[ETH_ADDR_LEN];
-} __attribute__((packed));
-
-struct ip6_addr_t {
-    uint8_t x[IP6_ADDR_LEN];
-} __attribute__((packed));
-
-extern const ip6_addr ip6_ll_all_nodes;
-extern const ip6_addr ip6_ll_all_routers;
-
-#define ETH_IP4 0x0800
-#define ETH_ARP 0x0806
-#define ETH_IP6 0x86DD
-
-#define HDR_HNH_OPT 0
-#define HDR_TCP 6
-#define HDR_UDP 17
-#define HDR_ROUTING 43
-#define HDR_FRAGMENT 44
-#define HDR_ICMP6 58
-#define HDR_NONE 59
-#define HDR_DST_OPT 60
-
-struct ip6_hdr_t {
-    uint32_t ver_tc_flow;
-    uint16_t length;
-    uint8_t next_header;
-    uint8_t hop_limit;
-    uint8_t src[IP6_ADDR_LEN];
-    uint8_t dst[IP6_ADDR_LEN];
-} __attribute__((packed));
-
-struct udp_hdr_t {
-    uint16_t src_port;
-    uint16_t dst_port;
-    uint16_t length;
-    uint16_t checksum;
-} __attribute__((packed));
-
-#define ICMP6_DEST_UNREACHABLE 1
-#define ICMP6_PACKET_TOO_BIG 2
-#define ICMP6_TIME_EXCEEDED 3
-#define ICMP6_PARAMETER_PROBLEM 4
-
-#define ICMP6_ECHO_REQUEST 128
-#define ICMP6_ECHO_REPLY 129
-
-#define ICMP6_NDP_N_SOLICIT 135
-#define ICMP6_NDP_N_ADVERTISE 136
-
-struct icmp6_hdr_t {
-    uint8_t type;
-    uint8_t code;
-    uint16_t checksum;
-} __attribute__((packed));
-
-struct ndp_n_hdr_t {
-    uint8_t type;
-    uint8_t code;
-    uint16_t checksum;
-    uint32_t flags;
-    uint8_t target[IP6_ADDR_LEN];
-    uint8_t options[0];
-} __attribute__((packed));
-
-#define NDP_N_SRC_LL_ADDR 1
-#define NDP_N_TGT_LL_ADDR 2
-#define NDP_N_PREFIX_INFO 3
-#define NDP_N_REDIRECTED_HDR 4
-#define NDP_N_MTU 5
-
-#ifndef ntohs
-#define ntohs(n) _swap16(n)
-#define htons(n) _swap16(n)
-static inline uint16_t _swap16(uint16_t n) {
-    return (n >> 8) | (n << 8);
-}
-#endif
-
-#ifndef ntohl
-#define ntohl(n) _swap32(n)
-#define htonl(n) _swap32(n)
-static inline uint32_t _swap32(uint32_t n) {
-    return (n >> 24) | ((n >> 8) & 0xFF00) |
-           ((n & 0xFF00) << 8) | (n << 24);
-}
-#endif
-
-// Formats an IP6 address into the provided buffer (which must be
-// at least IP6TOAMAX bytes in size), and returns the buffer address.
-char* ip6toa(char* _out, void* ip6addr);
-#define IP6TOAMAX 40
-
-// provided by inet6.c
-void ip6_init(void* macaddr);
-void eth_recv(void* data, size_t len);
-mac_addr eth_addr(void);
-
-// provided by interface driver
-void* eth_get_buffer(size_t len);
-void eth_put_buffer(void* ptr);
-int eth_send(void* data, size_t len);
-int eth_add_mcast_filter(const mac_addr* addr);
-
-// call to transmit a UDP packet
-int udp6_send(const void* data, size_t len,
-              const ip6_addr* daddr, uint16_t dport,
-              uint16_t sport);
-
-// handle a netboot UDP packet
-void netboot_recv(void* data, size_t len, const ip6_addr* saddr, uint16_t sport);
-
-// handle a TFTP (over UDP) packet
-void tftp_recv (void* data, size_t len, const ip6_addr* daddr, uint16_t dport,
-                const ip6_addr* saddr, uint16_t sport);
-
-// NOTES
-//
-// This is an extremely minimal IPv6 stack, supporting just enough
-// functionality to talk to link local hosts over UDP.
-//
-// It responds to ICMPv6 Neighbor Solicitations for its link local
-// address, which is computed from the mac address provided by the
-// ethernet interface driver.
-//
-// It responds to PINGs.
-//
-// It can only transmit to multicast addresses or to the address it
-// last received a packet from (general usecase is to reply to a UDP
-// packet from the UDP callback, which this supports)
-//
-// It does not currently do duplicate address detection, which is
-// probably the most severe bug.
-//
-// It does not support any IPv6 options and will drop packets with
-// options.
-//
-// It expects the network stack to provide transmit buffer allocation
-// and free functionality.  It will allocate a single transmit buffer
-// from udp6_send() or icmp6_send() to fill out and either pass to the
-// network stack via eth_send() or, in the event of an error, release
-// via eth_put_buffer().
-//
diff --git a/bootloader/src/logo.h b/bootloader/src/logo.h
deleted file mode 100644
index 08bb465..0000000
--- a/bootloader/src/logo.h
+++ /dev/null
@@ -1,1031 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-static unsigned logo_width = 512;
-static unsigned logo_height = 512;
-static unsigned char logo_rle[] = {
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0x3c,0x00,0x01,0x06,0x01,0x1f,0x01,0x36,0x01,0x49,0x01,0x5e,0x01,0x74,
-0x01,0x88,0x01,0x98,0x01,0xa6,0x01,0xb4,0x01,0xc2,0x01,0xd0,0x02,0xe0,0x01,0xef,
-0x01,0xf0,0x01,0xfe,0x08,0xff,0x01,0xf3,0x01,0xf0,0x01,0xed,0x01,0xe0,0x01,0xd3,
-0x01,0xc9,0x01,0xbf,0x01,0xb0,0x01,0xa0,0x01,0x8d,0x01,0x7b,0x01,0x69,0x01,0x57,
-0x01,0x40,0x01,0x27,0x01,0x0e,0xff,0x00,0xd0,0x00,0x01,0x10,0x01,0x31,0x01,0x53,
-0x01,0x75,0x01,0x96,0x01,0xb3,0x01,0xcd,0x01,0xe9,0x29,0xff,0x01,0xf6,0x01,0xdc,
-0x01,0xbf,0x01,0xa0,0x01,0x80,0x01,0x62,0x01,0x42,0x01,0x1f,0x01,0x01,0xff,0x00,
-0xc0,0x00,0x01,0x02,0x01,0x23,0x01,0x4d,0x01,0x75,0x01,0x9e,0x01,0xc6,0x01,0xee,
-0x39,0xff,0x01,0xf7,0x01,0xd2,0x01,0xad,0x01,0x87,0x01,0x5d,0x01,0x30,0x01,0x07,
-0xff,0x00,0xb5,0x00,0x01,0x0a,0x01,0x3a,0x01,0x69,0x01,0x98,0x01,0xc7,0x01,0xf5,
-0x45,0xff,0x01,0xfc,0x01,0xd7,0x01,0xaa,0x01,0x78,0x01,0x45,0x01,0x12,0xff,0x00,
-0xab,0x00,0x01,0x02,0x01,0x2d,0x01,0x64,0x01,0x99,0x01,0xd0,0x01,0xfc,0x50,0xff,
-0x01,0xdf,0x01,0xad,0x01,0x74,0x01,0x3a,0x01,0x08,0xff,0x00,0xa2,0x00,0x01,0x08,
-0x01,0x3c,0x01,0x79,0x01,0xb7,0x01,0xf1,0x59,0xff,0x01,0xf9,0x01,0xc7,0x01,0x8c,
-0x01,0x4c,0x01,0x0f,0xff,0x00,0x9a,0x00,0x01,0x03,0x01,0x36,0x01,0x7b,0x01,0xbe,
-0x01,0xf8,0x61,0xff,0x01,0xfd,0x01,0xcc,0x01,0x8c,0x01,0x4a,0x01,0x0a,0xff,0x00,
-0x93,0x00,0x01,0x1c,0x01,0x65,0x01,0xaf,0x01,0xf0,0x69,0xff,0x01,0xf8,0x01,0xbc,
-0x01,0x74,0x01,0x2e,0xff,0x00,0x8c,0x00,0x01,0x02,0x01,0x3b,0x01,0x86,0x01,0xd0,
-0x71,0xff,0x01,0xe3,0x01,0x95,0x01,0x47,0x01,0x07,0xff,0x00,0x85,0x00,0x01,0x05,
-0x01,0x47,0x01,0x98,0x01,0xe7,0x77,0xff,0x01,0xf3,0x01,0xab,0x01,0x58,0x01,0x0c,
-0xff,0x00,0x7f,0x00,0x01,0x05,0x01,0x48,0x01,0xa2,0x01,0xef,0x2d,0xff,0x01,0xf7,
-0x01,0xe2,0x01,0xcc,0x01,0xb8,0x01,0xa4,0x01,0x94,0x01,0x86,0x01,0x78,0x01,0x6a,
-0x01,0x60,0x02,0x50,0x01,0x41,0x01,0x40,0x01,0x32,0x05,0x30,0x01,0x33,0x02,0x40,
-0x01,0x43,0x01,0x50,0x01,0x5a,0x01,0x65,0x01,0x70,0x01,0x7f,0x01,0x8c,0x01,0x9e,
-0x01,0xb2,0x01,0xc3,0x01,0xd5,0x01,0xea,0x2d,0xff,0x01,0xf7,0x01,0xad,0x01,0x58,
-0x01,0x0c,0xff,0x00,0x79,0x00,0x01,0x02,0x01,0x3e,0x01,0x98,0x01,0xeb,0x27,0xff,
-0x01,0xfa,0x01,0xda,0x01,0xb7,0x01,0x96,0x01,0x79,0x01,0x5d,0x01,0x43,0x01,0x27,
-0x01,0x0b,0x23,0x00,0x01,0x06,0x01,0x1c,0x01,0x37,0x01,0x4f,0x01,0x6e,0x01,0x8c,
-0x01,0xac,0x01,0xcc,0x01,0xec,0x27,0xff,0x01,0xf7,0x01,0xa9,0x01,0x4c,0x01,0x05,
-0xff,0x00,0x74,0x00,0x01,0x23,0x01,0x82,0x01,0xe0,0x24,0xff,0x01,0xe3,0x01,0xbc,
-0x01,0x92,0x01,0x6b,0x01,0x41,0x01,0x1e,0x01,0x02,0x34,0x00,0x01,0x11,0x01,0x37,
-0x01,0x5d,0x01,0x83,0x01,0xab,0x01,0xd8,0x01,0xfc,0x23,0xff,0x01,0xec,0x01,0x95,
-0x01,0x36,0xff,0x00,0x6f,0x00,0x01,0x0b,0x01,0x62,0x01,0xc2,0x21,0xff,0x01,0xfa,
-0x01,0xcd,0x01,0x9e,0x01,0x6f,0x01,0x3f,0x01,0x10,0x41,0x00,0x01,0x08,0x01,0x30,
-0x01,0x5e,0x01,0x8e,0x01,0xc2,0x01,0xf3,0x21,0xff,0x01,0xd3,0x01,0x70,0x01,0x14,
-0xff,0x00,0x6a,0x00,0x01,0x2d,0x01,0x96,0x01,0xf2,0x1f,0xff,0x01,0xd9,0x01,0xa4,
-0x01,0x6d,0x01,0x37,0x01,0x07,0x4b,0x00,0x01,0x02,0x01,0x28,0x01,0x5b,0x01,0x94,
-0x01,0xce,0x01,0xfc,0x1e,0xff,0x01,0xf9,0x01,0xaa,0x01,0x41,0x01,0x01,0xff,0x00,
-0x64,0x00,0x01,0x06,0x01,0x5e,0x01,0xc6,0x1d,0xff,0x01,0xfc,0x01,0xcc,0x01,0x90,
-0x01,0x53,0x01,0x16,0x55,0x00,0x01,0x0b,0x01,0x41,0x01,0x7c,0x01,0xbc,0x01,0xf8,
-0x1d,0xff,0x01,0xd6,0x01,0x6c,0x01,0x0e,0xff,0x00,0x60,0x00,0x01,0x17,0x01,0x81,
-0x01,0xe9,0x1c,0xff,0x01,0xd5,0x01,0x92,0x01,0x4f,0x01,0x0f,0x5d,0x00,0x01,0x08,
-0x01,0x40,0x01,0x80,0x01,0xc5,0x01,0xfd,0x1b,0xff,0x01,0xf4,0x01,0x95,0x01,0x26,
-0xff,0x00,0x5c,0x00,0x01,0x30,0x01,0xa3,0x01,0xfa,0x1a,0xff,0x01,0xf2,0x01,0xac,
-0x01,0x61,0x01,0x1a,0x65,0x00,0x01,0x10,0x01,0x53,0x01,0x9b,0x01,0xe3,0x1a,0xff,
-0x01,0xfe,0x01,0xb2,0x01,0x40,0xff,0x00,0x58,0x00,0x01,0x43,0x01,0xb9,0x1a,0xff,
-0x01,0xdd,0x01,0x8e,0x01,0x41,0x01,0x05,0x6b,0x00,0x01,0x01,0x01,0x31,0x01,0x80,
-0x01,0xce,0x1a,0xff,0x01,0xce,0x01,0x58,0x01,0x03,0xff,0x00,0x52,0x00,0x01,0x02,
-0x01,0x56,0x01,0xcc,0x19,0xff,0x01,0xd3,0x01,0x81,0x01,0x2f,0x73,0x00,0x01,0x1d,
-0x01,0x6d,0x01,0xc3,0x01,0xfe,0x18,0xff,0x01,0xdc,0x01,0x66,0x01,0x06,0xff,0x00,
-0x4e,0x00,0x01,0x02,0x01,0x58,0x01,0xd6,0x18,0xff,0x01,0xd8,0x01,0x81,0x01,0x28,
-0x79,0x00,0x01,0x1a,0x01,0x6d,0x01,0xc6,0x18,0xff,0x01,0xe6,0x01,0x70,0x01,0x09,
-0xff,0x00,0x4a,0x00,0x01,0x03,0x01,0x60,0x01,0xd7,0x17,0xff,0x01,0xe7,0x01,0x8a,
-0x01,0x33,0x7f,0x00,0x01,0x22,0x01,0x7e,0x01,0xda,0x17,0xff,0x01,0xe7,0x01,0x70,
-0x01,0x09,0xff,0x00,0x46,0x00,0x01,0x01,0x01,0x53,0x01,0xd6,0x16,0xff,0x01,0xf9,
-0x01,0xaa,0x01,0x4a,0x01,0x03,0x84,0x00,0x01,0x36,0x01,0x98,0x01,0xf2,0x16,0xff,
-0x01,0xe7,0x01,0x6d,0x01,0x06,0xff,0x00,0x43,0x00,0x01,0x48,0x01,0xce,0x16,0xff,
-0x01,0xd6,0x01,0x6e,0x01,0x11,0x89,0x00,0x01,0x0a,0x01,0x5e,0x01,0xc2,0x16,0xff,
-0x01,0xde,0x01,0x5c,0x01,0x02,0xff,0x00,0x3f,0x00,0x01,0x33,0x01,0xbf,0x15,0xff,
-0x01,0xf8,0x01,0xa3,0x01,0x3d,0x8f,0x00,0x01,0x2a,0x01,0x93,0x01,0xf2,0x15,0xff,
-0x01,0xd1,0x01,0x4b,0xff,0x00,0x3c,0x00,0x01,0x1d,0x01,0xa3,0x01,0xfe,0x14,0xff,
-0x01,0xe5,0x01,0x7b,0x01,0x15,0x93,0x00,0x01,0x0c,0x01,0x68,0x01,0xd3,0x15,0xff,
-0x01,0xbd,0x01,0x2e,0xff,0x00,0x38,0x00,0x01,0x0b,0x01,0x87,0x01,0xf7,0x14,0xff,
-0x01,0xc7,0x01,0x58,0x01,0x05,0x97,0x00,0x01,0x01,0x01,0x45,0x01,0xb7,0x14,0xff,
-0x01,0xfd,0x01,0x9b,0x01,0x17,0xff,0x00,0x34,0x00,0x01,0x01,0x01,0x5a,0x01,0xe5,
-0x14,0xff,0x01,0xb3,0x01,0x3c,0x9d,0x00,0x01,0x2a,0x01,0x9b,0x01,0xfa,0x13,0xff,
-0x01,0xf3,0x01,0x77,0x01,0x06,0xff,0x00,0x31,0x00,0x01,0x31,0x01,0xc3,0x13,0xff,
-0x01,0xfa,0x01,0x9e,0x01,0x2a,0xa1,0x00,0x01,0x1b,0x01,0x8e,0x01,0xf4,0x13,0xff,
-0x01,0xd8,0x01,0x45,0xff,0x00,0x2e,0x00,0x01,0x0e,0x01,0x90,0x01,0xfd,0x12,0xff,
-0x01,0xfa,0x01,0x98,0x01,0x1e,0xa5,0x00,0x01,0x14,0x01,0x80,0x01,0xf0,0x13,0xff,
-0x01,0xab,0x01,0x1d,0xff,0x00,0x2b,0x00,0x01,0x54,0x01,0xe4,0x12,0xff,0x01,0xf7,
-0x01,0x93,0x01,0x1e,0xa9,0x00,0x01,0x10,0x01,0x80,0x01,0xf0,0x12,0xff,0x01,0xf3,
-0x01,0x6f,0x01,0x03,0xff,0x00,0x27,0x00,0x01,0x1e,0x01,0xb4,0x12,0xff,0x01,0xfc,
-0x01,0x9a,0x01,0x1d,0xad,0x00,0x01,0x10,0x01,0x80,0x01,0xf4,0x12,0xff,0x01,0xcb,
-0x01,0x31,0xff,0x00,0x24,0x00,0x01,0x01,0x01,0x69,0x01,0xf2,0x11,0xff,0x01,0xfe,
-0x01,0xa7,0x01,0x24,0xb1,0x00,0x01,0x15,0x01,0x91,0x01,0xfa,0x11,0xff,0x01,0xfc,
-0x01,0x8a,0x01,0x08,0xff,0x00,0x21,0x00,0x01,0x25,0x01,0xbf,0x12,0xff,0x01,0xbc,
-0x01,0x2f,0xb5,0x00,0x01,0x20,0x01,0xa3,0x01,0xfe,0x11,0xff,0x01,0xd8,0x01,0x38,
-0xff,0x00,0x1e,0x00,0x01,0x01,0x01,0x6e,0x01,0xf6,0x11,0xff,0x01,0xd4,0x01,0x4a,
-0xb9,0x00,0x01,0x32,0x01,0xc0,0x11,0xff,0x01,0xfd,0x01,0x8b,0x01,0x08,0xff,0x00,
-0x1b,0x00,0x01,0x1d,0x01,0xbc,0x11,0xff,0x01,0xec,0x01,0x67,0x01,0x04,0xbc,0x00,
-0x01,0x51,0x01,0xdc,0x11,0xff,0x01,0xd8,0x01,0x33,0xff,0x00,0x19,0x00,0x01,0x5c,
-0x01,0xf0,0x10,0xff,0x01,0xfc,0x01,0x93,0x01,0x11,0xbf,0x00,0x01,0x06,0x01,0x78,
-0x01,0xf5,0x10,0xff,0x01,0xfb,0x01,0x7c,0x01,0x03,0xff,0x00,0x15,0x00,0x01,0x0f,
-0x01,0xa7,0x11,0xff,0x01,0xc0,0x01,0x2d,0xc3,0x00,0x01,0x1b,0x01,0xa8,0x11,0xff,
-0x01,0xc6,0x01,0x23,0xff,0x00,0x13,0x00,0x01,0x39,0x01,0xde,0x10,0xff,0x01,0xeb,
-0x01,0x5f,0x01,0x01,0xc6,0x00,0x01,0x42,0x01,0xd8,0x10,0xff,0x01,0xf3,0x01,0x59,
-0xff,0x00,0x10,0x00,0x01,0x02,0x01,0x7a,0x01,0xfc,0x10,0xff,0x01,0x9c,0x01,0x13,
-0xc9,0x00,0x01,0x07,0x01,0x81,0x01,0xf9,0x10,0xff,0x01,0x9d,0x01,0x0b,0xff,0x00,
-0x0d,0x00,0x01,0x14,0x01,0xba,0x10,0xff,0x01,0xdb,0x01,0x3e,0xcd,0x00,0x01,0x29,
-0x01,0xc3,0x10,0xff,0x01,0xd6,0x01,0x2d,0xff,0x00,0x0b,0x00,0x01,0x39,0x01,0xe4,
-0x0f,0xff,0x01,0xfd,0x01,0x8b,0x01,0x09,0xcf,0x00,0x01,0x01,0x01,0x6b,0x01,0xf4,
-0x0f,0xff,0x01,0xf6,0x01,0x5e,0xff,0x00,0x09,0x00,0x01,0x71,0x01,0xfb,0x0f,0xff,
-0x01,0xd4,0x01,0x35,0xd3,0x00,0x01,0x21,0x01,0xbf,0x10,0xff,0x01,0x98,0x01,0x07,
-0xff,0x00,0x05,0x00,0x01,0x0a,0x01,0xa6,0x0f,0xff,0x01,0xfe,0x01,0x8c,0x01,0x08,
-0xd5,0x00,0x01,0x01,0x01,0x6b,0x01,0xf4,0x0f,0xff,0x01,0xcb,0x01,0x1f,0xff,0x00,
-0x03,0x00,0x01,0x20,0x01,0xd0,0x0f,0xff,0x01,0xdf,0x01,0x3f,0xd9,0x00,0x01,0x25,
-0x01,0xc9,0x0f,0xff,0x01,0xeb,0x01,0x3f,0xff,0x00,0x01,0x00,0x01,0x43,0x01,0xed,
-0x0f,0xff,0x01,0xa2,0x01,0x0e,0xdb,0x00,0x01,0x04,0x01,0x80,0x01,0xfc,0x0e,0xff,
-0x01,0xfb,0x01,0x6a,0xfe,0x00,0x01,0x6a,0x01,0xfc,0x0e,0xff,0x01,0xf2,0x01,0x5b,
-0xdf,0x00,0x01,0x38,0x01,0xdf,0x0f,0xff,0x01,0x9a,0x01,0x06,0xfa,0x00,0x01,0x03,
-0x01,0x93,0x0f,0xff,0x01,0xc9,0x01,0x23,0x6b,0x00,0x01,0x10,0x01,0x1a,0x07,0x20,
-0x01,0x1a,0x01,0x10,0x01,0x01,0x6a,0x00,0x01,0x10,0x01,0xab,0x0f,0xff,0x01,0xc0,
-0x01,0x12,0xf8,0x00,0x01,0x0f,0x01,0xb8,0x0f,0xff,0x01,0x8f,0x01,0x05,0x5f,0x00,
-0x01,0x10,0x01,0x29,0x01,0x45,0x01,0x5e,0x01,0x78,0x01,0x93,0x01,0xab,0x01,0xbd,
-0x01,0xcb,0x01,0xd8,0x01,0xe6,0x01,0xf3,0x0d,0xff,0x01,0xf9,0x01,0xf0,0x01,0xe0,
-0x01,0xd8,0x01,0xc8,0x01,0xb1,0x01,0x99,0x01,0x83,0x01,0x6a,0x01,0x55,0x01,0x3b,
-0x01,0x24,0x01,0x05,0x5f,0x00,0x01,0x68,0x01,0xf7,0x0e,0xff,0x01,0xd9,0x01,0x25,
-0xf6,0x00,0x01,0x1c,0x01,0xd3,0x0e,0xff,0x01,0xf1,0x01,0x52,0x5a,0x00,0x01,0x11,
-0x01,0x38,0x01,0x5f,0x01,0x84,0x01,0xac,0x01,0xd2,0x01,0xf6,0x25,0xff,0x01,0xfc,
-0x01,0xdd,0x01,0xbb,0x01,0x95,0x01,0x71,0x01,0x4f,0x01,0x2b,0x01,0x06,0x59,0x00,
-0x01,0x2f,0x01,0xdd,0x0e,0xff,0x01,0xed,0x01,0x3d,0xf4,0x00,0x01,0x2e,0x01,0xe4,
-0x0e,0xff,0x01,0xd0,0x01,0x23,0x55,0x00,0x01,0x01,0x01,0x25,0x01,0x58,0x01,0x8b,
-0x01,0xbe,0x01,0xec,0x33,0xff,0x01,0xfb,0x01,0xd3,0x01,0xa6,0x01,0x78,0x01,0x45,
-0x01,0x12,0x55,0x00,0x01,0x10,0x01,0xb1,0x0e,0xff,0x01,0xfa,0x01,0x56,0xf2,0x00,
-0x01,0x43,0x01,0xf1,0x0e,0xff,0x01,0xa3,0x01,0x09,0x52,0x00,0x01,0x18,0x01,0x57,
-0x01,0x8b,0x01,0xbe,0x01,0xf1,0x3e,0xff,0x01,0xde,0x01,0xa9,0x01,0x6e,0x01,0x34,
-0x01,0x04,0x51,0x00,0x01,0x01,0x01,0x78,0x01,0xfd,0x0e,0xff,0x01,0x70,0xf0,0x00,
-0x01,0x57,0x01,0xfa,0x0d,0xff,0x01,0xfd,0x01,0x73,0x50,0x00,0x01,0x18,0x01,0x58,
-0x01,0x98,0x01,0xd8,0x47,0xff,0x01,0xf5,0x01,0xbc,0x01,0x7b,0x01,0x38,0x01,0x04,
-0x4f,0x00,0x01,0x46,0x01,0xef,0x0e,0xff,0x01,0x8c,0x01,0x01,0xed,0x00,0x01,0x68,
-0x01,0xfd,0x0d,0xff,0x01,0xed,0x01,0x43,0x4d,0x00,0x01,0x08,0x01,0x4b,0x01,0x96,
-0x01,0xd8,0x4f,0xff,0x01,0xf3,0x01,0xb1,0x01,0x69,0x01,0x22,0x4d,0x00,0x01,0x24,
-0x01,0xd6,0x0e,0xff,0x01,0xa3,0x01,0x03,0xeb,0x00,0x01,0x7c,0x0e,0xff,0x01,0xd7,
-0x01,0x23,0x4b,0x00,0x01,0x18,0x01,0x63,0x01,0xb0,0x01,0xf5,0x56,0xff,0x01,0xd8,
-0x01,0x8a,0x01,0x3b,0x01,0x02,0x4a,0x00,0x01,0x0d,0x01,0xb2,0x0e,0xff,0x01,0xb2,
-0x01,0x07,0xe8,0x00,0x01,0x01,0x01,0x8d,0x0e,0xff,0x01,0xba,0x01,0x10,0x49,0x00,
-0x01,0x28,0x01,0x7b,0x01,0xc9,0x01,0xfe,0x5c,0xff,0x01,0xea,0x01,0x98,0x01,0x43,
-0x01,0x03,0x48,0x00,0x01,0x03,0x01,0x8c,0x0e,0xff,0x01,0xbe,0x01,0x0c,0xe6,0x00,
-0x01,0x01,0x01,0x97,0x0e,0xff,0x01,0x96,0x01,0x04,0x47,0x00,0x01,0x20,0x01,0x78,
-0x01,0xcd,0x63,0xff,0x01,0xea,0x01,0x98,0x01,0x3b,0x01,0x01,0x47,0x00,0x01,0x67,
-0x01,0xfc,0x0d,0xff,0x01,0xc9,0x01,0x0f,0xe4,0x00,0x01,0x03,0x01,0x99,0x0e,0xff,
-0x01,0x75,0x46,0x00,0x01,0x0e,0x01,0x61,0x01,0xc0,0x01,0xfe,0x68,0xff,0x01,0xde,
-0x01,0x81,0x01,0x23,0x46,0x00,0x01,0x46,0x01,0xf1,0x0d,0xff,0x01,0xca,0x01,0x15,
-0xe2,0x00,0x01,0x03,0x01,0xa5,0x0d,0xff,0x01,0xfa,0x01,0x58,0x45,0x00,0x01,0x3a,
-0x01,0xa0,0x01,0xf6,0x6e,0xff,0x01,0xbd,0x01,0x5a,0x01,0x07,0x44,0x00,0x01,0x2f,
-0x01,0xe6,0x0d,0xff,0x01,0xd3,0x01,0x15,0xe0,0x00,0x01,0x03,0x01,0xa5,0x0d,0xff,
-0x01,0xf1,0x01,0x40,0x43,0x00,0x01,0x0e,0x01,0x6d,0x01,0xd5,0x73,0xff,0x01,0xee,
-0x01,0x8b,0x01,0x21,0x43,0x00,0x01,0x1f,0x01,0xd8,0x0d,0xff,0x01,0xd3,0x01,0x15,
-0xde,0x00,0x01,0x01,0x01,0xa3,0x0d,0xff,0x01,0xe9,0x01,0x2e,0x42,0x00,0x01,0x28,
-0x01,0x94,0x01,0xf3,0x77,0xff,0x01,0xfe,0x01,0xb3,0x01,0x46,0x01,0x01,0x41,0x00,
-0x01,0x13,0x01,0xc5,0x0d,0xff,0x01,0xd3,0x01,0x15,0xdc,0x00,0x01,0x01,0x01,0x97,
-0x0d,0xff,0x01,0xde,0x01,0x24,0x41,0x00,0x01,0x41,0x01,0xb5,0x7d,0xff,0x01,0xd3,
-0x01,0x5f,0x01,0x06,0x40,0x00,0x01,0x0a,0x01,0xb9,0x0d,0xff,0x01,0xce,0x01,0x0f,
-0xdb,0x00,0x01,0x96,0x0d,0xff,0x01,0xd3,0x01,0x1c,0x3f,0x00,0x01,0x02,0x01,0x57,
-0x01,0xcc,0x81,0xff,0x01,0xe6,0x01,0x73,0x01,0x0c,0x3f,0x00,0x01,0x06,0x01,0xac,
-0x0d,0xff,0x01,0xc9,0x01,0x0f,0xd9,0x00,0x01,0x86,0x0d,0xff,0x01,0xce,0x01,0x15,
-0x3e,0x00,0x01,0x04,0x01,0x60,0x01,0xd6,0x85,0xff,0x01,0xec,0x01,0x7d,0x01,0x10,
-0x3e,0x00,0x01,0x03,0x01,0x9e,0x0d,0xff,0x01,0xc3,0x01,0x0a,0xd7,0x00,0x01,0x75,
-0x0d,0xff,0x01,0xc9,0x01,0x0f,0x3d,0x00,0x01,0x04,0x01,0x60,0x01,0xdc,0x89,0xff,
-0x01,0xf0,0x01,0x7f,0x01,0x0c,0x3d,0x00,0x01,0x01,0x01,0x97,0x0d,0xff,0x01,0xb6,
-0x01,0x06,0xd5,0x00,0x01,0x66,0x0d,0xff,0x01,0xc6,0x01,0x0f,0x3c,0x00,0x01,0x01,
-0x01,0x58,0x01,0xd8,0x8d,0xff,0x01,0xec,0x01,0x77,0x01,0x09,0x3c,0x00,0x01,0x01,
-0x01,0x97,0x0d,0xff,0x01,0xa6,0x01,0x01,0xd3,0x00,0x01,0x52,0x01,0xfd,0x0c,0xff,
-0x01,0xc2,0x01,0x0a,0x3c,0x00,0x01,0x44,0x01,0xce,0x91,0xff,0x01,0xe4,0x01,0x62,
-0x01,0x02,0x3b,0x00,0x01,0x01,0x01,0x8b,0x0d,0xff,0x01,0x94,0xd2,0x00,0x01,0x3c,
-0x01,0xf6,0x0c,0xff,0x01,0xc9,0x01,0x0f,0x3b,0x00,0x01,0x2d,0x01,0xb9,0x95,0xff,
-0x01,0xd3,0x01,0x49,0x3c,0x00,0x01,0x8d,0x0d,0xff,0x01,0x7c,0xd0,0x00,0x01,0x29,
-0x01,0xee,0x0c,0xff,0x01,0xc9,0x01,0x0f,0x3a,0x00,0x01,0x15,0x01,0x97,0x01,0xfc,
-0x98,0xff,0x01,0xb5,0x01,0x26,0x3a,0x00,0x01,0x01,0x01,0x97,0x0d,0xff,0x01,0x5f,
-0xce,0x00,0x01,0x19,0x01,0xe1,0x0c,0xff,0x01,0xce,0x01,0x0f,0x39,0x00,0x01,0x04,
-0x01,0x6e,0x01,0xef,0x9b,0xff,0x01,0xfa,0x01,0x8b,0x01,0x0d,0x39,0x00,0x01,0x01,
-0x01,0x9b,0x0c,0xff,0x01,0xfa,0x01,0x45,0xcc,0x00,0x01,0x0a,0x01,0xcd,0x0c,0xff,
-0x01,0xd9,0x01,0x15,0x39,0x00,0x01,0x39,0x01,0xcf,0x9f,0xff,0x01,0xe4,0x01,0x54,
-0x39,0x00,0x01,0x03,0x01,0xa5,0x0c,0xff,0x01,0xf1,0x01,0x2e,0xca,0x00,0x01,0x02,
-0x01,0xae,0x0c,0xff,0x01,0xe2,0x01,0x1c,0x38,0x00,0x01,0x10,0x01,0x9a,0x01,0xfe,
-0xa2,0xff,0x01,0xb7,0x01,0x21,0x38,0x00,0x01,0x05,0x01,0xb4,0x0c,0xff,0x01,0xe2,
-0x01,0x18,0xc9,0x00,0x01,0x89,0x0c,0xff,0x01,0xeb,0x01,0x24,0x38,0x00,0x01,0x52,
-0x01,0xe7,0xa5,0xff,0x01,0xf5,0x01,0x70,0x01,0x02,0x37,0x00,0x01,0x0a,0x01,0xc3,
-0x0c,0xff,0x01,0xc8,0x01,0x08,0xc7,0x00,0x01,0x61,0x0c,0xff,0x01,0xf3,0x01,0x33,
-0x37,0x00,0x01,0x15,0x01,0xae,0xa9,0xff,0x01,0xc8,0x01,0x2a,0x37,0x00,0x01,0x0f,
-0x01,0xd1,0x0c,0xff,0x01,0xa7,0x01,0x01,0xc5,0x00,0x01,0x37,0x01,0xf9,0x0b,0xff,
-0x01,0xfa,0x01,0x47,0x37,0x00,0x01,0x55,0x01,0xeb,0xab,0xff,0x01,0xf8,0x01,0x74,
-0x01,0x02,0x36,0x00,0x01,0x19,0x01,0xe1,0x0c,0xff,0x01,0x7c,0xc4,0x00,0x01,0x19,
-0x01,0xe7,0x0c,0xff,0x01,0x60,0x36,0x00,0x01,0x10,0x01,0xa5,0xaf,0xff,0x01,0xc3,
-0x01,0x21,0x36,0x00,0x01,0x29,0x01,0xef,0x0b,0xff,0x01,0xfe,0x01,0x4c,0xc2,0x00,
-0x01,0x07,0x01,0xc8,0x0c,0xff,0x01,0x7b,0x36,0x00,0x01,0x3d,0x01,0xe1,0xb1,0xff,
-0x01,0xf3,0x01,0x5d,0x36,0x00,0x01,0x3d,0x01,0xf9,0x0b,0xff,0x01,0xf0,0x01,0x26,
-0xc1,0x00,0x01,0x9a,0x0c,0xff,0x01,0xa2,0x35,0x00,0x01,0x04,0x01,0x84,0x01,0xfd,
-0xb4,0xff,0x01,0xa5,0x01,0x0e,0x35,0x00,0x01,0x58,0x0c,0xff,0x01,0xd6,0x01,0x0d,
-0xbf,0x00,0x01,0x5f,0x0c,0xff,0x01,0xc2,0x01,0x06,0x34,0x00,0x01,0x1c,0x01,0xc4,
-0xb7,0xff,0x01,0xdd,0x01,0x33,0x35,0x00,0x01,0x80,0x0c,0xff,0x01,0xad,0x01,0x01,
-0xbd,0x00,0x01,0x2e,0x01,0xf7,0x0b,0xff,0x01,0xdb,0x01,0x13,0x34,0x00,0x01,0x49,
-0x01,0xec,0xb9,0xff,0x01,0xf9,0x01,0x69,0x34,0x00,0x01,0x01,0x01,0xa7,0x0c,0xff,
-0x01,0x70,0xbc,0x00,0x01,0x0f,0x01,0xdb,0x0b,0xff,0x01,0xf2,0x01,0x2a,0x33,0x00,
-0x01,0x01,0x01,0x80,0x01,0xfe,0xbc,0xff,0x01,0xa7,0x01,0x0c,0x33,0x00,0x01,0x09,
-0x01,0xc9,0x0b,0xff,0x01,0xfb,0x01,0x39,0xbb,0x00,0x01,0xaa,0x0c,0xff,0x01,0x4e,
-0x33,0x00,0x01,0x10,0x01,0xb4,0xbf,0xff,0x01,0xd4,0x01,0x22,0x33,0x00,0x01,0x19,
-0x01,0xe7,0x0b,0xff,0x01,0xe2,0x01,0x14,0xb9,0x00,0x01,0x66,0x0c,0xff,0x01,0x7d,
-0x33,0x00,0x01,0x28,0x01,0xda,0xc1,0xff,0x01,0xee,0x01,0x46,0x33,0x00,0x01,0x39,
-0x01,0xfa,0x0b,0xff,0x01,0xb5,0x01,0x01,0xb7,0x00,0x01,0x2c,0x01,0xf7,0x0b,0xff,
-0x01,0xae,0x01,0x01,0x32,0x00,0x01,0x46,0x01,0xf0,0xc3,0xff,0x01,0xfd,0x01,0x73,
-0x33,0x00,0x01,0x66,0x0c,0xff,0x01,0x6f,0xb6,0x00,0x01,0x09,0x01,0xd5,0x0b,0xff,
-0x01,0xdb,0x01,0x0e,0x32,0x00,0x01,0x6d,0x01,0xfd,0xc6,0xff,0x01,0x9a,0x01,0x05,
-0x32,0x00,0x01,0x9b,0x0b,0xff,0x01,0xf9,0x01,0x2f,0xb5,0x00,0x01,0x94,0x0b,0xff,
-0x01,0xf6,0x01,0x2d,0x31,0x00,0x01,0x03,0x01,0x92,0xc9,0xff,0x01,0xbd,0x01,0x10,
-0x31,0x00,0x01,0x08,0x01,0xd0,0x0b,0xff,0x01,0xd7,0x01,0x0b,0xb3,0x00,0x01,0x48,
-0x0c,0xff,0x01,0x5e,0x31,0x00,0x01,0x0a,0x01,0xaf,0xcb,0xff,0x01,0xd5,0x01,0x1d,
-0x31,0x00,0x01,0x23,0x01,0xf1,0x0b,0xff,0x01,0x97,0xb2,0x00,0x01,0x13,0x01,0xe6,
-0x0b,0xff,0x01,0x9c,0x31,0x00,0x01,0x14,0x01,0xc7,0xcd,0xff,0x01,0xe4,0x01,0x2e,
-0x31,0x00,0x01,0x52,0x0c,0xff,0x01,0x48,0xb1,0x00,0x01,0xac,0x0b,0xff,0x01,0xd6,
-0x01,0x0b,0x30,0x00,0x01,0x1c,0x01,0xd5,0xcf,0xff,0x01,0xf1,0x01,0x3f,0x31,0x00,
-0x01,0x92,0x0b,0xff,0x01,0xe5,0x01,0x12,0xaf,0x00,0x01,0x5b,0x0b,0xff,0x01,0xf8,
-0x01,0x2d,0x30,0x00,0x01,0x25,0x01,0xe1,0xd1,0xff,0x01,0xf6,0x01,0x4c,0x30,0x00,
-0x01,0x07,0x01,0xd1,0x0b,0xff,0x01,0xa7,0xae,0x00,0x01,0x16,0x01,0xed,0x0b,0xff,
-0x01,0x69,0x30,0x00,0x01,0x2d,0x01,0xeb,0xd3,0xff,0x01,0xfa,0x01,0x59,0x30,0x00,
-0x01,0x29,0x01,0xf5,0x0b,0xff,0x01,0x54,0xad,0x00,0x01,0xab,0x0b,0xff,0x01,0xb3,
-0x30,0x00,0x01,0x31,0x01,0xeb,0xd5,0xff,0x01,0xfd,0x01,0x60,0x30,0x00,0x01,0x66,
-0x0b,0xff,0x01,0xe8,0x01,0x13,0xab,0x00,0x01,0x55,0x0b,0xff,0x01,0xea,0x01,0x16,
-0x2f,0x00,0x01,0x37,0x01,0xf1,0x5e,0xff,0x01,0xfc,0x01,0xe6,0x01,0xc9,0x01,0xb0,
-0x01,0x97,0x01,0x81,0x01,0x72,0x01,0x64,0x01,0x57,0x01,0x49,0x03,0x40,0x01,0x32,
-0x02,0x30,0x01,0x3f,0x01,0x47,0x01,0x50,0x01,0x60,0x01,0x68,0x01,0x78,0x01,0x8f,
-0x01,0xa7,0x01,0xbd,0x01,0xd6,0x01,0xef,0x5f,0xff,0x01,0x69,0x30,0x00,0x01,0xb1,
-0x0b,0xff,0x01,0xa1,0xaa,0x00,0x01,0x12,0x01,0xe9,0x0b,0xff,0x01,0x4e,0x2f,0x00,
-0x01,0x37,0x01,0xf1,0x59,0xff,0x01,0xdf,0x01,0xb7,0x01,0x91,0x01,0x6a,0x01,0x43,
-0x01,0x1d,0x01,0x02,0x1a,0x00,0x01,0x13,0x01,0x35,0x01,0x5b,0x01,0x7f,0x01,0xa1,
-0x01,0xd1,0x01,0xfb,0x59,0xff,0x01,0x69,0x2f,0x00,0x01,0x16,0x01,0xeb,0x0b,0xff,
-0x01,0x4a,0xa9,0x00,0x01,0x9c,0x0b,0xff,0x01,0x9c,0x2f,0x00,0x01,0x2d,0x01,0xef,
-0x55,0xff,0x01,0xdf,0x01,0xab,0x01,0x78,0x01,0x45,0x01,0x12,0x27,0x00,0x01,0x07,
-0x01,0x32,0x01,0x63,0x01,0x94,0x01,0xcc,0x01,0xfd,0x55,0xff,0x01,0x66,0x2f,0x00,
-0x01,0x51,0x0b,0xff,0x01,0xe2,0x01,0x0c,0xa7,0x00,0x01,0x3e,0x0b,0xff,0x01,0xe2,
-0x01,0x0e,0x2e,0x00,0x01,0x2d,0x01,0xeb,0x52,0xff,0x01,0xdc,0x01,0x9c,0x01,0x5c,
-0x01,0x1c,0x31,0x00,0x01,0x0c,0x01,0x48,0x01,0x85,0x01,0xc4,0x01,0xf9,0x51,0xff,
-0x01,0xfd,0x01,0x5b,0x2f,0x00,0x01,0xa1,0x0b,0xff,0x01,0x8c,0xa6,0x00,0x01,0x07,
-0x01,0xd7,0x0b,0xff,0x01,0x46,0x2e,0x00,0x01,0x24,0x01,0xe5,0x4f,0xff,0x01,0xf7,
-0x01,0xb5,0x01,0x68,0x01,0x1d,0x39,0x00,0x01,0x0c,0x01,0x50,0x01,0x9c,0x01,0xe6,
-0x4f,0xff,0x01,0xfd,0x01,0x55,0x2e,0x00,0x01,0x10,0x01,0xe6,0x0a,0xff,0x01,0xfc,
-0x01,0x2e,0xa5,0x00,0x01,0x7b,0x0b,0xff,0x01,0x9b,0x2e,0x00,0x01,0x1b,0x01,0xdc,
-0x4d,0xff,0x01,0xee,0x01,0x9d,0x01,0x4f,0x01,0x0a,0x3f,0x00,0x01,0x01,0x01,0x32,
-0x01,0x81,0x01,0xd8,0x4d,0xff,0x01,0xfa,0x01,0x44,0x2e,0x00,0x01,0x50,0x0b,0xff,
-0x01,0xc7,0x01,0x02,0xa3,0x00,0x01,0x1f,0x01,0xf6,0x0a,0xff,0x01,0xe5,0x01,0x0f,
-0x2d,0x00,0x01,0x0f,0x01,0xd3,0x4b,0xff,0x01,0xf7,0x01,0xa8,0x01,0x4d,0x01,0x05,
-0x46,0x00,0x01,0x33,0x01,0x8c,0x01,0xe3,0x4b,0xff,0x01,0xf4,0x01,0x36,0x2e,0x00,
-0x01,0xa9,0x0b,0xff,0x01,0x66,0xa3,0x00,0x01,0xac,0x0b,0xff,0x01,0x52,0x2d,0x00,
-0x01,0x06,0x01,0xc1,0x4a,0xff,0x01,0xc1,0x01,0x5e,0x01,0x0c,0x4b,0x00,0x01,0x02,
-0x01,0x40,0x01,0xa6,0x01,0xf9,0x49,0xff,0x01,0xeb,0x01,0x26,0x2d,0x00,0x01,0x15,
-0x01,0xec,0x0a,0xff,0x01,0xeb,0x01,0x11,0xa1,0x00,0x01,0x45,0x0b,0xff,0x01,0xb1,
-0x2d,0x00,0x01,0x01,0x01,0xaa,0x48,0xff,0x01,0xf2,0x01,0x93,0x01,0x2b,0x51,0x00,
-0x01,0x15,0x01,0x76,0x01,0xdc,0x48,0xff,0x01,0xdd,0x01,0x15,0x2d,0x00,0x01,0x61,
-0x0b,0xff,0x01,0x93,0xa0,0x00,0x01,0x04,0x01,0xd7,0x0a,0xff,0x01,0xf3,0x01,0x1d,
-0x2d,0x00,0x01,0x8a,0x47,0xff,0x01,0xd7,0x01,0x66,0x01,0x0b,0x55,0x00,0x01,0x02,
-0x01,0x47,0x01,0xbb,0x47,0xff,0x01,0xc8,0x01,0x0a,0x2c,0x00,0x01,0x01,0x01,0xc2,
-0x0a,0xff,0x01,0xfc,0x01,0x2c,0x9f,0x00,0x01,0x6c,0x0b,0xff,0x01,0x70,0x2d,0x00,
-0x01,0x63,0x46,0xff,0x01,0xc8,0x01,0x51,0x01,0x02,0x5a,0x00,0x01,0x33,0x01,0xaa,
-0x01,0xfe,0x45,0xff,0x01,0xae,0x01,0x01,0x2c,0x00,0x01,0x2a,0x01,0xfa,0x0a,0xff,
-0x01,0xbd,0x9e,0x00,0x01,0x10,0x01,0xed,0x0a,0xff,0x01,0xd4,0x01,0x04,0x2c,0x00,
-0x01,0x40,0x01,0xfa,0x44,0xff,0x01,0xb8,0x01,0x3f,0x5f,0x00,0x01,0x24,0x01,0x99,
-0x01,0xfa,0x44,0xff,0x01,0x86,0x2d,0x00,0x01,0x86,0x0b,0xff,0x01,0x4d,0x9d,0x00,
-0x01,0x8d,0x0b,0xff,0x01,0x3f,0x2c,0x00,0x01,0x22,0x01,0xed,0x43,0xff,0x01,0xc4,
-0x01,0x3d,0x63,0x00,0x01,0x24,0x01,0xa5,0x01,0xfe,0x43,0xff,0x01,0x5b,0x2c,0x00,
-0x01,0x0b,0x01,0xe3,0x0a,0xff,0x01,0xd8,0x01,0x04,0x9b,0x00,0x01,0x23,0x01,0xfa,
-0x0a,0xff,0x01,0xa5,0x2c,0x00,0x01,0x0b,0x01,0xd2,0x42,0xff,0x01,0xd0,0x01,0x4b,
-0x67,0x00,0x01,0x2f,0x01,0xb3,0x42,0xff,0x01,0xf8,0x01,0x34,0x2c,0x00,0x01,0x58,
-0x0b,0xff,0x01,0x68,0x9b,0x00,0x01,0xa6,0x0a,0xff,0x01,0xf4,0x01,0x1b,0x2b,0x00,
-0x01,0x01,0x01,0xa9,0x41,0xff,0x01,0xe6,0x01,0x5d,0x01,0x02,0x6a,0x00,0x01,0x3c,
-0x01,0xcf,0x41,0xff,0x01,0xe1,0x01,0x14,0x2b,0x00,0x01,0x01,0x01,0xc2,0x0a,0xff,
-0x01,0xe9,0x01,0x0d,0x99,0x00,0x01,0x31,0x01,0xfe,0x0a,0xff,0x01,0x7e,0x2c,0x00,
-0x01,0x73,0x40,0xff,0x01,0xfa,0x01,0x8b,0x01,0x0d,0x6d,0x00,0x01,0x03,0x01,0x6b,
-0x01,0xef,0x40,0xff,0x01,0xbd,0x01,0x03,0x2b,0x00,0x01,0x2f,0x01,0xfe,0x0a,0xff,
-0x01,0x80,0x99,0x00,0x01,0xb6,0x0a,0xff,0x01,0xe4,0x01,0x09,0x2b,0x00,0x01,0x3c,
-0x01,0xfb,0x3f,0xff,0x01,0xb9,0x01,0x28,0x71,0x00,0x01,0x14,0x01,0x9b,0x01,0xfe,
-0x3f,0xff,0x01,0x88,0x2c,0x00,0x01,0x9d,0x0a,0xff,0x01,0xf1,0x01,0x14,0x97,0x00,
-0x01,0x3f,0x0b,0xff,0x01,0x5d,0x2b,0x00,0x01,0x15,0x01,0xe4,0x3e,0xff,0x01,0xed,
-0x01,0x5b,0x75,0x00,0x01,0x39,0x01,0xd8,0x3f,0xff,0x01,0x49,0x2b,0x00,0x01,0x1a,
-0x01,0xf5,0x0a,0xff,0x01,0x8a,0x97,0x00,0x01,0xc0,0x0a,0xff,0x01,0xcc,0x01,0x01,
-0x2a,0x00,0x01,0x01,0x01,0xba,0x3e,0xff,0x01,0xab,0x01,0x18,0x77,0x00,0x01,0x08,
-0x01,0x8b,0x01,0xfd,0x3d,0xff,0x01,0xec,0x01,0x1c,0x2b,0x00,0x01,0x82,0x0a,0xff,
-0x01,0xf7,0x01,0x19,0x95,0x00,0x01,0x40,0x0b,0xff,0x01,0x44,0x2b,0x00,0x01,0x75,
-0x3d,0xff,0x01,0xeb,0x01,0x55,0x7b,0x00,0x01,0x38,0x01,0xd8,0x3d,0xff,0x01,0xc3,
-0x01,0x03,0x2a,0x00,0x01,0x0c,0x01,0xe8,0x0a,0xff,0x01,0x95,0x95,0x00,0x01,0xc0,
-0x0a,0xff,0x01,0xbc,0x2b,0x00,0x01,0x32,0x01,0xfa,0x3c,0xff,0x01,0xb9,0x01,0x16,
-0x7d,0x00,0x01,0x08,0x01,0x91,0x3d,0xff,0x01,0x7c,0x2b,0x00,0x01,0x6c,0x0a,0xff,
-0x01,0xf7,0x01,0x19,0x93,0x00,0x01,0x47,0x0b,0xff,0x01,0x34,0x2a,0x00,0x01,0x0c,
-0x01,0xda,0x3b,0xff,0x01,0xfb,0x01,0x76,0x01,0x01,0x80,0x00,0x01,0x4f,0x01,0xee,
-0x3b,0xff,0x01,0xfc,0x01,0x37,0x2a,0x00,0x01,0x06,0x01,0xe1,0x0a,0xff,0x01,0x90,
-0x93,0x00,0x01,0xc3,0x0a,0xff,0x01,0xab,0x2b,0x00,0x01,0x96,0x3b,0xff,0x01,0xde,
-0x01,0x37,0x83,0x00,0x01,0x1e,0x01,0xc6,0x3b,0xff,0x01,0xdb,0x01,0x0c,0x2a,0x00,
-0x01,0x60,0x0a,0xff,0x01,0xf7,0x01,0x19,0x91,0x00,0x01,0x3b,0x0a,0xff,0x01,0xfe,
-0x01,0x2a,0x2a,0x00,0x01,0x46,0x3b,0xff,0x01,0xb4,0x01,0x0f,0x85,0x00,0x01,0x04,
-0x01,0x89,0x3b,0xff,0x01,0x95,0x2a,0x00,0x01,0x04,0x01,0xd7,0x0a,0xff,0x01,0x8a,
-0x91,0x00,0x01,0xb5,0x0a,0xff,0x01,0xa8,0x2a,0x00,0x01,0x10,0x01,0xe5,0x3a,0xff,
-0x01,0x86,0x01,0x02,0x88,0x00,0x01,0x58,0x01,0xf6,0x3a,0xff,0x01,0x41,0x2a,0x00,
-0x01,0x58,0x0a,0xff,0x01,0xf4,0x01,0x10,0x8f,0x00,0x01,0x2e,0x0a,0xff,0x01,0xfe,
-0x01,0x2a,0x2a,0x00,0x01,0x9f,0x39,0xff,0x01,0xf6,0x01,0x57,0x8b,0x00,0x01,0x32,
-0x01,0xe3,0x39,0xff,0x01,0xe2,0x01,0x0d,0x29,0x00,0x01,0x02,0x01,0xd9,0x0a,0xff,
-0x01,0x7a,0x8f,0x00,0x01,0xa6,0x0a,0xff,0x01,0xa8,0x2a,0x00,0x01,0x45,0x39,0xff,
-0x01,0xe4,0x01,0x31,0x8d,0x00,0x01,0x18,0x01,0xc7,0x39,0xff,0x01,0x92,0x2a,0x00,
-0x01,0x60,0x0a,0xff,0x01,0xe8,0x01,0x08,0x8d,0x00,0x01,0x1d,0x01,0xfc,0x0a,0xff,
-0x01,0x2f,0x29,0x00,0x01,0x0b,0x01,0xdf,0x38,0xff,0x01,0xd5,0x01,0x1c,0x8f,0x00,
-0x01,0x07,0x01,0xa8,0x38,0xff,0x01,0xfe,0x01,0x39,0x29,0x00,0x01,0x04,0x01,0xdc,
-0x0a,0xff,0x01,0x66,0x8d,0x00,0x01,0x8b,0x0a,0xff,0x01,0xb5,0x2a,0x00,0x01,0x8d,
-0x38,0xff,0x01,0xc3,0x01,0x11,0x91,0x00,0x01,0x01,0x01,0x8d,0x38,0xff,0x01,0xd5,
-0x01,0x05,0x29,0x00,0x01,0x65,0x0a,0xff,0x01,0xd9,0x01,0x01,0x8b,0x00,0x01,0x0c,
-0x01,0xf0,0x0a,0xff,0x01,0x3c,0x29,0x00,0x01,0x2f,0x01,0xfc,0x37,0xff,0x01,0xae,
-0x01,0x09,0x94,0x00,0x01,0x73,0x38,0xff,0x01,0x78,0x29,0x00,0x01,0x07,0x01,0xe7,
-0x0a,0xff,0x01,0x48,0x8b,0x00,0x01,0x6d,0x0a,0xff,0x01,0xc3,0x29,0x00,0x01,0x01,
-0x01,0xc6,0x37,0xff,0x01,0x9b,0x01,0x03,0x96,0x00,0x01,0x64,0x01,0xfd,0x36,0xff,
-0x01,0xf5,0x01,0x1e,0x29,0x00,0x01,0x79,0x0a,0xff,0x01,0xb8,0x8a,0x00,0x01,0x01,
-0x01,0xdb,0x0a,0xff,0x01,0x4e,0x29,0x00,0x01,0x64,0x37,0xff,0x01,0x97,0x01,0x01,
-0x98,0x00,0x01,0x5b,0x01,0xfd,0x36,0xff,0x01,0xae,0x29,0x00,0x01,0x10,0x01,0xf3,
-0x0a,0xff,0x01,0x27,0x89,0x00,0x01,0x46,0x0a,0xff,0x01,0xda,0x01,0x02,0x28,0x00,
-0x01,0x0f,0x01,0xea,0x36,0xff,0x01,0x97,0x01,0x01,0x9a,0x00,0x01,0x5a,0x01,0xfa,
-0x36,0xff,0x01,0x45,0x29,0x00,0x01,0x8d,0x0a,0xff,0x01,0x93,0x89,0x00,0x01,0xb0,
-0x0a,0xff,0x01,0x6c,0x29,0x00,0x01,0x8e,0x36,0xff,0x01,0x97,0x01,0x01,0x9c,0x00,
-0x01,0x59,0x01,0xfd,0x35,0xff,0x01,0xd3,0x01,0x04,0x28,0x00,0x01,0x21,0x01,0xfe,
-0x09,0xff,0x01,0xf2,0x01,0x0b,0x87,0x00,0x01,0x1e,0x01,0xfd,0x09,0xff,0x01,0xef,
-0x01,0x0c,0x28,0x00,0x01,0x27,0x01,0xfa,0x35,0xff,0x01,0x9e,0x01,0x01,0x9e,0x00,
-0x01,0x5b,0x01,0xfd,0x35,0xff,0x01,0x6a,0x29,0x00,0x01,0xb0,0x0a,0xff,0x01,0x64,
-0x87,0x00,0x01,0x83,0x0a,0xff,0x01,0x8b,0x29,0x00,0x01,0xb3,0x35,0xff,0x01,0xae,
-0x01,0x03,0xa0,0x00,0x01,0x6f,0x35,0xff,0x01,0xec,0x01,0x0f,0x28,0x00,0x01,0x41,
-0x0a,0xff,0x01,0xcd,0x86,0x00,0x01,0x03,0x01,0xe5,0x09,0xff,0x01,0xfe,0x01,0x23,
-0x28,0x00,0x01,0x3d,0x35,0xff,0x01,0xbf,0x01,0x06,0xa2,0x00,0x01,0x88,0x35,0xff,
-0x01,0x85,0x29,0x00,0x01,0xd3,0x0a,0xff,0x01,0x33,0x85,0x00,0x01,0x4c,0x0a,0xff,
-0x01,0xb7,0x28,0x00,0x01,0x01,0x01,0xc8,0x34,0xff,0x01,0xd2,0x01,0x0f,0xa3,0x00,
-0x01,0x01,0x01,0xa1,0x34,0xff,0x01,0xf6,0x01,0x1a,0x28,0x00,0x01,0x6a,0x0a,0xff,
-0x01,0x99,0x85,0x00,0x01,0xae,0x0a,0xff,0x01,0x4d,0x28,0x00,0x01,0x54,0x34,0xff,
-0x01,0xe7,0x01,0x1d,0xa5,0x00,0x01,0x06,0x01,0xb8,0x34,0xff,0x01,0x98,0x28,0x00,
-0x01,0x0e,0x01,0xf5,0x09,0xff,0x01,0xf1,0x01,0x09,0x83,0x00,0x01,0x16,0x01,0xfb,
-0x09,0xff,0x01,0xe1,0x01,0x02,0x27,0x00,0x01,0x02,0x01,0xd6,0x33,0xff,0x01,0xf8,
-0x01,0x37,0xa7,0x00,0x01,0x0d,0x01,0xd4,0x33,0xff,0x01,0xfb,0x01,0x24,0x28,0x00,
-0x01,0x9d,0x0a,0xff,0x01,0x58,0x83,0x00,0x01,0x72,0x0a,0xff,0x01,0x80,0x28,0x00,
-0x01,0x59,0x34,0xff,0x01,0x5d,0xa9,0x00,0x01,0x24,0x01,0xee,0x33,0xff,0x01,0xa0,
-0x28,0x00,0x01,0x35,0x0a,0xff,0x01,0xb8,0x83,0x00,0x01,0xce,0x09,0xff,0x01,0xfe,
-0x01,0x1f,0x27,0x00,0x01,0x04,0x01,0xdc,0x33,0xff,0x01,0x8b,0xab,0x00,0x01,0x45,
-0x01,0xfd,0x32,0xff,0x01,0xfc,0x01,0x24,0x28,0x00,0x01,0xd0,0x09,0xff,0x01,0xfd,
-0x01,0x1b,0x81,0x00,0x01,0x2a,0x0a,0xff,0x01,0xbb,0x28,0x00,0x01,0x5e,0x33,0xff,
-0x01,0xb6,0x01,0x03,0xac,0x00,0x01,0x73,0x33,0xff,0x01,0xa0,0x28,0x00,0x01,0x70,
-0x0a,0xff,0x01,0x76,0x81,0x00,0x01,0x86,0x0a,0xff,0x01,0x57,0x27,0x00,0x01,0x02,
-0x01,0xd6,0x32,0xff,0x01,0xe4,0x01,0x14,0xae,0x00,0x01,0xa8,0x32,0xff,0x01,0xfc,
-0x01,0x1e,0x27,0x00,0x01,0x15,0x01,0xfb,0x09,0xff,0x01,0xcd,0x80,0x00,0x01,0x01,
-0x01,0xe0,0x09,0xff,0x01,0xf1,0x01,0x08,0x27,0x00,0x01,0x53,0x32,0xff,0x01,0xfd,
-0x01,0x3c,0xaf,0x00,0x01,0x0e,0x01,0xdd,0x32,0xff,0x01,0x98,0x28,0x00,0x01,0xb0,
-0x0a,0xff,0x01,0x28,0x7f,0x00,0x01,0x38,0x0a,0xff,0x01,0x9d,0x28,0x00,0x01,0xce,
-0x32,0xff,0x01,0x7c,0xb1,0x00,0x01,0x36,0x01,0xfb,0x31,0xff,0x01,0xf7,0x01,0x16,
-0x27,0x00,0x01,0x52,0x0a,0xff,0x01,0x7e,0x7f,0x00,0x01,0x8d,0x0a,0xff,0x01,0x41,
-0x27,0x00,0x01,0x43,0x32,0xff,0x01,0xbd,0x01,0x02,0xb2,0x00,0x01,0x75,0x32,0xff,
-0x01,0x83,0x27,0x00,0x01,0x07,0x01,0xf1,0x09,0xff,0x01,0xd8,0x7e,0x00,0x01,0x01,
-0x01,0xe2,0x09,0xff,0x01,0xe4,0x01,0x02,0x27,0x00,0x01,0xb5,0x31,0xff,0x01,0xed,
-0x01,0x19,0xb3,0x00,0x01,0x01,0x01,0xb9,0x31,0xff,0x01,0xec,0x01,0x09,0x27,0x00,
-0x01,0x9e,0x0a,0xff,0x01,0x2c,0x7d,0x00,0x01,0x38,0x0a,0xff,0x01,0x8d,0x27,0x00,
-0x01,0x2a,0x32,0xff,0x01,0x5b,0xb5,0x00,0x01,0x1d,0x01,0xf2,0x31,0xff,0x01,0x69,
-0x27,0x00,0x01,0x48,0x0a,0xff,0x01,0x7d,0x7d,0x00,0x01,0x8c,0x0a,0xff,0x01,0x38,
-0x27,0x00,0x01,0x98,0x31,0xff,0x01,0xb0,0xb7,0x00,0x01,0x65,0x31,0xff,0x01,0xd5,
-0x01,0x01,0x26,0x00,0x01,0x03,0x01,0xea,0x09,0xff,0x01,0xce,0x7d,0x00,0x01,0xdb,
-0x09,0xff,0x01,0xe2,0x01,0x01,0x26,0x00,0x01,0x0f,0x01,0xf5,0x30,0xff,0x01,0xed,
-0x01,0x18,0xb7,0x00,0x01,0x01,0x01,0xbb,0x31,0xff,0x01,0x42,0x27,0x00,0x01,0x98,
-0x0a,0xff,0x01,0x20,0x7b,0x00,0x01,0x29,0x0a,0xff,0x01,0x8d,0x27,0x00,0x01,0x70,
-0x31,0xff,0x01,0x5e,0xb9,0x00,0x01,0x21,0x01,0xf4,0x30,0xff,0x01,0xaf,0x27,0x00,
-0x01,0x47,0x0a,0xff,0x01,0x71,0x7b,0x00,0x01,0x76,0x0a,0xff,0x01,0x38,0x26,0x00,
-0x01,0x01,0x01,0xda,0x30,0xff,0x01,0xbb,0xbb,0x00,0x01,0x72,0x30,0xff,0x01,0xfc,
-0x01,0x1a,0x26,0x00,0x01,0x05,0x01,0xf0,0x09,0xff,0x01,0xbe,0x7b,0x00,0x01,0xc5,
-0x09,0xff,0x01,0xe7,0x01,0x02,0x26,0x00,0x01,0x40,0x30,0xff,0x01,0xfb,0x01,0x2a,
-0xbb,0x00,0x01,0x04,0x01,0xd6,0x30,0xff,0x01,0x7d,0x27,0x00,0x01,0xa3,0x09,0xff,
-0x01,0xfa,0x01,0x0d,0x79,0x00,0x01,0x13,0x01,0xfd,0x09,0xff,0x01,0x9b,0x27,0x00,
-0x01,0xa4,0x30,0xff,0x01,0x8b,0xbd,0x00,0x01,0x43,0x30,0xff,0x01,0xdf,0x01,0x02,
-0x26,0x00,0x01,0x53,0x0a,0xff,0x01,0x52,0x79,0x00,0x01,0x58,0x0a,0xff,0x01,0x4e,
-0x26,0x00,0x01,0x11,0x01,0xf8,0x2f,0xff,0x01,0xe7,0x01,0x0e,0xbe,0x00,0x01,0xab,
-0x30,0xff,0x01,0x45,0x26,0x00,0x01,0x0d,0x01,0xfa,0x09,0xff,0x01,0x9d,0x79,0x00,
-0x01,0x9f,0x09,0xff,0x01,0xf7,0x01,0x09,0x26,0x00,0x01,0x6b,0x30,0xff,0x01,0x5b,
-0xbf,0x00,0x01,0x1f,0x01,0xf7,0x2f,0xff,0x01,0xa5,0x27,0x00,0x01,0xbc,0x09,0xff,
-0x01,0xe6,0x79,0x00,0x01,0xe6,0x09,0xff,0x01,0xb3,0x27,0x00,0x01,0xc7,0x2f,0xff,
-0x01,0xce,0x01,0x01,0xc0,0x00,0x01,0x88,0x2f,0xff,0x01,0xf5,0x01,0x0d,0x26,0x00,
-0x01,0x72,0x0a,0xff,0x01,0x2b,0x77,0x00,0x01,0x2e,0x0a,0xff,0x01,0x6d,0x26,0x00,
-0x01,0x25,0x30,0xff,0x01,0x48,0xc1,0x00,0x01,0x11,0x01,0xf0,0x2f,0xff,0x01,0x60,
-0x26,0x00,0x01,0x27,0x0a,0xff,0x01,0x6e,0x77,0x00,0x01,0x70,0x0a,0xff,0x01,0x25,
-0x26,0x00,0x01,0x81,0x2f,0xff,0x01,0xc0,0xc3,0x00,0x01,0x7b,0x2f,0xff,0x01,0xba,
-0x27,0x00,0x01,0xde,0x09,0xff,0x01,0xb1,0x77,0x00,0x01,0xb0,0x09,0xff,0x01,0xde,
-0x27,0x00,0x01,0xd8,0x2f,0xff,0x01,0x39,0xc3,0x00,0x01,0x0c,0x01,0xe8,0x2e,0xff,
-0x01,0xfd,0x01,0x16,0x26,0x00,0x01,0x9b,0x09,0xff,0x01,0xf1,0x01,0x04,0x75,0x00,
-0x01,0x03,0x01,0xef,0x09,0xff,0x01,0x97,0x26,0x00,0x01,0x2d,0x2f,0xff,0x01,0xb2,
-0xc5,0x00,0x01,0x70,0x2f,0xff,0x01,0x68,0x26,0x00,0x01,0x57,0x0a,0xff,0x01,0x38,
-0x75,0x00,0x01,0x34,0x0a,0xff,0x01,0x54,0x26,0x00,0x01,0x83,0x2f,0xff,0x01,0x37,
-0xc5,0x00,0x01,0x09,0x01,0xec,0x2e,0xff,0x01,0xbd,0x26,0x00,0x01,0x15,0x0a,0xff,
-0x01,0x75,0x75,0x00,0x01,0x74,0x0a,0xff,0x01,0x15,0x26,0x00,0x01,0xd8,0x2e,0xff,
-0x01,0xbf,0xc7,0x00,0x01,0x7d,0x2e,0xff,0x01,0xfc,0x01,0x11,0x26,0x00,0x01,0xd0,
-0x09,0xff,0x01,0xb1,0x75,0x00,0x01,0xaf,0x09,0xff,0x01,0xd4,0x26,0x00,0x01,0x29,
-0x2f,0xff,0x01,0x49,0xc7,0x00,0x01,0x12,0x01,0xf4,0x2e,0xff,0x01,0x5a,0x26,0x00,
-0x01,0x90,0x09,0xff,0x01,0xed,0x01,0x01,0x74,0x00,0x01,0xe9,0x09,0xff,0x01,0x94,
-0x26,0x00,0x01,0x77,0x2e,0xff,0x01,0xd1,0x01,0x01,0xc8,0x00,0x01,0x8e,0x2e,0xff,
-0x01,0xa6,0x26,0x00,0x01,0x54,0x0a,0xff,0x01,0x2a,0x73,0x00,0x01,0x22,0x0a,0xff,
-0x01,0x56,0x26,0x00,0x01,0xc6,0x2e,0xff,0x01,0x5b,0xc9,0x00,0x01,0x1e,0x01,0xfc,
-0x2d,0xff,0x01,0xef,0x01,0x04,0x25,0x00,0x01,0x18,0x0a,0xff,0x01,0x67,0x73,0x00,
-0x01,0x5b,0x0a,0xff,0x01,0x1c,0x25,0x00,0x01,0x14,0x01,0xfe,0x2d,0xff,0x01,0xe8,
-0x01,0x06,0xca,0x00,0x01,0xb0,0x2e,0xff,0x01,0x41,0x26,0x00,0x01,0xda,0x09,0xff,
-0x01,0x9c,0x73,0x00,0x01,0x96,0x09,0xff,0x01,0xe2,0x26,0x00,0x01,0x5a,0x2e,0xff,
-0x01,0x86,0xcb,0x00,0x01,0x47,0x2e,0xff,0x01,0x8f,0x26,0x00,0x01,0x9d,0x09,0xff,
-0x01,0xd3,0x73,0x00,0x01,0xcb,0x09,0xff,0x01,0xa9,0x26,0x00,0x01,0xa2,0x2d,0xff,
-0x01,0xfe,0x01,0x21,0xcb,0x00,0x01,0x02,0x01,0xdd,0x2d,0xff,0x01,0xda,0x26,0x00,
-0x01,0x67,0x09,0xff,0x01,0xfd,0x01,0x0b,0x71,0x00,0x01,0x05,0x01,0xf9,0x09,0xff,
-0x01,0x6f,0x25,0x00,0x01,0x01,0x01,0xe8,0x2d,0xff,0x01,0xb6,0xcd,0x00,0x01,0x76,
-0x2e,0xff,0x01,0x1c,0x25,0x00,0x01,0x31,0x0a,0xff,0x01,0x3e,0x71,0x00,0x01,0x32,
-0x0a,0xff,0x01,0x38,0x25,0x00,0x01,0x2c,0x2e,0xff,0x01,0x50,0xcd,0x00,0x01,0x15,
-0x01,0xfb,0x2d,0xff,0x01,0x5c,0x25,0x00,0x01,0x04,0x01,0xf7,0x09,0xff,0x01,0x73,
-0x71,0x00,0x01,0x62,0x09,0xff,0x01,0xfc,0x01,0x09,0x25,0x00,0x01,0x6c,0x2d,0xff,
-0x01,0xeb,0x01,0x05,0xce,0x00,0x01,0xb5,0x2d,0xff,0x01,0x9c,0x26,0x00,0x01,0xc5,
-0x09,0xff,0x01,0xa2,0x71,0x00,0x01,0x95,0x09,0xff,0x01,0xd4,0x26,0x00,0x01,0xaf,
-0x2d,0xff,0x01,0x97,0xcf,0x00,0x01,0x5a,0x2d,0xff,0x01,0xdc,0x26,0x00,0x01,0x91,
-0x09,0xff,0x01,0xd1,0x71,0x00,0x01,0xc3,0x09,0xff,0x01,0xa2,0x25,0x00,0x01,0x01,
-0x01,0xee,0x2d,0xff,0x01,0x3d,0xcf,0x00,0x01,0x0c,0x01,0xf4,0x2d,0xff,0x01,0x1c,
-0x25,0x00,0x01,0x61,0x09,0xff,0x01,0xfb,0x01,0x05,0x70,0x00,0x01,0xf0,0x09,0xff,
-0x01,0x6e,0x25,0x00,0x01,0x29,0x2d,0xff,0x01,0xe2,0x01,0x02,0xd0,0x00,0x01,0xa6,
-0x2d,0xff,0x01,0x5c,0x25,0x00,0x01,0x31,0x0a,0xff,0x01,0x30,0x6f,0x00,0x01,0x1d,
-0x0a,0xff,0x01,0x40,0x25,0x00,0x01,0x64,0x2d,0xff,0x01,0x8b,0xd1,0x00,0x01,0x4e,
-0x2d,0xff,0x01,0x9b,0x25,0x00,0x01,0x07,0x01,0xfc,0x09,0xff,0x01,0x5e,0x6f,0x00,
-0x01,0x48,0x0a,0xff,0x01,0x14,0x25,0x00,0x01,0x9e,0x2d,0xff,0x01,0x38,0xd1,0x00,
-0x01,0x09,0x01,0xf7,0x2c,0xff,0x01,0xd2,0x26,0x00,0x01,0xd3,0x09,0xff,0x01,0x86,
-0x6f,0x00,0x01,0x74,0x09,0xff,0x01,0xe8,0x26,0x00,0x01,0xd5,0x2c,0xff,0x01,0xeb,
-0x01,0x02,0xd2,0x00,0x01,0xb3,0x2c,0xff,0x01,0xfc,0x01,0x09,0x25,0x00,0x01,0xa6,
-0x09,0xff,0x01,0xb0,0x6f,0x00,0x01,0x9d,0x09,0xff,0x01,0xbb,0x25,0x00,0x01,0x0d,
-0x01,0xfd,0x2c,0xff,0x01,0xa1,0xd3,0x00,0x01,0x66,0x2d,0xff,0x01,0x38,0x25,0x00,
-0x01,0x7e,0x09,0xff,0x01,0xd8,0x6f,0x00,0x01,0xc1,0x09,0xff,0x01,0x90,0x25,0x00,
-0x01,0x3e,0x2d,0xff,0x01,0x56,0xd3,0x00,0x01,0x19,0x2d,0xff,0x01,0x6b,0x25,0x00,
-0x01,0x55,0x09,0xff,0x01,0xfb,0x01,0x05,0x6e,0x00,0x01,0xe8,0x09,0xff,0x01,0x6b,
-0x25,0x00,0x01,0x72,0x2c,0xff,0x01,0xfb,0x01,0x10,0xd4,0x00,0x01,0xcd,0x2c,0xff,
-0x01,0x9e,0x25,0x00,0x01,0x2d,0x0a,0xff,0x01,0x28,0x6d,0x00,0x01,0x0d,0x0a,0xff,
-0x01,0x43,0x25,0x00,0x01,0xa0,0x2c,0xff,0x01,0xc4,0xd5,0x00,0x01,0x8c,0x2c,0xff,
-0x01,0xd2,0x25,0x00,0x01,0x06,0x01,0xfd,0x09,0xff,0x01,0x4b,0x6d,0x00,0x01,0x33,
-0x0a,0xff,0x01,0x1f,0x25,0x00,0x01,0xcf,0x2c,0xff,0x01,0x85,0xd5,0x00,0x01,0x4c,
-0x2c,0xff,0x01,0xfc,0x01,0x09,0x25,0x00,0x01,0xdf,0x09,0xff,0x01,0x6d,0x6d,0x00,
-0x01,0x54,0x09,0xff,0x01,0xf7,0x01,0x02,0x24,0x00,0x01,0x04,0x01,0xf8,0x2c,0xff,
-0x01,0x48,0xd5,0x00,0x01,0x0f,0x01,0xfd,0x2c,0xff,0x01,0x33,0x25,0x00,0x01,0xbd,
-0x09,0xff,0x01,0x8e,0x6d,0x00,0x01,0x72,0x09,0xff,0x01,0xd6,0x25,0x00,0x01,0x27,
-0x2c,0xff,0x01,0xfd,0x01,0x0c,0xd6,0x00,0x01,0xcc,0x2c,0xff,0x01,0x5a,0x25,0x00,
-0x01,0x9b,0x09,0xff,0x01,0xb0,0x6d,0x00,0x01,0x92,0x09,0xff,0x01,0xb7,0x25,0x00,
-0x01,0x4d,0x2c,0xff,0x01,0xcc,0xd7,0x00,0x01,0x8d,0x2c,0xff,0x01,0x80,0x25,0x00,
-0x01,0x7a,0x09,0xff,0x01,0xd2,0x6d,0x00,0x01,0xb1,0x09,0xff,0x01,0x98,0x25,0x00,
-0x01,0x71,0x2c,0xff,0x01,0x8f,0xd7,0x00,0x01,0x58,0x2c,0xff,0x01,0xa7,0x25,0x00,
-0x01,0x57,0x09,0xff,0x01,0xee,0x6d,0x00,0x01,0xd0,0x09,0xff,0x01,0x78,0x25,0x00,
-0x01,0x93,0x2c,0xff,0x01,0x5d,0xd7,0x00,0x01,0x25,0x2c,0xff,0x01,0xce,0x25,0x00,
-0x01,0x39,0x0a,0xff,0x01,0x09,0x6c,0x00,0x01,0xe9,0x09,0xff,0x01,0x59,0x25,0x00,
-0x01,0xb8,0x2c,0xff,0x01,0x2d,0xd7,0x00,0x01,0x01,0x01,0xf1,0x2b,0xff,0x01,0xf3,
-0x25,0x00,0x01,0x1e,0x0a,0xff,0x01,0x25,0x6b,0x00,0x01,0x05,0x0a,0xff,0x01,0x3e,
-0x25,0x00,0x01,0xdd,0x2b,0xff,0x01,0xf8,0x01,0x04,0xd8,0x00,0x01,0xbe,0x2c,0xff,
-0x01,0x1b,0x24,0x00,0x01,0x05,0x01,0xfe,0x09,0xff,0x01,0x40,0x6b,0x00,0x01,0x1a,
-0x0a,0xff,0x01,0x26,0x24,0x00,0x01,0x04,0x01,0xfb,0x2b,0xff,0x01,0xcb,0xd9,0x00,
-0x01,0x8c,0x2c,0xff,0x01,0x3f,0x25,0x00,0x01,0xe8,0x09,0xff,0x01,0x5a,0x6b,0x00,
-0x01,0x36,0x0a,0xff,0x01,0x0c,0x24,0x00,0x01,0x23,0x2c,0xff,0x01,0x9c,0xd9,0x00,
-0x01,0x61,0x2c,0xff,0x01,0x5a,0x25,0x00,0x01,0xcb,0x09,0xff,0x01,0x73,0x6b,0x00,
-0x01,0x4b,0x09,0xff,0x01,0xf5,0x25,0x00,0x01,0x41,0x2c,0xff,0x01,0x73,0xd9,0x00,
-0x01,0x3c,0x2c,0xff,0x01,0x76,0x25,0x00,0x01,0xb6,0x09,0xff,0x01,0x87,0x6b,0x00,
-0x01,0x62,0x09,0xff,0x01,0xda,0x25,0x00,0x01,0x58,0x2c,0xff,0x01,0x4f,0xd9,0x00,
-0x01,0x14,0x2c,0xff,0x01,0x8e,0x25,0x00,0x01,0xa1,0x09,0xff,0x01,0x9b,0x6b,0x00,
-0x01,0x74,0x09,0xff,0x01,0xc8,0x25,0x00,0x01,0x6f,0x2c,0xff,0x01,0x2c,0xda,0x00,
-0x01,0xef,0x2b,0xff,0x01,0xa8,0x25,0x00,0x01,0x8b,0x09,0xff,0x01,0xb0,0x6b,0x00,
-0x01,0x85,0x09,0xff,0x01,0xb6,0x25,0x00,0x01,0x87,0x2c,0xff,0x01,0x09,0xda,0x00,
-0x01,0xc8,0x2b,0xff,0x01,0xc4,0x25,0x00,0x01,0x77,0x09,0xff,0x01,0xc6,0x6b,0x00,
-0x01,0x97,0x09,0xff,0x01,0xa4,0x25,0x00,0x01,0x9c,0x2b,0xff,0x01,0xe3,0xdb,0x00,
-0x01,0xa7,0x2b,0xff,0x01,0xdc,0x25,0x00,0x01,0x64,0x09,0xff,0x01,0xd6,0x6b,0x00,
-0x01,0xa9,0x09,0xff,0x01,0x92,0x25,0x00,0x01,0xb5,0x2b,0xff,0x01,0xc6,0xdb,0x00,
-0x01,0x8c,0x2b,0xff,0x01,0xf7,0x25,0x00,0x01,0x52,0x09,0xff,0x01,0xe2,0x6b,0x00,
-0x01,0xb7,0x09,0xff,0x01,0x80,0x25,0x00,0x01,0xca,0x2b,0xff,0x01,0xad,0xdb,0x00,
-0x01,0x73,0x2c,0xff,0x01,0x0a,0x24,0x00,0x01,0x45,0x09,0xff,0x01,0xf0,0x6b,0x00,
-0x01,0xc1,0x09,0xff,0x01,0x72,0x25,0x00,0x01,0xdf,0x2b,0xff,0x01,0x97,0xdb,0x00,
-0x01,0x58,0x2c,0xff,0x01,0x17,0x24,0x00,0x01,0x38,0x0a,0xff,0x6b,0x00,0x01,0xd0,
-0x09,0xff,0x01,0x68,0x25,0x00,0x01,0xef,0x2b,0xff,0x01,0x7f,0xdb,0x00,0x01,0x3e,
-0x2c,0xff,0x01,0x25,0x24,0x00,0x01,0x2b,0x0a,0xff,0x01,0x0c,0x6a,0x00,0x01,0xdc,
-0x09,0xff,0x01,0x5e,0x25,0x00,0x01,0xf7,0x2b,0xff,0x01,0x68,0xdb,0x00,0x01,0x26,
-0x2c,0xff,0x01,0x32,0x24,0x00,0x01,0x1e,0x0a,0xff,0x01,0x19,0x6a,0x00,0x01,0xe6,
-0x09,0xff,0x01,0x50,0x25,0x00,0x2c,0xff,0x01,0x53,0xdb,0x00,0x01,0x18,0x2c,0xff,
-0x01,0x40,0x24,0x00,0x01,0x10,0x0a,0xff,0x01,0x20,0x6a,0x00,0x01,0xf0,0x09,0xff,
-0x01,0x43,0x24,0x00,0x01,0x0f,0x2c,0xff,0x01,0x46,0xdb,0x00,0x01,0x0b,0x2c,0xff,
-0x01,0x4f,0x24,0x00,0x01,0x10,0x0a,0xff,0x01,0x25,0x6a,0x00,0x01,0xf0,0x09,0xff,
-0x01,0x40,0x24,0x00,0x01,0x18,0x2c,0xff,0x01,0x3e,0xdc,0x00,0x01,0xfe,0x2b,0xff,
-0x01,0x5d,0x24,0x00,0x01,0x01,0x0a,0xff,0x01,0x30,0x6a,0x00,0x01,0xfb,0x09,0xff,
-0x01,0x40,0x24,0x00,0x01,0x20,0x2c,0xff,0x01,0x30,0xdc,0x00,0x01,0xf0,0x2b,0xff,
-0x01,0x66,0x25,0x00,0x0a,0xff,0x01,0x30,0x6a,0x00,0x0a,0xff,0x01,0x31,0x24,0x00,
-0x01,0x30,0x2c,0xff,0x01,0x26,0xdc,0x00,0x01,0xe0,0x2b,0xff,0x01,0x70,0x25,0x00,
-0x0a,0xff,0x01,0x37,0x6a,0x00,0x0a,0xff,0x01,0x30,0x24,0x00,0x01,0x30,0x2c,0xff,
-0x01,0x20,0xdc,0x00,0x01,0xe0,0x2b,0xff,0x01,0x70,0x25,0x00,0x01,0xf0,0x09,0xff,
-0x01,0x40,0x6a,0x00,0x0a,0xff,0x01,0x30,0x24,0x00,0x01,0x30,0x2c,0xff,0x01,0x20,
-0xdc,0x00,0x01,0xe0,0x2b,0xff,0x01,0x70,0x25,0x00,0x01,0xf0,0x09,0xff,0x01,0x40,
-0x6a,0x00,0x0a,0xff,0x01,0x30,0x24,0x00,0x01,0x30,0x2c,0xff,0x01,0x20,0xdc,0x00,
-0x01,0xe0,0x2b,0xff,0x01,0x70,0x25,0x00,0x01,0xf0,0x09,0xff,0x01,0x40,0x6a,0x00,
-0x0a,0xff,0x01,0x30,0x24,0x00,0x01,0x30,0x2c,0xff,0x01,0x20,0xdc,0x00,0x01,0xe0,
-0x2b,0xff,0x01,0x70,0x25,0x00,0x01,0xf0,0x09,0xff,0x01,0x40,0x6a,0x00,0x0a,0xff,
-0x01,0x30,0x24,0x00,0x01,0x30,0x2c,0xff,0x01,0x20,0xdc,0x00,0x01,0xd3,0x2b,0xff,
-0x01,0x70,0x25,0x00,0x0a,0xff,0x01,0x3c,0x6a,0x00,0x0a,0xff,0x01,0x30,0x24,0x00,
-0x01,0x30,0x2c,0xff,0x01,0x20,0xdc,0x00,0x01,0xdf,0x2b,0xff,0x01,0x70,0x25,0x00,
-0x0a,0xff,0x01,0x30,0x6a,0x00,0x0a,0xff,0x01,0x34,0x24,0x00,0x01,0x23,0x2c,0xff,
-0x01,0x26,0xdc,0x00,0x01,0xe7,0x2b,0xff,0x01,0x6d,0x25,0x00,0x0a,0xff,0x01,0x30,
-0x6a,0x00,0x01,0xf6,0x09,0xff,0x01,0x40,0x24,0x00,0x01,0x20,0x2c,0xff,0x01,0x34,
-0xdc,0x00,0x01,0xf0,0x2b,0xff,0x01,0x60,0x24,0x00,0x01,0x02,0x0a,0xff,0x01,0x30,
-0x6a,0x00,0x01,0xf0,0x09,0xff,0x01,0x43,0x24,0x00,0x01,0x17,0x2c,0xff,0x01,0x41,
-0xdc,0x00,0x2c,0xff,0x01,0x55,0x24,0x00,0x01,0x10,0x0a,0xff,0x01,0x25,0x6a,0x00,
-0x01,0xe8,0x09,0xff,0x01,0x50,0x24,0x00,0x01,0x09,0x2c,0xff,0x01,0x50,0xdb,0x00,
-0x01,0x08,0x2c,0xff,0x01,0x4d,0x24,0x00,0x01,0x16,0x0a,0xff,0x01,0x20,0x6a,0x00,
-0x01,0xe0,0x09,0xff,0x01,0x52,0x25,0x00,0x01,0xfc,0x2b,0xff,0x01,0x5f,0xdb,0x00,
-0x01,0x16,0x2c,0xff,0x01,0x40,0x24,0x00,0x01,0x20,0x0a,0xff,0x01,0x11,0x6a,0x00,
-0x01,0xd9,0x09,0xff,0x01,0x60,0x25,0x00,0x01,0xef,0x2b,0xff,0x01,0x6d,0xdb,0x00,
-0x01,0x2b,0x2c,0xff,0x01,0x35,0x24,0x00,0x01,0x2b,0x0a,0xff,0x01,0x0c,0x6a,0x00,
-0x01,0xcb,0x09,0xff,0x01,0x6f,0x25,0x00,0x01,0xe0,0x2b,0xff,0x01,0x87,0xdb,0x00,
-0x01,0x45,0x2c,0xff,0x01,0x2c,0x24,0x00,0x01,0x30,0x0a,0xff,0x6b,0x00,0x01,0xbd,
-0x09,0xff,0x01,0x7d,0x25,0x00,0x01,0xd1,0x2b,0xff,0x01,0xa2,0xdb,0x00,0x01,0x5a,
-0x2c,0xff,0x01,0x1c,0x24,0x00,0x01,0x2d,0x09,0xff,0x01,0xf3,0x6b,0x00,0x01,0xae,
-0x09,0xff,0x01,0x8b,0x25,0x00,0x01,0xc4,0x2b,0xff,0x01,0xba,0xdb,0x00,0x01,0x73,
-0x2c,0xff,0x01,0x07,0x24,0x00,0x01,0x06,0x01,0xf5,0x08,0xff,0x01,0xc2,0x6b,0x00,
-0x01,0xa0,0x09,0xff,0x01,0x99,0x25,0x00,0x01,0xae,0x2b,0xff,0x01,0xd6,0xdb,0x00,
-0x01,0x8a,0x2b,0xff,0x01,0xef,0x26,0x00,0x01,0x8d,0x08,0xff,0x01,0x54,0x6b,0x00,
-0x01,0x90,0x09,0xff,0x01,0xaa,0x25,0x00,0x01,0x96,0x2b,0xff,0x01,0xf1,0xdb,0x00,
-0x01,0xad,0x2b,0xff,0x01,0xd8,0x26,0x00,0x01,0x0b,0x01,0xc8,0x06,0xff,0x01,0x97,
-0x6c,0x00,0x01,0x7d,0x09,0xff,0x01,0xbe,0x25,0x00,0x01,0x79,0x2c,0xff,0x01,0x13,
-0xda,0x00,0x01,0xd0,0x2b,0xff,0x01,0xc1,0x27,0x00,0x01,0x09,0x01,0x85,0x01,0xea,
-0x02,0xff,0x01,0xd8,0x01,0x63,0x01,0x01,0x6c,0x00,0x01,0x69,0x09,0xff,0x01,0xd5,
-0x25,0x00,0x01,0x60,0x2c,0xff,0x01,0x3b,0xda,0x00,0x01,0xf3,0x2b,0xff,0x01,0xa9,
-0x2a,0x00,0x01,0x19,0x01,0x12,0x6f,0x00,0x01,0x55,0x09,0xff,0x01,0xe8,0x25,0x00,
-0x01,0x47,0x2c,0xff,0x01,0x61,0xd9,0x00,0x01,0x18,0x2c,0xff,0x01,0x93,0x9b,0x00,
-0x01,0x40,0x09,0xff,0x01,0xfc,0x25,0x00,0x01,0x2c,0x2c,0xff,0x01,0x87,0xd9,0x00,
-0x01,0x3b,0x2c,0xff,0x01,0x7a,0x9b,0x00,0x01,0x2a,0x0a,0xff,0x01,0x17,0x24,0x00,
-0x01,0x12,0x2c,0xff,0x01,0xae,0xd9,0x00,0x01,0x67,0x2c,0xff,0x01,0x5b,0x9b,0x00,
-0x01,0x13,0x0a,0xff,0x01,0x31,0x25,0x00,0x01,0xf4,0x2b,0xff,0x01,0xdb,0xd9,0x00,
-0x01,0x97,0x2c,0xff,0x01,0x37,0x9c,0x00,0x01,0xf8,0x09,0xff,0x01,0x4c,0x25,0x00,
-0x01,0xcf,0x2c,0xff,0x01,0x0f,0xd8,0x00,0x01,0xc8,0x2c,0xff,0x01,0x13,0x9c,0x00,
-0x01,0xdb,0x09,0xff,0x01,0x68,0x25,0x00,0x01,0xa8,0x2c,0xff,0x01,0x42,0xd7,0x00,
-0x01,0x03,0x01,0xf5,0x2b,0xff,0x01,0xef,0x9d,0x00,0x01,0xc1,0x09,0xff,0x01,0x83,
-0x25,0x00,0x01,0x81,0x2c,0xff,0x01,0x75,0xd7,0x00,0x01,0x29,0x2c,0xff,0x01,0xcd,
-0x9d,0x00,0x01,0xa7,0x09,0xff,0x01,0xa2,0x25,0x00,0x01,0x5c,0x2c,0xff,0x01,0xa8,
-0xd7,0x00,0x01,0x5d,0x2c,0xff,0x01,0xa8,0x9d,0x00,0x01,0x87,0x09,0xff,0x01,0xc4,
-0x25,0x00,0x01,0x34,0x2c,0xff,0x01,0xe0,0xd7,0x00,0x01,0x9b,0x2c,0xff,0x01,0x84,
-0x9d,0x00,0x01,0x66,0x09,0xff,0x01,0xe6,0x25,0x00,0x01,0x0f,0x2d,0xff,0x01,0x20,
-0xd6,0x00,0x01,0xd8,0x2c,0xff,0x01,0x5e,0x0c,0x00,0x01,0x0e,0x01,0x15,0x01,0x07,
-0x8e,0x00,0x01,0x44,0x0a,0xff,0x01,0x09,0x25,0x00,0x01,0xe6,0x2c,0xff,0x01,0x60,
-0xd5,0x00,0x01,0x17,0x2d,0xff,0x01,0x30,0x0c,0x00,0x01,0x82,0x02,0xff,0x01,0xf9,
-0x01,0xe9,0x01,0xd0,0x01,0xb8,0x01,0x9e,0x01,0x80,0x01,0x5d,0x01,0x3a,0x01,0x14,
-0x85,0x00,0x01,0x22,0x0a,0xff,0x01,0x2b,0x25,0x00,0x01,0xb5,0x2c,0xff,0x01,0xa0,
-0xd5,0x00,0x01,0x54,0x2c,0xff,0x01,0xfc,0x01,0x07,0x0c,0x00,0x01,0xb0,0x0b,0xff,
-0x01,0xe9,0x01,0xba,0x01,0x8c,0x01,0x59,0x01,0x20,0x80,0x00,0x01,0x04,0x01,0xfc,
-0x09,0xff,0x01,0x51,0x25,0x00,0x01,0x82,0x2c,0xff,0x01,0xe0,0xd5,0x00,0x01,0x94,
-0x2c,0xff,0x01,0xd6,0x0d,0x00,0x01,0xdc,0x10,0xff,0x01,0xe7,0x01,0xad,0x01,0x6b,
-0x01,0x26,0x7d,0x00,0x01,0xdd,0x09,0xff,0x01,0x7a,0x25,0x00,0x01,0x4e,0x2d,0xff,
-0x01,0x22,0xd4,0x00,0x01,0xde,0x2c,0xff,0x01,0xa5,0x0c,0x00,0x01,0x0a,0x01,0xfe,
-0x14,0xff,0x01,0xe3,0x01,0x99,0x01,0x4a,0x01,0x07,0x79,0x00,0x01,0xb3,0x09,0xff,
-0x01,0xa2,0x25,0x00,0x01,0x1b,0x2d,0xff,0x01,0x6f,0xd3,0x00,0x01,0x29,0x2d,0xff,
-0x01,0x72,0x0c,0x00,0x01,0x35,0x18,0xff,0x01,0xf4,0x01,0xa8,0x01,0x50,0x01,0x07,
-0x76,0x00,0x01,0x8c,0x09,0xff,0x01,0xcb,0x26,0x00,0x01,0xeb,0x2c,0xff,0x01,0xbd,
-0xd3,0x00,0x01,0x74,0x2d,0xff,0x01,0x3d,0x0c,0x00,0x01,0x61,0x1b,0xff,0x01,0xee,
-0x01,0x9a,0x01,0x36,0x74,0x00,0x01,0x62,0x09,0xff,0x01,0xf2,0x01,0x01,0x25,0x00,
-0x01,0xb8,0x2c,0xff,0x01,0xfb,0x01,0x0f,0xd2,0x00,0x01,0xc0,0x2c,0xff,0x01,0xfd,
-0x01,0x0b,0x0c,0x00,0x01,0x95,0x1e,0xff,0x01,0xd0,0x01,0x6a,0x01,0x0c,0x71,0x00,
-0x01,0x3b,0x0a,0xff,0x01,0x22,0x25,0x00,0x01,0x85,0x2d,0xff,0x01,0x56,0xd1,0x00,
-0x01,0x10,0x01,0xfb,0x2c,0xff,0x01,0xcf,0x0d,0x00,0x01,0xca,0x20,0xff,0x01,0xf0,
-0x01,0x8b,0x01,0x1c,0x6f,0x00,0x01,0x11,0x0a,0xff,0x01,0x51,0x25,0x00,0x01,0x48,
-0x2d,0xff,0x01,0xa6,0xd1,0x00,0x01,0x62,0x2d,0xff,0x01,0x96,0x0c,0x00,0x01,0x07,
-0x01,0xfa,0x22,0xff,0x01,0xfb,0x01,0xa0,0x01,0x24,0x6e,0x00,0x01,0xe1,0x09,0xff,
-0x01,0x80,0x25,0x00,0x01,0x0c,0x01,0xfc,0x2c,0xff,0x01,0xf4,0x01,0x0c,0xd0,0x00,
-0x01,0xba,0x2d,0xff,0x01,0x5a,0x0c,0x00,0x01,0x37,0x25,0xff,0x01,0xfc,0x01,0xa0,
-0x01,0x24,0x6c,0x00,0x01,0xb3,0x09,0xff,0x01,0xb0,0x26,0x00,0x01,0xc8,0x2d,0xff,
-0x01,0x5a,0xcf,0x00,0x01,0x17,0x01,0xfd,0x2d,0xff,0x01,0x20,0x0c,0x00,0x01,0x6d,
-0x27,0xff,0x01,0xfc,0x01,0x95,0x01,0x17,0x6a,0x00,0x01,0x83,0x09,0xff,0x01,0xe1,
-0x26,0x00,0x01,0x88,0x2d,0xff,0x01,0xb5,0xcf,0x00,0x01,0x6d,0x2d,0xff,0x01,0xde,
-0x0d,0x00,0x01,0xa4,0x29,0xff,0x01,0xf4,0x01,0x7a,0x01,0x07,0x68,0x00,0x01,0x54,
-0x0a,0xff,0x01,0x16,0x25,0x00,0x01,0x48,0x2d,0xff,0x01,0xfb,0x01,0x14,0xce,0x00,
-0x01,0xc7,0x2d,0xff,0x01,0x9c,0x0d,0x00,0x01,0xe0,0x2b,0xff,0x01,0xdc,0x01,0x4b,
-0x67,0x00,0x01,0x25,0x0a,0xff,0x01,0x4b,0x25,0x00,0x01,0x0c,0x01,0xfc,0x2d,0xff,
-0x01,0x6d,0xcd,0x00,0x01,0x2a,0x2e,0xff,0x01,0x5c,0x0c,0x00,0x01,0x20,0x2e,0xff,
-0x01,0xaf,0x01,0x18,0x66,0x00,0x01,0xee,0x09,0xff,0x01,0x82,0x26,0x00,0x01,0xc8,
-0x2d,0xff,0x01,0xd4,0xcd,0x00,0x01,0x90,0x2e,0xff,0x01,0x18,0x0c,0x00,0x01,0x60,
-0x2f,0xff,0x01,0xef,0x01,0x60,0x65,0x00,0x01,0xb8,0x09,0xff,0x01,0xb8,0x26,0x00,
-0x01,0x84,0x2e,0xff,0x01,0x3d,0xcb,0x00,0x01,0x0a,0x01,0xf0,0x2d,0xff,0x01,0xd0,
-0x0d,0x00,0x01,0xa0,0x31,0xff,0x01,0xb5,0x01,0x16,0x63,0x00,0x01,0x83,0x09,0xff,
-0x01,0xee,0x01,0x02,0x25,0x00,0x01,0x38,0x2e,0xff,0x01,0xa5,0xcb,0x00,0x01,0x60,
-0x2e,0xff,0x01,0x88,0x0d,0x00,0x01,0xe0,0x32,0xff,0x01,0xe9,0x01,0x4b,0x62,0x00,
-0x01,0x4c,0x0a,0xff,0x01,0x2d,0x25,0x00,0x01,0x02,0x01,0xe9,0x2d,0xff,0x01,0xf9,
-0x01,0x15,0xca,0x00,0x01,0xc9,0x2e,0xff,0x01,0x40,0x0c,0x00,0x01,0x21,0x35,0xff,
-0x01,0x8e,0x01,0x05,0x60,0x00,0x01,0x16,0x0a,0xff,0x01,0x69,0x26,0x00,0x01,0x9e,
-0x2e,0xff,0x01,0x7a,0xc9,0x00,0x01,0x39,0x2e,0xff,0x01,0xee,0x01,0x04,0x0c,0x00,
-0x01,0x69,0x36,0xff,0x01,0xc3,0x01,0x1a,0x60,0x00,0x01,0xd8,0x09,0xff,0x01,0xa7,
-0x26,0x00,0x01,0x50,0x2e,0xff,0x01,0xe8,0x01,0x09,0xc8,0x00,0x01,0xb1,0x2e,0xff,
-0x01,0xa4,0x0d,0x00,0x01,0xb2,0x37,0xff,0x01,0xe8,0x01,0x38,0x5f,0x00,0x01,0x9c,
-0x09,0xff,0x01,0xe4,0x26,0x00,0x01,0x0b,0x01,0xf8,0x2e,0xff,0x01,0x68,0xc7,0x00,
-0x01,0x29,0x01,0xfe,0x2e,0xff,0x01,0x55,0x0c,0x00,0x01,0x08,0x01,0xf6,0x38,0xff,
-0x01,0xf7,0x01,0x58,0x5e,0x00,0x01,0x60,0x0a,0xff,0x01,0x24,0x26,0x00,0x01,0xb6,
-0x2e,0xff,0x01,0xdc,0x01,0x03,0xc6,0x00,0x01,0x9e,0x2e,0xff,0x01,0xf7,0x01,0x0c,
-0x0c,0x00,0x01,0x47,0x3b,0xff,0x01,0x7e,0x01,0x01,0x5c,0x00,0x01,0x23,0x0a,0xff,
-0x01,0x68,0x26,0x00,0x01,0x68,0x2f,0xff,0x01,0x57,0xc5,0x00,0x01,0x1b,0x01,0xfa,
-0x2e,0xff,0x01,0xad,0x0d,0x00,0x01,0x90,0x3c,0xff,0x01,0xa1,0x01,0x03,0x5c,0x00,
-0x01,0xe4,0x09,0xff,0x01,0xac,0x26,0x00,0x01,0x14,0x01,0xfb,0x2e,0xff,0x01,0xd1,
-0x01,0x02,0xc4,0x00,0x01,0x95,0x2f,0xff,0x01,0x58,0x0d,0x00,0x01,0xdd,0x3d,0xff,
-0x01,0xb0,0x01,0x06,0x5b,0x00,0x01,0xa1,0x09,0xff,0x01,0xee,0x01,0x02,0x26,0x00,
-0x01,0xb8,0x2f,0xff,0x01,0x5a,0xc3,0x00,0x01,0x23,0x01,0xfa,0x2e,0xff,0x01,0xf7,
-0x01,0x0c,0x0c,0x00,0x01,0x2f,0x3f,0xff,0x01,0xbb,0x01,0x0a,0x5a,0x00,0x01,0x5e,
-0x0a,0xff,0x01,0x34,0x26,0x00,0x01,0x62,0x2f,0xff,0x01,0xdc,0x01,0x04,0xc2,0x00,
-0x01,0xa3,0x2f,0xff,0x01,0xa9,0x0d,0x00,0x01,0x83,0x40,0xff,0x01,0xc4,0x01,0x0f,
-0x59,0x00,0x01,0x1b,0x0a,0xff,0x01,0x7e,0x26,0x00,0x01,0x0f,0x01,0xf7,0x2f,0xff,
-0x01,0x68,0xc1,0x00,0x01,0x2d,0x01,0xfe,0x2f,0xff,0x01,0x4d,0x0d,0x00,0x01,0xd8,
-0x41,0xff,0x01,0xc1,0x01,0x0a,0x59,0x00,0x01,0xd7,0x09,0xff,0x01,0xc8,0x27,0x00,
-0x01,0xa7,0x2f,0xff,0x01,0xe6,0x01,0x09,0xc0,0x00,0x01,0xb1,0x2f,0xff,0x01,0xeb,
-0x01,0x05,0x0c,0x00,0x01,0x2c,0x43,0xff,0x01,0xb8,0x01,0x06,0x58,0x00,0x01,0x91,
-0x09,0xff,0x01,0xfe,0x01,0x14,0x26,0x00,0x01,0x49,0x30,0xff,0x01,0x7f,0xbf,0x00,
-0x01,0x44,0x30,0xff,0x01,0x92,0x0d,0x00,0x01,0x7d,0x44,0xff,0x01,0xae,0x01,0x03,
-0x57,0x00,0x01,0x47,0x0a,0xff,0x01,0x5e,0x26,0x00,0x01,0x03,0x01,0xe6,0x2f,0xff,
-0x01,0xf7,0x01,0x20,0xbd,0x00,0x01,0x05,0x01,0xd6,0x30,0xff,0x01,0x2f,0x0d,0x00,
-0x01,0xd8,0x45,0xff,0x01,0x9c,0x57,0x00,0x01,0x08,0x01,0xf5,0x09,0xff,0x01,0xab,
-0x27,0x00,0x01,0x84,0x30,0xff,0x01,0xad,0xbd,0x00,0x01,0x74,0x30,0xff,0x01,0xcb,
-0x0d,0x00,0x01,0x36,0x47,0xff,0x01,0x77,0x57,0x00,0x01,0xb2,0x09,0xff,0x01,0xf4,
-0x01,0x09,0x26,0x00,0x01,0x22,0x01,0xfe,0x30,0xff,0x01,0x45,0xbb,0x00,0x01,0x19,
-0x01,0xf2,0x30,0xff,0x01,0x66,0x0d,0x00,0x01,0x94,0x47,0xff,0x01,0xfe,0x01,0x51,
-0x56,0x00,0x01,0x67,0x0a,0xff,0x01,0x4d,0x27,0x00,0x01,0xba,0x30,0xff,0x01,0xd6,
-0x01,0x07,0xba,0x00,0x01,0xa5,0x30,0xff,0x01,0xf2,0x01,0x0d,0x0c,0x00,0x01,0x06,
-0x01,0xec,0x48,0xff,0x01,0xf6,0x01,0x33,0x55,0x00,0x01,0x1b,0x0a,0xff,0x01,0x9f,
-0x27,0x00,0x01,0x50,0x31,0xff,0x01,0x85,0xb9,0x00,0x01,0x4b,0x31,0xff,0x01,0x94,
-0x0d,0x00,0x01,0x50,0x4a,0xff,0x01,0xe2,0x01,0x13,0x55,0x00,0x01,0xc8,0x09,0xff,
-0x01,0xee,0x01,0x05,0x26,0x00,0x01,0x03,0x01,0xe0,0x30,0xff,0x01,0xfb,0x01,0x30,
-0xb7,0x00,0x01,0x10,0x01,0xe5,0x31,0xff,0x01,0x29,0x0d,0x00,0x01,0xae,0x4b,0xff,
-0x01,0xb7,0x01,0x01,0x54,0x00,0x01,0x78,0x0a,0xff,0x01,0x48,0x27,0x00,0x01,0x78,
-0x31,0xff,0x01,0xd0,0x01,0x05,0xb6,0x00,0x01,0xa0,0x31,0xff,0x01,0xbc,0x0d,0x00,
-0x01,0x1a,0x01,0xfc,0x4c,0xff,0x01,0x7b,0x54,0x00,0x01,0x26,0x0a,0xff,0x01,0xa2,
-0x27,0x00,0x01,0x13,0x01,0xf6,0x31,0xff,0x01,0x7e,0xb5,0x00,0x01,0x4b,0x32,0xff,
-0x01,0x4b,0x0d,0x00,0x01,0x7f,0x4d,0xff,0x01,0xfd,0x01,0x3f,0x54,0x00,0x01,0xd4,
-0x09,0xff,0x01,0xf1,0x01,0x07,0x27,0x00,0x01,0x95,0x31,0xff,0x01,0xfa,0x01,0x34,
-0xb3,0x00,0x01,0x10,0x01,0xe2,0x31,0xff,0x01,0xd6,0x01,0x01,0x0c,0x00,0x01,0x03,
-0x01,0xe3,0x4e,0xff,0x01,0xe2,0x01,0x0e,0x53,0x00,0x01,0x7d,0x0a,0xff,0x01,0x53,
-0x27,0x00,0x01,0x24,0x01,0xfe,0x31,0xff,0x01,0xdd,0x01,0x0d,0xb2,0x00,0x01,0xa0,
-0x32,0xff,0x01,0x64,0x0d,0x00,0x01,0x50,0x50,0xff,0x01,0x9e,0x53,0x00,0x01,0x26,
-0x0a,0xff,0x01,0xae,0x28,0x00,0x01,0xad,0x32,0xff,0x01,0xa5,0xb1,0x00,0x01,0x4b,
-0x32,0xff,0x01,0xe7,0x01,0x08,0x0d,0x00,0x01,0xb7,0x51,0xff,0x01,0x4b,0x53,0x00,
-0x01,0xcd,0x09,0xff,0x01,0xfa,0x01,0x14,0x27,0x00,0x01,0x33,0x33,0xff,0x01,0x61,
-0xaf,0x00,0x01,0x0e,0x01,0xe7,0x32,0xff,0x01,0x73,0x0d,0x00,0x01,0x27,0x01,0xfe,
-0x51,0xff,0x01,0xe5,0x01,0x12,0x52,0x00,0x01,0x75,0x0a,0xff,0x01,0x6d,0x28,0x00,
-0x01,0xb8,0x32,0xff,0x01,0xf4,0x01,0x2a,0xae,0x00,0x01,0x94,0x32,0xff,0x01,0xec,
-0x01,0x0c,0x0d,0x00,0x01,0x98,0x53,0xff,0x01,0x98,0x52,0x00,0x01,0x1d,0x01,0xfe,
-0x09,0xff,0x01,0xcc,0x28,0x00,0x01,0x3d,0x33,0xff,0x01,0xdc,0x01,0x11,0xac,0x00,
-0x01,0x36,0x01,0xfe,0x32,0xff,0x01,0x7e,0x0d,0x00,0x01,0x14,0x01,0xf7,0x53,0xff,
-0x01,0xfe,0x01,0x34,0x52,0x00,0x01,0xbd,0x0a,0xff,0x01,0x2d,0x28,0x00,0x01,0xc0,
-0x33,0xff,0x01,0xb9,0x01,0x03,0xaa,0x00,0x01,0x02,0x01,0xcc,0x32,0xff,0x01,0xec,
-0x01,0x0f,0x0d,0x00,0x01,0x7d,0x55,0xff,0x01,0xc9,0x01,0x02,0x51,0x00,0x01,0x5e,
-0x0a,0xff,0x01,0x93,0x28,0x00,0x01,0x39,0x34,0xff,0x01,0x8c,0xaa,0x00,0x01,0x60,
-0x33,0xff,0x01,0x78,0x0d,0x00,0x01,0x08,0x01,0xe9,0x01,0xff,0x01,0xdd,0x01,0xb2,
-0x01,0x8c,0x01,0x6a,0x01,0x54,0x01,0x3a,0x01,0x30,0x01,0x25,0x01,0x20,0x01,0x2a,
-0x01,0x33,0x01,0x40,0x01,0x4f,0x01,0x70,0x01,0x91,0x01,0xb3,0x01,0xdc,0x44,0xff,
-0x01,0x65,0x51,0x00,0x01,0x0b,0x01,0xf3,0x09,0xff,0x01,0xf0,0x01,0x0a,0x28,0x00,
-0x01,0xb8,0x34,0xff,0x01,0x5c,0xa8,0x00,0x01,0x0c,0x01,0xe6,0x32,0xff,0x01,0xec,
-0x01,0x0c,0x0d,0x00,0x01,0x1c,0x01,0x49,0x01,0x12,0x11,0x00,0x01,0x16,0x01,0x4c,
-0x01,0x86,0x01,0xce,0x40,0xff,0x01,0xe9,0x01,0x0c,0x51,0x00,0x01,0x9e,0x0a,0xff,
-0x01,0x60,0x28,0x00,0x01,0x34,0x34,0xff,0x01,0xfa,0x01,0x44,0xa7,0x00,0x01,0x7c,
-0x33,0xff,0x01,0x70,0x26,0x00,0x01,0x1e,0x01,0x6d,0x01,0xc1,0x3e,0xff,0x01,0x7c,
-0x51,0x00,0x01,0x3d,0x0a,0xff,0x01,0xca,0x29,0x00,0x01,0xa9,0x34,0xff,0x01,0xf1,
-0x01,0x31,0xa5,0x00,0x01,0x11,0x01,0xf0,0x32,0xff,0x01,0xde,0x01,0x06,0x29,0x00,
-0x01,0x29,0x01,0x90,0x01,0xf0,0x3b,0xff,0x01,0xf0,0x01,0x12,0x51,0x00,0x01,0xd6,
-0x0a,0xff,0x01,0x33,0x28,0x00,0x01,0x24,0x01,0xfa,0x34,0xff,0x01,0xe7,0x01,0x21,
-0xa4,0x00,0x01,0x88,0x33,0xff,0x01,0x59,0x2c,0x00,0x01,0x0a,0x01,0x71,0x01,0xec,
-0x3a,0xff,0x01,0x89,0x51,0x00,0x01,0x6e,0x0a,0xff,0x01,0xa2,0x29,0x00,0x01,0x93,
-0x35,0xff,0x01,0xda,0x01,0x15,0xa2,0x00,0x01,0x12,0x01,0xf4,0x32,0xff,0x01,0xcc,
-0x01,0x01,0x2e,0x00,0x01,0x0c,0x01,0x78,0x01,0xef,0x38,0xff,0x01,0xf7,0x01,0x16,
-0x50,0x00,0x01,0x10,0x01,0xf6,0x09,0xff,0x01,0xfa,0x01,0x17,0x28,0x00,0x01,0x12,
-0x01,0xee,0x35,0xff,0x01,0xd2,0x01,0x0f,0xa1,0x00,0x01,0x80,0x33,0xff,0x01,0x3b,
-0x31,0x00,0x01,0x17,0x01,0xa4,0x38,0xff,0x01,0x84,0x51,0x00,0x01,0xa0,0x0a,0xff,
-0x01,0x7f,0x29,0x00,0x01,0x6e,0x36,0xff,0x01,0xc9,0x01,0x0f,0x9f,0x00,0x01,0x0c,
-0x01,0xec,0x32,0xff,0x01,0xa7,0x34,0x00,0x01,0x43,0x01,0xdc,0x36,0xff,0x01,0xed,
-0x01,0x0b,0x50,0x00,0x01,0x35,0x0a,0xff,0x01,0xe8,0x01,0x07,0x28,0x00,0x01,0x04,
-0x01,0xd7,0x36,0xff,0x01,0xc9,0x01,0x0f,0x9e,0x00,0x01,0x6a,0x32,0xff,0x01,0xf6,
-0x01,0x1d,0x35,0x00,0x01,0x0d,0x01,0xa6,0x36,0xff,0x01,0x6c,0x51,0x00,0x01,0xc6,
-0x0a,0xff,0x01,0x65,0x29,0x00,0x01,0x42,0x37,0xff,0x01,0xc9,0x01,0x13,0x9c,0x00,
-0x01,0x01,0x01,0xd9,0x32,0xff,0x01,0x7b,0x38,0x00,0x01,0x63,0x01,0xf6,0x34,0xff,
-0x01,0xdf,0x01,0x03,0x50,0x00,0x01,0x58,0x0a,0xff,0x01,0xd9,0x01,0x02,0x29,0x00,
-0x01,0xa8,0x37,0xff,0x01,0xd3,0x01,0x1a,0x9b,0x00,0x01,0x48,0x32,0xff,0x01,0xd8,
-0x01,0x06,0x39,0x00,0x01,0x33,0x01,0xe7,0x34,0xff,0x01,0x4d,0x50,0x00,0x01,0x05,
-0x01,0xe5,0x0a,0xff,0x01,0x52,0x29,0x00,0x01,0x19,0x01,0xf2,0x37,0xff,0x01,0xdc,
-0x01,0x23,0x9a,0x00,0x01,0xaf,0x32,0xff,0x01,0x42,0x3b,0x00,0x01,0x1d,0x01,0xd3,
-0x33,0xff,0x01,0xb0,0x51,0x00,0x01,0x79,0x0a,0xff,0x01,0xc8,0x2a,0x00,0x01,0x6d,
-0x38,0xff,0x01,0xea,0x01,0x34,0x98,0x00,0x01,0x17,0x01,0xfb,0x31,0xff,0x01,0xa3,
-0x3d,0x00,0x01,0x15,0x01,0xcb,0x32,0xff,0x01,0xfc,0x01,0x18,0x50,0x00,0x01,0x11,
-0x01,0xf4,0x0a,0xff,0x01,0x48,0x29,0x00,0x01,0x02,0x01,0xc6,0x38,0xff,0x01,0xf5,
-0x01,0x4d,0x97,0x00,0x01,0x74,0x31,0xff,0x01,0xeb,0x01,0x14,0x3e,0x00,0x01,0x0f,
-0x01,0xcd,0x32,0xff,0x01,0x78,0x51,0x00,0x01,0x8e,0x0a,0xff,0x01,0xc0,0x2a,0x00,
-0x01,0x2b,0x01,0xf9,0x38,0xff,0x01,0xfd,0x01,0x78,0x96,0x00,0x01,0xd3,0x31,0xff,
-0x01,0x59,0x40,0x00,0x01,0x15,0x01,0xd5,0x31,0xff,0x01,0xdb,0x51,0x00,0x01,0x1e,
-0x01,0xfb,0x0a,0xff,0x01,0x40,0x2a,0x00,0x01,0x7f,0x3a,0xff,0x01,0xa5,0x01,0x08,
-0x93,0x00,0x01,0x29,0x31,0xff,0x01,0xb3,0x42,0x00,0x01,0x1f,0x01,0xe8,0x31,0xff,
-0x01,0x2f,0x51,0x00,0x01,0xa3,0x0a,0xff,0x01,0xc0,0x2a,0x00,0x01,0x04,0x01,0xcc,
-0x3a,0xff,0x01,0xca,0x01,0x19,0x92,0x00,0x01,0x83,0x30,0xff,0x01,0xed,0x01,0x19,
-0x43,0x00,0x01,0x37,0x01,0xf8,0x30,0xff,0x01,0x83,0x51,0x00,0x01,0x2a,0x01,0xfe,
-0x0a,0xff,0x01,0x41,0x2a,0x00,0x01,0x2c,0x01,0xf9,0x3a,0xff,0x01,0xe8,0x01,0x43,
-0x91,0x00,0x01,0xd6,0x30,0xff,0x01,0x58,0x45,0x00,0x01,0x66,0x30,0xff,0x01,0xd8,
-0x52,0x00,0x01,0xa8,0x0a,0xff,0x01,0xc8,0x2b,0x00,0x01,0x74,0x3b,0xff,0x01,0xfd,
-0x01,0x83,0x01,0x03,0x82,0x00,0x01,0x4a,0x01,0x41,0x0a,0x00,0x01,0x23,0x30,0xff,
-0x01,0xa9,0x47,0x00,0x01,0xa5,0x30,0xff,0x01,0x2b,0x51,0x00,0x01,0x2f,0x0b,0xff,
-0x01,0x4e,0x2a,0x00,0x01,0x02,0x01,0xbd,0x3c,0xff,0x01,0xc1,0x01,0x1c,0x7f,0x00,
-0x01,0x07,0x01,0x8e,0x01,0xfe,0x01,0x15,0x0a,0x00,0x01,0x70,0x2f,0xff,0x01,0xeb,
-0x01,0x14,0x47,0x00,0x01,0x10,0x01,0xe3,0x2f,0xff,0x01,0x79,0x52,0x00,0x01,0xb0,
-0x0a,0xff,0x01,0xd0,0x01,0x02,0x2a,0x00,0x01,0x1b,0x01,0xed,0x3c,0xff,0x01,0xec,
-0x01,0x50,0x7d,0x00,0x01,0x28,0x01,0xce,0x01,0xff,0x01,0xd4,0x0b,0x00,0x01,0xbb,
-0x2f,0xff,0x01,0x58,0x49,0x00,0x01,0x46,0x2f,0xff,0x01,0xbe,0x52,0x00,0x01,0x31,
-0x0b,0xff,0x01,0x5d,0x2b,0x00,0x01,0x52,0x3e,0xff,0x01,0xa5,0x01,0x11,0x79,0x00,
-0x01,0x03,0x01,0x75,0x01,0xf8,0x02,0xff,0x01,0x96,0x0a,0x00,0x01,0x08,0x01,0xf8,
-0x2e,0xff,0x01,0xb3,0x4b,0x00,0x01,0xa8,0x2e,0xff,0x01,0xf8,0x01,0x0a,0x52,0x00,
-0x01,0xaa,0x0a,0xff,0x01,0xe2,0x01,0x09,0x2b,0x00,0x01,0x91,0x3e,0xff,0x01,0xe5,
-0x01,0x4b,0x77,0x00,0x01,0x28,0x01,0xc8,0x04,0xff,0x01,0x5c,0x0a,0x00,0x01,0x40,
-0x2e,0xff,0x01,0xfa,0x01,0x25,0x4b,0x00,0x01,0x1b,0x01,0xf4,0x2e,0xff,0x01,0x45,
-0x52,0x00,0x01,0x29,0x01,0xfc,0x0a,0xff,0x01,0x78,0x2b,0x00,0x01,0x06,0x01,0xca,
-0x3f,0xff,0x01,0xa7,0x01,0x19,0x73,0x00,0x01,0x07,0x01,0x7c,0x01,0xf8,0x05,0xff,
-0x01,0x26,0x0a,0x00,0x01,0x84,0x2e,0xff,0x01,0x93,0x4d,0x00,0x01,0x83,0x2e,0xff,
-0x01,0x8a,0x53,0x00,0x01,0xa0,0x0a,0xff,0x01,0xf1,0x01,0x15,0x2b,0x00,0x01,0x21,
-0x01,0xef,0x3f,0xff,0x01,0xf1,0x01,0x6c,0x01,0x03,0x70,0x00,0x01,0x43,0x01,0xd9,
-0x06,0xff,0x01,0xed,0x0b,0x00,0x01,0xbd,0x2d,0xff,0x01,0xf4,0x01,0x15,0x4d,0x00,
-0x01,0x10,0x01,0xed,0x2d,0xff,0x01,0xc7,0x53,0x00,0x01,0x1f,0x01,0xfa,0x0a,0xff,
-0x01,0x98,0x2c,0x00,0x01,0x49,0x01,0xfe,0x40,0xff,0x01,0xcc,0x01,0x3c,0x6d,0x00,
-0x01,0x1f,0x01,0xa8,0x08,0xff,0x01,0xbd,0x0a,0x00,0x01,0x03,0x01,0xf3,0x2d,0xff,
-0x01,0x8d,0x4f,0x00,0x01,0x7f,0x2d,0xff,0x01,0xf7,0x01,0x04,0x53,0x00,0x01,0x8e,
-0x0a,0xff,0x01,0xfd,0x01,0x30,0x2c,0x00,0x01,0x7d,0x42,0xff,0x01,0xac,0x01,0x22,
-0x69,0x00,0x01,0x0e,0x01,0x87,0x01,0xf7,0x09,0xff,0x01,0x8e,0x0a,0x00,0x01,0x2d,
-0x2d,0xff,0x01,0xfc,0x01,0x1e,0x4f,0x00,0x01,0x14,0x01,0xf7,0x2d,0xff,0x01,0x2e,
-0x53,0x00,0x01,0x12,0x01,0xef,0x0a,0xff,0x01,0xc3,0x01,0x01,0x2b,0x00,0x01,0x01,
-0x01,0xb1,0x42,0xff,0x01,0xfa,0x01,0x8d,0x01,0x14,0x65,0x00,0x01,0x06,0x01,0x6a,
-0x01,0xea,0x0b,0xff,0x01,0x5f,0x0a,0x00,0x01,0x60,0x2d,0xff,0x01,0xa7,0x51,0x00,
-0x01,0x9b,0x2d,0xff,0x01,0x65,0x54,0x00,0x01,0x73,0x0b,0xff,0x01,0x59,0x2c,0x00,
-0x01,0x0c,0x01,0xd1,0x43,0xff,0x01,0xf4,0x01,0x88,0x01,0x11,0x61,0x00,0x01,0x06,
-0x01,0x68,0x01,0xe2,0x0d,0xff,0x01,0x35,0x0a,0x00,0x01,0x8f,0x2d,0xff,0x01,0x44,
-0x51,0x00,0x01,0x36,0x2d,0xff,0x01,0x98,0x54,0x00,0x01,0x06,0x01,0xdf,0x0a,0xff,
-0x01,0xe6,0x01,0x0e,0x2c,0x00,0x01,0x20,0x01,0xea,0x44,0xff,0x01,0xf0,0x01,0x80,
-0x01,0x14,0x5d,0x00,0x01,0x08,0x01,0x66,0x01,0xdf,0x0f,0xff,0x01,0x0f,0x0a,0x00,
-0x01,0xbc,0x2c,0xff,0x01,0xe4,0x01,0x02,0x52,0x00,0x01,0xd5,0x2c,0xff,0x01,0xc5,
-0x55,0x00,0x01,0x54,0x0b,0xff,0x01,0x92,0x2d,0x00,0x01,0x3c,0x01,0xf8,0x45,0xff,
-0x01,0xf5,0x01,0x94,0x01,0x22,0x59,0x00,0x01,0x11,0x01,0x7b,0x01,0xe8,0x10,0xff,
-0x01,0xe9,0x0b,0x00,0x01,0xe7,0x2c,0xff,0x01,0x89,0x53,0x00,0x01,0x7d,0x2c,0xff,
-0x01,0xeb,0x56,0x00,0x01,0xbe,0x0a,0xff,0x01,0xfd,0x01,0x33,0x2d,0x00,0x01,0x55,
-0x47,0xff,0x01,0xfc,0x01,0xaa,0x01,0x3d,0x55,0x00,0x01,0x2a,0x01,0x94,0x01,0xf4,
-0x12,0xff,0x01,0xc7,0x0a,0x00,0x01,0x0d,0x2d,0xff,0x01,0x39,0x53,0x00,0x01,0x2c,
-0x2d,0xff,0x01,0x0f,0x55,0x00,0x01,0x2c,0x01,0xfc,0x0a,0xff,0x01,0xcc,0x01,0x03,
-0x2d,0x00,0x01,0x74,0x49,0xff,0x01,0xd3,0x01,0x6b,0x01,0x0e,0x4f,0x00,0x01,0x05,
-0x01,0x55,0x01,0xc0,0x15,0xff,0x01,0xa8,0x0a,0x00,0x01,0x2f,0x2c,0xff,0x01,0xee,
-0x01,0x03,0x54,0x00,0x01,0xe1,0x2c,0xff,0x01,0x35,0x56,0x00,0x01,0x93,0x0b,0xff,
-0x01,0x70,0x2e,0x00,0x01,0x92,0x4a,0xff,0x01,0xf4,0x01,0xa0,0x01,0x43,0x01,0x02,
-0x4a,0x00,0x01,0x34,0x01,0x92,0x01,0xeb,0x17,0xff,0x01,0x8a,0x0a,0x00,0x01,0x53,
-0x2c,0xff,0x01,0xa9,0x55,0x00,0x01,0x9d,0x2c,0xff,0x01,0x5b,0x56,0x00,0x01,0x11,
-0x01,0xea,0x0a,0xff,0x01,0xf6,0x01,0x23,0x2d,0x00,0x01,0x01,0x01,0xa6,0x4c,0xff,
-0x01,0xe4,0x01,0x89,0x01,0x31,0x45,0x00,0x01,0x28,0x01,0x7c,0x01,0xd5,0x1a,0xff,
-0x01,0x6f,0x0a,0x00,0x01,0x70,0x2c,0xff,0x01,0x68,0x55,0x00,0x01,0x5d,0x2c,0xff,
-0x01,0x78,0x57,0x00,0x01,0x5c,0x0b,0xff,0x01,0xbf,0x01,0x01,0x2d,0x00,0x01,0x06,
-0x01,0xb7,0x4e,0xff,0x01,0xdf,0x01,0x8d,0x01,0x3d,0x01,0x02,0x3d,0x00,0x01,0x01,
-0x01,0x31,0x01,0x82,0x01,0xd3,0x1d,0xff,0x01,0x59,0x0a,0x00,0x01,0x89,0x2c,0xff,
-0x01,0x35,0x55,0x00,0x01,0x28,0x2c,0xff,0x01,0x8e,0x57,0x00,0x01,0x01,0x01,0xbd,
-0x0b,0xff,0x01,0x66,0x2e,0x00,0x01,0x0a,0x01,0xc0,0x50,0xff,0x01,0xec,0x01,0xa7,
-0x01,0x61,0x01,0x1b,0x37,0x00,0x01,0x12,0x01,0x57,0x01,0xa0,0x01,0xe8,0x20,0xff,
-0x01,0x45,0x0a,0x00,0x01,0xa2,0x2b,0xff,0x01,0xfc,0x01,0x07,0x55,0x00,0x01,0x02,
-0x01,0xf3,0x2b,0xff,0x01,0xa6,0x58,0x00,0x01,0x27,0x01,0xf9,0x0a,0xff,0x01,0xf2,
-0x01,0x21,0x2e,0x00,0x01,0x0f,0x01,0xc9,0x53,0xff,0x01,0xd5,0x01,0x99,0x01,0x5d,
-0x01,0x22,0x2f,0x00,0x01,0x19,0x01,0x57,0x01,0x94,0x01,0xd4,0x01,0xfe,0x23,0xff,
-0x01,0x30,0x0a,0x00,0x01,0xba,0x2b,0xff,0x01,0xd4,0x57,0x00,0x01,0xcb,0x2b,0xff,
-0x01,0xba,0x59,0x00,0x01,0x7f,0x0b,0xff,0x01,0xc1,0x01,0x02,0x2e,0x00,0x01,0x0f,
-0x01,0xcd,0x56,0xff,0x01,0xe7,0x01,0xb3,0x01,0x82,0x01,0x52,0x01,0x20,0x24,0x00,
-0x01,0x01,0x01,0x20,0x01,0x4b,0x01,0x7e,0x01,0xb2,0x01,0xe5,0x28,0xff,0x01,0x20,
-0x0a,0x00,0x01,0xc9,0x2b,0xff,0x01,0xb2,0x57,0x00,0x01,0xa5,0x2b,0xff,0x01,0xd2,
-0x59,0x00,0x01,0x07,0x01,0xd4,0x0b,0xff,0x01,0x73,0x2f,0x00,0x01,0x15,0x01,0xc9,
-0x5a,0xff,0x01,0xf4,0x01,0xcf,0x01,0xa8,0x01,0x81,0x01,0x5d,0x01,0x41,0x01,0x25,
-0x01,0x08,0x15,0x00,0x01,0x06,0x01,0x21,0x01,0x40,0x01,0x60,0x01,0x80,0x01,0xa2,
-0x01,0xcd,0x01,0xf4,0x2d,0xff,0x01,0x13,0x0a,0x00,0x01,0xd8,0x2b,0xff,0x01,0x94,
-0x57,0x00,0x01,0x85,0x2b,0xff,0x01,0xe0,0x5a,0x00,0x01,0x36,0x01,0xfd,0x0a,0xff,
-0x01,0xf8,0x01,0x2b,0x2f,0x00,0x01,0x0f,0x01,0xc9,0x61,0xff,0x01,0xec,0x01,0xd9,
-0x01,0xc7,0x01,0xb5,0x01,0xa3,0x01,0x96,0x01,0x90,0x01,0x85,0x06,0x80,0x01,0x90,
-0x01,0x9a,0x01,0xa4,0x01,0xb2,0x01,0xc6,0x01,0xda,0x01,0xf0,0x35,0xff,0x01,0x07,
-0x0a,0x00,0x01,0xe7,0x2b,0xff,0x01,0x77,0x57,0x00,0x01,0x6c,0x2b,0xff,0x01,0xed,
-0x5b,0x00,0x01,0x8c,0x0b,0xff,0x01,0xd2,0x01,0x08,0x2f,0x00,0x01,0x0f,0x01,0xc9,
-0xaa,0xff,0x0b,0x00,0x01,0xf0,0x2b,0xff,0x01,0x60,0x57,0x00,0x01,0x57,0x2b,0xff,
-0x01,0xf0,0x5b,0x00,0x01,0x0a,0x01,0xdb,0x0b,0xff,0x01,0x94,0x30,0x00,0x01,0x0b,
-0x01,0xbd,0xa9,0xff,0x0b,0x00,0x01,0xf0,0x2b,0xff,0x01,0x59,0x57,0x00,0x01,0x4d,
-0x2b,0xff,0x01,0xfb,0x5c,0x00,0x01,0x39,0x01,0xfd,0x0b,0xff,0x01,0x4e,0x30,0x00,
-0x01,0x06,0x01,0xaf,0xa7,0xff,0x01,0xf3,0x0b,0x00,0x01,0xfd,0x2b,0xff,0x01,0x50,
-0x57,0x00,0x01,0x40,0x2c,0xff,0x5d,0x00,0x01,0x86,0x0b,0xff,0x01,0xec,0x01,0x1c,
-0x30,0x00,0x01,0x03,0x01,0x9e,0xa6,0xff,0x01,0xf0,0x0b,0x00,0x2c,0xff,0x01,0x46,
-0x57,0x00,0x01,0x40,0x2c,0xff,0x5d,0x00,0x01,0x06,0x01,0xd0,0x0b,0xff,0x01,0xc4,
-0x01,0x05,0x30,0x00,0x01,0x01,0x01,0x81,0xa5,0xff,0x01,0xfe,0x0b,0x00,0x01,0xf6,
-0x2b,0xff,0x01,0x50,0x57,0x00,0x01,0x40,0x2c,0xff,0x5e,0x00,0x01,0x2d,0x01,0xf8,
-0x0b,0xff,0x01,0x8c,0x32,0x00,0x01,0x65,0x01,0xfd,0xa4,0xff,0x0b,0x00,0x01,0xf0,
-0x2b,0xff,0x01,0x52,0x57,0x00,0x01,0x4b,0x2b,0xff,0x01,0xfd,0x5f,0x00,0x01,0x6d,
-0x0c,0xff,0x01,0x50,0x32,0x00,0x01,0x49,0x01,0xf1,0xa3,0xff,0x01,0x01,0x0a,0x00,
-0x01,0xee,0x2b,0xff,0x01,0x65,0x57,0x00,0x01,0x5a,0x2b,0xff,0x01,0xf0,0x5f,0x00,
-0x01,0x01,0x01,0xb4,0x0b,0xff,0x01,0xef,0x01,0x24,0x32,0x00,0x01,0x2b,0x01,0xe0,
-0xa2,0xff,0x01,0x10,0x0a,0x00,0x01,0xe0,0x2b,0xff,0x01,0x78,0x57,0x00,0x01,0x6d,
-0x2b,0xff,0x01,0xf0,0x60,0x00,0x01,0x14,0x01,0xe6,0x0b,0xff,0x01,0xd4,0x01,0x0c,
-0x32,0x00,0x01,0x16,0x01,0xc4,0xa1,0xff,0x01,0x1c,0x0a,0x00,0x01,0xd7,0x2b,0xff,
-0x01,0x92,0x57,0x00,0x01,0x8a,0x2b,0xff,0x01,0xe1,0x61,0x00,0x01,0x43,0x01,0xfd,
-0x0b,0xff,0x01,0xac,0x01,0x01,0x32,0x00,0x01,0x06,0x01,0x96,0xa0,0xff,0x01,0x27,
-0x0a,0x00,0x01,0xc4,0x2b,0xff,0x01,0xb3,0x57,0x00,0x01,0xaa,0x2b,0xff,0x01,0xcc,
-0x62,0x00,0x01,0x80,0x0c,0xff,0x01,0x7a,0x34,0x00,0x01,0x64,0x01,0xfa,0x9e,0xff,
-0x01,0x3a,0x0a,0x00,0x01,0xb0,0x2b,0xff,0x01,0xd8,0x57,0x00,0x01,0xcf,0x2b,0xff,
-0x01,0xb9,0x62,0x00,0x01,0x03,0x01,0xba,0x0b,0xff,0x01,0xfe,0x01,0x50,0x34,0x00,
-0x01,0x36,0x01,0xe0,0x9d,0xff,0x01,0x4f,0x0a,0x00,0x01,0x9c,0x2b,0xff,0x01,0xfd,
-0x01,0x09,0x55,0x00,0x01,0x04,0x01,0xf9,0x2b,0xff,0x01,0xa6,0x63,0x00,0x01,0x16,
-0x01,0xe4,0x0b,0xff,0x01,0xf5,0x01,0x31,0x34,0x00,0x01,0x12,0x01,0xb3,0x9c,0xff,
-0x01,0x65,0x0a,0x00,0x01,0x89,0x2c,0xff,0x01,0x36,0x55,0x00,0x01,0x2d,0x2c,0xff,
-0x01,0x90,0x64,0x00,0x01,0x3b,0x01,0xfa,0x0b,0xff,0x01,0xe2,0x01,0x19,0x34,0x00,
-0x01,0x01,0x01,0x77,0x01,0xfb,0x9a,0xff,0x01,0x7d,0x0a,0x00,0x01,0x68,0x2c,0xff,
-0x01,0x71,0x55,0x00,0x01,0x68,0x2c,0xff,0x01,0x72,0x65,0x00,0x01,0x6a,0x0c,0xff,
-0x01,0xcb,0x01,0x0a,0x35,0x00,0x01,0x35,0x01,0xdc,0x99,0xff,0x01,0x9b,0x0a,0x00,
-0x01,0x48,0x2c,0xff,0x01,0xad,0x55,0x00,0x01,0xa4,0x2c,0xff,0x01,0x52,0x66,0x00,
-0x01,0x9d,0x0c,0xff,0x01,0xb3,0x01,0x03,0x35,0x00,0x01,0x0d,0x01,0xa1,0x98,0xff,
-0x01,0xb8,0x0a,0x00,0x01,0x28,0x2c,0xff,0x01,0xf0,0x01,0x04,0x53,0x00,0x01,0x02,
-0x01,0xea,0x2c,0xff,0x01,0x31,0x66,0x00,0x01,0x07,0x01,0xc9,0x0c,0xff,0x01,0x98,
-0x37,0x00,0x01,0x50,0x01,0xe9,0x96,0xff,0x01,0xd8,0x0a,0x00,0x01,0x08,0x2d,0xff,
-0x01,0x3f,0x53,0x00,0x01,0x35,0x2d,0xff,0x01,0x10,0x67,0x00,0x01,0x1b,0x01,0xe7,
-0x0c,0xff,0x01,0x79,0x37,0x00,0x01,0x15,0x01,0xab,0x95,0xff,0x01,0xfa,0x01,0x03,
-0x0a,0x00,0x01,0xe0,0x2c,0xff,0x01,0x93,0x53,0x00,0x01,0x88,0x2c,0xff,0x01,0xe9,
-0x69,0x00,0x01,0x34,0x01,0xf6,0x0c,0xff,0x01,0x63,0x38,0x00,0x01,0x5a,0x01,0xed,
-0x94,0xff,0x01,0x23,0x0a,0x00,0x01,0xb1,0x2c,0xff,0x01,0xe6,0x01,0x03,0x51,0x00,
-0x01,0x01,0x01,0xe1,0x2c,0xff,0x01,0xbb,0x6a,0x00,0x01,0x57,0x0c,0xff,0x01,0xfd,
-0x01,0x52,0x38,0x00,0x01,0x15,0x01,0xa2,0x93,0xff,0x01,0x4b,0x0a,0x00,0x01,0x84,
-0x2d,0xff,0x01,0x4d,0x51,0x00,0x01,0x43,0x2d,0xff,0x01,0x8e,0x6b,0x00,0x01,0x7d,
-0x0c,0xff,0x01,0xfa,0x01,0x42,0x39,0x00,0x01,0x44,0x01,0xdc,0x91,0xff,0x01,0x77,
-0x0a,0x00,0x01,0x56,0x2d,0xff,0x01,0xb3,0x51,0x00,0x01,0xaa,0x2d,0xff,0x01,0x60,
-0x6b,0x00,0x01,0x01,0x01,0xa0,0x0c,0xff,0x01,0xf3,0x01,0x37,0x39,0x00,0x01,0x08,
-0x01,0x85,0x01,0xf9,0x8f,0xff,0x01,0xa5,0x0a,0x00,0x01,0x26,0x2d,0xff,0x01,0xfe,
-0x01,0x26,0x4f,0x00,0x01,0x1e,0x01,0xfc,0x2d,0xff,0x01,0x2e,0x6c,0x00,0x01,0x06,
-0x01,0xba,0x0c,0xff,0x01,0xf1,0x01,0x36,0x3a,0x00,0x01,0x23,0x01,0xb1,0x8e,0xff,
-0x01,0xd5,0x0b,0x00,0x01,0xea,0x2d,0xff,0x01,0x98,0x4f,0x00,0x01,0x90,0x2d,0xff,
-0x01,0xf2,0x01,0x03,0x6d,0x00,0x01,0x0f,0x01,0xd0,0x0c,0xff,0x01,0xeb,0x01,0x2d,
-0x3b,0x00,0x01,0x47,0x01,0xd6,0x8c,0xff,0x01,0xfd,0x01,0x0c,0x0a,0x00,0x01,0xb1,
-0x2d,0xff,0x01,0xfa,0x01,0x1e,0x4d,0x00,0x01,0x19,0x01,0xf7,0x2d,0xff,0x01,0xb9,
-0x6f,0x00,0x01,0x1b,0x01,0xe2,0x0c,0xff,0x01,0xeb,0x01,0x2d,0x3b,0x00,0x01,0x04,
-0x01,0x6d,0x01,0xea,0x8b,0xff,0x01,0x3f,0x0a,0x00,0x01,0x76,0x2e,0xff,0x01,0x9c,
-0x4d,0x00,0x01,0x93,0x2e,0xff,0x01,0x7e,0x70,0x00,0x01,0x27,0x01,0xeb,0x0c,0xff,
-0x01,0xeb,0x01,0x2d,0x3c,0x00,0x01,0x0c,0x01,0x80,0x01,0xf4,0x89,0xff,0x01,0x76,
-0x0a,0x00,0x01,0x39,0x2e,0xff,0x01,0xfe,0x01,0x30,0x4b,0x00,0x01,0x29,0x01,0xfc,
-0x2e,0xff,0x01,0x42,0x71,0x00,0x01,0x34,0x01,0xf1,0x0c,0xff,0x01,0xeb,0x01,0x2d,
-0x3d,0x00,0x01,0x16,0x01,0x93,0x01,0xfa,0x87,0xff,0x01,0xb4,0x0a,0x00,0x01,0x03,
-0x01,0xef,0x2e,0xff,0x01,0xc3,0x01,0x01,0x4a,0x00,0x01,0xba,0x2e,0xff,0x01,0xf5,
-0x01,0x07,0x72,0x00,0x01,0x41,0x01,0xf8,0x0c,0xff,0x01,0xeb,0x01,0x37,0x3e,0x00,
-0x01,0x1e,0x01,0x96,0x01,0xf7,0x85,0xff,0x01,0xf1,0x01,0x02,0x0a,0x00,0x01,0xa9,
-0x2f,0xff,0x01,0x67,0x49,0x00,0x01,0x5e,0x2f,0xff,0x01,0xb3,0x74,0x00,0x01,0x4e,
-0x01,0xfa,0x0c,0xff,0x01,0xf1,0x01,0x3d,0x3f,0x00,0x01,0x19,0x01,0x90,0x01,0xf7,
-0x83,0xff,0x01,0xfe,0x01,0x24,0x0a,0x00,0x01,0x62,0x2f,0xff,0x01,0xf2,0x01,0x20,
-0x47,0x00,0x01,0x1b,0x01,0xed,0x2f,0xff,0x01,0x6c,0x75,0x00,0x01,0x55,0x01,0xfd,
-0x0c,0xff,0x01,0xf6,0x01,0x49,0x40,0x00,0x01,0x18,0x01,0x85,0x01,0xed,0x7f,0xff,
-0x01,0xf7,0x01,0x96,0x01,0x24,0x0b,0x00,0x01,0x1a,0x30,0xff,0x01,0xc4,0x01,0x03,
-0x45,0x00,0x01,0x01,0x01,0xbc,0x30,0xff,0x01,0x22,0x76,0x00,0x01,0x5b,0x01,0xfd,
-0x0c,0xff,0x01,0xfa,0x01,0x56,0x41,0x00,0x01,0x0b,0x01,0x6c,0x01,0xde,0x7b,0xff,
-0x01,0xeb,0x01,0x7f,0x01,0x14,0x0e,0x00,0x01,0xc8,0x30,0xff,0x01,0x88,0x45,0x00,
-0x01,0x7f,0x30,0xff,0x01,0xce,0x78,0x00,0x01,0x63,0x0d,0xff,0x01,0xfd,0x01,0x6b,
-0x42,0x00,0x01,0x02,0x01,0x52,0x01,0xbc,0x77,0xff,0x01,0xc8,0x01,0x5e,0x01,0x07,
-0x10,0x00,0x01,0x6f,0x31,0xff,0x01,0x54,0x43,0x00,0x01,0x4b,0x01,0xfe,0x30,0xff,
-0x01,0x78,0x79,0x00,0x01,0x61,0x01,0xfd,0x0d,0xff,0x01,0x86,0x01,0x01,0x43,0x00,
-0x01,0x26,0x01,0x8f,0x01,0xef,0x71,0xff,0x01,0xf6,0x01,0x9f,0x01,0x33,0x13,0x00,
-0x01,0x1a,0x01,0xfe,0x30,0xff,0x01,0xf6,0x01,0x36,0x41,0x00,0x01,0x30,0x01,0xf3,
-0x31,0xff,0x01,0x23,0x7a,0x00,0x01,0x5b,0x01,0xfd,0x0d,0xff,0x01,0xa0,0x01,0x05,
-0x44,0x00,0x01,0x0a,0x01,0x5e,0x01,0xbe,0x01,0xfe,0x6c,0xff,0x01,0xc6,0x01,0x65,
-0x01,0x0e,0x16,0x00,0x01,0xc3,0x31,0xff,0x01,0xeb,0x01,0x26,0x3f,0x00,0x01,0x24,
-0x01,0xe5,0x31,0xff,0x01,0xcd,0x7c,0x00,0x01,0x5b,0x01,0xfd,0x0d,0xff,0x01,0xbb,
-0x01,0x0f,0x46,0x00,0x01,0x20,0x01,0x7e,0x01,0xdb,0x67,0xff,0x01,0xe2,0x01,0x89,
-0x01,0x28,0x19,0x00,0x01,0x63,0x32,0xff,0x01,0xe4,0x01,0x24,0x3d,0x00,0x01,0x1c,
-0x01,0xde,0x32,0xff,0x01,0x6d,0x7d,0x00,0x01,0x54,0x01,0xfa,0x0d,0xff,0x01,0xd6,
-0x01,0x21,0x47,0x00,0x01,0x01,0x01,0x38,0x01,0x8d,0x01,0xe2,0x61,0xff,0x01,0xe6,
-0x01,0x93,0x01,0x3a,0x01,0x01,0x1b,0x00,0x01,0x0c,0x01,0xf3,0x32,0xff,0x01,0xe4,
-0x01,0x26,0x3b,0x00,0x01,0x24,0x01,0xdf,0x32,0xff,0x01,0xf8,0x01,0x11,0x7e,0x00,
-0x01,0x47,0x01,0xf6,0x0d,0xff,0x01,0xea,0x01,0x39,0x49,0x00,0x01,0x01,0x01,0x38,
-0x01,0x8d,0x01,0xe0,0x5b,0xff,0x01,0xdf,0x01,0x90,0x01,0x41,0x01,0x03,0x1f,0x00,
-0x01,0x9a,0x33,0xff,0x01,0xeb,0x01,0x36,0x39,0x00,0x01,0x31,0x01,0xe6,0x33,0xff,
-0x01,0xa3,0x80,0x00,0x01,0x3b,0x01,0xf1,0x0d,0xff,0x01,0xf8,0x01,0x5e,0x4c,0x00,
-0x01,0x2b,0x01,0x78,0x01,0xc5,0x01,0xfd,0x53,0xff,0x01,0xfd,0x01,0xc9,0x01,0x7c,
-0x01,0x2e,0x23,0x00,0x01,0x35,0x34,0xff,0x01,0xf6,0x01,0x54,0x37,0x00,0x01,0x4c,
-0x01,0xf3,0x34,0xff,0x01,0x3f,0x81,0x00,0x01,0x31,0x01,0xe9,0x0e,0xff,0x01,0x8f,
-0x01,0x03,0x4d,0x00,0x01,0x13,0x01,0x57,0x01,0x9a,0x01,0xdd,0x4d,0xff,0x01,0xdf,
-0x01,0x9a,0x01,0x53,0x01,0x12,0x27,0x00,0x01,0xc8,0x35,0xff,0x01,0x87,0x01,0x03,
-0x33,0x00,0x01,0x02,0x01,0x80,0x01,0xfe,0x34,0xff,0x01,0xd2,0x83,0x00,0x01,0x22,
-0x01,0xdb,0x0e,0xff,0x01,0xbc,0x01,0x12,0x50,0x00,0x01,0x20,0x01,0x64,0x01,0xa0,
-0x01,0xda,0x45,0xff,0x01,0xd8,0x01,0x9c,0x01,0x5f,0x01,0x22,0x2b,0x00,0x01,0x55,
-0x36,0xff,0x01,0xc3,0x01,0x20,0x31,0x00,0x01,0x1c,0x01,0xbd,0x36,0xff,0x01,0x5d,
-0x84,0x00,0x01,0x15,0x01,0xca,0x0e,0xff,0x01,0xdf,0x01,0x33,0x53,0x00,0x01,0x15,
-0x01,0x4e,0x01,0x88,0x01,0xbc,0x01,0xed,0x3b,0xff,0x01,0xeb,0x01,0xb7,0x01,0x82,
-0x01,0x4e,0x01,0x15,0x2f,0x00,0x01,0x03,0x01,0xde,0x36,0xff,0x01,0xf2,0x01,0x67,
-0x01,0x01,0x2d,0x00,0x01,0x01,0x01,0x61,0x01,0xef,0x36,0xff,0x01,0xe5,0x01,0x06,
-0x85,0x00,0x01,0x0a,0x01,0xb5,0x0e,0xff,0x01,0xf8,0x01,0x64,0x57,0x00,0x01,0x1e,
-0x01,0x4f,0x01,0x81,0x01,0xac,0x01,0xd3,0x01,0xfa,0x2f,0xff,0x01,0xfa,0x01,0xd0,
-0x01,0xa5,0x01,0x7b,0x01,0x4e,0x01,0x1e,0x35,0x00,0x01,0x6d,0x38,0xff,0x01,0xc2,
-0x01,0x30,0x2b,0x00,0x01,0x2c,0x01,0xbd,0x38,0xff,0x01,0x76,0x87,0x00,0x01,0x03,
-0x01,0x94,0x0f,0xff,0x01,0x9f,0x01,0x09,0x5a,0x00,0x01,0x03,0x01,0x24,0x01,0x4e,
-0x01,0x70,0x01,0x90,0x01,0xb0,0x01,0xd0,0x01,0xf0,0x21,0xff,0x01,0xe9,0x01,0xce,
-0x01,0xb0,0x01,0x8d,0x01,0x6b,0x01,0x46,0x01,0x23,0x01,0x04,0x3a,0x00,0x01,0x09,
-0x01,0xe7,0x38,0xff,0x01,0xfe,0x01,0x9b,0x01,0x1e,0x27,0x00,0x01,0x1a,0x01,0x99,
-0x01,0xfc,0x38,0xff,0x01,0xec,0x01,0x0c,0x89,0x00,0x01,0x6d,0x01,0xfd,0x0e,0xff,
-0x01,0xd4,0x01,0x2b,0x61,0x00,0x01,0x09,0x01,0x21,0x01,0x38,0x01,0x4f,0x01,0x67,
-0x01,0x79,0x01,0x88,0x01,0x97,0x01,0xa6,0x01,0xb4,0x01,0xc0,0x01,0xc1,0x02,0xd0,
-0x01,0xda,0x02,0xe0,0x01,0xd3,0x03,0xd0,0x01,0xc2,0x01,0xbc,0x01,0xb0,0x01,0xa5,
-0x01,0x98,0x01,0x86,0x01,0x74,0x01,0x62,0x01,0x4e,0x01,0x39,0x01,0x1e,0x01,0x05,
-0x43,0x00,0x01,0x6e,0x3a,0xff,0x01,0xfa,0x01,0x98,0x01,0x26,0x23,0x00,0x01,0x22,
-0x01,0x93,0x01,0xf7,0x3a,0xff,0x01,0x78,0x8b,0x00,0x01,0x4a,0x01,0xf3,0x0e,0xff,
-0x01,0xf7,0x01,0x65,0xc4,0x00,0x01,0x06,0x01,0xe2,0x3b,0xff,0x01,0xfe,0x01,0xb3,
-0x01,0x4d,0x01,0x03,0x1d,0x00,0x01,0x02,0x01,0x4a,0x01,0xaf,0x01,0xfd,0x3b,0xff,
-0x01,0xe7,0x01,0x0a,0x8c,0x00,0x01,0x2c,0x01,0xdd,0x0f,0xff,0x01,0xa9,0x01,0x10,
-0xc3,0x00,0x01,0x66,0x3e,0xff,0x01,0xe6,0x01,0x93,0x01,0x3f,0x01,0x04,0x17,0x00,
-0x01,0x03,0x01,0x3c,0x01,0x92,0x01,0xe6,0x3e,0xff,0x01,0x6f,0x8e,0x00,0x01,0x12,
-0x01,0xbb,0x0f,0xff,0x01,0xe3,0x01,0x42,0xc2,0x00,0x01,0x04,0x01,0xd3,0x40,0xff,
-0x01,0xf2,0x01,0xaf,0x01,0x72,0x01,0x38,0x01,0x0a,0x0f,0x00,0x01,0x09,0x01,0x36,
-0x01,0x6f,0x01,0xac,0x01,0xef,0x40,0xff,0x01,0xda,0x01,0x06,0x8f,0x00,0x01,0x03,
-0x01,0x8e,0x0f,0xff,0x01,0xfe,0x01,0x8d,0x01,0x07,0xc1,0x00,0x01,0x44,0x44,0xff,
-0x01,0xfd,0x01,0xdb,0x01,0xb5,0x01,0x94,0x01,0x7a,0x01,0x67,0x01,0x54,0x03,0x50,
-0x01,0x53,0x01,0x66,0x01,0x79,0x01,0x94,0x01,0xb4,0x01,0xd8,0x01,0xfd,0x44,0xff,
-0x01,0x4e,0x92,0x00,0x01,0x59,0x01,0xf4,0x0f,0xff,0x01,0xd4,0x01,0x34,0xc1,0x00,
-0x01,0xb0,0x97,0xff,0x01,0xb9,0x94,0x00,0x01,0x2b,0x01,0xd8,0x0f,0xff,0x01,0xfc,
-0x01,0x85,0x01,0x07,0xbf,0x00,0x01,0x23,0x01,0xf7,0x95,0xff,0x01,0xfa,0x01,0x2a,
-0x95,0x00,0x01,0x0d,0x01,0xab,0x10,0xff,0x01,0xd4,0x01,0x35,0xbf,0x00,0x01,0x78,
-0x95,0xff,0x01,0x81,0x98,0x00,0x01,0x6a,0x01,0xf8,0x0f,0xff,0x01,0xfd,0x01,0x92,
-0x01,0x0d,0xbd,0x00,0x01,0x04,0x01,0xcf,0x93,0xff,0x01,0xd6,0x01,0x07,0x99,0x00,
-0x01,0x2f,0x01,0xd8,0x10,0xff,0x01,0xe3,0x01,0x4e,0xbd,0x00,0x01,0x34,0x01,0xfc,
-0x91,0xff,0x01,0xfe,0x01,0x3b,0x9b,0x00,0x01,0x0b,0x01,0x9f,0x11,0xff,0x01,0xaf,
-0x01,0x1f,0xbc,0x00,0x01,0x83,0x91,0xff,0x01,0x8c,0x9e,0x00,0x01,0x55,0x01,0xed,
-0x10,0xff,0x01,0xf6,0x01,0x7d,0x01,0x08,0xba,0x00,0x01,0x04,0x01,0xc8,0x8f,0xff,
-0x01,0xcf,0x01,0x07,0x9f,0x00,0x01,0x1b,0x01,0xba,0x11,0xff,0x01,0xdd,0x01,0x4e,
-0xba,0x00,0x01,0x23,0x01,0xf4,0x8d,0xff,0x01,0xf7,0x01,0x29,0xa1,0x00,0x01,0x01,
-0x01,0x6e,0x01,0xf6,0x11,0xff,0x01,0xbc,0x01,0x2e,0xb9,0x00,0x01,0x5e,0x8d,0xff,
-0x01,0x67,0xa4,0x00,0x01,0x25,0x01,0xc3,0x11,0xff,0x01,0xfd,0x01,0x9b,0x01,0x18,
-0xb8,0x00,0x01,0x97,0x8b,0xff,0x01,0xa0,0xa6,0x00,0x01,0x02,0x01,0x70,0x01,0xf6,
-0x11,0xff,0x01,0xf4,0x01,0x82,0x01,0x0e,0xb6,0x00,0x01,0x06,0x01,0xc8,0x89,0xff,
-0x01,0xcf,0x01,0x09,0xa8,0x00,0x01,0x24,0x01,0xbc,0x12,0xff,0x01,0xec,0x01,0x71,
-0x01,0x07,0xb5,0x00,0x01,0x1c,0x01,0xe9,0x87,0xff,0x01,0xee,0x01,0x21,0xaa,0x00,
-0x01,0x01,0x01,0x5e,0x01,0xec,0x12,0xff,0x01,0xe2,0x01,0x68,0x01,0x06,0xb4,0x00,
-0x01,0x37,0x01,0xf6,0x85,0xff,0x01,0xfa,0x01,0x3d,0xad,0x00,0x01,0x14,0x01,0xa2,
-0x13,0xff,0x01,0xe2,0x01,0x68,0x01,0x06,0xb3,0x00,0x01,0x53,0x01,0xfe,0x84,0xff,
-0x01,0x5a,0xb0,0x00,0x01,0x3f,0x01,0xd4,0x13,0xff,0x01,0xe2,0x01,0x6b,0x01,0x09,
-0xb2,0x00,0x01,0x73,0x83,0xff,0x01,0x7c,0xb2,0x00,0x01,0x04,0x01,0x70,0x01,0xf1,
-0x13,0xff,0x01,0xe9,0x01,0x78,0x01,0x10,0xb1,0x00,0x01,0x89,0x81,0xff,0x01,0x95,
-0xb5,0x00,0x01,0x17,0x01,0x9f,0x01,0xfe,0x13,0xff,0x01,0xf1,0x01,0x8c,0x01,0x1f,
-0xaf,0x00,0x01,0x01,0x01,0x97,0x7f,0xff,0x01,0x9f,0x01,0x01,0xb7,0x00,0x01,0x32,
-0x01,0xc0,0x14,0xff,0x01,0xfc,0x01,0xa9,0x01,0x37,0xae,0x00,0x01,0x01,0x01,0xa3,
-0x7d,0xff,0x01,0xa8,0x01,0x03,0xba,0x00,0x01,0x51,0x01,0xdb,0x15,0xff,0x01,0xc9,
-0x01,0x5f,0x01,0x08,0xac,0x00,0x01,0x03,0x01,0xa3,0x7b,0xff,0x01,0xa8,0x01,0x06,
-0xbc,0x00,0x01,0x05,0x01,0x6a,0x01,0xe7,0x15,0xff,0x01,0xec,0x01,0x89,0x01,0x22,
-0x8d,0x00,0x01,0x0f,0x01,0x65,0x01,0xab,0x01,0xc0,0x01,0xa3,0x01,0x51,0x01,0x01,
-0x17,0x00,0x01,0x01,0x01,0x97,0x79,0xff,0x01,0xa0,0x01,0x03,0xbf,0x00,0x01,0x0b,
-0x01,0x7c,0x01,0xf0,0x16,0xff,0x01,0xbd,0x01,0x5b,0x01,0x08,0x87,0x00,0x01,0x02,
-0x01,0x42,0x01,0xa4,0x01,0xf6,0x05,0xff,0x01,0xb7,0x01,0x0a,0x17,0x00,0x01,0x01,
-0x01,0x8a,0x77,0xff,0x01,0x97,0x01,0x01,0xc2,0x00,0x01,0x14,0x01,0x88,0x01,0xf4,
-0x16,0xff,0x01,0xef,0x01,0x94,0x01,0x37,0x83,0x00,0x01,0x20,0x01,0x80,0x01,0xe0,
-0x09,0xff,0x01,0xa5,0x19,0x00,0x01,0x75,0x75,0xff,0x01,0x7d,0xc6,0x00,0x01,0x14,
-0x01,0x88,0x01,0xf4,0x17,0xff,0x01,0xda,0x01,0x7f,0x01,0x24,0x7d,0x00,0x01,0x16,
-0x01,0x68,0x01,0xbf,0x01,0xfe,0x0c,0xff,0x01,0x29,0x19,0x00,0x01,0x54,0x01,0xf7,
-0x71,0xff,0x01,0xfa,0x01,0x5c,0xc9,0x00,0x01,0x14,0x01,0x87,0x01,0xf0,0x18,0xff,
-0x01,0xc8,0x01,0x73,0x01,0x1e,0x77,0x00,0x01,0x12,0x01,0x63,0x01,0xb8,0x01,0xfb,
-0x0f,0xff,0x01,0x6e,0x1a,0x00,0x01,0x3a,0x01,0xea,0x6f,0xff,0x01,0xee,0x01,0x3f,
-0xcc,0x00,0x01,0x10,0x01,0x78,0x01,0xe9,0x19,0xff,0x01,0xcb,0x01,0x78,0x01,0x27,
-0x71,0x00,0x01,0x16,0x01,0x63,0x01,0xb8,0x01,0xfb,0x12,0xff,0x01,0x7e,0x1b,0x00,
-0x01,0x1e,0x01,0xcb,0x6d,0xff,0x01,0xd0,0x01,0x22,0xcf,0x00,0x01,0x09,0x01,0x6b,
-0x01,0xdb,0x1a,0xff,0x01,0xda,0x01,0x8b,0x01,0x3e,0x01,0x03,0x69,0x00,0x01,0x01,
-0x01,0x33,0x01,0x7f,0x01,0xc9,0x01,0xfe,0x15,0xff,0x01,0x5e,0x1c,0x00,0x01,0x07,
-0x01,0x9c,0x6b,0xff,0x01,0xa3,0x01,0x0a,0xd2,0x00,0x01,0x02,0x01,0x4e,0x01,0xc0,
-0x1b,0xff,0x01,0xef,0x01,0xac,0x01,0x63,0x01,0x1d,0x63,0x00,0x01,0x0f,0x01,0x52,
-0x01,0x9e,0x01,0xe8,0x18,0xff,0x01,0xf4,0x01,0x12,0x1e,0x00,0x01,0x63,0x01,0xf5,
-0x67,0xff,0x01,0xf8,0x01,0x6a,0xd7,0x00,0x01,0x32,0x01,0xa0,0x01,0xf8,0x1c,0xff,
-0x01,0xd5,0x01,0x94,0x01,0x54,0x01,0x15,0x5b,0x00,0x01,0x0f,0x01,0x4c,0x01,0x8c,
-0x01,0xcc,0x01,0xfd,0x1b,0xff,0x01,0x67,0x20,0x00,0x01,0x27,0x01,0xce,0x65,0xff,
-0x01,0xd2,0x01,0x2c,0xda,0x00,0x01,0x13,0x01,0x75,0x01,0xde,0x1e,0xff,0x01,0xd4,
-0x01,0x96,0x01,0x5b,0x01,0x22,0x53,0x00,0x01,0x18,0x01,0x4e,0x01,0x8c,0x01,0xcc,
-0x01,0xfd,0x1d,0xff,0x01,0xf0,0x01,0x63,0x22,0x00,0x01,0x06,0x01,0x88,0x01,0xfe,
-0x62,0xff,0x01,0x8f,0x01,0x07,0xdd,0x00,0x01,0x02,0x01,0x4a,0x01,0xad,0x01,0xfa,
-0x1f,0xff,0x01,0xe8,0x01,0xae,0x01,0x78,0x01,0x46,0x01,0x15,0x49,0x00,0x01,0x0e,
-0x01,0x42,0x01,0x78,0x01,0xad,0x01,0xe3,0x20,0xff,0x01,0xc8,0x01,0x66,0x01,0x0e,
-0x25,0x00,0x01,0x39,0x01,0xd5,0x5f,0xff,0x01,0xd9,0x01,0x3e,0xe2,0x00,0x01,0x16,
-0x01,0x73,0x01,0xd6,0x22,0xff,0x01,0xe2,0x01,0xaf,0x01,0x81,0x01,0x55,0x01,0x28,
-0x01,0x04,0x3d,0x00,0x01,0x04,0x01,0x28,0x01,0x52,0x01,0x7e,0x01,0xab,0x01,0xd8,
-0x01,0xfe,0x21,0xff,0x01,0xe8,0x01,0x8b,0x01,0x29,0x29,0x00,0x01,0x06,0x01,0x7f,
-0x01,0xf9,0x5b,0xff,0x01,0xfb,0x01,0x85,0x01,0x08,0xe6,0x00,0x01,0x37,0x01,0x93,
-0x01,0xea,0x24,0xff,0x01,0xf8,0x01,0xd1,0x01,0xad,0x01,0x85,0x01,0x61,0x01,0x3b,
-0x01,0x18,0x01,0x01,0x2f,0x00,0x01,0x02,0x01,0x1d,0x01,0x3e,0x01,0x5e,0x01,0x80,
-0x01,0xa8,0x01,0xd2,0x01,0xfa,0x24,0xff,0x01,0xfb,0x01,0xae,0x01,0x4d,0x01,0x04,
-0x2d,0x00,0x01,0x29,0x01,0xb9,0x59,0xff,0x01,0xbe,0x01,0x2d,0xea,0x00,0x01,0x05,
-0x01,0x4a,0x01,0xa7,0x01,0xf4,0x28,0xff,0x01,0xf9,0x01,0xda,0x01,0xbb,0x01,0x9c,
-0x01,0x82,0x01,0x69,0x01,0x50,0x01,0x38,0x01,0x20,0x01,0x0c,0x1d,0x00,0x01,0x10,
-0x01,0x27,0x01,0x3d,0x01,0x55,0x01,0x6a,0x01,0x82,0x01,0x9a,0x01,0xba,0x01,0xdc,
-0x01,0xfa,0x28,0xff,0x01,0xfb,0x01,0xb8,0x01,0x63,0x01,0x12,0x32,0x00,0x01,0x4b,
-0x01,0xda,0x55,0xff,0x01,0xde,0x01,0x51,0xef,0x00,0x01,0x09,0x01,0x53,0x01,0xa8,
-0x01,0xf4,0x2f,0xff,0x01,0xfa,0x01,0xe8,0x01,0xd6,0x01,0xc5,0x01,0xba,0x01,0xb0,
-0x01,0xa0,0x01,0x96,0x01,0x90,0x01,0x88,0x02,0x80,0x01,0x78,0x02,0x70,0x04,0x80,
-0x01,0x89,0x01,0x90,0x01,0x98,0x01,0xa0,0x01,0xac,0x01,0xba,0x01,0xc9,0x01,0xd7,
-0x01,0xe5,0x01,0xf9,0x2f,0xff,0x01,0xfb,0x01,0xb8,0x01,0x63,0x01,0x12,0x36,0x00,
-0x01,0x06,0x01,0x6f,0x01,0xe7,0x51,0xff,0x01,0xec,0x01,0x75,0x01,0x07,0xf3,0x00,
-0x01,0x09,0x01,0x51,0x01,0x9f,0x01,0xeb,0x75,0xff,0x01,0xf6,0x01,0xb2,0x01,0x66,
-0x01,0x12,0x3b,0x00,0x01,0x0a,0x01,0x78,0x01,0xec,0x4d,0xff,0x01,0xf0,0x01,0x7a,
-0x01,0x0c,0xf8,0x00,0x01,0x02,0x01,0x3b,0x01,0x89,0x01,0xd4,0x6f,0xff,0x01,0xde,
-0x01,0x93,0x01,0x48,0x01,0x08,0x40,0x00,0x01,0x0c,0x01,0x76,0x01,0xe5,0x49,0xff,
-0x01,0xe8,0x01,0x7b,0x01,0x10,0xfe,0x00,0x01,0x1c,0x01,0x62,0x01,0xaa,0x01,0xee,
-0x67,0xff,0x01,0xf6,0x01,0xbc,0x01,0x74,0x01,0x29,0x46,0x00,0x01,0x06,0x01,0x5f,
-0x01,0xd2,0x45,0xff,0x01,0xd5,0x01,0x64,0x01,0x07,0xff,0x00,0x04,0x00,0x01,0x03,
-0x01,0x34,0x01,0x74,0x01,0xb4,0x01,0xf1,0x5f,0xff,0x01,0xf6,0x01,0xbc,0x01,0x7c,
-0x01,0x3c,0x01,0x06,0x4b,0x00,0x01,0x01,0x01,0x40,0x01,0xa4,0x01,0xf8,0x3f,0xff,
-0x01,0xf9,0x01,0xa9,0x01,0x43,0x01,0x01,0xff,0x00,0x0a,0x00,0x01,0x04,0x01,0x38,
-0x01,0x72,0x01,0xab,0x01,0xe6,0x57,0xff,0x01,0xee,0x01,0xb8,0x01,0x7c,0x01,0x3c,
-0x01,0x06,0x52,0x00,0x01,0x12,0x01,0x6f,0x01,0xcd,0x3b,0xff,0x01,0xd3,0x01,0x73,
-0x01,0x14,0xff,0x00,0x12,0x00,0x01,0x1e,0x01,0x58,0x01,0x8b,0x01,0xbe,0x01,0xf1,
-0x4d,0xff,0x01,0xf5,0x01,0xc5,0x01,0x8e,0x01,0x59,0x01,0x24,0x5a,0x00,0x01,0x23,
-0x01,0x7c,0x01,0xd3,0x35,0xff,0x01,0xd5,0x01,0x7d,0x01,0x28,0xff,0x00,0x19,0x00,
-0x01,0x01,0x01,0x25,0x01,0x58,0x01,0x85,0x01,0xb1,0x01,0xde,0x42,0xff,0x01,0xfe,
-0x01,0xde,0x01,0xb2,0x01,0x88,0x01,0x5e,0x01,0x2e,0x01,0x04,0x61,0x00,0x01,0x24,
-0x01,0x6e,0x01,0xb5,0x01,0xf6,0x2d,0xff,0x01,0xf8,0x01,0xb9,0x01,0x70,0x01,0x27,
-0xff,0x00,0x22,0x00,0x01,0x0c,0x01,0x35,0x01,0x5d,0x01,0x82,0x01,0xa8,0x01,0xcf,
-0x01,0xf3,0x35,0xff,0x01,0xee,0x01,0xce,0x01,0xac,0x01,0x8a,0x01,0x60,0x01,0x35,
-0x01,0x0b,0x6a,0x00,0x01,0x08,0x01,0x44,0x01,0x81,0x01,0xbb,0x01,0xf4,0x25,0xff,
-0x01,0xf5,0x01,0xbe,0x01,0x83,0x01,0x47,0x01,0x09,0xff,0x00,0x2c,0x00,0x01,0x13,
-0x01,0x32,0x01,0x52,0x01,0x70,0x01,0x8f,0x01,0xa8,0x01,0xc2,0x01,0xd9,0x01,0xf4,
-0x23,0xff,0x01,0xeb,0x01,0xd7,0x01,0xbf,0x01,0xa9,0x01,0x91,0x01,0x72,0x01,0x50,
-0x01,0x30,0x01,0x0f,0x75,0x00,0x01,0x03,0x01,0x31,0x01,0x61,0x01,0x90,0x01,0xbe,
-0x01,0xec,0x1b,0xff,0x01,0xed,0x01,0xc0,0x01,0x91,0x01,0x63,0x01,0x34,0x01,0x04,
-0xff,0x00,0x39,0x00,0x01,0x0a,0x01,0x1d,0x01,0x30,0x01,0x43,0x01,0x55,0x01,0x67,
-0x01,0x72,0x01,0x80,0x01,0x8c,0x01,0x96,0x01,0xa0,0x01,0xac,0x02,0xb0,0x01,0xbb,
-0x06,0xc0,0x01,0xb5,0x01,0xb0,0x01,0xa6,0x01,0xa0,0x01,0x97,0x01,0x8f,0x01,0x80,
-0x01,0x71,0x01,0x63,0x01,0x55,0x01,0x47,0x01,0x31,0x01,0x19,0x01,0x05,0x84,0x00,
-0x01,0x12,0x01,0x33,0x01,0x54,0x01,0x74,0x01,0x93,0x01,0xa8,0x01,0xbb,0x01,0xcd,
-0x01,0xe3,0x02,0xf0,0x05,0xff,0x02,0xf0,0x01,0xe4,0x01,0xcf,0x01,0xbb,0x01,0xa8,
-0x01,0x94,0x01,0x76,0x01,0x54,0x01,0x34,0x01,0x14,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,
-0xff,0x00,0xd4,0x00,
-};
diff --git a/bootloader/src/misc.c b/bootloader/src/misc.c
deleted file mode 100644
index e8527df..0000000
--- a/bootloader/src/misc.c
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "osboot.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <xefi.h>
-
-#include <zircon/pixelformat.h>
-
-static efi_guid AcpiTableGUID = ACPI_TABLE_GUID;
-static efi_guid Acpi2TableGUID = ACPI_20_TABLE_GUID;
-static efi_guid SmbiosTableGUID = SMBIOS_TABLE_GUID;
-static efi_guid Smbios3TableGUID = SMBIOS3_TABLE_GUID;
-static uint8_t ACPI_RSD_PTR[8] = "RSD PTR ";
-static uint8_t SmbiosAnchor[4] = "_SM_";
-static uint8_t Smbios3Anchor[5] = "_SM3_";
-
-uint64_t find_acpi_root(efi_handle img, efi_system_table* sys) {
-    efi_configuration_table* cfgtab = sys->ConfigurationTable;
-    for (size_t i = 0; i < sys->NumberOfTableEntries; i++) {
-        if (xefi_cmp_guid(&cfgtab[i].VendorGuid, &AcpiTableGUID) &&
-            xefi_cmp_guid(&cfgtab[i].VendorGuid, &Acpi2TableGUID)) {
-            // not an ACPI table
-            continue;
-        }
-        if (memcmp(cfgtab[i].VendorTable, ACPI_RSD_PTR, 8)) {
-            // not the Root Description Pointer
-            continue;
-        }
-        return (uint64_t)cfgtab[i].VendorTable;
-    }
-    return 0;
-}
-
-uint64_t find_smbios(efi_handle img, efi_system_table* sys) {
-    efi_configuration_table* cfgtab = sys->ConfigurationTable;
-    for (size_t i = 0; i < sys->NumberOfTableEntries; i++) {
-        if (!xefi_cmp_guid(&cfgtab[i].VendorGuid, &SmbiosTableGUID)) {
-            if (!memcmp(cfgtab[i].VendorTable, SmbiosAnchor, sizeof(SmbiosAnchor))) {
-                return (uint64_t)cfgtab[i].VendorTable;
-            }
-        } else if (!xefi_cmp_guid(&cfgtab[i].VendorGuid, &Smbios3TableGUID)) {
-            if (!memcmp(cfgtab[i].VendorTable, Smbios3Anchor, sizeof(Smbios3Anchor))) {
-                return (uint64_t)cfgtab[i].VendorTable;
-            }
-        }
-    }
-    return 0;
-}
-
-static void get_bit_range(uint32_t mask, int* high, int* low) {
-    *high = -1;
-    *low = -1;
-    int idx = 0;
-    while (mask) {
-        if (*low < 0 && (mask & 1)) *low = idx;
-        idx++;
-        mask >>= 1;
-    }
-    *high = idx - 1;
-}
-
-static int get_zx_pixel_format_from_bitmask(efi_pixel_bitmask bitmask) {
-    int r_hi = -1, r_lo = -1, g_hi = -1, g_lo = -1, b_hi = -1, b_lo = -1;
-
-    get_bit_range(bitmask.RedMask, &r_hi, &r_lo);
-    get_bit_range(bitmask.GreenMask, &g_hi, &g_lo);
-    get_bit_range(bitmask.BlueMask, &b_hi, &b_lo);
-
-    if (r_lo < 0 || g_lo < 0 || b_lo < 0) {
-        goto unsupported;
-    }
-
-    if ((r_hi == 23 && r_lo == 16) &&
-        (g_hi == 15 && g_lo == 8) &&
-        (b_hi == 7 && b_lo == 0)) {
-        return ZX_PIXEL_FORMAT_RGB_x888;
-    }
-
-    if ((r_hi == 7 && r_lo == 5) &&
-        (g_hi == 4 && g_lo == 2) &&
-        (b_hi == 1 && b_lo == 0)) {
-        return ZX_PIXEL_FORMAT_RGB_332;
-    }
-
-    if ((r_hi == 15 && r_lo == 11) &&
-        (g_hi == 10 && g_lo == 5) &&
-        (b_hi == 4 && b_lo == 0)) {
-        return ZX_PIXEL_FORMAT_RGB_565;
-    }
-
-    if ((r_hi == 7 && r_lo == 6) &&
-        (g_hi == 5 && g_lo == 4) &&
-        (b_hi == 3 && b_lo == 2)) {
-        return ZX_PIXEL_FORMAT_RGB_2220;
-    }
-
-unsupported:
-    printf("unsupported pixel format bitmask: r %08x / g %08x / b %08x\n",
-            bitmask.RedMask, bitmask.GreenMask, bitmask.BlueMask);
-    return ZX_PIXEL_FORMAT_NONE;
-}
-
-uint32_t get_zx_pixel_format(efi_graphics_output_protocol* gop) {
-    efi_graphics_pixel_format efi_fmt = gop->Mode->Info->PixelFormat;
-    switch (efi_fmt) {
-    case PixelBlueGreenRedReserved8BitPerColor:
-        return ZX_PIXEL_FORMAT_RGB_x888;
-    case PixelBitMask:
-        return get_zx_pixel_format_from_bitmask(gop->Mode->Info->PixelInformation);
-    default:
-        printf("unsupported pixel format %d!\n", efi_fmt);
-        return ZX_PIXEL_FORMAT_NONE;
-    }
-}
diff --git a/bootloader/src/netboot.c b/bootloader/src/netboot.c
deleted file mode 100644
index a735f24..0000000
--- a/bootloader/src/netboot.c
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdio.h>
-#include <string.h>
-
-#include <device_id.h>
-#include <inet6.h>
-#include <netifc.h>
-#include <xefi.h>
-
-#include <zircon/boot/netboot.h>
-#include <tftp/tftp.h>
-
-#define TFTP_BUF_SZ 2048
-char tftp_session_scratch[TFTP_BUF_SZ];
-char tftp_out_scratch[TFTP_BUF_SZ];
-
-// item being downloaded
-static nbfile* item;
-
-// TFTP file state
-typedef struct {
-    nbfile* netboot_file_data;
-    size_t file_size;
-    unsigned int progress_reported;
-} file_info_t;
-
-// TFTP transport state
-typedef struct {
-    struct ip6_addr_t dest_addr;
-    uint16_t dest_port;
-} transport_info_t;
-
-static uint32_t last_cookie = 0;
-static uint32_t last_cmd = 0;
-static uint32_t last_arg = 0;
-static uint32_t last_ack_cmd = 0;
-static uint32_t last_ack_arg = 0;
-
-static int nb_boot_now = 0;
-static int nb_active = 0;
-
-static char advertise_nodename[64] = "";
-static char advertise_data[256] = "nodename=zircon";
-
-static void send_query_ack(const ip6_addr* addr, uint16_t port,
-                           uint32_t cookie) {
-    uint8_t buffer[256];
-    nbmsg* msg = (void*)buffer;
-    msg->magic = NB_MAGIC;
-    msg->cookie = cookie;
-    msg->cmd = NB_ACK;
-    msg->arg = NB_VERSION_CURRENT;
-    memcpy(msg->data, advertise_nodename, sizeof(advertise_nodename));
-    udp6_send(buffer, sizeof(nbmsg) + strlen(advertise_nodename) + 1,
-              addr, port, NB_SERVER_PORT);
-}
-
-static void advertise(void) {
-    uint8_t buffer[sizeof(nbmsg) + sizeof(advertise_data)];
-    nbmsg* msg = (void*)buffer;
-    msg->magic = NB_MAGIC;
-    msg->cookie = 0;
-    msg->cmd = NB_ADVERTISE;
-    msg->arg = NB_VERSION_CURRENT;
-    size_t data_len = strlen(advertise_data) + 1;
-    memcpy(msg->data, advertise_data, data_len);
-    udp6_send(buffer, sizeof(nbmsg) + data_len, &ip6_ll_all_nodes,
-              NB_ADVERT_PORT, NB_SERVER_PORT);
-}
-
-void netboot_recv(void* data, size_t len, const ip6_addr* saddr, uint16_t sport) {
-    nbmsg* msg = data;
-    nbmsg ack;
-    int do_transmit = 1;
-
-    if (len < sizeof(nbmsg))
-        return;
-    len -= sizeof(nbmsg);
-
-    // printf("netboot: MSG %08x %08x %08x %08x datalen %zu\n",
-    //        msg->magic, msg->cookie, msg->cmd, msg->arg, len);
-
-    if ((last_cookie == msg->cookie) &&
-        (last_cmd == msg->cmd) && (last_arg == msg->arg)) {
-        // host must have missed the ack. resend
-        ack.magic = NB_MAGIC;
-        ack.cookie = last_cookie;
-        ack.cmd = last_ack_cmd;
-        ack.arg = last_ack_arg;
-        goto transmit;
-    }
-
-    ack.cmd = NB_ACK;
-    ack.arg = 0;
-
-    switch (msg->cmd) {
-    case NB_COMMAND:
-        if (len == 0)
-            return;
-        msg->data[len - 1] = 0;
-        break;
-    case NB_SEND_FILE:
-        if (len == 0)
-            return;
-        msg->data[len - 1] = 0;
-        for (size_t i = 0; i < (len - 1); i++) {
-            if ((msg->data[i] < ' ') || (msg->data[i] > 127)) {
-                msg->data[i] = '.';
-            }
-        }
-        item = netboot_get_buffer((const char*)msg->data, msg->arg);
-        if (item) {
-            item->offset = 0;
-            ack.arg = msg->arg;
-            size_t prefix_len = strlen(NB_FILENAME_PREFIX);
-            const char* filename;
-            if (!strncmp((char*)msg->data, NB_FILENAME_PREFIX, prefix_len)) {
-                filename = &((const char*)msg->data)[prefix_len];
-            } else {
-                filename = (const char*)msg->data;
-            }
-            printf("netboot: Receive File '%s'...\n", filename);
-        } else {
-            printf("netboot: Rejected File '%s'...\n", (char*) msg->data);
-            ack.cmd = NB_ERROR_BAD_FILE;
-        }
-        break;
-
-    case NB_DATA:
-    case NB_LAST_DATA:
-        if (item == 0) {
-            printf("netboot: > received chunk before NB_FILE\n");
-            return;
-        }
-        if (msg->arg != item->offset) {
-            // printf("netboot: < received chunk at offset %d but current offset is %zu\n", msg->arg, item->offset);
-            ack.arg = item->offset;
-            ack.cmd = NB_ACK;
-        } else if ((item->offset + len) > item->size) {
-            ack.cmd = NB_ERROR_TOO_LARGE;
-            ack.arg = msg->arg;
-        } else {
-            memcpy(item->data + item->offset, msg->data, len);
-            item->offset += len;
-            ack.cmd = msg->cmd == NB_LAST_DATA ? NB_FILE_RECEIVED : NB_ACK;
-            if (msg->cmd != NB_LAST_DATA) {
-                do_transmit = 0;
-            }
-        }
-        break;
-    case NB_BOOT:
-        nb_boot_now = 1;
-        printf("netboot: Boot Kernel...\n");
-        break;
-    case NB_QUERY:
-        // Send reply and return w/o getting the netboot state out of sync.
-        send_query_ack(saddr, sport, msg->cookie);
-        return;
-    default:
-        ack.cmd = NB_ERROR_BAD_CMD;
-        ack.arg = 0;
-    }
-
-    last_cookie = msg->cookie;
-    last_cmd = msg->cmd;
-    last_arg = msg->arg;
-    last_ack_cmd = ack.cmd;
-    last_ack_arg = ack.arg;
-
-    ack.cookie = msg->cookie;
-    ack.magic = NB_MAGIC;
-transmit:
-    nb_active = 1;
-    if (do_transmit) {
-        // printf("netboot: MSG %08x %08x %08x %08x\n",
-        //   ack.magic, ack.cookie, ack.cmd, ack.arg);
-
-        udp6_send(&ack, sizeof(ack), saddr, sport, NB_SERVER_PORT);
-    }
-}
-
-static tftp_status buffer_open(const char* filename, size_t size, void* cookie) {
-    file_info_t* file_info = cookie;
-    file_info->netboot_file_data = netboot_get_buffer(filename, size);
-    if (file_info->netboot_file_data == NULL) {
-        printf("netboot: unrecognized file %s - rejecting\n", filename);
-        return TFTP_ERR_INVALID_ARGS;
-    }
-    file_info->netboot_file_data->offset = 0;
-    const char* base_filename;
-    size_t prefix_len = strlen(NB_FILENAME_PREFIX);
-    if (!strncmp(filename, NB_FILENAME_PREFIX, prefix_len)) {
-        base_filename = &filename[prefix_len];
-    } else {
-        base_filename = filename;
-    }
-    printf("Receiving %s [%lu bytes]... ", base_filename, (unsigned long)size);
-    file_info->file_size = size;
-    file_info->progress_reported = 0;
-    return TFTP_NO_ERROR;
-}
-
-static tftp_status buffer_write(const void* data, size_t* len, off_t offset, void* cookie) {
-    file_info_t* file_info = cookie;
-    nbfile* nb_buf_info = file_info->netboot_file_data;
-    if (offset > nb_buf_info->size || (offset + *len) > nb_buf_info->size) {
-        printf("netboot: attempt to write past end of buffer\n");
-        return TFTP_ERR_INVALID_ARGS;
-    }
-    memcpy(&nb_buf_info->data[offset], data, *len);
-    nb_buf_info->offset = offset + *len;
-    if (file_info->file_size >= 100) {
-        unsigned int progress_pct = offset / (file_info->file_size / 100);
-        if ((progress_pct > file_info->progress_reported) &&
-            (progress_pct - file_info->progress_reported >= 5)) {
-            printf("%u%%... ", progress_pct);
-            file_info->progress_reported = progress_pct;
-        }
-    }
-    return TFTP_NO_ERROR;
-}
-
-static void buffer_close(void* cookie) {
-    file_info_t* file_info = cookie;
-    file_info->netboot_file_data = NULL;
-    printf("Done\n");
-}
-
-static tftp_status udp_send(void* data, size_t len, void* cookie) {
-    transport_info_t* transport_info = cookie;
-    int bytes_sent = udp6_send(data, len, &transport_info->dest_addr, transport_info->dest_port,
-                               NB_TFTP_OUTGOING_PORT);
-    return bytes_sent < 0 ? TFTP_ERR_IO : TFTP_NO_ERROR;
-}
-
-static int udp_timeout_set(uint32_t timeout_ms, void* cookie) {
-    // TODO
-    return 0;
-}
-
-static int strcmp8to16(const char* str8, const char16_t* str16) {
-    while (*str8 != '\0' && *str8 == *str16) {
-        str8++;
-        str16++;
-    }
-    return *str8 - *str16;
-}
-
-void tftp_recv(void* data, size_t len, const ip6_addr* daddr, uint16_t dport,
-               const ip6_addr* saddr, uint16_t sport) {
-    static tftp_session* session = NULL;
-    static file_info_t file_info = {.netboot_file_data = NULL};
-    static transport_info_t transport_info = {};
-
-    if (dport == NB_TFTP_INCOMING_PORT) {
-        if (session != NULL) {
-            printf("Aborting to service new connection\n");
-        }
-        // Start TFTP session
-        int ret = tftp_init(&session, tftp_session_scratch, sizeof(tftp_session_scratch));
-        if (ret != TFTP_NO_ERROR) {
-            printf("netboot: failed to initiate tftp session\n");
-            session = NULL;
-            return;
-        }
-
-        // Override our window size on the Acer tablet
-        if (!strcmp8to16("INSYDE Corp.", gSys->FirmwareVendor)) {
-            uint16_t window_size = 8;
-            tftp_set_options(session, NULL, NULL, &window_size);
-        }
-
-        // Initialize file interface
-        tftp_file_interface file_ifc = {NULL, buffer_open, NULL, buffer_write, buffer_close};
-        tftp_session_set_file_interface(session, &file_ifc);
-
-        // Initialize transport interface
-        memcpy(&transport_info.dest_addr, saddr, sizeof(struct ip6_addr_t));
-        transport_info.dest_port = sport;
-        tftp_transport_interface transport_ifc = {udp_send, NULL, udp_timeout_set};
-        tftp_session_set_transport_interface(session, &transport_ifc);
-    } else if (!session) {
-        // Ignore anything sent to the outgoing port unless we've already established a connection
-        return;
-    }
-
-    size_t outlen = sizeof(tftp_out_scratch);
-
-    char err_msg[128];
-    tftp_handler_opts handler_opts = {.inbuf = data,
-                                      .inbuf_sz = len,
-                                      .outbuf = tftp_out_scratch,
-                                      .outbuf_sz = &outlen,
-                                      .err_msg = err_msg,
-                                      .err_msg_sz = sizeof(err_msg)};
-    tftp_status status = tftp_handle_msg(session, &transport_info, &file_info, &handler_opts);
-    if (status < 0) {
-        printf("netboot: tftp protocol error: %s\n", err_msg);
-        session = NULL;
-    } else if (status == TFTP_TRANSFER_COMPLETED) {
-        session = NULL;
-    }
-}
-
-#define FAST_TICK 100
-#define SLOW_TICK 1000
-
-int netboot_init(const char* nodename) {
-    if (netifc_open()) {
-        printf("netboot: Failed to open network interface\n");
-        return -1;
-    }
-    char buf[DEVICE_ID_MAX];
-    if (!nodename || (nodename[0] == 0)) {
-        device_id(eth_addr(), buf);
-        nodename = buf;
-    }
-    if (nodename) {
-        strncpy(advertise_nodename, nodename, sizeof(advertise_nodename) - 1);
-        snprintf(advertise_data, sizeof(advertise_data),
-                 "version=%s;nodename=%s", BOOTLOADER_VERSION, nodename);
-    }
-    return 0;
-}
-
-const char* netboot_nodename() {
-    return advertise_nodename;
-}
-
-static int nb_fastcount = 0;
-static int nb_online = 0;
-
-int netboot_poll(void) {
-    if (netifc_active()) {
-        if (nb_online == 0) {
-            printf("netboot: interface online\n");
-            nb_online = 1;
-            nb_fastcount = 20;
-            netifc_set_timer(FAST_TICK);
-            advertise();
-        }
-    } else {
-        if (nb_online == 1) {
-            printf("netboot: interface offline\n");
-            nb_online = 0;
-        }
-        return 0;
-    }
-    if (netifc_timer_expired()) {
-        if (nb_fastcount) {
-            nb_fastcount--;
-            netifc_set_timer(FAST_TICK);
-        } else {
-            netifc_set_timer(SLOW_TICK);
-        }
-        if (nb_active) {
-            // don't advertise if we're in a transfer
-            nb_active = 0;
-        } else {
-            advertise();
-        }
-    }
-
-    netifc_poll();
-
-    if (nb_boot_now) {
-        nb_boot_now = 0;
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-void netboot_close(void) {
-    netifc_close();
-}
diff --git a/bootloader/src/netifc.c b/bootloader/src/netifc.c
deleted file mode 100644
index abfe8ba..0000000
--- a/bootloader/src/netifc.c
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <efi/protocol/simple-network.h>
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <xefi.h>
-
-#include "inet6.h"
-#include "netifc.h"
-#include "osboot.h"
-
-static efi_simple_network_protocol* snp;
-
-#define MAX_FILTER 8
-static efi_mac_addr mcast_filters[MAX_FILTER];
-static unsigned mcast_filter_count = 0;
-
-// if nonzero, drop 1 in DROP_PACKETS packets at random
-#define DROP_PACKETS 0
-
-#if DROP_PACKETS > 0
-
-//TODO: use libc random() once it's actually random
-
-// Xorshift32 prng
-typedef struct {
-    uint32_t n;
-} rand32_t;
-
-static inline uint32_t rand32(rand32_t* state) {
-    uint32_t n = state->n;
-    n ^= (n << 13);
-    n ^= (n >> 17);
-    n ^= (n << 5);
-    return (state->n = n);
-}
-
-rand32_t rstate = {.n = 0x8716253};
-#define random() rand32(&rstate)
-
-static int txc;
-static int rxc;
-#endif
-
-#define NUM_BUFFER_PAGES 8
-#define ETH_BUFFER_SIZE 1516
-#define ETH_HEADER_SIZE 16
-#define ETH_BUFFER_MAGIC 0x424201020304A7A7UL
-
-typedef struct eth_buffer_t eth_buffer;
-struct eth_buffer_t {
-    uint64_t magic;
-    eth_buffer* next;
-    uint8_t data[0];
-};
-
-static efi_physical_addr eth_buffers_base = 0;
-static eth_buffer* eth_buffers = NULL;
-static int num_eth_buffers = 0;
-static int eth_buffers_avail = 0;
-
-void* eth_get_buffer(size_t sz) {
-    eth_buffer* buf;
-    if (sz > ETH_BUFFER_SIZE) {
-        return NULL;
-    }
-    if (eth_buffers == NULL) {
-        return NULL;
-    }
-    buf = eth_buffers;
-    eth_buffers = buf->next;
-    buf->next = NULL;
-    eth_buffers_avail--;
-    return buf->data;
-}
-
-void eth_put_buffer(void* data) {
-    efi_physical_addr buf_paddr = (efi_physical_addr)data;
-    if ((buf_paddr < eth_buffers_base)
-        || (buf_paddr >= (eth_buffers_base + (NUM_BUFFER_PAGES * PAGE_SIZE)))) {
-        printf("fatal: attempt to use buffer outside of allocated range\n");
-        for (;;)
-            ;
-    }
-
-    eth_buffer* buf = (void*)(buf_paddr & (~2047));
-    if (buf->magic != ETH_BUFFER_MAGIC) {
-        printf("fatal: eth buffer %p (from %p) bad magic %" PRIx64 "\n",
-               buf, data, buf->magic);
-        for (;;)
-            ;
-    }
-
-    buf->next = eth_buffers;
-    eth_buffers_avail++;
-    eth_buffers = buf;
-}
-
-int eth_send(void* data, size_t len) {
-#if DROP_PACKETS
-    txc++;
-    if ((random() % DROP_PACKETS) == 0) {
-        printf("tx drop %d\n", txc);
-        eth_put_buffer(data);
-        return 0;
-    }
-#endif
-    efi_status r;
-    if ((r = snp->Transmit(snp, 0, len, (void*)data, NULL, NULL, NULL))) {
-        eth_put_buffer(data);
-        return -1;
-    } else {
-        return 0;
-    }
-}
-
-void eth_dump_status(void) {
-#ifdef VERBOSE
-    printf("State/HwAdSz/HdrSz/MaxSz %d %d %d %d\n",
-           snp->Mode->State, snp->Mode->HwAddressSize,
-           snp->Mode->MediaHeaderSize, snp->Mode->MaxPacketSize);
-    printf("RcvMask/RcvCfg/MaxMcast/NumMcast %d %d %d %d\n",
-           snp->Mode->ReceiveFilterMask, snp->Mode->ReceiveFilterSetting,
-           snp->Mode->MaxMCastFilterCount, snp->Mode->MCastFilterCount);
-    uint8_t* x = snp->Mode->CurrentAddress.addr;
-    printf("MacAddr %02x:%02x:%02x:%02x:%02x:%02x\n",
-           x[0], x[1], x[2], x[3], x[4], x[5]);
-    printf("SetMac/MultiTx/LinkDetect/Link %d %d %d %d\n",
-           snp->Mode->MacAddressChangeable, snp->Mode->MultipleTxSupported,
-           snp->Mode->MediaPresentSupported, snp->Mode->MediaPresent);
-#endif
-}
-
-int eth_add_mcast_filter(const mac_addr* addr) {
-    if (mcast_filter_count >= MAX_FILTER)
-        return -1;
-    if (mcast_filter_count >= snp->Mode->MaxMCastFilterCount)
-        return -1;
-    memcpy(mcast_filters + mcast_filter_count, addr, ETH_ADDR_LEN);
-    mcast_filter_count++;
-    return 0;
-}
-
-static efi_event net_timer = NULL;
-
-#define TIMER_MS(n) (((uint64_t)(n)) * 10000UL)
-
-void netifc_set_timer(uint32_t ms) {
-    if (net_timer == 0) {
-        return;
-    }
-    gBS->SetTimer(net_timer, TimerRelative, TIMER_MS(ms));
-}
-
-int netifc_timer_expired(void) {
-    if (net_timer == 0) {
-        return 0;
-    }
-    if (gBS->CheckEvent(net_timer) == EFI_SUCCESS) {
-        return 1;
-    }
-    return 0;
-}
-
-/* Search the available network interfaces via SimpleNetworkProtocol handles
- * and find the first valid one with a Link detected */
-efi_simple_network_protocol* netifc_find_available(void) {
-    efi_boot_services* bs = gSys->BootServices;
-    efi_status ret;
-    efi_simple_network_protocol* cur_snp = NULL;
-    efi_handle handles[32];
-    char16_t *paths[32];
-    size_t nic_cnt = 0;
-    size_t sz = sizeof(handles);
-    uint32_t last_parent = 0;
-    uint32_t int_sts;
-    void *tx_buf;
-
-    /* Get the handles of all devices that provide SimpleNetworkProtocol interfaces */
-    ret = bs->LocateHandle(ByProtocol, &SimpleNetworkProtocol, NULL, &sz, handles);
-    if (ret != EFI_SUCCESS) {
-        printf("Failed to locate network interfaces (%s)\n", xefi_strerror(ret));
-        return NULL;
-    }
-
-    nic_cnt = sz / sizeof(efi_handle);
-    for (size_t i = 0; i < nic_cnt; i++) {
-        paths[i] = xefi_handle_to_str(handles[i]);
-    }
-
-    /* Iterate over our SNP list until we find one with an established link */
-    for (size_t i = 0; i < nic_cnt; i++) {
-         /* Check each interface once, but ignore any additional device paths a given interface
-          * may provide. e1000 tends to add a path for ipv4 and ipv6 configuration information
-          * for instance */
-        if (i != last_parent) {
-            if (memcmp(paths[i], paths[last_parent], strlen_16(paths[last_parent])) == 0) {
-                continue;
-            } else {
-                last_parent = i;
-            }
-        }
-
-        puts16(paths[i]);
-        printf(": ");
-        ret = bs->HandleProtocol(handles[i], &SimpleNetworkProtocol, (void**)&cur_snp);
-        if (ret) {
-            printf("Failed to open (%s)\n", xefi_strerror(ret));
-            continue;
-        }
-
-        /* If a driver is provided by the firmware then it should be started already, but check
-         * to make sure. This also covers the case where we're providing the AX88772 driver in-line
-         * during this boot itself */
-        ret = cur_snp->Start(cur_snp);
-        if (EFI_ERROR(ret) && ret != EFI_ALREADY_STARTED) {
-            printf("Failed to start (%s)", xefi_strerror(ret));
-            goto link_fail;
-        }
-
-        if (ret != EFI_ALREADY_STARTED) {
-            ret = cur_snp->Initialize(cur_snp, 0, 0);
-            if (EFI_ERROR(ret)) {
-                printf("Failed to initialize (%s)\n", xefi_strerror(ret));
-                goto link_fail;
-            }
-        }
-
-        /* Prod the driver to cache its current status. We don't need the status or buffer,
-         * but some drivers appear to require the OPTIONAL parameters. */
-        ret = cur_snp->GetStatus(cur_snp, &int_sts, &tx_buf);
-        if (EFI_ERROR(ret)) {
-            printf("Failed to read status (%s)\n", xefi_strerror(ret));
-            goto link_fail;
-        }
-
-        /* With status cached, do we have a Link detected on the netifc? */
-        if (!cur_snp->Mode->MediaPresent) {
-            printf("No link detected\n");
-            goto link_fail;
-        }
-
-        printf("Link detected!\n");
-        return cur_snp;
-
-link_fail:
-        bs->CloseProtocol(handles[i], &SimpleNetworkProtocol, gImg, NULL);
-        cur_snp = NULL;
-    }
-
-    return NULL;
-}
-
-int netifc_open(void) {
-    efi_boot_services* bs = gSys->BootServices;
-    efi_status ret;
-
-    bs->CreateEvent(EVT_TIMER, TPL_CALLBACK, NULL, NULL, &net_timer);
-
-    snp = netifc_find_available();
-    if (!snp) {
-        printf("Failed to find a usable network interface\n");
-        return -1;
-    }
-
-    if (bs->AllocatePages(AllocateAnyPages, EfiLoaderData, NUM_BUFFER_PAGES, &eth_buffers_base)) {
-        printf("Failed to allocate net buffers\n");
-        return -1;
-    }
-
-    num_eth_buffers = NUM_BUFFER_PAGES * 2;
-    uint8_t* ptr = (void*)eth_buffers_base;
-    for (int i = 0; i < num_eth_buffers; ++i) {
-        eth_buffer* buf = (void*)ptr;
-        buf->magic = ETH_BUFFER_MAGIC;
-        eth_put_buffer(buf);
-        ptr += 2048;
-    }
-
-    ip6_init(snp->Mode->CurrentAddress.addr);
-
-    ret = snp->ReceiveFilters(snp,
-                            EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
-                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST,
-                            0, 0, mcast_filter_count, (void*)mcast_filters);
-    if (ret) {
-        printf("Failed to install multicast filters %s\n", xefi_strerror(ret));
-        return -1;
-    }
-
-    eth_dump_status();
-
-    if (snp->Mode->MCastFilterCount != mcast_filter_count) {
-        printf("OOPS: expected %d filters, found %d\n",
-               mcast_filter_count, snp->Mode->MCastFilterCount);
-        goto force_promisc;
-    }
-    for (size_t i = 0; i < mcast_filter_count; i++) {
-        //uint8_t *m = (void*) &mcast_filters[i];
-        //printf("i=%d %02x %02x %02x %02x %02x %02x\n", i, m[0], m[1], m[2], m[3], m[4], m[5]);
-        for (size_t j = 0; j < mcast_filter_count; j++) {
-            //m = (void*) &snp->Mode->MCastFilter[j];
-            //printf("j=%d %02x %02x %02x %02x %02x %02x\n", j, m[0], m[1], m[2], m[3], m[4], m[5]);
-            if (!memcmp(mcast_filters + i, &snp->Mode->MCastFilter[j], 6)) {
-                goto found_it;
-            }
-        }
-        printf("OOPS: filter #%zu missing\n", i);
-        goto force_promisc;
-    found_it:;
-    }
-
-    return 0;
-
-force_promisc:
-    ret = snp->ReceiveFilters(snp,
-                            EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
-                                EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS |
-                                EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST,
-                            0, 0, 0, NULL);
-    if (ret) {
-        printf("Failed to set promiscuous mode (%s)\n", xefi_strerror(ret));
-        return -1;
-    }
-    return 0;
-}
-
-void netifc_close(void) {
-    gBS->SetTimer(net_timer, TimerCancel, 0);
-    gBS->CloseEvent(net_timer);
-    snp->Shutdown(snp);
-    snp->Stop(snp);
-}
-
-int netifc_active(void) {
-    return (snp != 0);
-}
-
-void netifc_poll(void) {
-    uint8_t data[1514];
-    efi_status r;
-    size_t hsz, bsz;
-    uint32_t irq;
-    void* txdone;
-
-    if (eth_buffers_avail < num_eth_buffers) {
-        // Only check for completion if we have operations in progress.
-        // Otherwise, the result of GetStatus is unreliable. See ZX-759.
-        if ((r = snp->GetStatus(snp, &irq, &txdone))) {
-            return;
-        }
-        if (txdone) {
-            // Check to make sure this is one of our buffers (see ZX-1516)
-            efi_physical_addr buf_paddr = (efi_physical_addr)txdone;
-            if ((buf_paddr >= eth_buffers_base)
-                && (buf_paddr < (eth_buffers_base + (NUM_BUFFER_PAGES * PAGE_SIZE)))) {
-                eth_put_buffer(txdone);
-            }
-        }
-    }
-
-    hsz = 0;
-    bsz = sizeof(data);
-    r = snp->Receive(snp, &hsz, &bsz, data, NULL, NULL, NULL);
-    if (r != EFI_SUCCESS) {
-        return;
-    }
-
-#if DROP_PACKETS
-    rxc++;
-    if ((random() % DROP_PACKETS) == 0) {
-        printf("rx drop %d\n", rxc);
-        return;
-    }
-#endif
-
-#if TRACE
-    printf("RX %02x:%02x:%02x:%02x:%02x:%02x < %02x:%02x:%02x:%02x:%02x:%02x %02x%02x %d\n",
-            data[0], data[1], data[2], data[3], data[4], data[5],
-            data[6], data[7], data[8], data[9], data[10], data[11],
-            data[12], data[13], (int)(bsz - hsz));
-#endif
-    eth_recv(data, bsz);
-}
diff --git a/bootloader/src/netifc.h b/bootloader/src/netifc.h
deleted file mode 100644
index 74f0b20..0000000
--- a/bootloader/src/netifc.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-// setup networking
-int netifc_open(void);
-
-// process inbound packet(s)
-void netifc_poll(void);
-
-// return nonzero if interface exists
-int netifc_active(void);
-
-// shut down networking
-void netifc_close(void);
-
-// set a timer to expire after ms milliseconds
-void netifc_set_timer(uint32_t ms);
-
-// returns true once the timer has expired
-int netifc_timer_expired(void);
diff --git a/bootloader/src/osboot.c b/bootloader/src/osboot.c
deleted file mode 100644
index 946e308..0000000
--- a/bootloader/src/osboot.c
+++ /dev/null
@@ -1,579 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <efi/boot-services.h>
-#include <efi/protocol/device-path.h>
-#include <efi/protocol/graphics-output.h>
-#include <efi/protocol/simple-text-input.h>
-#include <efi/system-table.h>
-
-#include <cmdline.h>
-#include <device_id.h>
-#include <framebuffer.h>
-#include <inet6.h>
-#include <xefi.h>
-
-#include "osboot.h"
-
-#include <zircon/boot/netboot.h>
-
-#define DEFAULT_TIMEOUT 3
-
-#define KBUFSIZE (32*1024*1024)
-#define RBUFSIZE (512 * 1024 * 1024)
-
-
-static nbfile nbkernel;
-static nbfile nbramdisk;
-static nbfile nbcmdline;
-
-nbfile* netboot_get_buffer(const char* name, size_t size) {
-    if (!strcmp(name, NB_KERNEL_FILENAME)) {
-        return &nbkernel;
-    }
-    if (!strcmp(name, NB_RAMDISK_FILENAME)) {
-        efi_physical_addr mem = 0xFFFFFFFF;
-        size_t buf_size = size > 0 ? (size + PAGE_MASK) & ~PAGE_MASK : RBUFSIZE;
-
-        if (nbramdisk.size > 0) {
-            if (nbramdisk.size < buf_size) {
-                mem = (efi_physical_addr)nbramdisk.data;
-                nbramdisk.data = 0;
-                if (gBS->FreePages(mem - FRONT_BYTES, (nbramdisk.size / PAGE_SIZE) + FRONT_PAGES)) {
-                    printf("Could not free previous ramdisk allocation\n");
-                    nbramdisk.size = 0;
-                    return NULL;
-                }
-                nbramdisk.size = 0;
-            } else {
-                return &nbramdisk;
-            }
-        }
-
-        printf("netboot: allocating %zu for ramdisk (requested %zu)\n", buf_size, size);
-        if (gBS->AllocatePages(AllocateMaxAddress, EfiLoaderData,
-                               (buf_size / PAGE_SIZE) + FRONT_PAGES, &mem)) {
-            printf("Failed to allocate network io buffer\n");
-            return NULL;
-        }
-        nbramdisk.data = (void*) (mem + FRONT_BYTES);
-        nbramdisk.size = buf_size;
-
-        return &nbramdisk;
-    }
-    if (!strcmp(name, NB_CMDLINE_FILENAME)) {
-        return &nbcmdline;
-    }
-    return NULL;
-}
-
-// Wait for a keypress from a set of valid keys. If 0 < timeout_s < INT_MAX, the
-// first key in the set of valid keys will be returned after timeout_s seconds
-// if no other valid key is pressed.
-char key_prompt(const char* valid_keys, int timeout_s) {
-    if (strlen(valid_keys) < 1) return 0;
-    if (timeout_s <= 0) return valid_keys[0];
-
-    efi_event TimerEvent;
-    efi_event WaitList[2];
-
-    efi_status status;
-    size_t Index;
-    efi_input_key key;
-    memset(&key, 0, sizeof(key));
-
-    status = gBS->CreateEvent(EVT_TIMER, 0, NULL, NULL, &TimerEvent);
-    if (status != EFI_SUCCESS) {
-        printf("could not create event timer: %s\n", xefi_strerror(status));
-        return 0;
-    }
-
-    status = gBS->SetTimer(TimerEvent, TimerPeriodic, 10000000);
-    if (status != EFI_SUCCESS) {
-        printf("could not set timer: %s\n", xefi_strerror(status));
-        return 0;
-    }
-
-    size_t wait_idx = 0;
-    size_t key_idx = wait_idx;
-    WaitList[wait_idx++] = gSys->ConIn->WaitForKey;
-    size_t timer_idx = wait_idx;  // timer should always be last
-    WaitList[wait_idx++] = TimerEvent;
-
-    bool cur_vis = gConOut->Mode->CursorVisible;
-    int32_t col = gConOut->Mode->CursorColumn;
-    int32_t row = gConOut->Mode->CursorRow;
-    gConOut->EnableCursor(gConOut, false);
-
-    // TODO: better event loop
-    char pressed = 0;
-    if (timeout_s < INT_MAX) {
-        printf("%-10d", timeout_s);
-    }
-    do {
-        status = gBS->WaitForEvent(wait_idx, WaitList, &Index);
-
-        // Check the timer
-        if (!EFI_ERROR(status)) {
-            if (Index == timer_idx) {
-                if (timeout_s < INT_MAX) {
-                    timeout_s--;
-                    gConOut->SetCursorPosition(gConOut, col, row);
-                    printf("%-10d", timeout_s);
-                }
-                continue;
-            } else if (Index == key_idx) {
-                status = gSys->ConIn->ReadKeyStroke(gSys->ConIn, &key);
-                if (EFI_ERROR(status)) {
-                    // clear the key and wait for another event
-                    memset(&key, 0, sizeof(key));
-                } else {
-                    char* which_key = strchr(valid_keys, key.UnicodeChar);
-                    if (which_key) {
-                        pressed = *which_key;
-                        break;
-                    }
-                }
-            }
-        } else {
-            printf("Error waiting for event: %s\n", xefi_strerror(status));
-            gConOut->EnableCursor(gConOut, cur_vis);
-            return 0;
-        }
-    } while (timeout_s);
-
-    gBS->CloseEvent(TimerEvent);
-    gConOut->EnableCursor(gConOut, cur_vis);
-    if (timeout_s > 0 && pressed) {
-        return pressed;
-    }
-
-    // Default to first key in list
-    return valid_keys[0];
-}
-
-void do_select_fb() {
-    uint32_t cur_mode = get_gfx_mode();
-    uint32_t max_mode = get_gfx_max_mode();
-    while (true) {
-        printf("\n");
-        print_fb_modes();
-        printf("Choose a framebuffer mode or press (b) to return to the menu\n");
-        char key = key_prompt("b0123456789", INT_MAX);
-        if (key == 'b') break;
-        if ((uint32_t)(key - '0') >= max_mode) {
-            printf("invalid mode: %c\n", key);
-            continue;
-        }
-        set_gfx_mode(key - '0');
-        printf("Use \"bootloader.fbres=%ux%u\" to use this resolution by default\n",
-                get_gfx_hres(), get_gfx_vres());
-        printf("Press space to accept or (r) to choose again ...");
-        key = key_prompt("r ", 5);
-        if (key == ' ') {
-            return;
-        }
-        set_gfx_mode(cur_mode);
-    }
-}
-
-void do_bootmenu(bool have_fb) {
-    const char* menukeys;
-    if (have_fb)
-        menukeys = "rfx";
-    else
-        menukeys = "rx";
-    printf("  BOOT MENU  \n");
-    printf("  ---------  \n");
-    if (have_fb)
-        printf("  (f) list framebuffer modes\n");
-    printf("  (r) reset\n");
-    printf("  (x) exit menu\n");
-    printf("\n");
-    char key = key_prompt(menukeys, INT_MAX);
-    switch (key) {
-    case 'f': {
-        do_select_fb();
-        break;
-    }
-    case 'r':
-        gSys->RuntimeServices->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
-        break;
-    case 'x':
-    default:
-        break;
-    }
-}
-
-static char cmdbuf[CMDLINE_MAX];
-void print_cmdline(void) {
-    cmdline_to_string(cmdbuf, sizeof(cmdbuf));
-    printf("cmdline: %s\n", cmdbuf);
-}
-
-static char netboot_cmdline[CMDLINE_MAX];
-void do_netboot() {
-    efi_physical_addr mem = 0xFFFFFFFF;
-    if (gBS->AllocatePages(AllocateMaxAddress, EfiLoaderData, KBUFSIZE / 4096, &mem)) {
-        printf("Failed to allocate network io buffer\n");
-        return;
-    }
-    nbkernel.data = (void*) mem;
-    nbkernel.size = KBUFSIZE;
-
-    // ramdisk is dynamically allocated now
-    nbramdisk.data = 0;
-    nbramdisk.size = 0;
-
-    nbcmdline.data = (void*) netboot_cmdline;
-    nbcmdline.size = sizeof(netboot_cmdline);
-    nbcmdline.offset = 0;
-
-    printf("\nNetBoot Server Started...\n\n");
-    efi_tpl prev_tpl = gBS->RaiseTPL(TPL_NOTIFY);
-    while (true) {
-        int n = netboot_poll();
-        if (n < 1) {
-            continue;
-        }
-        if (nbkernel.offset < 32768) {
-            // too small to be a kernel
-            continue;
-        }
-        uint8_t* x = nbkernel.data;
-        if ((x[0] == 'M') && (x[1] == 'Z') && (x[0x80] == 'P') && (x[0x81] == 'E')) {
-            size_t exitdatasize;
-            efi_status r;
-            efi_handle h;
-
-            efi_device_path_hw_memmap mempath[2] = {
-                {
-                    .Header = {
-                        .Type = DEVICE_PATH_HARDWARE,
-                        .SubType = DEVICE_PATH_HW_MEMMAP,
-                        .Length = { (uint8_t)(sizeof(efi_device_path_hw_memmap) & 0xff),
-                            (uint8_t)((sizeof(efi_device_path_hw_memmap) >> 8) & 0xff), },
-                    },
-                    .MemoryType = EfiLoaderData,
-                    .StartAddress = (efi_physical_addr)nbkernel.data,
-                    .EndAddress = (efi_physical_addr)(nbkernel.data + nbkernel.offset),
-                },
-                {
-                    .Header = {
-                        .Type = DEVICE_PATH_END,
-                        .SubType = DEVICE_PATH_ENTIRE_END,
-                        .Length = { (uint8_t)(sizeof(efi_device_path_protocol) & 0xff),
-                            (uint8_t)((sizeof(efi_device_path_protocol) >> 8) & 0xff), },
-                    },
-                },
-            };
-
-            printf("Attempting to run EFI binary...\n");
-            r = gBS->LoadImage(false, gImg, (efi_device_path_protocol*)mempath, (void*)nbkernel.data, nbkernel.offset, &h);
-            if (EFI_ERROR(r)) {
-                printf("LoadImage Failed (%s)\n", xefi_strerror(r));
-                continue;
-            }
-            r = gBS->StartImage(h, &exitdatasize, NULL);
-            if (EFI_ERROR(r)) {
-                printf("StartImage Failed %zu\n", r);
-                continue;
-            }
-            printf("\nNetBoot Server Resuming...\n");
-            continue;
-        }
-
-        // make sure network traffic is not in flight, etc
-        netboot_close();
-
-        // Restore the TPL before booting the kernel, or failing to netboot
-        gBS->RestoreTPL(prev_tpl);
-
-        cmdline_append((void*) nbcmdline.data, nbcmdline.offset);
-        print_cmdline();
-
-        const char* fbres = cmdline_get("bootloader.fbres", NULL);
-        if (fbres) {
-            set_gfx_mode_from_cmdline(fbres);
-        }
-
-        // maybe it's a kernel image?
-        boot_kernel(gImg, gSys, (void*) nbkernel.data, nbkernel.offset,
-                    (void*) nbramdisk.data, nbramdisk.offset);
-        break;
-    }
-}
-
-// Finds c in s and swaps it with the character at s's head. For example:
-// swap_to_head('b', "foobar", 6) = "boofar";
-static inline void swap_to_head(const char c, char* s, const size_t n) {
-    // Empty buffer?
-    if (n == 0) return;
-
-    // Find c in s
-    size_t i;
-    for (i = 0; i < n; i++) {
-        if (c == s[i]) {
-            break;
-        }
-    }
-
-    // Couldn't find c in s
-    if (i == n) return;
-
-    // Swap c to the head.
-    const char tmp = s[0];
-    s[0] = s[i];
-    s[i] = tmp;
-}
-
-size_t kernel_zone_size;
-efi_physical_addr kernel_zone_base;
-
-EFIAPI efi_status efi_main(efi_handle img, efi_system_table* sys) {
-    xefi_init(img, sys);
-    gConOut->ClearScreen(gConOut);
-
-    uint64_t mmio;
-    if (xefi_find_pci_mmio(gBS, 0x0C, 0x03, 0x30, &mmio) == EFI_SUCCESS) {
-        char tmp[32];
-        sprintf(tmp, "%#" PRIx64 , mmio);
-        cmdline_set("xdc.mmio", tmp);
-    }
-
-    // Load the cmdline
-    size_t csz = 0;
-    char* cmdline_file = xefi_load_file(L"cmdline", &csz, 0);
-    if (cmdline_file) {
-        cmdline_append(cmdline_file, csz);
-    }
-
-    efi_graphics_output_protocol* gop;
-    efi_status status = gBS->LocateProtocol(&GraphicsOutputProtocol, NULL,
-                                            (void**)&gop);
-    bool have_fb = !EFI_ERROR(status);
-
-    if (have_fb) {
-        const char* fbres = cmdline_get("bootloader.fbres", NULL);
-        if (fbres) {
-            set_gfx_mode_from_cmdline(fbres);
-        }
-        draw_logo();
-    }
-
-    int32_t prev_attr = gConOut->Mode->Attribute;
-    gConOut->SetAttribute(gConOut, EFI_LIGHTZIRCON | EFI_BACKGROUND_BLACK);
-    draw_version(BOOTLOADER_VERSION);
-    gConOut->SetAttribute(gConOut, prev_attr);
-
-    if (have_fb) {
-        printf("Framebuffer base is at %" PRIx64 "\n\n",
-               gop->Mode->FrameBufferBase);
-    }
-
-    // Set aside space for the kernel down at the 1MB mark up front
-    // to avoid other allocations getting in the way.
-    // The kernel itself is about 1MB, but we leave generous space
-    // for its BSS afterwards.
-    //
-    // Previously we requested 32MB but that caused issues. When the kernel
-    // becomes relocatable this won't be an problem. See ZX-2368.
-    kernel_zone_base = 0x100000;
-    kernel_zone_size = 6 * 1024 * 1024;
-
-    if (gBS->AllocatePages(AllocateAddress, EfiLoaderData,
-                          BYTES_TO_PAGES(kernel_zone_size), &kernel_zone_base)) {
-        printf("boot: cannot obtain %zu bytes for kernel @ %p\n", kernel_zone_size,
-               (void*) kernel_zone_base);
-        kernel_zone_size = 0;
-    }
-    // HACK: Try again with a smaller size - certain platforms (ex: GCE) are unable
-    // to support a large fixed allocation at 0x100000.
-    if (kernel_zone_size == 0) {
-        kernel_zone_size = 3 * 1024 * 1024;
-        efi_status status = gBS->AllocatePages(AllocateAddress, EfiLoaderData,
-                                               BYTES_TO_PAGES(kernel_zone_size),
-                                               &kernel_zone_base);
-        if (status) {
-            printf("boot: cannot obtain %zu bytes for kernel @ %p\n",
-                   kernel_zone_size,
-                   (void*) kernel_zone_base);
-            kernel_zone_size = 0;
-        }
-    }
-    printf("KALLOC DONE\n");
-
-    // Default boot defaults to network
-    const char* defboot = cmdline_get("bootloader.default", "network");
-    const char* nodename = cmdline_get("zircon.nodename", "");
-
-    // See if there's a network interface
-    bool have_network = netboot_init(nodename) == 0;
-    if (have_network) {
-        if (have_fb) {
-            draw_nodename(netboot_nodename());
-        } else {
-            printf("\nNodename: %s\n", netboot_nodename());
-        }
-        // If nodename was set through cmdline earlier in the code path then
-        // netboot_nodename will return that same value, otherwise it will
-        // return the generated value in which case it needs to be added to
-        // the command line arguments.
-        if (nodename[0] == 0) {
-            cmdline_set("zircon.nodename", netboot_nodename());
-        }
-    }
-
-    printf("\n\n");
-    print_cmdline();
-
-    // First look for a self-contained zircon boot image
-    size_t zedboot_size = 0;
-    void* zedboot_kernel = NULL;
-
-    zedboot_kernel = xefi_load_file(L"zedboot.bin", &zedboot_size, 0);
-    switch (identify_image(zedboot_kernel, zedboot_size)) {
-    case IMAGE_COMBO:
-        printf("zedboot.bin is a valid kernel+ramdisk combo image\n");
-        break;
-    case IMAGE_EMPTY:
-        break;
-    default:
-        zedboot_kernel = NULL;
-        zedboot_size = 0;
-    }
-
-    // Look for a kernel image on disk
-    size_t ksz = 0;
-    unsigned ktype = IMAGE_INVALID;
-    void* kernel = NULL;
-
-    kernel = image_load_from_disk(img, sys, &ksz);
-    if (kernel != NULL) {
-        printf("zircon image loaded from zircon partition\n");
-        ktype = IMAGE_COMBO;
-    } else {
-        kernel = xefi_load_file(L"zircon.bin", &ksz, 0);
-        switch ((ktype = identify_image(kernel, ksz))) {
-        case IMAGE_EMPTY:
-            break;
-        case IMAGE_KERNEL:
-            printf("zircon.bin is a kernel image\n");
-            break;
-        case IMAGE_COMBO:
-            printf("zircon.bin is a kernel+ramdisk combo image\n");
-            break;
-        case IMAGE_RAMDISK:
-            printf("zircon.bin is a ramdisk?!\n");
-        case IMAGE_INVALID:
-            printf("zircon.bin is not a valid kernel or combo image\n");
-            ktype = IMAGE_INVALID;
-            ksz = 0;
-            kernel = NULL;
-        }
-    }
-
-    if (!have_network && zedboot_kernel == NULL && kernel == NULL) {
-        goto fail;
-    }
-
-    char valid_keys[5];
-    memset(valid_keys, 0, sizeof(valid_keys));
-    size_t key_idx = 0;
-
-    if (have_network) {
-        valid_keys[key_idx++] = 'n';
-    }
-    if (kernel != NULL) {
-        valid_keys[key_idx++] = 'm';
-    }
-    if (zedboot_kernel) {
-        valid_keys[key_idx++] = 'z';
-    }
-
-    // The first entry in valid_keys will be the default after the timeout.
-    // Use the value of bootloader.default to determine the first entry. If
-    // bootloader.default is not set, use "network".
-    if (!memcmp(defboot, "local", 5)) {
-        swap_to_head('m', valid_keys, key_idx);
-    } else if (!memcmp(defboot, "zedboot", 7)) {
-        swap_to_head('z', valid_keys, key_idx);
-    } else {
-        swap_to_head('n', valid_keys, key_idx);
-    }
-    valid_keys[key_idx++] = 'b';
-
-    // make sure we update valid_keys if we ever add new options
-    if (key_idx >= sizeof(valid_keys)) goto fail;
-
-    // Disable WDT
-    // The second parameter can be any value outside of the range [0,0xffff]
-    gBS->SetWatchdogTimer(0, 0x10000, 0, NULL);
-
-    int timeout_s = cmdline_get_uint32("bootloader.timeout", DEFAULT_TIMEOUT);
-    while (true) {
-        printf("\nPress (b) for the boot menu");
-        if (have_network) {
-            printf(", ");
-            if (!kernel) printf("or ");
-            printf("(n) for network boot");
-        }
-        if (kernel) {
-            printf(", ");
-            printf("or (m) to boot the zircon.bin on the device");
-        }
-        if (zedboot_kernel) {
-            printf(", ");
-            printf("or (z) to launch zedboot");
-        }
-        printf(" ...");
-
-        char key = key_prompt(valid_keys, timeout_s);
-        printf("\n\n");
-
-        switch (key) {
-        case 'b':
-            do_bootmenu(have_fb);
-            break;
-        case 'n':
-            do_netboot();
-            break;
-        case 'm':
-            if (ktype == IMAGE_COMBO) {
-                zedboot(img, sys, kernel, ksz);
-            } else {
-                size_t rsz = 0;
-                void* ramdisk = NULL;
-                efi_file_protocol* ramdisk_file = xefi_open_file(L"bootdata.bin");
-                const char* ramdisk_name = "bootdata.bin";
-                if (ramdisk_file == NULL) {
-                    ramdisk_file = xefi_open_file(L"ramdisk.bin");
-                    ramdisk_name = "ramdisk.bin";
-                }
-                if (ramdisk_file) {
-                    printf("Loading %s...\n", ramdisk_name);
-                    ramdisk = xefi_read_file(ramdisk_file, &rsz, FRONT_BYTES);
-                    ramdisk_file->Close(ramdisk_file);
-                }
-                boot_kernel(gImg, gSys, kernel, ksz, ramdisk, rsz);
-            }
-            goto fail;
-        case 'z':
-            zedboot(img, sys, zedboot_kernel, zedboot_size);
-            goto fail;
-        default:
-            goto fail;
-        }
-    }
-
-fail:
-    printf("\nBoot Failure\n");
-    xefi_wait_any_key();
-    return EFI_SUCCESS;
-}
diff --git a/bootloader/src/osboot.h b/bootloader/src/osboot.h
deleted file mode 100644
index cf49784..0000000
--- a/bootloader/src/osboot.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#pragma once
-
-#include <stdint.h>
-
-#include <efi/system-table.h>
-#include <efi/protocol/graphics-output.h>
-
-#define PAGE_SIZE (4096)
-#define PAGE_MASK (PAGE_SIZE - 1)
-
-#define BYTES_TO_PAGES(n) (((n) + PAGE_MASK) / PAGE_SIZE)
-
-// Ensure there are some pages preceding the
-// Ramdisk so that the kernel start code can
-// use them to prepend bootdata items if desired.
-#define FRONT_PAGES (8)
-#define FRONT_BYTES (PAGE_SIZE * FRONT_PAGES)
-
-#define CMDLINE_MAX PAGE_SIZE
-
-int boot_kernel(efi_handle img, efi_system_table* sys,
-                void* image, size_t sz,
-                void* ramdisk, size_t rsz);
-
-uint64_t find_acpi_root(efi_handle img, efi_system_table* sys);
-uint64_t find_smbios(efi_handle img, efi_system_table* sys);
-
-uint32_t get_zx_pixel_format(efi_graphics_output_protocol* gop);
-
-int boot_deprecated(efi_handle img, efi_system_table* sys,
-                    void* image, size_t sz,
-                    void* ramdisk, size_t rsz,
-                    void* cmdline, size_t csz);
-
-int zedboot(efi_handle img, efi_system_table* sys,
-            void* image, size_t sz);
-
-#define IMAGE_INVALID 0
-#define IMAGE_EMPTY   1
-#define IMAGE_KERNEL  2
-#define IMAGE_RAMDISK 3
-#define IMAGE_COMBO   4
-
-
-unsigned identify_image(void* image, size_t sz);
-
-// sz may be just one block or sector
-// if the header looks like a kernel image, return expected size
-// otherwise returns 0
-size_t image_getsize(void* imageheader, size_t sz);
-
-
-void* image_load_from_disk(efi_handle img, efi_system_table* sys, size_t* sz);
-
-
-// Where to start the kernel from
-extern size_t kernel_zone_size;
-extern efi_physical_addr kernel_zone_base;
diff --git a/bootloader/src/pci.c b/bootloader/src/pci.c
deleted file mode 100644
index e228016..0000000
--- a/bootloader/src/pci.c
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2016 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <efi/types.h>
-#include <efi/protocol/pci-root-bridge-io.h>
-
-#include <stdio.h>
-#include <xefi.h>
-
-typedef struct {
-    uint8_t descriptor;
-    uint16_t len;
-    uint8_t res_type;
-    uint8_t gen_flags;
-    uint8_t specific_flags;
-    uint64_t addrspace_granularity;
-    uint64_t addrrange_minimum;
-    uint64_t addrrange_maximum;
-    uint64_t addr_tr_offset;
-    uint64_t addr_len;
-} __attribute__((packed)) acpi_addrspace_desc64_t;
-
-#define ACPI_ADDRESS_SPACE_DESCRIPTOR 0x8A
-#define ACPI_END_TAG_DESCRIPTOR       0x79
-
-#define ACPI_ADDRESS_SPACE_TYPE_BUS   0x02
-
-typedef struct {
-    uint16_t vid;
-    uint16_t did;
-    uint16_t cmd;
-    uint16_t status;
-    uint8_t rev_id;
-    uint8_t class_code[3];
-    uint8_t cache_line_size;
-    uint8_t primary_lat_timer;
-    uint8_t hdr_type;
-    uint8_t bist;
-    uint32_t bar[6];
-    uint32_t cardbus_cis;
-    uint16_t subid;
-    uint16_t subvid;
-    uint32_t exprom_bar;
-    uint8_t cap_ptr;
-    uint8_t reserved[7];
-    uint8_t irq_line;
-    uint8_t irq_pin;
-    uint8_t min_grant;
-    uint8_t max_lat;
-} __attribute__((packed)) pci_common_header_t;
-
-#define PCI_MAX_DEVICES 32
-#define PCI_MAX_FUNCS 8
-
-efi_status xefi_find_pci_mmio(efi_boot_services* bs, uint8_t cls, uint8_t sub, uint8_t ifc, uint64_t* mmio) {
-    size_t num_handles;
-    efi_handle* handles;
-    efi_status status = bs->LocateHandleBuffer(ByProtocol, &PciRootBridgeIoProtocol,
-            NULL, &num_handles, &handles);
-    if (EFI_ERROR(status)) {
-        printf("Could not find PCI root bridge IO protocol: %s\n", xefi_strerror(status));
-        return status;
-    }
-
-    for (size_t i = 0; i < num_handles; i++) {
-        printf("handle %zu\n", i);
-        efi_pci_root_bridge_io_protocol* iodev;
-        status = bs->HandleProtocol(handles[i], &PciRootBridgeIoProtocol, (void**)&iodev);
-        if (EFI_ERROR(status)) {
-            printf("Could not get protocol for handle %zu: %s\n",
-                   i, xefi_strerror(status));
-            continue;
-        }
-        acpi_addrspace_desc64_t* descriptors;
-        status = iodev->Configuration(iodev, (void**)&descriptors);
-        if (EFI_ERROR(status)) {
-            printf("Could not get configuration for handle %zu: %s\n",
-                   i, xefi_strerror(status));
-            continue;
-        }
-
-        uint16_t min_bus, max_bus;
-        while (descriptors->descriptor != ACPI_END_TAG_DESCRIPTOR) {
-            min_bus = (uint16_t)descriptors->addrrange_minimum;
-            max_bus = (uint16_t)descriptors->addrrange_maximum;
-
-            if (descriptors->res_type != ACPI_ADDRESS_SPACE_TYPE_BUS) {
-                descriptors++;
-                continue;
-            }
-
-            for (int bus = min_bus; bus <= max_bus; bus++) {
-                for (int dev = 0; dev < PCI_MAX_DEVICES; dev++) {
-                    for (int func = 0; func < PCI_MAX_FUNCS; func++) {
-                        pci_common_header_t pci_hdr;
-                        bs->SetMem(&pci_hdr, sizeof(pci_hdr), 0);
-                        uint64_t address = (uint64_t)((bus << 24) + (dev << 16) + (func << 8));
-                        status = iodev->Pci.Read(iodev, EfiPciWidthUint16, address, sizeof(pci_hdr) / 2, &pci_hdr);
-                        if (EFI_ERROR(status)) {
-                            printf("could not read pci configuration for bus %d dev %d func %d: %s\n",
-                                    bus, dev, func, xefi_strerror(status));
-                            continue;
-                        }
-                        if (pci_hdr.vid == 0xffff) break;
-                        if ((pci_hdr.class_code[2] == cls) &&
-                            (pci_hdr.class_code[1] == sub) &&
-                            (pci_hdr.class_code[0] == ifc)) {
-                            uint64_t n = ((uint64_t) pci_hdr.bar[0]) |
-                                         ((uint64_t) pci_hdr.bar[1]) << 32UL;
-                            *mmio = n & 0xFFFFFFFFFFFFFFF0UL;
-                            status = EFI_SUCCESS;
-                            goto found_it;
-                        }
-#if 0
-                        printf("bus %04x dev %02x func %02x: ", bus, dev, func);
-                        printf("VID: 0x%04x  DID: 0x%04x  Class: 0x%02x  Subclass: 0x%02x  Intf: 0x%02x\n",
-                                pci_hdr.vid, pci_hdr.did, pci_hdr.class_code[2], pci_hdr.class_code[1],
-                                pci_hdr.class_code[0]);
-                        printf("     hdr_type: %02x\n", pci_hdr.hdr_type);
-                        if ((pci_hdr.hdr_type & 0x7f) == 0x00) {
-                            for (int bar = 0; bar < 6; bar++) {
-                                if (pci_hdr.bar[bar]) {
-                                    printf("     bar[%d]: 0x%08x\n", bar, pci_hdr.bar[bar]);
-                                }
-                                bool is64bit = (pci_hdr.bar[bar] & 0x06) == 0x04;
-                                if (is64bit) {
-                                    printf("     bar[%d]: 0x%08x\n", bar+1, pci_hdr.bar[bar+1]);
-                                    bar++;
-                                }
-                                // TODO: get the BAR size
-                                //   - disable IO
-                                //   - write 1s
-                                //   - read it back
-                                //   - reset or map to somewhere else(?)
-                            }
-                        }
-#endif
-                        if (!(pci_hdr.hdr_type & 0x80) && func == 0) {
-                            break;
-                        }
-                    }
-                }
-            }
-            descriptors++;
-        }
-    }
-
-    status = EFI_NOT_FOUND;
-found_it:
-    bs->FreePool(handles);
-    return status;
-}
diff --git a/bootloader/src/zircon.c b/bootloader/src/zircon.c
deleted file mode 100644
index 4ac51c6..0000000
--- a/bootloader/src/zircon.c
+++ /dev/null
@@ -1,420 +0,0 @@
-// Copyright 2017 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "osboot.h"
-
-#include <efi/protocol/graphics-output.h>
-#include <efi/runtime-services.h>
-#include <efi/zircon.h>
-
-#include <cmdline.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-#include <xefi.h>
-
-#include <zircon/boot/image.h>
-#include <zircon/pixelformat.h>
-
-
-static efi_guid zircon_guid = ZIRCON_VENDOR_GUID;
-static char16_t crashlog_name[] = ZIRCON_CRASHLOG_EFIVAR;
-
-static size_t get_last_crashlog(efi_system_table* sys, void* ptr, size_t max) {
-    efi_runtime_services* rs = sys->RuntimeServices;
-
-    uint32_t attr = ZIRCON_CRASHLOG_EFIATTR;
-    size_t sz = max;
-    efi_status r = rs->GetVariable(crashlog_name, &zircon_guid, &attr, &sz, ptr);
-    if (r == EFI_SUCCESS) {
-        // Erase it
-        rs->SetVariable(crashlog_name, &zircon_guid, ZIRCON_CRASHLOG_EFIATTR, 0, NULL);
-    } else {
-        sz = 0;
-    }
-    return sz;
-}
-
-static unsigned char scratch[32768];
-
-static void start_zircon(uint64_t entry, void* bootdata) {
-#if __x86_64__
-    // ebx = 0, ebp = 0, edi = 0, esi = bootdata
-    __asm__ __volatile__(
-        "movl $0, %%ebp \n"
-        "cli \n"
-        "jmp *%[entry] \n" ::[entry] "a"(entry),
-        [bootdata] "S"(bootdata),
-        "b"(0), "D"(0));
-#else
-#warning "add code for other arches here"
-#endif
-    for (;;)
-        ;
-}
-
-static int add_bootdata(void** ptr, size_t* avail,
-                        zbi_header_t* bd, void* data) {
-    size_t len = ZBI_ALIGN(bd->length);
-    if ((sizeof(zbi_header_t) + len) > *avail) {
-        printf("boot: no room for bootdata type=%08x size=%08x\n",
-               bd->type, bd->length);
-        return -1;
-    }
-    bd->flags |= ZBI_FLAG_VERSION;
-    bd->reserved0 = 0;
-    bd->reserved1 = 0;
-    bd->magic = ZBI_ITEM_MAGIC;
-    bd->crc32 = ZBI_ITEM_NO_CRC32;
-
-    memcpy(*ptr, bd, sizeof(zbi_header_t));
-    memcpy((*ptr) + sizeof(zbi_header_t), data, len);
-    len += sizeof(zbi_header_t);
-    (*ptr) += len;
-    (*avail) -= len;
-
-    return 0;
-}
-
-size_t image_getsize(void* image, size_t sz) {
-    if (sz < sizeof(zircon_kernel_t)) {
-        return 0;
-    }
-    zircon_kernel_t* kernel = image;
-    if ((kernel->hdr_file.type != ZBI_TYPE_CONTAINER) ||
-        (kernel->hdr_file.magic != ZBI_ITEM_MAGIC) ||
-        (kernel->hdr_kernel.type != ZBI_TYPE_KERNEL_X64) ||
-        (kernel->hdr_kernel.magic != ZBI_ITEM_MAGIC)) {
-        return 0;
-    }
-    return ZBI_ALIGN(kernel->hdr_file.length) + sizeof(zbi_header_t);
-}
-
-static int header_check(void* image, size_t sz, uint64_t* _entry,
-                        size_t* _flen, size_t* _klen) {
-    zbi_header_t* bd = image;
-    size_t flen, klen;
-    uint64_t entry;
-
-    if (!(bd->flags & ZBI_FLAG_VERSION)) {
-        printf("boot: v1 bootdata kernel no longer supported\n");
-        return -1;
-    }
-    zircon_kernel_t* kernel = image;
-    if ((sz < sizeof(zircon_kernel_t)) ||
-        (kernel->hdr_kernel.type != ZBI_TYPE_KERNEL_X64) ||
-        ((kernel->hdr_kernel.flags & ZBI_FLAG_VERSION) == 0)) {
-        printf("boot: invalid zircon kernel header\n");
-        return -1;
-    }
-    flen = ZBI_ALIGN(kernel->hdr_file.length);
-    klen = ZBI_ALIGN(kernel->hdr_kernel.length);
-    entry = kernel->data_kernel.entry;
-    if (flen > (sz - sizeof(zbi_header_t))) {
-        printf("boot: invalid zircon kernel header (bad flen)\n");
-        return -1;
-    }
-
-    if (klen > (sz - (sizeof(zbi_header_t) * 2))) {
-        printf("boot: invalid zircon kernel header (bad klen)\n");
-        return -1;
-    }
-    if (_entry) {
-        *_entry = entry;
-    }
-    if (_flen) {
-        *_flen = flen;
-        *_klen = klen;
-    }
-
-    return 0;
-}
-
-static int item_check(zbi_header_t* bd, size_t sz) {
-    if (sz > 0x7FFFFFFF) {
-        // disallow 2GB+ items to avoid wrap on align issues
-        return -1;
-    }
-    if ((bd->magic != ZBI_ITEM_MAGIC) ||
-        ((bd->flags & ZBI_FLAG_VERSION) == 0) ||
-        (ZBI_ALIGN(bd->length) > sz)) {
-        return -1;
-    } else {
-        return 0;
-    }
-}
-
-//TODO: verify crc32 when present
-unsigned identify_image(void* image, size_t sz) {
-    if (sz == 0) {
-        return IMAGE_EMPTY;
-    }
-    if (sz < sizeof(zbi_header_t)) {
-        printf("image is too small\n");
-        return IMAGE_INVALID;
-    }
-    zbi_header_t* bd = image;
-    sz -= sizeof(zbi_header_t);
-    if ((bd->type != ZBI_TYPE_CONTAINER) ||
-        item_check(bd, sz)) {
-        printf("image has invalid header\n");
-        return IMAGE_INVALID;
-    }
-    image += sizeof(zbi_header_t);
-    unsigned n = 0;
-    unsigned r = 0;
-    while (sz > sizeof(zbi_header_t)) {
-        bd = image;
-        sz -= sizeof(zbi_header_t);
-        if (item_check(image, sz)) {
-            printf("image has invalid bootitem\n");
-            return IMAGE_INVALID;
-        }
-        if (ZBI_IS_KERNEL_BOOTITEM(bd->type)) {
-            if (n != 0) {
-                printf("image has kernel in middle\n");
-                return IMAGE_INVALID;
-            } else {
-                r = IMAGE_KERNEL;
-            }
-        }
-        if (bd->type == ZBI_TYPE_STORAGE_BOOTFS) {
-            if ((r == IMAGE_KERNEL) || (r == IMAGE_COMBO)) {
-                r = IMAGE_COMBO;
-            } else {
-                r = IMAGE_RAMDISK;
-            }
-        }
-        image += ZBI_ALIGN(bd->length) + sizeof(zbi_header_t);
-        sz -= ZBI_ALIGN(bd->length);
-        n++;
-    }
-
-    return r;
-}
-
-int boot_zircon(efi_handle img, efi_system_table* sys,
-                 void* image, size_t isz, void* ramdisk, size_t rsz,
-                 void* cmdline, size_t csz) {
-
-    efi_boot_services* bs = sys->BootServices;
-    uint64_t entry;
-
-    if (header_check(image, isz, &entry, NULL, NULL)) {
-        return -1;
-    }
-    if ((ramdisk == NULL) || (rsz < sizeof(zbi_header_t))) {
-        printf("boot: ramdisk missing or too small\n");
-        return -1;
-    }
-    if (isz > kernel_zone_size) {
-        printf("boot: kernel image too large\n");
-        return -1;
-    }
-
-    zbi_header_t* hdr0 = ramdisk;
-    if ((hdr0->type != ZBI_TYPE_CONTAINER) ||
-        (hdr0->extra != ZBI_CONTAINER_MAGIC) ||
-        !(hdr0->flags & ZBI_FLAG_VERSION)) {
-        printf("boot: ramdisk has invalid bootdata header\n");
-        return -1;
-    }
-
-    if ((hdr0->length > (rsz - sizeof(zbi_header_t)))) {
-        printf("boot: ramdisk has invalid bootdata length\n");
-        return -1;
-    }
-
-    // osboot ensures we have FRONT_BYTES ahead of the
-    // ramdisk to prepend our own bootdata items.
-    void* bptr = ramdisk - FRONT_BYTES;
-    size_t blen = FRONT_BYTES;
-
-    // We create a new container header of the same size
-    // as the one at the start of the ramdisk
-    zbi_header_t hdr = ZBI_CONTAINER_HEADER(hdr0->length + FRONT_BYTES);
-    memcpy(bptr, &hdr, sizeof(hdr));
-    bptr += sizeof(hdr);
-
-    // pass kernel commandline
-    hdr.type = ZBI_TYPE_CMDLINE;
-    hdr.length = csz;
-    hdr.extra = 0;
-    hdr.flags = ZBI_FLAG_VERSION;
-    if (add_bootdata(&bptr, &blen, &hdr, cmdline)) {
-        return -1;
-    }
-
-    // pass ACPI root pointer
-    uint64_t rsdp = find_acpi_root(img, sys);
-    if (rsdp != 0) {
-        hdr.type = ZBI_TYPE_ACPI_RSDP;
-        hdr.length = sizeof(rsdp);
-        if (add_bootdata(&bptr, &blen, &hdr, &rsdp)) {
-            return -1;
-        }
-    }
-
-    // pass SMBIOS entry point pointer
-    uint64_t smbios = find_smbios(img, sys);
-    if (smbios != 0) {
-        hdr.type = ZBI_TYPE_SMBIOS;
-        hdr.length = sizeof(smbios);
-        if (add_bootdata(&bptr, &blen, &hdr, &smbios)) {
-            return -1;
-        }
-    }
-
-    // pass EFI system table
-    uint64_t addr = (uintptr_t) sys;
-    hdr.type = ZBI_TYPE_EFI_SYSTEM_TABLE;
-    hdr.length = sizeof(sys);
-    if (add_bootdata(&bptr, &blen, &hdr, &addr)) {
-        return -1;
-    }
-
-    // pass framebuffer data
-    efi_graphics_output_protocol* gop = NULL;
-    bs->LocateProtocol(&GraphicsOutputProtocol, NULL, (void**)&gop);
-    if (gop) {
-        zbi_swfb_t fb = {
-            .base = gop->Mode->FrameBufferBase,
-            .width = gop->Mode->Info->HorizontalResolution,
-            .height = gop->Mode->Info->VerticalResolution,
-            .stride = gop->Mode->Info->PixelsPerScanLine,
-            .format = get_zx_pixel_format(gop),
-        };
-        hdr.type = ZBI_TYPE_FRAMEBUFFER;
-        hdr.length = sizeof(fb);
-        if (add_bootdata(&bptr, &blen, &hdr, &fb)) {
-            return -1;
-        }
-    }
-
-    memcpy((void*)kernel_zone_base, image, isz);
-
-    // Obtain the system memory map
-    size_t msize, dsize;
-    for (int attempts = 0;;attempts++) {
-        efi_memory_descriptor* mmap = (efi_memory_descriptor*) (scratch + sizeof(uint64_t));
-        uint32_t dversion = 0;
-        size_t mkey = 0;
-        msize = sizeof(scratch) - sizeof(uint64_t);
-        dsize = 0;
-        efi_status r = sys->BootServices->GetMemoryMap(&msize, mmap, &mkey, &dsize, &dversion);
-        if (r != EFI_SUCCESS) {
-            printf("boot: cannot GetMemoryMap()\n");
-            goto fail;
-        }
-
-        r = sys->BootServices->ExitBootServices(img, mkey);
-        if (r == EFI_SUCCESS) {
-            break;
-        }
-        if (r == EFI_INVALID_PARAMETER) {
-            if (attempts > 0) {
-                printf("boot: cannot ExitBootServices(): %s\n", xefi_strerror(r));
-                goto fail;
-            }
-            // Attempting to exit may cause us to have to re-grab the
-            // memory map, but if it happens more than once something's
-            // broken.
-            continue;
-        }
-        printf("boot: cannot ExitBootServices(): %s\n", xefi_strerror(r));
-        goto fail;
-    }
-    memcpy(scratch, &dsize, sizeof(uint64_t));
-
-    // install memory map
-    hdr.type = ZBI_TYPE_EFI_MEMORY_MAP;
-    hdr.length = msize + sizeof(uint64_t);
-    if (add_bootdata(&bptr, &blen, &hdr, scratch)) {
-        goto fail;
-    }
-
-    // obtain the last crashlog if we can
-    size_t sz = get_last_crashlog(sys, scratch, 4096);
-    if (sz > 0) {
-        hdr.type = ZBI_TYPE_CRASHLOG;
-        hdr.length = sz;
-        add_bootdata(&bptr, &blen, &hdr, scratch);
-    }
-
-    // fill the remaining gap between pre-data and ramdisk image
-    if ((blen < sizeof(hdr)) || (blen & 7)) {
-        goto fail;
-    }
-    hdr.type = ZBI_TYPE_DISCARD;
-    hdr.length = blen - sizeof(hdr);
-    hdr.flags = ZBI_FLAG_VERSION;
-    memcpy(bptr, &hdr, sizeof(hdr));
-
-    // jump to the kernel
-    start_zircon(entry, ramdisk - FRONT_BYTES);
-
-fail:
-    return -1;
-}
-
-static char cmdline[CMDLINE_MAX];
-
-int zedboot(efi_handle img, efi_system_table* sys,
-            void* image, size_t sz) {
-
-    size_t flen, klen;
-    if (header_check(image, sz, NULL, &flen, &klen)) {
-        return -1;
-    }
-
-    // ramdisk portion is file - headers - kernel len
-    uint32_t rlen = flen - sizeof(zbi_header_t) - klen;
-    uint32_t roff = (sizeof(zbi_header_t) * 2) + klen;
-    if (rlen == 0) {
-        printf("zedboot: no ramdisk?!\n");
-        return -1;
-    }
-
-    // allocate space for the ramdisk
-    efi_boot_services* bs = sys->BootServices;
-    size_t rsz = rlen + sizeof(zbi_header_t) + FRONT_BYTES;
-    size_t pages = BYTES_TO_PAGES(rsz);
-    void* ramdisk = NULL;
-    efi_status r = bs->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
-                                     (efi_physical_addr*)&ramdisk);
-    if (r) {
-        printf("zedboot: cannot allocate ramdisk buffer\n");
-        return -1;
-    }
-
-    ramdisk += FRONT_BYTES;
-    *(zbi_header_t*)ramdisk = (zbi_header_t)ZBI_CONTAINER_HEADER(rlen);
-    memcpy(ramdisk + sizeof(zbi_header_t), image + roff, rlen);
-    rlen += sizeof(zbi_header_t);
-
-    printf("ramdisk @ %p\n", ramdisk);
-
-    size_t csz = cmdline_to_string(cmdline, sizeof(cmdline));
-
-    // shrink original image header to include only the kernel
-    zircon_kernel_t* kernel = image;
-    kernel->hdr_file.length = sizeof(zbi_header_t) + klen;
-
-    return boot_zircon(img, sys, image, roff, ramdisk, rlen, cmdline, csz);
-}
-
-int boot_kernel(efi_handle img, efi_system_table* sys,
-                void* image, size_t sz,
-                void* ramdisk, size_t rsz) {
-
-    size_t csz = cmdline_to_string(cmdline, sizeof(cmdline));
-
-    zbi_header_t* bd = image;
-    if ((bd->type == ZBI_TYPE_CONTAINER) &&
-        (bd->extra == ZBI_CONTAINER_MAGIC)) {
-        return boot_zircon(img, sys, image, sz, ramdisk, rsz, cmdline, csz);
-    } else {
-        return -1;
-    }
-}
diff --git a/docs/MAINTAINERS b/docs/MAINTAINERS
deleted file mode 100644
index 21e98f2..0000000
--- a/docs/MAINTAINERS
+++ /dev/null
@@ -1,3 +0,0 @@
-cpu@google.com
-kulakowski@google.com
-swetland@google.com
diff --git a/docs/abigen/grammar.md b/docs/abigen/grammar.md
deleted file mode 100644
index 15e7f4d..0000000
--- a/docs/abigen/grammar.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# abigen grammar
-
-## Modified BNF rules
-
-This is the grammar for abigen files. The grammar is expressed in
-a modified BNF format.
-
-A nonterminal symbol matches a sequence of other symbols, delimited by
-commas.
-```
-nonterminal = list , of , symbols ;
-```
-
-Some symbols are terminals, which are either in all caps or are in
-double quotes.
-```
-another-nonterminal = THESE , ARE , TERMINALS , AND , SO , IS , "this" ;
-```
-
-Alternation is expressed with a pipe.
-```
-choice = this | that | the-other ;
-```
-
-An option (zero or one) is expressed with parentheses.
-```
-optional = ( maybe , these ) , but , definitely , these ;
-```
-
-Repetition (zero or more) is expressed with parentheses and a star.
-```
-zero-or-more = ( list-part )* ;
-```
-
-## The grammar
-
-`file` is the starting symbol.
-
-```
-file = ( declaration )* , EOF ;
-
-declaration = syscall-declaration ;
-
-syscall-declaration = syscall IDENTIFIER attribute-list "(" parameter-list ")"
-                      ( "returns" "(" type ( "," parameter-list ) ")" )
-
-parameter-list = parameter | parameter "," parameter-list
-
-parameter = IDENTIFIER ":" type attribute-list ( inout )
-
-attribute-list = ( attribute )*
-
-attribute = IDENTIFIER
-
-type = IDENTIFIER
-
-inout = "IN" | "OUT" | "INOUT"
-```
diff --git a/docs/architecture_support.md b/docs/architecture_support.md
deleted file mode 100644
index 81ed7ea..0000000
--- a/docs/architecture_support.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Architecture Support
-
-Fuchsia supports two ISAs: arm64 and x86-64.
-
-## arm64
-
-Fuchsia supports arm64 (also called AArch64) with no restrictions on
-supported microarchitectures.
-
-## x86-64
-
-Fuchsia supports x86-64 (also called IA32e or AMD64), but with some restrictions
-on supported microarchitectures.
-
-### Intel
-
-For Intel CPUs, only Broadwell and later are actively supported and will have new features added for them.  Additionally, we will accept patches to keep Nehalem and later booting.
-
-### AMD
-
-AMD CPUs are not actively supported (in particular, we have no active testing on them), but we will accept patches to ensure correct booting on them.
diff --git a/docs/benchmarks/microbenchmarks.md b/docs/benchmarks/microbenchmarks.md
deleted file mode 100644
index 12c9b40..0000000
--- a/docs/benchmarks/microbenchmarks.md
+++ /dev/null
@@ -1,266 +0,0 @@
-### Micro-benchmarks
-
-## Environment
-
-The benchmarks recorded below are obtained by running zircon-benchmarks in a
-release build of fuchsia via ssh. When the benchmarks are recorded the Fuchsia
-user shell (GPU-accelerated) is running but no user has yet logged in.
-
-These are the running processes at the time of the benchmark:
-
-```
- ps
-TASK                    PSS PRIVATE  SHARED NAME
-j:1029               796.8M  783.9M         root
-  p:1044             558.8M  558.8M     28k bin/devmgr
-  j:1078              48.1M   39.6M         zircon-drivers
-    p:1752           180.8k    180k     28k devhost:root
-    p:1791          1596.8k   1596k     28k devhost:acpi
-    p:1840           592.8k    592k     28k devhost:misc
-    p:4684            35.0M   26.7M   16.5M devhost:pci#1:8086:5916
-    p:4730          1420.8k   1420k     28k devhost:pci#3:8086:9d2f
-    p:4858          8540.8k   8540k     28k devhost:pci#6:8086:9d03
-    p:4979           532.8k    532k     28k devhost:pci#14:8086:9d71
-    p:5052           546.8k    380k    360k devhost:pci#16:8086:15d8
-  j:1179            5745.4k   1624k         zircon-services
-    p:1182           256.8k    256k     28k crashlogger
-    p:1330          4490.8k    440k   8128k virtual-console
-    p:1425           266.8k    200k    160k netsvc
-    p:4547           176.8k    176k     28k sh:console
-    p:6058           184.8k    184k     28k vc:sh
-    p:6093           184.8k    184k     28k vc:sh
-    p:6148           184.8k    184k     28k vc:sh
-  j:1180             184.3M  183.9M         fuchsia
-    p:1234           588.8k    588k     28k appmgr
-    j:2000           183.8M  183.3M         root
-      p:2045         688.8k    688k     28k bootstrap
-      j:2336         183.1M  182.6M         boot
-        p:2427      1320.8k   1320k     28k wlanstack
-        p:2467       316.8k    316k     28k device_runner
-        p:2505       320.8k    320k     28k listen
-        p:2707      3532.8k   3432k    228k netstack
-        p:3001       288.8k    288k     28k device_runner_monitor
-        p:3101       468.8k    468k     28k netconnector
-        p:3412       336.8k    336k     28k trace_manager
-        p:3529       356.8k    356k     28k root_presenter
-        p:3587       124.2M  124.0M    404k flutter:userpicker_device_shell
-        p:3810       288.8k    288k     28k ktrace_provider
-        p:3955       332.8k    332k     28k view_manager
-        p:4110        49.2M   49.1M    356k scene_manager
-        p:4269       456.8k    456k     28k icu_data
-        p:4404       456.8k    456k     28k fonts
-        p:24555      296.8k    296k     28k oauth_token_manager
-        j:3240      1102.3k   1100k         tcp:22
-          j:24964   1102.3k   1100k         fe80::a2b3:ccff:fefb:4467:43218
-            p:24965  712.8k    712k     28k /system/bin/sshd
-            p:25157  216.8k    216k     28k /boot/bin/sh
-            p:25311  172.8k    172k     28k /boot/bin/ps
-
-```
-
-The typical thread load of the system before running the benchmarks (via k threadload):
-
-```
- cpu    load sched (cs ylds pmpts)  pf  sysc ints (hw  tmr tmr_cb) ipi (rs  gen)
-   0   0.01%        32    0     0    2    51        0    3      3        9    0
-   1   0.03%       255    0     0    3   496        0  115    115       10    0
-   2   0.45%        55    0     0    1  4218        6   11     11        8    0
-   3   0.02%        24    0     0    0    44        0    7      7        5    0
- cpu    load sched (cs ylds pmpts)  pf  sysc ints (hw  tmr tmr_cb) ipi (rs  gen)
-   0   0.00%        17    0     0    1    27        0    1      1        9    0
-   1   0.00%        13    0     0    1    19        0    2      2        8    0
-   2   0.48%       297    0     0    1  3800        5  129    129        6    1
-   3   0.02%        28    0     0    3    45        0    5      5        9    1
- cpu    load sched (cs ylds pmpts)  pf  sysc ints (hw  tmr tmr_cb) ipi (rs  gen)
-   0   0.16%       236    0     0   16   483       11   62     62       36   25
-   1   0.19%        96    0     0   35   344        0    5      5       27   39
-   2   0.57%       161    0     0   15  4715        6   15     15       53   31
-   3   0.15%       196    0     0   20   492        0   60     60       32   28
-```
-
-It is believed that the running processes has a very minor impact on benchmark results.
-
-
-## Run 8-17-2017
-
-Intel NUC  Model: NUC7i3BNK
-
-+ Processor: i3-7100U @ 2.40 GHz (Cache: 3M)
-+ Memory type: DDR4-2133 1.2V SO-DIMM
-+ Max Memory Bandwidth 34.1 GB/s
-
-```
-buildid:  GIT_5E66D79D5A167878ACF9A944AF92D0EBB6A60DF2
-ELF build ID: d1af6f49136a548ddc216a079f29341e7f4f8df9
-
-Benchmark                               Time           CPU Iterations
----------------------------------------------------------------------
-Channel/Create                        896 ns        897 ns     778195
-Channel/Write/64                      728 ns        730 ns     950200   83.6564MB/s
-Channel/Write/1024                    771 ns        773 ns     906612   1.23397GB/s
-Channel/Write/32k                    2147 ns       2149 ns     323812   14.1992GB/s
-Channel/Write/64k                    3600 ns       3599 ns     192480   16.9572GB/s
-Channel/Read/64                       717 ns        718 ns     972365   85.0027MB/s
-Channel/Read/1024                     750 ns        751 ns     934482   1.27003GB/s
-Channel/Read/32k                     2102 ns       2101 ns     332341   14.5272GB/s
-Channel/Read/64k                     3550 ns       3545 ns     198392    17.217GB/s
-ChannelMultiProcess/Write/64        88319 ns       1114 ns     100000   54.7862MB/s
-ChannelMultiProcess/Write/1024     238838 ns       1779 ns     100000   548.933MB/s
-ChannelMultiProcess/Write/32k      322097 ns      22632 ns      38626   1.34843GB/s
-ChannelMultiProcess/Write/64k      207986 ns      39543 ns      19765   1.54353GB/s
-ChannelMultiProcess/Read/64          1141 ns       1025 ns     671510    59.561MB/s
-ChannelMultiProcess/Read/1024        1292 ns       1148 ns     602280   850.681MB/s
-ChannelMultiProcess/Read/32k        19830 ns       5456 ns     128700   5.59307GB/s
-ChannelMultiProcess/Read/64k        38534 ns      10650 ns      67404   5.73121GB/s
-Event/Create                          591 ns        594 ns    1181620
-Event/Close                           681 ns        680 ns    1032407
-Event/Signal                          201 ns        199 ns    3506137
-EventPair/Create                      870 ns        871 ns     802191
-Fifo/Create                          1030 ns       1028 ns     685065
-Port/Create/0                         607 ns        610 ns    1146240
-Port/Create/0                         607 ns        609 ns    1147258
-Socket/Write/64                       698 ns        701 ns    1001960   87.0535MB/s
-Socket/Write/1024                     717 ns        720 ns     969184    1.3249GB/s
-Socket/Write/32k                     3055 ns       3047 ns     230028   10.0172GB/s
-Socket/Write/64k                     5372 ns       5327 ns     131993    11.458GB/s
-Socket/Read/64                        649 ns        652 ns    1073736    93.671MB/s
-Socket/Read/1024                      673 ns        674 ns    1039222   1.41413GB/s
-Socket/Read/32k                      2933 ns       2919 ns     240752   10.4564GB/s
-Socket/Read/64k                      5986 ns       5945 ns     122719   10.2659GB/s
-Syscall/Null                           69 ns         68 ns   10327057
-Syscall/ManyArgs                       77 ns         76 ns    9134297
-Thread/Create                        4992 ns       4967 ns     141135
-```
-
-
-## Run 1-2-2018
-
-Same NUC as before 8-17-2017.
-
-```
-buildid:  git-6e45a186511c53445c17a4c387ae8368e3e25c4a
-ELF build ID: dd1f121de3039422aa0cc0f292055f3a53d01770
-
-Benchmark                                       Time           CPU Iterations
------------------------------------------------------------------------------
-Channel/Create                                755 ns        758 ns     923119
-Channel/Write/64                              618 ns        622 ns    1124585   98.0975MB/s
-Channel/Write/1024                            656 ns        660 ns    1060610   1.44547GB/s
-Channel/Write/32k                            1710 ns       1715 ns     411234   17.7992GB/s
-Channel/Write/64k                            2728 ns       2732 ns     253504   22.3449GB/s
-Channel/Read/64                               608 ns        611 ns    1144235   99.8811MB/s
-Channel/Read/1024                             625 ns        629 ns    1113263    1.5171GB/s
-Channel/Read/32k                             1691 ns       1697 ns     413080   17.9864GB/s
-Channel/Read/64k                             2678 ns       2680 ns     194598   22.7719GB/s
-ChannelMultiProcess/Write/64                 3937 ns       1533 ns     395465   39.8076MB/s
-ChannelMultiProcess/Write/1024               5035 ns       2039 ns     367404   478.838MB/s
-ChannelMultiProcess/Write/32k                6659 ns       6565 ns      99409   4.64865GB/s
-ChannelMultiProcess/Write/64k               10233 ns      10184 ns      72843   5.99321GB/s
-ChannelMultiProcess/Read/64                   929 ns        785 ns    1003276   77.7725MB/s
-ChannelMultiProcess/Read/1024                1917 ns       1269 ns     635923   769.733MB/s
-ChannelMultiProcess/Read/32k                 6939 ns       3926 ns     185505   7.77224GB/s
-ChannelMultiProcess/Read/64k                11143 ns       7238 ns      85510   8.43315GB/s
-Event/Create                                  508 ns        512 ns    1367132
-Event/Close                                   538 ns        541 ns    1293589
-Event/Signal                                  184 ns        184 ns    3795881
-Event/Duplicate                               504 ns        507 ns    1379397
-Event/Replace                                 881 ns        888 ns     787550
-WaitItems/WaitForAlreadySignaledEvent         426 ns        426 ns    1640965
-WaitItems/WaitForManyAlread.....Event          904 ns        904 ns     774063
-EventPair/Create                              754 ns        757 ns     909870
-Fifo/Create                                   866 ns        869 ns     805670
-Filesystem_Stat                              9166 ns       5361 ns     127441
-Filesystem_Open                              8450 ns       5094 ns     100000
-Filesystem_Fstat                               92 ns         92 ns    6438952
-Mmu/MapUnmap                              2788415 ns    2788416 ns        251   89.6567M items/s
-Mmu/MapUnmapWithFaults                   47238357 ns   47238369 ns         15   677.415k items/s
-Null                                            2 ns          2 ns  343940286
-Port/Create/0                                 530 ns        534 ns    1309413
-Port/Create/0                                 530 ns        534 ns    1309573
-RoundTrip_BasicChannel_SingleProcess         6978 ns       2866 ns     272560
-RoundTrip_BasicChannel_MultiProcess          6423 ns       2598 ns     245377
-RoundTrip_ChannelPort_SingleProcess         19099 ns       7025 ns     100000
-RoundTrip_ChannelPort_MultiProcess           6802 ns       3578 ns     201762
-RoundTrip_ChannelCall_SingleProcess          5976 ns       2054 ns     299455
-RoundTrip_ChannelCall_MultiProcess           6452 ns       2248 ns     352439
-RoundTrip_Port_SingleProcess                 5240 ns       2044 ns     364514
-RoundTrip_Port_MultiProcess                  5277 ns       2050 ns     350067
-RoundTrip_Fidl_SingleProcess                 7557 ns       3431 ns     202477
-RoundTrip_Fidl_MultiProcess                  7952 ns       3529 ns     191490
-RoundTrip_Futex_SingleProcess                1919 ns        733 ns     774109
-RoundTrip_PthreadCondvar_SingleProcess       5009 ns       1958 ns     337155
-Socket/Write/64                               620 ns        624 ns    1105152   97.8442MB/s
-Socket/Write/1024                             642 ns        645 ns    1085336   1.47847GB/s
-Socket/Write/32k                             2441 ns       2442 ns     286410   12.4976GB/s
-Socket/Write/64k                             4355 ns       4357 ns     165482   14.0074GB/s
-Socket/Read/64                                566 ns        570 ns    1227297   107.058MB/s
-Socket/Read/1024                              585 ns        589 ns    1188832   1.61839GB/s
-Socket/Read/32k                              2424 ns       2434 ns     287447   12.5394GB/s
-Socket/Read/64k                              4268 ns       4276 ns     157620   14.2755GB/s
-Syscall/Null                                   66 ns         66 ns   10633067
-Syscall/ManyArgs                               73 ns         73 ns    9628920
-Thread/Create                              180160 ns     180210 ns      10000
-Thread/CreateAndJoin                       533727 ns     529902 ns       1639
-TimeGetMonotonic                               84 ns         84 ns    8334566
-TimeGetUtc                                     84 ns         84 ns    8315454
-TimeGetThread                                 114 ns        114 ns    6163473
-TicksGet                                       11 ns         11 ns   62389940
-Vmo/Create                                    713 ns        718 ns     976569
-
-```
-
-## Channels benchmark change from baseline
-
-Baseline is 8-17-2017
-
-```
-                                    1-2-18
--------------------------------------------
-Channel/Create                      18.68%
-Channel/Write/64                    17.80%
-Channel/Write/1024                  17.53%
-Channel/Write/32k                   25.56%
-Channel/Write/64k                   31.96%
-Channel/Read/64                     17.93%
-Channel/Read/1024                   20.00%
-Channel/Read/32k                    24.31%
-Channel/Read/64k                    32.56%
-ChannelMultiProcess/Write/64      2143.31%
-ChannelMultiProcess/Write/1024    4643.56%
-ChannelMultiProcess/Write/32k     4737.02%
-ChannelMultiProcess/Write/64k     1932.50%
-ChannelMultiProcess/Read/64         22.82%
-ChannelMultiProcess/Read/1024      -32.60%  (decrease)
-ChannelMultiProcess/Read/32k       185.78%
-ChannelMultiProcess/Read/64k       245.81%
-```
-
-## Events benchmark change from baseline
-
-Baseline is 8-17-2017
-
-```
-                                    1-2-18
-------------------------------------------
-Event/Create                        16.34%
-Event/Close                         26.58%
-Event/Signal                         9.24%
-```
-
-## Socket benchmark change from baseline
-
-Baseline is 8-17-2017
-
-```
-                                    1-2-18
-------------------------------------------
-Socket/Write/64                     12.58%
-Socket/Write/1024                   11.68%
-Socket/Write/32k                    25.15%
-Socket/Write/64k                    23.35%
-Socket/Read/64                      14.66%
-Socket/Read/1024                    15.04%
-Socket/Read/32k                     21.00%
-Socket/Read/64k                     40.25%
-
-```
diff --git a/docs/block_device_testing.md b/docs/block_device_testing.md
deleted file mode 100644
index 81eecc5..0000000
--- a/docs/block_device_testing.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# Block device testing
-
-__WARNING: All of the following tests are destructive, and they may not
-ask for confirmation before executing. Run at your own risk.__
-
-## Protocol testing
-
-*blktest* is an integration which may be used to check adherence to the block protocol.
-
-```shell
-$ blktest -d /dev/class/block/000
-```
-
-## Filesystem testing
-
-*fs-test* is a filesystem integration test suite that can be used to verify
-Fuchsia filesystem correctness on a filesystem.
-
-To avoid racing with the auto-mounter, it is recommended to run this
-test with the kernel command line option "zircon.system.disable-automount=true".
-
-TODO(ZX-1604): Ensure this filesystem test suite can execute on large
-partitions. It is currently recommended to use this test on a 1-2 GB GPT
-partition on the block device.
-
-```shell
-$ /boot/test/fs/fs-test -d /dev/class/block/000 -f minfs
-```
-
-## Correctness testing
-
-*iochk* is a tool which pseudorandomly reads and writes to a block device to check for errors.
-
-```shell
-$ iochk -bs 32k -t 8 /dev/class/block/000
-```
-
-## Performance testing
-
-*iotime* is a benchmarking tool which tests the read and write performance of block devices.
-
-```shell
-$ iotime read fifo /dev/class/block/000 64m 4k
-```
-
-
diff --git a/docs/bootsvc.md b/docs/bootsvc.md
deleted file mode 100644
index 8301816..0000000
--- a/docs/bootsvc.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Bootsvc
-
-`bootsvc` is (typically) the first program loaded by usermode (contrast with
-[userboot](userboot.md), which is loaded by the kernel).  `bootsvc` provides
-several system services:
-- A filesystem service with the contents of the bootfs (/boot)
-- A loader service that loads from that bootfs
-
-After preparing these services, it launches one program from the bootfs.  The
-program may be selected with a [kernel command line argument](kernel_cmdline.md)
-`bootsvc.next` (this default to `bin/devmgr` currently).  The launched program
-is provided with the bootfs mounted at `/boot` and the loader service.  The
-kernel command line arguments are provided to it via `envp`.  See the
-documentation in `system/core/bootsvc/main.cpp:LaunchNextProcess()` for more
-details.
diff --git a/docs/concepts.md b/docs/concepts.md
deleted file mode 100644
index 4a4dd69..0000000
--- a/docs/concepts.md
+++ /dev/null
@@ -1,229 +0,0 @@
-# Zircon Kernel Concepts
-
-## Introduction
-
-The kernel manages a number of different types of Objects. Those which are
-accessible directly via system calls are C++ classes which implement the
-Dispatcher interface. These are implemented in
-[kernel/object](../kernel/object). Many are self-contained higher-level Objects.
-Some wrap lower-level [lk](../../docs/glossary.md#lk) primitives.
-
-## [System Calls](syscalls.md)
-
-Userspace code interacts with kernel objects via system calls, and almost
-exclusively via [Handles](handles.md).  In userspace, a Handle is represented as
-32bit integer (type zx_handle_t).  When syscalls are executed, the kernel checks
-that Handle parameters refer to an actual handle that exists within the calling
-process's handle table.  The kernel further checks that the Handle is of the
-correct type (passing a Thread Handle to a syscall requiring an event handle
-will result in an error), and that the Handle has the required Rights for the
-requested operation.
-
-System calls fall into three broad categories, from an access standpoint:
-
-1. Calls which have no limitations, of which there are only a very few, for
-example [*zx_clock_get()*](syscalls/clock_get.md)
-and [*zx_nanosleep()*](syscalls/nanosleep.md) may be called by any thread.
-2. Calls which take a Handle as the first parameter, denoting the Object they act upon,
-which are the vast majority, for example [*zx_channel_write()*](syscalls/channel_write.md)
-and [*zx_port_queue()*](syscalls/port_queue.md).
-3. Calls which create new Objects but do not take a Handle, such as
-[*zx_event_create()*](syscalls/event_create.md) and
-[*zx_channel_create()*](syscalls/channel_create.md).  Access to these (and limitations
-upon them) is controlled by the Job in which the calling Process is contained.
-
-System calls are provided by libzircon.so, which is a "virtual" shared
-library that the Zircon kernel provides to userspace, better known as the
-[*virtual Dynamic Shared Object* or vDSO](vdso.md).
-They are C ELF ABI functions of the form *zx_noun_verb()* or
-*zx_noun_verb_direct-object()*.
-
-The system calls are defined by [syscalls.abigen](../system/public/zircon/syscalls.abigen)
-and processed by the [abigen](../system/host/abigen/) tool into include files and glue
-code in libzircon and the kernel's libsyscalls.
-
-
-## [Handles](handles.md) and [Rights](rights.md)
-
-Objects may have multiple Handles (in one or more Processes) that refer to them.
-
-For almost all Objects, when the last open Handle that refers to an Object is closed,
-the Object is either destroyed, or put into a final state that may not be undone.
-
-Handles may be moved from one Process to another by writing them into a Channel
-(using [*zx_channel_write()*](syscalls/channel_write.md)), or by using
-[*zx_process_start()*](syscalls/process_start.md) to pass a Handle as the argument
-of the first thread in a new Process.
-
-The actions which may be taken on a Handle or the Object it refers to are governed
-by the Rights associated with that Handle.  Two Handles that refer to the same Object
-may have different Rights.
-
-The [*zx_handle_duplicate()*](syscalls/handle_duplicate.md) and
-[*zx_handle_replace()*](syscalls/handle_replace.md) system calls may be used to
-obtain additional Handles referring to the same Object as the Handle passed in,
-optionally with reduced Rights.  The [*zx_handle_close()*](syscalls/handle_close.md)
-system call closes a Handle, releasing the Object it refers to, if that Handle is
-the last one for that Object. The [*zx_handle_close_many()*](syscalls/handle_close_many.md)
-system call similarly closes an array of handles.
-
-
-## Kernel Object IDs
-
-Every object in the kernel has a "kernel object id" or "koid" for short.
-It is a 64 bit unsigned integer that can be used to identify the object
-and is unique for the lifetime of the running system.
-This means in particular that koids are never reused.
-
-There are two special koid values:
-
-*ZX_KOID_INVALID* Has the value zero and is used as a "null" sentinel.
-
-*ZX_KOID_KERNEL* There is only one kernel, and it has its own koid.
-
-Kernel generated koids only use 63 bits (which is plenty).
-This leaves space for artificially allocated koids by having the most
-significant bit set.
-Artificial koids exist to support things like identifying artificial objects,
-like virtual threads in tracing, for consumption by tools.
-How artificial koids are allocated is left to each program,
-this document does not impose any rules or conventions.
-
-
-## Running Code: Jobs, Processes, and Threads.
-
-Threads represent threads of execution (CPU registers, stack, etc) within an
-address space which is owned by the Process in which they exist.  Processes are
-owned by Jobs, which define various resource limitations.  Jobs are owned by
-parent Jobs, all the way up to the Root Job which was created by the kernel at
-boot and passed to [`userboot`, the first userspace Process to begin execution](userboot.md).
-
-Without a Job Handle, it is not possible for a Thread within a Process to create another
-Process or another Job.
-
-[Program loading](program_loading.md) is provided by userspace facilities and
-protocols above the kernel layer.
-
-See: [process_create](syscalls/process_create.md),
-[process_start](syscalls/process_start.md),
-[thread_create](syscalls/thread_create.md),
-and [thread_start](syscalls/thread_start.md).
-
-
-## Message Passing: Sockets and Channels
-
-Both Sockets and Channels are IPC Objects which are bi-directional and two-ended.
-Creating a Socket or a Channel will return two Handles, one referring to each endpoint
-of the Object.
-
-Sockets are stream-oriented and data may be written into or read out of them in units
-of one or more bytes.  Short writes (if the Socket's buffers are full) and short reads
-(if more data is requested than in the buffers) are possible.
-
-Channels are datagram-oriented and have a maximum message size given by **ZX_CHANNEL_MAX_MSG_BYTES**,
-and may also have up to **ZX_CHANNEL_MAX_MSG_HANDLES** Handles attached to a message.
-They do not support short reads or writes -- either a message fits or it does not.
-
-When Handles are written into a Channel, they are removed from the sending Process.
-When a message with Handles is read from a Channel, the Handles are added to the receiving
-Process.  Between these two events, the Handles continue to exist (ensuring the Objects
-they refer to continue to exist), unless the end of the Channel which they have been written
-towards is closed -- at which point messages in flight to that endpoint are discarded and
-any Handles they contained are closed.
-
-See: [channel_create](syscalls/channel_create.md),
-[channel_read](syscalls/channel_read.md),
-[channel_write](syscalls/channel_write.md),
-[channel_call](syscalls/channel_call.md),
-[socket_create](syscalls/socket_create.md),
-[socket_read](syscalls/socket_read.md),
-and [socket_write](syscalls/socket_write.md).
-
-## Objects and Signals
-
-Objects may have up to 32 signals (represented by the zx_signals_t type and the ZX_*_SIGNAL_*
-defines) which represent a piece of information about their current state.  Channels and Sockets,
-for example, may be READABLE or WRITABLE.  Processes or Threads may be TERMINATED.  And so on.
-
-Threads may wait for signals to become active on one or more Objects.
-
-See [signals](signals.md) for more information.
-
-## Waiting: Wait One, Wait Many, and Ports
-
-A Thread may use [*zx_object_wait_one()*](syscalls/object_wait_one.md)
-to wait for a signal to be active on a single handle or
-[*zx_object_wait_many()*](syscalls/object_wait_many.md) to wait for
-signals on multiple handles.  Both calls allow for a timeout after
-which they'll return even if no signals are pending.
-
-Timeouts may deviate from the specified deadline according to timer
-slack. See [timer slack](timer_slack.md) for more information.
-
-If a Thread is going to wait on a large set of handles, it is more efficient to use
-a Port, which is an Object that other Objects may be bound to such that when signals
-are asserted on them, the Port receives a packet containing information about the
-pending Signals.
-
-See: [port_create](syscalls/port_create.md),
-[port_queue](syscalls/port_queue.md),
-[port_wait](syscalls/port_wait.md),
-and [port_cancel](syscalls/port_cancel.md).
-
-
-## Events, Event Pairs.
-
-An Event is the simplest Object, having no other state than its collection of active Signals.
-
-An Event Pair is one of a pair of Events that may signal each other.  A useful property of
-Event Pairs is that when one side of a pair goes away (all Handles to it have been
-closed), the PEER_CLOSED signal is asserted on the other side.
-
-See: [event_create](syscalls/event_create.md),
-and [eventpair_create](syscalls/eventpair_create.md).
-
-
-## Shared Memory: Virtual Memory Objects (VMOs)
-
-Virtual Memory Objects represent a set of physical pages of memory, or the *potential*
-for pages (which will be created/filled lazily, on-demand).
-
-They may be mapped into the address space of a Process with
-[*zx_vmar_map()*](syscalls/vmar_map.md) and unmapped with
-[*zx_vmar_unmap()*](syscalls/vmar_unmap.md).  Permissions of
-mapped pages may be adjusted with [*zx_vmar_protect()*](syscalls/vmar_protect.md).
-
-VMOs may also be read from and written to directly with
-[*zx_vmo_read()*](syscalls/vmo_read.md) and [*zx_vmo_write()*](syscalls/vmo_write.md).
-Thus the cost of mapping them into an address space may be avoided for one-shot operations
-like "create a VMO, write a dataset into it, and hand it to another Process to use."
-
-## Address Space Management
-
-Virtual Memory Address Regions (VMARs) provide an abstraction for managing a
-process's address space.  At process creation time, a handle to the root VMAR
-is given to the process creator.  That handle refers to a VMAR that spans the
-entire address space.  This space can be carved up via the
-[*zx_vmar_map()*](syscalls/vmar_map.md) and
-[*zx_vmar_allocate()*](syscalls/vmar_allocate.md) interfaces.
-[*zx_vmar_allocate()*](syscalls/vmar_allocate.md) can be used to generate new
-VMARs (called subregions or children) which can be used to group together
-parts of the address space.
-
-See: [vmar_map](syscalls/vmar_map.md),
-[vmar_allocate](syscalls/vmar_allocate.md),
-[vmar_protect](syscalls/vmar_protect.md),
-[vmar_unmap](syscalls/vmar_unmap.md),
-and [vmar_destroy](syscalls/vmar_destroy.md),
-
-## Futexes
-
-Futexes are kernel primitives used with userspace atomic operations to implement
-efficient synchronization primitives -- for example, Mutexes which only need to make
-a syscall in the contended case.  Usually they are only of interest to implementers of
-standard libraries.  Zircon's libc and libc++ provide C11, C++, and pthread APIs for
-mutexes, condition variables, etc, implemented in terms of Futexes.
-
-See: [futex_wait](syscalls/futex_wait.md),
-[futex_wake](syscalls/futex_wake.md),
-and [futex_requeue](syscalls/futex_requeue.md).
diff --git a/docs/contributing.md b/docs/contributing.md
deleted file mode 100644
index 868f4b5..0000000
--- a/docs/contributing.md
+++ /dev/null
@@ -1,129 +0,0 @@
-# Contributing Patches to Zircon
-
-At this point in time, Zircon is under heavy, active development, and we're
-not seeking major changes or new features from new contributors, however, if
-you desire to [contribute](https://fuchsia.googlesource.com/docs/+/master/CONTRIBUTING.md), small bugfixes are welcome.
-
-Here are some general guidelines for patches to Zircon.  This list is
-incomplete and will be expanded over time.
-
-[TOC]
-
-## Process
-
-*   GitHub pull requests are not accepted. Patches are handled via Gerrit Code
-    Review at: https://fuchsia-review.googlesource.com/#/q/project:zircon
-
-*   The #fuchsia channel on the freenode irc network is a good place to ask
-    questions.
-
-*   Include [tags] in the commit subject flagging which module, library, app,
-    etc, is affected by the change. The style here is somewhat informal. Look at
-    past changes to get a feel for how these are used. Gerrit will flag your
-    change with `Needs Label: Commit-Message-has-tags` if these are missing.
-
-*   Include a line like `Test: <how this was tested>` in the commit message, or
-    else Gerrit will flag your change with `Needs Label:
-    Commit-Message-has-TEST-line`.
-
-    *   The full (Java-style) regex is `(?i:test|tests|tested|testing)[
-        \t]*[=:]`, so lines like `TESTED=asdf` or `Testing : 1234` are also
-        valid, along with lines that only contain `Test:` with the details on
-        the following lines.
-
-*   [Googlers only] Commit messages may reference issue IDs, which will be
-    turned into links in the Gerrit UI. Issues may also be automatically closed
-    using the syntax `BUG-123 #done`. *Note*: Zircon's issue tracker is not open
-    to external contributors at this time.
-
-*   Zircon should be buildable for all major targets (x86-64, arm64) at every
-    change. ./scripts/build-all-zircon can help with this.
-
-*   Avoid breaking the unit tests. Boot Zircon and run "runtests" to verify that
-    they're all passing.
-
-*   Avoid whitespace or style changes. Especially do not mix style changes with
-    patches that do other things as the style changes are a distraction.
-
-*   Avoid changes that touch multiple modules at once if possible. Most changes
-    should be to a single library, driver, app, etc.
-
-## Style
-
-* Code style mostly follows the [Google C++ Style Guide][google-style-guide], except:
-
-    - When editing existing code, match local style.  This supersedes the other style rules.
-
-    - Maximum line width is 100 characters rather than 80.
-
-    - Indentation is four spaces, not two.  Still never use tabs.  Do not leave trailing whitespace
-      on lines.  Gerrit will flag bad whitespace usage with a red background in diffs.
-
-    - Zircon declares pointers as `char* p` and **not** as `char *p;`.  The Google style guide is
-      ambivalent about this; Zircon standardized on asterisk-with-type instead of
-      asterisk-with-name.
-
-    - Inside a `switch` statement, the `case` labels are not indented.  Example:
-
-          void foo(int which) {
-              switch (which) {
-              case 0:
-                  foo_zero();
-                  break;
-              case 17:
-                  foo_seventeen();
-                  break;
-              default:
-                  panic("I don't know how to foo here (which = %d)\n", which);
-              }
-          }
-
-    - Put curly braces around the body of any loop and in any `if` statement where the body is on
-      another line (including any `if` statement that has an `else if` or `else` part). Trivial `if`
-      statements can be written on one line, like this:
-
-          if (result != ZX_OK) return result;
-
-       However, do **not** write:
-
-          if (result == ZX_OK)
-              return do_more_stuff(data);
-          else
-              return result;
-
-       and do **not** write:
-
-          while (result == ZX_OK)
-              result = do_another_step(data);
-
-      Note that this rule isn't enforced by `clang-fmt`, so please pay attention to it when writing
-      code and reviewing commits.
-
-* You can run `./scripts/clang-fmt` to reformat files.  Pass in the filenames as arguments, e.g.
-
-      scripts/clang-fmt kernel/top/main.c kernel/top/init.c
-
-  The `clang-fmt` script will automatically download and run the `clang-format` binary.  This fixes
-  most style problems, except for line length (since `clang-format` is too aggressive about
-  re-wrapping modified lines).
-
-## Documentation
-
-* Documentation is one honking great idea &mdash; let's do more of that!
-
-    - Documentation should be in Markdown files.  Our Markdown is rendered in Gitiles in
-      [the main repo browser][googlesource-docs]. Please check how your docs are rendered.
-
-    - Some notable docs: there's a list of syscalls in [docs/syscalls.md][syscall-doc] and a list of
-      kernel cmdline options in [docs/kernel_cmdline.md][cmdline-doc].  When editing or adding
-      syscalls or cmdlines, update the docs!
-
-    - [The `h2md` tool][h2md-doc] can scrape source files and extract embedded Markdown.  It's
-      currently used to generate API docs for DDK.  `./scripts/make-markdown` runs `h2md` against
-      all source files in the `system/` tree.
-
-[google-style-guide]: https://google.github.io/styleguide/cppguide.html
-[googlesource-docs]: https://fuchsia.googlesource.com/zircon/+/master/docs/
-[syscall-doc]: https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls.md
-[cmdline-doc]: https://fuchsia.googlesource.com/zircon/+/master/docs/kernel_cmdline.md
-[h2md-doc]: https://fuchsia.googlesource.com/zircon/+/master/docs/h2md.md
diff --git a/docs/cxx.md b/docs/cxx.md
deleted file mode 100644
index 7a5a1db..0000000
--- a/docs/cxx.md
+++ /dev/null
@@ -1,339 +0,0 @@
-# C++ in Zircon
-
-A subset of the C++17 language is used in the Zircon tree.  This includes both
-the kernel and userspace code.  C++ is mixed with C (and some assembly) in
-both places.  Some C++ language features are avoided or prohibited.  Use of
-the C++ standard library features is very circumspect.
-
-## Language features
-
-- Not allowed
-  - Exceptions
-  - RTTI and `dynamic_cast`
-  - Operator overloading
-  - Virtual inheritance
-  - Statically constructed objects
-  - Trailing return type syntax
-    - Exception: when necessary for lambdas with otherwise unutterable return types
-  - Initializer lists
-  - `thread_local` in kernel code
-- Allowed
-  - Pure interface inheritance
-  - Lambdas
-  - `constexpr`
-  - `nullptr`
-  - `enum class`es
-  - `template`s
-  - Default parameters
-    - But use judgment. One optional out parameter at the end is
-      probably fine. Four optional bool arguments, probably not.
-  - Plain old classes
-  - `auto`
-  - Multiple implementation inheritance
-    - But be judicious. This is used widely for e.g. intrusive
-    container mixins.
-- Needs more ruling TODO(cpu)
-  - Global constructors
-    - Currently we have these for global data structures.
-
-**TODO:** pointer to style guide(s)?
-
-## C++ Standard Edition (17 vs 14)
-
-Zircon code is built with `-std=c++17` and in general can use C++ 17 language
-and library features freely (subject to style/feature constraints described
-[above](#language-features) and library use guidelines described
-[below](#standard-library)).  There is no *general* concern with staying
-compatible with C++ 14 or earlier versions.  When a standard C++ 17 feature is
-the cleanest way to do something, do it that way.
-
-**However** any library that is **published to the SDK** must be compatible
-with SDK users building in **both** C++ 14 and C++ 17 modes.  So, any
-libraries exported to the SDK must have public header files that are
-*compatible with both `-std=c++14` and `-std=c++17`*.  If a library is
-exported to the SDK as source code rather than as a binary, then its *source
-code must also be completely compatible with both `-std=c++14` and
-`-std=c++17`* (and not require other special options). **TODO(mcgrathr):**
-_pointer to build-system docs about maintaining code to be exported to SDK_
-
-All pure C code (`.c` source files and headers used by them) is C 11.  Some
-special exceptions are made for code meant to be reused by out-of-tree boot
-loaders, which stick to a conservative C 89 subset for embedded code.
-
-## Standard Library
-
-The C++ standard library API has many interfaces of widely varying
-characteristics.  We subdivide the standard library API into several
-categories below, based on the predictability and complexity of each
-particular interface's code generation and use of machine and OS facilities.
-These can be thought of as widening concentric circles of the API from the
-most minimal C-like subset out to the full C++ 17 API.
-
-**NOTE: TODO([ZX-1751](https://fuchsia.atlassian.net/browse/ZX-1751))**
-Currently **Zircon userspace code is restricted to header-only library APIs**
-from the standard C++ library.  This limitation **will be lifted** by
-forthcoming fixes (or overhauls) to the C++ standard library runtime build and
-the build system.  There are no limitations on host-only C++ code.  If you're
-not sure whether an API is header-only, try using it in userspace code in the
-Zircon tree and if you get a link-time error then it's not header-only.
-
-#### Context Matters
-
-This section gives guidelines for how to think about the impact of using a
-particular standard C++ library API on the system as a whole.  There are no
-hard and fast rules, except for the kernel (see the next section)--and except
-for implementation constraints, which one always hopes should be temporary.
-
-The overwhelming rule is **be circumspect**.
-
- * Consider how well you understand the time and space complexity, the dynamic
-   allocation behavior (if any), and the failure modes of *each API you use*.
-
- * Then consider the specific *context* where it's being used, and how
-   sensitive that context is to those various kinds of concerns.
-
- * Be especially wary about **input-dependent** behavior that can quickly
-   become far harder to predict when using nontrivial library facilities.
-
-If you're writing the main I/O logic in a driver, or anything that's in a hot
-path for latency, throughput, or reliability, in any kind of system service,
-then you should be pretty conservative in what library facilities you rely on.
-They're all technically available to you in userspace (though far fewer in the
-kernel; see the next section).  But there's not so many you actually should
-use.  You probably don't want to lean on a lot of `std` containers that do
-fancy dynamic allocation behind the scenes.  They will make it hard for you to
-understand, predict, and control the storage/memory footprint, allocation
-behavior, performance, and reliability of your service.
-
-Nonetheless, even a driver is a userspace program that starts up and parses
-configuration files or arguments and so on.  For all those nonessential or
-start-time functions that are not part of the hot path, using more complex
-library facilities is probably fine when that makes the work easier.  Just
-remember to pay attention to overall metrics for your code, such as
-minimal/total/peak runtime memory use, code bloat (which uses both device
-storage and runtime memory), and resilience to unexpected failure modes.
-Maybe don't double the code size and memory footprint of your driver just to
-leverage that fancy configuration-parsing library.
-
-#### No `std` in kernel
-
-The C++ `std` namespace **cannot** be used in [kernel](../kernel) code, which
-also includes [bootloader](../bootloader).  The few C++ standard library
-headers that don't involve `std::` APIs can still be used directly.  See the
-next section.
-
-No other C++ standard headers should be used in kernel code.  Instead,
-any library facilities worthwhile to have in the kernel (such as
-`std::move`) are provided via kernel-specific APIs (such as
-`ktl::move`).  The kernel's implementations of these APIs may in fact
-rely on toolchain headers providing `std::` implementations that are
-aliased to kernel API names.  But only those API implementations and
-very special cases in certain library headers should ever use `std::`
-in source code built into the kernel.
-
-#### Universal headers
-
-These header APIs are safe to use everywhere, even in the kernel.
-
-They include the C++ wrappers on the subset of standard C interfaces that the
-kernel supports:
-
- * [`<cstdarg>`](https://en.cppreference.com/w/cpp/header/cstdarg)
- * [`<cstddef>`](https://en.cppreference.com/w/cpp/header/cstddef)
- * [`<climits>`](https://en.cppreference.com/w/cpp/header/climits)
- * [`<cstdint>`](https://en.cppreference.com/w/cpp/header/cstdint)
- * [`<cinttypes>`](https://en.cppreference.com/w/cpp/header/cinttypes)
- * [`<cassert>`](https://en.cppreference.com/w/cpp/header/cassert)
- * [`<cstring>`](https://en.cppreference.com/w/cpp/header/cstring)
-
-The `std` namespace aliases for C library APIs from these headers should not
-be used in kernel code.
-
-One pure C++ header is also available even in the kernel:
-
- * [`<new>`](https://en.cppreference.com/w/cpp/header/new)
-
-   The vanilla non-placement `operator new` and `operator new[]` are not
-   available in the kernel.  Use [`fbl::AllocChecker`
-   `new`](../system/ulib/fbl/include/fbl/alloc_checker.h) instead.
-
-#### Conservative userspace
-
-These header APIs are safe to use everywhere.  They're not allowed in the
-kernel because they're all entirely in the `std` namespace.  But subsets of
-these APIs are likely candidates to get an in-kernel API alias if there is a
-good case for using such an API in kernel code.
-
-These are pure header-only types and templates.  They don't do any dynamic
-allocation of their own.  The time and space complexity of each function
-should be clear from its description.
-
- * [`<algorithm>`](https://en.cppreference.com/w/cpp/header/algorithm)
- * [`<array>`](https://en.cppreference.com/w/cpp/header/array)
- * [`<atomic>`](https://en.cppreference.com/w/cpp/header/atomic)
- * [`<bitset>`](https://en.cppreference.com/w/cpp/header/bitset)
- * [`<initializer_list>`](https://en.cppreference.com/w/cpp/header/initializer_list)
- * [`<iterator>`](https://en.cppreference.com/w/cpp/header/iterator)
- * [`<limits>`](https://en.cppreference.com/w/cpp/header/limits)
- * [`<optional>`](https://en.cppreference.com/w/cpp/header/optional)
- * [`<tuple>`](https://en.cppreference.com/w/cpp/header/tuple)
- * [`<type_traits>`](https://en.cppreference.com/w/cpp/header/type_traits)
- * [`<utility>`](https://en.cppreference.com/w/cpp/header/utility)
- * [`<variant>`](https://en.cppreference.com/w/cpp/header/variant)
-
-These involve some dynamic allocation, but only what's explicit:
-
- * [`<any>`](https://en.cppreference.com/w/cpp/header/any)
- * [`<memory>`](https://en.cppreference.com/w/cpp/header/memory)
-
-   The `std::shared_ptr`, `std::weak_ptr`, and `std::auto_ptr` APIs should
-   **never** be used.  Use `std::unique_ptr` and `fbl::RefPtr` instead.
-
-##### Userspace-only
-
-These are not things that would ever be available at all or by any similar API
-or name in the kernel.  But they are generally harmless everywhere in
-userspace.  They do not involve dynamic allocation.
-
- * Floating-point is never available in kernel code, but can be used
-   (subject to performance considerations) in all userspace code.
-   * [`<cfenv>`](https://en.cppreference.com/w/cpp/header/cfenv)
-   * [`<cfloat>`](https://en.cppreference.com/w/cpp/header/cfloat)
-   * [`<cmath>`](https://en.cppreference.com/w/cpp/header/cmath)
-   * [`<complex>`](https://en.cppreference.com/w/cpp/header/complex)
-   * [`<numeric>`](https://en.cppreference.com/w/cpp/header/numeric)
-   * [`<ratio>`](https://en.cppreference.com/w/cpp/header/ratio)
-   * [`<valarray>`](https://en.cppreference.com/w/cpp/header/valarray)
-
- * Full C 11 standard library, via C++ wrappers or in standard C `<*.h>`.
-   * [`<csetjmp>`](https://en.cppreference.com/w/cpp/header/csetjmp)
-   * [`<cstdlib>`](https://en.cppreference.com/w/cpp/header/cstdlib)
-   * [Standard C11 interfaces](https://en.cppreference.com/w/c/header)
-
- * Synchronization and threads.  These standard APIs are safe to use in all
-   userspace code with appropriate discretion.  But it may often be better to
-   use Zircon's own library APIs for similar things, such as
-   [<lib/sync/...>](../system/ulib/sync/include).
-   * [`<condition_variable>`](https://en.cppreference.com/w/cpp/header/condition_variable)
-   * [`<execution>`](https://en.cppreference.com/w/cpp/header/execution)
-   * [`<mutex>`](https://en.cppreference.com/w/cpp/header/mutex)
-   * [`<shared_mutex>`](https://en.cppreference.com/w/cpp/header/shared_mutex)
-   * [`<thread>`](https://en.cppreference.com/w/cpp/header/thread)
-
-#### Kitchen sink
-
-These involve dynamic allocation that is hard to predict and is generally out
-of your control.  The exact runtime behavior and memory requirements are often
-hard to reason about.  Think very hard before using these interfaces in any
-critical path for reliability or performance or in any component that is meant
-to be lean and space-efficient.
-
- * The entire [Containers library](https://en.cppreference.com/w/cpp/container)
-
- * [`<functional>`](https://en.cppreference.com/w/cpp/header/functional)
-
-   See [`<lib/fit/function.h>`](../system/ulib/fit/include/lib/fit/function.h)
-   for a homegrown alternative.
-
- * [`<memory_resource>`](https://en.cppreference.com/w/cpp/header/memory_resource)
- * [`<scoped_allocator>`](https://en.cppreference.com/w/cpp/header/scoped_allocator)
-
- * [`<filesystem>`](https://en.cppreference.com/w/cpp/header/filesystem)
- * [`<regex>`](https://en.cppreference.com/w/cpp/header/regex)
-
-## FBL
-
-FBL is the Fuchsia Base Library, which is shared between kernel and userspace.
-As a result, FBL has very strict dependencies.  For example, FBL cannot depend
-on the syscall interface because the syscall interface is not available within
-the kernel.  Similarly, FBL cannot depend on C library features that are not
-available in the kernel.
-
-1. [system/ulib/fbl](../system/ulib/fbl) which is usable from both
-   kernel and userspace.
-2. [kernel/lib/fbl](../kernel/lib/fbl) which is usable only from
-    the kernel.
-
-**NOTE:** Some FBL interfaces below that overlap with standard C++ library
-interfaces will probably be either removed entirely or made kernel-only (and
-perhaps renamed inside the kernel) once userspace code has migrated to using
-standard C++ library facilities where appropriate.
-
-FBL provides:
-
-- utility code
-  - [basic algorithms](../system/ulib/fbl/include/fbl/algorithm.h)
-  - [integer type limits](../system/ulib/fbl/include/fbl/limits.h)
-  - [type traits](../system/ulib/fbl/include/fbl/type_support.h)
-  - [atomics](../system/ulib/fbl/include/fbl/atomic.h)
-  - [alloc checking new](../system/ulib/fbl/include/fbl/alloc_checker.h)
-- allocators
-  - [slab allocation](../system/ulib/fbl/include/fbl/slab_allocator.h)
-  - [slab malloc](../system/ulib/fbl/include/fbl/slab_malloc.h)
-- arrays
-  - [fixed sized arrays](../system/ulib/fbl/include/fbl/array.h)
-  - [fixed sized arrays](../kernel/lib/fbl/include/fbl/inline_array.h),
-    which stack allocates small arrays
-- inline containers
-  - [doubly linked list](../system/ulib/fbl/include/fbl/intrusive_double_list.h)
-  - [hash table](../system/ulib/fbl/include/fbl/intrusive_hash_table.h)
-  - [singly linked list](../system/ulib/fbl/include/fbl/intrusive_single_list.h)
-  - [wavl trees](../system/ulib/fbl/include/fbl/intrusive_wavl_tree.h)
-- smart pointers
-  - [intrusive refcounted mixin](../system/ulib/fbl/include/fbl/ref_counted.h)
-  - [intrusive refcounting pointer](../system/ulib/fbl/include/fbl/ref_ptr.h)
-  - [unique pointer](../system/ulib/fbl/include/fbl/unique_ptr.h)
-- raii utilities
-  - [auto call](../system/ulib/fbl/include/fbl/auto_call.h) to run
-    code upon leaving scope
-  - [AutoLock](../system/ulib/fbl/include/fbl/auto_lock.h)
-
-FBL has strict controls on memory allocation.  Memory allocation should be
-explicit, using an AllocChecker to let clients recover from allocation
-failures.  In some cases, implicit memory allocation is permitted, but
-functions that implicitly allocate memory must be #ifdef'ed to be unavailable
-in the kernel.
-
-FBL not available outside the Fuchsia Source Tree.
-
-## ZX
-
-ZX contains C++ wrappers for the Zircon [objects](objects) and
-[syscalls](syscalls.md).  These wrappers provide type safety and move semantics
-for handles but offer no opinion beyond what's in syscalls.abigen.  At some
-point in the future, we might autogenerate ZX from syscalls.abigen, similar to
-how we autogenerate the syscall wrappers in other languages.
-
-ZX is part of the Fuchsia SDK.
-
-## FZL
-
-FZL is the Fuchsia Zircon Library.  This library provides value-add for common
-operations involving kernel objects and is free to have opinions about how to
-interact with the Zircon syscalls.  If a piece of code has no dependency on
-Zircon syscalls, the code should go in FBL instead.
-
-FZL not available outside the Fuchsia Source Tree.
-
-## ZXCPP
-
-Some of our code runs in an environment which cannot include the
-standard C++ runtime environment. This environment includes symbols
-like __cxa_pure_virtual that are defined by the ABI and that the
-compiler expects to be ambient. [The zxcpp
-library](../system/ulib/zxcpp) provides that dependency. It also
-includes the placement operator new overloads and, in userspace, the
-standard new and delete operators. Note that it does not include the
-similarly named __cxa_atexit, which in userspace must be provided by
-the libc. See extensive comments in musl's atexit implementation if
-you are curious.
-
-*This library is mutually exclusive of the standard C++ library.*
-
-**NOTE: TODO([ZX-1751](https://fuchsia.atlassian.net/browse/ZX-1751))** The
-ZXCPP library will be removed in favor of hermetic static linking for the
-standard C++ library.  Closed-world C++ modules such as drivers or shared
-libraries with a pure C ABI can use the standard C++ library internally
-without affecting their outward ABIs.  Current users of ZXCPP will become
-users of the hermetic static standard C++ library that link in only the
-minimal ABI symbols that ZXCPP used to provide.
diff --git a/docs/ddk/advanced.md b/docs/ddk/advanced.md
deleted file mode 100644
index c2f24e3..0000000
--- a/docs/ddk/advanced.md
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-<!--
-    (C) Copyright 2018 The Fuchsia Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style license that can be
-    found in the LICENSE file.
--->
-
-# Advanced Topics and Tips
-
-This document is part of the [Driver Development Kit tutorial](ddk-tutorial.md) documentation.
-
-## Taking a long time to initialize
-
-What if your device takes a long time to initialize?
-When we discussed the **null_bind()** function above, we indicated that a successful
-return told the device manager that the driver is now associated with the device.
-We can't spend a lot of time in the bind function; we're basically expected to initialize
-our device, publish it, and be done.
-
-But your device might need to perform a lengthy initialization operation, such as:
-
-*   enumerate hardware points
-*   load firmware
-*   negotiate a protocol
-
-and so on, which might take a long time to do.
-
-You can publish your device as "invisible" using the `DEVICE_ADD_INVISIBLE` flag.
-This meets the requirements for the binding function, but nobody is able to use
-your device (because nobody knows about it yet, because it's not visible).
-Now your device can perform the long operations via a background thread.
-
-When your device is ready to service client requests, call
-**device_make_visible()**
-which will cause it to appear in the pathname space.
-
-### Power savings
-
-Two callouts, **suspend()** and **resume()**, are available for your device in
-order to support power or other resource saving features.
-
-Both take a device context pointer and a flags argument, but the flags argument is
-used only in the suspend case.
-
-Flag                                | Meaning
-------------------------------------|------------------------------------------------------------
-`DEVICE_SUSPEND_FLAG_REBOOT`        | The driver should shut itself down in preparation for a reboot or shutdown of the machine
-`DEVICE_SUSPEND_FLAG_REBOOT_BOOTLOADER` | ?
-`DEVICE_SUSPEND_FLAG_REBOOT_RECOVERY`   | ?
-`DEVICE_SUSPEND_FLAG_POWEROFF`      | The driver should shut itself down in preparation for power off
-`DEVICE_SUSPEND_FLAG_MEXEC`         | @@@ almost nobody uses this except for a graphics controller, what does it do? @@@
-`DEVICE_SUSPEND_FLAG_SUSPEND_RAM`   | The driver should arrange so that it can be restarted from RAM
-
-> @@@ Yeah, I'm just guessing on the flags; they're used so little...
-
-For documentation purposes, what should I write?
-That they are just hints, or that you *must* do something because of a given flag, or ... ?
-
-## Reference: Support functions
-
-This section lists support functions that are provided for your driver to use.
-
-### Accessor functions
-
-The context block that's passed as the first argument to your driver's protocol functions
-is an opaque data structure.
-This means that in order to access the data elements, you need to call an accessor function:
-
-Function                | Purpose
-------------------------|-------------------------------------------
-**device_get_name()**        | Retrieves the name of the device
-**device_get_parent()**      | Retrieves the parent device of the device
-
-### Administrative functions
-
-The following functions are used to administer the device:
-
-Function                    | Purpose
-----------------------------|-------------------------------------------
-**device_add()**                 | Adds a device to a parent
-**device_make_visible()**        | Makes a device visible
-**device_remove()**              | Removes a device from a parent
-
-### Signalling
-
-The following functions are used to set the state of a device:
-
-Function                | Purpose
-------------------------|-------------------------------------------
-**device_state_set()**       | sets the given signal(s) on the device
-**device_state_clr()**       | clears the given signal(s) on the device
-
-We saw these in the `/dev/misc/demo-fifo` handler above.
-
-@@@ Notes only @@@
-
-This section is great for things like open_at(), talking about buffer management,
-threading, best practices, advanced options for device_add(), and so on.
-I think it can be somewhere between the man page ("printf is used to print a string
-and takes the following parameters") and an application note &mdash; I want to see
-examples of how to use the functions, what the arguments mean, what the impact of
-various design decisions is, that kind of thing.
-
diff --git a/docs/ddk/ddk-tutorial.md b/docs/ddk/ddk-tutorial.md
deleted file mode 100644
index 7267d8a..0000000
--- a/docs/ddk/ddk-tutorial.md
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-<!--
-    (C) Copyright 2018 The Fuchsia Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style license that can be
-    found in the LICENSE file.
--->
-
-# The Driver Development Kit Tutorial
-
-This document is part of the [Zircon Driver Development Kit](overview.md) documentation.
-
-This Driver Development Kit (*DDK*) tutorial documentation section consists of:
-
-*   [Getting Started](getting_started.md) &mdash; a beginner's guide to writing device drivers
-*   [Simple Drivers](simple.md) &mdash; an overview of what a driver does, with code examples
-*   [Hardware Interfacing](hardware.md) &mdash; how to deal with your device's hardware
-*   [RAMDisk Device](ramdisk.md) &mdash; walkthrough of RAMdisk block driver
-*   [Ethernet Devices](ethernet.md) &mdash; walkthrough of Intel Ethernet driver
-*   [Advanced Topics and Tips](advanced.md) &mdash; hints for experienced driver writers
-    and comments on unusual situations
-*   [Tracing](tracing.md) &mdash; monitoring driver performance with tracing
-*   [Reference](reference.md) &mdash; helper functions, data structures, manifest constants
-
-The sections are listed above in default reading order, but it's perfectly fine
-to jump around and read them in order of interest or applicability.
-
-Generally, each section is written with increasing complexity; the first parts of each
-section can safely be skipped / skimmed by experts, whereas a beginner should find
-sufficient explanation to allow them to understand the advanced sections.
-
-Indeed, the above chapter structure follows the same progression: from beginner
-to advanced, allowing the expert to skip / skim early sections while providing a
-beginner with sufficient information.
-
diff --git a/docs/ddk/device-model.md b/docs/ddk/device-model.md
deleted file mode 100644
index 6236f69..0000000
--- a/docs/ddk/device-model.md
+++ /dev/null
@@ -1,297 +0,0 @@
-# Zircon Device Model
-
-## Introduction
-
-In Zircon, device drivers are implemented as ELF shared libraries (DSOs) which are
-loaded into Device Host (devhost) processes.  The Device Manager (devmgr) process,
-contains the Device Coordinator which keeps track of drivers and devices, manages
-the discovery of drivers, the creation and direction of Device Host processes, and
-maintains the Device Filesystem (devfs), which is the mechanism through which userspace
-services and applications (constrained by their namespaces) gain access to devices.
-
-The Device Coordinator views devices as part of a single unified tree.
-The branches (and sub-branches) of that tree consist of some number of
-devices within a Device Host process.  The decision as to how to sub-divide
-the overall tree among Device Hosts is based on system policy for isolating
-drivers for security or stability reasons and colocating drivers for performance
-reasons.
-
-NOTE: The current policy is simple (each device representing a physical bus-master
-capable hardware device and its children are placed into a separate devhost).  It
-will evolve to provide finer-grained partitioning.
-
-
-## Devices, Drivers, and Device Hosts
-
-Here's a (slightly trimmed for clarity) dump of the tree of devices in
-Zircon running on Qemu x86-64:
-
-```
-$ dm dump
-[root]
-   <root> pid=1509
-      [null] pid=1509 /boot/driver/builtin.so
-      [zero] pid=1509 /boot/driver/builtin.so
-   [misc]
-      <misc> pid=1645
-         [console] pid=1645 /boot/driver/console.so
-         [dmctl] pid=1645 /boot/driver/dmctl.so
-         [ptmx] pid=1645 /boot/driver/pty.so
-         [i8042-keyboard] pid=1645 /boot/driver/pc-ps2.so
-            [hid-device-001] pid=1645 /boot/driver/hid.so
-         [i8042-mouse] pid=1645 /boot/driver/pc-ps2.so
-            [hid-device-002] pid=1645 /boot/driver/hid.so
-   [sys]
-      <sys> pid=1416 /boot/driver/bus-acpi.so
-         [acpi] pid=1416 /boot/driver/bus-acpi.so
-         [pci] pid=1416 /boot/driver/bus-acpi.so
-            [00:00:00] pid=1416 /boot/driver/bus-pci.so
-            [00:01:00] pid=1416 /boot/driver/bus-pci.so
-               <00:01:00> pid=2015 /boot/driver/bus-pci.proxy.so
-                  [bochs_vbe] pid=2015 /boot/driver/bochs-vbe.so
-                     [framebuffer] pid=2015 /boot/driver/framebuffer.so
-            [00:02:00] pid=1416 /boot/driver/bus-pci.so
-               <00:02:00> pid=2052 /boot/driver/bus-pci.proxy.so
-                  [intel-ethernet] pid=2052 /boot/driver/intel-ethernet.so
-                     [ethernet] pid=2052 /boot/driver/ethernet.so
-            [00:1f:00] pid=1416 /boot/driver/bus-pci.so
-            [00:1f:02] pid=1416 /boot/driver/bus-pci.so
-               <00:1f:02> pid=2156 /boot/driver/bus-pci.proxy.so
-                  [ahci] pid=2156 /boot/driver/ahci.so
-            [00:1f:03] pid=1416 /boot/driver/bus-pci.so
-```
-
-The names in square brackets are devices.  The names in angle brackets are
-proxy devices, which are instantiated in the "lower" devhost, when process
-isolation is being provided.  The pid= field indicates the process object
-id of the devhost process that device is contained within.  The path indicates
-which driver implements that device.
-
-Above, for example, the pid 1416 devhost contains the pci bus driver, which has
-created devices for each PCI device in the system.  PCI device 00:02:00 happens
-to be an intel ethernet interface, which we have a driver for (intel-ethernet.so).
-A new devhost (pid 2052) is created, set up with a proxy device for PCI 00:02:00,
-and the intel ethernet driver is loaded and bound to it.
-
-Proxy devices are invisible within the Device filesystem, so this ethernet device
-appears as `/dev/sys/pci/00:02:00/intel-ethernet`.
-
-
-## Protocols, Interfaces, and Classes
-
-Devices may implement Protocols, which are C ABIs used by child devices
-to interact with parent devices in a device-specific manner. The
-[PCI Protocol](../../system/ulib/ddk/include/ddk/protocol/pci.h),
-[USB Protocol](../../system/ulib/ddk/include/ddk/protocol/usb.h),
-[Block Core Protocol](../../system/ulib/ddk/include/ddk/protocol/block.h), and
-[Ethermac Protocol](../../system/ulib/ddk/include/ddk/protocol/ethernet.h), are
-examples of these.  Protocols are usually in-process interactions between
-devices in the same devhost, but in cases of driver isolation, they may take
-place via RPC to a "higher" devhost (via proxy).
-
-Devices may implement Interfaces, which are RPC protocols that clients (services,
-applications, etc) use.  The base device interface supports POSIX style
-open/close/read/write IO.  Currently, Interfaces are supported via the ioctl
-operation in the base device interface.  In the future, Fuchsia's interface definition
-language and bindings (FIDL) will be supported.
-
-In many cases a Protocol is used to allow drivers to be simpler by taking advantage
-of a common implementation of an Interface.  For example, the "block" driver implements
-the common block interface, and binds to devices implementing the Block Core Protocol,
-and the "ethernet" driver does the same thing for the Ethernet Interface and Ethermac
-Protocol.  Some protocols, such as the two cited here, make use of shared memory, and
-non-rpc signaling for more efficient, lower latency, and higher throughput than could
-be achieved otherwise.
-
-Classes represent a promise that a device implements an Interface or Protocol.
-Devices exist in the Device Filesystem under a topological path, like
-`/sys/pci/00:02:00/intel-ethernet`.  If they are a specific class, they also appear
-as an alias under `/dev/class/CLASSNAME/...`.  The `intel-ethernet` driver implements
-the Ethermac interface, so it also shows up at `/dev/class/ethermac/000`.  The names
-within class directories are unique but not meaningful, and are assigned on demand.
-
-NOTE: Currently names in class directories are 3 digit decimal numbers, but they
-are likely to change form in the future.  Clients should not assume there is any
-specific meaning to a class alias name.
-
-
-## Device Driver Lifecycle
-
-Device drivers are loaded into devhost processes when it is determined they are
-needed.  What determines if they are loaded or not is the Binding Program, which
-is a description of what device a driver can bind to.  The Binding Program is
-defined using macros in [`ddk/binding.h`](../../system/ulib/ddk/include/ddk/binding.h)
-
-An example Binding Program from the Intel Ethernet driver:
-```
-ZIRCON_DRIVER_BEGIN(intel_ethernet, intel_ethernet_driver_ops, "zircon", "0.1", 9)
-    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PCI),
-    BI_ABORT_IF(NE, BIND_PCI_VID, 0x8086),
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x100E), // Qemu
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x15A3), // Broadwell
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1570), // Skylake
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1533), // I210 standalone
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x15b7), // Skull Canyon NUC
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x15b8), // I219
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x15d8), // Kaby Lake NUC
-ZIRCON_DRIVER_END(intel_ethernet)
-```
-
-The ZIRCON_DRIVER_BEGIN and _END macros include the necessary compiler directives
-to put the binding program into an ELF NOTE section, allowing it to be inspected
-by the Device Coordinator without needing to fully load the driver into its process.
-The second parameter to the _BEGIN macro is a `zx_driver_ops_t` structure pointer (defined
-by `[ddk/driver.h](../../system/ulib/ddk/include/ddk/driver.h)` which defines the
-init, bind, create, and release methods.
-
-`init()` is invoked when a driver is loaded into a Device Host process and allows for
-any global initialization.  Typically none is required.  If the `init()` method is
-implemented and fails, the driver load will fail.
-
-`bind()` is invoked to offer the driver a device to bind to.  The device is one that
-has matched the bind program the driver has published.  If the `bind()` method succeeds,
-the driver **must** create a new device and add it as a child of the device passed in
-to the `bind()` method.  See Device Lifecycle for more information.
-
-`create()` is invoked for platform/system bus drivers or proxy drivers.  For the
-vast majority of drivers, this method is not required.
-
-`release()` is invoked before the driver is unloaded, after all devices it may have
-created in `bind()` and elsewhere have been destroyed.  Currently this method is
-**never** invoked.  Drivers, once loaded, remain loaded for the life of a Device Host
-process.
-
-
-## Device Lifecycle
-
-Within a Device Host process, devices exist as a tree of `zx_device_t` structures
-which are opaque to the driver.  These are created with `device_add()` which the
-driver provides a `zx_protocol_device_t` structure to.  The methods defined by the
-function pointers in this structure are the "[device ops](device-ops.md)".  The
-various structures and functions are defined in [`device.h`](../../system/ulib/ddk/include/ddk/device.h)
-
-The `device_add()` function creates a new device, adding it as a child to the
-provided parent device.  That parent device **must** be either the device passed
-in to the `bind()` method of a device driver, or another device which has been
-created by the same device driver.
-
-A side-effect of `device_add()` is that the newly created device will be added
-to the global Device Filesystem maintained by the Device Coordinator.  If the
-device is created with the **DEVICE_ADD_INVISIBLE** flag, it will not be accessible
-via opening its node in devfs until `device_make_visible()` is invoked.  This
-is useful for drivers that have to do extended initialization or probing and
-do not want to visibly publish their device(s) until that succeeds (and quietly
-remove them if that fails).
-
-Devices are reference counted.  When a driver creates one with `device_add()`,
-it then holds a reference on that device until it eventually calls `device_remove()`.
-If a device is opened by a remote process via the Device Filesystem, a reference
-is acquired there as well.  When a device's parent is removed, its `unbind()`
-method is invoked.  This signals to the driver that it should start shutting
-the device down and remove any child devices it has created by calling `device_remove()`
-on them.
-
-Since a child device may have work in progress when its `unbind()` method is
-called, it's possible that the parent device which just called `device_remove()`
-on the child could continue to receive device method calls or protocol method
-calls on behalf of that child.  It is advisable that before removing its children,
-the parent device should arrange for these methods to return errors, so that
-calls from a child before the child removal is completed do not start more
-work or cause unexpected interactions.
-
-From the moment that `device_add()` is called without the **DEVICE_ADD_INVISIBLE**
-flag, or `device_make_visible()` is called on an invisible device, other device
-ops may be called by the Device Host.
-
-The `release()` method is only called after the creating driver has called
-`device_remove()` on the device, all open instances of that device have been
-closed, and all children of that device have been removed and released.  This
-is the last opportunity for the driver to destroy or free any resources associated
-with the device.  It is not valid to refer to the `zx_device_t` for that device
-after `release()` returns.  Calling any device methods or protocol methods for
-protocols obtained from the parent device past this point is illegal and will
-likely result in a crash.
-
-### An Example of the Tear-Down Sequence
-
-To explain how the `unbind()` and `release()` work during the tear-down process,
-below is an example of how a USB WLAN driver would usually handle it.  In short,
-the `unbind()` call sequence is top-down while the `release()` sequence is bottom-up.
-
-Note that this is just an example. This might not match what exactly the real WLAN driver
-is doing.
-
-Assume a WLAN device is plugged in as a USB device, and a PHY interface has been
-created under the USB device. In addition to the PHY interface, 2 MAC interfaces
-have been created under the PHY interface.
-
-```
-            +------------+
-            | USB Device |
-            +------------+
-                  |
-            +------------+
-            |  WLAN PHY  | .unbind()
-            +------------+ .release()
-              |        |
-    +------------+  +------------+
-    | WLAN MAC 0 |  | WLAN MAC 1 | .unbind()
-    +------------+  +------------+ .release()
-```
-
-Now, we unplug this USB WLAN device.
-
-* The USB XHCI detects the removal and calls `device_remove(usb_device)`.
-
-* Since the parent device is being removed, the WLAN PHY's `unbind()` is called.
-  In this `unbind()`, it would remove the interface it created via `device_add()`:
-
-```
-    wlan_phy_unbind(void* ctx) {
-        // Stop interrupt or anything to prevent incoming requests.
-        ...
-
-        device_remove(wlan_phy);
-    }
-```
-
-* When wlan_phy is removed, unbind() will be called on all of its children (wlan_mac_0, wlan_mac_1).
-
-```
-    wlan_mac_unbind(void* ctx) {
-        // Stop accepting new requests, and notify clients that this device is offline (often just
-        // by returning an ZX_ERR_IO_NOT_PRESENT to any requests that happen after unbind).
-        ...
-
-        device_remove(iface_mac_X);
-    }
-```
-
-* Once all the clients of a device have been removed, and that device has no children,
-  its refcount will reach zero and its release() method will be called.
-
-* WLAN MAC 0 and 1's `release()` are called.
-
-```
-    wlan_mac_release(void* ctx) {
-        // Release sources allocated at creation.
-        ...
-
-        // Delete the object here.
-        ...
-    }
-```
-
-* The wlan_phy has no open connections, but still has child devices (wlan_mac_0 and wlan_mac_1).
-  Once they have both been `release()`'d, its refcount finally reaches zero and its release()
-  method is invoked.
-
-```
-    wlan_phy_release(void* ctx) {
-        // Release sources allocated at creation.
-        ...
-
-        // Delete the object here.
-        ...
-    }
-```
diff --git a/docs/ddk/device-ops.md b/docs/ddk/device-ops.md
deleted file mode 100644
index 31d253a..0000000
--- a/docs/ddk/device-ops.md
+++ /dev/null
@@ -1,210 +0,0 @@
-
-# The Device Protocol
-
-Device drivers implement a set of hooks (methods) to support the
-operations that may be done on the devices that they publish.
-
-These are described below, including the action that is taken
-by the default implementation that is used for each hook if the
-driver does not provide its own implementation.
-
-## version
-This field must be set to `DEVICE_OPS_VERSION`
-```
-uint64_t version;
-```
-
-## open
-The open hook is called when a device is opened via the device filesystem,
-or when an existing open connection to a device is cloned (for example,
-when a device fd is shared with another process).  The default open hook,
-if a driver does not implement one, simply returns **ZX_OK**.
-
-Drivers may want to implement open to disallow simultaneous access (by
-failing if the device is already open), or to return a new **device instance**
-instead.
-
-The optional *dev_out* parameter allows a device to create and return a
-**device instance** child device, which can be used to manage per-instance
-state instead of all client connections interacting with the device itself.
-A child created for return as an instance **must** be created with the
-**DEVICE_ADD_INSTANCE** flag set in the arguments to **device_add()**.
-
-```
-zx_status_t (*open)(void* ctx, zx_device_t** dev_out, uint32_t flags);
-```
-
-## open_at
-DEPRECATED: See ZX-3277.
-The open_at hook is called in the event that the open path to the device
-contains segments after the device name itself.  For example, if a device
-exists as `/dev/misc/foo` and an attempt is made to `open("/dev/misc/foo/bar",...)`,
-the open_at hook would be invoked with a *path* of `"bar"`.
-
-The default open_at implementation returns **ZX_ERR_NOT_SUPPORTED**
-
-```
-zx_status_t (*open_at)(void* ctx, zx_device_t** dev_out, const char* path, uint32_t flags);
-```
-
-## close
-The close hook is called when a connection to a device is closed.  These
-calls will balance the calls to open or open_at.
-
-**Note:** If open or open_at return a **device instance**, the balancing close
-hook that is called is the close hook on the **instance**, not the parent.
-
-The default close implementation returns **ZX_OK**.
-```
-zx_status_t (*close)(void* ctx, uint32_t flags);
-```
-
-## unbind
-The unbind hook is called when the parent of this device is being removed (due
-to hot unplug, fatal error, etc).  At the point unbind is called, it is not
-possible for further open or open_at calls to occur, but io operations, etc
-may continue until those client connections are closed.
-
-The driver should avoid further method calls to its parent device or any
-protocols obtained from that device, and expect that any further such calls
-will return with an error.
-
-The driver should adjust its state to encourage its client connections to close
-(cause IO to error out, etc), and call **device_remove()** on itself when ready.
-
-The driver must continue to handle all device hooks until the **release** hook
-is invoked.
-
-```
-void (*unbind)(void* ctx);
-```
-
-## release
-The release hook is called after this device has been removed by **device_remove()**
-and all open client connections have been closed, and all child devices have been
-removed and released.
-
-At the point release is invoked, the driver will not receive any further calls
-and absolutely must not use the underlying **zx_device_t** or any protocols obtained
-from that device once this method returns.
-
-The driver must free all memory and release all resources related to this device
-before returning.
-```
-void (*release)(void* ctx);
-```
-
-## read
-The read hook is an attempt to do a non-blocking read operation.
-
-On success *actual* must be set to the number of bytes read (which may be less
-than the number requested in *count*), and return **ZX_OK**.
-
-A successful read of 0 bytes is generally treated as an End Of File notification
-by clients.
-
-If no data is available now, **ZX_ERR_SHOULD_WAIT** must be returned and when
-data becomes available `device_state_set(DEVICE_STATE_READABLE)` may be used to
-signal waiting clients.
-
-This hook **must not block**.
-
-The default read implementation returns **ZX_ERR_NOT_SUPPORTED**.
-
-```
-zx_status_t (*read)(void* ctx, void* buf, size_t count,
-                    zx_off_t off, size_t* actual);
-```
-
-## write
-The write hook is an attempt to do a non-blocking write operation.
-
-On success *actual* must be set to the number of bytes written (which may be
-less than the number requested in *count*), and **ZX_OK** should be returned.
-
-If it is not possible to write data at present **ZX_ERR_SHOULD_WAIT** must
-be returned and when it is again possible to write,
-`device_state_set(DEVICE_STATE_WRITABLE)` may be used to signal waiting clients.
-
-This hook **must not block**.
-
-The default write implementation returns **ZX_ERR_NOT_SUPPORTED**.
-
-```
-zx_status_t (*write)(void* ctx, const void* buf, size_t count,
-                     zx_off_t off, size_t* actual);
-```
-
-## get_size
-If the device is seekable, the get_size hook should return the size of the device.
-
-This is the offset at which no more reads or writes are possible.
-
-The default implementation returns 0.
-```
-zx_off_t (*get_size)(void* ctx);
-```
-
-## ioctl
-The ioctl hook allows support for device-specific operations.
-
-These, like read and write, must not block.
-
-On success, **ZX_OK** must be returned and *out_actual* must be set
-to the number of output bytes provided (0 if none).
-
-The default ioctl implementation returns **ZX_ERR_NOT_SUPPORTED**.
-```
-zx_status_t (*ioctl)(void* ctx, uint32_t op,
-                     const void* in_buf, size_t in_len,
-                     void* out_buf, size_t out_len, size_t* out_actual);
-```
-
-## rxrpc
-Only called for bus devices.
-When the "shadow" of a busdev sends an rpc message, the
-device that is shadowing is notified by the rxrpc op and
-should attempt to read and respond to a single message on
-the provided channel.
-
-Any error return from this method will result in the channel
-being closed and the remote "shadow" losing its connection.
-
-This method is called with ZX_HANDLE_INVALID for the channel
-when a new client connects -- at which point any state from
-the previous client should be torn down.
-```
-zx_status_t (*rxrpc)(void* ctx, zx_handle_t channel);
-```
-
-## message
-Process a FIDL rpc message.  This is used to handle class or
-device specific messaging.  fuchsia.io.{Node,File,Device} are
-handles by the devhost itself.
-
-The entire message becomes the responsibility of the driver,
-including the handles.
-
-The txn provided to respond to the message is only valid for
-the duration of the message() call.  It must not be cached
-and used later.
-
-If this method returns anything other than ZX_OK, the underlying
-connection is closed.
-```
-zx_status_t (*message)(void* ctx, fidl_msg_t* msg, fidl_txn_t* txn);
-```
-
-#### Device State Bits
-```
-#define DEV_STATE_READABLE DEVICE_SIGNAL_READABLE
-#define DEV_STATE_WRITABLE DEVICE_SIGNAL_WRITABLE
-#define DEV_STATE_ERROR DEVICE_SIGNAL_ERROR
-#define DEV_STATE_HANGUP DEVICE_SIGNAL_HANGUP
-#define DEV_STATE_OOB DEVICE_SIGNAL_OOB
-```
-
-#### device_state_set
-```
-void device_state_set(zx_device_t* dev, zx_signals_t stateflag);
-```
diff --git a/docs/ddk/dma-000-cropped.png b/docs/ddk/dma-000-cropped.png
deleted file mode 100644
index aeb0088..0000000
--- a/docs/ddk/dma-000-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/dma-001-cropped.png b/docs/ddk/dma-001-cropped.png
deleted file mode 100644
index 1765c9c..0000000
--- a/docs/ddk/dma-001-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/dma-002-cropped.png b/docs/ddk/dma-002-cropped.png
deleted file mode 100644
index 80ee298..0000000
--- a/docs/ddk/dma-002-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/dma.odg b/docs/ddk/dma.odg
deleted file mode 100644
index d5a05ad..0000000
--- a/docs/ddk/dma.odg
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/driver-development.md b/docs/ddk/driver-development.md
deleted file mode 100644
index 39bd6bc..0000000
--- a/docs/ddk/driver-development.md
+++ /dev/null
@@ -1,287 +0,0 @@
-# Zircon Driver Development
-
-Zircon drivers are shared libraries that are dynamically loaded in Device Host
-processes in user space. The process of loading a driver is controlled by the
-Device Coordinator. See [Device Model](device-model.md) for more information on
-Device Hosts, Device Coordinator and the driver and device lifecycles.
-
-## Directory structure
-
-Zircon drivers are found under [system/dev](../../system/dev).
-They are grouped based on the protocols they implement.
-The driver protocols are defined in
-[ddk/include/ddk/protodefs.h](../../system/ulib/ddk/include/ddk/protodefs.h).
-For example, a USB ethernet driver goes in [system/dev/ethernet](../../system/dev/ethernet)
-rather than [system/dev/usb](../../system/dev/usb) because it implements an ethernet protocol.
-However, drivers that implement the USB stack are in [system/dev/usb](../../system/dev/usb)
-because they implement USB protocols.
-
-In the driver's `rules.mk`, the `MODULE_TYPE` should
-be `driver`. This will install the driver shared lib in `/boot/driver/`.
-
-If your driver is built outside Zircon, install them in `/system/driver/`
-. The Device Coordinator looks in those directories for loadable
-drivers.
-
-## Declaring a driver
-
-At a minimum, a driver should contain the driver declaration and implement the
-`bind()` driver op.
-
-Drivers are loaded and bound to a device when the Device Coordinator
-successfully finds a matching driver for a device. A driver declares the
-devices it is compatible with via bindings.
-The following bind program
-declares the [AHCI driver](../../system/dev/block/ahci/ahci.c):
-
-```
-ZIRCON_DRIVER_BEGIN(ahci, ahci_driver_ops, "zircon", "0.1", 4)
-    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PCI),
-    BI_ABORT_IF(NE, BIND_PCI_CLASS, 0x01),
-    BI_ABORT_IF(NE, BIND_PCI_SUBCLASS, 0x06),
-    BI_MATCH_IF(EQ, BIND_PCI_INTERFACE, 0x01),
-ZIRCON_DRIVER_END(ahci)
-```
-
-The AHCI driver has 4 directives in the bind program. `"zircon"` is the vendor
-id and `"0.1"` is the driver version. It binds with `ZX_PROTOCOL_PCI` devices
-with PCI class 1, subclass 6, interface 1.
-
-The [PCI driver](../../system/dev/bus/pci/kpci.c) publishes the matching
-device with the following properties:
-
-```
-zx_device_prop_t device_props[] = {
-    {BIND_PROTOCOL, 0, ZX_PROTOCOL_PCI},
-    {BIND_PCI_VID, 0, info.vendor_id},
-    {BIND_PCI_DID, 0, info.device_id},
-    {BIND_PCI_CLASS, 0, info.base_class},
-    {BIND_PCI_SUBCLASS, 0, info.sub_class},
-    {BIND_PCI_INTERFACE, 0, info.program_interface},
-    {BIND_PCI_REVISION, 0, info.revision_id},
-    {BIND_PCI_BDF_ADDR, 0, BIND_PCI_BDF_PACK(info.bus_id, info.dev_id,
-                                             info.func_id)},
-};
-```
-
-Binding variables and macros are defined in
-[zircon/driver/binding.h](../../system/public/zircon/driver/binding.h).
-If you are introducing a new device class, you may need to introduce new
-binding variables in that file.
-Binding variables are 32-bit values. If your
-variable value requires greater than a 32-bit value,
-split them into multiple 32-bit variables. An
-example is ACPI HID values, which are 8 characters (64-bits) long.
-It is split into `BIND_ACPI_HID_0_3` and `BIND_ACPI_HID_4_7`.
-
-Binding directives are evaluated sequentially. The branching directives
-`BI_GOTO()` and `BI_GOTO_IF()` allow you to jump forward to the matching
-label, defined by `BI_LABEL()`.
-
-`BI_ABORT_IF_AUTOBIND` may be used (usually as the first instruction)
-to prevent the default automatic binding behaviour.
-In that case, a driver can be bound to a device using
-`ioctl_device_bind()` call
-
-
-## Driver binding
-
-A driver’s `bind()` function is called when it is matched to a device.
-Generally a driver will initialize any data structures needed for the device
-and initialize hardware in this function. It should not perform any
-time-consuming tasks or block in this function, because it is invoked from the
-devhost's RPC thread and it will not be able to service other requests in the
-meantime. Instead, it should spawn a new thread to perform lengthy tasks.
-
-The driver should make no assumptions about the state of the hardware in
-`bind()`, resetting the hardware or otherwise ensuring it is in a known state.
-Because the system recovers from a
-driver crash by re-spawning the devhost, the hardware may be in an unknown
-state when `bind()` is invoked.
-
-A driver is required to publish a `zx_device_t` in `bind()` by calling
-`device_add()`. This is necessary for the Device Coordinator to keep
-track of the
-device lifecycle. If the driver is not able to publish a functional device in
-`bind()`, for example if it is initializing the full device in a thread, it
-should publish an invisible device, and make this device visible when
-initialization is completed. See `DEVICE_ADD_INVISIBLE` and
-`device_make_visible()` in
-[zircon/ddk/driver.h](../../system/ulib/ddk/include/ddk/driver.h).
-
-There are generally four outcomes from `bind()`:
-
-1. The driver determines the device is supported and does not need to do any
-heavy lifting, so publishes a new device via `device_add()` and returns
-`ZX_OK`.
-
-2. The driver determines that even though the bind program matched, the device
-cannot be supported (maybe due to checking hw version bits or whatnot) and
-returns an error.
-
-3. The driver needs to do further initialization before the device is ready or
-it’s sure it can support it, so it publishes an invisible device and kicks off
-a thread to keep working, while returning `ZX_OK`. That thread will eventually
-make the device visible or, if it cannot successfully initialize it, remove it.
-
-4. The driver represents a bus or controller with 0..n children which may
-dynamically appear or disappear. In this case it should publish a device
-immediately representing the bus or controller, and then dynamically publish
-children (that downstream drivers will bind to) representing hardware on that
-bus. Examples: AHCI/SATA, USB, etc.
-
-After a device is added and made visible by the system, it is made available
-to client processes and for binding by compatible drivers.
-
-## Device protocols
-
-A driver provides a set of device ops and optional protocol ops to a device.
-Device ops implement the device lifecycle methods and the external interface
-to the device that are called by other user space applications and services.
-Protocol ops implement the ddk-internal protocols of the device that are
-called by other drivers.
-
-You can pass one set of protocol ops for the device in `device_add_args_t`. If
-a device supports multiple protocols, implement the `get_protocol()` device
-op. A device can only have one protocol id. The protocol id corresponds to the
-class the device is published under in devfs.
-
-Device protocol headers are found in
-[ddk/protocol/](../../system/ulib/ddk/include/ddk/protocol). Ops and any data
-structures passed between drivers should be defined in this header.
-
-## Driver operation
-
-A driver generally operates by servicing client requests from children drivers
-or other processes. It fulfills those requests either by communicating
-directly with hardware (for example, via MMIO) or by communicating with its
-parent device (for example, queuing a USB transaction).
-
-External client requests from processes outside the devhost are fulfilled by
-the device ops `read()`, `write()`, and `ioctl()`. Requests from children
-drivers, generally in the same process, are fulfilled by device
-protocols corresponding to the device class. Driver-to-driver requests should
-use device protocols instead of device ops.
-
-A device can get a protocol supported by its parent by calling
-`device_get_protocol()` on its parent device.
-
-## Device interrupts
-
-Device interrupts are implemented by interrupt objects, which are a type of
-kernel objects. A driver requests a handle to the device interrupt from its
-parent device in a device protocol method. The handle returned will be bound
-to the appropriate interrupt for the device, as defined by a parent driver.
-For example, the PCI protocol implements `map_interrupt()` for PCI children. A
-driver should spawn a thread to wait on the interrupt handle.
-
-The kernel will automatically handle masking and unmasking the
-interrupt as appropriate, depending on whether the interrupt is edge-triggered
-or level-triggered. For level-triggered hardware interrupts,
-[zx_interrupt_wait()](../syscalls/interrupt_wait.md) will mask the interrupt
-before returning and unmask the interrupt when it is called again the next
-time. For edge-triggered interrupts, the interrupt remains unmasked.
-
-The interrupt thread should not perform any long-running tasks. For drivers
-that perform lengthy tasks, use a worker thread.
-
-You can signal an interrupt handle with
-[zx_interrupt_signal()](../syscalls/interrupt_signal.md) on slot
-**ZX_INTERRUPT_SLOT_USER** to return from `zx_interrupt_wait()`. This is
-necessary to shut down the interrupt thread during driver clean up.
-
-## Ioctl
-
-Ioctls for each device class are defined in
-[zircon/device/](../../system/public/zircon/device). Ioctls may accept or
-return handles. The `IOCTL_KIND_*` defines in
-[zircon/device/ioctl.h](../../system/public/zircon/device/ioctl.h), used in
-the ioctl declaration, defines whether the ioctl accepts or returns handles
-and how many. The driver owns the handles passed in and should close the
-handles when they’re no longer needed, unless it returns
-`ZX_ERR_NOT_SUPPORTED` in which case the devhost RPC layer will close the
-handles.
-
-## Protocol ops vs. ioctls
-
-Protocol ops define the DDK-internal API for a device. Ioctls define the
-external API. Define a protocol op if the function is primarily meant to be
-called by other drivers, and generally a driver should call a protocol op on
-its parent instead of an ioctl.
-
-## Isolate devices
-
-Devices that are added with `DEVICE_ADD_MUST_ISOLATE` spawn a new proxy devhost.
-The device exists in both the parent devhost and as the root of the new devhost.
-Devmgr attempts to load <driver>.proxy.so into this proxy devhost. For example,
-PCI is supplied by libpci.so so devmgr would look to load libpci.proxy.so. The
-driver is provided a channel in `create()` when it creates the proxy device
-(the “bottom half” that runs in the new devhost). The proxy device should cache
-this channel for when it needs to communicate with the top half (e.g. if
-it needs to call API on the parent device).
-
-`rxrpc()` is invoked on the top half when this channel is written to by the
-bottom half. There is no common wire protocol for this channel. For an
-example, refer to the [PCI driver](../../system/dev/bus/pci).
-
-NOTE: This is a mechanism used by various bus devices and not something
-general drivers should have to worry about. (please ping swetland if you think
-you need to use this)
-
-## Logging
-
-[ddk/debug.h](../../system/ulib/ddk/include/ddk/debug.h) defines the
-`zxlogf(<log_level>,...)` macro. The log messages are printed to the system
-debuglog over the network and on the serial port if available for the device.
-By default, `ERROR` and `INFO` are always printed. You can control the log
-level for a driver by passing the boot cmdline
-`driver.<driver_name>.log=+<level>,-<level>`. For example,
-`driver.sdhci.log=-info,+trace,+spew` enables the `TRACE` and `SPEW` logs and
-disable the `INFO` logs for the sdhci driver.
-
-The log levels prefixed by "L" (`LERROR`, `LINFO`, etc.) do not get sent over
-the network and is useful for network logging.
-
-## Driver testing
-
-`ZX_PROTOCOL_TEST` provides a mechanism to test drivers by running the driver
-under test in an emulated environment. Write a driver that binds to a
-`ZX_PROTOCOL_TEST` device. This driver should publish a device that the driver
-under test can bind to, and it should implement the protocol functions the
-driver under test invokes in normal operation. This helper driver should be
-declared with `BI_ABORT_IF_AUTOBIND` in the bindings.
-
-The test harness calls `fuchsia.device.test.RootDevice.CreateDevice()` on
-`/dev/test/test`, which will create a `ZX_PROTOCOL_TEST` device and return
-its path. Then it calls `ioctl_device_bind()` with the helper driver on the
-newly created device.  This approach generally works better for mid-layer
-protocol drivers. It's possible to emulate real hardware with the same
-approach but it may not be as useful.
-
-The functions defined in
-[ddk/protocol/test.h](../../system/ulib/ddk/include/ddk/protocol/test.h) are
-for testing libraries that run as part of a driver. For an example, refer to
-[system/ulib/ddk/test](../../system/ulib/ddk/test). The test harness for these
-tests is
-[system/utest/driver-tests/main.c](../../system/utest/driver-tests/main.c)
-
-## Driver rights
-
-Although drivers run in user space processes, they have a more restricted set
-of rights than normal processes. Drivers are not allowed to access the
-filesystem, including devfs. That means a driver cannot interact with
-arbitrary devices. If your driver needs to do this, consider writing a service
-instead. For example, the virtual console is implemented by the
-[virtcon](../../system/core/virtcon) service.
-
-Privileged operations such as `zx_vmo_create_contiguous()` and
-[zx_interrupt_create](../syscalls/interrupt_create.md) require a root resource
-handle. This handle is not available to drivers other than the system driver
-([ACPI](../../system/dev/bus/acpi) on x86 systems and
-[platform](../../system/dev/bus/platform) on ARM systems). A device should
-request its parent to perform such operations for it. Contact the author
-of the parent driver if its protocol does not address this use case.
-
-Similarly, a driver is not allowed to request arbitrary MMIO ranges,
-interrupts or GPIOs. Bus drivers such as PCI and platform only return the
-resources associated to the child device.
diff --git a/docs/ddk/ethernet-000-cropped.png b/docs/ddk/ethernet-000-cropped.png
deleted file mode 100644
index 7db9178..0000000
--- a/docs/ddk/ethernet-000-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/ethernet.md b/docs/ddk/ethernet.md
deleted file mode 100644
index d984b91..0000000
--- a/docs/ddk/ethernet.md
+++ /dev/null
@@ -1,774 +0,0 @@
-
-
-<!--
-    (C) Copyright 2018 The Fuchsia Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style license that can be
-    found in the LICENSE file.
--->
-
-# Ethernet Devices
-
-This document is part of the [Driver Development Kit tutorial](ddk-tutorial.md) documentation.
-
-## Overview
-
-This chapter looks into the details of ethernet drivers, using the Intel driver code
-for specific examples.
-
-In order to handle ethernet devices, two distinct parts are involved.
-A "top half" driver handles the generic ethernet protocol, and is located in
-`//zircon/system/dev/ethernet/ethernet/ethernet.c` (yes, three "ethernets" in a row),
-and one or more "bottom half" drivers handle the actual devices, located one
-directory higher in `//zircon/system/dev/ethernet/`**_devicename_**`/`.
-
-Multiple Zircon IPC protocols are used for communication between modules.
-
-> We'll just use the term "protocol" to refer to these.
-> Granted, we *are* discussing an Ethernet driver, but since we won't be
-> discussing any of the on-wire communications protocols supported by the driver,
-> this usage shouldn't result in any confusion.
->
-> @@@ I hope.
-
-
-The top half provides a protocol interface that conforms to `ZX_PROTOCOL_ETHERNET_IMPL`.
-The bottom half provides a protocol interface that conforms to whatever the
-hardware is connected to (for example, this might be `ZX_PROTOCOL_PCI`, for
-PCI-based ethernet cards, or `ZX_PROTOCOL_USB` for USB-based ethernet devices,
-and so on).
-We'll focus on the PCI version here.
-
-The bottom half drivers all expose a `ZX_PROTOCOL_ETHERNET_IMPL` binding, which is how
-the top half finds the bottom halves.
-
-Effectively, the bottom half ethernet driver is responsible for managing the hardware
-associated with the ethernet device, and presenting a consistent abstraction of that
-hardware for use by the top half.
-The top half manages the ethernet interface to the system.
-
-![Figure: Relationship amongst layers in ethernet driver stack](ethernet-000-cropped.png)
-
-> @@@ this diagram: helpful? too busy? font too small?
-
-# Intel PCI-based ethernet
-
-The Intel ethernet driver can be found in `//zircon/system/dev/ethernet/intel-ethernet`,
-and consists of the following files:
-
-<dl>
-<dt>`ethernet.c`
-<dd>The device driver part of the code; handles interface to protocols.
-<dt>`ie.c`
-<dd>The Intel specific part of the code; knows about the hardware registers on the card.
-<dt>`ie-hw.h`
-<dd>Contains the manifest constants for all of the control registers.
-<dt>`ie.h`
-<dd>Common definitions (such as the device context block)
-</dl>
-
-This driver not only handles the `ethmac` protocol, but also:
-
-*   finds its device on the PCI bus,
-*   attaches to legacy or Message Signaled Interrupts (**MSI**),
-*   maps I/O memory, and
-*   creates a background IRQ handling thread.
-
-## Binding
-
-The file `ethernet.c` contains the binding information, implemented by the standard
-binding macros introduced in the [Simple Drivers](simple.md) chapter:
-
-```c
-ZIRCON_DRIVER_BEGIN(intel_ethernet, intel_ethernet_driver_ops, "zircon", "0.1", 11)
-    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PCI),
-    BI_ABORT_IF(NE, BIND_PCI_VID, 0x8086),
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x100E), // Qemu
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x15A3), // Broadwell
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1570), // Skylake
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1533), // I210 standalone
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x1539), // I211-AT
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x156f), // I219-LM (Dawson Canyon NUC)
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x15b7), // Skull Canyon NUC
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x15b8), // I219-V
-    BI_MATCH_IF(EQ, BIND_PCI_DID, 0x15d8), // Kaby Lake NUC
-ZIRCON_DRIVER_END(intel_ethernet)
-```
-
-This ends up binding to ethernet cards that are identified by vendor ID `0x8086` (Intel),
-and have any of the listed device IDs (the `BIND_PCI_DID` lines indicate the allowed
-hexadecimal device IDs).
-It also requires the `ZX_PROTOCOL_PCI` protocol.
-
-Note the sense of the logic here &mdash; the vendor ID is tested with a
-"`BI_ABORT_IF(NE`" construct (meaning, "**ABORT IF** the values are **N**ot **E**qual"),
-whereas the device IDs are tested with "`BI_MATCH_IF(EQ`" constructs (meaning "**MATCH
-IF** the values are **EQ**ual").
-
-Intuitively, you might think that the vendor ID could be tested with a "`BI_MATCH_IF(EQ`"
-as well, (looking for vendor `0x8086`), but this would have two major problems.
-First, evaluation stops as soon as a condition is true, so that means that **any** device
-that had the Intel vendor ID would be considered a "match."
-Second, even if the device wasn't an Intel vendor ID, it would open the possibility
-of allowing matches to other vendors' devices that had the same device ID as listed.
-
-> The individual tests are evaluated in sequence.
-> The first one that's true terminates evaluation, and performs
-> the given action (i.e., `ABORT` or `MATCH`).
-
-## More about binding
-
-From the command line, `dm drivers` will display this information.
-Here's the relevant portion for the Intel ethernet driver:
-
-```sh
-$ dm drivers
-<snip>
-    Name    : intel_ethernet
-    Driver  : /boot/driver/intel-ethernet.so
-    Flags   : 0x00000000
-    Binding : 11 instructions (88 bytes)
-    [1/11]: if (Protocol != 0x70504349) return no-match;
-    [2/11]: if (PCI.VID != 0x00008086) return no-match;
-    [3/11]: if (PCI.DID == 0x0000100e) return match;
-    [4/11]: if (PCI.DID == 0x000015a3) return match;
-    [5/11]: if (PCI.DID == 0x00001570) return match;
-    [6/11]: if (PCI.DID == 0x00001533) return match;
-    [7/11]: if (PCI.DID == 0x00001539) return match;
-    [8/11]: if (PCI.DID == 0x0000156f) return match;
-    [9/11]: if (PCI.DID == 0x000015b7) return match;
-    [10/11]: if (PCI.DID == 0x000015b8) return match;
-    [11/11]: if (PCI.DID == 0x000015d8) return match;
-```
-
-The `Name` field indicates the name of the driver, given as the first argument to the
-`ZIRCON_DRIVER_BEGIN` and `ZIRCON_DRIVER_END` macros.
-The `Driver` field indicates the location of the shared object that contains the driver code.
-
-> The `Flags` field is not used @@@ correct?
-
-The last section, the binding instructions, corresponds with the `BI_ABORT_IF` and `BI_MATCH_IF`
-macro directives.
-Note that the first binding instruction compares the field `Protocol` against the hexadecimal
-number `0x70504349` &mdash; that "number" is simply the ASCII encoding of the string "`pPCI`",
-indicating the PCI protocol (you can see all of the encodings in
-`//zircon/system/ulib/ddk/include/ddk/protodefs.h`)
-
-From the `ZIRCON_DRIVER_BEGIN` macro, the `intel_ethernet_driver_ops`
-structure contains the driver operations, in this case just the binding function
-**eth_bind()**.
-
-Let's turn our attention to the binding function itself.
-
-## PCI interface
-
-The first part of the binding function deals with the PCI interface.
-
-The Intel ethernet driver is a PCI bus peripheral.
-As such, it needs to first query the PCI configuration registers in order to discover
-where the BIOS (or other startup program) has located the device in memory
-address space, and what interrupt it was assigned.
-Second, it needs to initialize the device for use (such as mapping the configuration
-registers and attaching to the device's interrupt).
-We broadly discussed this in the [Hardware Interfacing](hardware.md) chapter.
-
-As usual, the binding function allocates and initializes a context block:
-
-```c
-static zx_status_t eth_bind(void* ctx, zx_device_t* dev) {
-    ethernet_device_t* edev;
-    if ((edev = calloc(1, sizeof(ethernet_device_t))) == NULL) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    mtx_init(&edev->lock, mtx_plain);
-    mtx_init(&edev->eth.send_lock, mtx_plain);
-```
-
-This allocates a zeroed ethernet context block (`ethernet_device_t`).
-Then we initialize two mutexes (one for locking the device itself (`edev->lock`), and one
-for locking the ethernet send buffers (`edev->eth.send_lock`)).
-
-We'll examine the context block in more detail below.
-
-### PCI protocol operations
-
-The next step fetches the PCI protocol operations pointer (or fails if it can't):
-
-```c
-    if (device_get_protocol(dev, ZX_PROTOCOL_PCI, &edev->pci)) {
-        printf("no pci protocol\n");
-        goto fail;
-    }
-```
-
-This populates `edev->pci` (of type `pci_protocol_t`) with pointers to functions that
-provide PCI protocol services.
-Of the many functions available, we use the following subset (listed in order of
-use in the binding function):
-
-Function            | Description
---------------------|------------------------------------------------------------------------------
-`get_bti`           | Used to get the Bus Transaction Initiator (**[BTI](../objects/bus_transaction_initiator.md)**) for the device
-`query_irq_mode`    | Returns the number of the specific type of IRQ available (MSI or legacy)
-`set_irq_mode`      | Requests the specified IRQ mode to be used for the device
-`map_interrupt`     | Creates an IRQ handle associated with the device's interrupt
-`map_bar`           | Returns a pointer to the Base Address Register (**BAR**) of the PCI device
-`enable_bus_master` | Enables / disables bus mastering for the device
-
-> Note that the function names given in the table above are the member names within
-> the `pci_protocol_t` structure; throughout the code we'll use the **pci_...()** accessor
-> functions to call the protocol ops.
-
-### Fetch the BTI
-
-The first PCI function we call is
-**pci_get_bti()**:
-
-```c
-    zx_status_t status = pci_get_bti(&edev->pci, 0, &edev->btih);
-    if (status != ZX_OK) {
-        goto fail;
-    }
-```
-
-A [BTI](../objects/bus_transaction_initiator.md)
-is used to represent the bus mastering / DMA capability of a device.
-It can be used for granting memory access to a device.
-The [BTI](../objects/bus_transaction_initiator.md)
-handle is stored in `edev->btih` and is used later to initialize transfer buffers.
-The [Hardware Interfacing](hardware.md) chapter talks more about this, in the DMA section.
-
-### Discover and map interrupts
-
-The interrupt is discovered and mapped next:
-
-```c
-    // Query whether we have MSI or Legacy interrupts.
-    uint32_t irq_cnt = 0;
-    if ((pci_query_irq_mode(&edev->pci, ZX_PCIE_IRQ_MODE_MSI, &irq_cnt) == ZX_OK) &&
-        (pci_set_irq_mode(&edev->pci, ZX_PCIE_IRQ_MODE_MSI, 1) == ZX_OK)) {
-        printf("eth: using MSI mode\n");
-    } else if ((pci_query_irq_mode(&edev->pci, ZX_PCIE_IRQ_MODE_LEGACY, &irq_cnt) == ZX_OK) &&
-               (pci_set_irq_mode(&edev->pci, ZX_PCIE_IRQ_MODE_LEGACY, 1) == ZX_OK)) {
-        printf("eth: using legacy irq mode\n");
-    } else {
-        printf("eth: failed to configure irqs\n");
-        goto fail;
-    }
-
-    zx_status_t r = pci_map_interrupt(&edev->pci, 0, &edev->irqh);
-    if (r != ZX_OK) {
-        printf("eth: failed to map irq\n");
-        goto fail;
-    }
-```
-
-The **pci_query_irq_mode()**
-function determines if the device supports any `MSI` or `LEGACY`
-style interrupts, and returns the count (in `irq_cnt`).
-We're expecting one interrupt, so we ignore the count and examine just the return status.
-If the return status indicates one or more interrupts of that type exist, we set the device to
-use that mode.
-
-The **pci_map_interrupt()**
-function is then used to bind the hardware interrupt to a handle, stored in `edev->irqh`.
-
-We'll see this handle later, when we look at the interrupt service thread.
-
-### Map PCI BAR
-
-Next up, we map the PCI BAR:
-
-```c
-    // map iomem
-    uint64_t sz;
-    zx_handle_t h;
-    void* io;
-    r = pci_map_bar(&edev->pci, 0u, ZX_CACHE_POLICY_UNCACHED_DEVICE, &io, &sz, &h);
-    if (r != ZX_OK) {
-        printf("eth: cannot map io %d\n", h);
-        goto fail;
-    }
-    edev->eth.iobase = (uintptr_t)io;
-    edev->ioh = h;
-
-    if ((r = pci_enable_bus_master(&edev->pci, true)) < 0) {
-        printf("eth: cannot enable bus master %d\n", r);
-        goto fail;
-    }
-```
-
-The call to **pci_map_bar()** creates a handle to the first BAR
-(the `0u` as the second argument
-specifies the BAR ID number), which we store into the context block's `ioh` member.
-(We also capture the virtual address into `edev->eth.iobase`.)
-
-### Ethernet setup and configuration
-
-At this point, we have access to enough of the device that we can go and set it up:
-
-```c
-    if (eth_enable_phy(&edev->eth) != ZX_OK) {
-        goto fail;
-    }
-
-    if (eth_reset_hw(&edev->eth)) {
-        goto fail;
-    }
-```
-
-The implementation of **eth_enable_phy()** and **eth_reset_hw()**
-is in the `ie.c` file.
-
-### DMA buffer setup and hardware configuration
-
-With the device configured, we can now set up the DMA buffers.
-Here we see the [BTI](../objects/bus_transaction_initiator.md)
-handle, `edev->btih`, that we set up above, as the 2nd argument to
-**io_buffer_init()**:
-
-```c
-
-    r = io_buffer_init(&edev->buffer, edev->btih, ETH_ALLOC, IO_BUFFER_RW | IO_BUFFER_CONTIG);
-    if (r < 0) {
-        printf("eth: cannot alloc io-buffer %d\n", r);
-        goto fail;
-    }
-
-    eth_setup_buffers(&edev->eth, io_buffer_virt(&edev->buffer), io_buffer_phys(&edev->buffer));
-    eth_init_hw(&edev->eth);
-```
-
-The **io_buffer_init()**
-function zeroes the buffer, and creates a [VMO](../objects/vm_object.md)
-handle to the [BTI](../objects/bus_transaction_initiator.md).
-The **eth_setup_buffers()** and **eth_init_hw()** functions are defined in the `ie.c` module.
-
-### Final driver binding
-
-The next part binds the device name ("`intel-ethernet`"), context block (`edev`,
-allocated above), device operations (`device_ops`, which supports suspend, resume, and release),
-and the additional optional protocol ops for ethernet (identified as `ZX_PROTOCOL_ETHERNET_IMPL`
-and contained in `ethmac_ops`):
-
-```c
-    device_add_args_t args = {
-        .version = DEVICE_ADD_ARGS_VERSION,
-        .name = "intel-ethernet",
-        .ctx = edev,
-        .ops = &device_ops,
-        .proto_id = ZX_PROTOCOL_ETHERNET_IMPL,
-        .proto_ops = &ethmac_ops,
-    };
-
-    if (device_add(dev, &args, &edev->zxdev)) {
-        goto fail;
-    }
-```
-
-### Interrupt thread creation
-
-Finally, the background Interrupt Handling Thread (**IHT**), **irq_thread()** is created:
-
-```c
-    thrd_create_with_name(&edev->thread, irq_thread, edev, "eth-irq-thread");
-    thrd_detach(edev->thread);
-
-    printf("eth: intel-ethernet online\n");
-
-    return ZX_OK;
-```
-
-As discussed in the [Hardware Interfacing](hardware.md) chapter,
-the IHT handles asynchronous hardware events.
-We'll look at the thread itself below.
-
-### Failure handling
-
-In case of failure, the `fail` label is the target of various `goto`s within the code, and is
-responsible for cleanup of allocated resources as well as returning a failure code to the caller:
-
-```c
-fail:
-    io_buffer_release(&edev->buffer);
-    if (edev->btih) {
-        zx_handle_close(edev->btih);
-    }
-    if (edev->ioh) {
-        pci_enable_bus_master(&edev->pci, false);
-        zx_handle_close(edev->irqh);
-        zx_handle_close(edev->ioh);
-    }
-    free(edev);
-    return ZX_ERR_NOT_SUPPORTED;
-}
-```
-
-That concludes the discussion of the binding function.
-
-## The context structure
-
-At this point, we can circle back and take a look at the context structure:
-
-```c
-typedef struct ethernet_device {
-    ethdev_t        eth;
-    mtx_t           lock;
-    eth_state       state;
-    zx_device_t*    zxdev;
-    pci_protocol_t  pci;
-    zx_handle_t     ioh;
-    zx_handle_t     irqh;
-    thrd_t          thread;
-    zx_handle_t     btih;
-    io_buffer_t     buffer;
-    bool            online;
-
-    // callback interface to attached ethernet layer
-    ethmac_ifc_t*   ifc;
-    void*           cookie;
-} ethernet_device_t;
-```
-
-It holds all of the context for the ethernet devices.
-
-> @@@ How much discussion do we want of the context block members?
-
-## Ethernet protocol operations
-
-Recall from the discussion around the binding function
-**eth_bind()**
-that we bound an `ethmac_protocol_ops_t` structure called
-`ethmac_ops` to the driver.
-This structure provides the following "bottom-half" ethernet driver protocol operations
-for the Intel driver:
-
-```c
-static ethmac_protocol_ops_t ethmac_ops = {
-    .query = eth_query,
-    .stop = eth_stop,
-    .start = eth_start,
-    .queue_tx = eth_queue_tx,
-    .set_param = eth_set_param,
-//  .get_bti not supported
-};
-```
-
-We examine each in turn below.
-
-### Ethernet protocol: **query()**
-
-The **query()** function takes three parameters:
-a context block, an options specifier, and a pointer to
-an `ethmac_info_t` where the information should be stored.
-
-> Note that at the present time, there are no options defined; therefore, the driver
-> should return `ZX_ERR_INVALID_ARGS` in case of a non-zero value.
-
-The `ethmac_info_t` structure is defined as follows (reserved fields omitted for clarity):
-
-```c
-typedef struct ethmac_info {
-    uint32_t    features;
-    uint32_t    mtu;
-    uint8_t     mac[ETH_MAC_SIZE];
-} ethmac_info_t;
-```
-
-The `mtu` field contains the Maximum Transmission Unit (**MTU**) size that the driver
-can support.
-A common value is `1500`.
-
-The `mac` field contains `ETH_MAC_SIZE` (6 bytes) worth of Media Access Control (**MAC**)
-address in big-endian order (that is, for a MAC of `01:23:45:67:89:ab`, the value of
-`mac[0]` is `0x01`).
-
-Finally, the `features` field contains a bitmap of available features:
-
-Feature                 | Meaning
-------------------------|--------------------------------------------
-`ETHMAC_FEATURE_WLAN`   | Device is a wireless network device
-`ETHMAC_FEATURE_SYNTH`  | Device is a synthetic network device
-`ETHMAC_FEATURE_DMA`    | Driver will be doing DMA to/from the VMO
-
-The Intel driver's **eth_query()** is representative:
-
-```c
-static zx_status_t eth_query(void* ctx, uint32_t options, ethmac_info_t* info) {
-    ethernet_device_t* edev = ctx;
-
-    if (options) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    memset(info, 0, sizeof(*info));
-    ZX_DEBUG_ASSERT(ETH_TXBUF_SIZE >= ETH_MTU);
-    info->mtu = ETH_MTU;
-    memcpy(info->mac, edev->eth.mac, sizeof(edev->eth.mac));
-
-    return ZX_OK;
-}
-```
-
-In that it returns `ZX_ERR_INVALID_ARGS` in case the `options` parameter is non zero,
-and otherwise fills the `mtu` and `mac` members.
-
-### Ethernet protocol: **queue_tx()**
-
-The **queue_tx()** function is responsible for taking the `ethmac_netbuf_t` network
-buffer and transmitting it.
-
-```c
-static zx_status_t eth_queue_tx(void* ctx, uint32_t options, ethmac_netbuf_t* netbuf) {
-    ethernet_device_t* edev = ctx;
-    if (edev->state != ETH_RUNNING) {
-        return ZX_ERR_BAD_STATE;
-    }
-    return eth_tx(&edev->eth, netbuf->data, netbuf->len);
-}
-```
-
-The real work for the Intel ethernet driver is done in `ie.c`:
-
-```c
-status_t eth_tx(ethdev_t* eth, const void* data, size_t len) {
-    if (len > ETH_TXBUF_DSIZE) {
-        printf("intel-eth: unsupported packet length %zu\n", len);
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    zx_status_t status = ZX_OK;
-
-    mtx_lock(&eth->send_lock);
-
-    reap_tx_buffers(eth);
-
-    // obtain buffer, copy into it, setup descriptor
-    framebuf_t *frame = list_remove_head_type(&eth->free_frames, framebuf_t, node);
-    if (frame == NULL) {
-        status = ZX_ERR_NO_RESOURCES;
-        goto out;
-    }
-
-    uint32_t n = eth->tx_wr_ptr;
-    memcpy(frame->data, data, len);
-    // Pad out short packets.
-    if (len < 60) {
-      memset(frame->data + len, 0, 60 - len);
-      len = 60;
-    }
-    eth->txd[n].addr = frame->phys;
-    eth->txd[n].info = IE_TXD_LEN(len) | IE_TXD_EOP | IE_TXD_IFCS | IE_TXD_RS;
-    list_add_tail(&eth->busy_frames, &frame->node);
-
-    // inform hw of buffer availability
-    n = (n + 1) & (ETH_TXBUF_COUNT - 1);
-    eth->tx_wr_ptr = n;
-    writel(n, IE_TDT);
-
-out:
-    mtx_unlock(&eth->send_lock);
-    return status;
-}
-```
-
-This function performs buffer management and talks to the hardware.
-It first locks the mutex, and then finds an available buffer.
-This is done by calling **reap_tx_buffers()** to find available buffers,
-and then calling the macro **list_remove_head_type()** to try and fetch
-a buffer from the head of the list.
-If no buffer is available, an error status (`ZX_ERR_NO_RESOURCES`) is set
-and the function returns.
-
-Otherwise, the frame data is copied (short frames, less than 60 bytes, are padded
-with zeros).
-
-The hardware is kicked via the macro **writel()**, which writes to the
-`IE_TDT` register telling it which buffer is available to be written to the ethernet.
-
-At this point, the frame is queued at the chip level, and will be sent shortly.
-(The timing depends on if there are other frames queued before this one.)
-
-### Ethernet protocol: **set_param()**
-
-Sets a parameter based on the passed `param` argument and `value` argument.
-The Intel driver supports enabling or disabling promiscuous mode, and nothing else:
-
-```c
-static zx_status_t eth_set_param(void *ctx, uint32_t param, int32_t value, void* data) {
-    ethernet_device_t* edev = ctx;
-    zx_status_t status = ZX_OK;
-
-    mtx_lock(&edev->lock);
-
-    switch (param) {
-    case ETHMAC_SETPARAM_PROMISC:
-        if ((bool)value) {
-            eth_start_promisc(&edev->eth);
-        } else {
-            eth_stop_promisc(&edev->eth);
-        }
-        status = ZX_OK;
-        break;
-    default:
-        status = ZX_ERR_NOT_SUPPORTED;
-    }
-    mtx_unlock(&edev->lock);
-
-    return status;
-}
-```
-
-The following parameters are available:
-
-Parameter                           | Meaning (additional data)
-------------------------------------|-------------------------------------------------------------
-`ETHMAC_SETPARAM_PROMISC`           | Controls promiscuous mode (bool)
-`ETHMAC_SETPARAM_MULTICAST_PROMISC` | Controls multicast promiscuous mode (bool)
-`ETHMAC_SETPARAM_MULTICAST_FILTER`  | Sets multicast filtering addresses (count + array)
-`ETHMAC_SETPARAM_DUMP_REGS`         | Used for debug, dumps the registers (no additional data)
-
-For multicast filtering, the `value` argument indicates the count of MAC addresses sequentially
-presented via the `data` argument. For example, if `value` was `2`, then `data`
-would point to two back-to-back MAC addresses (2 x 6 = 12 bytes total).
-
-Note that if a parameter is not supported, the value `ZX_ERR_NOT_SUPPORTED` is returned.
-
-### Ethernet protocol: **start()** and **stop()**
-
-The two functions, **eth_start()** and **eth_stop()** are used to start and stop
-the ethernet device:
-
-```c
-static void eth_stop(void* ctx) {
-    ethernet_device_t* edev = ctx;
-    mtx_lock(&edev->lock);
-    edev->ifc = NULL;
-    mtx_unlock(&edev->lock);
-}
-
-static zx_status_t eth_start(void* ctx, ethmac_ifc_t* ifc, void* cookie) {
-    ethernet_device_t* edev = ctx;
-    zx_status_t status = ZX_OK;
-
-    mtx_lock(&edev->lock);
-    if (edev->ifc) {
-        status = ZX_ERR_BAD_STATE;
-    } else {
-        edev->ifc = ifc;
-        edev->cookie = cookie;
-        edev->ifc->status(edev->cookie, edev->online ? ETHMAC_STATUS_ONLINE : 0);
-    }
-    mtx_unlock(&edev->lock);
-
-    return status;
-}
-```
-
-The Intel ethernet driver code shown above is typical; the `ifc` member of the context
-block is used as both an indication of status (`NULL` if stopped) and, when running,
-it points to a valid interface block.
-
-### Ethernet protocol: **get_bti()**
-
-The Intel ethernet driver doesn't support the optional **get_bti()** callout.
-
-This callout is used to return a handle to the [BTI](../objects/bus_transaction_initiator.md).
-In case the device doesn't support it, it can either leave it out of the `ethmac_protocol_ops_t`
-structure (like the Intel ethernet driver does), or it can return `ZX_HANDLE_INVALID`.
-
-If supported, the handle is returned from the function.
-Note that the ownership of the handle is *not* transferred; the ethernet driver still
-owns the handle.
-In particular, the caller must not close the handle.
-
-## Receiving data
-
-The IHT thread created by the binding function waits for data from the ethernet hardware.
-When data arrives, it calls **eth_handle_irq()** to process the data.
-
-The portion of the thread in `ethernet.c` is as follows:
-
-```c
-static int irq_thread(void* arg) {
-    ethernet_device_t* edev = arg;
-    for (;;) {
-        zx_status_t r;
-        r = zx_interrupt_wait(edev->irqh, NULL);
-        if (r != ZX_OK) {
-            printf("eth: irq wait failed? %d\n", r);
-            break;
-        }
-        mtx_lock(&edev->lock);
-        unsigned irq = eth_handle_irq(&edev->eth);
-        if (irq & ETH_IRQ_RX) {
-            void* data;
-            size_t len;
-
-            while (eth_rx(&edev->eth, &data, &len) == ZX_OK) {
-                if (edev->ifc && (edev->state == ETH_RUNNING)) {
-                    edev->ifc->recv(edev->cookie, data, len, 0);
-                }
-                eth_rx_ack(&edev->eth);
-            }
-        }
-        if (irq & ETH_IRQ_LSC) {
-            bool was_online = edev->online;
-            bool online = eth_status_online(&edev->eth);
-            zxlogf(TRACE, "intel-eth: ETH_IRQ_LSC fired: %d->%d\n", was_online, online);
-            if (online != was_online) {
-                edev->online = online;
-                if (edev->ifc) {
-                    edev->ifc->status(edev->cookie, online ? ETHMAC_STATUS_ONLINE : 0);
-                }
-            }
-        }
-        mtx_unlock(&edev->lock);
-    }
-    return 0;
-}
-```
-
-The thread waits on an interrupt, and, when one occurs, calls **eth_handle_irq()**
-to read the interrupt reason register (which also clears the interrupt
-indication on the card).
-
-Based on the value read from **eth_handle_irq()**,
-there are two major flows in the thread:
-
-1.  the bit `ETH_IRQ_RX` is present &mdash; this indicates data has been
-    received by the card,
-2.  the bit `ETH_IRQ_LSC` is present &mdash; this indicates a Line Status
-    Change (LSC) event has been detected by the card.
-
-If data has been received, the following functions are called:
-
-*   **eth_rx()** &mdash; obtains a pointer to the receive buffer containing the data
-*   **eth_rx_ack()** &mdash; acknowledges receipt of the packet by writing to registers on the card
-
-
-Note that further processing is done by the ethernet device protocol (available via `edev->ifc`):
-
-*   **edev->ifc->recv()** &mdash; processes the received data
-*   **edev->ifc->status()** &mdash; processes the status change
-
-In the case of a line status change, **eth_status_online()** is called to handle the event.
-
-```c
-status_t eth_rx(ethdev_t* eth, void** data, size_t* len) {
-    uint32_t n = eth->rx_rd_ptr;
-    uint64_t info = eth->rxd[n].info;
-
-    if (!(info & IE_RXD_DONE)) {
-        return ZX_ERR_SHOULD_WAIT;
-    }
-
-    // copy out packet
-    zx_status_t r = IE_RXD_LEN(info);
-
-    *data = eth->rxb + ETH_RXBUF_SIZE * n;
-    *len = r;
-
-    return ZX_OK;
-}
-```
-
diff --git a/docs/ddk/ethernet.odg b/docs/ddk/ethernet.odg
deleted file mode 100644
index 89efe8a..0000000
--- a/docs/ddk/ethernet.odg
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/firmware.md b/docs/ddk/firmware.md
deleted file mode 100644
index a1de484..0000000
--- a/docs/ddk/firmware.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# Device Firmware
-
-Device firmware are binary blobs containing code that are executed by device
-hardware. The binary blob is available in the driver's namespace for loading.
-
-Device firmware are stored in CIPD (Chrome Infrastructure Package Deployment)
-and mirrored in Google Storage.
-
-## Before You Start
-
-Ensure that CIPD is available. cipd must be either in PATH or
-`zircon/../buildtools/cipd`.
-
-The buildtools repository is available
-[here](https://fuchsia.googlesource.com/buildtools/).
-
-## Create a Firmware Package
-
-To create a firmware package, create a directory containing the following
-files:
-
-* One or more firmware files
-* A license file
-* [README.fuchsia](https://fuchsia.googlesource.com/docs/+/master/development/source_code/README.fuchsia.md)
-
-README.fuchsia must contain at least the following directives:
-
-* `Name`
-* `Version`
-* `Upstream Git`
-* `License`
-* `License File`
-
-If this is the first time you uploaded to CIPD from the host system,
-authenticate with CIPD:
-
-```
-cipd auth-login
-```
-
-Upload and tag the package in CIPD using the following command:
-
-```
-cipd create -in <package-directory> -install-mode copy \
-    -name <package-name> \
-    -tag git_repository:<source-git-repositry> \
-    -tag git_revision:<source-git-revision>
-```
-
-`package-name` has the format `fuchsia/firmware/<name>`.
-
-`<name>` should be a string that identifies the firmware. It may contain
-any non-whitespace character. It is helpful to identify the driver that will
-use the firmware in the name.
-
-After this step, the package is uploaded to CIPD. Check the
-[CIPD browser here](https://chrome-infra-packages.appspot.com/#/?path=fuchsia/firmware)
-for packages under `fuchsia/firmware`.
-
-## Adding the Firmware Package to the Build
-
-Add the following entry in `prebuilt/zircon.ensure`:
-
-```
-@Subdir firmware/<name>
-<package-name> git_revision:<source-git-revision>
-```
-
-Where `<name>`, `<package-name>` and `<source-git-revision>` matches the
-values passed to `cipd create` above. The package will be downloaded to
-the path specified by `@Subdir` under `prebuilt`, i.e.
-`prebuilt/firmware/<name>`.
-
-Next, update `prebuilt/zircon.versions` with the following command:
-
-```
-scripts/download-prebuilt --resolve
-```
-
-Upload this change to Gerrit and send it to the CQ.  The firmware package will
-be downloaded by `scripts/download-prebuilt` along with the toolchain and QEMU.
-
-## Using the Firmware Package in the Driver
-
-Add the following line to the driver's `rules.mk`:
-
-```
-MODULE_FIRMWARE := <name>/<path-to-binary-blob>
-```
-
-This will install the firmware to bootfs under
-`/boot/lib/firmware/$(basename $(MODULE_FIRMWARE))`.
-
-The `load_firmware()` API, defined in [`driver.h`](../../system/ulib/ddk/include/ddk/driver.h)
-loads the firmware pointed to by the path in a VMO.
diff --git a/docs/ddk/getting_started.md b/docs/ddk/getting_started.md
deleted file mode 100644
index dc17710..0000000
--- a/docs/ddk/getting_started.md
+++ /dev/null
@@ -1,268 +0,0 @@
-
-
-<!--
-    (C) Copyright 2018 The Fuchsia Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style license that can be
-    found in the LICENSE file.
--->
-
-# Getting Started
-
-This document is part of the [Driver Development Kit tutorial](ddk-tutorial.md) documentation.
-
-Writing a device driver is often viewed as a daunting task, fraught with complexities
-and requiring arcane knowledge of little-known kernel secrets.
-
-The goal of this section is to demystify the process; you'll learn everything you
-need to know about how to write device drivers, starting with what they do, how
-they work, and how they fit into the overall system.
-
-## Overview
-
-At the highest level, a device driver's job is to provide a uniform interface to
-a particular device, while hiding details specific to the device's implementation.
-
-Two different ethernet drivers, for example, both allow a client to send packets
-out an interface, using the exact same C language function.
-Each driver is responsible for managing its own hardware in a way that makes the
-client interfaces identical, even though the hardware is different.
-
-Note that the interfaces that are provided by the driver may be "intermediate" &mdash;
-that is, they might not necessarily represent the "final" device in the chain.
-
-Consider a PCI-based ethernet device.
-First, a base PCI driver is required that understands how to talk to the PCI bus itself.
-This driver doesn't know anything about ethernet, but it does know
-how to deal with the specific PCI chipset present on the machine.
-
-It enumerates the devices on that bus, collects information
-from the various registers on each device, and provides functions that allow
-its clients (such as the PCI-based ethernet driver) to perform PCI operations
-like allocating an interrupt or a DMA channel.
-
-Thus, this base PCI driver provides services to the ethernet driver, allowing
-the ethernet driver to manage its associated hardware.
-
-At the same time, other devices (such as a video card) could also use the base PCI
-driver in a similar manner to manage their hardware.
-
-## The Zircon model
-
-In order to provide maximum flexibility, drivers in the Zircon world are allowed
-to bind to matching "parent" devices, and publish "children" of their own.
-This hierarchy extends as required: one driver might publish a child, only to have
-another driver consider that child their parent, with the second driver publishing
-its own children, and so on.
-
-In order to understand how this works, let's follow the PCI-based ethernet example.
-
-The system starts by providing a special "PCI root" parent.
-Effectively, it's saying "I know that there's a PCI bus on this system, when you
-find it, bind it *here*."
-
-> The "Advanced Topics" section below has more details about this process.
-
-Drivers are evaluated by the system (a directory is searched), and drivers that
-match are automatically bound.
-
-In this case, a driver that binds to a "PCI root" parent is found, and bound.
-
-This is the base PCI driver.
-It's job is to configure the PCI bus, and enumerate the peripherals on the bus.
-
-The PCI bus has specific conventions for how peripherals are identified:
-a combination of a Vendor ID (**VID**) and Device ID (**DID**) uniquely identifies
-all possible PCI devices.
-During enumeration, these values are read from the peripheral, and new parent
-nodes are published containing the detected VID and DID (and a host of other
-information).
-
-Every time a new device is published, the same process as described above (for
-the initial PCI root device publication) repeats;
-that is, drivers are evaluated by the system, searching for drivers that match
-up with the new parents' characteristics.
-
-Whereas with the PCI root device we were searching for a driver that matched
-a certain kind of functionality (called a "protocol," we'll see this shortly), in
-this case, however, we're searching for drivers that match a different
-protocol, namely one that satisfies the requirements of "is a PCI device and
-has a given VID and DID."
-
-If a suitable driver is found (one that matches the required protocol, VID and
-DID), it's bound to the parent.
-
-As part of binding, we initialize the driver &mdash; this involves such operations
-as setting up the card for operation, bringing up the interface(s), and
-publishing a child or children of this device.
-In the case of the PCI ethernet driver, it publishes the "ethernet" interface,
-which conforms to yet another protocol, called the "ethernet implementation" protocol.
-This protocol represents a common protocol that's close to the functions that
-clients use (but is one step removed; we'll come back to this).
-
-### Protocols
-
-We mentioned three protocols above:
-
-*   the PCI root protocol (`ZX_PROTOCOL_PCIROOT`),
-*   the PCI device protocol (`ZX_PROTOCOL_PCI`), and
-*   the ethernet implementation protocol (`ZX_PROTOCOL_ETHERNET_IMPL`).
-
-The names in brackets are the C language constants corresponding to the protocols, for reference.
-
-So what is a protocol?
-
-A protocol is a strict interface definition.
-
-The ethernet driver published an interface that conforms to `ZX_PROTOCOL_ETHERNET_IMPL`.
-This means that it must provide a set of functions defined in a data structure
-(in this case, `ethmac_protocol_ops_t`).
-
-These functions are common to all devices implementing the protocol &mdash; for example,
-all ethernet devices must provide a function that queries the MAC address of the
-interface.
-
-Other protocols will of course have different requirements for the functions they
-must provide.
-For example a block device will publish an interface that conforms to the
-"block implementation protocol" (`ZX_PROTOCOL_BLOCK_IMPL`) and
-provide functions defined by `block_protocol_ops_t`.
-This protocol includes a function that returns the size of the device in blocks,
-for example.
-
-We'll examine these protocols in the following chapters.
-
-# Advanced Topics
-
-The above has presented a big picture view of Zircon drivers, with a focus on protocols.
-
-In this section, we'll examine some advanced topics, such as platform dependent
-and platform independent code decoupling,
-the "miscellaneous" protocol, and how protocols and processes are mapped.
-
-## Platform dependent vs platform independent
-
-Above, we mentioned that `ZX_PROTOCOL_ETHERNET_IMPL` was "close to" the functions used
-by the client, but one step removed.
-That's because there's one more protocol, `ZX_PROTOCOL_ETHERNET`, that sits between
-the client and the driver.
-This additional protocol is in place to handle functionality common to all ethernet
-drivers (in order to avoid code duplication).
-Such functionality includes buffer management, status reporting, and administrative
-functions.
-
-This is effectively a "platform dependent" vs "platform independent" decoupling;
-common code exists in the platform independent part (once), and driver-specific code
-is implemented in the platform dependent part.
-
-This architecture is repeated in multiple places.
-With block devices, for example, the hardware driver binds to the bus (e.g., PCI)
-and provides a `ZX_PROTOCOL_BLOCK_IMPL` protocol.
-The platform independent driver binds to `ZX_PROTOCOL_BLOCK_IMPL`, and publishes the
-client-facing protocol, `ZX_PROTOCOL_BLOCK`.
-
-You'll also see this with the display controllers, I<sup>2</sup>C bus, and serial drivers.
-
-## Miscellaneous protocol
-
-In [simple drivers](simple.md), we show the code for several drivers that illustrate
-basic functionality, but don't provide services related to a specific protocol
-(i.e., they are not "ethernet" or "block" devices).
-These drivers are bound to `ZX_PROTOCOL_MISC_PARENT`.
-
-> @@@ More content?
-
-## Process / protocol mapping
-
-In order to keep the discussions above simple, we didn't talk about process separation
-as it relates to the drivers.
-To understand the issues, let's see how other operating systems deal with them,
-and compare that to the Zircon approach.
-
-In a monolithic kernel, such as Linux, many drivers are implemented within the kernel.
-This means that they share the same address space, and effectively live in the same
-"process."
-
-The major problem with this approach is fault isolation / exploitation.
-A bad driver can take out the entire kernel, because it lives in the same address
-space and thus has privileged access to all kernel memory and resources.
-A compromised driver can present a security threat for the same reason.
-
-The other extreme, that is, putting each and every driver service into its own
-process, is used by some microkernel operating systems.
-Its major drawback is that if one driver relies on the services of another driver,
-the kernel must effect at least a context switch operation (if not a data transfer
-as well) between the two driver processes.
-While microkernel operating systems are usually designed to be fast at these
-kinds of operations, performing them at high frequency is undesirable.
-
-The approach taken by Zircon is based on the concept of a device host (**devhost**).
-A devhost is a process that contains a protocol stack &mdash; that is, one or
-more protocols that work together.
-The devhost loads drivers from ELF shared libraries (called Dynamic Shared Objects,
-or **DSO**s).
-In the [simple drivers](simple.md) section, we'll see the meta information
-that's contained in the DSO to facilitate the discovery process.
-
-The protocol stack effectively allows the creation of a complete "driver" for
-a device, consisting of platform dependent and platform independent components,
-in a self-contained process container.
-
-For the advanced reader, take a look at the `dm dump` command available from
-the Zircon command line.
-It displays a tree of devices, and shows you the process ID, DSO name, and
-other useful information.
-
-Here's a highly-edited version showing just the PCI ethernet driver parts:
-
-```
-1. [root]
-2.    [sys]
-3.       <sys> pid=1416 /boot/driver/bus-acpi.so
-4.          [acpi] pid=1416 /boot/driver/bus-acpi.so
-5.          [pci] pid=1416 /boot/driver/bus-acpi.so
-            ...
-6.             [00:02:00] pid=1416 /boot/driver/bus-pci.so
-7.                <00:02:00> pid=2052 /boot/driver/bus-pci.proxy.so
-8.                   [intel-ethernet] pid=2052 /boot/driver/intel-ethernet.so
-9.                      [ethernet] pid=2052 /boot/driver/ethernet.so
-```
-
-From the above, you can see that process ID `1416` (lines 3 through 6)
-is the Advanced Configuration and Power Interface (**ACPI**) driver, implemented
-by the DSO `bus-acpi.so`.
-
-During primary enumeration, the ACPI DSO detected a PCI bus.
-This caused the publication of a parent with `ZX_PROTOCOL_PCI_ROOT` (line 5,
-causing the appearance of the `[pci]` entry),
-which then caused the devhost to load the `bus-pci.so` DSO and bind to it.
-That DSO is the "base PCI driver" to which we've been referring throughout the
-discussions above.
-
-During its binding, the base PCI driver enumerated the PCI bus, and found an ethernet
-card (line 6 detects bus 0, device 2, function 0, shown as `[00:02:00]`).
-(Of course, many other devices were found as well, but we've removed them from
-the above listing for simplicity).
-
-The detection of this device then caused the base PCI driver to publish a new parent
-with `ZX_PROTOCOL_PCI` and the device's VID and DID.
-Additionally, a new devhost (process ID `2052`) was created and loaded with the
-`bus-pci.proxy.so` DSO (line 7).
-This proxy serves as the interface from the new devhost (pid `2052`) to the base PCI
-driver (pid `1416`).
-
-> This is where the decision was made to "sever" the device driver into its own
-> process &mdash; the new devhost and the base PCI driver now live in two
-> different processes.
-
-The new devhost `2052` then finds a matching child (the `intel-ethernet.so`
-DSO on line 8; it's considered a match because it has `ZX_PROTOCOL_PCI` and the correct
-VID and DID).
-That DSO publishes a `ZX_PROTOCOL_ETHERNET_IMPL`, which binds to a matching
-child (the `ethernet.so` DSO on line 9; it's considered a match because it has a
-`ZX_PROTOCOL_ETHERNET_IMPL` protocol).
-
-What's not shown by this chain is that the final DSO (`ethernet.so`) publishes
-a `ZX_PROTOCOL_ETHERNET` &mdash; that's the piece that clients can use, so of
-course there's no further "device" binding involved.
-
-
diff --git a/docs/ddk/hardware.md b/docs/ddk/hardware.md
deleted file mode 100644
index 550f4b6..0000000
--- a/docs/ddk/hardware.md
+++ /dev/null
@@ -1,708 +0,0 @@
-
-
-<!--
-    (C) Copyright 2018 The Fuchsia Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style license that can be
-    found in the LICENSE file.
--->
-
-# Hardware Interfacing
-
-This document is part of the [Driver Development Kit tutorial](ddk-tutorial.md) documentation.
-
-## Overview
-
-In past chapters, we saw how the protocol stack was organized within a devhost,
-and some of the work that goes into binding the individual driver protocols into
-a device driver.
-
-In this section, we'll look at practical considerations of dealing with hardware
-such as determining configuration, binding to interrupts, allocating memory,
-and performing DMA operations.
-
-Here, we'll look at the concepts involved, and show snippets of code as required.
-Complete working code is shown in subsequent chapters (e.g., [Ethernet Devices](ethernet.md)).
-
-For the most part, we'll focus on the PCI bus, and we'll cover the following
-functions:
-
-* Access related:
-    *   **pci_map_bar()**
-* Interrupt related:
-    *   **pci_map_interrupt()**
-    *   **pci_query_irq_mode()**
-    *   **pci_set_irq_mode()**
-* DMA related:
-    *   **pci_enable_bus_master()**
-    *   **pci_get_bti()**
-
-# Configuration
-
-Hardware peripherals are attached to the CPU via a bus, such as the PCI bus.
-
-During bootup, the BIOS (or equivalent platform startup software)
-discovers all of the peripherals attached to the PCI bus.
-Each peripheral is assigned resources (notably interrupt vectors,
-and address ranges for configuration registers).
-
-The impact of this is that the actual resources assigned to each peripheral may
-be different across reboots.
-When the operating system software starts up, it enumerates
-the bus and starts drivers for all supported devices.
-The drivers then call PCI functions in order to obtain configuration information about
-their device(s) so that they can map registers and bind to interrupts.
-
-## Base address register
-
-The Base Address Register (**BAR**) is a configuration register that exists on each
-PCI device.
-It's where the BIOS stores information about the device, such as the assigned interrupt vector
-and addresses of control registers.
-Other, device specific information, is stored there as well.
-
-Call **pci_map_bar()**
-to cause the BAR register to be mapped into the devhost's address space:
-
-```c
-zx_status_t pci_map_bar(const pci_protocol_t* pci, uint32_t bar_id,
-                        uint32_t cache_policy, void** vaddr, size_t* size,
-                        zx_handle_t* out_handle);
-```
-
-The first parameter, `pci`, is a pointer to the PCI protocol.
-Typically, you obtain this in your **bind()** function via
-**device_get_protocol()**.
-
-The second parameter, `bar_id`, is the BAR register number, starting with `0`.
-
-The third parameter, `cache_policy`, determines the caching policy for access,
-and can take on the following values:
-
-`cache_policy` value                | Meaning
-------------------------------------|---------------------
-`ZX_CACHE_POLICY_CACHED`            | use hardware caching
-`ZX_CACHE_POLICY_UNCACHED`          | disable caching
-`ZX_CACHE_POLICY_UNCACHED_DEVICE`   | disable caching, and treat as device memory
-`ZX_CACHE_POLICY_WRITE_COMBINING`   | uncached with write combining
-
-Note that `ZX_CACHE_POLICY_UNCACHED_DEVICE` is architecture dependent
-and may in fact be equivalent to `ZX_CACHE_POLICY_UNCACHED` on some architectures.
-
-The next three arguments are return values.
-The `vaddr` and `size` return a pointer (and length) of the register region, while
-`out_handle` stores the created handle to the
-[VMO](../objects/vm_object.md).
-
-## Reading and writing memory
-
-Once the **pci_map_bar()**
-function returns with a valid result, you can access the BAR via simple pointer
-operations, for example:
-
-```c
-volatile uint32_t* base;
-...
-zx_status_t rc;
-rc = pci_map_bar(dev->pci, 0, ZX_CACHE_POLICY_UNCACHED_DEVICE, &base, &size, &handle);
-if (rc == ZX_OK) {
-    base[REGISTER_X] = 0x1234;  // configure register X for deep sleep mode
-}
-```
-
-It's important to declare `base` as `volatile` &mdash; this tells the compiler not to
-make any assumptions about the contents of the data that `base` points to.
-For example:
-
-```c
-int timeout = 1000;
-while (timeout-- > 0 && !(base[REGISTER_READY] & READY_BIT)) ;
-```
-
-is a typical (bounded) polling loop, intended for short polling sequences.
-Without the `volatile` keyword in the declaration, the compiler would have no reason
-to believe that the value at `base[REGISTER_READY]` would ever change, so it would
-cause it to be read only once.
-
-# Interrupts
-
-An interrupt is an asynchronous event, generated by a device when it needs servicing.
-For example, an interrupt is generated when data is available on a serial port,
-or an ethernet packet has arrived.
-Interrupts allow a driver to know about an event as soon as it
-occurs, but without the driver spending time polling (actively waiting) for it.
-
-The general architecture of a driver that uses interrupts is that a background
-Interrupt Handling Thread (**IHT**) is created during the driver startup / binding
-operation.
-This thread waits for an interrupt to happen, and, when it does, performs some
-kind of servicing action.
-
-As an example, consider a serial port driver.
-It may receive interrupts due to any of the following events happening:
-
-*   one or more characters have arrived,
-*   room is now available to transmit one or more characters,
-*   a control line (like `DTR`, for example) has changed state.
-
-The interrupt wakes up the IHT.
-The IHT determines the cause of the event, usually by reading some status registers.
-Then, it runs an appropriate service function to handle the event.
-Once done, the IHT goes back to sleep, waiting for the next interrupt.
-
-For example, if a character arrives, the IHT wakes up, reads a status register that
-indicates "data is available," and then calls a function that drains all available
-characters from the serial port FIFO into the driver's buffer.
-
-## No kernel-level code required
-
-You may be familiar with other operating systems which use Interrupt
-Service Routines (**ISR**).
-These are kernel-level handlers that run in privileged mode and interface with
-the interrupt controller hardware.
-
-In Fuchsia, the kernel deals with the privileged part of the interrupt
-handling, and provides thread-level functions for driver use.
-
-The difference is that the IHT runs at thread level, whereas the ISR runs
-at kernel level in a very restricted (and sometimes fragile) environment.
-A principal advantage is that if the IHT crashes, it takes out only the
-driver, whereas a failing ISR can take out the entire operating system.
-
-## Attaching to an interrupt
-
-Currently, the only bus that provides interrupts is the PCI bus.
-It supports two kinds: legacy and Message Signaled Interrupts (**MSI**).
-
-Therefore, in order to use interrupts on PCI:
-
-1.  determine which kind your device supports (legacy or MSI),
-2.  set the interrupt mode to match,
-3.  get a handle to your device's interrupt vector (usually one, but may be multiple),
-4.  start IHT background thread,
-5.  arrange for IHT thread to wait for interrupts (on handle(s) from step 3).
-
-Steps `1` and `2` are usually done closely together, for example:
-
-```c
-// Query whether we have MSI or Legacy interrupts.
-uint32_t irq_cnt = 0;
-if ((pci_query_irq_mode(&edev->pci, ZX_PCIE_IRQ_MODE_MSI, &irq_cnt) == ZX_OK) &&
-    (pci_set_irq_mode(&edev->pci, ZX_PCIE_IRQ_MODE_MSI, 1) == ZX_OK)) {
-    // using MSI interrupts
-} else if ((pci_query_irq_mode(&edev->pci, ZX_PCIE_IRQ_MODE_LEGACY, &irq_cnt) == ZX_OK) &&
-           (pci_set_irq_mode(&edev->pci, ZX_PCIE_IRQ_MODE_LEGACY, 1) == ZX_OK)) {
-    // using legacy interrupts
-} else {
-    // an error
-}
-```
-
-The **pci_query_irq_mode()**
-function takes three arguments:
-
-```c
-zx_status_t pci_query_irq_mode(const pci_protocol_t* pci,
-                               zx_pci_irq_mode_t mode,
-                               uint32_t* out_max_irqs);
-```
-
-The first argument, `pci`, is a pointer to the PCI protocol stack bound to your device
-just like we saw above, in the BAR documentation.
-
-The second argument, `mode`, is the kind of interrupt that you are interested in;
-it's one of the two constants shown in the example.
-
-> @@@ there's also a `ZX_PCIE_IRQ_MODE_MSI_X` in the syscalls/pci.h file; should I say anything about that? How would we use it in the above case, just make a third condition?
-
-The third argument is a pointer to integer that returns how many
-interrupts of the specified type your device supports.
-
-Having determined the kind of interrupt supported, you then call
-**pci_set_irq_mode()**
-to indicate that this is indeed the kind of interrupt that you wish to use.
-
-Finally, you call **pci_map_interrupt()**
-to create a handle to the selected interrupt. Note that
-**pci_map_interrupt()** has the following prototype:
-
-```c
-zx_status_t pci_map_interrupt(const pci_protocol_t* pci,
-                              int which_irq,
-                              zx_handle_t* out_handle);
-```
-
-The first argument is the same as in the previous call, the second argument, `which_irq`
-indicates the device-relative interrupt number you'd like, and the third argument
-is a pointer to the created interrupt handle.
-
-You now have an interrupt handle.
-
-> Note that the vast majority of devices have just one interrupt, so simply passing
-> `0` for `which_irq` is normal.
-> If your device does have more than one interrupt, the common practice is to run the
-> **pci_map_interrupt()** function in a `for` loop
-> and bind handles to each interrupt.
-
-## Waiting for the interrupt
-
-In your IHT, you call [**zx_interrupt_wait()**](../syscalls/interrupt_wait.md)
-to wait for the interrupt.
-The following prototype applies:
-
-```c
-zx_status_t zx_interrupt_wait(zx_handle_t handle,
-                              zx_time_t* out_timestamp);
-```
-
-The first argument is the handle you obtained via the call to
-**pci_map_interrupt()**,
-and the second parameter can be `NULL` (typical), or it can be a pointer to a time
-stamp that indicates when the interrupt was triggered (in nanoseconds,
-relative to the clock source `ZX_CLOCK_MONOTONIC`).
-
-Therefore, a typical IHT would have the following shape:
-
-```c
-static int irq_thread(void* arg) {
-    my_device_t* dev = arg;
-    for (;;) {
-        zx_status_t rc;
-        rc = zx_interrupt_wait(dev->irq_handle, NULL);
-        // do stuff
-    }
-}
-```
-
-The convention is that the argument passed to the IHT is your device context block.
-The context block has a member (here `irq_handle`) that is the handle you obtained via
-**pci_map_interrupt()**.
-
-## Edge vs level interrupt mode
-
-The interrupt hardware can operate in one of two modes; "edge" or "level".
-
-In edge mode, the interrupt is armed on the active-going edge (when the hardware
-signal goes from inactive to active), and works as a one-shot.
-That is, the signal must go back to inactive before it can be recognized again.
-
-In level mode, the interrupt is active when the hardware signal is in the
-active state.
-
-Typically, edge mode is used when the interrupt is dedicated, and level mode is
-used when the interrupt is shared by multiple devices (because you want the
-interrupt to remain active until *all* devices have de-asserted their request line).
-
-The Zircon kernel automatically masks and unmasks the interrupt as appropriate.
-For level-triggered hardware interrupts,
-[**zx_interrupt_wait()**](../syscalls/interrupt_wait.md)
-masks the interrupt before returning, and unmasks it when called the next time.
-For edge-triggered interrupts, the interrupt remains unmasked.
-
-> The IHT should not perform any long-running tasks.
-> For drivers that perform lengthy tasks, use a worker thread.
-
-## Shutting down a driver that uses interrupts
-
-In order to cleanly shut down a driver that uses interrupts, you can use
-[**zx_interrupt_destroy()**](../syscalls/interrupt_destroy.md)
-to abort the
-[**zx_interrupt_wait()**](../syscalls/interrupt_wait.md)
-call.
-
-The idea is that when the foreground thread determines that the driver should be
-shut down, it simply destroys the interrupt handle, causing the IHT to shut down:
-
-```c
-static void main_thread() {
-    ...
-    if (shutdown_requested) {
-        // destroy the handle, this will cause zx_interrupt_wait() to pop
-        zx_interrupt_destroy(dev->irq_handle);
-
-        // wait for the IHT to finish
-        thrd_join(dev->iht, NULL);
-    }
-    ...
-}
-
-static int irq_thread(void* arg) {
-    ...
-    for(;;) {
-        zx_status_t rc;
-        rc = zx_interrupt_wait(dev->irq_handle, NULL);
-        if (rc == ZX_ERR_CANCELED) {
-            // we are being shut down, do any cleanups required
-            ...
-            return;
-        }
-        ...
-    }
-}
-```
-
-The main thread, when requested to shut down, destroys the interrupt handle.
-This causes the IHT's
-[**zx_interrupt_wait()**](../syscalls/interrupt_wait.md)
-call to wake up with an error code.
-The IHT looks at the error code (in this case, `ZX_ERR_CANCELED`) and makes
-the decision to end.
-Meanwhile, the main thread is waiting to join the IHT via the call
-to **thrd_join()**.
-Once the IHT exits, **thrd_join()** returns, and the main
-thread can finish its processing.
-
-The advanced reader is invited to look at some of the other interrupt related
-functions available:
-
-*   [**zx_interrupt_ack()**](../syscalls/interrupt_ack.md)
-*   [**zx_interrupt_bind()**](../syscalls/interrupt_bind.md)
-*   [**zx_interrupt_create()**](../syscalls/interrupt_create.md)
-*   [**zx_interrupt_trigger()**](../syscalls/interrupt_trigger.md)
-
-# DMA
-
-Direct Memory Access (**DMA**) is a feature that allows hardware to access
-memory without CPU intervention.
-At the highest level, the hardware is given the source and destination of the
-memory region to transfer (along with its size) and told to copy the data.
-Some hardware peripherals even support the ability to do multiple
-"scatter / gather" style operations, where several copy operations
-can be performed, one after the other, without additional CPU intervention.
-
-## DMA considerations
-
-In order to fully appreciate the issues involved, it's important to
-keep the following in mind:
-
-*   each process operates in a virtual address space,
-*   an MMU can map a contiguous virtual address range onto multiple,
-    discontiguous physical address ranges (and vice-versa),
-*   each process has a limited window into physical address space,
-*   some peripherals support their own virtual addresses
-    via an Input / Output Memory Management Unit (**IOMMU**).
-
-Let's discuss each point in turn.
-
-### Virtual, physical, and device-physical addresses
-
-The addresses that the process has access to are virtual; that is, they are
-an illusion created by the CPU's Memory Management Unit (**MMU**).
-A virtual address is mapped by the MMU into a physical address.
-The mapping granularity is based on a parameter called "page size," which
-is at least 4k bytes, though larger sizes are available on modern processors.
-
-![Figure: Relationship between virtual and physical addresses](dma-000-cropped.png)
-
-In the diagram above, we show a specific process (process 12) with a number of
-virtual addresses (in blue).
-The MMU is responsible for mapping the blue virtual addresses into CPU physical
-bus addresses (red).
-Each process has its own mapping; so even though process 12 has a virtual address
-`300`, some other process may also have a virtual address `300`.
-That other process's virtual address `300` (if it exists) would be mapped
-to a different physical address than the one in process 12.
-
-> Note that we've used small decimal numbers as "addresses" to keep the discussion simple.
-> In reality, each square shown above represents a page of memory (4k or more),
-> and is identified by a 32 or 64 bit value (depending on the platform).
-
-The key points shown in the diagram are:
-
-1.  virtual addresses can be allocated in groups (three are shown, `300`-`303`, `420`-`421`,
-    and `770`-`771`),
-2.  virtually contiguous (e.g., `300`-`303`) is not necessarily physically contiguous.
-3.  some virtual addresses are not mapped (for example, there is no virtual address
-    `304`)
-4.  not all physical addresses are available to each process (for example, process
-    `12` doesn't have access to physical address `120`).
-
-Depending on the hardware available on the platform, a device's address space
-may or may not follow a similar translation.
-Without an IOMMU, the addresses that the peripheral uses are the same as
-the physical addresses used by the CPU:
-
-![Figure: A device that doesn't use an IOMMU](dma-002-cropped.png)
-
-In the diagram above, portions of the device's address space (for example, a
-frame buffer, or control registers), appear directly in the CPU's physical
-address range.
-That is to say, the device occupies physical addresses `122` through `125`
-inclusive.
-
-In order for the process to access the device's memory, it would need to create
-an MMU mapping from some virtual addresses to the physical addresses `122` through
-`125`.
-We'll see how to do that, below.
-
-But with an IOMMU, the addresses seen by a peripheral may be different than
-the CPU's physical addresses:
-
-![Figure: A device that uses an IOMMU](dma-001-cropped.png)
-
-Here, the device has its own "device-physical" addresses that it knows about,
-that is, addresses `0` through `3` inclusive.
-It's up to the IOMMU to map the device-physical addresses `0` through `3`
-into CPU physical addresses `109`, `110`, `101`, and `119`, respectively.
-
-In this scenario, in order for the process to use the device's memory, it needs
-to arrange two mappings:
-
-*   one set from the virtual address space (e.g., `300` through `303`) to the
-    CPU physical address space (`109`, `110`, `101`, and `119`, respectively),
-    via the MMU, and
-*   one set from the CPU physical address space (addresses `109`, `110`, `101`,
-    and `119`) to the device-physical addresses (`0` through `3`) via the IOMMU.
-
-While this may seem complicated, Zircon provides an abstraction that removes
-the complexity.
-
-Also, as we'll see below, the reason for having an IOMMU, and the benefits provided,
-are similar to those obtained by having an MMU.
-
-### Contiguity of memory
-
-When you allocate a large chunk of memory (e.g. via **calloc()**),
-your process will, of course, see a large, contiguous virtual address range.
-The MMU creates the illusion of contiguous memory at the virtual addressing
-level, even though the MMU may choose to back that memory area with physically
-discontiguous memory at the physical address level.
-
-Furthermore, as processes allocate and deallocate memory, the mapping of
-physical memory to virtual address space tends to become more
-complex, encouraging more "swiss cheese" holes to appear (that is,
-more discontiguities in the mapping).
-
-Therefore, it's important to keep in mind that contiguous virtual addresses
-are not necessarily contiguous physical addresses, and indeed that contiguous
-physical memory becomes more precious over time.
-
-### Access controls
-
-Another benefit of the MMU is that processes are limited in their view of
-physical memory (for security and reliability reasons).
-The impact on drivers, though, is that a process has to specifically request
-a mapping from virtual address space to physical address space, and
-have the requisite privilege in order to do so.
-
-### IOMMU
-
-Contiguous physical memory is generally preferred.
-It's more efficient to do one transfer (with one source address and one
-destination address) than it is to set up and manage multiple individual
-transfers (which may require CPU intervention between each transfer in
-order to set up the next one).
-
-The IOMMU, if available, alleviates this problem by doing the same thing for
-the peripherals that the CPU's MMU does for the process &mdash; it gives the peripheral
-the illusion that it's dealing with a contiguous address space by
-mapping multiple discontiguous chunks into a virtually contiguous space.
-By limiting the mapping region, the IOMMU also provides security (in the same way as
-the MMU does), by preventing the peripheral from accessing memory that's not "in scope"
-for the current operation.
-
-### Tying it all together
-
-So, it may appear that you need to worry about virtual, physical, and device-physical
-address spaces when you are writing your driver.
-But that's not the case.
-
-## DMA and your driver
-
-Zircon provides a set of functions that allow you to cleanly deal with all of the
-above.
-The following work together:
-
-*   a Bus Transaction Initiator (**[BTI](../objects/bus_transaction_initiator.md)**), and
-*   a Virtual Memory Object (**[VMO](../objects/vm_object.md)**).
-
-The [BTI](../objects/bus_transaction_initiator.md)
-kernel object provides an abstraction of the model, and an API to deal with
-physical (or device-physical) addresses associated with
-[VMO](../objects/vm_object.md)s.
-
-In your driver's initialization, call
-**pci_get_bti()**
-to obtain a [BTI](../objects/bus_transaction_initiator.md) handle:
-
-```c
-zx_status_t pci_get_bti(const pci_protocol_t* pci,
-                        uint32_t index,
-                        zx_handle_t* bti_handle);
-```
-
-The **pci_get_bti()**
-function takes a `pci` protocol pointer (just like all the other **pci_...()** functions
-discussed above) and an `index` (reserved for future use, use `0`).
-It returns a [BTI](../objects/bus_transaction_initiator.md)
-handle through the `bti_handle` pointer argument.
-
-Next, you need a [VMO](../objects/vm_object.md).
-Simplistically, you can think of the [VMO](../objects/vm_object.md)
-as a pointer to a chunk of memory,
-but it's more than that &mdash; it's a kernel object that represents a set
-of virtual pages (that may or may not have physical pages committed to them),
-which can be mapped into the virtual address space of the driver process.
-(It's even more than that, but that's a discussion for a different chapter.)
-
-Ultimately, these pages serve as the source or destination of the DMA transfer.
-
-There are two functions,
-[**zx_vmo_create()**](../syscalls/vmo_create.md)
-and
-[**zx_vmo_create_contiguous()**](../syscalls/vmo_create_contiguous.md)
-that allocate memory and bind it to a [VMO](../objects/vm_object.md):
-
-```c
-zx_status_t zx_vmo_create(uint64_t size,
-                          uint32_t options,
-                          zx_handle_t* out);
-
-zx_status_t zx_vmo_create_contiguous(zx_handle_t bti,
-                                     size_t size,
-                                     uint32_t alignment_log2,
-                                     zx_handle_t* out);
-```
-
-As you can see, they both take a `size` parameter indicating the number of bytes required,
-and they both return a [VMO](../objects/vm_object.md) (via `out`).
-They both allocate virtually contiguous pages, for a given size.
-
-> Note that this differs from the standard C library memory allocation functions,
-> (e.g., **malloc()**), which allocate virtually contiguous memory, but without
-> regard to page boundaries. Two small **malloc()** calls in a row might allocate
-> two memory regions from the *same* page, for instance, whereas
-> the [VMO](../objects/vm_object.md)
-> creation functions will always allocate memory starting with a *new* page.
-
-The
-[**zx_vmo_create_contiguous()**](../syscalls/vmo_create_contiguous.md)
-function does what
-[**zx_vmo_create()**](../syscalls/vmo_create.md)
-does, *and* ensures that the pages are suitably
-organized for use with the specified [BTI](../objects/bus_transaction_initiator.md)
-(which is why it needs the [BTI](../objects/bus_transaction_initiator.md) handle).
-It also features an `alignment_log2` parameter that can be used to specify a minimum
-alignment requirement.
-As the name suggests, it must be an integer power of 2 (with the value `0` indicating
-page aligned).
-
-At this point, you have two "views" of the allocated memory:
-
-*   one contiguous virtual address space that represents memory
-    from the point of view of the driver, and
-*   a set of (possibly contiguous, possibly committed) physical pages
-    for use by the peripheral.
-
-Before using these pages, you need to ensure that they are present in memory (that is,
-"committed" &mdash; the physical pages are accessible to your process), and that the
-peripheral has access to them (via the IOMMU if present).
-You will also need the addresses of the pages (from the point of view of the device)
-so that you can program the DMA controller on your device to access them.
-
-The
-[**zx_bti_pin()**](../syscalls/bti_pin.md)
-function is used to do all that:
-
-```c
-#include <zircon/syscalls.h>
-
-zx_status_t zx_bti_pin(zx_handle_t bti, uint32_t options,
-                       zx_handle_t vmo, uint64_t offset, uint64_t size,
-                       zx_paddr_t* addrs, size_t addrs_count,
-                       zx_handle_t* pmt);
-```
-
-There are 8 parameters to this function:
-
-Parameter       | Purpose
-----------------|------------------------------------
-`bti`           | the [BTI](../objects/bus_transaction_initiator.md) for this peripheral
-`options`       | options (see below)
-`vmo`           | the [VMO](../objects/vm_object.md) for this memory region
-`offset`        | offset from the start of the [VMO](../objects/vm_object.md)
-`size`          | total number of bytes in [VMO](../objects/vm_object.md)
-`addrs`         | list of return addresses
-`addrs_count`   | number of elements in `addrs`
-`pmt`           | returned [PMT](../objects/pinned_memory_token.md) (see below)
-
-The `addrs` parameter is a pointer to an array of `zx_paddr_t` that you supply.
-This is where the peripheral addresses for each page are returned into.
-The array is `addrs_count` elements long, and must match the count of
-elements expected from
-[**zx_bti_pin()**](../syscalls/bti_pin.md).
-
-> The values written into `addrs` are suitable for programming the peripheral's
-> DMA controller &mdash; that is, they take into account any translations that
-> may be performed by an IOMMU, if present.
-
-On a technical note, the other effect of
-[**zx_bti_pin()**](../syscalls/bti_pin.md)
-is that the kernel will ensure those pages are not decommitted
-(i.e., moved or reused) while pinned.
-
-The `options` argument is actually a bitmap of options:
-
-Option                  | Purpose
-------------------------|--------------------------------
-`ZX_BTI_PERM_READ`      | pages can be read by the peripheral (written by the driver)
-`ZX_BTI_PERM_WRITE`     | pages can be written by the peripheral (read by the driver)
-`ZX_BTI_COMPRESS`       | (see "Minimum contiguity property," below)
-
-For example, refer to the diagrams above showing "Device #3".
-If an IOMMU is present, `addrs` would contain `0`, `1`, `2`, and `3` (that is,
-the device-physical addresses).
-If no IOMMU is present, `addrs` would contain `109`, `110`, `101`, and `119` (that is,
-the physical addresses).
-
-### Permissions
-
-Keep in mind that the permissions are from the perspective
-*of the peripheral*, and not the driver.
-For example, in a block device **write** operation, the device **reads** from memory pages and
-therefore the driver specifies `ZX_BTI_PERM_READ`, and vice versa in the block device read.
-
-### Minimum contiguity property
-
-By default, each address returned through `addrs` is one page long.
-Larger chunks may be requested by setting the `ZX_BTI_COMPRESS` option
-in the `options` argument.
-In that case, the length of each entry returned corresponds to the "minimum contiguity" property.
-While you can't set this property, you can read it via
-[**zx_object_get_info()**](../syscalls/object_get_info.md).
-Effectively, the minimum contiguity property is a guarantee that
-[**zx_bti_pin()**](../syscalls/bti_pin.md)
-will always be able to return addresses that are contiguous for at least that many bytes.
-
-For example, if the property had the value 1MB, then a call to
-[**zx_bti_pin()**](../syscalls/bti_pin.md)
-with a requested size of 2MB would return at most two physically-contiguous runs.
-If the requested size was 2.5MB, it would return at most three physically-contiguous runs,
-and so on.
-
-### Pinned Memory Token (**PMT**)
-
-[**zx_bti_pin()**](../syscalls/bti_pin.md) returns a Pinned Memory Token
-(**[PMT](../objects/pinned_memory_token.md)**)
-upon success in the *pmt* argument.
-The driver must call [**zx_pmt_unpin()**](../syscalls/pmt_unpin.md) when the device is done with
-the memory transaction to unpin and revoke access to the memory pages by the device.
-
-## Advanced topics
-
-### Cache Coherency
-
-On fully DMA-coherent architectures, hardware ensures the data in the CPU cache is the same
-as the data in main memory without software intervention. Not all architectures are
-DMA-coherent. On these systems, the driver must ensure the CPU cache is made coherent by
-invoking appropriate cache operations on the memory range before performing DMA operations,
-so that no stale data will be accessed.
-
-To invoke cache operations on the memory represented by [VMO](../objects/vm_object.md)s, use the
-[**zx_vmo_op_range()**](../syscalls/vmo_op_range.md)
-syscall.
-Prior to a peripheral-read
-(driver-write) operation, clean the cache using `ZX_VMO_OP_CACHE_CLEAN` to write out dirty
-data to main memory. Prior to a peripheral-write (driver-read), mark the cache lines
-as invalid using `ZX_VMO_OP_CACHE_INVALIDATE` to ensure data is fetched from main
-memory on the next access.
-
diff --git a/docs/ddk/overview.md b/docs/ddk/overview.md
deleted file mode 100644
index 37bdd3f..0000000
--- a/docs/ddk/overview.md
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-# Zircon Driver Development Kit
-
-* [Device Model](device-model.md)
-* [Device Ops](device-ops.md)
-* [Driver Development](driver-development.md)
-* [Platform Bus](platform-bus.md)
-* [Device Firmware](firmware.md)
-
-## Tutorial presentation
-
-* [Driver Development Kit tutorial](ddk-tutorial.md)
-
diff --git a/docs/ddk/platform-bus.md b/docs/ddk/platform-bus.md
deleted file mode 100644
index 5b7a776..0000000
--- a/docs/ddk/platform-bus.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# Zircon's Platform Bus
-
-## Introduction
-
-The term **platform bus** refers to a specific Zircon driver with source code located at
-[system/dev/bus/platform/](../../system/dev/bus/platform/)).
-However this term also refers to the framework that manages lower level drivers on arm64
-SOC-based platforms. To differentiate the two below, we will use *platform bus driver*
-when referring to the specific driver, and *platform bus* when referring to the general framework.
-
-The platform bus is currently not used on x86 platforms, since ACPI performs a similar role on x86.
-On platforms that use it, the platform bus is represented in the device tree as `/sys`.
-
-The platform bus as a whole contains several types of drivers:
-
-- The **platform bus driver**, which manages the platform bus. This is a generic driver
-with no hardware specific functionality. The platform bus driver is started automatically
-by the devmgr when the system boots.
-
-- The **board driver**, which is the first driver loaded by the platform bus driver.
-The board driver contains all the platform specific information needed by the platform bus
-and controls what other drivers will be loaded by the platform bus.
-The platform bus driver uses information from the bootloader to bind the correct board driver
-for the platform it is running on.
-
-- The **platform device drivers** are the foundations for the higher level drivers in Zircon.
-These drivers provide the lowest level of support for a particular feature, like USB,
-eMMC or NAND storage, etc., with higher level drivers loading on top of that.
-
-- The **protocol implementation drivers**, such as GPIO or I2C, which provide protocol
-support as resources to platform device drivers. These drivers run in the same devhost as the
-platform bus driver. Protocol implementation drivers can also implement vendor or SOC-specific
-protocols and make them available to platform devices using a **proxy client driver** (see below).
-
-- The **proxy client driver** is a driver that implements client support for a vendor or
-SOC-specific protocol. This driver loads in the platform device's devhost and is responsible
-for proxying its protocol to the protocol implementation driver.
-The Amlogic Canvas driver at [system/dev/display/aml-canvas/](../../system/dev/display/aml-canvas/)
-provides a simple example of how the proxying works.
-
-- Finally, the **platform proxy driver** a companion to the platform bus driver that loads
-into the platform device devhosts. This driver supports proxying the platform device protocol
-and other resource protocols from the platform device driver to the platform bus driver and
-protocol implementation drivers. This is needed because the platform device drivers run in a
-different devhost process than the platform bus driver and the protocol implementation drivers.
-
-![Zircon Platform Bus diagram](platform-bus.png)
-Source: [https://goto.google.com/zircon-platform-bus-diagram](https://goto.google.com/zircon-platform-bus-diagram)
-
-## Initialization
-
-The platform bus driver is started automatically by the devmgr at boot.
-Since the platform bus driver is a generic driver that contains no information about the
-platform it is running on, it first loads the board driver, which handles platform specific logic.
-To determine which board driver to load, platform bus driver reads the `BOOTDATA_PLATFORM_ID`
-record from the [ZBI data](../../system/public/zircon/boot/image.h) passed from the bootloader.
-It then adds a device with protocol `ZX_PROTOCOL_PBUS` with the
-`BIND_PLATFORM_DEV_VID` and `BIND_PLATFORM_DEV_PID` binding variables set to the vid and did
-from the platform data record. The correct board driver will bind to this device and continue
-the platform bus initialization process..
-
-The board driver uses the platform bus protocol to communicate with the platform bus driver.
-After it does its own initialization, the board driver then uses the `pbus_protocol_device_add()`
-API to load protocol implementation drivers for GPIO, I2C and other low level SOC protocols to be
-provided to the platform device drivers.
-After the protocol implementation drivers are loaded and have registered their protocols
-via the pbus_register_protocol() API, the board driver will call pbus_device_add() to create
-platform devices, which will result in platform device drivers loading each in its own devhost.
-After the platform devices are created, the platform bus initialization is complete.
-
-## Platform Device Protocol
-
-The [platform device protocol](../../system/ulib/ddk/include/ddk/protocol/platform-device.h)
-(`ZX_PROTOCOL_PDEV`) is the main protocol provided by the platform bus to
-platform device drivers. This protocol provides access to resources like MMIO ranges, interrupts,
-BTIs, and SMC ranges to the platform device driver. Rather than requesting MMIOs and interrupts by
-physical addresses or IRQ numbers, these resource are requested by a zero-based index.
-This allows us to have platform device drivers for particular IP that works across multiple
-platforms, since the knowledge of the exact MMIO addresses and interrupt numbers do not need to be
-known by the driver. Instead the board driver configures the MMIO addresses and IRQ numbers in the
-`pbus_dev_t` struct passed via `pbus_add_device()`.
-
-The platform device protocol is also available to protocol implementation drivers.
-For example, a GPIO driver may use the platform device protocol to access its MMIO and interrupts.
-This allows protocol implementation drivers to be shared among different SOC variants,
-where the functionality may be identical but the MMIO addresses and interrupt numbers may be
-different.
-
-The platform device protocol can also be made available to children or indirect descendants
-of platform devices. This solves the use case where children or grandchildren of platform devices
-have drivers that also need to access platform bus resources like MMIO regions and interrupts.
-
-## Resource Protocols
-
-In Zircon, DDK protocols are typically provided as part of the device parent/child relationship.
-The driver for the parent device implements a protocol and the driver for the child device is a
-client of that protocol. However, some protocols don't fit well with the parent/child device
-relationship.
-For example, a driver may need to access one or more GPIOs, but the GPIO is unrelated to the
-main function of the driver. For cases like this, the platform bus can provide protocols to
-platform devices outside of the parent/child relationship.
-
-In addition to MMIOs and interrupts, the board driver can assign GPIOs and I2C buses to platform
-devices via the `pbus_dev_t` struct passed via `pbus_add_device()`.
-The platform device drivers can call `device_get_protocol()` to retrieve these protocols
-and then work with the GPIO pins and I2C buses assigned by the board driver.
-In these protocols, the platform device driver uses zero-based indices to refer to these resources
-rather than raw GPIO pin numbers or I2C bus and address numbers.
-This allows platform device drivers to be more easily reused across different platforms.
-
-## Platform Bus Protocol
-
-The [platform bus protocol](../../system/ulib/ddk/include/ddk/protocol/platform-bus.h)
-(`ZX_PROTOCOL_PBUS`) is used by board drivers and protocol implementation drivers
-to communicate with the platform bus driver. It is only available to drivers running in the
-platform bus's devhost (in particular, it is not accessible to platform device drivers).
-The purpose of this protocol is for the board driver to load protocol implementation drivers
-and to start platform device drivers. It is also used by protocol implementation drivers to
-register their protocols with the platform bus so their protocols can be made available
-to platform device drivers.
-
-## Platform Proxy Protocol
-
-The [platform proxy protocol](../../system/ulib/ddk/include/ddk/protocol/platform-proxy.h)
-(`ZX_PROTOCOL_PLATFORM_PROXY`) is used by the proxy client drivers that proxy protocols to
-protocol implementation drivers. It provides support for the proxy client driver to register
-its protocol with the platform proxy driver and for proxying its protocol to the
-protocol implementation driver over a channel.
diff --git a/docs/ddk/platform-bus.png b/docs/ddk/platform-bus.png
deleted file mode 100644
index 2589c85..0000000
--- a/docs/ddk/platform-bus.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/ramdisk.md b/docs/ddk/ramdisk.md
deleted file mode 100644
index e5b0d8b..0000000
--- a/docs/ddk/ramdisk.md
+++ /dev/null
@@ -1,423 +0,0 @@
-
-
-<!--
-    (C) Copyright 2018 The Fuchsia Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style license that can be
-    found in the LICENSE file.
--->
-
-# RAMdisk Device
-
-This document is part of the [Driver Development Kit tutorial](ddk-tutorial.md) documentation.
-
-## Overview
-
-In this section, we'll examine a simplified RAM-disk driver.
-
-This driver introduces:
-
-*   the block protocol's **query()** and **queue()** ops
-*   Virtual Memory Address Regions ([VMAR](../objects/vm_address_region.md)s)
-    and Virtual Memory Objects ([VMO](../objects/vm_object.md)s)
-
-The source is in `//zircon/system/dev/sample/ramdisk/demo-ramdisk.c`.
-
-As with all drivers, the first thing to look at is how the driver initializes itself:
-
-```c
-static zx_status_t ramdisk_driver_bind(void* ctx, zx_device_t* parent) {
-    zx_status_t status = ZX_OK;
-
-    // (1) create the device context block
-    ramdisk_device_t* ramdev = calloc(1, sizeof((*ramdev)));
-    if (ramdev == NULL) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    // (2) create a VMO
-    status = zx_vmo_create(RAMDISK_SIZE, 0, &ramdev->vmo);
-    if (status != ZX_OK) {
-        goto cleanup;
-    }
-
-    // (3) map the VMO into our address space
-    status = zx_vmar_map(zx_vmar_root_self(), 0, ramdev->vmo, 0, RAMDISK_SIZE,
-                         ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE, &ramdev->mapped_addr);
-    if (status != ZX_OK) {
-        goto cleanup;
-    }
-
-    // (4) add the device
-    device_add_args_t args = {
-        .version = DEVICE_ADD_ARGS_VERSION,
-        .name = "demo-ramdisk",
-        .ctx = ramdev,
-        .ops = &ramdisk_proto,
-        .proto_id = ZX_PROTOCOL_BLOCK_IMPL,
-        .proto_ops = &block_ops,
-    };
-
-    if ((status = device_add(parent, &args, &ramdev->zxdev)) != ZX_OK) {
-        ramdisk_release(ramdev);
-    }
-    return status;
-
-    // (5) clean up after ourselves
-cleanup:
-    zx_handle_close(ramdev->vmo);
-    free(ramdev);
-    return status;
-}
-
-static zx_driver_ops_t ramdisk_driver_ops = {
-    .version = DRIVER_OPS_VERSION,
-    .bind = ramdisk_driver_bind,
-};
-
-ZIRCON_DRIVER_BEGIN(ramdisk, ramdisk_driver_ops, "zircon", "0.1", 1)
-    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_MISC_PARENT),
-ZIRCON_DRIVER_END(ramdisk)
-
-```
-
-At the bottom, you can see that this driver binds to a `ZX_PROTOCOL_MISC_PARENT` type of
-protocol, and provides `ramdisk_driver_ops` as the list of operations supported.
-This is no different than any of the other drivers we've seen so far.
-
-The binding function, **ramdisk_driver_bind()**, does the following:
-
-1.  Allocates the device context block.
-2.  Creates a [VMO](../objects/vm_object.md).
-    The [VMO](../objects/vm_object.md)
-    is a kernel object that represents a chunk of memory.
-    In this simplified RAM-disk driver, we're creating a
-    [VMO](../objects/vm_object.md) that's `RAMDISK_SIZE`
-    bytes long.
-    This chunk of memory **is** the RAM-disk &mdash; that's where the data is stored.
-    The [VMO](../objects/vm_object.md)
-    creation call, [**zx_vmo_create()**](../syscalls/vmo_create.md),
-    returns the [VMO](../objects/vm_object.md) handle through
-    its third argument, which is a member in our context block.
-3.  Maps the [VMO](../objects/vm_object.md) into our address space via
-    [**zx_vmar_map()**](../syscalls/vmar_map.md).
-    This function returns a pointer to a
-    [VMAR](../objects/vm_address_region.md)
-    that points to the entire
-    [VMO](../objects/vm_object.md) (because
-    we specified `RAMDISK_SIZE` as the mapping size argument) and gives us read and
-    write access (because of the `ZX_VM_FLAG_PERM_*` flags).
-    The pointer is stored in our context block's `mapped_addr` member.
-4.  Adds our device via **device_add()**,
-    just like all the examples we've seen above.
-    The difference here, though is that we see two new members: `proto_id` and
-    `proto_ops`.
-    These are defined as "optional custom protocol" members.
-    As usual, we store the newly created device in the `zxdev` member of our
-    context block.
-5.  Cleans up resources if there were any problems along the way.
-
-For completeness, here's the context block:
-
-```c
-typedef struct ramdisk_device {
-    zx_device_t*    zxdev;
-    uintptr_t       mapped_addr;
-    uint32_t        flags;
-    zx_handle_t     vmo;
-    bool            dead;
-} ramdisk_device_t;
-```
-
-The fields are:
-
-Type            | Field         | Description
-----------------|---------------|----------------
-`zx_device_t*`  | zxdev         | the ramdisk device
-`uintptr_t`     | mapped_addr   | address of the [VMAR](../objects/vm_address_region.md)
-`uin32_t`       | flags         | device flags
-`zx_handle_t`   | vmo           | a handle to our [VMO](../objects/vm_object.md)
-`bool`          | dead          | indicates if the device is still alive
-
-### Operations
-
-Where this device is different from the others that we've seen, though,
-is that the **device_add()**
-function adds two sets of operations; the "regular" one, and an
-optional "protocol specific" one:
-
-```c
-static zx_protocol_device_t ramdisk_proto = {
-    .version = DEVICE_OPS_VERSION,
-    .ioctl = ramdisk_ioctl,
-    .get_size = ramdisk_getsize,
-    .unbind = ramdisk_unbind,
-    .release = ramdisk_release,
-};
-
-static block_protocol_ops_t block_ops = {
-    .query = ramdisk_query,
-    .queue = ramdisk_queue,
-};
-```
-
-The `zx_protocol_device_t` one handles control ops (**ramdisk_ioctl()**), device size
-queries (**ramdisk_getsize()**), and device cleanups (**ramdisk_unbind()** and
-**ramdisk_release()**).
-
-> @@@ should I discuss the ioctls, or were they to have been removed as part of the simplification?
-
-The `block_protocol_ops_t` one contains protocol operations particular to the
-block protocol.
-We bound these to the device in the `device_add_args_t` structure (step (4) above) via
-the `.proto_ops` field.
-We also set the `.proto_id` field to `ZX_PROTOCOL_BLOCK_IMPL` &mdash; this is what
-identifies this driver as being able to handle block protocol operations.
-
-Let's tackle the trivial functions first:
-
-```c
-static zx_off_t ramdisk_getsize(void* ctx) {
-    return RAMDISK_SIZE;
-}
-
-static void ramdisk_unbind(void* ctx) {
-    ramdisk_device_t* ramdev = ctx;
-    ramdev->dead = true;
-    device_remove(ramdev->zxdev);
-}
-
-static void ramdisk_release(void* ctx) {
-    ramdisk_device_t* ramdev = ctx;
-
-    if (ramdev->vmo != ZX_HANDLE_INVALID) {
-        zx_vmar_unmap(zx_vmar_root_self(), ramdev->mapped_addr, RAMDISK_SIZE);
-        zx_handle_close(ramdev->vmo);
-    }
-    free(ramdev);
-}
-
-static void ramdisk_query(void* ctx, block_info_t* bi, size_t* bopsz) {
-    ramdisk_get_info(ctx, bi);
-    *bopsz = sizeof(block_op_t);
-}
-```
-
-**ramdisk_getsize()** is the easiest &mdash; it simply returns the size of the resource, in bytes.
-In our simplified RAM-disk driver, this is hardcoded as a `#define` near the top of the file.
-
-Next, **ramdisk_unbind()** and **ramdisk_release()** work together.
-When the driver is being shut down, the **ramdisk_unbind()** hook is called.
-It sets the `dead` flag to indicate that the driver is shutting down (this is checked
-in the **ramdisk_queue()** handler, below).
-It's expected that the driver will finish up any I/O operations that are in progress (there
-won't be any in our RAM-disk), and it should call
-**device_remove()**
-to remove itself from the parent.
-
-After **device_remove()** is called,
-the driver's **ramdisk_release()** will be called.
-Here we unmap the [VMAR](../objects/vm_address_region.md),
-via [**zx_vmar_unmap()**](../syscalls/vmar_unmap.md), and close the
-[VMO](../objects/vm_object.md),
-via [**zx_handle_close()**](../syscalls/handle_close.md).
-As our final act, we release the device context block.
-At this point, the device is finished.
-
-### Block Operations
-
-The **ramdisk_query()** function is called by the block protocol in order to get
-information about the device.
-There's a data structure (the `block_info_t`) that's filled out by the driver:
-
-```c
-// from .../system/public/zircon/device/block.h:
-typedef struct {
-    uint64_t    block_count;        // The number of blocks in this block device
-    uint32_t    block_size;         // The size of a single block
-    uint32_t    max_transfer_size;  // Max size in bytes per transfer.
-                                    // May be BLOCK_MAX_TRANSFER_UNBOUNDED if there
-                                    // is no restriction.
-    uint32_t    flags;
-    uint32_t    reserved;
-} block_info_t;
-
-// our helper function
-static void ramdisk_get_info(void* ctx, block_info_t* info) {
-    ramdisk_device_t* ramdev = ctx;
-    memset(info, 0, sizeof(*info));
-    info->block_size = BLOCK_SIZE;
-    info->block_count = BLOCK_COUNT;
-    // Arbitrarily set, but matches the SATA driver for testing
-    info->max_transfer_size = BLOCK_MAX_TRANSFER_UNBOUNDED;
-    info->flags = ramdev->flags;
-}
-```
-
-In this simplified driver, the `block_size`, `block_count`, and `max_transfer_size`
-fields are hardcoded numbers.
-
-The `flags` member is used to identify if the device is read-only (`BLOCK_FLAG_READONLY`,
-otherwise it's read/write), removable (`BLOCK_FLAG_REMOVABLE`, otherwise it's not
-removable) or has a bootable partition (`BLOCK_FLAG_BOOTPART`, otherwise it doesn't).
-
-The final value that **ramdisk_query()** returns is the "block operation size" value
-through the pointer to `bopsz`.
-This is a host-maintained block that's big enough to contain the `block_op_t` *plus*
-any additional data the driver wants (appended to the `block_op_t`), like an
-extended context block.
-
-### Reading and writing
-
-Finally, it's time to discuss the actual "block" data transfers; that is, how does
-data get read from / written to the device?
-
-The second block protocol handler, **ramdisk_queue()**, performs that function.
-
-As you might suspect from the name, it's intended that this hook starts whatever
-transfer operation (a read or a write) is requested, but doesn't require that
-the operation completes before the hook returns.
-This is a little like what we saw in earlier chapters
-in the **read()** and **write()** handlers
-for devices like `/dev/misc/demo-fifo` &mdash; there, we could either return
-data immediately, or put the client to sleep, waking it up later when data (or room
-for data) became available.
-
-With **ramdisk_queue()** we get passed a block operations structure that indicates
-the expected operation: `BLOCK_OP_READ`, `BLOCK_OP_WRITE`, or `BLOCK_OP_FLUSH`.
-The structure also contains additional fields telling us the offset and size of
-the transfer (from `//zircon/system/ulib/ddk/include/ddk/protocol/block.h`):
-
-```c
-// simplified from original
-struct block_op {
-    struct {
-        uint32_t    command;    // command and flags
-        uint32_t    extra;      // available for temporary use
-        zx_handle_t vmo;        // vmo of data to read or write
-        uint32_t    length;     // transfer length in blocks (0 is invalid)
-        uint64_t    offset_dev; // device offset in blocks
-        uint64_t    offset_vmo; // vmo offset in blocks
-        uint64_t*   pages;      // optional physical page list
-    } rw;
-
-    void (*completion_cb)(block_op_t* block, zx_status_t status);
-};
-```
-
-The transfer takes place to or from the `vmo` in the structure &mdash; in the case of
-a read, we transfer data to the [VMO](../objects/vm_object.md),
-and vice versa for a write.
-The `length` indicates the number of *blocks* (not bytes) to transfer, and the
-two offset fields, `offset_dev` and `offset_vmo`, indicate the relative offsets (again,
-in blocks not bytes) into the device and the [VMO](../objects/vm_object.md)
-of where the transfer should take place.
-
-The implementation is straightforward:
-
-```c
-static void ramdisk_queue(void* ctx, block_op_t* bop) {
-    ramdisk_device_t* ramdev = ctx;
-
-    // (1) see if we should still be handling requests
-    if (ramdev->dead) {
-        bop->completion_cb(bop, ZX_ERR_IO_NOT_PRESENT);
-        return;
-    }
-
-    // (2) what operation are we performing?
-    switch ((bop->command &= BLOCK_OP_MASK)) {
-    case BLOCK_OP_READ:
-    case BLOCK_OP_WRITE: {
-        // (3) perform validation common for both
-        if ((bop->rw.offset_dev >= BLOCK_COUNT)
-            || ((BLOCK_COUNT - bop->rw.offset_dev) < bop->rw.length)
-            || bop->rw.length * BLOCK_SIZE > MAX_TRANSFER_BYTES) {
-            bop->completion_cb(bop, ZX_ERR_OUT_OF_RANGE);
-            return;
-        }
-
-        // (4) compute address
-        void* addr = (void*) ramdev->mapped_addr + bop->rw.offset_dev * BLOCK_SIZE;
-        zx_status_t status;
-
-        // (5) now perform actions specific to each
-        if (bop->command == BLOCK_OP_READ) {
-            status = zx_vmo_write(bop->rw.vmo, addr, bop->rw.offset_vmo * BLOCK_SIZE,
-                                  bop->rw.length * BLOCK_SIZE);
-        } else {
-            status = zx_vmo_read(bop->rw.vmo, addr, bop->rw.offset_vmo * BLOCK_SIZE,
-                                 bop->rw.length * BLOCK_SIZE);
-        }
-
-        // (6) indicate completion
-        bop->completion_cb(bop, status);
-        break;
-        }
-
-    case BLOCK_OP_FLUSH:
-        bop->completion_cb(bop, ZX_OK);
-        break;
-
-    default:
-        bop->completion_cb(bop, ZX_ERR_NOT_SUPPORTED);
-        break;
-    }
-}
-```
-
-As usual, we establish a context block at the top by casting the `ctx` argument.
-The `bop` argument is the "block operation" structure we saw above.
-The `command` field indicates what the **ramdisk_queue()** function should do.
-
-In step (1), we check to see if we've set the `dead` flag (**ramdisk_unbind()**
-sets it when required).
-If so, it means that our device is no longer accepting new requests, so we return
-`ZX_ERR_IO_NOT_PRESENT` in order to encourage clients to close the device.
-
-In step (3), we handle some common validation for both read and write &mdash;
-neither should allow offsets that exceed the size of the device, nor transfer
-more than the maximum transfer size.
-
-Similarly, in step (4) we compute the device address (that is, we establish a
-pointer to our [VMAR](../objects/vm_address_region.md)
-that's offset by the appropriate number of blocks as per the request).
-
-In step (5) we perform either a [**zx_vmo_read()**](../syscalls/vmo_read.md)
-or a [**zx_vmo_write()**](../syscalls/vmo_write.md), depending
-on the command.
-This is what transfers data between a pointer within our
-[VMAR](../objects/vm_address_region.md) (`addr`)
-and the client's [VMO](../objects/vm_object.md) (`bop->rw.vmo`).
-Notice that in the read case, we *write* to the [VMO](../objects/vm_object.md),
-and in the write case, we *read* from the [VMO](../objects/vm_object.md).
-
-Finally, in step (6) (and the other two cases), we signal completion via the
-`completion` callback in the block ops structure.
-
-The interesting thing about completion is that:
-
-*   it doesn't have to happen right away &mdash; we could have queued this
-    operation and signalled completion some time later,
-*   it is allowed to be called before this function returns (like we did).
-
-The last point simply means that we are not *forced* to defer completion until
-after the queuing function returns.
-This allows us to complete the operation directly in the function.
-For our trivial RAM-disk example, this makes sense &mdash; we have the ability to
-do the data transfer to or from media instantly; no need to defer.
-
-## How is the real one more complicated?
-
-The RAM-disk presented above is somewhat simplified from the "real" RAM-disk
-device (present at `//zircon/system/dev/block/ramdisk/ramdisk.c`).
-
-The real one adds the following functionality:
-
-*   dynamic device creation via new VMO
-*   ability to use an existing VMO
-*   background thread
-*   sleep mode
-
-> @@@ how much, if anything, do we want to say about this one? I found the
-> dynamic device creation of interest, for example...
-
diff --git a/docs/ddk/reference.md b/docs/ddk/reference.md
deleted file mode 100644
index 21ecb6c..0000000
--- a/docs/ddk/reference.md
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-<!--
-    (C) Copyright 2018 The Fuchsia Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style license that can be
-    found in the LICENSE file.
--->
-
-# Reference
-
-This document is part of the [Driver Development Kit tutorial](ddk-tutorial.md) documentation.
-
-## Overview
-
-@@@ Notes Only @@@
-
-What it sounds like :-)
-
diff --git a/docs/ddk/simple-000-cropped.png b/docs/ddk/simple-000-cropped.png
deleted file mode 100644
index 464ffd4..0000000
--- a/docs/ddk/simple-000-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/simple-001-cropped.png b/docs/ddk/simple-001-cropped.png
deleted file mode 100644
index d83a311..0000000
--- a/docs/ddk/simple-001-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/simple-002-cropped.png b/docs/ddk/simple-002-cropped.png
deleted file mode 100644
index ad6ce4b..0000000
--- a/docs/ddk/simple-002-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/simple-003-cropped.png b/docs/ddk/simple-003-cropped.png
deleted file mode 100644
index 407cdc4..0000000
--- a/docs/ddk/simple-003-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/simple-008-cropped.png b/docs/ddk/simple-008-cropped.png
deleted file mode 100644
index 14241c0..0000000
--- a/docs/ddk/simple-008-cropped.png
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/simple.md b/docs/ddk/simple.md
deleted file mode 100644
index dd7036a..0000000
--- a/docs/ddk/simple.md
+++ /dev/null
@@ -1,1282 +0,0 @@
-<!--
-    (C) Copyright 2018 The Fuchsia Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style license that can be
-    found in the LICENSE file.
--->
-
-# Simple Drivers
-
-This document is part of the [Driver Development Kit tutorial](ddk-tutorial.md) documentation.
-
-## Overview
-
-In this chapter, we're going to learn about the fundamentals of drivers.
-We'll progress from simple through to moderately complex, with each driver illustrating a
-specific set of concepts as follows:
-
-`dev/misc/demo-null` and `dev/misc/demo-zero`:
-
-*   trivial, "no-state" sink / source drivers, used to explain the basics, like how to handle a
-    client's **read()** and **write()** requests.
-
-`dev/misc/demo-number`:
-
-*   a driver that returns an ASCII number, illustrates per-device context, one-shot **read()**
-    operation, and introduces FIDL-based control operations.
-
-`dev/misc/demo-multi`:
-
-*   a driver with multiple sub-devices.
-
-`dev/misc/demo-fifo`:
-
-*   shows more complex device state, examines partial **read()** and **write()** operations, and
-    introduces state signalling to enable blocking I/O.
-
-For reference, the source code for all of these drivers is in the
-`//zircon/system/dev/sample` directory.
-
-## Registration
-
-A system process called the device manager (`devmgr` henceforth) is responsible for device drivers.
-During initialization, it searches `/boot/driver` and `/system/driver` for drivers.
-<!-- @@@ TODO Brian says that /system is going away as we transition to a package-based
-world, at which point these drivers will be provided by the package manager in garnet -->
-These drivers are implemented as Dynamic Shared Objects (**DSO**s), and provide
-two items of interest:
-
-*   a set of instructions for `devmgr` to use when evaluating driver binding, and
-*   a binding function.
-
-Let's look at the bottom of `demo-null.c` in the `dev/sample/null` directory:
-
-```c
-static zx_driver_ops_t demo_null_driver_ops = {
-    .version = DRIVER_OPS_VERSION,
-    .bind = null_bind,
-};
-
-ZIRCON_DRIVER_BEGIN(demo_null_driver, demo_null_driver_ops, "zircon", "0.1", 1)
-    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_MISC_PARENT),
-ZIRCON_DRIVER_END(demo_null_driver)
-```
-<!-- @@@ alainv sez these macros are being deprecated in favour of a Driver Binding Language -->
-
-The C preprocessor macros `ZIRCON_DRIVER_BEGIN` and `ZIRCON_DRIVER_END` delimit
-an ELF note section that's created in the DSO.
-This section contains one or more statements that are evaluated by `devmgr`.
-
-In the above, the macro `BI_MATCH_IF` is a condition that evaluates to `true` if
-the device has `BIND_PROTOCOL` equal to `ZX_PROTOCOL_MISC_PARENT`.
-A `true` evaluation causes `devmgr` to then bind the driver, using the binding ops
-provided in the `ZIRCON_DRIVER_BEGIN` macro.
-
-We can ignore this "glue" for now, and just note that this part of the code:
-
-*   tells `devmgr` that this driver can be bound to devices requiring the
-    `ZX_PROTOCOL_MISC_PARENT` protocol, and
-*   contains a pointer to the `zx_drivers_ops_t` table that lists the
-    functions provided by this DSO.
-
-To initialize the device, `devmgr` calls the binding function **null_bind()**
-through the `.bind` member (also in `demo-null.c`):
-
-```c
-static zx_protocol_device_t null_device_ops = {
-    .version = DEVICE_OPS_VERSION,
-    .read = null_read,
-    .write = null_write,
-};
-
-zx_status_t null_bind(void* ctx, zx_device_t* parent) {
-    device_add_args_t args = {
-        .version = DEVICE_ADD_ARGS_VERSION,
-        .name = "demo-null",
-        .ops = &null_device_ops,
-    };
-
-    return device_add(parent, &args, NULL);
-}
-```
-
-The binding function is responsible for "publishing" the device by calling
-**device_add()** with
-a pointer to the parent device, and an arguments structure.
-
-The new device is bound relative to the parent's pathname &mdash; notice how we pass just
-`"demo-null"` in the `.name` member above.
-
-The `.ops` member is a pointer to a `zx_protocol_device_t` structure that lists the operations
-available for that device.
-We'll see these functions, **null_read()** and **null_write()**, below.
-
-After calling **device_add()**,
-the device name is registered, and the operations passed in
-the `.ops` member of the argument structure are bound to the device.
-A successful return from **null_bind()** indicates to `devmgr` that the driver is now
-associated with the device.
-
-At this point, our `/dev/misc/demo-null` device is ready to handle client requests,
-which means that it must:
-
-*   support **open()** and **close()**
-*   provide a **read()** handler that returns end-of-file (**EOF**) immediately
-*   provide a **write()** handler that discards all data sent to it
-
-No other functionality is required.
-
-## Reading data from the device
-
-In the `zx_protocol_device_t` structure `null_device_ops`, we indicated that we support reading
-and writing via the functions **null_read()** and **null_write()** respectively.
-
-The **null_read()** function provides reading:
-
-```c
-static zx_status_t
-null_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual) {
-    *actual = 0;
-    return ZX_OK;
-}
-```
-
-and ends up being called in response to a client's call to **read()**.
-
-Notice that there are two size-related arguments passed to the handler:
-
-Parameter   | Meaning
-------------|--------------------------------------------------------
-`count`     | Maximum number of bytes that the client can accept
-`actual`    | Actual number of bytes sent to the client
-
-The following diagram illustrates the relationship:
-
-![Figure: Relationship between client's **read()** and `/dev/misc/demo-null`'s
-**null_read()**](simple-000-cropped.png)
-
-That is, the available size of the client's buffer (here, `sizeof(buf)`), is passed as the `count`
-parameter to **null_read()**.
-Similarly, when **null_read()** indicates the number of bytes that it read (0 in our case), this
-appears as the return value from the client's **read()** function.
-
-> **NOTE:
-> The handler is expected to always return immediately.
-> By convention, indicating zero bytes in `*actual` indicates EOF**
-
-There are, of course, cases when the device doesn't have data immediately available, *AND* it's
-not an EOF situation.
-For example, a serial port may be waiting for more characters to arrive from the remote end.
-This is handled by a special notification, which we'll see below, in the `/dev/misc/demo-fifo`
-device.
-
-### Writing data to the device
-
-Writing data from the client to the device is almost identical, and is provided
-by **null_write()**:
-
-```c
-static zx_status_t
-null_write(void* ctx, const void* buf, size_t count, zx_off_t off, size_t* actual) {
-    *actual = count;
-    return ZX_OK;
-}
-```
-
-As with the **read()**, the **null_write()** is triggered by the client's call to **write()**:
-
-![Figure: Relationship between client's **write()** and `/dev/misc/demo-null`'s
-**null_write()**](simple-001-cropped.png)
-
-The client specifies the number of bytes they wish to transfer in their **write()** function, and
-this appears as the `count` parameter in the device's **null_write()** function.
-It's possible that the device may be full (not in the case of our `/dev/misc/demo-null`, though
-&mdash; it never fills up), so the device needs to tell the client how many bytes it actually
-wrote.
-This is done via the `actual` parameter, which shows up as the return value to the client's
-**write()** function.
-
-Note that our **null_write()** function includes the code:
-
-```c
-*actual = count;
-```
-
-This tells the client that all of their data was written.
-Of course, since this is the `/dev/misc/demo-null` device, the data doesn't actually *go*
-anywhere.
-
-> **NOTE:
-> Just like in the** **null_read()** **case, the handler must not block.**
-
-## What about **open()** and **close()**?
-
-We didn't provide an **open()** nor **close()** handler, and yet our device supports those
-operations.
-
-This is possible because any operation hooks that are not provided take on defaults.
-Most of the defaults simply return "not supported," but in the case of **open()** and **close()**
-the defaults provide adequate support for simple devices.
-
-## `/dev/misc/demo-zero`
-
-As you might imagine, the source code for the `/dev/misc/demo-zero` device is almost identical
-to that for `/dev/misc/demo-null`.
-From an operational point of view, `/dev/misc/demo-zero` is supposed to return an endless stream
-of zeros &mdash; for as long as the client cares to read.
-We don't support writing.
-
-Consider `/dev/misc/demo-zero`'s **zero_read()** function:
-
-```c
-static zx_status_t
-zero_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual) {
-    memset(buf, 0, count);
-    *actual = count;
-    return ZX_OK;
-}
-```
-
-The code sets the entire buffer `buf` to zero (the length is given by the client in the
-`count` argument),
-and tells the client that that many bytes are available (by setting `*actual` to the same number
-as the client request).
-
-## `/dev/misc/demo-number`
-
-Let's build a more complicated device, based on the concepts we learned above.
-We'll call it `/dev/misc/demo-number`, and its job is to return an ASCII string representing
- the next number in sequence.
-For example, the following might be a typical command-line session using the device:
-
-```shell
-$ cat /dev/misc/demo-number
-0
-$ cat /dev/misc/demo-number
-1
-$ cat /dev/misc/demo-number
-2
-```
-
-And so on.
-
-Whereas `/dev/misc/demo-null` returned EOF immediately, and `/dev/misc/demo-zero` returned
-a never-ending stream of zeros, `/dev/misc/demo-number` is kind of in the middle: it needs
-to return a short data sequence, and *then* return EOF.
-
-In the real world, the client could read one byte at a time, or it could ask for a large buffer's
-worth of data.
-For our initial version, we're going to assume that the client asks for a buffer that's "big
-enough" to get all the data at once.
-
-This means that we can take a shortcut.
-There's an offset parameter (`zx_off_t off`) that's passed as the 4th parameter to the **read()**
-handler function:
-
-```c
-static zx_status_t
-number_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual)
-```
-
-This indicates where the client would like to begin (or continue) reading from.
-The simplification that we're making here is that if the client has an offset of zero, it means
-that it's starting from the beginning, so we return as much data as the client can handle.
-However, if the offset isn't zero, we return `EOF`.
-
-Let's discuss the code (note that we're initially presenting a slightly simpler version than what's
-in the source directory):
-
-```c
-static int global_counter;      // good and bad, see below
-
-static zx_status_t
-number_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual) {
-    // (1) why are we here?
-    if (off == 0) {
-        // (2) first read; return as much data as we can
-        int n = atomic_add(&global_counter);
-        char tmp[22];           // 2^64 is 20 digits + \n + nul = 22 bytes
-        *actual = snprintf(tmp, sizeof(tmp), "%d\n", n);
-        if (*actual > count) {
-            *actual = count;
-        }
-        memcpy(buf, tmp, *actual);
-    } else {
-        // (3) not the first time -- return EOF
-        *actual = 0;
-    }
-    return ZX_OK;
-}
-```
-
-The first decision we make is in step (1), where we determine if the client is reading the
-string for the first time, or not.
-If the offset is zero, it's the first time.
-In that case, in step (2), we grab a value from `global_counter`, put it into a string,
-and tell the client that we're returning some number of bytes.
-The number of bytes we return is limited to the smaller of:
-
-*   the size of the client's buffer (given by `count`), or
-*   the size of the generated string (returned from **snprintf()**).
-
-If the offset is not zero, however, it means that it's not the first time that the client
-is reading data from this device.
-In this case, in step (3) we simply set the number of bytes that we're returning (the value
-of `*actual`) to zero, and this has the effect of indicating `EOF` to the client (just like
-it did in the `null` driver, above).
-
-### Globals are bad
-
-The `global_counter` that we used was global to the driver.
-This means that each and every session that ends up calling **number_read()** will end up
-incrementing that number.
-
-This is expected &mdash; after all, `/dev/misc/demo-number`'s job is to "hand out increasing
-numbers to its clients."
-
-What may not be expected is that if the driver is instantiated multiple times (as might happen
-with real hardware drivers, for example), then the value is *shared* across those multiple
-instances.
-Generally, this isn't what you want for real hardware drivers (because each driver instance
-is independent).
-
-The solution is to create a "per-device" context block; this context block would contain
-data that's unique for each device.
-
-In order to create per-device context blocks, we need to adjust our binding routine.
-Recall that the binding routine is where the association is made between the device and
-its protocol ops.
-If we were to create our context block in the binding routine, we'd then be able to
-use it later on in our read handler:
-
-
-```c
-typedef struct {
-    zx_device_t*    zxdev;
-    uint64_t        counter;
-} number_device_t;
-
-zx_status_t
-number_bind(void* ctx, zx_device_t* parent) {
-    // allocate & initialize per-device context block
-    number_device_t* device = calloc(1, sizeof(*device));
-    if (!device) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    device_add_args_t args = {
-        .version = DEVICE_ADD_ARGS_VERSION,
-        .name = "demo-number",
-        .ops = &number_device_ops,
-        .ctx = device,
-    };
-
-    zx_status_t rc = device_add(parent, &args, &device->zxdev);
-    if (rc != ZX_OK) {
-        free(device);
-    }
-    return rc;
-}
-```
-
-Here we've allocated a context block and stored it in the `ctx` member of the `device_add_args_t`
-structure `args` that we passed to **device_add()**.
-A unique instance of the context block, created at binding time, is now associated with each
-bound device instance, and is available for use in all protocol functions bound by
-**number_bind()**.
-Note that while we don't use the `zxdev` device from the context block, it's good practice
-to hang on to it in case we need it for any other device related operations later.
-
-![Figure: **device_add()** binds context
-blocks to devices](simple-003-cropped.png)
-
-The context block can be used in all protocol functions defined by `number_device_ops`, like
-our **number_read()** function:
-
-```c
-static zx_status_t
-number_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual) {
-    if (off == 0) {
-        number_device_t* device = ctx;
-        int n = atomic_fetch_add(&device->counter, 1);
-
-        //------------------------------------------------
-        // everything else is the same as previous version
-        //------------------------------------------------
-
-        char tmp[22];   // 2^64 is 20 digits + \n + \0
-        *actual = snprintf(tmp, sizeof(tmp), "%d\n", n);
-        if (*actual > count) {
-            *actual = count;
-        }
-        memcpy(buf, tmp, *actual);
-    } else {
-        *actual = 0;
-    }
-    return ZX_OK;
-}
-```
-
-Notice how we replaced the original version's `global_counter` with the value from the
-context block.
-Using the context block, each device gets its own, independent counter.
-
-### Cleaning up the context
-
-Of course, every time we **calloc()** something, we're going to have to **free()** it somewhere.
-This is done in our **number_release()** handler, which we store in our `zx_protocol_device_t
-number_device_ops` structure:
-
-```c
-static zx_protocol_device_t
-number_device_ops = {
-    // other initializations ...
-    .release = number_release,
-};
-```
-
-The **number_release()** function is simply:
-
-```c
-static void
-number_release(void* ctx) {
-    free(ctx);
-}
-```
-
-The **number_release()** function is called before the driver is unloaded.
-
-### Controlling your device
-
-Sometimes, it's desirable to send a control message to your device.
-This is data that doesn't travel over the **read()** / **write()** interface.
-For example, in `/dev/misc/demo-number`, we might want a way to preset the count to a given number.
-
-In a tradition POSIX environment, this is done with an **ioctl()** call on the client
-side, and an appropriate **ioctl()** handler on the driver side.
-
-Under Fuchsia, this is done differently, by marshalling data through the Fuchsia Interface
-Definition Language
-([**FIDL**](https://fuchsia.googlesource.com/docs/+/master/development/languages/fidl/README.md)).
-
-For more details about FIDL itself, consult the reference above.
-For our purposes here, FIDL:
-
-*   is described by a C-like language,
-*   is used to define the input and output arguments for your control functions,
-*   generates code for the client and driver side.
-
-> If you're already familiar with Google's "Protocol Buffers" then you'll be very comfortable
-> with FIDL.
-
-There are multiple advantages to FIDL.
-Because the input and output arguments are well-defined, the result is
-generated code that has strict type safety and checking, on both the client and driver
-sides.
-By abstracting the definition of the messages from their implementation, the FIDL
-code generator can generate code for multiple different languages, without additional
-work on your part.
-This is especially useful, for example, when clients require APIs
-in languages with which you aren't necessarily familiar.
-
-#### Using FIDL
-
-In the majority of cases, you'll be using FIDL APIs already provided by the device,
-and will rarely need to create your own.
-However, it's a good idea to understand the mechanism, end-to-end.
-
-Using FIDL for your device control is simple:
-
-*   define your inputs, outputs, and interfaces in a "`.fidl`" file,
-*   compile the FIDL code and generate your client functions, and
-*   add message handlers to your driver to receive control messages.
-
-We'll look at these steps by implementing the "preset counter to value"
-control function for our `/dev/misc/demo-number` driver.
-
-#### Define the FIDL interface
-
-The first thing we need to do is define what the interface looks like.
-Since all we want to do is preset the count to a user-specified value,
-our interface will be very simple.
-
-This is what the "`.fidl`" file looks like:
-
-```fidl
-library zircon.sample.number;
-
-[Layout="Simple"]
-interface Number {
-
-    // set the number to a given value
-    1: SetNumber(uint32 value) -> (uint32 previous);
-};
-```
-
-The first line, `library zircon.sample.number;` provides a name for the library that will
-be generated.
-
-Next, `[Layout="Simple"]` generates [simple C bindings](https://fuchsia.googlesource.com/docs/+/master/development/languages/fidl/languages/c.md#simple-bindings).
-
-Finally, the `interface` section defines all of the interfaces that are available.
-Each interface is numbered, has a name, and specifies inputs and outputs.
-
-Here, we have one interface function, called **SetNumber()**, which takes a `uint32` (which is
-the FIDL equivalent of the C standard integer `uint32_t` type) as input, and returns a `uint32`
-as the result (the previous value of the counter before it was changed).
-
-We'll see more advanced examples below.
-
-#### Compile the FIDL code
-
-The FIDL code is compiled automatically by the build system; you just need to add a dependency
-into the `rules.mk` makefile.
-This is what a stand-alone `rules.mk` would look like, assuming the "`.fidl`" file is called
-`demo_number.fidl`:
-
-```makefile
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_TYPE := fidl
-
-MODULE_PACKAGE := fidl
-
-MODULE_FIDL_LIBRARY := zircon.sample.number
-
-MODULE_SRCS += $(LOCAL_DIR)/demo_number.fidl
-
-include make/module.mk
-```
-
-Once compiled, the interface files will show up in the build output directory.
-The exact path depends on the build target (e.g., ...`/zircon/build-x64/`... for x86
-64-bit builds), and the source directory containing the FIDL files.
-
-For this example, we'll use the following paths:
-
-<dl>
-<dt>...`/zircon/system/dev/sample/number/demo-number.c`
-<dd>source file for `/dev/misc/demo-number` driver
-<dt>...`/zircon/system/fidl/zircon-sample/demo_number.fidl`
-<dd>source file for FIDL interface definition
-<dt>...`/zircon/build-x64/system/fidl/zircon-sample/gen/include/zircon/sample/number/c/fidl.h`
-<dd>generated interface definition header include file
-</dl>
-
-It's instructive to see the interface definition header file that was generated by the
-FIDL compiler.
-Here it is, annotated and edited slightly to just show the highlights:
-
-```c
-// (1) Forward declarations
-#define zircon_sample_number_NumberSetNumberOrdinal ((uint32_t)0x1)
-
-// (2) Extern declarations
-extern const fidl_type_t zircon_sample_number_NumberSetNumberRequestTable;
-extern const fidl_type_t zircon_sample_number_NumberSetNumberResponseTable;
-
-// (3) Declarations
-struct zircon_sample_number_NumberSetNumberRequest {
-    fidl_message_header_t hdr;
-    uint32_t value;
-};
-
-struct zircon_sample_number_NumberSetNumberResponse {
-    fidl_message_header_t hdr;
-    uint32_t result;
-};
-
-// (4) client binding prototype
-zx_status_t
-zircon_sample_number_NumberSetNumber(zx_handle_t _channel,
-                                     uint32_t value,
-                                     uint32_t* out_result);
-
-// (5) FIDL message ops structure
-typedef struct zircon_sample_number_Number_ops {
-    zx_status_t (*SetNumber)(void* ctx, uint32_t value, fidl_txn_t* txn);
-} zircon_sample_number_Number_ops_t;
-
-// (6) dispatch prototypes
-zx_status_t
-zircon_sample_number_Number_dispatch(void* ctx, fidl_txn_t* txn, fidl_msg_t* msg,
-                                     const zircon_sample_number_Number_ops_t* ops);
-
-zx_status_t
-zircon_sample_number_Number_try_dispatch(void* ctx, fidl_txn_t* txn, fidl_msg_t* msg,
-                                         const zircon_sample_number_Number_ops_t* ops);
-
-// (7) reply prototype
-zx_status_t
-zircon_sample_number_NumberSetNumber_reply(fidl_txn_t* _txn, uint32_t result);
-```
-
-> Note that this generated file contains code relevant to both the client *and* the driver.
-
-Briefly, the generated code presents:
-
-1.  a definition for the command numbers (the "`NumberOrdinal`", recall we used command
-    number `1` for **SetNumber()**),
-2.  external definitions of tables (we don't use these),
-3.  declarations for the request and response message formats; these consist of a FIDL
-    overhead header and the data we specified,
-4.  client binding prototypes &mdash; we'll see how the client uses this below,
-5.  FIDL message ops structure; this is a list of functions that you supply in the driver
-    to handle each and every FIDL interface defined in the "`.fidl`" file,
-6.  display prototypes &mdash; this is called by our FIDL message handler,
-7.  reply prototype &mdash; we call this in our driver when we want to reply to the client.
-
-#### The client side
-
-Let's start with a tiny, command-line based client, called `set_number`,
-that uses the above FIDL interface.
-It assumes that the device we're controlling is called `/dev/misc/demo-number`.
-The program takes exactly one argument &mdash; the number to set the current counter to.
-
-Here's a sample of the program's operation:
-
-```bash
-$ cat /dev/misc/demo-number
-0
-$ cat /dev/misc/demo-number
-1
-$ cat /dev/misc/demo-number
-2
-$ set_number 77
-Original value was 3
-$ cat /dev/misc/demo-number
-77
-$ cat /dev/misc/demo-number
-78
-```
-
-The complete program is as follows:
-
-```c
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include <zircon/syscalls.h>
-#include <lib/fdio/util.h>
-
-// (1) include the generated definition file
-#include <zircon/sample/number/c/fidl.h>
-
-int main(int argc, const char** argv)
-{
-    static const char* dev = "/dev/misc/demo-number";
-
-    // (2) get number from command line
-    if (argc != 2) {
-        fprintf(stderr, "set_number:  needs exactly one numeric argument,"
-                " the value to set %s to\n", dev);
-        exit(EXIT_FAILURE);
-    }
-    uint32_t n = atoi(argv[1]);
-
-    // (3) establish file descriptor to device
-    int fd = open(dev, O_RDWR);
-    if (fd == -1) {
-        fprintf(stderr, "set_number: can't open %s for O_RDWR, errno %d (%s)\n",
-                dev, errno, strerror(errno));
-        exit(EXIT_FAILURE);
-    }
-
-    // (4) establish handle to FDIO service on device
-    zx_handle_t num;
-    zx_status_t rc;
-    if ((rc = fdio_get_service_handle(fd, &num)) != ZX_OK) {
-        fprintf(stderr, "set_number: can't get fdio service handle, error %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
-
-    // (5) send FDIO command, get response
-    uint32_t orig;
-    if ((rc = zircon_sample_number_NumberSetNumber(num, n, &orig)) != ZX_OK) {
-        fprintf(stderr, "set_number: can't execute FIDL command to set number, error %d\n", rc);
-        exit(EXIT_FAILURE);
-    }
-    printf("Original value was %d\n", orig);
-    exit(EXIT_SUCCESS);
-}
-```
-
-This is very similar to the approach taken with POSIX **ioctl()**, except that:
-
-*   we established a handle to the FDIO service (step 4), and
-*   the API is type-safe and prototyped for the specific operation (step 5).
-
-Notice the FDIO command has a very long name: **zircon_sample_number_NumberSetNumber()**
-(which includes a lot of repetition).
-This is a facet of the code generation process from the FIDL compiler &mdash; the
-"`zircon_sample_number`" part came from the "`library zircon.sample.number`"
-statement, the first "`Number`" came from the "`interface Number`" statement, and the final
-"`SetNumber`" is the name of the interface from the interface definition statement.
-
-#### Add a message handler to the driver
-
-On the driver side, we need to:
-
-*   handle the FIDL message
-*   demultiplex the message (figure out which control message it is)
-*   generate a reply
-
-In conjunction with the prototype above, to handle the FIDL control message in our
-driver we need to bind a message handling function (just like we did in order
-to handle **read()**, for example):
-
-```c
-static zx_protocol_device_t number_device_ops = {
-    .version = DEVICE_OPS_VERSION,
-    .read = number_read,
-    .release = number_release,
-    .message = number_message,  // handle FIDL messages
-};
-```
-
-The **number_message()** function is trivial in this case; it simply wraps the dispatch
-function:
-
-```c
-static zircon_sample_number_Number_ops_t number_fidl_ops = {
-    .SetNumber = fidl_SetNumber,
-};
-
-static zx_status_t number_message(void* ctx, fidl_msg_t* msg, fidl_txn_t* txn) {
-    zx_status_t status = zircon_sample_number_Number_dispatch(ctx, txn, msg, &number_fidl_ops);
-    return status;
-}
-```
-
-The generated **zircon_sample_number_Number_dispatch()** function takes the incoming message
-and calls the appropriate handling function based on the provided table of functions in
-`number_fidl_ops`.
-Of course, in our trivial example, there is only the one function, `SetNumber`:
-
-```c
-static zx_status_t fidl_SetNumber(void* ctx, uint32_t value, fidl_txn_t* txn)
-{
-    number_device_t* device = ctx;
-    int saved = device->counter;
-    device->counter = value;
-    return zircon_sample_number_NumberSetNumber_reply (txn, saved);
-}
-```
-
-The **fidl_SetNumber()** handler:
-
-*   establishes a pointer to the device context,
-*   saves the current count value (so that it can return it later),
-*   sets the new value into the device context, and
-*   calls the "reply" function to return the value to the client.
-
-Notice that the **fidl_SetNumber()** function has a prototype that matches the FIDL
-specification, ensuring type safety. Similarly, the reply function,
-**zircon_sample_number_NumberSetNumber_reply()** also conforms to the FIDL
-specification's prototype of the result portion of the interface definition.
-
-#### Advanced uses
-
-FIDL expressions can certainly be made more complex than what we've shown above.
-For example, nested structures can be used, rather than the simple `uint32`.
-Multiple parameters are allowed for both inputs and outputs. See the
-[FIDL reference](https://fuchsia.googlesource.com/docs/+/master/development/languages/fidl/README.md).
-
-## Registering multiple devices with `/dev/misc/demo-multi`
-
-So far, the devices discussed were "singletons" &mdash; that is, one registered name did one thing
-(`null` manifested the null device, `number` manifested the number device, and so on).
-
-What if you have a cluster of devices that all perform similar functions?
-For example, you might have a multi-channel controller of some kind that has 16 channels.
-
-The correct way to handle this is to:
-
-1.  create a driver instance,
-2.  create a base device node, and
-3.  manifest your sub-devices under that base device.
-
-Creating the driver instance is good practice as discussed above, in "Globals are bad" (we'll
-discuss it a little more in this particular context later).
-
-In this example, we're going to create a base device `/dev/misc/demo-multi`, and then
-we're going to create 16 sub-devices under that called `0` through `15` (e.g.,
-`/dev/misc/demo-multi/7`).
-
-```c
-static zx_protocol_device_t multi_device_ops = {
-    .version = DEVICE_OPS_VERSION,
-    .read = multi_read,
-    .release = multi_release,
-};
-
-static zx_protocol_device_t multi_base_device_ops = {
-    .version = DEVICE_OPS_VERSION,
-    .read = multi_base_read,
-    .release = multi_release,
-};
-
-zx_status_t multi_bind(void* ctx, zx_device_t* parent) {
-    // (1) allocate & initialize per-device context block
-    multi_root_device_t* device = calloc(1, sizeof(*device));
-    if (!device) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    device->parent = parent;
-
-    // (2) set up base device args structure
-    device_add_args_t args = {
-        .version = DEVICE_ADD_ARGS_VERSION,
-        .ops = &multi_base_device_ops,          // use base ops initially
-        .name = "demo-multi",
-        .ctx = &device->base_device,
-    };
-
-    // (3) bind base device
-    zx_status_t rc = device_add(parent, &args, &device->base_device.zxdev);
-    if (rc != ZX_OK) {
-        return rc;
-    }
-
-    // (4) allocate and bind sub-devices
-    args.ops = &multi_device_ops;               // switch to sub-device ops
-    for (int i = 0; i < NDEVICES; i++) {
-        char name[ZX_DEVICE_NAME_MAX + 1];
-        sprintf(name, "%d", i);
-        args.name = name;                       // change name for each sub-device
-        device->devices[i] = calloc(1, sizeof(*device->devices[i]));
-        if (device->devices[i]) {
-            args.ctx = &device->devices[i];     // store device pointer in context
-            device->devices[i]->devno = i;      // store number as part of context
-            rc = device_add(device->base_device.zxdev, &args, &device->devices[i]->zxdev);
-            if (rc != ZX_OK) {
-                free(device->devices[i]);       // device "i" failed; free its memory
-            }
-        } else {
-            rc = ZX_ERR_NO_MEMORY;
-        }
-
-        // (5) failure backout
-        if (rc != ZX_OK) {
-            for (int j = 0; j < i; j++) {
-                device_remove(device->devices[j].zxdev);
-                free(device->devices[j]);
-            }
-            device_remove(device->base_device.zxdev);
-            free(device);
-            return rc;
-        }
-    }
-
-    return rc;
-}
-
-// (6) release the per-device context block
-static void multi_release(void* ctx) {
-    free(ctx);
-}
-```
-
-The steps are:
-
-1.  Establish a device context pointer, in case this driver is loaded multiple times.
-2.  Create and initialize an `args` structure that we'll pass to
-    **device_add()**.
-    This structure has the base device name, "`demo-multi`", and a context pointer
-    to the base device context block `base_device`.
-3.  Call **device_add()** to add the base device.
-    This has now created `/dev/misc/demo-multi`.
-    Note that we store the newly created device into `base_device.zxdev`. This then
-    serves as the "parent" device for the sub-device children.
-4.  Now create 16 sub-devices as children of the base ("parent") device.
-    Notice that we changed the `ops` member to point to the sub-device protocol ops
-    `multi_device_ops` instead of the base version.
-    The name of each sub-device is simply the ASCII representation of the device number.
-    Note that we store the device number index `i` (0 .. 15) in `devno` as context
-    (we have an array of contexts called `multi_devices` which we'll see shortly).
-    We also illustrate allocating each sub-device dynamically, rather than
-    allocating its space in the parent's structure.
-    This is a more realistic use-case for "hot-plug" devices &mdash; you don't
-    want to allocate a large context structure, or perform initialization work,
-    for devices that aren't (yet) present.
-5.  In case of a failure, we need to remove and deallocate the devices that we
-    already added, including the base device and the per-device context block.
-    Note that we release up to, but not including, the failed device index.
-    This is why we called **free()** on the sub-device structure in step 4 in
-    case of **device_add()** failure.
-6.  We release the per-device context block in our release handler.
-
-### Which device is which?
-
-We have two **read()** functions, **multi_read()** and **multi_base_read()**.
-This allows us to have different behaviors for reading the base device versus
-reading one of the 16 sub-devices.
-
-The base device read is almost identical to what we saw above in `/dev/misc/demo-number`:
-
-```c
-static zx_status_t
-multi_base_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual) {
-    const char* base_name = "base device\n";
-
-    if (off == 0) {
-        *actual = strlen(base_name);
-        if (*actual > count) {
-            *actual = count;
-        }
-        memcpy(buf, base_name, *actual);
-    } else {
-        *actual = 0;
-    }
-    return ZX_OK;
-}
-```
-
-This just returns the string "`base device\n`" for the read, up to the maximum
-number of bytes allowed by the client, of course.
-
-But the read for the sub-devices needs to know which device it's being called
-on behalf of.
-We keep a device index, called `devno`, in the individual sub-device context block:
-
-```c
-typedef struct {
-    zx_device_t*    zxdev;
-    int             devno;              // device number (index)
-} multidev_t;
-```
-
-The context blocks for the 16 sub-devices, as well as the base device, are stored in
-the per-device context block created in step (1) of the binding function, above.
-
-```c
-// this contains our per-device instance
-#define NDEVICES 16
-typedef struct {
-    zx_device_t*    parent;
-    multidev_t*     devices[NDEVICES];  // pointers to our 16 sub-devices
-    multidev_t      base_device;        // our base device
-} multi_root_device_t;
-```
-
-Notice that the `multi_root_device_t` per-device context structure contains 1 `multidev_t`
-context block (for the base device) and 16 pointers to dynamically allocated context
-blocks for the sub-devices.
-The initialization of those context blocks occurred in steps (3) (for the base device)
-and (4) (done in the `for` loop for each sub-device).
-
-![Figure: Relationship between per-device context and devices](simple-008-cropped.png)
-
-The diagram above illustrates the relationship between the per-device context block,
-and the individual devices.
-Sub-device 7 is representative of all sub-devices.
-
-This is what our **multi_read()** function looks like:
-
-```c
-static const char* devnames[NDEVICES] = {
-    "zero", "one", "two", "three",
-    "four", "five", "six", "seven",
-    "eight", "nine", "ten", "eleven",
-    "twelve", "thirteen", "fourteen", "fifteen",
-};
-
-static zx_status_t
-multi_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual) {
-    multidev_t* device = ctx;
-
-    if (off == 0) {
-        char tmp[16];
-        *actual = snprintf(tmp, sizeof(tmp), "%s\n", devnames[device->devno]);
-        if (*actual > count) {
-            *actual = count;
-        }
-        memcpy(buf, tmp, *actual);
-    } else {
-        *actual = 0;
-    }
-    return ZX_OK;
-}
-```
-
-Exercising our device from the command line gives results like this:
-
-```shell
-$ cat /dev/misc/demo-multi
-base device
-$ cat /dev/misc/demo-multi/7
-seven
-$ cat /dev/misc/demo-multi/13
-thirteen
-```
-
-and so on.
-
-### Multiple multiple devices
-
-It may seem odd to create a "per device" context block for a controller that
-supports multiple devices, but it's really no different than any other controller.
-If this were a real hardware device (say a 16 channel data acquisition system),
-you could certainly have two or more of these plugged into your system.
-Each driver would be given a unique base device name (e.g. `/dev/daq-0`,
-`/dev/daq-1`, and so on), and would then manifest its channels under that name
-(e.g., `/dev/daq-1/7` for the 8th channel on the 2nd data acquisition system).
-
-Ideally, the assignment of unique base device names should be done based on some kind of
-hardware provided unique key.
-This has the advantage of repeatability / predictability, especially with hot-plug
-devices.
-For example, in the data acquisition case, there would be distinct devices connected
-to each of the controller channels.
-After a reboot, or a hot unplug / replug event, it would be desirable to be able to
-associate each controller with a known base device name; it wouldn't be useful
-to have the device name change randomly between plug / unplug events.
-
-## Blocking reads and writes: `/dev/misc/demo-fifo`
-
-So far, all of the devices that we've examined returned data immediately (for a **read()**
-operation), or (in the case of `/dev/misc/demo-null`), accepted data without blocking
-(for the **write()** operation).
-
-The next device we'll discuss, `/dev/misc/demo-fifo`, will return data immediately if
-there's data available, otherwise it will block the client until data is available.
-Similarly, for writing, it will accept data immediately if there's room, otherwise
-it will block the client until room is available.
-
-The individual handlers for reading and writing must return immediately (regardless of whether
-data or room is available or not).
-However, they don't have to return or accept *data* immediately; they can instead
-indicate to the client that it should wait.
-
-Our FIFO device operates by maintaining a single, 32kbyte FIFO.
-Clients can read from, and write to, the FIFO, and will exhibit the blocking behavior discussed
-above during full and empty conditions, as appropriate.
-
-### The context structure
-
-The first thing to look at is the context structure:
-
-```c
-#define FIFOSIZE 32768
-
-typedef struct {
-    zx_device_t*    zxdev;
-    mtx_t           lock;
-    uint32_t        head;
-    uint32_t        tail;
-    char            data[FIFOSIZE];
-} fifodev_t;
-```
-
-This is a basic circular buffer; data is written to the position indicated by `head`
-and read from the position indicated by `tail`.
-If `head == tail` then the FIFO is empty, if `head` is just before `tail` (using wraparound math)
-then the FIFO is full, otherwise it has both some data and some room available.
-
-At a high level, the **fifo_read()** and **fifo_write()** functions are almost identical,
-so let's start with the **fifo_write()**:
-
-
-```c
-static zx_status_t
-fifo_write(void* ctx, const void* buf, size_t len,
-           zx_off_t off, size_t* actual) {
-    // (1) establish context pointer
-    fifodev_t* fifo = ctx;
-
-    // (2) lock mutex
-    mtx_lock(&fifo->lock);
-
-    // (3) write as much data as possible
-    size_t n = 0;
-    size_t count;
-    while ((count = fifo_put(fifo, buf, len)) > 0) {
-        len -= count;
-        buf += count;
-        n += count;
-    }
-
-    if (n) {
-        // (4) wrote something, device is readable
-        device_state_set(fifo->zxdev, DEV_STATE_READABLE);
-    }
-    if (len) {
-        // (5) didn't write everything, device is full
-        device_state_clr(fifo->zxdev, DEV_STATE_WRITABLE);
-    }
-
-    // (6) release mutex
-    mtx_unlock(&fifo->lock);
-
-    // (7) inform client of results, possibly blocking it
-    *actual = n;
-    return (n == 0) ? ZX_ERR_SHOULD_WAIT : ZX_OK;
-}
-```
-
-In step (1), we establish a context pointer to this device instance's context block.
-Next, we lock the mutex in step (2).
-This is done because we may have multiple threads in our driver, and we don't
-want them to interfere with each other.
-
-Buffer management is performed in step (3) &mdash; we'll examine the implementation later.
-
-It's important to understand what actions we need to take after step (3):
-
-*   If we wrote one or more bytes (as indicated by `n` being non-zero), we need to
-    mark the device as "readable" (via **device_state_set()**
-    and `DEV_STATE_READABLE`),
-    which is done in step (4). We do this because data is now available.
-*   If we still have bytes left to write (as indicated by `len` being non-zero), we
-    need to mark the device as "not writable" (via
-    **device_state_clr()** and
-    `DEV_STATE_WRITABLE`), which is done in step (5). We know that the FIFO is full because
-    we were not able to write all of our data.
-
-It's possible that we may execute one or both steps (4) and (5) depending
-on what happened during the write.
-We will always execute at least one of them because `n` and `len` can never both
-be zero.
-That would imply an impossible condition where we both didn't write any data (`n`, the
-total number of bytes transferred, was zero) and simultaneously wrote all of the data
-(`len`, the remaining number of bytes to transfer, was also zero).
-
-In step (7) is where the decision is made about blocking the client.
-If `n` is zero, it means that we were not able to write any data.
-In that case, we return `ZX_ERR_SHOULD_WAIT`.
-This return value blocks the client.
-
-The client is unblocked when the **device_state_set()**
-function is called in step (2) from the **fifo_read()** handler:
-
-```c
-static zx_status_t
-fifo_read(void* ctx, void* buf, size_t len,
-          zx_off_t off, size_t* actual) {
-    fifodev_t* fifo = ctx;
-
-    mtx_lock(&fifo->lock);
-    size_t n = 0;
-    size_t count;
-
-    while ((count = fifo_get(fifo, buf, len)) > 0) {
-        len -= count;
-        buf += count;
-        n += count;
-    }
-
-    // (1) same up to here; except read as much as possible
-
-    if (n) {
-        // (2) read something, device is writable
-        device_state_set(fifo->zxdev, DEV_STATE_WRITABLE);
-    }
-    if (len) {
-        // (3) didn't read everything, device is empty
-        device_state_clr(fifo->zxdev, DEV_STATE_READABLE);
-    }
-
-    mtx_unlock(&fifo->lock);
-    *actual = n;
-
-    return (n == 0) ? ZX_ERR_SHOULD_WAIT : ZX_OK;
-}
-```
-
-The shape of the algorithm is the same as in the writing case, with two differences:
-
-1.  We're reading data, so call **fifo_get()** instead of **fifo_put()**
-2.  The `DEV_STATE` logic is complementary: in the writing case we set readable
-    and cleared writable, in the reading case we set writable and clear
-    readable.
-
-Similar to the writing case, after the `while` loop we will perform one or both of the
-following actions:
-
-*   If we read one or more bytes (as indicated by `n` being non-zero), we need to mark the
-    device as now being writable (we consumed data, so there's now some space free).
-*   If we still have bytes to read (as indicated by `len` being non-zero), we mark the
-    device as empty (we didn't get all of our data, so that must be because we drained
-    the device).
-
-As in the writing case, at least one of the above actions will execute.
-In order for neither of them to execute, both `n` (the number of bytes read) and `len`
-(the number of bytes left to read) would have to be zero, implying the impossible,
-almost metaphysical condition of having read both nothing and everything at the same time.
-
-> An additional subtlety applies here as well.
-> When `n` is zero, we *must* return `ZX_ERR_SHOULD_WAIT` &mdash; we can't return `ZX_OK`.
-> Returning `ZX_OK` with `*actual` set to zero indicates EOF, and that's definitely not
-> the case here.
-
-### Read and write interaction
-
-As you can see, the read handler is what allows blocked writing clients to unblock, and the
-write handler is what allows blocked reading clients to unblock.
-
-When a client is blocked (via the `ZX_ERR_SHOULD_WAIT` return code), it gets kicked by
-the corresponding **device_state_set()**
-function.
-This kick causes the client to try their read or write operation again.
-
-Note that there's no guarantee of success for the client after it gets kicked.
-We can have multiple readers, for example, waiting for data.
-Assume that all of them are now blocked, because the FIFO is empty.
-Another client comes along and writes to the FIFO.
-This causes the **device_state_set()**
-function to get called with `DEV_STATE_READABLE`.
-It's possible that one of the clients consumes all of the available data; the
-other clients will try to read, but will get `ZX_ERR_SHOULD_WAIT` and will block.
-
-### Buffer management
-
-As promised, and for completeness, here's a quick examination of the buffer management that's
-common to both routines.
-We'll look at the read path (the write path is virtually identical).
-
-In the heart of the read function, we see:
-
-```c
-    size_t n = 0;
-    size_t count;
-
-    while ((count = fifo_get(fifo, buf, len)) > 0) {
-        len -= count;
-        buf += count;
-        n += count;
-    }
-```
-
-The three variables, `n`, `count`, and `len` are inter-related.
-The total number of bytes transferred is stored in `n`.
-During each iteration, `count` gets the number of bytes transferred, and it's used as the
-basis to control the `while` loop.
-The variable `len` indicates the remaining number of bytes to transfer.
-Each time through the loop, `len` is decreased by the number of bytes transferred, and `n` is
-correspondingly increased.
-
-Because the FIFO is implemented as a circular buffer, it means that one
-complete set of data might be located contiguously in the FIFO, or it may wrap-around
-the end of the FIFO back to the beginning.
-
-The underlying **fifo_get()** function gets as much data as it can without wrapping.
-That's why the `while` loop "retries" the operation; to see if it could get
-more data possibly due to the `tail` wrapping back to the beginning of the buffer.
-
-We'll call **fifo_get()** between one and three times.
-
-1.  If the FIFO is empty, we'll call it just once.
-    It will return zero, indicating no data is available.
-2.  We call it twice if the data is contiguously located in the underlying FIFO buffer;
-    the first time to get the data, and the second time will return zero, indicating that
-    no more data is available.
-3.  We'll call it three times if the data is wrapped around in the buffer.
-    Once to get the first part, a second time to get the wrap-around part, and a third time
-    will return zero, indicating that no more data is available.
-
diff --git a/docs/ddk/simple.odg b/docs/ddk/simple.odg
deleted file mode 100644
index 1a0520b..0000000
--- a/docs/ddk/simple.odg
+++ /dev/null
Binary files differ
diff --git a/docs/ddk/tracing.md b/docs/ddk/tracing.md
deleted file mode 100644
index 1f02b24..0000000
--- a/docs/ddk/tracing.md
+++ /dev/null
@@ -1,142 +0,0 @@
-# Adding tracing to device drivers
-
-This document describes how to add tracing to device drivers.
-
-## Overview
-
-Please read [Fuchsia Tracing System Design](../tracing/design.md)
-for an overview of tracing.
-
-## Trace Provider
-
-Drivers don't have to specify a Trace Provider, the devhost process
-via `libdriver.so` provides it. It is mentioned here in case the topic
-comes up.
-
-## Adding trace records
-
-### Source additions
-
-Trace records are easiest to add by invoking the `TRACE_*()` macros
-from `ddk/trace/event.h`.
-
-There are various kinds of trace records that can be emitted.
-Please see `trace/internal/event_common.h` for a description
-of the various macros.
-
-Looking up macro documentation from internal implementation files
-is a temporary situation. Ultimately such documentation will live
-in a more appropriate place.
-
-Example:
-
-```c++
-#include <ddk/trace/event.h>
-
-void DoSomething(int a, std::string b) {
-  TRACE_DURATION("example:example1", "DoSomething", "a", a, "b", b);
-
-  // Do something
-}
-```
-
-The first two arguments to most macros are the "category" and the
-event name. Here they are "example:example1" and "DoSomething" respectively.
-
-Trace categories are how the tracing system lets the user specify
-what data to collect. If a category is not requested by the user
-then the data is not collected.
-
-Categories don't need to be unique across the driver.
-One typically groups several events under the same category.
-By convention categories have the format
-"<provider-name>:<category-name>[:<subcategory1-name>...]".
-"<provider-name>" for drivers should generally by the driver name.
-This is done to avoid collisions in category names across the
-entire system. A potential augmentation to this convention is to prefix
-all driver categories with "driver:". E.g., "driver:ethernet:packets".
-Avoiding naming collisions with other trace providers is important,
-otherwise the user may ask for a particular category and get completely
-unrelated data from a different trace provider.
-
-The event name is included in the trace to describe what the event
-is about. It is typically unique for each event.
-
-Note that currently the default is that no code will be generated
-by the addition of these `TRACE_*()` macros. Akin to <assert.h>'s use of
-`#define NDEBUG` to disable `assert()`s, tracing uses `#define NTRACE` to
-disable tracing. `NTRACE` is currently defined by default unless
-`ENABLE_DRIVER_TRACING=true` is passed to `make`. See below.
-
-### Makefile additions
-
-The following addition to your driver's `rules.mk` file is needed to
-pick up tracing support:
-
-```make
-ifeq ($(call TOBOOL,$(ENABLE_DRIVER_TRACING)),true)
-MODULE_STATIC_LIBS += system/ulib/trace.driver
-endif
-MODULE_HEADER_DEPS += system/ulib/trace system/ulib/trace-engine
-```
-
-## Booting with tracing
-
-To be super conservative, not only does tracing currently require a special
-compile flag to enable it: `ENABLE_DRIVER_TRACING=true`,
-it also requires an extra kernel command line flag to enable it:
-`driver.tracing.enable=1`
-
-`ENABLE_DRIVER_TRACING=true` is now the default. To disable compiling in
-driver tracing support, pass `ENABLE_DRIVER_TRACING=false` to make.
-
-`driver.tracing.enable=1` is also now the default. To disable partipation
-of drivers in Fuchsia tracing, boot the kernel with `driver.tracing.enable=0`.
-
-Example:
-
-First build:
-
-```sh
-$ fx set $arch
-$ fx build-zircon
-$ fx build
-```
-
-Then boot. With QEMU:
-
-```sh
-$ fx run -k -N
-```
-
-Or on h/w (augment with options specific to your h/w):
-
-```sh
-$ fx serve
-```
-
-These extra requirements will be removed once tracing support stabilizes.
-
-## Using tracing
-
-Once the system is booted you can collect traces on the target and
-then manually copy them to your development host.
-These examples use the category from the source additions described above.
-
-Example:
-
-```sh
-fuchsia$ trace record --categories=example:example1
-host$ fx cp --to-host /data/trace.json trace.json
-```
-
-However, it's easier to invoke the `traceutil` program on your development
-host and it will copy the files directly to your host and prepare them for
-viewing with the Chrome trace viewer.
-
-```sh
-host$ fx traceutil record --categories=example:example1
-```
-
-See the [Tracing Usage Guide](https://fuchsia.googlesource.com/garnet/+/master/docs/tracing_usage_guide.md)
-for further info.
diff --git a/docs/debugging/acpi.md b/docs/debugging/acpi.md
deleted file mode 100644
index fc75cbc..0000000
--- a/docs/debugging/acpi.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# ACPI debugging
-
-## ACPICA debug interfaces
-
-To turn on ACPICA's debug output, pass "ENABLE\_ACPI\_DEBUG=1" to make.  When this
-option is enabled, ACPICA uses two global variables to control debug output.
-
-### AcpiDbgLevel
-
-AcpiDbgLevel is a bitmap of values defined in
-third\_party/lib/acpica/source/include/acpica/acoutput.h with the prefix
-"ACPI\_LV\_".  For convenience, there are some pre-defined verbosity levels:
-ACPI\_LV\_VERBOSITY1, ACPI\_LV\_VERBOSITY2, ACPI\_LV\_VERBOSITY3.  These control
-types of tracing events to log.  For example, if you want to trace all function
-calls and mutex operations, you can set AcpiDbgLevel to
-
-"ACPI\_LV\_FUNCTIONS | ACPI\_LV\_MUTEX"
-
-### AcpiDbgLayer
-
-AcpiDbgLayer is a bitmap of values defined in
-third\_party/lib/acpica/source/include/acpica/acoutput.h.  These do not have a
-common prefix, but are listed as "Component IDs".  These control which
-submodules of ACPICA are to be traced.  For example, to trace through the
-namespace logic and the executor, you can set AcpiDbgLayer to
-
-"ACPI\_NAMESPACE | ACPI\_EXECUTOR"
-
-### Setting these values
-
-One easy place to set these in the AcpiOsInitialize method that we define in
-third\_party/lib/acpica/source/os\_specific/service\_layers/osfuchsia.cpp.
-One technique that may be useful is zeroing both values in AcpiOsInitialize, and
-setting it to a non-zero value immediate before a call into ACPICA of interest.
-
-### AcpiDebugTrace
-
-There is additionally a method named AcpiDebugTrace in the ACPIA API.  It
-supposedly supports tracing particular ACPI methods by their 4-character
-namespace names (but with no scoping to particular Nodes).  See the ACPICA
-manual for details.
diff --git a/docs/debugging/tips.md b/docs/debugging/tips.md
deleted file mode 100644
index 4b2889e..0000000
--- a/docs/debugging/tips.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Debugging Tips
-
-For general debugging info see the [Fuchsia Debugging Workflow][fuchsia-debugging-doc].
-
-## Generating debug info
-
-There are several make variables used to control the generation of debug info.
-
-### GLOBAL_DEBUGFLAGS
-
-GLOBAL\_DEBUGFLAGS specifies level of debug info to generate.
-The default is -g.
-A useful value for getting less debug info usable in backtraces is -g1.
-
-### BOOTFS_DEBUG_MODULES
-
-BOOTFS\_DEBUG\_INFO\_FILES allows one to specify which modules
-(apps,libs,tests) have their associated debug info included
-in the boot image.
-
-The value is a comma-separated list of "module short names"
-which are generally `parent_directory/module_directory`.
-E.g., `ulib/launchpad,utest/debugger`
-Make-style patterns (%) are allowed, e.g., `ulib/%,utest/debugger`.
-
-The default is empty (meaning none).
-
-## Adding debug info to boot image
-
-By default the boot image does not contain debug info as it
-can require a lot of extra space. Adding debug info is useful when
-using tools like debuggers natively. Note that this does not apply
-to cross debugging where the debugger is running on separate machine.
-Adding debug info to the boot image is for when you are running debugging
-tools on zircon itself.
-
-Example:
-```
-$ make -j10 x86 BOOTFS_DEBUG_MODULES=ulib/%,utest/debugger GLOBAL_DEBUGFLAGS=-g1
-```
-
-This example will include in the boot image debug info files for all
-shared libraries and for the "debugger" test program. To reduce the amount
-of debug info to just that usable in backtraces `GLOBAL_DEBUGFLAGS=-g1`
-is passed.
-
-## Debugging the kernel with QEMU+GDB.
-
-See "Debugging the kernel with GDB" in [QEMU](../qemu.md) for
-documentation on debugging zircon with QEMU+GDB.
-
-[fuchsia-debugging-doc]: https://fuchsia.googlesource.com/docs/+/master/development/workflows/debugging.md
-
-## Symbolizing the backtraces
-
-To automatically symbolize the backtraces when running zircon, pass the logs
-through the symbolizer as follows:
-
-```
-$ ./scripts/run-zircon -a (x64|arm64) | ./scripts/symbolize
-...
-> crasher
-...
-[00021.715] 01044.01212> devmgr: crash_analyzer_listener: analyzing exception type 0x108
-[00021.721] 01102.01116> <== fatal exception: process crasher[2853] thread initial-thread[2867]
-[00021.721] 01102.01116> <== fatal page fault, PC at 0x38ed815cdbd7
-[00021.721] 01102.01116>  CS:                   0 RIP:     0x38ed815cdbd7 EFL:              0x246 CR2:                  0
-[00021.721] 01102.01116>  RAX:                  0 RBX:                0x1 RCX:                0x1 RDX:     0x75dec26db264
-[00021.722] 01102.01116>  RSI:                  0 RDI:                  0 RBP:      0x5663cdc3f90 RSP:      0x5663cdc3f80
-[00021.722] 01102.01116>   R8:                  0  R9:                  0 R10:                  0 R11:              0x206
-[00021.722] 01102.01116>  R12:     0x6a3f40970d70 R13:     0x6a3f40970db0 R14:               0x16 R15:         0x7986f4ef
-[00021.722] 01102.01116>  errc:               0x6
-[00021.722] 01102.01116> bottom of user stack:
-[00021.723] 01102.01116> 0x000005663cdc3f80: 40970d70 00006a3f 9af1eb38 00006fea |p..@?j..8....o..|
-[00021.724] 01102.01116> 0x000005663cdc3f90: 3cdc3fd0 00000566 815cdba7 000038ed |.?.<f.....\..8..|
-[00021.724] 01102.01116> 0x000005663cdc3fa0: 00000008 00000000 9af1eb38 00006fea |........8....o..|
-[00021.724] 01102.01116> 0x000005663cdc3fb0: 40970f70 00006a3f 40970f70 00006a3f |p..@?j..p..@?j..|
-[00021.724] 01102.01116> 0x000005663cdc3fc0: c26db570 000075de 40970db0 00006a3f |p.m..u.....@?j..|
-[00021.724] 01102.01116> 0x000005663cdc3fd0: 3cdc3ff0 00000566 c261cdef 000075de |.?.<f.....a..u..|
-[00021.724] 01102.01116> 0x000005663cdc3fe0: 00000054 00000000 40970f70 00006a3f |T.......p..@?j..|
-[00021.724] 01102.01116> 0x000005663cdc3ff0: 40970fe0 00006a3f 00000000 00000000 |...@?j..........|
-[00021.724] 01102.01116> arch: x86_64
-[00021.728] 01102.01116> dso: id=31c12edecfd596b0be787e782f896efadf23e3da base=0x75dec2603000 name=libc.so
-[00021.728] 01102.01116> dso: id=b4f9333e0d1bb7e79370905f90299d1da94e4271 base=0x51d5c67da000 name=<vDSO>
-[00021.728] 01102.01116> dso: id=a0106c6ceae6a63d35eb7e8923ebc1a62a8df3e8 base=0x38ed815cd000 name=app:crasher
-[00021.728] 01102.01116> dso: id=881704361e6af74805ab9e2a236ccf2962cdecc9 base=0x2ce98f7b2000 name=libfdio.so
-[00021.738] 01102.01116> bt#01: pc 0x38ed815cdbd7 sp 0x5663cdc3f80 (app:crasher,0xbd7)
-[00021.746] 01102.01116> bt#02: pc 0x38ed815cdba7 sp 0x5663cdc3fa0 (app:crasher,0xba7)
-[00021.747] 01102.01116> bt#03: pc 0x75dec261cdef sp 0x5663cdc3fe0 (libc.so,0x19def)
-[00021.749] 01102.01116> bt#04: pc 0 sp 0x5663cdc4000
-[00021.749] 01102.01116> bt#05: end
-
-start of symbolized stack:
-#01: blind_write at ./system/uapp/crasher/crasher.c:21
-#02: main at ./system/uapp/crasher/crasher.c:137
-#03: start_main at ./third_party/ulib/musl/src/env/__libc_start_main.c:49
-#04: unknown, can't find pc, sp or app/library in line
-end of symbolized stack
-```
diff --git a/docs/driver_interfaces/audio.md b/docs/driver_interfaces/audio.md
deleted file mode 100644
index 4e905c4..0000000
--- a/docs/driver_interfaces/audio.md
+++ /dev/null
@@ -1,773 +0,0 @@
-# Audio Driver Streaming Interface
-
-This document describes the audio streaming interface exposed by audio drivers
-in Zircon.  It is meant to serve as a reference for both users and
-driver-authors, and to unambiguously define the interface contract which drivers
-must implement and users must follow.
-
-## Overview
-
-Audio streams are device nodes published by driver services intended to be used
-by applications in order to capture and/or render audio on a Zircon device.
-Each stream in the system (input or output) represents a stream of digital audio
-information which may be either received or transmitted by device.  Streams are
-dynamic and may created or destroyed by the system at any time.  Which streams
-exist at any given point in time, and what controls their lifecycles are
-considered to be issues of audio policy and codec management and are not discussed
-in this document.  Additionally, the information present in audio outputs
-streams is exclusive to the application owner of the stream.  Mixing of audio is
-_not_ a service provided by the audio stream interface.
-
-> TODO: extend this interface to support the concept of low-latency hardware
-> mixers.
-
-### Basic Vocabulary
-
-Term | Definition
------|-----------
-Sample | A representation of the sound rendered by a single speaker, or captured by a single microphone, at a single instant in time.
-LPCM | Linear pulse code modulation.  The specific representation of audio samples present in all Zircon uncompressed audio streams.  LPCM audio samples are representations of the amplitude of the audio signal at an instant in time where the numeric values of the encoded audio are linearly distributed across the amplitude levels of the rendering or capture device.  This is in contrast to A-law and &mu;-law encodings which have non-linear mappings from numeric value to amplitude level.
-Channel | Within an audio stream, the subset of information which will be rendered by a single speaker, or which was captured by a single microphone in a stream.
-Frame | A set of audio samples for every channel of a audio stream captured/rendered at a single instant in time.
-Frame Rate | a.k.a. "Sample Rate".  The rate (in Hz) at which audio frames are produced or consumed.  Common sample rates include 44.1 KHz, 48 KHz, 96 KHz, and so on.
-Client or User or Application | These terms are used interchangeably in this document. They refer to modules that use these interfaces to communicate with an audio driver/device.
-
-> TODO: do we need to extend this interface to support non-linear audio sample
-> encodings?  This may be important for telephony oriented microphones which
-> deliver &mu;-law encoded samples.
-
-### Basic Operation
-
-Communication with an audio stream device is performed using messages sent over
-a [channel](../objects/channel.md).  Applications open the device node for a
-stream and obtain a channel by issuing an ioctl.  After obtaining the channel,
-the device node may be closed.  All subsequent communication with the stream
-will occur using channels.
-
-The "stream" channel will then be used for most command and control tasks,
-including:
- * Capability interrogation
- * Format negotiation
- * Hardware gain control
- * Determining outboard latency
- * Plug detection notification
- * Access control capability detection and signalling
- * Policy level stream purpose indication/Stream Association (TBD)
-
-> TODO: Should plug/unplug detection be done by sending notifications over the
-> stream channel (as it is today), or by publishing/unpublishing the device
-> nodes (and closing all channels in the case of unpublished channels)?
-
-In order to actually send or receive audio information on the stream, the
-specific format to be used must first be set.  The response to a successful
-SetFormat operation will contain a new "ring-buffer" channel.  The ring-buffer
-channel may be used to request a shared buffer from the stream (delivered in the
-form of a [VMO](../objects/vm_object.md)) which may be mapped into the address
-space of the application and used to send or receive audio data as appropriate.
-Generally, the operations conducted over the ring buffer channel include...
- * Requesting a shared buffer
- * Starting and Stopping stream playback/capture
- * Receiving notifications of playback/capture progress
- * Receiving notifications of error conditions such as HW FIFO under/overflow,
-   bus transaction failure, etc...
- * Receiving clock recovery information in the case that the audio output clock
-   is based on a different oscillator than the oscillator which backs
-   [ZX_CLOCK_MONOTONIC](../syscalls/clock_get.md)
-
-## Operational Details
-
-### Protocol definition
-
-In order to use the C API definitions of the
-[audio](../../system/public/zircon/device/audio.h) protocol, applications and
-drivers simply say
-```C
-#include <device/audio.h>
-```
-
-### Device nodes
-
-Audio stream device nodes **must** be published by drivers using the protocol
-preprocessor symbol given in the table below.  This will cause stream device
-nodes to be published in the locations given in the table.  Applications can
-monitor these directories in order to discover new streams as they are published
-by the drivers.
-
-Stream Type | Protocol | Location
-------------|----------|---------
-Input | `ZX_PROTOCOL_AUDIO_INPUT` | /dev/class/audio-input
-Output | `ZX_PROTOCOL_AUDIO_OUTPUT` | /dev/class/audio-output
-
-### Establishing the stream channel
-
-After opening the device node, client applications may obtain a stream channel
-for subsequent communication using the `AUDIO_IOCTL_GET_CHANNEL` ioctl.  For
-example...
-```C
-zx_handle_t OpenStream(const char* dev_node_path) {
-    zx_handle_t ret = ZX_HANDLE_INVALID;
-    int fd = open(dev_node_path, O_RDONLY);
-
-    if (fd < 0) {
-        LOG("Failed to open \"%s\" (res %d)\n", dev_node_path, fd);
-        return ret;
-    }
-
-    ssize_t res = fdio_ioctl(fd, AUDIO_IOCTL_GET_CHANNEL,
-                             nullptr, 0,
-                             &ret, sizeof(ret));
-    close(fd);
-
-    if (res != ZX_OK)
-        printf("Failed to obtain channel (res %zd)\n", res);
-
-    return ret;
-}
-```
-
-### Client side termination of the stream channel
-
-Clients **may** terminate the connection to the stream at any time simply by
-calling [zx_handle_close(...)](../syscalls/handle_close.md) on the stream
-channel.  Drivers **must** close any active ring-buffer channels established
-using this stream channel and **must** make every attempt to gracefully quiesce
-any on-going streaming operations in the process.
-
-### Sending and receiving messages on the stream and ring-buffer channels
-
-All of the messages and message payloads which may be sent or received over
-stream and ring buffer channels are defined in the
-[audio](../../system/public/zircon/device/audio.h) protocol header.  Messages
-may be sent to the driver using the
-[zx_channel_write(...)](../syscalls/channel_write.md) syscall.  If a response is
-expected, it may be read using the
-[zx_channel_read(...)](../syscalls/channel_read.md) syscall.  Best practice,
-however, is to queue packets for your [channel(s)](../objects/channel.md)
-[port](../objects/port.md) using the
-[zx_port_queue(...)](../syscalls/port_queue.md) syscall, and use the
-[zx_port_wait(...)](../syscalls/port_wait.md) syscall to determine when your set
-of channels have messages (either expected responses or asynchronous
-notifications) to be read.
-
-All messages either sent or received over stream an ring buffer channels are
-prefaced with an `audio_cmd_hdr_t` structure which contains a 32-bit
-transaction ID and an `audio_cmd_hdr_t` enumeration value indicating the
-specific command being requested by the application, the specific command being
-responded to by the driver, or the asynchronous notification being delivered by
-the driver to the application.
-
-When sending a command to the driver, applications **must** place a transaction
-ID in the header's `transaction_id` field which is not equal to
-`AUDIO_INVALID_TRANSACTION_ID`.  If a response to a command needs to be sent by
-the driver to the application, the driver **must** use the transaction ID and
-`audio_cmd_t` values sent by the client during the request.  When sending
-asynchronous notification to the application, the driver **must** use
-`AUDIO_INVALID_TRANSACTION_ID` as the transaction ID for the message.
-Transaction IDs may be used by clients for whatever purpose they desire, however
-if the IDs are kept unique across all transactions in-flight, the
-[zx_channel_call(...)](../syscalls/channel_call.md) may be used to implement a
-simple synchronous calling interface.
-
-### Validation requirements
-
-All drivers **must** validate requests and enforce the protocol described above.
-In case of any violation, drivers **should** immediately quiesce their hardware
-and **must** close the channel, terminating any operations which happen to be in
-flight at the time.  Additionally, they **may** log a message to a central
-logging service to assist in application developers in debugging the cause of
-the protocol violation.  Examples of protocol violation include...
- * Using `AUDIO_INVALID_TRANSACTION_ID` as the value of
-   `message.hdr.transaction_id`
- * Using a value not present in the `audio_cmd_t` enumeration as the value of
-   `message.hdr.cmd`
- * Supplying a payload whose size does not match the size of the request
-   payload for a given command.
-
-## Format Negotiation
-
-### Sample Formats
-
-Sample formats are described using the `audio_sample_format_t` type.  It is a
-bitfield style enumeration which describes either the numeric encoding of the
-uncompressed LPCM audio samples as they reside in memory, or indicating that the
-audio stream consists of a compressed bitstream instead of uncompressed LPCM
-samples.  Refer to the [audio](../../system/public/zircon/device/audio.h)
-protocol header for exact symbol definitions.
-
-Notes
- * With the exception of FORMAT_BITSTREAM, samples are always assumed to
-   use linear PCM encoding.  BITSTREAM is used for transporting compressed
-   audio encodings (such as AC3, DTS, and so on) over a digital interconnect
-   to a decoder device somewhere outside of the system.
- * Be default, multi-byte sample formats are assumed to use host-endianness.
-   If the INVERT_ENDIAN flag is set on the format, the format uses the
-   opposite of host endianness.  eg. A 16 bit little endian PCM audio format
-   would have the INVERT_ENDIAN flag set on it in a when used on a big endian
-   host.  The INVERT_ENDIAN flag has no effect on COMPRESSED, 8BIT or FLOAT
-   encodings.
- * The 32BIT_FLOAT encoding uses specifically the IEE 754 floating point
-   representation.
- * Be default, non-floating point PCM encodings are assumed expressed using
-   2s compliment signed integers.  eg. the bit values for a 16 bit PCM sample
-   format would range from [0x8000, 0x7FFF] with 0x0000 representing zero
-   speaker deflection.  If the UNSIGNED flag is set on the format, the bit
-   values would range from [0x0000, 0xFFFF] with 0x8000 representing zero
-   deflection.
- * When used to set formats, exactly one non-flag bit **must** be set.
- * When used to describe supported formats, any number of non-flag bits **may**
-   be set.  Flags (when present) apply to all of the relevant non-flag bits in
-   the bitfield.  eg.  If a stream supports COMPRESSED, 16BIT and 32BIT_FLOAT,
-   and the UNSIGNED bit is set, it applies only to the 16BIT format.
- * When encoding a smaller sample size in a larger container (eg 20 or 24bit
-   in 32), the most significant bits of the 32 bit container are used while
-   the least significant bits should be zero.  eg. a 20 bit sample would be
-   mapped onto the range [12,32] of the 32 bit container.
-
-> TODO: can we make the claim that the LSBs will be ignored, or do we have to
-> require that they be zero?
-
-> TODO: describe what 20-bit packed audio looks like in memory.  Does it need to
-> have an even number of channels in the overall format?  Should we strike it
-> from this list if we cannot find a piece of hardware which demands this format
-> in memory?
-
-### Enumeration of supported formats
-
-In order to determine the formats supported by a given audio stream,
-applications send an `AUDIO_STREAM_CMD_GET_FORMATS` message over the stream
-channel.  No additional parameters are required.  Drivers **must** respond to
-this request using one or more `audio_stream_cmd_get_formats_resp_t` messages,
-even if only to report that there are no formats currently supported.
-
-### Range structures
-
-Drivers indicate support for formats by sending messages containing zero or more
-`audio_stream_format_range_t` structures.  Each structure contains field which
-describe...
- * A bitmask of supported sample formats.
- * A minimum and maximum number of channels.
- * A set of frame rates.
-
-A single range structure indicates support for each of the combinations of the
-three different sets of values (sample formats, channel counts, and frame
-rates).  For example, if a range structure indicated support for...
- * 16 bit signed LPCM samples
- * 48000, and 44100 Hz frame rates
- * 1 and 2 channels
-
-Then the fully expanded set of supported formats indicated by the range
-structure would be...
- * Stereo 16-bit 48 KHz audio
- * Stereo 16-bit 44.1 KHz audio
- * Mono 16-bit 48 KHz audio
- * Mono 16-bit 44.1 KHz audio
-
-See the Sample Formats section (above) for a description of how sample formats
-are encoded in the `sample_formats` member of a range structure.
-
-Supported channel counts are indicated using a pair of min/max channels fields
-which indicate an exclusive range of channel counts which apply to this range.
-For example, a min/max channels range of [1, 4] would indicate that this audio
-stream supports 1, 2, 3 or 4 channels.  A range of [2, 2] would indicate that
-this audio stream supports only stereo audio.
-
-Supported frame rates are signalled similarly to channel counts using a pair of
-min/max frame per second fields along with a flags field.  While the min/max
-values provide an inclusive range of frame rates, the flags determine how to
-interpret this range.  Currently defined flags include...
-Flag | Definition
------|-----------
-`ASF_RANGE_FLAG_FPS_CONTINUOUS` | The frame rate range is continuous.  All frame rates in the range [min, max] are valid.
-`ASF_RANGE_FLAG_FPS_48000_FAMILY` | The frame rate range includes the members of the 48 KHz family which exist in the range [min, max]
-`ASF_RANGE_FLAG_FPS_44100_FAMILY` | The frame rate range includes the members of the 44.1 KHz family which exist in the range [min, max]
-
-So, conceptually, the valid frame rates are the union of the sets produced by
-applying each of the flags which are set to the inclusive [min, max] range.  For
-example, if both the 48 KHz and 44.1 KHz were set, and the range given was
-[16000, 47999], then the supported frame rates for this range would be
- * 16000 Hz
- * 22050 Hz
- * 32000 Hz
- * 44100 Hz
-
-The official members of the 48 KHz and 44.1 KHz families are
-Family | Frame Rates
--------|------------
-`ASF_RANGE_FLAG_FPS_48000_FAMILY` | 8000 16000 32000 48000 96000 192000 384000 768000
-`ASF_RANGE_FLAG_FPS_44100_FAMILY` | 11025 22050 44100 88200 176400
-
-Drivers **must** set at least one of the flags, or else the set of supported
-frame rates is empty and there was no reason to transmit this range structure.
-Also note that the set of valid frame rates is the union of the frame rates
-produce by applying each of the set flags.  This implies that there is never any
-good reason to set the `ASF_RANGE_FLAG_FPS_CONTINUOUS` in conjunction with any
-of the other flags.  While it is technically legal to do so, drivers **should**
-avoid this behavior.
-
-### Transporting range structures
-
-Range structures are transmitted from drivers to applications using the
-`audio_stream_cmd_get_formats_resp_t` message.  Because of the large number of
-formats which may be supported by a stream, drivers may need to send multiple
-messages in order to enumerate all available modes.  Messages include the
-following fields.
- * A standard `audio_cmd_hdr_t` header.  **All** messages involved in the
-   response to an application request **must** use the transaction ID of the
-   original request, and **must** set the cmd field of the header to
-   `AUDIO_STREAM_CMD_GET_FORMATS`.
- * A `format_range_count` field.  This indicates the total number of format
-   range structures which will be sent in this response to the application.
-   This number **must** be present in **all** messages involved in the response,
-   and **must not** change from message to message.
- * A `first_format_range_ndx` field indicating the zero-based index of the first
-   format range being specified in this particular message.  See below for
-   details.
- * An array of `audio_stream_cmd_get_formats_resp_t` structures which is at most
-   `AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE` elements long.
-
-Drivers **must**
- * Always transmit all of the available audio format ranges.
- * Always transmit the available audio format ranges in ascending index order.
- * Always pack as many ranges as possible in the fixed size message structure.
- * Never overlap index regions or leave gaps.
-
-Given these requirements, if the maximum number of ranges per response were 15,
-and a driver needed to send 35 ranges in response to an application's request,
-then 3 messages in total would be needed, and the `format_range_count` and
-`first_format_range_ndx` fields for each message would be as follows.
-Msg # | `format_range_count` | `first_format_range_ndx`
-------|----------------------|-------------------------
-1 | 35 | 0
-2 | 35 | 15
-3 | 35 | 30
-
-`first_format_range_ndx` **must** never be greater than `format_range_count`,
-however `format_range_count` **may** be zero if an audio stream currently
-supports no formats.  The total number of `audio_stream_format_range_t`
-structures in an `audio_stream_cmd_get_formats_resp_t` message is given by the
-formula
-
-```C
-valid_ranges = MIN(AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE,
-                   msg.format_range_count - msg.first_format_range_ndx);
-```
-
-Drivers **may** choose to always send an entire
-`audio_stream_cmd_get_formats_resp_t` message, or to send a truncated message
-which ends after the last valid range structure in the `format_ranges` array.
-Applications **must** be prepared to receive up to
-`sizeof(audio_stream_cmd_get_formats_resp_t)` bytes for each message, but also
-accept messages as short as
-`offsetof(audio_stream_cmd_get_formats_resp_t, format_ranges)`
-
-> TODO: how do devices signal a change of supported formats (e.g., HDMI hot-plug
-> event)?  Are such devices required to simply remove and republish the device?
-
-> TODO: define how to enumerate supported compressed bitstream formats.
-
-### Setting the desired stream format
-
-In order to select a stream format, applications send an
-`AUDIO_STREAM_CMD_SET_FORMAT` message over the stream channel.  In the message,
-for uncompressed audio streams, the application specifies
- * The frame rate of the stream in Hz using the `frames_per_second` field (in
-   the case of an uncompressed audio stream).
- * The number of channels packed into each frame using the `channels` field.
- * The format of the samples in the frame using the `sample_format` field (see
-   Sample Formats, above)
-
-Success or failure, drivers **must** respond to a request to set format using a
-`audio_stream_cmd_set_format_resp_t`.
-
-In the case of success, drivers **must** set the `result` field of the response
-to `ZX_OK` and **must** return a new ring buffer channel over which streaming
-operations will be conducted.  If a previous ring buffer channel had been
-established and was still active, the driver **must** close this channel and
-make every attempt to gracefully quiesce any on-going streaming operations in
-the process.
-
-In the case of failure, drivers **must** indicate the cause of failure using the
-`result` field of the message and **must not** simply close the stream channel
-as is done for a generic protocol violation.  Additionally, they **may** choose
-to preserve a pre-existing ring-buffer channel, or to simply close such a
-channel as is mandated for a successful operation.
-
-> TODO: specify how compressed bitstream formats will be set
-
-## Hardware Gain Control
-
-### Hardware gain control capability reporting
-
-In order to determine a stream's gain control capabilities, applications send an
-`AUDIO_STREAM_CMD_GET_GAIN` message over the stream channel.  No parameters
-need to be supplied with this message.  All stream drivers **must** respond to
-this message, regardless of whether or not the stream hardware is capable of any
-gain control.  All gain values are expressed using 32 bit floating point numbers
-expressed in dB.
-
-Drivers respond to this message with values which indicate the current gain
-settings of the stream, as well as the stream's gain control capabilities.
-Current gain settings are expressed using a bool/float tuple indicating if the
-stream is currently muted or not along with the current dB gain of the stream.
-Gain capabilities consist of bool and 3 floats.  The bool indicates whether or
-not the stream can be muted.  The floats give the minimum and maximum gain
-settings, along with the `gain step size`.  The `gain step size` indicates the
-smallest increment with which the gain can be controlled counting from the
-minimum gain value.
-
-For example, an amplifier which has 5 gain steps of 7.5 dB each and a maximum
-0 dB gain would indicate a range of (-30.0, 0.0) and a step size of 7.5.
-Amplifiers capable of functionally continuous gain control **may** encode their
-gain step size as 0.0.
-
-Regardless of mute capabilities, drivers for fixed gain streams **must** report
-their min/max gain as (0.0, 0.0).  The gain step size is meaningless in this
-situation, but drivers **should** report their step size as 0.0.
-
-### Setting hardware gain control levels
-
-In order to change a stream's current gain settings, applications send an
-`AUDIO_STREAM_CMD_SET_GAIN` message over the stream channel.  Two parameters
-are supplied with this message, a set of flags which control the request, and a
-float indicating the dB gain which should be applied to the stream.
-
-Three valid flags are currently defined.
- * `AUDIO_SGF_MUTE_VALID`.  Set when the application wishes to set the
-   muted/un-muted state of the stream.  Clear if the application wishes to
-   preserve the current muted/un-muted state.
- * `AUDIO_SGF_GAIN_VALID`.  Set when the application wishes to set the
-   dB gain state of the stream.  Clear if the application wishes to
-   preserve the current gain state.
- * `AUDIO_SGF_MUTE`.  Indicates the application's desired mute/un-mute state
-   for the stream.  Significant only if `AUDIO_SGF_MUTE_VALID` is also set.
-
-Drivers **must** fail the request with an `ZX_ERR_INVALID_ARGS` result if the
-application's request is incompatible with the stream's capabilities.
-Incompatible requests include.
- * The requested gain is less than the minimum support gain for the stream.
- * The requested gain is more than the maximum support gain for the stream.
- * Mute was requested, but the stream does not support an explicit mute.
-
-Presuming that the request is valid, drivers **should** round the request to the
-nearest supported gain step size.  For example, if a stream can control its
-gain on the range from -60.0 to 0.0 dB, a request to set the gain to -33.3 dB
-will result in a gain of -33.5 being applied.  A request for a gain of -33.2 dB
-will result in a gain of -33.0 being applied.
-
-Applications **may** choose not to receive an acknowledgement of a SET_GAIN
-command by setting the `AUDIO_FLAG_NO_ACK` flag on their command.  No response
-message will be sent to the application, regardless of the success or failure of
-the command.  If an acknowledgement was requested by the application, drivers
-respond with a message indicating the success or failure of the operation as
-well as the current gain/mute status of the system (regardless of whether the
-request was a success).
-
-## Determining external latency
-
-The external latency of an audio stream is defined as the amount of time it
-takes outbound audio to travel from the system's interconnect to the speakers
-themselves, or inbound audio to travel from the microphone to the system's
-interconnect.  For example, if an external codec connected to the system using a
-TDM interconnect introduced a 4 frame delay between reception of a TDM frame and
-rendering of the frame at the speakers themselves, the external delay of this
-audio path would be 4 audio frames.
-
-External delay is reported in the `external_delay_nsec` field of a successful
-`AUDIO_STREAM_CMD_SET_FORMAT` response as a non-negative number of nanoseconds.
-Drivers **should** make their best attempt to accurately report the total of all
-of the sources of delay the driver knows about.  Information about this delay
-can frequently be found in codec data sheets, dynamically reported as properties
-of codecs using protocols such as Intel HDA or the USB Audio specifications, or
-reported by down stream devices using mechanisms such as EDID when using HDMI or
-DisplayPort interconnects.
-
-## Plug Detection
-
-In addition to streams being published/unpublished in response to being
-connected or disconnected to/from their bus, streams may have the ability to be
-plugged or unplugged at any given point in time.  For example, a set of USB
-headphones may publish a new output stream when connected to USB, but choose to
-be "hardwired" from a plug detection standpoint.  A different USB audio adapter
-with a standard 3.5mm phono jack might publish an output stream when connected
-via USB, but choose to change its plugged/unplugged state as the user plugs and
-unplugs an analog device via the 3.5mm jack.
-
-The ability to query the currently plugged or unplugged state of a stream, and
-to register for asynchonous notifications of plug state changes (if supported)
-is handled via plug detection messages.
-
-### AUDIO_STREAM_CMD_PLUG_DETECT
-
-In order to determine a stream's plug detection capabilities and current plug
-state, and to enable or disable for asynchronous plug detection notifications,
-applications send a `AUDIO_STREAM_CMD_PLUG_DETECT` command over the stream
-channel.  Drivers respond with a set of `audio_pd_notify_flags_t`, along with a
-timestamp referenced from `ZX_CLOCK_MONOTONIC` indicating the last time the plug
-state changed.
-
-Three valid plug-detect notification flags (PDNF) are currently defined:
- * `AUDIO_PDNF_HARDWIRED` Set when the stream hardware is considered to be
-   "hardwired".  In other words, the stream is considered to be connected as
-   long as the device is published.  Examples include a set of built-in
-   speakers, a pair of USB headphones, or a pluggable audio device with no plug
-   detection functionality.
- * `AUDIO_PDNF_CAN_NOTIFY` Set when the stream hardware is capable of
-   asynchronously detecting that a device's plug state has changed, then sending
-   a notification message if requested by the client.
- * `AUDIO_PDNF_PLUGGED` Set when the stream hardware considers the stream to be
-   currently in the "plugged-in" state.
-
-Drivers for "hardwired" streams **must not** set the `CAN_NOTIFY` flag, and
-**must** set the `PLUGGED` flag.  In addition, the plug state time of the
-response to the `PLUG_DETECT` message **should** always be set to the time at
-which the stream device was published by the driver.
-
-Applications **may** choose not to receive an acknowledgement of a `PLUG_DETECT`
-command by setting the `AUDIO_FLAG_NO_ACK` flag on their command.  No response
-message will be sent to the application, regardless of the success or failure of
-the command.  The most common use for this would be when an application wanted
-to disable asynchronous plug state detection messages and was not actually
-interested in the current plugged/unplugged state of the stream.
-
-### AUDIO_STREAM_PLUG_DETECT_NOTIFY
-
-Applications may request that streams send them asynchronous notifications of
-plug state changes, using the flags field of the `AUDIO_STREAM_CMD_PLUG_DETECT`
-command.
-
-Two valid flags are currently defined:
- * `AUDIO_PDF_ENABLE NOTIFICATIONS` Set by clients in order to request that the
-   stream proactively generate `AUDIO_STREAM_PLUG_DETECT_NOTIFY` messages when
-   its plug state changes, if the stream has this capability.
- * `AUDIO_PDF_DISABLE_NOTIFICATIONS` Set by clients in order to request that NO
-   subsequent `AUDIO_STREAM_PLUG_DETECT_NOTIFY` messages should be sent,
-   regardless of the stream's ability to generate them.
-
-In order to request the current plug state without altering the current
-notification behavior, clients simply set neither `ENABLE` nor `DISABLE` --
-passing either 0, or the value `AUDIO_PDF_NONE`.  Clients **should** not set
-both flags at the same time.  If they do, drivers **must** interpret this to
-mean that the final state of the system should be _disabled_.
-
-Clients which request asynchronous notifications of plug state changes
-**should** always check the `CAN_NOTIFY` flag in the driver response.  Streams
-may be capable of plug detection (i.e. if `HARDWIRED` is not set), yet be
-incapable of detecting plug state changes asynchronously.  Clients may still
-learn of plug state changes, but only by periodically polling the state with
-`PLUG_DETECT` commands.  Drivers for streams which do not set the `CAN_NOTIFY`
-flag are free to ignore enable/disable notification requests from applications,
-and **must** not ever send an `AUDIO_STREAM_PLUG_DETECT_NOTIFY` message. Note
-that even such a driver must always respond to a `AUDIO_STREAM_CMD_PLUG_DETECT`
-message.
-
-## Access control capability detection and signaling
-
-> TODO: specify how this works.  In particular, specify how drivers indicate
-> to applications support for various digital access control mechanisms such as
-> S/PDIF control words and HDCP.
-
-## Stream purpose and association
-
-> TODO: specify how drivers can indicate the general "purpose" of an audio
-> stream in the system (if known), as well as its relationship to other streams
-> (if known).  For example, an embedded target like a phone or a tablet needs to
-> indicate which output stream is the built-in speaker vs. which is the headset
-> jack output.  In addition, it needs to make clear which input stream is the
-> microphone associated with the headset output vs. the builtin speaker.
-
-## Ring-Buffer Channels
-
-### Overview
-
-Generally speaking, client use the ring-buffer channel to establish a shared
-memory buffer, and then start/stop playback/capture of audio stream data.  Once
-started, stream consumption/production is assumed to proceed at the nominal rate
-from the point in time given in a successful response to the start command,
-allowing clients to operate without the need to receive any periodic
-notifications about consumption/production position from the ring buffer itself.
-Note that the ring-buffer will almost certainly have some form of FIFO buffer
-between the memory bus and the audio hardware which causes it to either
-read-ahead in the stream (in the case of playback), or potentially hold onto
-data (in the case of capturing).  In the case of open-loop operation, it is
-important for clients to query the size of this buffer before beginning
-operation so they know how far ahead/behind the stream's nominal inferred
-read/write position they need to stay in order to prevent audio glitching.
-
-Also note that because of the shared buffer nature of the system, and the fact
-that drivers are likely to be DMA-ing directly from this buffer to hardware, it
-is important for clients running on architectures which are not automatically
-cache coherent to be sure that they have properly written-back their cache after
-writing playback data to the buffer, or invalidated their cache before reading
-captured data.
-
-### Determining the FIFO depth
-
-Applications determine stream's FIFO depth using the
-`AUDIO_RB_CMD_GET_FIFO_DEPTH` command.  Drivers **must** return their FIFO
-depth, expressed in bytes, in the `fifo_depth` field of the response.  In order
-to ensure proper playback or capture of audio, applications and drivers must be
-careful to respect this value.  This is to say that drivers must not read beyond
-the nominal playback position of the stream plus this number of bytes when
-playing audio stream data.  Applications must stay this number of bytes behind
-the nominal capture point of the stream when capturing audio stream data.
-
-Once the format of a stream is set and a ring-buffer channel has been opened,
-the driver **must not** change this value.  From an application's point of view,
-it is a constant property of the ring-buffer channel.
-
-### Obtaining a shared buffer
-
-Once an application has successfully set the format of a stream, it will receive
-a new [channel](../objects/channel.md) representing its connection to the
-stream's ring-buffer.  In order to send or receive audio, the application must
-first establish a shared memory buffer.  This is done by sending an
-`AUDIO_RB_CMD_GET_BUFFER` request over the ring-buffer channel.  This may only
-be done while the ring-buffer is stopped.  Applications **must** specify two
-parameters when requesting a ring buffer.
-
-#### `min_ring_buffer_frames`
-The minimum number of frames of audio the client need allocated for the ring
-buffer.  Drivers may need to make this buffer larger in order to meet hardware
-requirement.  Clients **must** use the returned VMOs size (in bytes) to
-determine the actual size of the ring buffer may not assume that the size of
-the buffer (as determined by the driver) is exactly the size they requested.
-Drivers **must** ensure that the size of the ring buffer is an integral number
-of audio frames.
-
-> TODO : Is it reasonable to require that drivers produce buffers which are an
-> integral number of audio frames in length?  It certainly makes the audio
-> client's life easier (client code never needs to split or re-assemble a frame
-> before processing), but it might make it difficult for some audio hardware to
-> meet its requirements without making the buffer significantly larger than the
-> client asked for.
-
-#### `notifications_per_ring`
-The number of position update notifications (`audio_rb_position_notify_t`) the
-client would like the driver to send per cycle through the ring buffer.  Drivers
-should attempt to space the notifications as uniformly throughout the ring as
-their hardware design allows, but clients may not rely on perfectly uniform
-spacing of the update notifications.  Client's are not required to request any
-notifications at all and may choose to run using only start time and FIFO depth
-information to determine the driver's playout or capture position.
-
-Success or failure, drivers **must** respond to a `GET_BUFFER` request using an
-`audio_rb_cmd_get_buffer_resp_t` message.  If the driver fails the request
-because a buffer has already been established and the ring-buffer has already
-been started, it **must not** either stop the ring-buffer, or discard the
-existing shared memory.  If the application requests a new buffer after having
-already established a buffer while the ring buffer is stopped, it **must**
-consider the existing buffer is has to be invalid.  Success or failure, the old
-buffer is now gone.
-
-Upon succeeding, the driver **must** return a handle to a
-[VMO](../objects/vm_object.md) with permissions which allow applications to map
-the VMO into their address space using [zx_vmar_map](../syscalls/vmar_map.md),
-and to read/write data in the buffer in the case of readback, or simply read the
-data in the buffer in the case of capture.  Additionally, the driver **must**
-report the actual number of frames of audio it will use in the buffer via the
-`num_ring_buffer_frames` field of the `audio_rb_cmd_get_buffer_resp_t` message.
-This number **may** be larger than the `min_ring_buffer_frames` request from the
-client but **must not** be either smaller than this number, nor larger than the
-size (when converted to bytes) of the VMO as reported by
-[zx_vmo_get_size()](../syscalls/vmo_get_size.md)
-
-### Starting and Stopping the ring-buffer
-
-Clients may request that a ring-buffer start or stop using the
-`AUDIO_RB_CMD_START` and `AUDIO_RB_CMD_STOP` commands.  Success or failure,
-drivers **must** send a response to these requests.  Attempting to start a
-stream which is already started **must** be considered a failure.  Attempting to
-stop a stream which is already stopped **should** be considered a success.
-Ring-buffers cannot be either stopped or started until after a shared buffer has
-been established using the `GET_BUFFER` operation.
-
-Upon successfully starting a stream, drivers **must** provide their best
-estimate of the time at which their hardware began to transmit or capture the
-stream in the `start_time` field of the response.  This time stamp **must** be
-taken from the clock exposed via the
-[ZX_CLOCK_MONOTONIC](../syscalls/clock_get.md) syscall.  Along with the FIFO
-depth property of the ring buffer, this timestamp allows applications to send or
-receive stream data without the need for periodic position updates from the
-driver.  Along with the outboard latency estimate provided by the stream
-channel, this timestamp allows applications to synchronize presentation of audio
-information across multiple streams, or even multiple devices (provided that an
-external time synchronization protocol is used to synchronize the
-[ZX_CLOCK_MONOTONIC](../syscalls/clock_get.md) timelines across the cohort of
-synchronized devices).
-
-> TODO: Redefine `start_time` to allow it to be an arbitrary 'audio stream
-> clock' instead of the `ZX_CLOCK_MONOTONIC` clock.  If the stream clock is made
-> to count in audio frames since start, then this `start_time` can be replaced
-> with the terms for a segment of a piecewise linear transformation which can be
-> subsequently updated via notifications sent by the driver in the case that the
-> audio hardware clock is rooted in a different oscillator from the system's
-> tick counter.  Clients can then use this transformation either to control the
-> rate of consumption of input streams, or to determine where to sample in the
-> input stream to effect clock correction.
-
-Upon successfully starting a stream, drivers **must** guarantee that no position
-notifications will be sent before the start response has been enqueued into the
-ring-buffer channel.
-
-Upon successfully stopping a stream, drivers **must** guarantee that no position
-notifications will be enqueued into the ring-buffer channel after the stop
-response has been enqueued.
-
-### Position notifications
-
-If requested by the application during the `GET_BUFFER` operation, the driver
-will periodically send updates to the application informing it of its current
-production or consumption position in the buffer.  This position is expressed in
-bytes in the `ring_buffer_pos` field of the `audio_rb_position_notify_t`
-message.  These messages will only ever be sent while the ring-buffer is
-started.  Note, these position notifications indicate where in the buffer the
-driver has consumed or produced data, *not* where the nominal playback or
-capture position is.  Their arrival is not guaranteed to be perfectly uniform
-and they should not be used in an attempt to effect clock recovery.  If an
-application discovers that a driver has consumed past the point in the ring
-buffer where it has written data for playback, the audio presentation has
-certainly glitched.  Applications should increase their clock lead time and be
-certain to stay ahead of this point in the stream in the future.  Likewise,
-applications which are capturing audio data should make no attempt to read
-beyond the point in the ring buffer indicated by the most recent position
-notification sent by the driver.
-
-Driver playback/capture positions *always* begin at byte 0 in the ring buffer
-immediately following a successful start command.  When they reach the size of
-the VMO (as determined by [zx_vmo_get_size(...)](../syscalls/vmo_get_size.md))
-they wrap back to zero.  Drivers are not required to consume or produce data in
-integral numbers of audio frames.  Client whose notion of stream position
-depends on position notifications should take care to request that a sufficient
-number of notifications per ring be sent (minimum 2) and that they are processed
-quickly enough that aliasing does not occur.
-
-### Error notifications
-
-> TODO: define these and what the behavior of drivers should be in case they
-> occur.
-
-### Unexpected application termination
-
-If the other side of a ring buffer control channel is closed for any reason,
-drivers **must** immediately close the control channel, and shut down the ring
-buffer such that playback ring buffers begin to produce silence.  While drivers
-are encouraged to do so in a way which produces a graceful transition to
-silence, the requirement is that the audio stream go silent instead of looping.
-Once the transition to silence is complete, the resources associated with
-playback may be released and reused by the driver.
-
-This way, if an application teminates unexpectedly, the kernel will close the
-application's channels and cause audio playback to stop instead of continuing to
-loop.
-
-### Clock recovery
-
-> TODO: define a way that clock recovery information can be sent to clients in
-> the case that the audio output oscillator is not derived from the
-> `ZX_CLOCK_MONOTONIC` oscillator.  In addition, if the oscillator is slew-able
-> in hardware, provide the ability to discover this capability and control the
-> slew rate.  Given the fact that this oscillator is likely to be shared by
-> multiple streams, it might be best to return some form of system wide clock
-> identifier and provide the ability to obtain a channel on which clock
-> recovery notifications can be delivered to clients and HW slewing command can
-> be sent from clients to the clock.
diff --git a/docs/editors.md b/docs/editors.md
deleted file mode 100644
index 6efb70c..0000000
--- a/docs/editors.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Editor integration for Zircon
-
-## YouCompleteMe
-
-[YouCompleteMe](https://valloric.github.io/YouCompleteMe/) is a semantic
-code-completion engine. YouCompleteMe works natively with Vim but it can also be
-integrated with other editors through [ycmd](https://github.com/Valloric/ycmd).
-
-### Install YouCompleteMe in your editor
-
-See the [installation
-guide](https://github.com/Valloric/YouCompleteMe#installation).
-
-**Note**: Installing YCM on MacOS with Homebrew is not recommended because of
-library compatibility errors. Use the official installation guide instead.
-
-#### gLinux (Googlers only)
-
-(This applies to anyone compiling on gLinux, even if editing over SSHFS on
-MacOS) Ignore the above. Search the Google intranet for "YouCompleteMe" for
-installation instructions.
-
-### Generate compilation database
-
-YouCompleteMe (and other tools like clang-tidy) require a [JSON compilation
-database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) that
-specifies how each file is compiled. This database is normally stored in a file
-called `compile_commands.json`. There are multiple ways to generate this
-database for Zircon.
-
-#### compiledb-generator
-
-[compiledb-generator](https://github.com/nickdiego/compiledb-generator) is the
-recommended way to generate a compilation database. It works by running make in
-no-op mode and parsing the output. Thus it may be less accurate than bear, but
-it should be able to produce a complete database very quickly and without
-requiring a clean build.
-
-To use it, download it from GitHub and run (ensure that compiledb is in your PATH)
-
-```bash
-cd "${ZIRCON_DIR}"
-compiledb -o compile_commands.json -n make <make args>
-```
-
-#### Bear
-
-Bear intercepts `exec(3)` calls made during a build and scrapes commandlines
-that look like C/C++ compiler invocations. Thus it is guaranteed to accurately
-capture the commands used during compilation. However it can't incrementally
-maintain a compilation database, so it requires performing a clean build.
-
-##### Install Bear
-
-You can try using your system's package manager (apt-get, brew) to install Bear,
-but you will need version 2.2.1 or later to match the compiler names that Zircon
-uses. Both homebrew's and Debian testing's versions are sufficiently new. You
-can also fall back to installing it from
-[GitHub](https://github.com/rizsotto/Bear).
-
-##### Invoke Bear on the Zircon build system
-
-You'll need to do this whenever the sources or makefiles change in a way that
-affects includes or types, or when you add/delete/move files, though it doesn't
-hurt to use a stale database.
-
-As easy as:
-
-```bash
-cd "${ZIRCON_DIR}"
-make clean
-bear make -j$(getconf _NPROCESSORS_ONLN)
-```
-
-This will create a `compile_commands.json` file in the local directory.
-
-### Use it
-
-YouCompleteMe will use `compile_commands.json` to do code completion and find
-symbol definitions/declarations. See your editor's YouCompleteMe docs for
-details.
-
-It should pick up the `json` file automatically. If you want to move it out of
-the `zircon` tree, you can move the file to its parent directory.
-
-## See also
-
-For Fuchsia integration, see
-https://fuchsia.googlesource.com/scripts/+/master/vim/README.md
diff --git a/docs/entropy_collection_todos.md b/docs/entropy_collection_todos.md
deleted file mode 100644
index f8591f1..0000000
--- a/docs/entropy_collection_todos.md
+++ /dev/null
@@ -1,129 +0,0 @@
-# Entropy collection TODOs
-
-I'm writing this at the end of my internship to record some of the things I didn't get to.
-
-[TOC]
-
-## Proper use of RdRand
-
-On x86, `RdRand` reads from a deterministic CPRNG (which is seeded from a hardware entropy source).
-The newer `RdSeed` instruction reads from the underlying entropy source directly (well, with some
-post-processing). Currently, we prefer to use `RdSeed` but if that isn't available we fall back on
-`RdRand`. However, we just draw random bits directly from `RdRand`, in contravention of the Intel
-HWRNG guide
-([online here](https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide);
-see section 4.2.5 "Guaranteeing DBRG Reseeding"). We should fix that.
-
-Googlers: see issue ZX-983
-
-## Reseeding the CPRNG during runtime
-
-My hacky virtio driver will reseed the CPRNG on qemu (on a five minute recurring timer). I think
-that's the only entropy source that is currently used to reseed after system startup.
-
-As a start, we should be able to use the entropy sources built into the kernel (RdRand and
-jitterentropy). Just running these on a periodic timer would improve our reseeding story. Note that
-once every 5 minutes is probably more often than we need.
-
-We've talked about reseeding more often if large amounts of data have been drawn from the CPRNG (on
-the order of 2^48 bits, I think).
-
-## Monitoring entropy sources
-
-Entropy sources can potentially fail, either totally or partially.
-
-Total failures like "the device was unplugged" or "the device is not responding to I/O" will
-hopefully be reported by the hardware layer.
-
-Partial failures, where the device returns data but with less entropy than expected, are scarier. We
-should run simple health tests to try to detect partial failures. See for example the continuous
-health tests in NIST SP800-90B, section 4.4. The health tests there are pretty simple and require
-minimal resources. They do require storing some statistics about recent entropy source outputs,
-which presents some security risk.
-
-The NIST SP also suggests (well, requires, but I'm not aware of any immediate plans for
-certification) running startup tests. The NIST startup tests involve running the continuous tests
-over at least 4096 samples (see section 4.3 #12), after which these samples may be reused to seed
-the CPRNG.
-
-Once monitoring is in place, we need to decide how to respond to entropy source failures. If one of
-six different entropy sources fails, we might treat that as a minor hardware failure that gets
-logged. If the system has only one entropy source and it fails, we need to take more drastic action
-(on the order of shutting off the CPRNG or halting the system).
-
-## Userspace RNG drivers
-
-Once DDK settles down, we should add to and improve our RNG drivers. Currently, there are two
-RNG-related drivers: TPM and virtio-rng.
-
-An important requirement is to restrict access to the `zx_cprng_add_entropy` syscall, via a Resource
-or similar mechanism. We should also use this to differentiate between the devices providing
-entropy, for monitoring purposes. It would also be nice if the kernel can send start/stop signals to
-the drivers through this Resource.
-
-Here are some currently unused entropy sources to consider:
-
-- There's an existing TPM driver, which calls `cprng_add_entropy` in its `bind()` callback. We
-  should add support for TPM 2.0, for better coverage.
-
-- There are plenty of commercially available hardware RNGs, often connecting over USB. We could add
-  drivers for those, but it probably makes sense to expect third party drivers instead.
-
-- There's also apparently a hardware RNG built into the SoC in Raspberry Pis, according to
-  [the Raspberry Pi forums](https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=19334&p=273944#p273944).
-  In general we could check other specific targets (i.e. not "pc-x86-64") for hardware RNGs and wire
-  those up. If we're lucky, many of these will be accessible from the kernel for use during or
-  immediately after boot.
-
-- Finally, we could record entropy from hardware IRQs, especially for hard disks, network cards,
-  input devices, and other classic entropy sources. This won't be anywhere near as fast as a
-  dedicated hardware RNG, but it's attractive since a few lines of code added in the right places in
-  our driver stack should enable entropy collection from a wide variety of very common devices.
-
-Googlers: SEC-29
-
-## Jitterentropy
-
-### Replace the noise-generating functions by assembly, and remove '-O0'
-
-Right now, jitterentropy is compiled at optimization level `-O0` (as per the author's
-documentation). The reason is the two noise-generating functions: `jent_lfsr_time` and
-`jent_memaccess`. We should replace these C functions by assembly code (probably by compiling with
-flags `-S -O0`), then compile the rest of jitterentropy with optimizations enabled. After this, we
-should re-test to make sure our entropy estimates remain accurate.
-
-Googlers: SEC-14
-
-### Test jitterentropy more thoroughly
-
-I've been testing on the same handful of physical devices. We should test jitterentropy on a few
-other PCs, RPis, etc.
-
-Googlers: SEC-22
-
-### Test jitterentropy at runtime
-
-Right now, jitterentropy only runs (and was only tested) during the single-core part of the boot
-sequence. We should test jitterentropy during SMP runtime, and consider whether we need to (say)
-disable interrupts or pin ourselves to a CPU inside jitterentropy.
-
-Googlers: ZX-1024
-
-### More tuning
-
-See [the tuning doc](jitterentropy/config-tuning.md). The current universally hard-coded parameters
-seem to be decent, so this probably isn't incredibly urgent. Still, since jitterentropy is on the
-critical path for every single boot and since it will run during runtime as well (hopefully soon!),
-it's probably worth optimizing at some point.
-
-We should probably at least tune jitterentropy on a per-architecture basis, and ideally per-target.
-Note that right now, the `entropy_per_1000_bytes` statistic in
-`kernel/lib/crypto/entropy/jitterentropy_collector.cpp` is hard-coded and not arch/target dependent.
-That should probably also be configurable.
-
-Googlers: ZX-1022
-
-## Cloning the NIST test suite
-
-We may want to clone the NIST test suite into Fuchsia third\_party. This would help us to automate
-the testing and analysis of our entropy sources (Jitterentropy in particular).
diff --git a/docs/entropy_quality_tests.md b/docs/entropy_quality_tests.md
deleted file mode 100644
index 550dd62..0000000
--- a/docs/entropy_quality_tests.md
+++ /dev/null
@@ -1,222 +0,0 @@
-# Entropy quality tests
-
-This document describes how we test the quality of the entropy sources used to
-seed the Zircon CPRNG.
-
-[TOC]
-
-## Theoretical concerns
-
-Approximately speaking, it's sometimes easy to tell that a stream of numbers is
-not random by recognizing a pattern in it. It's impossible to be sure that the
-numbers are truly random. The state of the art seems to be running several
-statistical tests on the data, and hoping to detect any exploitable weaknesses.
-
-The problem of testing for randomness gets more difficult when the random
-numbers aren't perfectly random (when their distributions aren't uniform, or
-when there are some limited correlations between numbers in the sequence). A
-stream of non-perfect random numbers still contains some randomness, but it's
-hard to determine how random it is.
-
-For our purposes, a good measure of how much randomness is contained in a stream
-of non-perfectly random numbers is the min-entropy. This is related to the
-Shannon entropy used in information theory, but is always takes a smaller value.
-The min-entropy controls how much randomness we can reliably extract from the
-entropy source; see, for example
-<https://en.wikipedia.org/wiki/Randomness_extractor#Formal_definition_of_extractors>
-
-From a practical standpoint, we can use the test suite described in US NIST
-SP800-90B to analyze samples of random from an entropy source. A prototype
-implementation for the tests is available from
-<https://github.com/usnistgov/SP800-90B_EntropyAssessment>. The suite takes a
-sample data file (say, 1MB of random bytes) as input. The nice thing about this
-test suite is that it can handle non-perfect RNGs, and it reports an estimate
-for how much min-entropy is contained in each byte of the random data stream.
-
-### The importance of testing unprocessed data
-
-After drawing entropy from our entropy sources, we will mix it into the CPRNG in
-a "safe" way that basically gets rid of detectable correlations and
-distributional imperfections in the raw random byte stream from the entropy
-source. This is a very important thing to do when actually generating random
-numbers to use, but we must avoid this mixing and processing phase when testing
-the entropy source itself.
-
-For a stark example of why it's important to test unprocessed data if we want to
-test our actual entropy sources, here's an experiment. It should run on any
-modern linux system with OpenSSL installed.
-
-    head -c 1000000 /dev/zero >zero.bin
-    openssl enc -aes-256-ctr -in zero.bin -out random.bin -nosalt -k "password"
-
-This takes one million bytes from /dev/zero, encrypts them via AES-256, with a
-weak password and no salt (a terrible crypto scheme, of course!). The fact that
-the output looks like good random data is a sign that AES is working as
-intended, but this demonstrates the risk of estimating entropy content from
-processed data: together, /dev/zero and "password" provide ~0 bits of entropy,
-but our tests are way more optimistic about the resulting data!
-
-For a more concrete Zircon-related example, consider jitterentropy (the RNG
-discussed here: <http://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.html>).
-Jitterentropy draws entropy from variations in CPU timing. The unprocessed data
-are how long it took to run a certain block of CPU- and memory-intensive code
-(in nanoseconds). Naturally, these time data are not perfectly random: there's
-an average value that they center around, with some fluctuations. Each
-individual data sample might be several bits (e.g. a 64-bit integer) but only
-contribute 1 bit or less of min-entropy.
-
-The full jitterentropy RNG code takes several raw time data samples and
-processes them into a single random output (by shifting through a LFSR, among
-other things). If we test the processed output, we're seeing apparent randomness
-both from the actual timing variations and from the LFSR. We want to focus on
-just the timing variation, so we should test the raw time samples. Note that
-jitterentropy's built-in processing can be turned on and off via the
-`kernel.jitterentropy.raw` cmdline.
-
-## Quality test implementation
-
-As mentioned above, the NIST test suite takes a file full of random bytes as
-input. We collect those bytes on a Zircon system (possibly with a thin Fuchsia
-layer on top), then usually export them to a more capable workstation to run the
-test suite.
-
-## Boot-time tests
-
-Some of our entropy sources are read during boot, before userspace is started.
-To test these entropy sources in a realistic environment, we run the tests
-during boot. The relevant code is in
-`kernel/lib/crypto/entropy/quality\_test.cpp`, but the basic idea is that the
-kernel allocates a large static buffer to hold test data during early boot
-(before the VMM is up, so before it's possible to allocate a VMO). Later on, the
-data is copied into a VMO, and the VMO is passed to userboot and devmgr, where
-it's presented as a pseudo-file at `/boot/kernel/debug/entropy.bin`. Userspace
-apps can read this file and export the data (by copying to persistent storage or
-using the network, for example).
-
-In theory, you should be able to build Zircon with entropy collector testing
-enabled using `scripts/entropy-test/make-parallel`, and then you should be able
-to run a single boot-time test with the script
-`scripts/entropy-test/run-boot-test`. The `run-boot-test` script is mostly
-intended to be invoked by other scripts, so it's a little bit rough around the
-edges (for example, most of its arguments are passed via command line options
-like `-a x86-64`, but many of these "options" are in fact mandatory).
-
-Assuming the `run-boot-test` script succeeds, it should produce two files in the
-output directory: `entropy.000000000.bin` and `entropy.000000000.meta`. The
-first is the raw data collected from the entropy source, and the second is a
-simple text file, where each line is a key-value pair. The keys are single words
-matching `/[a-zA-Z0-9_-]+/`, and the values are separated by whitespace matching
-`/[ \t]+/`. This file can be pretty easily parsed via `read` in Bash,
-`str.split()` in Python, or (with the usual caution about buffer overruns)
-`scanf` in C.
-
-In practice, I'm nervous about bit-rot in these scripts, so the next couple
-sections document what the scripts are supposed to do, to make it easier to run
-the tests manually or fix the scripts if/when they break.
-
-### Boot-time tests: building
-
-Since the boot-time entropy test requires that a large block of memory be
-permanently reserved (for the temporary, pre-VMM buffer), we don't usually build
-the entropy test mode into the kernel. The tests are enabled by passing the
-`ENABLE_ENTROPY_COLLECTOR_TEST` flag at build time, e.g. by adding the line
-
-```
-EXTERNAL_DEFINES += ENABLE_ENTROPY_COLLECTOR_TEST=1
-```
-
-to `local.mk`. Currently, there's also a build-time constant,
-`ENTROPY_COLLECTOR_TEST_MAXLEN`, which (if provided) is the size of the
-statically allocated buffer. The default value if unspecified is 1MiB.
-
-### Boot-time tests: configuring
-
-The boot-time tests are controlled via kernel cmdlines. The relevant cmdlines
-are `kernel.entropy-test.*`, documented in
-[kernel\_cmdline.md](kernel_cmdline.md).
-
-Some entropy sources, notably jitterentropy, have parameter values that can be
-tweaked via kernel cmdline. Again, see [kernel\_cmdline.md](kernel_cmdline.md)
-for further details.
-
-### Boot-time tests: running
-
-The boot-time tests will run automatically during boot, as long as the correct
-kernel cmdlines are passed (if there are problems with the cmdlines, error
-messages will be printed instead). The tests run just before the first stage of
-RNG seeding, which happens at LK\_INIT\_LEVEL\_PLATFORM\_EARLY, shortly before
-the heap the VMM are brought up. If running a large test, boot will often slow
-down noticeably. For example, collecting 128kB of data from jitterentropy on
-rpi3 can take around a minute, depending on the parameter values.
-
-## Run-time tests
-
-*TODO(SEC-29): discuss actual user-mode test process*
-
-*Current rough ideas: only the kernel can trigger hwrng reads. To test,
-userspace issues a kernel command (e.g. `k hwrng test`), with some arguments to
-specify the test source and length. The kernel collects random bytes into the
-existing VMO-backed pseudo-file at `/boot/kernel/debug/entropy.bin`, assuming
-that this is safely writeable. Currently unimplemented; blocked by lack of a
-userspace HWRNG driver. Can test the VMO-rewriting mechanism first.*
-
-## Test data export
-
-Test data is saved in `/boot/kernel/debug/entropy.bin` in the Zircon system
-under test. So far I've usually exported the data file manually via `netcp`.
-Other options include `scp` if you build with the correct Fuchsia packages, or
-saving to persistent storage (probably using the Fuchsia `thinfs` FAT
-filesystem, so you can read the files on a non-Zircon computer).
-
-## Running the NIST test suite
-
-*Note: the NIST tests aren't actually mirrored in Fuchsia yet. Today, you need
-to clone the tests from the repo at
-<https://github.com/usnistgov/SP800-90B_EntropyAssessment>.*
-
-The NIST test suite has three entry points (as of the version committed on Oct.
-25, 2016): `iid_main.py`, `noniid_main.py`, and `restart.py`. The two "main"
-scripts perform the bulk of the work. The `iid_main.py` script is meant for
-entropy sources that produce independent, identically distributed data samples.
-Most of the testing is to validate the iid condition. Many entropy sources will
-not be iid, so the `noniid_main.py` test implements several entropy estimators
-that don't require iid data.
-
-Note that the test binaries from the NIST repo are Python scripts without a
-shebang line, so you probably need to explicitly call `python` on the command
-line when invoking them.
-
-The first two scripts take two arguments, both mandatory: the data file to read,
-and the number of significant bits per sample (if less than 8, only the low `N`
-bits will be used from each byte). They optionally accept a `-v` flag to produce
-verbose output or `-h` for help.
-
-The `noniid_main.py` also optionally accepts a `-u <int>` flag that can reduce
-the number of bits below the `N` value passed in the second mandatory argument.
-I'm not entirely sure why this flag is provided; it seems functionally
-redundant, but passing it does change the verbose output slightly. My best guess
-is that this is provided because the noniid Markov test only works on samples of
-at most 6 bits, so 7- or 8-bit datasets will be reduced to their low 6 bits for
-this test. In contrast, all the iid tests can run on 8-bit samples.
-
-A sample invocation of the `iid_main.py` script:
-
-```
-python2 -- $FUCHSIA_DIR/third_party/sp800-90b-entropy-assessment/iid_main.py -v /path/to/datafile.bin 8
-```
-
-The `restart.py` script takes the same two arguments, plus a third argument: the
-min-entropy estimate returned by a previous run of `iid_main.py` or
-`noniid_main.py`. This document doesn't describe restart tests. For now, see
-NIST SP800-90B for more details.
-
-## Future directions
-
-### Automation
-
-It would be nice to automate the process of building, configuring, and running a
-quality test. As a first step, it should be easy to write a shell script to
-perform these steps. Even better would be to use the testing infrastructure to
-run entropy collector quality tests this automatically, mostly to reduce bit-rot
-in the test code. Failing automation, we have to rely on humans to periodically
-run the tests (or to fix the tests when they break).
diff --git a/docs/errors.md b/docs/errors.md
deleted file mode 100644
index 215b7b0..0000000
--- a/docs/errors.md
+++ /dev/null
@@ -1,138 +0,0 @@
-# Errors
-
-This describes the set of userspace-exposed errors used in Zircon. The first section provides the
-canonical names and description of each error code. The second section provides the concrete values.
-
-Within the kernel, errors are typically resulted as variables of type `status_t` and errors are
-defined by macros of the form `ZX_ERR_CANONICAL_NAME` e.g. `ZX_ERR_INTERNAL`. All error cases are negative
-values and success is represented by a non-negative value.
-
-In userspace the syscall dispatch layer (libzircon) exposes the result values as variables of type
-`zx_status_t` that currently use the same spelling and values as the kernel for errors, but which
-will transition to using 0 for success and positive values for errors.
-
-See [Kernel internal errors](kernel_internal_errors.md) for a list of kernel-internal values.
-
-## Descriptions
-
-Each category represents a class of errors. The first error code in each category is the generic
-code for that category and is used when no more specific code applies. Further error codes (if any)
-within a category represent particular types of errors within the class. In general, more specific
-error codes are preferred where possible.
-
-Errors are described in terms of an operation, arguments, a subject, and identifiers. An operation
-is typically a function or system call. Arguments are typically the parameters to the call. The
-subject of an operation is the primary object the operation acts on, typically a handle and
-typically passed as the first argument. Identifiers are typically numbers or strings intended to
-unambiguously identify a resource used in the operation.
-
-## Categories
-
-### Success
-**ZX\_OK**
- Operation succeeded.
-
-### General errors
-
-These indicate that the system hit a general error while attempting the operation.
-
-**INTERNAL**
-  The system encountered an otherwise unspecified error while performing the operation.
-
-**NOT\_SUPPORTED**
-  The operation is not supported, implemented, or enabled.
-
-**NO\_RESOURCES**
-  The system was not able to allocate some resource needed for the operation.
-
-**NO\_MEMORY**
-  The system was not able to allocate memory needed for the operation.
-
-### Parameter errors
-
-These indicate that the caller specified a parameter that does not specify a valid operation or that
-is invalid for the specified operation.
-
-**INVALID\_ARGUMENT**
-  An argument is invalid.
-
-**WRONG\_TYPE**
-  The subject of the operation is the wrong type to perform the operation.
-  Example: Attempting a message\_read on a thread handle.
-
-**BAD\_SYSCALL**
-  The specified syscall number is invalid.
-
-**BAD\_HANDLE**
-  A specified handle value does not refer to a handle.
-
-**OUT\_OF\_RANGE**
-  An argument is outside the valid range for this operation.
-   Note: This is used when the argument may be valid if the system changes state, unlike
-    INVALID\_ARGUMENT which is used when the argument will never be valid.
-
-**BUFFER\_TOO\_SMALL**
-  A caller provided buffer is too small for this operation.
-
-### Precondition or state errors
-
-These indicate that the operation could not succeed because the preconditions for the operation are
-not satisfied or the system is unable to complete the operation in its current state.
-
-**BAD\_STATE**
-  The system is unable to perform the operation in its current state.
-   Note: FAILED\_PRECONDITION is a reserved alias for this error
-
-**NOT\_FOUND**
-  The requested entity was not found.
-
-**TIMED\_OUT**
-  The time limit for the operation elapsed before the operation completed.
-
-**ALREADY\_EXISTS**
-  An object with the specified identifier already exists.
-  Example: Attempting to create a file when a file already exists with that name.
-
-**ALREADY\_BOUND**
-  The operation failed because the named entity is already owned or controlled by another entity.
-  The operation could succeed later if the current owner releases the entity.
-
-**HANDLE\_CLOSED**
-  A handle being waited on was closed.
-
-**REMOTE\_CLOSED**
-  The operation failed because the remote end of the subject of the operation was closed.
-
-**UNAVAILABLE**
-  The subject of the operation is currently unable to perform the operation.
-  Note: This is used when there's no direct way for the caller to observe when the subject will be
-  able to perform the operation and should thus retry.
-
-**SHOULD\_WAIT**
-  The operation cannot be performed currently but potentially could succeed if the caller waits for
-  a prerequisite to be satisfied, for example waiting for a handle to be readable or writable.
-  Example: Attempting to read from a channel that has no messages waiting but has an open
-  remote will return **SHOULD\_WAIT**. Attempting to read from a channel that has no messages
-  waiting and has a closed remote end will return **REMOTE\_CLOSED**.
-
-### Permission errors
-
-**ACCESS\_DENIED**
-  The caller did not have permission to perform the specified operation.
-
-### Input/output errors
-
-**IO**
-  Otherwise unspecified error occurred during I/O.
-
-**IO\_REFUSED**
-  The entity the I/O operation is being performed on rejected the operation.
-  Example: an I2C device NAK'ing a transaction or a disk controller rejecting an invalid command.
-
-**IO\_DATA\_INTEGRITY**
-  The data in the operation failed an integrity check and is possibly corrupted.
-  Example: CRC or Parity error.
-
-**IO\_DATA\_LOSS**
-  The data in the operation is currently unavailable and may be permanently lost.
-  Example: A disk block is irrecoverably damaged.
diff --git a/docs/exceptions.md b/docs/exceptions.md
deleted file mode 100644
index 0734e18..0000000
--- a/docs/exceptions.md
+++ /dev/null
@@ -1,449 +0,0 @@
-# Exception handling
-
-## Introduction
-
-Exception handling support in Zircon was inspired by similar support in Mach.
-
-Exceptions are mainly used for debugging. Outside of debugging
-one generally uses ["signals"](signals.md).
-Signals are the core Zircon mechanism for observing state changes on
-kernel Objects (a Channel becoming readable, a Process terminating,
-an Event becoming signaled, etc).
-See [Signals](#signals) below.
-
-The reader is assumed to have a basic understanding of what exceptions like
-segmentation faults, etc. are, as well as Posix signals.
-This document does not explain what a segfault is, nor what "exception
-handling" is at a high level (though it certainly can if there is a need).
-
-## The basics
-
-Exceptions are handled from userspace by binding a Zircon Port to the
-Exception Port of the desired object: thread, process, or job.
-This is done with the
-[**task_bind_exception_port**() system call](syscalls/task_bind_exception_port.md).
-
-Example:
-
-```cpp
-  zx_handle_t eport;
-  auto status = zx_port_create(0, &eport);
-  // ... check status ...
-  uint32_t options = 0;
-  // The key is anything that is useful to the code handling the exception.
-  uint64_t child_key = 0;
-  // Assume |child| is a process handle.
-  status = zx_task_bind_exception_port(child, eport, child_key, options);
-  // ... check status ...
-```
-
-When an exception occurs a report is sent to the port,
-after which the receiver must reply with either "exception handled"
-or "exception not handled".
-The thread stays paused until then, or until the port is unbound,
-either explicitly or by the port being closed (say because the handler
-process exited). If the port is unbound, for whatever reason, the
-exception is processed as if the reply was "exception not handled".
-
-Here is a simple exception handling loop.
-The main components of it are the call to the
-[**port_wait**() system call](syscalls/port_wait.md)
-to wait for an exception, or anything else that's interesting, to happen,
-and the call to the
-[**task_resume_from_exception**() system call](syscalls/task_resume_from_exception.md)
-to indicate the handler is finished processing the exception.
-
-```cpp
-  while (true) {
-    zx_port_packet_t packet;
-    auto status = zx_port_wait(eport, ZX_TIME_INFINITE, packet);
-    // ... check status ...
-    if (packet.key != child_key) {
-      // ... do something else, depending on what else the port is used for ...
-      continue;
-    }
-    if (!ZX_PKT_IS_EXCEPTION(packet.type)) {
-      // ... probably a signal, process it ...
-      continue;
-    }
-    zx_koid_t packet_tid = packet.exception.tid;
-    zx_handle_t thread;
-    status = zx_object_get_child(child, packet_tid, ZX_RIGHT_SAME_RIGHTS,
-                                 &thread);
-    // ... check status ...
-    bool handled = process_exception(child, thread, &packet);
-    uint32_t resume_flags = 0;
-    if (!handled)
-      resume_flags |= ZX_RESUME_TRY_NEXT;
-    status = zx_task_resume_from_exception(thread, eport, resume_flags);
-    // ... check status ...
-    status = zx_handle_close(thread);
-    assert(status == ZX_OK);
-  }
-```
-
-To unbind an exception port, pass **ZX_HANDLE_INVALID** for the
-exception port:
-
-```cpp
-  uint32_t options = 0;
-  status = zx_task_bind_exception_port(child, ZX_HANDLE_INVALID,
-                                       key, options);
-  // ... check status ...
-```
-
-## Exception processing details
-
-When a thread gets an exception it is paused while the kernel processes
-the exception. The kernel looks for bound exception ports in a specific order
-and if it finds one an "exception report" is sent to the bound port.
-
-Exception reports are messages sent through the port with a specific format
-defined by the port message protocol. The packet contents are defined by
-the *zx_packet_exception_t* type defined in
-[`<zircon/syscalls/port.h>`](../system/public/zircon/syscalls/port.h).
-
-The exception handler is expected to read the message, decide how it
-wants to process the exception, and then resume the thread that got the
-exception with the
-[**task_resume_from_exception**() system call](syscalls/task_resume_from_exception.md).
-
-Resuming the thread can be done in either of two ways:
-
-- Resume execution of the thread as if the exception has been resolved.
-If the thread gets another exception then exception processing begins
-again anew. An example of when one would do this is when resuming after a
-debugger breakpoint.
-
-```cpp
-  auto status = zx_task_resume_from_exception(thread, eport, 0);
-  // ... check status ...
-```
-
-- Resume exception processing, marking the exception as "unhandled" by the
-current handler, thus giving the next exception port in the search order a
-chance to process the exception. An example of when one would do this is
-when the exception is not one the handler intends to process.
-
-```cpp
-  auto status = zx_task_resume_from_exception(thread, eport,
-      ZX_RESUME_TRY_NEXT);
-  // ... check status ...
-```
-
-If there are no remaining exception ports to try the kernel terminates
-the process, as if *zx_task_kill(process)* was called.
-The return code of a process terminated by an exception is an
-unspecified non-zero value.
-The return code can be obtained with *zx_object_get_info(ZX_INFO_PROCESS)*.
-Example:
-
-```cpp
-    zx_info_process_t info;
-    auto status = zx_object_get_info(process, ZX_INFO_PROCESS, &info,
-                                     sizeof(info), nullptr, nullptr);
-    // ... check status ...
-    int return_code = info.return_code;
-```
-
-Resuming the thread requires a handle of the thread, which the handler
-may not yet have. The handle is obtained with the
-[**object_get_child**() system call](syscalls/object_get_child.md).
-The pid,tid necessary to look up the thread are contained in the
-exception report. See the above trivial exception handler example.
-
-## Types of exceptions
-
-At a high level there are two types of exceptions: architectural and
-synthetic.
-Architectural exceptions are things like a segment fault (e.g., dereferencing
-the NULL pointer) or executing an undefined instruction. Synthetic exceptions
-are things like thread start and exit notifications. Synthetic
-exceptions are further distinguished as being debugger-specific or not.
-
-We use the term "general exceptions" to describe non-debugger-specific
-exceptions, and we use the term "debugger-specific exceptions" to describe
-exceptions that are only sent to debuggers.
-
-Exception types are enumerated in the *zx_excp_type_t* enum defined
-in [`<zircon/syscalls/exception.h>`](../system/public/zircon/syscalls/exception.h).
-
-## Exception ports
-
-Exception ports are where exception packets get sent to.
-A zircon port is bound to the exception port of a task object
-(thread, process, job) and then exception packets are sent to that
-port in a manner described below.
-
-Zircon supports the following general exception ports:
-
-- *Thread*
-- *Process*
-- *Job*
-
-Zircon also supports the following debugger-specific exception ports:
-
-- *Process Debugger*
-- *Job Debugger*
-
-There is only one of each kind of these per associated object.
-Note that processes and jobs have two distinct exception ports:
-the general one and a debugger-specific one.
-
-To bind to the debugger exception port pass
-**ZX_EXCEPTION_PORT_DEBUGGER** in *options* when binding an
-exception port to the process or job.
-
-## Exception delivery
-
-### Debugger only exceptions
-
-Debugger-only exceptions are only sent to one potential handler
-if it is present: a debugger.
-
-The job debugger exception port receives the following synthetic
-exception:
-
-- **ZX_EXCP_PROCESS_STARTING**
-
-The process debugger exception port receives the following synthetic
-exceptions:
-
-- **ZX_EXCP_THREAD_STARTING**
-- **ZX_EXCP_THREAD_EXITING**
-
-Note that there is no **ZX_EXCP_PROCESS_EXITING** exception.
-Also note that the process debugger exception port also receives
-all general exceptions: We want the debugger to be notified if, for
-example, a thread being debugged segfaults.
-
-### General exceptions
-
-Exceptions that are not debugger specific are all architectural
-exceptions and all synthetic exceptions not previously listed as
-debugger-specific, e.g., **ZX_EXCP_POLICY_ERROR**.
-
-General exceptions are sent to exception ports in the following order:
-
-- *Process Debugger* - The process debugger exception port is for
-things like zxdb and gdb.
-
-- *Thread* - This is for exception ports bound directly to the thread.
-
-- *Process* - This is for exception ports bound directly to the process.
-
-- *Job* - This is for exception ports bound to the process's job. Note that
-jobs have a hierarchy. First the process's job is searched. If it has a bound
-exception port then the exception is delivered to that port. If it does not
-have a bound exception port, or if the handler returns **ZX_RESUME_TRY_NEXT**,
-then that job's parent job is searched, and so on right up to the root job.
-
-If no exception port handles the exception then the kernel finishes
-exception processing by killing the process.
-
-Notes:
-
-- The search order is different than that of Mach. In Zircon the
-debugger exception port is tried first, before all other ports.
-This is useful for at least a few reasons:
-
-    - Allows "fix and continue" debugging. E.g., if a thread gets a segfault,
-      the debugger user can fix the segfault and resume the thread before the
-      thread even knows it got a segfault.
-    - Makes debugger breakpoints easier to reason about.
-
-## Interaction with thread suspension
-
-Exceptions and thread suspensions are treated separately.
-In other words, a thread can be both in an exception and be suspended.
-This can happen if the thread is suspended while waiting for a response
-from an exception handler. The thread stays paused until it is resumed
-for both the exception and the suspension:
-
-```cpp
-  auto status = zx_task_resume_from_exception(thread, eport, 0);
-  // ... check status ...
-```
-
-and one for the suspension:
-
-```cpp
-  // suspend_token was obtained by an earlier call to zx_task_suspend().
-  auto status = zx_handle_close(suspend_token);
-  // ... check status ...
-```
-
-The order does not matter.
-
-## Signals
-
-Signals are the core Zircon mechanism for observing state changes on
-kernel Objects (a Channel becoming readable, a Process terminating,
-an Event becoming signaled, etc). See ["signals"](signals.md).
-
-Unlike exceptions, signals do not require a response from an exception handler.
-On the other hand signals are sent to whomever is waiting on the thread's
-handle, instead of being sent to the exception port that could be
-bound to the thread's process.
-This is generally not a problem for exception handlers because they generally
-keep track of thread handles anyway. For example, they need the thread handle
-to resume the thread after an exception.
-
-It does, however, mean that an exception handler must wait on the
-port *and* every thread handle that it wishes to monitor.
-Fortunately, one can reduce this to continuing to just have to wait
-on the port by using the
-[**object_wait_async**() system call](syscalls/object_wait_async.md)
-to have signals regarding each thread sent to the port.
-In other words, there is still just one system call involved to wait
-for something interesting to happen.
-
-```cpp
-  uint64_t key = some_key_denoting_the_thread;
-  bool is_suspended = thread_is_suspended(thread);
-  zx_signals_t signals = ZX_THREAD_TERMINATED;
-  if (is_suspended)
-    signals |= ZX_THREAD_RUNNING;
-  else
-    signals |= ZX_THREAD_SUSPENDED;
-  uint32_t options = ZX_WAIT_ASYNC_ONCE;
-  auto status = zx_object_wait_async(thread, eport, key, signals, options);
-  // ... check status ...
-```
-
-When the thread gets any of the specified signals a **ZX_PKT_TYPE_SIGNAL_ONE**
-packet will be sent to the port. After processing the signal the above
-call to **zx_object_wait_async**() must be done again, that is the nature
-of **ZX_WAIT_ASYNC_ONCE**.
-
-*Note:* There is both an exception and a signal for thread termination.
-The **ZX_EXCP_THREAD_EXITING** exception is sent first. When the thread
-is finally terminated the **ZX_THREAD_TERMINATED** signal is sent.
-
-The following signals are relevant to exception handlers:
-
-- **ZX_THREAD_TERMINATED**
-- **ZX_THREAD_SUSPENDED**
-- **ZX_THREAD_RUNNING**
-
-When a thread is started **ZX_THREAD_RUNNING** is asserted.
-When it is suspended **ZX_THREAD_RUNNING** is deasserted, and
-**ZX_THREAD_SUSPENDED** is asserted. When the thread is resumed
-**ZX_THREAD_SUSPENDED** is deasserted and **ZX_THREAD_RUNNING** is
-asserted. When a thread terminates both **ZX_THREAD_RUNNING** and
-**ZX_THREAD_SUSPENDED** are deasserted and **ZX_THREAD_TERMINATED**
-is asserted. However, signals are OR'd into the state maintained by
-the port thus you may see any combination of requested signals
-when **zx_port_wait**() returns.
-
-## Comparison with Posix (and Linux)
-
-This table shows equivalent terms, types, and function calls between
-Zircon and Posix/Linux for exceptions and the kinds of things exception
-handlers generally do.
-
-```
-Zircon                       Posix/Linux
-------                       -----------
-Exception/Signal             Signal
-ZX_EXCP_*                    SIG*
-task_bind_exception_port()   ptrace(ATTACH,DETACH)
-task_suspend()               kill(SIGSTOP),ptrace(KILL(SIGSTOP))
-handle_close(suspend_token)  kill(SIGCONT),ptrace(CONT)
-task_resume_from_exception   kill(SIGCONT),ptrace(CONT)
-N/A                          kill(everything_other_than_SIGKILL)
-task_kill()                  kill(SIGKILL)
-TBD                          signal()/sigaction()
-port_wait()                  wait*()
-various                      W*() macros from sys/wait.h
-zx_packet_exception_t        siginfo_t
-zx_exception_context_t       siginfo_t
-thread_read_state            ptrace(GETREGS,GETREGSET)
-thread_write_state           ptrace(SETREGS,SETREGSET)
-process_read_memory          ptrace(PEEKTEXT)
-process_write_memory         ptrace(POKETEXT)
-```
-
-Zircon does not have asynchronous signals like SIGINT, SIGQUIT, SIGTERM,
-SIGUSR1, SIGUSR2, and so on.
-
-Another significant different from Posix is that the exception handler
-is always run on a separate thread.
-
-## Example programs
-
-There are three good example programs in the Zircon tree to use to
-further one's understanding of exceptions and signals in Zircon.
-
-- `system/core/svchost/crashsvc`
-
-`crash-svc` is the crash service thread hosted in `svchost`. It
-delegates the processing of the crash to either `ulib/inspector` in a
-standalone zircon build or to a upper layer FIDL service if the build
-contains garnet.
-
-- `system/utest/exception`
-
-The basic exception handling testcase.
-
-- `system/utest/debugger`
-
-Testcase for the rest of the system calls a debugger would use, beyond
-those exercised by system/utest/exception.
-There are tests for segfault recovery, reading/writing thread registers,
-reading/writing process memory, as well as various other tests.
-
-## Todo
-
-There are a few outstanding issues:
-
-- signal()/sigaction() replacement
-
-In Posix one is able to specify handlers for particular signals,
-whereas in Zircon there is currently just the exception port,
-and the handler is expected to understand all possible exceptions.
-This is tracked as ZX-560.
-
-- W*() macros from sys/wait.h
-
-When a process exits because of an exception, no information is provided
-on which exception the process got (e.g., segfault). At present only a
-non-specific non-zero exit code is returned.
-This is tracked as ZX-1974.
-
-- more selectiveness in which exceptions to see
-
-In addition to ZX-560 IWBN to be able to specify to the kernel
-when binding the exception port that one is only interested in
-seeing a particular subset of exceptions.
-This is tracked as ZX-990.
-
-- ability to say exception ports unbind quietly when closed
-
-The default behaviour when a port is unbound implicitly due to
-the port being closed is to resume exception processing, i.e.,
-given the next exception port in the search order a try.
-In debugging sessions it is useful to change the default behavior
-and have the port unbound "quietly", in other words leave things as
-is, with the thread still waiting for an exception response.
-This is because debuggers can crash, and obliterating an active debugging
-session is counterproductive.
-This is tracked as ZX-988.
-
-- rights for binding exception ports and getting debuggable thread handles
-
-In Zircon rights can, in general, only be taken away, they can't be added.
-However, one doesn't want to have "debuggability" a default right:
-debuggers are privileged processes. Thus we need a way to obtain handles
-with sufficient rights for debugging.
-This is tracked as ZX-509, ZX-911, and ZX-923.
-
-- no way to obtain currently bound port or to chain handlers
-
-Currently, there's no way to get the currently bound exception port.
-Possible use-cases are for debugging purposes (e.g, to see what's going on
-in the system).
-Another possible use-case is to allow chaining exception handlers, though for
-the case of in-process chaining it's likely better to use a
-signal()/sigaction() replacement (see ZX-560).
-This is tracked as ZX-1216.
diff --git a/docs/fit_promise_guide.md b/docs/fit_promise_guide.md
deleted file mode 100644
index 0ecb8fd..0000000
--- a/docs/fit_promise_guide.md
+++ /dev/null
@@ -1,361 +0,0 @@
-# `fit::promise<>` User Guide
-
-Welcome! You probably dislike writing code in C++ that describes multi-step asynchronous operations.
-
-`fit::promise<>` [[1](https://fuchsia.googlesource.com/zircon/+/master/system/ulib/fit/include/lib/fit/promise.h)] makes this a bit easier. This guide covers common problems in asynchronous control flow programming and offers common usage patterns which solve those problems in the `fit::promise<>` library.
-
-## What makes asynchronous code challenging?
-
-Within the `fit::promise<>` library an asynchronous task is defined as one that is made up of multiple *synchronous* blocks of code with explicit suspend points.
-
-When defining an asynchronous task, there must be solutions for the following problems:
-
-1) **Expressing the flow of control**: how is the *sequence* of synchronous blocks and how data flows between them expressed? How is this done in an understandable way?
-2) **Management of state & resources**: what intermediate state is needed to support task execution, and what external resources must be captured? How is this expressed and how is it done safely?
-
-
-## Terminology
-* `fit::promise<>` is a move-only object made up of a collection of lambdas or callbacks that describes an asynchronous task which eventually produces a value or an error.
-* a *handler function* is a callback provided at promise creation.
-* a *continuation function* is a callback provided to various *methods of continuation* on an existing promise.
-* a `fit::executor` is responsible for scheduling and executing promises. Promises do not run until their ownership has been transferred to a `fit::executor`. At this point the executor is responsible for its scheduling and execution.
-* `fit::context` is optionally passed to handler and continuation functions to gain access to the `fit::executor` and to low-level suspend and resume controls.
-## Building & executing your first `fit::promise<>`
-
-Let's write a simple promise.
-
-```cpp
-#include <lib/fit/promise.h>
-
-...
-fit::promise<> p = fit::make_promise([] {
-  // This is a handler function.
-
-  auto world_is_flat = AssessIfWorldIsFlat();
-  if (world_is_flat) {
-    return fit::error();
-  }
-  return fit::ok();
-});
-```
-
-`p` now contains a promise that describes a simple task.
-
-In order to run the promise, it must be scheduled it on an implementation of `fit::executor`. The most commonly used executor is an `async::Executor` [[2](https://fuchsia.googlesource.com/garnet/+/master/public/lib/async_promise/executor.h)] which schedules callbacks on an `async_dispatcher_t`. For the purposes of testing and exploration, there is also  `fit::single_threaded_executor` and its associated method `fit::run_single_threaded()`[[3](https://fuchsia.googlesource.com/zircon/+/master/system/ulib/fit/include/lib/fit/single_threaded_executor.h#72)] which is used here.
-
-```cpp
-// When a promise is scheduled, the `fit::executor` takes ownership of it.
-fit::result<> result = fit::run_single_threaded(std::move(p));
-assert(result.is_ok());
-```
-
-## Building a more complex `fit::promise<>`
-
-### Return, error types & resolution states
-
-As mentioned above, the template arguments for `fit::promise<>` represent the return and error types:
-
-```cpp
-fit::promise<ReturnType, ErrorType>
-```
-
-The error type can be omitted and it will take the default error type of `void` (e.g. `fit::promise<MyReturnType>` is equivalent to `fit::promise<MyReturnType, void>`).
-
-During execution, a promise must eventually reach one of the following states:
-
-* Success: the handler function or the last continuation function (see below) has returned `fit::ok()`.
-* Error: the handler function or some continuation function has returned `fit::error()`, *and* no subsequent continuation function has intercepted it.
-* Abandoned: the promise was destroyed before resolving to either Success or Error.
-
-### `.then()`, `.and_then()`, `.or_else()`: Chaining asynchronous blocks
-
-Often complex tasks can be decomposed into smaller more granular tasks. Each of these tasks needs to be asynchronously executed, but if there is some dependency between the tasks, there is a need to preserve them. This can be achieved through different combinators, such as:
-
-* `fit::promise::then()` becomes useful for defining task dependency, as execute task 1 then task 2, regardless of task 1's status.
-```cpp
-auto execute_task_1_then_task_2 = fit::make_promise([] () -> fit::result<ReturnType, ErrorType> {
-     …..;
-}).then([] (fit::result<ReturnType, ErrorType>& result) {
-    if (result.is_ok()) {
-      ...
-    } else {  // result.is_error()
-      ...
-    }
-});
-```
-
-* `fit::promise::and_then()` becomes useful for defining task dependency only in the case of task 1's success.
-```cpp
-auto execute_task_1_then_task_2 = fit::make_promise([] () {
-  ...
-}).and_then([] (ReturnType& success_value) {
-  ...
-});
-```
-
-* `fit::promise::or_else()` becomes useful for defining task dependency only in the case of task 1's failure.
-```cpp
-auto execute_task_1_then_task_2 = fit::make_promise([] () {
-  ...;
-}).or_else([] (ErrorType& failure_value) {
-  ...;
-});
-```
-
-### `fit::join_promises()` & `fit::join_promise_vector()`: Executing in parallel
-
-Sometimes, multiple promises can be executed with no dependencies between them, but the aggregate result is a dependency of the next asynchronous step. In this case, `fit::join_promises()` and `fit::join_promise_vector()` are used to join on the results of multiple promises.
-
-`fit::join_promises()` is used when each promise is referenced by a variable. `fit::join_promises()` supports heterogeneous promise types.
-```cpp
-auto DoImportantThingsInParallel() {
-  auto promise1 = FetchStringFromDbAsync("foo");
-  auto promise2 = InitializeFrobinatorAsync();
-  return fit::join_promises(std::move(promise1), std::move(promise2))
-      .and_then([](std::tuple<fit::result<std::string>, fit::result<Frobinator>> results) {
-        return fit::ok(results.get<0>.value() + results.get<1>.value().GetFrobinatorSummary());
-      });
-}
-```
-
-`fit::join_promise_vector()` is used when the promises are stored in `std::vector<>`. This has the added constraint that all promises must be homogeneous (be of the same type).
-
-### `return fit::make_promise()`: Chaining or branching by returning new promises
-
-It may become useful to defer the decision of which promises to chain together until runtime. This method is in contrast with chaining that is performed syntactically (through the use of consecutive `.then()`, `.and_then()` and `.or_else()` calls).
-
-```cpp
-fit::make_promise(...)
-  .then(fit::result<> result) {
-    if (result.is_ok()) {
-      return fit::make_promise(...); // Do work in success case.
-    } else {
-      return fit::make_promise(...); // Error case.
-    }
-  });
-```
-
-This pattern is also useful to decompose what could be a long promise into smaller readable chunks, such as by having a continuation function return the result of `DoImportantThingsInParallel()` from the example above.
-
-> NOTE: See the gotcha "Handlers / continuation functions can return ..." below.
-
-### Declaring and keeping intermediate state alive
-
-Some tasks require state be kept alive only so long as the promise itself is either pending or executing. This state is not suited to be moved into any given lambda due to its need to be shared, nor is it appropriate to transfer ownership to a longer-lived container due to a desire for its lifecycle to be coupled to the promise.
-
-Although not the only solution, usage of both `std::unique_ptr<>` and `std::shared_ptr<>` are common patterns:
-
-#### `std::unique_ptr<>`
-
-```cpp
-fit::promise<> MakePromise() {
-  struct State {
-    int i;
-  };
-  // Create a single std::unique_ptr<> container for an instance of State and capture
-  // raw pointers to the state in the handler and continuations.
-  //
-  // Ownership of the underlying memory is transferred to a lambda passed to
-  // `.inspect()`. |state| will die when the returned promise is resolved or is abandoned.
-  auto state = std::make_unique<State>();
-  state->i = 0;
-  return fit::make_promise([state = state.get()] {
-    state->i++;
-  }).and_then([state = state.get()] {
-    state->i--;
-  }).inspect([state = std::move(state)] {});
-}
-```
-
-#### `std::shared_ptr<>`
-
-fit::promise<> MakePromise() {
-  struct State {
-    int i;
-  };
-  // Rely on shared_ptr's reference counting to destroy |state| when it is safe to do so.
-  auto state = std::make_shared<State>();
-  state->i = 0;
-  return fit::make_promise([state] {
-    state->i++;
-  }).and_then([state] {
-    state->i--;
-  });
-}
-### `fit::scope`: Abandoning promises to avoid memory safety violations
-
-`fit::scope` becomes useful to tie the lifecycle of a `fit::promise<>` to a resource in memory. For example:
-
-```cpp
-#include <lib/fit/scope.h>
-
-class A {
- public:
-  fit::promise<> MakePromise() {
-    // Capturing |this| is dangerous: the returned promise will be scheduled
-    // and executed in an unknown context. Use |scope_| to protect against
-    // possible memory safety violations.
-    //
-    // The call to `.wrap_with(scope_)` abandons the promise if |scope_| is destroyed. Since
-    // |scope_| and |this| share the same lifecycle, it is safe to capture |this|.
-    return fit::make_promise([this] {
-      // |foo_| is critical to the operation!
-      return fit::ok(foo_.Frobinate());
-    }).wrap_with(scope_);
-  }
-
- private:
-  Frobinator foo_;
-  fit::scope scope_;
-};
-
-void main() {
-  auto a = std::make_unique<A>();
-  auto promise = a->MakePromise();
-  a.reset();
-  // |promise| will not run any more, even if scheduled, protected access to the out-of-scope
-  // resources.
-}
-```
-### `fit::sequencer`: Blocking a promise on a separate promise's completion
-
-TODO: you can .wrap_with(sequencer) to block this promise on the completion of the last promise wrapped with the same sequencer object
-
-```cpp
-#include <lib/fit/sequencer.h>
-// TODO
-```
-### `fit::bridge`: integrating with callback-based async functions
-
-TODO: fit::bridge is useful to chain continuation off a callback-based async function
-
-```cpp
-#include <lib/fit/bridge.h>
-// TODO
-```
-### `fit::bridge`: decoupling execution of a single chain of continuation
-
-TODO: fit::bridge is also useful to decouple one chain of continuation into two promises that can be executed on different `fit::executor` instances
-
-## Common gotchas
-
-### It is not possible to change ErrorType mid-promise
-
-A promise's handler and all of its continuations may have different *ResultTypes*, but they must all share the same *ErrorType*.
-
-TODO: write more and how to get around this problem
-
-### Handlers / continuation functions can return fit::result<> or a new fit::promise<>, not both
-
-You may wish to write a handler which return a `fit::promise<>` in one conditional branch and a `fit::ok()` or `fit::error()` in another. This is illegal because there is no way for the compiler to cast a `fit::result<>` to a `fit::promise<>`.
-
-The workaround is to return a `fit::promise<>` that resolves to the result you want:
-
-```cpp
-auto a = fit::make_promise([] {
-  if (condition) {
-    return MakeComplexPromise();
-  }
-  return fit::make_promise([] { return fit::ok(); });
-});
-```
-### Continuation signatures
-
-Have you seen an error message like this?
-
-```
-../../zircon/system/ulib/fit/include/lib/fit/promise_internal.h:342:5: error: static_assert failed "The provided handler's last argument was expected to be of type V&, const V&, or V (if the value is copy-constructible).  Please refer to the combinator's documentation for
- a list of supported handler function signatures."
-```
-
-or:
-
-```
-../../zircon/system/ulib/fit/include/lib/fit/promise.h:288:5: error: static_assert failed due to requirement '::fit::internal::is_continuation<fit::internal::and_then_continuation<fit::promise_impl<fit::function_impl<16, false, fit::result<fuchsia::modular::storymodel::St
-oryModel, void> (fit::context &)> >, (lambda at ../../peridot/bin/sessionmgr/story/model/ledger_story_model_storage.cc:222:17)>, void>::value' "Continuation type is invalid.  A continuation is a callable object with this signature: fit::result<V, E>(fit::context&)."
-```
-
-This most likely means that one of the continuation functions has a signature that isn't valid. The valid signatures for different continuation functions are shown below:
-
-For `.then()`:
-
-```cpp
-.then([] (fit::result<V, E>& result) {});
-.then([] (const fit::result<V, E>& result) {});
-.then([] (fit::result<V, E> result) {});  // Only if V and E are copyable
-.then([] (fit::context& c, fit::result<V, E>& result) {});
-.then([] (fit::context& c, const fit::result<V, E>& result) {});
-.then([] (fit::context& c, fit::result<V, E> result) {});  // Only if V and E are copyable
-```
-
-For `.and_then()`:
-
-```cpp
-.and_then([] (V& success_value) {});
-.and_then([] (const V& success_value) {});
-.and_then([] (V success_value) {});  // Only if V is copyable
-.and_then([] (fit::context& c, V& success_value) {});
-.and_then([] (fit::context& c, const V& success_value) {});
-.and_then([] (fit::context& c, V& success_value) {});  // Only if V is copyable
-```
-
-For `.or_else()`:
-
-```cpp
-.or_else([] (E& error_value) {});
-.or_else([] (const E& error_value) {});
-.or_else([] (E error_value) {});  // Only if E is copyable
-.or_else([] (fit::context& c, E& error_value) {});
-.or_else([] (fit::context& c, const E& error_value) {});
-.or_else([] (fit::context& c, E& error_value) {});  // Only if E is copyable
-```
-
-For `.inspect()`:
-
-```cpp
-// TODO
-```
-### Captures and Argument Lifecycle
-
-Promises are composed of handler and continuation functions that are usually
-lambdas. Care must be taken when constructing lambda capture lists to avoid
-capturing memory that is will not be valid when the handler or continuation in
-question executes.
-
-For example, this promise captures memory that is guaranteed to be invalid
-by the time Foo() returns (and thus, when the returned promise is scheduled and
-executed).
-
-```cpp
-fit::promise<> Foo() {
-  int i;
-  return fit::make_promise([&i] {
-    i++;  // |i| is only valid within the scope of Foo().
-  });
-}
-```
-
-Instances in real code are more nuanced. A slightly less obvious example:
-
-```cpp
-fit::promise<> Foo() {
-  return fit::make_promise([i = 0] {
-    return fit::make_promise([&i] {
-      i++;
-    });
-  });
-}
-```
-
-`fit::promise` eagerly destroys handler and continuation functions: the outer-most
-handler will be destroyed once it returns the inner-most handler. See
-"Declaring and keeping intermediate state alive" above for the correct pattern
-to use in this case.
-
-## >>> sections to write
-
-* converting from one error type to another
-* fit::bridge
-* common gotchas:
-captured state lifecycle
-
diff --git a/docs/fuzzing_fidl.md b/docs/fuzzing_fidl.md
deleted file mode 100644
index d27de0a..0000000
--- a/docs/fuzzing_fidl.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Fuzzing the fidl host tools
-
-Some notes on fuzzing the `system/host/fidl` parser using [afl-fuzz](http://lcamtuf.coredump.cx/afl/).
-
-## Build afl-fuzz
-
-Download and build it, then:
-```
-export AFL_PATH=~/src/afl-2.41b/
-```
-with whatever path you downloaded and built it with.
-
-## Patch the parser to not trap on invalid syntax
-
-afl-fuzz treats crashes as interesting but the parser currently calls `__builtin_trap()` when it encounters invalid
-syntax. Remove that line in [parser.h](../system/host/fidl/parser.h) - its in the `Parser::Fail()` method.
-
-## Build the `fidl` tool with afl-fuzz's instrumentation
-
-Clear any existing build and then build with the afl-fuzz compiler wrappers.
-
-```
-cd $ZIRCON_DIR
-rm -fr build-x86
-PATH=$PWD/prebuilt/downloads/clang+llvm-x86_64-linux/bin/:$PATH:$AFL_PATH make \
-  build-x86/tools/fidl HOST_TOOLCHAIN_PREFIX=afl-
-```
-adjusting if you're not building on x86 Linux, etc.
-
-## Run the fuzzer
-
-The parser includes some examples to use as inputs. As fidl becomes adopted we can expand our inputs to include all of
-the different interfaces declared across our tree, but for now we use what's in `system/host/fidl/examples`.
-
-```
-$AFL_PATH/afl-fuzz -i system/host/fidl/examples -o fidl-fuzz-out build-x86/tools/fidl dump '@@'
-```
-
-## Results
-
-Running against the source from early May 2017, there were no crashes or hangs after two days of fuzzing on a fairly
-fast machine. It ran over 300 million executions.
diff --git a/docs/getting_started.md b/docs/getting_started.md
deleted file mode 100644
index dc840db..0000000
--- a/docs/getting_started.md
+++ /dev/null
@@ -1,290 +0,0 @@
-# Quick Start Recipes
-
-## Checking out the Zircon source code
-
-*** note
-NOTE: The Fuchsia source includes Zircon. See Fuchsia's
-[Getting Started](https://fuchsia.googlesource.com/docs/+/master/getting_started.md)
-doc. Follow this doc to work on only Zircon.
-***
-
-The Zircon Git repository is located
-at: https://fuchsia.googlesource.com/zircon
-
-To clone the repository, assuming you setup the $SRC variable
-in your environment:
-```shell
-git clone https://fuchsia.googlesource.com/zircon $SRC/zircon
-```
-
-For the purpose of this document, we will assume that Zircon is checked
-out in $SRC/zircon and that we will build toolchains, QEMU, etc alongside
-that.  Various make invocations are presented with a "-j32" option for
-parallel make.  If that's excessive for the machine you're building on,
-try -j16 or -j8.
-
-## Preparing the build environment
-
-### Ubuntu
-
-On Ubuntu this should obtain the necessary pre-reqs:
-```
-sudo apt-get install texinfo libglib2.0-dev autoconf libtool bison libsdl-dev build-essential
-```
-
-### macOS
-Install the Xcode Command Line Tools:
-```
-xcode-select --install
-```
-
-Install the other pre-reqs:
-
-* Using Homebrew:
-```
-brew install wget pkg-config glib autoconf automake libtool
-```
-
-* Using MacPorts:
-```
-port install autoconf automake libtool libpixman pkgconfig glib2
-```
-
-## Install Toolchains
-
-If you're developing on Linux or macOS, there are prebuilt toolchain binaries available.
-Just run this script from your Zircon working directory:
-
-```
-./scripts/download-prebuilt
-```
-
-If you would like to build the toolchains yourself, follow the instructions later
-in the document.
-
-## Build Zircon
-
-Build results will be in $SRC/zircon/build-{arm64,x64}
-
-The variable $BUILDDIR in examples below refers to the build output directory
-for the particular build in question.
-
-```
-cd $SRC/zircon
-
-# for aarch64
-make -j32 arm64
-
-# for x64
-make -j32 x64
-```
-
-### Using Clang
-
-To build Zircon using Clang as the target toolchain, set the
-`USE_CLANG=true` variable when invoking Make.
-
-```
-cd $SRC/zircon
-
-# for aarch64
-make -j32 USE_CLANG=true arm64
-
-# for x64
-make -j32 USE_CLANG=true x64
-```
-
-## Building Zircon for all targets
-
-```
-# The -r enables release builds as well
-./scripts/buildall -r
-```
-
-Please build for all targets before submitting to ensure builds work
-on all architectures.
-
-## QEMU
-
-You can skip this if you're only testing on actual hardware, but the emulator
-is handy for quick local tests and generally worth having around.
-
-See [QEMU](qemu.md) for information on building and using QEMU with zircon.
-
-
-## Build Toolchains (Optional)
-
-If the prebuilt toolchain binaries do not work for you, you can build your
-own from vanilla upstream sources.
-
- * The GCC toolchain is used to build Zircon by default.
- * The Clang toolchain is used to build Zircon if you build with
-   `USE_CLANG=true` or `USE_ASAN=true`.
- * The Clang toolchain is also used by default to build host-side code, but
-   any C++14-capable toolchain for your build host should work fine.
-
-Build one or the other or both, as needed for how you want build Zircon.
-
-### GCC Toolchain
-
-We use GNU `binutils` 2.30(`*`) and GCC 8.2(`**`), configured with
-`--enable-initfini-array --enable-gold`, and with `--target=x86_64-elf
---enable-targets=x86_64-pep` for x86-64 or `--target=aarch64-elf` for ARM64.
-
-For `binutils`, we recommend `--enable-deterministic-archives` but that switch
-is not necessary to get a working build.
-
-For GCC, it's necessary to pass `MAKEOVERRIDES=USE_GCC_STDINT=provide` on the
-`make` command line.  This should ensure that the `stdint.h` GCC installs is
-one that works standalone (`stdint-gcc.h` in the source) rather than one that
-uses `#include_next` and expects another `stdint.h` file installed elsewhere.
-
-Only the C and C++ language support is required and no target libraries other
-than `libgcc` are required, so you can use various `configure` switches to
-disable other things and make your build of GCC itself go more quickly and use
-less storage, e.g. `--enable-languages=c,c++ --disable-libstdcxx
---disable-libssp --disable-libquadmath`.  See the GCC installation
-documentation for more details.
-
-You may need various other `configure` switches or other prerequisites to
-build on your particular host system.  See the GNU documentation.
-
-(`*`) The `binutils` 2.30 release has some harmless `make check` failures in
-the `aarch64-elf` and `x86_64-elf` configurations.  These are fixed on the
-upstream `binutils-2_30-branch` git branch, which is what we actually build.
-But the 2.30 release version works fine for building Zircon; it just has some
-spurious failures in its own test suite.
-
-(`**`) As of 2008-6-15, GCC 8.2 has not been released yet.  There is no
-released version of GCC that works for building Zircon without backporting
-some fixes.  What we actually use is the upstream `gcc-8-branch` git branch.
-
-### Clang/LLVM Toolchain
-
-We use a trunk snapshot of Clang and update to new snapshots frequently.  Any
-build of recent-enough Clang with support for `x86_64` and `aarch64` compiled
-in should work.  You'll need a toolchain that also includes the runtime
-libraries.  We normally also use the same build of Clang for the host as well
-as for the `*-fuchsia` targets.  See
-[here](https://fuchsia.googlesource.com/docs/+/master/development/build/toolchain.md)
-for details on how we build Clang.
-
-### Set up `local.mk` for toolchains
-
-If you're using the prebuilt toolchains, you can skip this step, since
-the build will find them automatically.
-
-Create a GNU makefile fragment in `local.mk` that points to where you
-installed the toolchains:
-
-```makefile
-CLANG_TOOLCHAIN_PREFIX := .../clang-install/bin/
-ARCH_x86_64_TOOLCHAIN_PREFIX := .../gnu-install/bin/x86_64-elf-
-ARCH_arm64_TOOLCHAIN_PREFIX := .../gnu-install/bin/aarch64-elf-
-```
-
-Note that `CLANG_TOOLCHAIN_PREFIX` should have a trailing slash, and the
-`ARCH_*_TOOLCHAIN_PREFIX` variables for the GNU toolchains should include the
-`${target_alias}-` prefix, so that simple command names like `gcc`, `ld`, or
-`clang` can be appended to the prefix with no separator.  If the `clang` or
-`gcc` in your `PATH` works for Zircon, you can just use empty prefixes.
-
-## Copying files to and from Zircon
-
-With local link IPv6 configured, the host tool ./build-ARCH/tools/netcp
-can be used to copy files.
-
-```
-# Copy the file myprogram to Zircon
-netcp myprogram :/tmp/myprogram
-
-# Copy the file myprogram back to the host
-netcp :/tmp/myprogram myprogram
-```
-
-## Including Additional Userspace Files
-
-The Zircon build creates a bootfs image containing necessary userspace components
-for the system to boot (the device manager, some device drivers, etc).  The kernel
-is capable of including a second bootfs image which is provided by QEMU or the
-bootloader as a ramdisk image.
-
-To create such a bootfs image, use the zbi tool that's generated as part of
-the build.  It can assemble a bootfs image for either source directories (in which
-case every file in the specified directory and its subdirectories are included) or
-via a manifest file which specifies on a file-by-file basis which files to include.
-
-```
-$BUILDDIR/tools/zbi -o extra.bootfs @/path/to/directory
-
-echo "issue.txt=/etc/issue" > manifest
-echo "etc/hosts=/etc/hosts" >> manifest
-$BUILDDIR/tools/zbi -o extra.bootfs manifest
-```
-
-On the booted Zircon system, the files in the bootfs will appear under /boot, so
-in the above manifest example, the "hosts" file would appear at /boot/etc/hosts.
-
-## Network Booting
-
-Network booting is supported via two mechanisms: Gigaboot and Zirconboot.
-Gigaboot is an EFI based bootloader whereas zirconboot is a mechanism that
-allows a minimal zircon system to serve as a bootloader for zircon.
-
-On systems that boot via EFI (such as Acer and NUC), either option is viable.
-On other systems, zirconboot may be the only option for network booting.
-
-### Via Gigaboot
-The [GigaBoot20x6](https://fuchsia.googlesource.com/zircon/+/master/bootloader) bootloader speaks a simple network boot protocol (over IPV6 UDP)
-which does not require any special host configuration or privileged access to use.
-
-It does this by taking advantage of IPV6 Link Local Addressing and Multicast,
-allowing the device being booted to advertise its bootability and the host to find
-it and send a system image to it.
-
-If you have a device (for example a Broadwell or Skylake Intel NUC) running
-GigaBoot20x6 first create a USB drive [manually](https://fuchsia.googlesource.com/zircon/+/master/docs/targets/acer12.md#How-to-Create-a-Bootable-USB-Flash-Drive)
-or (Linux only) using the [script](https://fuchsia.googlesource.com/scripts/+/master/build-bootable-usb-gigaboot.sh).
-
-```
-$BUILDDIR/tools/bootserver $BUILDDIR/zircon.bin
-
-# if you have an extra bootfs image (see above):
-$BUILDDIR/tools/bootserver $BUILDDIR/zircon.bin /path/to/extra.bootfs
-```
-
-By default bootserver will continue to run and every time it observes a netboot
-beacon it will send the kernel (and bootfs if provided) to that device.  If you
-pass the -1 option, bootserver will exit after a successful boot instead.
-
-
-### Via Zirconboot
-Zirconboot is a mechanism that allows a zircon system to serve as the
-bootloader for zircon itself. Zirconboot speaks the same boot protocol as
-Gigaboot described above.
-
-To use zirconboot, pass the `netsvc.netboot=true` argument to zircon via the
-kernel command line. When zirconboot starts, it will attempt to fetch and boot
-into a zircon system from a bootserver running on the attached host.
-
-## Network Log Viewing
-
-The default build of Zircon includes a network log service that multicasts the
-system log over the link local IPv6 UDP.  Please note that this is a quick hack
-and the protocol will certainly change at some point.
-
-For now, if you're running Zircon on QEMU with the -N flag or running on hardware
-with a supported ethernet interface (ASIX USB Dongle or Intel Ethernet on NUC),
-the loglistener tool will observe logs broadcast over the local link:
-
-```
-$BUILDDIR/tools/loglistener
-```
-
-## Debugging
-
-For random tips on debugging in the zircon environment see
-[debugging](debugging/tips.md).
-
-## Contribute changes
-* See [contributing.md](contributing.md).
diff --git a/docs/h2md.md b/docs/h2md.md
deleted file mode 100644
index 03e16e2..0000000
--- a/docs/h2md.md
+++ /dev/null
@@ -1,27 +0,0 @@
-
-# h2md - Header To Markdown
-
-h2md is a simple tool for generating markdown api docs from headers.
-
-It avoids any dependencies and has a very simple line-oriented parser.
-Whitespace at the start and end of lines is ignored.
-
-Lines starting with `//@` are either a directive to h2md or the start of
-a chunk of markdown.
-
-Markdown chunks are continued on every following line starting
-with `//`.  They are ended by a blank line, or a line of source code.
-
-A line of source code after a markdown chunk is expected to be a function
-or method declaration, which will be terminated (on the same line or
-a later line) by a `{` or `;`. It will be presented as a code block.
-
-Lines starting with `//{` begin a code block, and all following lines
-will be code until a line starting with `//}` is observed.
-
-To start a new document, use a doc directive, like
-`//@doc(docs/my-markdown.md)`
-
-From the start of a doc directive until the next doc directive, any
-generated markdown will be sent to the file specified in the directive.
-
diff --git a/docs/hacking.md b/docs/hacking.md
deleted file mode 100644
index 2305935..0000000
--- a/docs/hacking.md
+++ /dev/null
@@ -1,161 +0,0 @@
-# Notes for hacking on Zircon
-
-This file contains a random collection of notes for hacking on Zircon.
-
-[TOC]
-
-## Building and testing
-
-To ensure changes don't impact any of the builds it is recommended that
-that one tests all targets, with gcc and clang, and in both release mode
-and debug mode. This can all be executed with the `buildall` script:
-
-```./scripts/buildall -q -c -r```
-
-From the zircon shell run `k ut all` to execute all kernel tests, and
-`runtests` to execute all userspace tests.
-
-## Syscall generation
-
-Syscall support is generated from
-system/public/zircon/syscalls.abigen.  A host tool called
-[abigen](../system/host/abigen) consumes that file and produces output
-for both the kernel and userspace in a variety of languages. This
-output includes C or C++ headers for both the kernel and userspace,
-syscall entry points, other language bindings, and so on.
-
-This tool is invoked as a part of the build, rather than checking in
-its output.
-
-## Terminal navigation and keyboard shortcuts
-
-* Alt+Tab switches between VTs
-* Alt+F{1,2,...} switches directly to a VT
-* Alt+Up/Down scrolls up and down by lines
-* Shift+PgUp/PgDown scrolls up and down by half page
-* Ctrl+Alt+Delete reboots
-
-## Kernel panics
-
-Since the kernel can't reliably draw to a framebuffer when the GPU is enabled,
-the system will reboot by default if the kernel crashes or panics.
-
-If the kernel crashes and the system reboots, the log from the kernel panic will
-appear at `/boot/log/last-panic.txt`, suitable for viewing, downloading, etc.
-
-> Please attach your `last-panic.txt` and `zircon.elf` files to any kernel
-> panic bugs you file.
-
-If there's a `last-panic.txt`, that indicates that this is the first successful
-boot since a kernel panic occurred.
-
-It is not "sticky" -- if you reboot cleanly, it will be gone, and if you crash
-again it will be replaced.
-
-To disable reboot-on-panic, pass the kernel commandline argument
-[`kernel.halt-on-panic=true`](kernel_cmdline.md#kernel_halt_on_panic_bool).
-
-## Low level kernel development
-
-For kernel development it's not uncommon to need to monitor or break things
-before the gfxconsole comes up.
-
-To force-enable log output to the legacy serial console on an x64 machine, pass
-"kernel.serial=legacy".  For other serial configurations, see the kernel.serial
-docs in [kernel_cmdline.md](kernel_cmdline.md).
-
-To enable the early console before the graphical console comes up use the
-``gfxconsole.early`` cmdline option. More information can be found in
-[kernel_cmdline.md](kernel_cmdline.md).
-Enabling ``startup.keep-log-visible``will ensure that the kernel log stays
-visible if the gfxconsole comes up after boot. To disable the gfxconsole
-entirely you can disable the video driver it is binding to via ``driver.<driver
-name>.disable``.
-On a skylake system, all these options together would look something like:
-
-```
-$ tools/build-x86/bootserver build-x86/zircon.bin -- gfxconsole.early driver.intel-i915-display.disable
-```
-
-To directly output to the console rather than buffering it (useful in the event
-of kernel freezes) you can enable ``ENABLE_KERNEL_LL_DEBUG`` in your ``local.mk`` like so:
-
-```
-EXTERNAL_KERNEL_DEFINES := ENABLE_KERNEL_LL_DEBUG=1
-
-```
-
-There is also a kernel cmdline parameter kernel.bypass-debuglog, which can be set
-to true to force output to the console instead of buffering it. The reason we have
-both a compile switch and a cmdline parameter is to facilitate prints in the kernel
-before cmdline is parsed to be forced to go to the console. The compile switch setting
-overrides the cmdline parameter (if both are present). Note that both the compile switch
-and the cmdline parameter have the side effect of disabling irq driven uart Tx.
-
-More information on ``local.mk`` can be found via ``make help``
-
-## Changing the compiler optimization level of a module
-
-You can override the default `-On` level for a module by defining in its
-`rules.mk`:
-
-```
-MODULE_OPTFLAGS := -O0
-```
-
-## Requesting a backtrace
-
-### From within a user process
-
-For debugging purposes, the system crashlogger can print backtraces by
-request. It requires modifying your source, but in the absence of a
-debugger, or as a general builtin debug mechanism, this can be useful.
-
-```
-#include <lib/backtrace-request/backtrace-request.h>
-
-void my_function() {
-  backtrace_request();
-}
-```
-
-When `backtrace\_request` is called, it causes an
-exception used by debuggers for breakpoint handling.
-If a debugger is not attached, the system crashlogger will
-process the exception, print a backtrace, and then resume the thread.
-
-### From a kernel thread
-
-```
-#include <kernel/thread.h>
-
-void my_function() {
-  thread_print_backtrace(get_current_thread(), __GET_FRAME(0));
-}
-```
-
-## Exporting debug data during boot
-
-To support testing the system during early boot, there is a mechanism to export
-data files from the kernel to the /boot filesystem. To export a data file,
-create a VMO, give it a name, and pass it to userboot with handle\_info of type
-PA\_VMO\_DEBUG\_FILE (and argument 0). Then userboot will automatically pass it
-through to devmgr, and devmgr will export the VMO as a file at the path
-
-```
-/boot/kernel/<name-of-vmo>
-```
-
-This mechanism is used by the entropy collector quality tests to export
-relatively large (~1 Mbit) files full of random data.
-
-## How to deprecate #define constants
-
-One can create a deprecated typedef and have the constant definition
-cast to that type.  The ensuing warning/error will include the name
-of the deprecated typedef.
-
-```
-typedef int ZX_RESUME_NOT_HANDLED_DEPRECATION __attribute__((deprecated));
-#define ZX_RESUME_NOT_HANDLED ((ZX_RESUME_NOT_HANDLED_DEPRECATION)(2))
-```
diff --git a/docs/handles.md b/docs/handles.md
deleted file mode 100644
index 5fdf7e3..0000000
--- a/docs/handles.md
+++ /dev/null
@@ -1,138 +0,0 @@
-# Zircon Handles
-
-[TOC]
-
-## Basics
-Handles are kernel constructs that allows user-mode programs to
-reference a kernel object. A handle can be thought as a session
-or connection to a particular kernel object.
-
-It is often the case that multiple processes concurrently access
-the same object via different handles. However, a single handle
-can only be either bound to a single process or be bound to
-kernel.
-
-When it is bound to kernel we say it's 'in-transit'.
-
-In user-mode a handle is simply a specific number returned by
-some syscall. Only handles that are not in-transit are visible
-to user-mode.
-
-The integer that represents a handle is only meaningful for that
-process. The same number in another process might not map to any
-handle or it might map to a handle pointing to a completely
-different kernel object.
-
-The integer value for a handle is any 32-bit number except
-the value corresponding to ZX_HANDLE_INVALID.
-
-For kernel-mode, a handle is a C++ object that contains three
-logical fields:
-
-+ A reference to a kernel object
-+ The rights to the kernel object
-+ The process it is bound to (or if it's bound to kernel)
-
-The '[rights](rights.md)' specify what operations on the kernel object
-are allowed. It is possible for a single process to have two different
-handles to the same kernel object with different rights.
-
-## Using Handles
-There are many syscalls that create a new kernel object
-and which return a handle to it. To name a few:
-+ [`zx_event_create`](syscalls/event_create.md)
-+ [`zx_process_create`](syscalls/process_create.md)
-+ [`zx_thread_create`](syscalls/thread_create.md)
-
-These calls create both the kernel object and the first
-handle pointing to it. The handle is bound to the process that
-issued the syscall and the rights are the default rights for
-that type of kernel object.
-
-There is only one syscall that can make a copy of a handle,
-which points to the same kernel object and is bound to the same
-process that issued the syscall:
-+ [`zx_handle_duplicate`](syscalls/handle_duplicate.md)
-
-There is one syscall that creates an equivalent handle (possibly
-with fewer rights), invalidating the original handle:
-+ [`zx_handle_replace`](syscalls/handle_replace.md)
-
-There is one syscall that just destroys a handle:
-+ [`zx_handle_close`](syscalls/handle_close.md)
-
-There are two syscalls that takes a handle bound to calling
-process and binds it into kernel (puts the handle in-transit):
-+ [`zx_channel_write`](syscalls/channel_write.md)
-+ [`zx_socket_share`](syscalls/socket_share.md)
-
-There are three syscalls that takes an in-transit handle and
-binds it to the calling process:
-+ [`zx_channel_read`](syscalls/channel_read.md)
-+ [`zx_channel_call`](syscalls/channel_call.md)
-+ [`zx_socket_accept`](syscalls/socket_accept.md)
-
-The channel and socket syscalls above are used to transfer a handle from
-one process to another. For example it is possible to connect
-two processes with a channel. To transfer a handle the source process
-calls `zx_channel_write` or `zx_channel_call` and then the destination
-process calls `zx_channel_read` on the same channel.
-
-Finally, there is a single syscall that gives a new process its
-bootstrapping handle, that is, the handle that it can use to
-request other handles:
-+ [`zx_process_start`](syscalls/process_start.md)
-
-The bootstrapping handle can be of any transferable kernel object but
-the most reasonable case is that it points to one end of a channel
-so this initial channel can be used to send further handles into the
-new process.
-
-## Garbage Collection
-If a handle is valid, the kernel object it points to is guaranteed
-to be valid. This is ensured because kernel objects are ref-counted
-and each handle holds a reference to its kernel object.
-
-The opposite does not hold. When a handle is destroyed it does not
-mean its object is destroyed. There could be other handles pointing
-to the object or the kernel itself could be holding a reference to
-the kernel object. An example of this is a handle to a thread; the
-fact that the last handle to a thread is closed it does not mean that
-the thread has been terminated.
-
-When the last reference to a kernel object is released, the kernel
-object is either destroyed or the kernel marks the object for
-garbage collection; the object will be destroyed at a later time
-when the current set of pending operations on it are completed.
-
-## Special Cases
-+ When a handle is in-transit and the channel or socket it was written
-to is destroyed, the handle is closed.
-+ Debugging sessions (and debuggers) might have special syscalls to
-get access to handles.
-
-## Invalid Handles and handle reuse
-
-It is an error to pass to any syscall except for `zx_object_get_info`
-the following values:
-
-+ A handle value that corresponds to a closed handle
-+ The **ZX_HANDLE_INVALID** value, except for `zx_handle_close` syscall
-
-The kernel is free to re-use the integer values of closed handles for
-newly created objects. Therefore, it is important to make sure that proper
-handle hygiene is observed:
-
-+ Don't have one thread close a given handle and another thread use the
-  same handle in a racy way. Even if the second thread is also closing it.
-+ Don't ignore **ZX_ERR_BAD_HANDLE** return codes. They usually mean the
-  code has a logic error.
-
-Detecting invalid handle usage can be automated by using the
-**ZX_POL_BAD_HANDLE** Job policy with **ZX_POL_ACTION_EXCEPTION** to
-generate an exception when a process under such job object attempts any of
-the of the mentioned invalid cases.
-
-## See Also
-[Objects](objects.md),
-[Rights](rights.md)
diff --git a/docs/jitterentropy/config-basic.md b/docs/jitterentropy/config-basic.md
deleted file mode 100644
index 4158034..0000000
--- a/docs/jitterentropy/config-basic.md
+++ /dev/null
@@ -1,333 +0,0 @@
-# Jitterentropy: basic configuration
-
-The jitterentropy library is written by Stephan Mueller, is available at
-<https://github.com/smuellerDD/jitterentropy-library>, and is documented at
-<http://www.chronox.de/jent.html>. In Zircon, it's used as a simple entropy
-source to seed the system CPRNG.
-
-This document describes and analyzes two (independent) configuration options of
-jitterentropy:
-
-1. Whether to use a variable, pseudorandom number of iterations in the noise
-   generating functions.
-2. Whether to post-process the raw noise samples with jitterentropy's internal
-   processing routines.
-
-I consider these basic configuration options because the affect the basic
-process that jitterentropy uses. I'm contrasting them to tunable parameters
-(like the precise value used for loop counts if they are not chosen
-pseudorandomly, or the size of the scratch memory used internal by
-jitterentropy), since the tunable parameters don't greatly affect the means by
-which jitterentropy collects entropy, just the amount it collects and the time
-it takes.
-
-My full conclusions are at the end of this document, but in summary I think that
-we should avoid both choosing pseudorandom iteration numbers and using the
-jitterentropy post-processed data.
-
-[TOC]
-
-## Brief explanation of jitterentropy
-
-The author's documentation is available in HTML form at
-<http://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.html>, or in PDF form at
-<http://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.pdf>. In brief, the library
-collects random bits from variations in CPU instruction timing.
-
-Jitterentropy maintains a random state, in the form of a 64-bit number that is
-affected by many of the jitterentropy functions, and ultimately is used as the
-output randomness.
-
-There are two noise sources, both of which are blocks of relatively slow-running
-code whose precise runtime is measured (using a system clock, requiring roughly
-nanosecond resolution). The precise time to complete these blocks of code will
-vary. We test these times to ensure that they are unpredictable; while we can't
-be perfectly certain that they are, the test results (including the results
-below) are encouraging. Note however that the purpose of this document is not to
-justify our estimates for the min-entropy in jitterentropy samples, but rather
-to discuss the two configuration options listed above.
-
-The first of the code blocks used as a noise source is a CPU-intensive LFSR
-loop, implemented in
-[the `jent_lfsr_time` function](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/jitterentropy-base.c#185).
-The number of times the LFSR logic is repeated is controlled by the
-`kernel.jitterentropy.ll` cmdline ("`ll`" stands for "LFSR loops"). If `ll = 0`,
-a pseudorandom count is used, and otherwise the value of `ll` is used.
-Looking at the source code, the outer loop repeats according to the `ll`
-parameter.  The inner loop advances an LFSR by 64 steps, each time XOR-ing in
-one bit from the most recent time sample. Passing the time sample through the
-LFSR this way serves as a processing step, generally tending to whiten the
-random timesteps. As described in the
-[entropy quality testing doc](../entropy_quality_tests.md), it's important to
-skip this processing when testing the entropic content of the CPU time
-variations.  It's also the case that enabling the processing increases the
-entropy estimates by a suspicious amount in some cases (see
-[the "Effects of processing the raw samples" section](#effects-of-processing-the-raw-samples)).
-
-The second noise source is a memory access loop, in
-[the `jent_memaccess` function](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/jitterentropy-base.c#261).
-The memory access loop is repeated according to the `kernel.jitterentropy.ml`
-cmdline ("`ml`" for "memory loops"), where again a value of 0 activates the
-pseudorandom loop count, and any non-zero value overrides the pseudorandom
-count. Each iteration of the actual memory access loop both reads and writes a
-relatively large chunk of memory, divided into `kernel.jitterentropy.bc`-many
-blocks of size `kernel.jitterentropy.bs` bytes each. The default values when I
-wrote the current document are `bc = 1024` and `bs = 64`; up-to-date defaults
-should be documented in
-[the cmdline document](../kernel_cmdline.md). For comparison, the defaults in
-the jitterentropy source code are `bc = 64` and `bs = 32`,
-[defined here](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/include/lib/jitterentropy/jitterentropy.h#79).
-Per the comment above the `jent_memaccess` function, the total memory size
-should be larger than the L1 cache size of the target machine. Confusingly,
-`bc = 64` and `bs = 32` produce a memory size of 2048 bytes, which is much
-smaller than even most L1 caches (I couldn't find any CPU with more than 0 bytes
-but less than 4KB of L1). Using `bs = 64` and `bc = 1024` result in 64KB of
-memory, which is usually enough to overflow L1 data caches.
-
-### Option 1: Pseudorandom loop counts
-
-Jitterentropy was originally designed so that the two noise generating functions
-run a pseudorandom number of times. Specifically,
-[the `jent_loop_shuffle` function](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/jitterentropy-base.c#125)
-mixes together (1) the time read from the high-resolution clock and (2)
-jitterentropy's internal random state in order to decide how many times to run
-the noise sources.
-
-We added the ability to override these pseudorandom loop counts, and tested
-jitterentropy's performance both with and without the override. The results are
-discussed in more depth in
-[the "Effects of pseudorandom loop counts" section](#effects-of-pseudorandom-loop-counts),
-but in summary: the statistical tests suggested that the pseudorandom loop
-counts increased the entropy far more than expected.  This makes me mistrust
-these higher entropy counts, so I recommend using the lower estimates and
-preferring deterministic loop counts to pseudorandom.
-
-### Jitterentropy's random data processing
-
-As mentioned above, jitterentropy can process its random data, which makes the
-data look "more random".  Specifically, the processing should decrease (and
-ideally remove) the deviation of the random data from the uniform distribution,
-and reduce (ideally, remove) any intercorrelations between random bytes.
-
-The main function of interest for generating processed samples is
-[`jent_gen_entropy`](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/jitterentropy-base.c#462),
-which is called in a loop by
-[`jent_read_entropy`](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/jitterentropy-base.c#544)
-to produce an arbitrarily large number of random bytes.
-In essence, `jent_gen_entropy` calls the noise functions in a loop 64 times.
-Each of the 64 invocations of `jent_lfsr_time` mixes the noisy time measurement
-into the jitterentropy random state.
-
-After these 64 iterations, the random state is optionally "stirred" in
-[`jent_stir_pool`](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/jitterentropy-base.c#403)
-by XOR-ing with a "mixer" value, itself dependent on the jitterentropy random
-state. As noted in the source code, this operation cannot increase or decrease
-the entropy in the pool (since XOR is bijective), but it can potentially improve
-the statistical appearance of the random state.
-
-In principle, invoking the noise source functions 64 times should produce 64
-times as much entropy, up to the maximum 64 bits that the random state can hold.
-This assumes that the mixing operation in `jent_lfsr_time` is cryptographically
-sound. I'm not an expert in cryptanalysis, but a LFSR itself is not a
-cryptographically secure RNG, since 64 successive bits reveal the entire state
-of a 64-bit LFSR, after which all past and future values can be easily
-computed. I am not sure that the jitterentropy scheme &mdash; XOR-ing the time
-measurement into the "bottom" of the LFSR as the LFSR is shifted &mdash; is more
-secure. Without careful cryptographic examination of this scheme (which for all
-I know may exist, but the I did not see it mentioned in the jitterentropy
-documentation), I would lean towards using unprocessed samples, and mixing them
-into our system entropy pool in a known-good way (e.g. SHA-2, as we do now).
-
-That said, I did run the NIST test suite against processed data samples. My
-results are in
-[the "Effects of processing the raw samples" section](#effects-of-processing-the-raw-samples))
-below.
-
-## Testing process
-
-The procedure for running entropy source quality tests is documented in
-[the entropy quality tests document](../entropy_quality_tests.md).
-
-These preliminary results were gathered on a Zircon debug build on Raspberry Pi
-3, built from commit
-[18358de5e90a012cb1e042efae83f5ea264d1502](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d)
-"\[virtio]\[entropy] Basic virtio-rng driver". The following flags were set in
-my `local.mk` file when building:
-
-```
-ENABLE_ENTROPY_COLLECTOR_TEST=1
-ENTROPY_COLLECTOR_TEST_MAXLEN=1048576
-```
-
-I ran the boot-time tests after netbooting the debug kernel on the Pi with the
-following kernel cmdline, varying the values of `$ML`, `$LL`, and `$RAW`:
-
-```
-kernel.entropy-test.src=jitterentropy
-kernel.jitterentropy.bs=64
-kernel.jitterentropy.bc=1024
-kernel.jitterentropy.ml=$ML
-kernel.jitterentropy.ll=$LL
-kernel.jitterentropy.raw=$RAW
-```
-
-## Test results and analysis
-
-### Effects of pseudorandom loop counts
-
-#### Raw Data
-
-Following the logic in the jitterentropy source code (search for
-[`MAX_FOLD_LOOP_BIT`](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/jitterentropy-base.c#191)
-and
-[`MAX_ACC_LOOP_BIT`](https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d/third_party/lib/jitterentropy/jitterentropy-base.c#265))
-the pseudorandom loop counts vary within these ranges:
-
-```
-ml: 1 .. 128 (inclusive)
-ll: 1 .. 16 (inclusive)
-```
-
-I have included the overall min-entropy estimate from the NIST suite in this
-table, as well as two contributing estimates: the compression estimate and the
-Markov estimate. The NIST min-entropy estimate is the minimum of 10 different
-estimates, including these two. The compression estimate is generally the
-smallest for jitterentropy raw samples with deterministic loop counts, and the
-Markov estimate is generally smallest for jitterentropy with other
-configurations.
-
-| `ml`              | `ll`             | min-entropy (bits / byte) | Compression estimate | Markov estimate |
-|:-----------------:|:----------------:|:-------------------------:|:--------------------:|:---------------:|
-| random (1 .. 128) | random (1 .. 16) | 5.77                      | 6.84                 | 5.77            |
-| 128               | 16               | 1.62                      | 1.62                 | 3.60            |
-| 1                 | 1                | 0.20                      | 0.20                 | 0.84            |
-
-
-In other words, varying the loop counts pseudorandomly increased the min-entropy
-estimate for raw samples by 4.15 bits (or 250%), compared to the deterministic
-version that always used the maximum values from the pseudorandom ranges.
-
-#### Analysis
-
-The pseudorandom loop count values are determined by adding one extra time
-sample per noise function. First, these time samples are not independent of the
-noise function time measurements, since the gaps between the loop count time
-samples correspond predictably to the noise function time measurements. As a
-result it would be highly questionable to assume that they increase the
-min-entropy of the output data at all.  Second, it is absurd to imagine that the
-loop count time samples were somehow about 250% as random as the noise function
-time measurements, since both rely on the same noise source, except that the
-very first loop count time samples maybe get a small boost from the random
-amount of time needed to boot the system enough to run the test.
-
-Consequently, I suspect that what happened is that the pseudorandom loop counts
-were enough to "fool" the particular suite of statistical tests and
-predictor-based tests in the NIST suite, but that a predictor test written with
-specific knowledge of how the jitterentropy pseudorandom loop counts are derived
-could in fact predict the output with far better accuracy. I think the "true"
-min-entropy in the pseudorandom loop count test, against an adversary that's
-specifically targeting our code, is within the bounds of the two deterministic
-tests, i.e. between about 0.20 and 1.62 bits per byte.
-
-Using pseudorandom counts forces us to make an additional decision: do we
-conservatively estimate the actual entropy content at 0.20 bits per byte (as if
-the pseudorandom count function always chose `ml = 1` and `ll = 1`)? Or do we
-chose an average entropy content (there is probably a more intelligent averaging
-technique than to compute (1.62 + 0.20) / 2 = 0.91 bits / byte, but that will
-serve for the purpose of this discussion) and risk the pseudorandom loop counts
-occasionally causing us to undershoot this average entropy content? If we are
-too conservative, we will spend more time collecting entropy than is needed; if
-we are too optimistic, we might have a security vulnerability. Ultimately, this
-forces a trade-off between security (which prefers conservative entropy
-estimates) and efficiency (which prefers optimistic entropy estimates).
-
-### Effects of processing the raw samples
-
-#### Raw Data
-
-I repeated the three tests reported above, but with jitterentropy's internal
-processing turned on (with `kernel.jitterentropy.raw = false` instead of the
-default value `true`). For convenience, the tables below include both the raw
-sample results (copied from above) in the top three rows, and the processed
-results (newly added) in the bottom three rows.
-
-| `ml`              | `ll`             | raw   | min-entropy (bits / byte) | Compression estimate | Markov estimate |
-|:-----------------:|:----------------:|:-----:|:-------------------------:|:--------------------:|:---------------:|
-| random (1 .. 128) | random (1 .. 16) | true  | 5.77                      | 6.84                 | 5.77            |
-| 128               | 16               | true  | 1.62                      | 1.62                 | 3.60            |
-| 1                 | 1                | true  | 0.20                      | 0.20                 | 0.84            |
-
-| `ml`              | `ll`             | raw   | min-entropy (bits / byte) | Compression estimate | Markov estimate |
-|:-----------------:|:----------------:|:-----:|:-------------------------:|:--------------------:|:---------------:|
-| random (1 .. 128) | random (1 .. 16) | false | 5.79                      | 6.59                 | 5.79            |
-| 128               | 16               | false | 5.78                      | 6.97                 | 5.78            |
-| 1                 | 1                | false | 5.77                      | 6.71                 | 5.77            |
-
-#### Analysis
-
-The post-processing min-entropy estimates are all essentially equal (up to
-slight variations easily explained by randomness), and also equal to the
-min-entropy estimate for raw samples with pseudorandom loop counts.
-
-Recall that jitterentropy's processed entropy is formed from 64 separate random
-data samples, mixed together in a 64-bit internal state buffer. Each of the raw
-samples corresponds to a sample in the `raw = true` table. In particular, it's
-absurd to think that combining 64 samples with `ml = 1` and `ll = 1` then
-processing these could produce (5.77 \* 8) = 46.2 bits of entropy per 8 bytes of
-processed output, since that would imply (46.2 / 64) = 0.72 bits of entropy per
-unprocessed sample as opposed to the measured value of 0.20 bits.
-
-This argument applies against the `ml = 1`, `ll = 1`, `raw = false` measurement,
-but does *not* apply to `ml = 128`, `ll = 16`, `raw = false`. In particular,
-combining 64 raw samples with `ml = 128` and `ll = 16` could in principle
-collect (1.64 \* 64 / 8) = 13.1 bits of entropy per processed byte, except that
-of course there is a hard limit at 8 bits per byte.
-
-Interestingly, the minimal entropy estimator switches from the compression
-estimate to the Markov estimator. My theory is that the additional "confusion"
-from post-processing is enough to "fool" the compression estimate. If there is a
-cryptographic vulnerability in the jitterentropy processing routine, it may be
-possible to write a similar estimator that reveals a significantly smaller
-min-entropy. If we use the general-purpose tests to decide how many raw samples
-to collect in order to have 256 of min-entropy, but an adversary uses a targeted
-attack, then (relative to this targeted attack) our system may have less entropy
-in its entropy pool than we expect. This is a security vulnerability.
-
-If there is a very bad weakness in the jitterentropy processing routine, it may
-in fact be reducing the "true" entropy in jitterentropy's internal pool. The
-arithmetical argument regarding `ml = 1` and `ll = 1` shows that we can't trust
-the NIST test suite to accurately measure the actual min-entropy in the
-processed data, so it is possible that the processing actually reduces
-min-entropy and our tools just can't detect the loss. This would exacerbate the
-vulnerability described in the previous paragraph.
-
-## Conclusions
-
-Jitterentropy's pseudorandom loop counts are of questionable benefit at best,
-and if used they force us to make a security/efficiency trade-off. Unless we can
-show convincing evidence that the pseudorandom times really do drastically
-increase entropy estimates rather than just defeating the NIST test suite, we
-should use deterministic loop counts, ideally tuned for performance on a
-per-target basis.
-
-Jitterentropy's processing is also questionable, since (to my knowledge) it
-hasn't been subjected to enough cryptographic analysis and testing to be
-trusted. Furthermore, we can't directly measure the min-entropy in the
-post-processed data via the NIST test suite, so if there is a cryptographic
-vulnerability we can't easily detect it. I think we should instead rely on the
-entropy mixing code in the Zircon CPRNG (based on SHA-2), and leave
-jitterentropy's processing disabled.
-
-## TODOs
-
-1. Repeat the tests reported above against different versions of Zircon, and
-   ensure that the entropy estimates remain consistent.
-2. Repeat the tests on different platforms and targets (note: x86 targets don't
-   currently have access to a system clock during early boot, so the early boot
-   entropy tests and early boot CPRNG seeding don't yet support jitterentropy on
-   x86).
-3. Automate the process of running the tests and generating the reports in this
-   document. Specifically, the tests should compare:
-
-   - pseudorandom loop counts versus various deterministic loop count values
-   - raw samples versus processed data
diff --git a/docs/jitterentropy/config-tuning.md b/docs/jitterentropy/config-tuning.md
deleted file mode 100644
index c30a93a..0000000
--- a/docs/jitterentropy/config-tuning.md
+++ /dev/null
@@ -1,201 +0,0 @@
-# Jitterentropy: tuning the configuration
-
-The jitterentropy library is written by Stephan Mueller, is available at
-<https://github.com/smuellerDD/jitterentropy-library>, and is documented at
-<http://www.chronox.de/jent.html>. In Zircon, it's used as a simple entropy
-source to seed the system CPRNG.
-
-[The companion document about basic configuration options to jitterentropy](config-basic.md)
-describes two options that fundamentally affect how jitterentropy runs. This document describes
-instead the numeric parameters that control how fast jitterentropy is and how much entropy it
-collects, but without fundamentally altering its principles of operation. It also describes how to
-test various parameters and what to look for in the output (e.g. if adding support for a new device,
-or to do a more thorough job of optimizing the parameters).
-
-[TOC]
-
-## A rundown of jitterentropy's parameters
-
-The following tunable parameters control how fast jitterentropy runs, and how fast it collects
-entropy:
-
-### [`kernel.jitterentropy.ll`](../kernel_cmdline.md#kernel_jitterentropy_ll_num)
-
-"`ll`" stands for "LFSR loops". Jitterentropy uses a (deliberately inefficient implementation of a)
-LFSR to exercise the CPU, as part of its noise generation. The inner loop shifts the LFSR 64 times;
-the outer loop repeats `kernel.jitterentropy.ll`-many times.
-
-In my experience, the LFSR code significantly slows down jitterentropy, but doesn't generate very
-much entropy. I tested this on RPi3 and qemu-arm64 with qualitatively similar results, but it hasn't
-been tested on x86 yet. This is something to consider when tuning: using fewer LFSR loops tends to
-lead to better overall performance.
-
-Note that setting `kernel.jitterentropy.ll=0` causes jitterentropy to choose the number of LFSR
-loops in a "random-ish" way. As described in [the basic config doc](config-basic.md), I discourage
-the use of `kernel.jitterentropy.ll=0`.
-
-
-### [`kernel.jitterentropy.ml`](../kernel_cmdline.md#kernel_jitterentropy_ml_num)
-
-"`ml`" stands for "memory access loops". Jitterentropy walks through a moderately large chunk of
-RAM, reading and writing each byte. The size of the chunk and access pattern are controlled by the
-two parameters below. The memory access loop is repeated `kernel.jitterentropy.ml`-many times.
-
-In my experience, the memory access loops are a good source of raw entropy. Again, I've only tested
-this on RPi3 and qemu-arm64 so far.
-
-Much like `kernel.jitterentropy.ll`, if you set `kernel.jitterentropy.ml=0`, then jitterentropy will
-choose a "random-ish" value for the memory access loop count. I also discourage this.
-
-### [`kernel.jitterentropy.bs`](../kernel_cmdline.md#kernel_jitterentropy_bs_num)
-
-"`bs`" stands for "block size". Jitterentropy divides its chunk of RAM into blocks of this size. The
-memory access loop starts with byte 0 of block zero, then "byte -1" of block 1 (which is actually
-the last byte of block 0), then "byte -2" of block 2 (i.e. the second-to-last byte of block 1), and
-so on. This pattern ensures that every byte gets hit, and most accesses go into different blocks.
-
-I have usually tested jitterentropy with `kernel.jitterentropy.bs=64`, based on the size of a cache
-line. I haven't tested yet to see whether there's a better option on some/all platforms.
-
-### [`kernel.jitterentropy.bc`](../kernel_cmdline.md#kernel_jitterentropy_bc_num)
-
-"`bc`" stands for "block count". Jitterentropy uses this many blocks of RAM, each of size
-`kernel.jitterentropy.bs`, in its memory access loops.
-
-Since I choose `kernel.jitterentropy.bs=64`, I usually choose `kernel.jitterentropy.bc=1024`.
-This means using 64KB of RAM, which is enough to overflow L1 cache.
-
-The [jitterentropy source code](../../third_party/lib/jitterentropy/jitterentropy-base.c#234)
-in the comment before `jent_memaccess` suggests choosing the block size and count so that the RAM
-used is bigger than L1. Confusingly, the default values in upstream jitterentropy (block size = 32,
-block count = 64) aren't big enough to overflow L1.
-
-## Tuning process
-
-The basic idea is simple: on a particular target device, try different values for the parameters.
-Collect a large amount of data for each parameter set (ideally around 1MB), then
-[run the NIST test suite to analyze the data](../entropy_quality_tests.md#running-the-nist-test-suite).
-Determine which parameters give the best entropy per unit time. The time taken to draw the entropy
-samples is logged on the system under test.
-
-One complication is the startup testing built into jitterentropy. This essentially draws and
-discards 400 samples, after performing some basic analysis (mostly making sure that the clock is
-monotonic and has a high enough resolution and variability). A more accurate test would reboot twice
-for each set of parameters: once to collect around 1MB of data for analysis, and a second time to
-boot with the "right" amount of entropy (as computed according to the entropy estimate in the first
-phase, with appropriate safety margins, etc. See
-["Determining the entropy\_per\_1000\_bytes statistic"](#determining-the-entropy_per_1000_bytes-statistic),
-below). This second phase of testing simulates a real boot, including the startup tests. After
-completing the second phase, choose the parameter set that boots fastest. Of course, each phase of
-testing should be repeated a few times to reduce random variations.
-
-## Determining the entropy\_per\_1000\_bytes statistic
-
-The `crypto::entropy::Collector` interface in
-[kernel/lib/crypto/include/lib/crypto/entropy/collector.h](../../kernel/lib/crypto/include/lib/crypto/entropy/collector.h)
-requires a parameter `entropy_per_1000_bytes` from its instantiations. The value relevant to
-jitterentropy is currently hard-coded in
-[kernel/lib/crypto/entropy/jitterentropy\_collector.cpp](../../kernel/lib/crypto/entropy/jitterentropy_collector.cpp).
-This value is meant to measure how much min-entropy is contained in each byte of data produced by
-jitterentropy (since the bytes aren't independent and uniformly distributed, this will be less than
-8 bits). The "per 1000 bytes" part simply makes it possible to specify fractional amounts of
-entropy, like "0.123 bits / byte", without requiring fractional arithmetic (since `float` is
-disallowed in kernel code, and fixed-point arithmetic is confusing).
-
-The value should be determined by using the NIST test suite to analyze random data samples, as
-described in
-[the entropy quality tests document](../entropy_quality_tests.md#running-the-nist-test-suite).
-The test suite produces an estimate of the min-entropy; repeated tests of the same RNG have (in my
-experience) varied by a few tenths of a bit (which is pretty significant when entropy values can be
-around 0.5 bits per byte of data!). After getting good, consistent results from the test suites,
-apply a safety factor (i.e. divide the entropy estimate by 2), and update the value of
-`entropy_per_1000_bytes` (don't forget to multiply by 1000).
-
-Note that eventually `entropy_per_1000_bytes` should probably be configured somewhere instead of
-hard-coded in jitterentropy\_collector.cpp. Kernel cmdlines or even a preprocessor symbol could work.
-
-## Notes about the testing script
-
-The `scripts/entropy-test/jitterentropy/test-tunable` script automates the practice of looping
-through a large test matrix. The downside is that tests run in sequence on a single machine, so (1)
-an error will stall the test pipeline so supervision *is* required, and (2) the machine is being
-constantly rebooted rather than cold-booted (plus it's a netboot-reboot), which could conceivably
-confound the tests. Still, it beats hitting power-off/power-on a thousand times by hand!
-
-Some happy notes:
-
-1. When netbooting, the script leaves bootserver on while waiting for netcp to successfully export
-   the data file. If the system hangs, you can power it off and back on, and the existing bootserver
-   process will restart the failed test.
-
-2. If the test is going to run (say) 16 combinations of parameters 10 times each, it will go like
-   this:
-
-       test # 0: ml = 1   ll = 1  bc = 1  bs = 1
-       test # 1: ml = 1   ll = 1  bc = 1  bs = 64
-       test # 2: ml = 1   ll = 1  bc = 32 bs = 1
-       test # 3: ml = 1   ll = 1  bc = 32 bs = 64
-       ...
-       test #15: ml = 128 ll = 16 bc = 32 bs = 64
-       test #16: ml = 1   ll = 1  bc = 1  bs = 1
-       test #17: ml = 1   ll = 1  bc = 1  bs = 64
-       ...
-
-   (The output files are numbered starting with 0, so I started with 0 above.)
-
-   So, if test #17 fails, you can delete tests #16 and #17, and re-run 9 more iterations of each
-   test. You can at least keep the complete results from the first iteration. In theory, the tests
-   could be smarter and also keep the existing result from test #16, but the current shell scripts
-   aren't that sophisticated.
-
-The scripts don't do a two-phase process like I suggested in the ["Tuning process"](#tuning-process)
-section above. It's certainly possible, but again the existing scripts aren't that sophisticated.
-
-## Open questions
-
-### How much do we trust the low-entropy extreme?
-
-It's *a priori* possible that we maximize entropy per unit time by choosing small parameter values.
-Most extreme is of course `ll=1, ml=1, bs=1, bc=1`, but even something like `ll=1, ml=1, bs=64,
-bc=32` is an example of what I'm thinking of.  Part of the concern is the variability in the test
-suite: if hypothetically the tests are only accurate to within 0.2 bits of entropy per byte, and if
-they're reporting 0.15 bits of entropy per byte, what do we make of it? Hopefully running the same
-test a few hundred times in a row will reveal a clear modal value, but it's still a little bit risky
-to rely on that low estimate to be accurate.
-
-The NIST publication states (line 1302, page 35, second draft) that the estimators "work well when
-the entropy-per-sample is greater than 0.1". This is fairly low, so hopefully it isn't an issue in
-practice. Still, the fact that there is a lower bound means we should probably leave a fairly
-conservative envelope around it.
-
-### How device-dependent is the optimal choice of parameters?
-
-There's evidently a significant difference in the actual "bits of entropy per byte" metric on
-different architectures or different hardware. Is it possible that most systems are optimal at
-similar parameter values (so that we can just hard-code these values into
-`kernel/lib/crypto/entropy/jitterentropy_collector.cpp`? Or, do we need to put the parameters into
-MDI or into a preprocessor macro, so that we can use different defaults on a per-platform basis (or
-whatever level of granularity is appropriate).
-
-### Can we even record optimal parameters with enough granularity?
-
-I mentioned it above, but one of our targets is "x86", which is what runs on any x86
-PC. Naturally, x86 PCs can very quite a bit. Even if we did something like add preprocessor symbols
-like `JITTERENTROPY_LL_VALUE` etc. to the build, customized in `kernel/project/target/pc-x86.mk`,
-could we pick a good value for *all PCs*?
-
-If not, what are our options?
-
-1. We could store a lookup table based on values accessible at runtime (like the exact CPU model,
-   the core memory size, cache line size, etc.). This seems rather unwieldy. Maybe if we could find
-   one or two simple properties to key off of, say "CPU core frequency" and "L1 cache size", we
-   could make this relatively non-terrible.
-
-2. We could try an adaptive approach: monitor the quality of the entropy stream, and adjust the
-   parameters according on the fly. This would take a lot of testing and justification if we want to
-   trust it.
-
-3. We could settle for "good enough" parameters on most devices, with the option to tune via kernel
-   cmdlines or a similar mechanism. This seems like the most likely outcome to me. I expect that
-   "good enough" parameters will be easy to find, and not disruptive enough to justify extreme
-   solutions.
diff --git a/docs/kernel_cmdline.md b/docs/kernel_cmdline.md
deleted file mode 100644
index d8b6837..0000000
--- a/docs/kernel_cmdline.md
+++ /dev/null
@@ -1,542 +0,0 @@
-# Zircon Kernel Commandline Options
-
-The Zircon kernel receives a textual commandline from the bootloader,
-which can be used to alter some behaviours of the system.  Kernel commandline
-parameters are in the form of *option* or *option=value*, separated by
-spaces, and may not contain spaces.
-
-For boolean options, *option=0*, *option=false*, or *option=off* will
-disable the option.  Any other form (*option*, *option=true*, *option=wheee*,
-etc) will enable it.
-
-The kernel commandline is passed from the kernel to the userboot process
-and the device manager, so some of the options described below apply to
-those userspace processes, not the kernel itself.
-
-The devmgr reads the file /boot/config/devmgr (if it exists) at startup
-and imports name=value lines into its environment, augmenting or overriding
-the values from the kernel commandline.  Leading whitespace is ignored and
-lines starting with # are ignored.  Whitespace is not allowed in names.
-
-## aslr.disable
-
-If this option is set, the system will not use Address Space Layout
-Randomization.
-
-## bootsvc.next=\<bootfs path\>
-Controls what program is executed by bootsvc to continue the boot process.
-If this is not specified, the default next program will be used.
-
-## devmgr\.epoch=\<seconds\>
-
-Sets the initial offset (from the Unix epoch, in seconds) for the UTC clock.
-This is useful for platforms lacking an RTC, where the UTC offset would
-otherwise remain at 0.
-
-## devmgr\.require-system=\<bool\>
-
-Instructs the devmgr that a /system volume is required.  Without this,
-devmgr assumes this is a standalone Zircon build and not a full Fuchsia
-system.
-
-## devmgr\.suspend-timeout-debug
-
-If this option is set, the system prints out debugging when mexec, suspend,
-reboot, or power off did not finish in 10 seconds.
-
-## devmgr\.suspend-timeout-fallback
-
-If this option is set, the system invokes kernel fallback to reboot or poweroff
-the device when the operation did not finish in 10 seconds.
-
-## devmgr\.devhost\.asan
-
-This option must be set if any drivers not included directly in /boot are built
-with `-fsanitize=address`.  If there are `-fsanitize=address` drivers in /boot,
-then all `-fsanitize=address` drivers will be supported regardless of this
-option.  If this option is not set and there are no such drivers in /boot, then
-drivers built with `-fsanitize=address` cannot be loaded and will be rejected.
-
-## devmgr\.devhost\.strict-linking
-
-If this option is set, devmgr will only allow `libasync-default.so`,
-`libdriver.so`, and `libfdio.so` to be dynamically linked into a devhost. This
-prevents drivers from dynamically linking with libraries that they should not.
-All other libraries should be statically linked into a driver.
-
-## devmgr\.verbose
-
-Turn on verbose logging.
-
-## driver.\<name>.disable
-
-Disables the driver with the given name. The driver name comes from the
-zircon\_driver\_info, and can be found as the first argument to the
-ZIRCON\_DRIVER\_BEGIN macro.
-
-Example: `driver.usb_audio.disable`
-
-## driver.\<name>.log=\<flags>
-
-Set the log flags for a driver.  Flags are one or more comma-separated
-values which must be preceded by a "+" (in which case that flag is enabled)
-or a "-" (in which case that flag is disabled).  The textual constants
-"error", "warn", "info", "trace", "spew", "debug1", "debug2", "debug3", and "debug4"
-may be used, and they map to the corresponding bits in DDK_LOG_... in `ddk/debug.h`
-The default log flags for a driver is "error", "warn", and "info".
-
-Individual drivers may define their own log flags beyond the eight mentioned
-above.
-
-Example: `driver.usb_audio.log=-error,+info,+0x1000`
-
-Note again that the name of the driver is the "Driver" argument to the
-ZIRCON\_DRIVER\_BEGIN macro. It is not, for example, the name of the device,
-which for some drivers is almost identical, except that the device may be
-named "foo-bar" whereas the driver name must use underscores, e.g., "foo_bar".
-
-## driver.tracing.enable=\<bool>
-
-Enable or disable support for tracing drivers.
-When enabled drivers may participate in [Fuchsia tracing](ddk/tracing.md).
-
-Implementation-wise, what this option does is tell each devhost whether to
-register as "trace provider".
-
-The default is enabled. This options exists to provide a quick fallback should
-a problem arise.
-
-## gfxconsole.early=\<bool>
-
-This option (disabled by default) requests that the kernel start a graphics
-console during early boot (if possible), to display kernel debug print
-messages while the system is starting.  When userspace starts up, a usermode
-graphics console driver takes over.
-
-The early kernel console can be slow on some platforms, so if it is not
-needed for debugging it may speed up boot to disable it.
-
-## gfxconsole.font=\<name>
-
-This option asks the graphics console to use a specific font.  Currently
-only "9x16" (the default) and "18x32" (a double-size font) are supported.
-
-## iommu.enable=\<bool>
-
-This option (disabled by default) allows the system to use a hardware IOMMU
-if present.
-
-## kernel.bypass-debuglog=\<bool>
-
-When enabled, forces output to the console instead of buffering it. The reason
-we have both a compile switch and a cmdline parameter is to facilitate prints
-in the kernel before cmdline is parsed to be forced to go to the console.
-The compile switch setting overrides the cmdline parameter (if both are present).
-Note that both the compile switch and the cmdline parameter have the side effect
-of disabling irq driven uart Tx.
-
-## kernel.entropy-mixin=\<hex>
-
-Provides entropy to be mixed into the kernel's CPRNG.
-
-## kernel.entropy-test.len=\<len>
-
-When running an entropy collector quality test, collect the provided number of
-bytes. Defaults to the maximum value `ENTROPY_COLLECTOR_TEST_MAXLEN`.
-
-The default value for the compile-time constant `ENTROPY_COLLECTOR_TEST_MAXLEN`
-is 1MiB.
-
-## kernel.entropy-test.src=\<source>
-
-When running an entropy collector quality test, use the provided entropy source.
-Currently recognized sources: `hw_rng`, `jitterentropy`. This option is ignored
-unless the kernel was built with `ENABLE_ENTROPY_COLLECTOR_TEST=1`.
-
-## kernel.halt-on-panic=\<bool>
-If this option is set (disabled by default), the system will halt on
-a kernel panic instead of rebooting.
-
-## kernel.jitterentropy.bs=\<num>
-
-Sets the "memory block size" parameter for jitterentropy (the default is 64).
-When jitterentropy is performing memory operations (to increase variation in CPU
-timing), the memory will be accessed in blocks of this size.
-
-## kernel.jitterentropy.bc=\<num>
-
-Sets the "memory block count" parameter for jitterentropy (the default is 512).
-When jitterentropy is performing memory operations (to increase variation in CPU
-timing), this controls how many blocks (of size `kernel.jitterentropy.bs`) are
-accessed.
-
-## kernel.jitterentropy.ml=\<num>
-
-Sets the "memory loops" parameter for jitterentropy (the default is 32). When
-jitterentropy is performing memory operations (to increase variation in CPU
-timing), this controls how many times the memory access routine is repeated.
-This parameter is only used when `kernel.jitterentropy.raw` is true. If the
-value of this parameter is `0` or if `kernel.jitterentropy.raw` is `false`,
-then jitterentropy chooses the number of loops is a random-ish way.
-
-## kernel.jitterentropy.ll=\<num>
-
-Sets the "LFSR loops" parameter for jitterentropy (the default is 1). When
-jitterentropy is performing CPU-intensive LFSR operations (to increase variation
-in CPU timing), this controls how many times the LFSR routine is repeated.  This
-parameter is only used when `kernel.jitterentropy.raw` is true. If the value of
-this parameter is `0` or if `kernel.jitterentropy.raw` is `false`, then
-jitterentropy chooses the number of loops is a random-ish way.
-
-## kernel.jitterentropy.raw=\<bool>
-
-When true (the default), the jitterentropy entropy collector will return raw,
-unprocessed samples. When false, the raw samples will be processed by
-jitterentropy, producing output data that looks closer to uniformly random. Note
-that even when set to false, the CPRNG will re-process the samples, so the
-processing inside of jitterentropy is somewhat redundant.
-
-## kernel.memory-limit-dbg=\<bool>
-
-This option enables verbose logging from the memory limit library.
-
-## kernel.memory-limit-mb=\<num>
-
-This option tells the kernel to limit system memory to the MB value specified
-by 'num'. Using this effectively allows a user to simulate the system having
-less physical memory than physically present.
-
-## kernel.oom.enable=\<bool>
-
-This option (true by default) turns on the out-of-memory (OOM) kernel thread,
-which kills processes when the PMM has less than `kernel.oom.redline_mb` free
-memory, sleeping for `kernel.oom.sleep_sec` between checks.
-
-The OOM thread can be manually started/stopped at runtime with the `k oom start`
-and `k oom stop` commands, and `k oom info` will show the current state.
-
-See `k oom` for a list of all OOM kernel commands.
-
-## kernel.oom.redline-mb=\<num>
-
-This option (50 MB by default) specifies the free-memory threshold at which the
-out-of-memory (OOM) thread will trigger a low-memory event and begin killing
-processes.
-
-The `k oom info` command will show the current value of this and other
-parameters.
-
-## kernel.oom.sleep-sec=\<num>
-
-This option (1 second by default) specifies how long the out-of-memory (OOM)
-kernel thread should sleep between checks.
-
-The `k oom info` command will show the current value of this and other
-parameters.
-
-## kernel.mexec-pci-shutdown=\<bool>
-
-If false, this option leaves PCI devices running when calling mexec. Defaults
-to true.
-
-## kernel.serial=\<string\>
-
-This controls what serial port is used.  If provided, it overrides the serial
-port described by the system's bootdata.
-
-If set to "none", the kernel debug serial port will be disabled.
-
-### x64 specific values
-
-On x64, some additional values are supported for configuring 8250-like UARTs:
-- If set to "legacy", the legacy COM1 interface is used.
-- A port-io UART can be specified using "ioport,\<portno>,\<irq>".
-- An MMIO UART can be specified using "mmio,\<physaddr>,\<irq>".
-
-For example, "ioport,0x3f8,4" would describe the legacy COM1 interface.
-
-All numbers may be in any base accepted by *strtoul*().
-
-All other values are currently undefined.
-
-## kernel.shell=\<bool>
-
-This option tells the kernel to start its own shell on the kernel console
-instead of a userspace sh.
-
-## kernel.smp.maxcpus=\<num>
-
-This option caps the number of CPUs to initialize.  It cannot be greater than
-*SMP\_MAX\_CPUS* for a specific architecture.
-
-## kernel.smp.ht=\<bool>
-
-This option can be used to disable the initialization of hyperthread logical
-CPUs.  Defaults to true.
-
-## kernel.wallclock=\<name>
-
-This option can be used to force the selection of a particular wall clock.  It
-only is used on pc builds.  Options are "tsc", "hpet", and "pit".
-
-## ktrace.bufsize
-
-This option specifies the size of the buffer for ktrace records, in megabytes.
-The default is 32MB.
-
-## ktrace.grpmask
-
-This option specifies what ktrace records are emitted.
-The value is a bitmask of KTRACE\_GRP\_\* values from zircon/ktrace.h.
-Hex values may be specified as 0xNNN.
-
-## ldso.trace
-
-This option (disabled by default) turns on dynamic linker trace output.
-The output is in a form that is consumable by clients like Intel
-Processor Trace support.
-
-## thread.set.priority.disable=\<bool>
-
-This option (false by default) prevents the syscall that increases
-a thread priority (`zx_thread_set_priority`) from taking effect.
-
-## zircon.autorun.boot=\<command>
-
-This option requests that *command* be run at boot, after devmgr starts up.
-
-Any `+` characters in *command* are treated as argument separators, allowing
-you to pass arguments to an executable.
-
-### Sidebar: Injecting a personal autorun script <a name="autorun"></a>
-
-It's often useful to inject a personal autorun script into the boot filesystem,
-especially for running tests or setup tasks. You can do this with the zircon
-build system's `EXTRA_USER_MANIFEST_LINES` make variable.
-
-1.  Create a local shell script with the commands you want to run; for this
-    example, call it `${HOME}/my_local_script.sh`. \
-    **NOTE**: The first line must be a `#!` line, typically `#!/boot/bin/sh`.
-2.  Add your script to the boot filesystem by invoking `make` (or one of the
-    `//zircon/scripts/build-*` scripts) with \
-    `EXTRA_USER_MANIFEST_LINES="my_installed_script=${HOME}/my_local_script.sh"`
-    \
-    This will copy your local script into the boot filesystem at the path
-    `/boot/my_installed_script`. (You can change the `my_installed_script` part
-    to change the basename of the installed script, though it will always appear
-    under `/boot`.)
-3.  Tell `devmgr` to invoke your script by passing a commandline like
-    `zircon.autorun.boot=/boot/my_installed_script`
-
-## zircon.autorun.system=\<command>
-
-This option requests that *command* be run once the system partition is mounted
-and *init* is launched.  If there is no system bootfs or system partition, it
-will never be launched.
-
-Any `+` characters in *command* are treated as argument separators, allowing
-you to pass arguments to an executable.
-
-## zircon.system.blob-init=\<command>
-
-**DEPRECATED** See [`zircon.system.pkgfs.cmd`](#zircon.system.pkgfs.cmd).
-
-This option requests that *command* be run once the blob partition is
-mounted. The given command is expected to mount /system, and then signal its
-process handle with `ZX_USER_SIGNAL_0`.
-
-*command* may not assume that any other filesystem has been mounted. If
-`zircon.system.blob-init-arg` is set, it will be provided as the first
-argument.
-
-A ramdisk containing `/system` takes precedence over
-`zircon.system.blob-init` and *command* will not be run if a system
-ramdisk is present. blob init will take precedence over a minfs
-partition with the system GUID, and the minfs partition will not be mounted
-if `zircon.system.blob-init` is set.
-
-## zircon.system.disable-automount=\<bool>
-
-This option prevents the fshost from auto-mounting any disk filesystems
-(/system, /data, etc), which can be useful for certain low level test setups.
-It is false by default.  It is implied by **netsvc.netboot=true**
-
-## zircon.system.pkgfs.cmd=\<command>
-
-This option requests that *command* be run once the blob partition is mounted.
-Any `+` characters in *command* are treated as argument separators, allowing
-you to pass arguments to an executable.
-
-The executable and its dependencies (dynamic linker and shared libraries) are
-found in the blob filesystem.  The executable *path* is *command* before the
-first `+`.  The dynamic linker (`PT_INTERP`) and shared library (`DT_NEEDED`)
-name strings sent to the loader service are prefixed with `lib/` to produce a
-*path*.  Each such *path* is resolved to a blob ID (i.e. merkleroot in ASCII
-hex) using the `zircon.system.pkgfs.file.`*path* command line argument.  In
-this way, `/boot/config/devmgr` contains a fixed manifest of files used to
-start the process.
-
-The new process receives a `PA_USER0` channel handle at startup that will be
-used as the client filesystem handle mounted at `/pkgfs`.  The command is
-expected to start serving on this channel and then signal its process handle
-with `ZX_USER_SIGNAL_0`.  Then `/pkgfs/system` will be mounted as `/system`.
-
-## zircon.system.pkgfs.file.*path*=\<blobid>
-
-Used with [`zircon.system.pkgfs.cmd`](#zircon.system.pkgfs.cmd), above.
-
-## zircon.system.writable=\<bool>
-
-This option requests that if a minfs partition with the system type GUID is
-found, it is to be mounted read-write rather than read-only.
-
-## zircon.system.volume=\<arg>
-
-This option specifies where to find the "/system" volume.
-
-It may be set to:
-"any", in which case the first volume of the appropriate type will be used.
-"local" in which the first volume that's non-removable of the appropriate type
-  will be used.
-"none" (default) which avoids mounting anything.
-
-A "/system" ramdisk provided by bootdata always supersedes this option.
-
-## zircon.system.filesystem-check=\<bool>
-
-This option requests that filesystems automatically mounted by the system
-are pre-verified using a filesystem consistency checker before being mounted.
-
-By default, this option is set to false.
-
-## netsvc.netboot=\<bool>
-
-If true, zircon will attempt to netboot into another instance of zircon upon
-booting.
-
-More specifically, zircon will fetch a new zircon system from a bootserver on
-the local link and attempt to kexec into the new image, thereby replacing the
-currently running instance of zircon.
-
-This setting implies **zircon.system.disable-automount=true**
-
-## netsvc.advertise=\<bool>
-
-If true, netsvc will seek a bootserver by sending netboot advertisements.
-Defaults to true.
-
-## netsvc.interface=\<path>
-
-This option instructs netsvc to use only the ethernet device at the given
-topological path. All other ethernet devices are ignored by netsvc. The
-topological path for a device can be determined from the shell by running the
-`lsdev` command on the ethernet class device (e.g., `/dev/class/ethernet/000`).
-
-This is useful for configuring network booting for a device with multiple
-ethernet ports which may be enumerated in a non-deterministic order.
-
-## userboot=\<path>
-
-This option instructs the userboot process (the first userspace process) to
-execute the specified binary within the bootfs, instead of following the
-normal userspace startup process (launching the device manager, etc).
-
-It is useful for alternate boot modes (like a factory test or system
-unit tests).
-
-The pathname used here is relative to `/boot`, so it should not start with
-a `/` prefix.
-
-Note that this option does not work for executables that are linked with
-libraries other than libc and the dynamic linker.
-
-Example: `userboot=bin/core-tests`
-
-## userboot.reboot
-
-If this option is set, userboot will attempt to reboot the machine after
-waiting 3 seconds when the process it launches exits.
-
-*If running with userboot=bin/core-tests in QEMU, this will cause the system to
-continually run tests and reboot.*
-
-## userboot.shutdown
-
-If this option is set, userboot will attempt to power off the machine
-when the process it launches exits.
-
-## vdso.soft_ticks=\<bool>
-
-If this option is set, the `zx_ticks_get` and `zx_ticks_per_second` system
-calls will use `zx_clock_get_monotonic()` in nanoseconds rather than
-hardware cycle counters in a hardware-based time unit.  Defaults to false.
-
-## virtcon.disable
-
-Do not launch the virtual console service if this option is present.
-
-## virtcon.hide-on-boot
-
-If this option is present, the virtual console will not take ownership of any
-displays until the user switches to it with a device control key combination.
-
-## virtcon.keep-log-visible
-
-If this option is present, the virtual console service will keep the
-debug log (vc0) visible instead of switching to the first shell (vc1) at startup.
-
-## virtcon.keymap=\<name>
-
-Specify the keymap for the virtual console.  "qwerty" and "dvorak" are supported.
-
-## virtcon.font=\<name>
-
-Specify the font for the virtual console.  "9x16" and "18x32" are supported.
-
-## zircon.nodename=\<name>
-
-Set the system nodename, as used by `bootserver`, `loglistener`, and the
-`net{addr,cp,ls,runcmd}` tools.  If omitted, the system will generate a
-human-readable nodename from its MAC address.  This cmdline is honored by
-GigaBoot and Zircon.
-
-## console.path=\<path>
-
-Specify console device path. If not specified device manager will open
-`/dev/misc/console`. Only has effect if kernel.shell=false.
-
-# Additional Gigaboot Commandline Options
-
-## bootloader.timeout=\<num>
-This option sets the boot timeout in the bootloader, with a default of 3
-seconds. Set to zero to skip the boot menu.
-
-## bootloader.fbres=\<w>x\<h>
-This option sets the framebuffer resolution. Use the bootloader menu to display
-available resolutions for the device.
-
-Example: `bootloader.fbres=640x480`
-
-## bootloader.default=\<network|local|zedboot>
-This option sets the default boot device to netboot, use a local zircon.bin or to netboot via zedboot.
-
-# How to pass the commandline to the kernel
-
-## in Qemu, using scripts/run-zircon*
-
-Pass each option using -c, for example:
-```
-./scripts/run-zircon-x64 -c gfxconsole.font=18x32 -c gfxconsole.early=false
-```
-
-## in GigaBoot20x6, when netbooting
-
-Pass the kernel commandline at the end, after a -- separator, for example:
-```
-bootserver zircon.bin bootfs.bin -- gfxconsole.font=18x32 gfxconsole.early=false
-```
-
-## in GigaBoot20x6, when booting from USB flash
-
-Create a text file named "cmdline" in the root of the USB flash drive's
-filesystem containing the command line.
diff --git a/docs/kernel_internal_errors.md b/docs/kernel_internal_errors.md
deleted file mode 100644
index b7aa2b4..0000000
--- a/docs/kernel_internal_errors.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Kernel internal errors
-
-These are error codes that are specific to the kernel and are not exposed to userspace programs or
-drivers.
-
-TODO: Document these codes.
diff --git a/docs/kernel_invariants.md b/docs/kernel_invariants.md
deleted file mode 100644
index a29d480..0000000
--- a/docs/kernel_invariants.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Zircon Kernel Invariants
-
-On x86, Zircon needs to maintain the following invariants for code running
-in ring 0 (kernel mode).
-
-These invariants are documented here because they are not necessarily easy
-to test -- breaking an invariant will not necessarily be caught by
-Zircon's test suite.
-
-* Flags register:
-
-  * The direction flag (DF) should be 0.  This is required by the x86
-    calling conventions.
-
-    If this flag is set to 1, uses of x86 string instructions (e.g. `rep
-    movs` in `memcpy()` or inlined by the compiler) can go wrong and copy
-    in the wrong direction.  It is OK for a function to set this flag to 1
-    temporarily as long as it changes it back to 0 before returning or
-    calling other functions.
-
-  * The alignment check flag (AC) should normally be 0.  On CPUs that
-    support SMAP, this prevents the kernel from accidentally reading or
-    writing userland data.
-
-* The `gs_base` register must point to the current CPU's `x86_percpu`
-  struct whenever running in kernel mode with interrupts enabled.
-  `gs_base` should only be changed to point to something else while
-  interrupts are disabled.  For example, the `swapgs` instruction should
-  only be used when interrupts are disabled.
-
-* The following are partially enforced by the compiler:
-
-  * No use of extended registers (SSE, AVX, x87, etc.) is allowed, because
-    that would clobber userland's register state.
-
-    This is partially achieved by passing `-mno-sse` to the compiler.  This
-    option is necessary to prevent the compiler from using SSE registers in
-    optimizations (e.g. memory copies).
-
-    We would like to prevent accidentally using the `float` or `double`
-    types in kernel code, but GCC and Clang won't do that for us in all
-    cases.  `-mno-sse` does not prevent using `float`/`double` with either
-    compiler -- the compilers will use x87 instructions instead.
-
-    We compile with `-msoft-float`, which seems to prevent GCC from
-    generating x87 instructions (and hence using x87 registers): GCC 6.3.0
-    will give an error on `float`/`double` arithmetic and return values,
-    but it does not prevent passing these types around as arguments.
-    However, passing `-msoft-float` to Clang seems to have no effect: Clang
-    7.0.0 will still generate x87 instructions (and use x87 registers) for
-    code using `float` or `double`.
-
-  * No storing data below `%rsp` on the stack.  Note that userland code can
-    do this: the SysV x86-64 ABI allows functions to store data in the "red
-    zone", which is the 128 bytes below %rsp.  However, kernel code cannot
-    use the red zone because interrupts may clobber this region -- the CPU
-    pushes data onto the stack immediately below %rsp when it invokes an
-    interrupt handler.
-
-    This is generally enforced by passing `-mno-red-zone` to the compiler.
diff --git a/docs/kernel_scheduling.md b/docs/kernel_scheduling.md
deleted file mode 100644
index 77421f5..0000000
--- a/docs/kernel_scheduling.md
+++ /dev/null
@@ -1,168 +0,0 @@
-Zircon Scheduling
-=================
-
-Background
-==========
-
-The primary responsibility of any scheduler is to share the limited
-resource of processor time between all threads that wish to use it. In a
-general purpose operating system, it tries to do so in a fair way,
-ensuring that all threads are allowed to make some progress.
-
-Our scheduler is an evolution of LK’s scheduler. As such it
-started as a minimal scheduler implementation and was extended to meet
-our needs as the project grew.
-
-Design
-======
-
-#### Overview
-
-In essence there is a scheduler running on each logical CPU in the machine.
-These schedulers run independently and use IPI (Inter-Processor
-Interrupts) to coordinate. However each CPU is responsible for
-scheduling the threads that are running on it. See [*CPU
-Assignment*](#cpu-assignment-and-migration) below for how we decide
-which CPU a thread is on, and how/when it migrates.
-
-Each CPU has its own set of priority queues. One for each priority level
-in the system, currently 32. Note that these are fifo queues, not the data
-structure known as a priority queue. In each queue is an ordered list of
-runnable threads awaiting execution. When it is time for a new thread to run,
-the scheduler simply looks at the highest numbered queue that contains a thread,
-pops the head off of that queue and runs that thread.See
-[*Priority Management*](#priority-management) below for more details
-about how it decides which thread should be in which queue. If there are no
-threads in the queues to run it will instead run the idle thread, see [*Realtime
-and Idle Threads*](#realtime-and-idle-threads) below for more details.
-
-Each thread is assigned the same timeslice size (THREAD_INITIAL_TIME_SLICE)
-when it is picked to start running. If it uses its whole timeslice it will be
-reinserted at the end of the appropriate priority queue. However if it has
-some of its timeslice remaining from a previous run it will be inserted at the
-head of the priority queue so it will be able to resume as quickly as possible.
-When it is picked back up again it will only run for the remainder of its
-previous timeslice.
-
-When the scheduler selects a new thread from the priority queue it sets
-the CPU's preemption timer for either a full timeslice, or the remainder of the
-previous timeslice. When that timer fires the scheduler will stop execution on
-that thread, add it to the appropriate queue, select another thread and start
-over again.
-
-If a thread blocks waiting for a shared resource then it's taken out of
-its priority queue and is placed in a wait queue for the shared resource.
-When it is unblocked it will be reinserted in the appropriate priority
-queue of an eligible CPU ([*CPU
-Assignment*](#cpu-assignment-and-migration)) and if it had remaining timeslice
-to run it will be added to the front of the queue for expedited handling.
-
-#### Priority Management
-
-There are three different factors used to determine the effective
-priority of a thread, the effective priority being what is used to
-determine which queue it will be in.
-
-The first factor is the base priority, which is simply the thread’s
-requested priority. There are currently 32 levels with 0 being the
-lowest and 31 being the highest.
-
-The second factor is the priority boost. This is a value bounded between
-\[-MAX_PRIORITY_ADJ, MAX_PRIORITY_ADJ\] used to offset the base priority, it is
-modified by the following cases:
-
--   When a thread is unblocked, after waiting on a shared resource or
-    sleeping, it is given a one point boost.
-
--   When a thread yields (volunteers to give up control), or volunteers
-    to reschedule, its boost is decremented by one but is capped at 0
-    (won’t go negative).
-
--   When a thread is preempted and has used up its entire timeslice, its
-    boost is decremented by one but is able to go negative.
-
-The third factor is its inherited priority. If the thread is in control
-of a shared resource and it is blocking another thread of a higher
-priority then it is given a temporary boost up to that thread’s priority
-to allow it to finish quickly and allow the higher priority thread to
-resume.
-
-The effective priority of the thread is either the inherited priority,
-if it has one, or the base priority plus its boost. When this priority
-changes, due to any of the factors changing, the scheduler will move it
-to a new priority queue and reschedule the CPU. Allowing it to have
-control if it is now the highest priority task, or relinquish control if
-it is no longer highest.
-
-The intent in this system is to ensure that interactive threads are
-serviced quickly. These are usually the threads that interact directly
-with the user and cause user-perceivable latency. These threads usually
-do little work and spend most of their time blocked awaiting another
-user event. So they get the priority boost from unblocking while
-background threads that do most of the processing receive the priority
-penalty for using their entire timeslice.
-
-#### CPU Assignment and Migration
-
-Threads are able to request which CPUs on which they wish to run using a
-CPU affinity mask, a 32 bit mask where 0b001 is CPU 1, 0b100 is CPU 3,
-and 0b101 is either CPU 1 or CPU 3. This mask is usually respected but
-if the CPUs it requests are all inactive it will be assigned to another
-CPU. Also notable, if it is “pinned” to a CPU, that is its mask contains
-only one CPU, and that CPU becomes inactive the thread will sit
-unserviced until that CPU becomes active again. See [*CPU
-Activation*](#cpu-activation) below for details.
-
-When selecting a CPU for a thread the scheduler will choose, in order:
-
-1.  The CPU doing the selection, if it is **idle** and in the affinity mask.
-
-2.  The CPU the thread last ran on, if it is **idle** and in the affinity mask.
-
-3.  Any **idle** CPU in the affinity mask.
-
-4.  The CPU the thread last ran on, if it is active and in the affinity mask.
-
-5.  The CPU doing the selection, if it is the only one in the affinity mask or
-    all cpus in the mask are not active.
-
-6.  Any active CPU in the affinity mask.
-
-If the thread is running on a CPU not in its affinity mask (due to case
-5 above) the scheduler will try to rectify this every time the thread is
-preempted, yields, or voluntarily reschedules. Also if the thread
-changes its affinity mask the scheduler may migrate it.
-
-Every time a thread comes back from waiting on a shared resource or
-sleeping and needs to be assigned a priority queue, the scheduler will
-re-evaluate its CPU choice for the thread, using the above logic, and
-may move it.
-
-#### CPU Activation
-
-When a CPU is being deactivated, that is shutdown and removed from the
-system, the scheduler will transition all running threads onto other
-CPUs. The only exception is threads that are “pinned”, that is they only
-have the deactivating CPU in their affinity mask, these threads are put
-back into the run queue where they will sit unserviced until the CPU is
-reactivated.
-
-When a CPU is reactivated it will service the waiting pinned threads and
-threads that are running on non-Affinity CPUs should be migrated back
-pretty quickly by their CPUs scheduler due to the above rules. There is
-no active rebalancing of threads to the newly awakened CPU, but as it
-should be idle more often, it should see some migration due to the logic
-laid out above in [*CPU Assignment and
-Migration*](#cpu-assignment-and-migration).
-
-#### Realtime and Idle Threads
-
-These are special threads that are treated a little differently.
-
-The idle thread runs when no other threads are runnable. There is one on
-each CPU and it lives outside of the priority queues, but effectively in
-a priority queue of -1. It is used to track idle time and can be used by
-platform implementations for a low power wait mode.
-
-Realtime threads (marked with `THREAD_FLAG_REAL_TIME`) are allowed to run without
-preemption and will run until they block, yield, or manually reschedule.
diff --git a/docs/libc.md b/docs/libc.md
deleted file mode 100644
index ae00479..0000000
--- a/docs/libc.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Fuchsia's libc
-
-TODO(ZX-1598) Type more here.
-
-## Standards
-
-### C11
-
-Fuchsia's libc supports most of the [C11][c11std] standard. This
-in particular includes the atomic and threading portions of the
-standard library.
-
-### POSIX
-
-Fuchsia implements a subset of POSIX.
-
-Things at least partially supported include the basics of POSIX I/O
-(open/close/read/write/stat/...), and pthreads (threads and mutexes).
-
-On Fuchsia, the portion of file paths beginning with a sequence of
-`..` is resolved locally. See [this writeup][dotdot] for more
-information.
-
-Similarly, symlinks are not supported on Fuchsia.
-
-Conspicuously not supported are UNIX signals, fork, and exec.
-
-## FDIO
-
-Fuchsia's libc does not directly support I/O operations. Instead it
-provides weak symbols that another library can override. This is
-typically done by [fdio.so][fdio].
-
-## Linking
-
-Statically linking libc is not supported. Everything dynamically links libc.so.
-
-## Dynamic linking and loading
-
-libc.so is also the dynamic linker.
-
-[c11std]: https://en.wikipedia.org/wiki/C11_(C_standard_revision)
-[dotdot]: https://fuchsia.googlesource.com/docs/+/master/dotdot.md
-[fdio]: ../system/ulib/fdio
diff --git a/docs/lockdep-design.md b/docs/lockdep-design.md
deleted file mode 100644
index c066d65..0000000
--- a/docs/lockdep-design.md
+++ /dev/null
@@ -1,781 +0,0 @@
-# Runtime Lock Validation in Zircon and Fuchsia
-
-## Introduction
-
-Lock validation is a technique for checking the consistency of locking behavior
-in a program to find potential deadlock hazards. This document discusses
-relevant aspects of the static and dynamic approaches to lock validation and
-presents the foundation for the runtime lock validation library available in
-Zircon and Fuchsia.
-
-## Background
-
-Lock validation may be performed either statically or dynamically. The following
-summarizes the important differences between static and dynamic approaches to
-lock validation:
-
-* When the validation is performed: compile time vs. run time.
-* How effective the validator is at finding potential problems.
-* What level of involvement is required by the programmer.
-* The overhead cost of the validation itself.
-
-### Static Validation
-
-Static validation is typically performed at compile time by analyzing the call
-graphs produced by the compiler or other source-level processor. With this
-approach it is necessary to instrument the code and locking primitives with
-annotations to inform the validator about which types represent locks and which
-rules to apply (or not) to the code that uses the lock types.
-
-The benefits of static validation include early detection of issues at build
-time, deterministic validation results, and zero runtime overhead. This
-combination of properties make it attractive to always enable static validation,
-ensuring that locking issues are often caught before code makes it into the
-build, without impacting the performance of the build artifacts.
-
-Static validation also has some down sides. One problem is that static
-validation requires correct, consistent application of a variety of annotations
-to both locks and code to provide useful results. This can cause maintenance
-issues unless diligent code review standards are implemented. Another issue is
-that static validation has limited visibility and can be fooled by conditional
-paths, dynamic dispatch, move semantics, and lock dependencies that span
-compilation units.
-
-### Dynamic Validation
-
-Dynamic validation is performed online at runtime by observing the relationships
-between locks as the code executes. With this approach it is generally
-sufficient to instrument just the locking primitives and acquire/release
-operations to provide the information required for validation.
-
-The benefits of dynamic validation include simpler instrumentation (from the
-user's perspective) and potentially greater visibility into the actual runtime
-behavior of the program. This makes dynamic validation useful in large code
-bases, where it may not be possible for static validation to see the full
-set of possible lock interactions.
-
-The main downsides of dynamic validation are runtime overhead and execution
-coverage requirements. Because dynamic validation must track lock interactions
-at runtime, each acquire and release incurs a non-zero execution cost to update
-tracking data, in addition to the memory overhead of the tracking data itself.
-Runtime tracking also has the consequence that code paths that are not executed
-cannot be analyzed by the validator. This may increase the burden on the
-developer and QA to ensure sufficient execution coverage if that is not already
-a project requirement.
-
-
-### Locking Ordering Invariant
-
-The job of the lock validator is to determine whether or not the lock invariants
-of the program hold. The primary invariant is the order between two or more
-locks: all paths in a program that acquire two or more locks must do so in an
-order consistent with every other path involving two or more of the same locks to
-avoid the potential for deadlock. Environments that deal with hardware
-interrupts, such as embedded systems and kernels, have an additional ordering
-invariant to avoid interrupt-induced deadlocks. These invariants are illustrated
-in the following subsections.
-
-##### Basic Inversion
-
-The simplest form of inversion occurs when a program has two locks that are
-both acquired sequentially with inconsistent orders in different paths.
-
-For example, a program with the locks **A** and **B** and code paths
-**P<sub>1</sub>** and **P<sub>2</sub>** and the following behavior has the
-potential for deadlock:
-
-Path **P<sub>1</sub>** acquires and releases the locks in the sequence:
-
-1. Acquire(**A**)
-2. Acquire(**B**)
-3. Release(**B**)
-4. Release(**A**)
-
-Path **P<sub>2</sub>** acquires and releases the locks in the inverted sequence:
-
-1. Acquire(**B**)
-2. Acquire(**A**)
-3. Release(**A**)
-4. Release(**B**)
-
-With the right interleaving, perhaps due to both paths executing concurrently
-on different threads, a deadlock occurs when path **P<sub>1</sub>** holds lock
-**A** and blocks waiting for lock **B**, while path **P<sub>2</sub>** holds lock
-**B** and blocks waiting for lock **A**.
-
-##### Circular Dependency
-
-Inversion may also occur between more than two locks and paths. This kind of
-inversion is much harder to recognize through manual inspection because each
-pair of locks involved may appear to be correctly ordered in every path involving
-just the pairs, and yet a potential deadlock may still exist given overall
-ordering of the locks.
-
-For example, a program with the locks **A**, **B**, and **C**; paths
-**P<sub>1</sub>**, **P<sub>2</sub>**, and **P<sub>3</sub>**; with the following
-behavior has the potential for deadlock:
-
-Path **P<sub>1</sub>** acquires and releases the locks in the sequence:
-
-1. Acquire(**A**)
-2. Acquire(**B**)
-3. Release(**B**)
-4. Release(**A**)
-
-Path **P<sub>2</sub>** acquires and releases the locks in the sequence:
-
-1. Acquire(**B**)
-2. Acquire(**C**)
-3. Release(**C**)
-4. Release(**B**)
-
-Path **P<sub>3</sub>** acquires and releases the locks in the sequence:
-
-1. Acquire(**C**)
-2. Acquire(**A**)
-3. Release(**A**)
-4. Release(**C**)
-
-With the right interleaving of paths **P<sub>1</sub>**, **P<sub>2</sub>**,
-and **P<sub>3</sub>** a deadlock occurs as each path acquires the lock at the
-first step and waits for the lock at the second step. In practice this situation
-may be compounded by the existence of many different paths that produce the same
-pairwise lock sequences.
-
-##### IRQ-Safe Ordering
-
-In systems that deal with hardware interrupts the ordering between irq-safe and
-non-irq-safe locks is critical: a non-irq-safe lock must never be acquired while
-holding an irq-safe lock to prevent indirect lock inversions. Irq-safe locks
-preserve ordering between irq and non-irq context; a consistent order of two or
-more irq-safe locks is guaranteed to be safe for paths running in both irq and
-non-irq context. The same is not true for non-irq-safe locks. The reason for this
-is that non-irq-safe locks permit irq handlers to effectively insert the locks
-acquired by the handler at arbitrary points in the interrupted task's lock
-sequences.
-
-For example, a system with non-irq-safe lock **A** and irq-safe lock
-**B<sub>irq</sub>**; paths **P<sub>1</sub>**, **P<sub>2</sub>**, and irq path
-**P<sub>irq</sub>**; with the following behavior has the potential for deadlock:
-
-Path **P<sub>1</sub>** on **CPU1** acquires and releases the lock in sequence:
-
-1. Acquire(**A**)
-2. _**P<sub>irq</sub>** interrupts here on **CPU1**_
-3. Release(**A**)
-
-Path **P<sub>irq</sub>** on **CPU1** acquires and releases the lock in sequence:
-
-1. Acquire(**B<sub>irq</sub>**)
-2. Release(**B<sub>irq</sub>**)
-
-Path **P<sub>2</sub>** on **CPU2** acquires and releases the locks in sequence:
-
-1. Acquire(**B<sub>irq</sub>**)
-2. Acquire(**A**)
-3. Release(**A**)
-4. Release(**B<sub>irq</sub>**)
-
-With the right interleaving of paths **P<sub>1</sub>**, **P<sub>2</sub>**, and
-**P<sub>irq</sub>** a deadlock occurs as **P<sub>irq</sub>** attempts to acquire
-**B<sub>irq</sub>** while **P<sub>2</sub>** holds **B<sub>irq</sub>** and blocks
-waiting for **A**. This is an indirect lock inversion: **P<sub>irq</sub>**
-effectively inserts an acquire/release sequence of **B<sub>irq</sub>** in the
-middle of the acquire/release sequence of **A** in path **P<sub>1</sub>**, which
-is inconsistent with the lock sequence for the same locks in path
-**P<sub>2</sub>**.
-
-### Performing Validation
-
-The invariants discussed in the previous section can be validated using a finite
-directed graph. The directed graph tracks the identity and order of locks as the
-analysis traverses the code paths. Such a graph can be built either by traversing
-the call graphs generated by a compiler or source-level processor (static
-analysis) or by observing the ordering of locks during program execution (dynamic
-analysis). This section introduce the process in abstract terms that apply to
-either approach, in preparation for developing a concrete dynamic analysis
-strategy later on.
-
-In the most general terms, building a directed graph from a code path requires
-maintaining a list of actively held locks as the path is traversed: a node
-representing a lock is added to the list whenever the lock is acquired and
-removed from the list whenever the lock is released. In addition to maintaining
-the active list, a directed edge is added to the graph from a vertex representing
-the newly acquired lock to each vertex representing a lock already in the list.
-
-#### Basic Inversion Example
-
-This section illustrates a directed graph approach to detect a basic two-lock
-inversion.
-
-Recall from the earlier example a program with the locks **A** and **B**; code
-paths **P<sub>1</sub>** and **P<sub>2</sub>**; and the following behavior:
-
-Path **P<sub>1</sub>** acquires and releases the locks in the sequence:
-
-1. Acquire(**A**)
-2. Acquire(**B**)
-3. Release(**B**)
-4. Release(**A**)
-
-Path **P<sub>2</sub>** acquires and releases the locks in the inverted sequence:
-
-1. Acquire(**B**)
-2. Acquire(**A**)
-3. Release(**A**)
-4. Release(**B**)
-
-##### Analysis of Path **P<sub>1</sub>**
-
-Starting with path **P<sub>1</sub>** we define and update the directed graph.
-
-Let **L<sub>1</sub>** be the ordered _active_ list of locks held by path
-**P<sub>1</sub>**.
-
-Let **G** = (**V**, **E**) be the directed graph, having the set of vertices
-**V** representing observed locks and the set of directed edges between vertices
-**E**.
-
-Initial state:
-
-| **L<sub>1</sub>** | **V** | **E** |
-|-------------------|-------|-------|
-| ()                | {}    | {}    |
-
-After **P<sub>1</sub>** step 1:
-
-| **L<sub>1</sub>** | **V**   | **E** |
-|-------------------|---------|-------|
-| (**A**)           | {**A**} | {}    |
-
-This step adds lock **A** to the active list and introduces a vertex for the
-same lock to the directed graph. Since there are no other locks in the active
-list no edges are added.
-
-After **P<sub>1</sub>** step 2:
-
-| **L<sub>1</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| (**A**, **B**)    | {**A**, **B**} | {(**B**, **A**)} |
-
-This step adds lock **B** to the active list and also introduces a corresponding
-vertex to the graph. This time the active list does contain a lock, so an edge
-from the new lock to the existing lock is added to the graph. This edge
-represents that lock **B** now _depends_ on lock **A** preceding it in any
-other path that involves both locks.
-
-After **P<sub>1</sub>** step 3:
-
-| **L<sub>1</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| (**A**)           | {**A**, **B**} | {(**B**, **A**)} |
-
-Lock **B** is removed from the active list. No updates to the graph.
-
-After **P<sub>1</sub>** step 4:
-
-| **L<sub>1</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| ()                | {**A**, **B**} | {(**B**, **A**)} |
-
-Lock **A** is removed from the active list. No updates to the graph.
-
-##### Analysis of Path **P<sub>2</sub>**
-
-Let **L<sub>2</sub>** be the active list of locks held by **P<sub>2</sub>**.
-
-Initial state:
-
-| **L<sub>2</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| ()                | {**A**, **B**} | {(**B**, **A**)} |
-
-In this case the initial state is the final state from path **P<sub>1</sub>**.
-
-After **P<sub>2</sub>** step 1:
-
-| **L<sub>2</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| (**B**)           | {**A**, **B**} | {(**B**, **A**)} |
-
-This step adds lock **B** to the active list. As there are no other locks in the
-active list no edges are added to the graph. Since **B** already has a vertex in
-the graph there is also no change to **V**.
-
-After **P<sub>2</sub>** step 2:
-
-| **L<sub>2</sub>** | **V**          | **E**                            |
-|-------------------|----------------|----------------------------------|
-| (**B**, **A**)    | {**A**, **B**} | {(**B**, **A**), (**A**, **B**)} |
-
-This step adds lock **A** to the active list. Since this lock already has a
-vertex there is no change to **V**. However, because there is a lock in the
-active list an edge from the new lock to the existing lock is added to the
-graph. With this new edge the graph now forms a cycle between vertices **A** and
-**B**, indicating that ordering between these locks is not consistent between
-the two paths considered thus far and that a potential deadlock exists.
-
-#### Circular Dependency Example
-
-This section illustrates a directed graph approach to detect a circular
-dependency inversion using previously discussed example from the invariants
-section. This illustration is somewhat abbreviated due to the similarity to the
-previous illustration.
-
-Consider a program with the locks **A**, **B**, and **C** and paths
-**P<sub>1</sub>**, **P<sub>2</sub>**, and **P<sub>3</sub>** and the following
-behavior:
-
-Path **P<sub>1</sub>** acquires and releases the locks in the sequence:
-
-1. Acquire(**A**)
-2. Acquire(**B**)
-3. Release(**B**)
-4. Release(**A**)
-
-Path **P<sub>2</sub>** acquires and releases the locks in the sequence:
-
-1. Acquire(**B**)
-2. Acquire(**C**)
-3. Release(**C**)
-4. Release(**B**)
-
-Path **P<sub>3</sub>** acquires and releases the locks in the sequence:
-
-1. Acquire(**C**)
-2. Acquire(**A**)
-3. Release(**A**)
-4. Release(**C**)
-
-##### Analysis of Path **P<sub>1</sub>**
-
-Let **L<sub>1</sub>** be the ordered _active_ list of locks held by path
-**P<sub>1</sub>**.
-
-Let **G** = (**V**, **E**) be the directed graph, having the set of vertices
-**V** representing observed locks and the set of directed edges between vertices
-**E**.
-
-Initial state:
-
-| **L<sub>1</sub>** | **V** | **E** |
-|-------------------|-------|-------|
-| ()                | {}    | {}    |
-
-After **P<sub>1</sub>** step 1:
-
-| **L<sub>1</sub>** | **V**   | **E** |
-|-------------------|---------|-------|
-| (**A**)           | {**A**} | {}    |
-
-
-After **P<sub>1</sub>** step 2:
-
-| **L<sub>1</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| (**A**, **B**)    | {**A**, **B**} | {(**B**, **A**)} |
-
-
-After **P<sub>1</sub>** step 3:
-
-| **L<sub>1</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| (**A**)           | {**A**, **B**} | {(**B**, **A**)} |
-
-
-After **P<sub>1</sub>** step 4:
-
-| **L<sub>1</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| ()                | {**A**, **B**} | {(**B**, **A**)} |
-
-##### Analysis of Path **P<sub>2</sub>**
-
-Let **L<sub>2</sub>** be the ordered _active_ list of locks held by path
-**P<sub>2</sub>**.
-
-Initial state:
-
-| **L<sub>2</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| ()                | {**A**, **B**} | {(**B**, **A**)} |
-
-
-After **P<sub>2</sub>** step 1:
-
-| **L<sub>2</sub>** | **V**          | **E**            |
-|-------------------|----------------|------------------|
-| (**B**)           | {**A**, **B**} | {(**B**, **A**)} |
-
-After **P<sub>2</sub>** step 2:
-
-| **L<sub>2</sub>** | **V**                 | **E**                            |
-|-------------------|-----------------------|----------------------------------|
-| (**B**, **C**)    | {**A**, **B**, **C**} | {(**B**, **A**), (**C**, **B**)} |
-
-This step adds lock **C** to the active list and also introduces a corresponding
-vertex to the graph. The active list contains the lock **B**, so an edge is added
-from **C** to **B**.
-
-After **P<sub>2</sub>** step 3:
-
-| **L<sub>2</sub>** | **V**                 | **E**                            |
-|-------------------|-----------------------|----------------------------------|
-| (**B**)           | {**A**, **B**, **C**} | {(**B**, **A**), (**C**, **B**)} |
-
-
-After **P<sub>2</sub>** step 4:
-
-| **L<sub>2</sub>** | **V**                 | **E**                            |
-|-------------------|-----------------------|----------------------------------|
-| ()                | {**A**, **B**, **C**} | {(**B**, **A**), (**C**, **B**)} |
-
-##### Analysis of Path **P<sub>3</sub>**
-
-Let **L<sub>3</sub>** be the ordered _active_ list of locks held by path
-**P<sub>3</sub>**.
-
-Initial state:
-
-| **L<sub>3</sub>** | **V**                 | **E**                            |
-|-------------------|-----------------------|----------------------------------|
-| ()                | {**A**, **B**, **C**} | {(**B**, **A**), (**C**, **B**)} |
-
-
-After **P<sub>3</sub>** step 1:
-
-| **L<sub>3</sub>** | **V**                 | **E**                            |
-|-------------------|-----------------------|----------------------------------|
-| (**C**)           | {**A**, **B**, **C**} | {(**B**, **A**), (**C**, **B**)} |
-
-After **P<sub>3</sub>** step 2:
-
-| **L<sub>3</sub>** | **V**                 | **E**                                            |
-|-------------------|-----------------------|--------------------------------------------------|
-| (**C**, **A**)    | {**A**, **B**, **C**} | {(**B**, **A**), (**C**, **B**), (**A**, **C**)} |
-
-This step adds lock **A** to the active list. The active list contains the lock
-**C**, so an edge is added from **A** to **C**. With this new edge the graph now
-forms a cycle in the vertices (**A**, **B**, **C**), indicating a circular
-dependency and the potential for deadlock if paths **P<sub>1</sub>**,
-**P<sub>2</sub>**, and **P<sub>3</sub>** are interleaved in the right way.
-
-#### IRQ-Safe Ordering Example
-
-This section illustrates a directed graph approach to detect irq-safe order
-violations using the previously discussed example from the invariants section.
-
-Recall the example system with non-irq-safe lock **A** and irq-safe lock
-**B<sub>irq</sub>**; paths **P<sub>1</sub>**, **P<sub>2</sub>**, and irq path
-**P<sub>irq</sub>**; with the following behavior:
-
-Path **P<sub>1</sub>** acquires and releases the lock in sequence:
-
-1. Acquire(**A**)
-2. Release(**A**)
-
-Path **P<sub>irq</sub>** acquires and releases the lock in sequence:
-
-1. Acquire(**B<sub>irq</sub>**)
-2. Release(**B<sub>irq</sub>**)
-
-Path **P<sub>2</sub>** acquires and releases the locks in sequence:
-
-1. Acquire(**B<sub>irq</sub>**)
-2. Acquire(**A**)
-3. Release(**A**)
-4. Release(**B<sub>irq</sub>**)
-
-##### Analysis of Path **P<sub>1</sub>**
-
-Let **L<sub>1</sub>** be the ordered _active_ list of locks held by path
-**P<sub>1</sub>**.
-
-Let **G** = (**V**, **E**) be the directed graph, having the set of vertices
-**V** representing observed locks and the set of directed edges between vertices
-**E**.
-
-Initial state:
-
-| **L<sub>1</sub>** | **V** | **E** |
-|-------------------|-------|-------|
-| ()                | {}    | {}    |
-
-After **P<sub>1</sub>** step 1:
-
-| **L<sub>1</sub>** | **V**   | **E** |
-|-------------------|---------|-------|
-| (**A**)           | {**A**} | {}    |
-
-After **P<sub>1</sub>** step 2:
-
-| **L<sub>1</sub>** | **V**   | **E** |
-|-------------------|---------|-------|
-| ()                | {**A**} | {}    |
-
-##### Analysis of Path **P<sub>irq</sub>**
-
-Let **L<sub>irq</sub>** be the ordered _active_ list of locks held by path
-**P<sub>irq</sub>**.
-
-Initial state:
-
-| **L<sub>irq</sub>** | **V**   | **E** |
-|---------------------|---------|-------|
-| ()                  | {**A**} | {}    |
-
-After **P<sub>irq</sub>** step 1:
-
-| **L<sub>irq</sub>**   | **V**                        | **E** |
-|-----------------------|------------------------------|-------|
-| (**B<sub>irq</sub>**) | {**A**, **B<sub>irq</sub>**} | {}    |
-
-After **P<sub>irq</sub>** step 2:
-
-| **L<sub>irq</sub>** | **V**                        | **E** |
-|---------------------|------------------------------|-------|
-| ()                  | {**A**, **B<sub>irq</sub>**} | {}    |
-
-##### Analysis of Path **P<sub>irq</sub>**
-
-Let **L<sub>2</sub>** be the ordered _active_ list of locks held by path
-**P<sub>2</sub>**.
-
-Initial state:
-
-| **L<sub>2</sub>** | **V**   | **E** |
-|-------------------|---------|-------|
-| ()                | {**A**} | {}    |
-
-After **P<sub>2</sub>** step 1:
-
-| **L<sub>2</sub>**     | **V**                        | **E** |
-|-----------------------|------------------------------|-------|
-| (**B<sub>irq</sub>**) | {**A**, **B<sub>irq</sub>**} | {}    |
-
-After **P<sub>2</sub>** step 2:
-
-| **L<sub>2</sub>**            | **V**                        | **E**                          |
-|------------------------------|------------------------------|--------------------------------|
-| (**B<sub>irq</sub>**, **A**) | {**A**, **B<sub>irq</sub>**} | {(**A**, **B<sub>irq</sub>**)} |
-
-This step adds lock **A** to the active list. The active list contains lock
-**B<sub>irq</sub>**, so an edge is added from **A** to **B<sub>irq</sub>**.
-Because this is an edge from a non-irq-safe lock to an irq-safe lock the irq-safe
-ordering invariant is violated and a potential deadlock exists.
-
-## From Theory to Implementation
-
-This section develops a concrete strategy to implement a directed graph
-validator, based on the analysis techniques of the previous section.
-
-The implementation strategy has the following goals:
-
-1. Avoid dynamic allocation if possible.
-2. Minimize the overhead of validation.
-3. Support environments that manage hardware interrupts.
-
-### Removing Redundancy with Lock Classes
-
-In the analysis earlier in this document, locks are considered abstractly with
-the implication that the tracked objects are individual instances of locks.
-While tracking individual instances produces correct results, it has several
-consequences that might be avoided:
-
-1. Tracking structures must be dynamically adjusted as lock instances come into
-   and out of existence, possibly requiring dynamic allocation or other
-   per-instance data storage.
-2. The graph contains redundant information when multiple instances of locks are
-   used identically by the same code paths.
-3. Relatedly, it may take longer to identify violations by locks that serve
-   identical functions, but have not yet individually propagated through all of
-   the necessary code paths.
-
-A key observation is that locks that serve identical functions should follow the
-same ordering rules, regardless of the number of instances.
-
-Consider the following types with lock members and an operation that mutates
-both types:
-
-```C++
-struct Foo {
-    Mutex lock;
-    int data; GUARDED_BY(lock);
-};
-
-struct Bar {
-    Mutex lock;
-    int data; GUARDED_BY(lock);
-};
-
-void Swap(Foo* foo, Bar* bar) {
-    foo->lock.Acquire();
-    bar->lock.Acquire();
-
-    int temp = foo->data;
-    foo->data = bar->data;
-    bar->data = temp;
-
-    bar->Release();
-    foo->Release();
-}
-```
-
-Since operation `Swap` may operate on any instance of `Foo` and any instance of
-`Bar` it follows that `Swap` establishes an order between the locks of all
-instances of `Foo` and `Bar`; failure to apply this order consistently in other
-parts of a program could result in a deadlock when the same instances of `Foo`
-and `Bar` are locked concurrently in different orders.
-
-Note that it is possible to intentionally or unintentionally segregate different
-collections of `Foo` and `Bar` such that instances locked in different orders
-never overlap. This is still dangerous however, because seemingly innocuous
-changes to the inputs, structure, or timing of the program could defeat the
-segregation and introduce a potential deadlock. This problem can be avoided
-entirely by treating all instances of `Foo` and `Bar` equivalently and applying
-the same ordering rules throughout the program.
-
-Ensuring universal ordering throughout the program can be achieved by tracking
-classes of locks instead of lock instances: each lock member in each type
-represents a unique lock class. The relationships between each lock class can
-be tracked and analyzed using the same directed graph techniques as with
-individual locks.
-
-Tracking lock classes has the following benefits:
-
-1. Statically allocated memory: because all lock classes are known at compile
-   time, tracking structures can be allocated up front as static global data.
-2. Elimination of redundant graph nodes: locks in the same class use the same
-   tracking structures.
-3. Faster detection of invariant violations: violations are detected when
-   lock class orders are inconsistent, even if the individual instances involved
-   have never been used together.
-
-#### Additional Ordering Rules
-
-Tracking lock classes introduces additional ordering considerations when locking
-multiple locks of the same class. Because individual instances are not tracked
-it is necessary to take additional steps to ensure consistency when multiple
-locks of the same class must be acquired at the same time.
-
-##### Externally Ordered Locks
-
-Nesting locks of the same class is necessary when a hierarchical or other
-ordered data structure has locks in each node and more than one per-node lock
-must be held at a time. In this situation the data structure or access pattern
-must provide a stable ordering that is used to guarantee ordering of the locks.
-
-Validation of nestable lock classes requires only that the external order is
-recorded in the active locks list for each nestable lock and compared when new
-locks of the same class are added to the list. A consequence of this design is
-that other lock classes may not be interspersed between nested locks of the
-same class, only wholly before or after a collection of nested locks.
-
-For example, non-nestable lock classes **A** and **B**, and nestable lock class
-**N** may be interspersed like this:
-
-**A**, **N<sub>0</sub>**, **N<sub>1</sub>**, ... **N<sub>n</sub>**, **B**
-
-But not like this:
-
-**A**, **N<sub>0</sub>**, **B**, **N<sub>1</sub>**, ... **N<sub>n</sub>** or
-**A**, **N<sub>0</sub>**, **N<sub>1</sub>**, **B**, ... **N<sub>n</sub>** or
-... etc
-
-In most situations this is a reasonable constraint, as interspersing other locks
-within a nested structure with arbitrary depth is likely to result in inversions
-as the structure is updated at runtime. On the other hand, in situations where
-nesting is bounded to a few levels it may be more effective to define separate
-lock classes for each level instead of using a nested class -- in this case
-other locks may be allowed at a specific level following normal lock ordering
-rules.
-
-##### Address Ordering
-
-It is difficult to generalize lock ordering between locks of the same class
-without an externally provided order when the locks are acquired at different
-times. It is possible however, to provide an ordering guarantee when acquiring
-multiple locks at the same time, without temporal separation. In this situation
-the locks may be ordered by address, guaranteeing that any path that acquires
-the same set locks produces a consistent locking order.
-
-For example, consider an operation **F**(**S<sub>a</sub>**, **S<sub>b</sub>**)
-that operates on two instances of structure **S**, each with a lock of class
-**L** and, as part of the operation **F** must lock both locks.
-
-If instance **S<usb>0</sub>** is ordered in memory before instance
-**S<sub>1</sub>** then the locks have the same relative ordering as their
-containing instances. We can consider the locks to have the subclasses
-**L<sub>0</sub>** and **L<sub>1</sub>** respectively.
-
-A lock ordering problem arises if we perform the operation with different
-orders:
-
-**F**(**S<sub>0</sub>**, **S<sub>1</sub>**) and
-**F**(**S<sub>1</sub>**, **S<sub>0</sub>**)
-
-Without intervention these produce the inverted lock sequences:
-
-**L<sub>0</sub>**, **L<sub>1</sub>** and **L<sub>1</sub>**, **L<sub>0</sub>**
-
-Since **F** has simultaneous access to both locks at the same time, it is
-possible to order the locks by address, resulting in a consistent lock
-sequence regardless of the original order of the arguments.
-
-Now suppose we add two more lock classes to the sequence: class **A** acquired
-before operation **F** and class **B** acquired after operation **F**. The
-resulting lock sequence is:
-
-**A**, **L<sub>0</sub>**, **L<sub>1</sub>**, **B**
-
-Note that this looks similar to the nested lock class sequence diagram in the
-previous section. It is in fact the same situation, only the ordering of locks
-is provided by address rather than an external order. This means that the same
-bookkeeping in the active threads list can be used for both situations.
-
-#### Lock Class Tracking Data Structure
-
-This section discusses implementation details for tracking lock classes and
-concrete processing techniques to detect potential deadlocks.
-
-Each lock class has a statically allocated node in the directed graph
-representing all locks belonging to that class. Each node has the following data
-structures:
-
-##### Lock-Free, Wait-Free Hash Set
-
-Each lock class node has a hash set that tracks the edges from the lock class to
-the lock classes ordered before it.
-
-**TODO**: Add implementation details of the hash set.
-
-##### Lock-Free, Wait-Free Disjoint Set Structures
-
-Each lock class node has a parent pointer used to track nodes that are connected
-in cycles in the directed graph. This permits reporting cycles that have been
-previously by the loop detection algorithm without fully re-traversing the graph.
-
-**TODO**: Add implementation details of the disjoint set structure.
-
-##### Thread-Local Lock List
-
-Each thread maintains a thread-local list of the locks it currently holds.
-
-**TODO**: Add implementation details of the thread-local lock list.
-
-##### Loop Detection Thread
-
-Whenever a new edge is added to the directed graph, the loop detection thread is
-triggered to traverse the graph to find circular dependencies involving more than
-two locks. Tarjan's strongly connected sets algorithm is an efficient choice,
-with worst case complexity of **O**(|**E**| + |**V**|). This algorithm is stable
-even when traversing a graph that is updated concurrently by other threads.
-
-**TODO**: Add implementation details of the loop detection thread.
-
-## References
-
-1. Clang static [thread safety analysis](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html).
-2. LLVM runtime [thread sanitizer](https://github.com/google/sanitizers/wiki/ThreadSanitizerDeadlockDetector).
-3. Linux Kernel [lockdep subsystem](https://www.kernel.org/doc/Documentation/locking/lockdep-design.txt).
-
diff --git a/docs/lockdep.md b/docs/lockdep.md
deleted file mode 100644
index cfdcfc8..0000000
--- a/docs/lockdep.md
+++ /dev/null
@@ -1,431 +0,0 @@
-# Runtime Lock Validation in Zircon
-
-## Introduction
-
-Zircon integrates a runtime lock validator to diagnose inconsistent lock
-ordering that could lead to deadlocks. This document discusses how the
-validator is integrated, how to enable and tune the validator at build time,
-and what output the validator produces.
-
-The theory of operation for the validator itself can be found in the
-[design document](lockdep-design.md).
-
-## Enabling the Lock Validator
-
-Lock validation is disabled by default. **When disabled the lock instrumentation
-is transparent, acting as a zero-overhead wrapper for the underlying locking
-primitives**.
-
-The validator is enabled at compile time by setting the make variable
-`ENABLE_LOCK_DEP` to true. As of this writing logic for this variable is
-handled by [make/engine.mk](../make/engine.mk).
-
-You can set this variable in your `local.mk` like this:
-
-```makefile
-# local.mk
-ENABLE_LOCK_DEP := true
-```
-
-When the lock validator is enabled a set of global lock-free, wait-free data
-structures are generated to track the relationships between the instrumented
-locks; the acquire/release operations of the locks are augmented to update
-these data structures.
-
-## Lock Instrumentation
-
-The current incarnation of the runtime lock validator requires manually
-instrumenting each lock in kernel with a wrapper type. The wrapper type provides
-the context the validator needs to properly identify the lock and generate a
-global tracking structure for locks with the same context or role.
-
-The kernel defines utility macros for this purpose in `kernel/spinlock.h` and
-`kernel/mutex.h`.
-
-### Member Locks
-
-A type with a lock member like this:
-
-```C++
-#include <kernel/mutex.h>
-
-class MyType {
-public:
-	// ...
-private:
-	mutable fbl::Mutex lock_;
-	// ...
-};
-```
-
-May be instrumented like this:
-
-```C++
-#include <kernel/mutex.h>
-
-class MyType {
-public:
-	// ...
-private:
-	mutable DECLARE_MUTEX(MyType) lock_;
-	// ...
-};
-```
-
-Note that the containing type is passed to the macro
-`DECLARE_MUTEX(containing_type)`. This type provides the context the validator
-needs to distinguish locks that are members of `MyType` from locks that are
-members of other types.
-
-The macro `DECLARE_SPINLOCK(containing_type)` provides similar support for
-instrumenting `SpinLock` members.
-
-For those who are curious, the macro in the example above expands to this type
-expression: `::lockdep::LockDep<containing_type, fbl::Mutex, __LINE__>`. This
-expression results in a unique instantiation of the `lockdep::LockDep<>` type,
-both across different containing types, and within a containing type where
-there is more than one mutex.
-
-### Global Locks
-
-Global locks are instrumented using a singleton-type pattern. The kernel defines
-utility macros for this purpose in `kernel/mutex.h` and `kernel/spinlock.h`.
-
-In Zircon global locks are typically defined either at global/namespace scope or
-within another type as a static member.
-
-example.h:
-```C++
-#include <kernel/mutex.h>
-
-extern fbl::Mutex a_global_lock;
-
-class MyType {
-public:
-	// ...
-private:
-	static fbl::Mutex all_objects_lock_;
-};
-```
-
-example.cpp:
-```C++
-#include "example.h"
-
-fbl::Mutext a_global_lock;
-
-fbl::Mutext MyType::all_objects_lock_;
-```
-
-The instrumentation simplifies declaring locks by declaring singleton types that
-may be used in either scope and handles ODR-use automatically.
-
-example.h:
-```
-#include <kernel/mutex.h>
-
-DECLARE_SINGLETON_MUTEX(AGlobalLock);
-
-class MyType {
-public:
-	// ...
-private:
-	DECLARE_SINGLETON_MUTEX(AllObjectsLock);
-};
-```
-
-These macro invocations declare new singleton types, `AGlobalLock` and
-`MyType::AllObjectsLock` respectively. These types have a static `Get()` method
-that returns the underlying global lock with all of the necessary
-instrumentation. Note that there is no need to separately define storage for the
-locks, this is handled automatically by the supporting template types.
-
-The macro `DECLARE_SINGLETON_SPINLOCK(name)` provides similar support for
-declaring a global `SpinLock`.
-
-### Lock Guards
-
-Instrumented locks are acquired and released using the scoped capability types
-`Guard` and `GuardMultiple`. In the kernel these types are defined in
-`kernel/lockdep.h`.
-
-The operation of `Guard` for simple mutexes is similar to `AutoLock`:
-
-```C++
-#include <kernel/mutex.h>
-
-class MyType {
-public:
-	// ...
-
-	int GetData() const {
-		Guard<fbl::Mutex> guard{&lock_};
-		return data_;
-	}
-
-	int DoSomething() {
-		Guard<fbl::Mutex> guard{&lock_};
-		int data_copy = data_;
-		guard.Release();
-
-		return DoWorkUnlocked(data_copy);
-	}
-
-private:
-	mutable DECLARE_MUTEX(MyType) lock_;
-	int data_{0} TA_GUARDED(lock_);
-};
-```
-
-`SpinLock` types require an additional template argument to `Guard` to select
-one of a few possible options when acquiring the lock: `IrqSave`, `NoIrqSave`,
-and `TryLockNoIrqSave`. Omitting one of these type tags results in a
-compile-time error.
-
-```C++
-#include <kernel/spinlock.h>
-
-class MyType {
-public:
-	// ...
-
-	int GetData() const {
-		Guard<SpinLock, IrqSave> guard{&lock_};
-		return data_;
-	}
-
-	void DoSomethingInIrqContext() {
-		Guard<SpinLock, NoIrqSave> guard{&lock_};
-		// ...
-	}
-
-	bool TryToDoSomethingInIrqContext() {
-		if (Guard<SpinLock, TryLockNoIrqSave> guard{&lock_}) {
-			// ...
-			return true;
-		}
-		return false;
-	}
-
-private:
-	mutable DECLARE_SPINLOCK(MyType) lock_;
-	int data_{0} TA_GUARDED(lock_);
-};
-```
-
-Instrumented global locks work similarly:
-
-```C++
-#include <kernel/mutex.h>
-#include <fbl/intrusive_double_list.h>
-
-class MyType : public fbl::DoublyLinkedListable<MyType> {
-public:
-	// ...
-
-	void AddToList(MyType* object) {
-		Guard<fbl::Mutex> guard{AllObjectsLock::Get()};
-		all_objects_list_.push_back(*object);
-	}
-
-private:
-	DECLARE_SINGLETON_MUTEX(AllObjectsLock);
-	fbl::DoublyLinkedList<MyType> all_objects_list_ TA_GUARDED(AllObjectsLock::Get());
-};
-```
-
-Note that instrumented locks do not have manual `Acquire()` and `Release()`
-methods; using a `Guard` is the only way to acquire the locks directly. There
-are two important reasons for this:
-
-1. Manual acquire/release operations are more error prone than guard, plus
-   manual release when necessary.
-2. When lock validation is enabled the guard provides the storage that the
-   validator uses to account for actively held locks. This approach permits
-   temporary storage of validator state on the stack only for the duration the
-   lock is held, which corresponds with the use patterns of guard objects.
-   Without this approach the tracking data would either have to be stored with
-   each lock instance, increasing memory use even when locks are not held, or
-   stored in heap allocated memory. Neither of these alternatives is desirable.
-
-In rare circumstances the underlying lock may be accessed using the `lock()`
-accessor of the instrumented lock. This should be done with care as manipulating
-the underlying lock directly may result inconsistency between the state of the
-lock and the state the lock validator; at best this may lead to missing a lock
-order warning and at worst may lead to a deadlock. **You have been warned!**
-
-## Clang Static Analysis and Instrumented Locks
-
-The lock instrumentation is designed to interoperate with Clang static lock
-analysis. In general usage, an instrumented lock may be used as a "mutex"
-capability and specified in any of the static lock annotations.
-
-There are two special cases that need some extra attention:
-
-1. Returning pointers or references to capabilities.
-2. Unlocking a guard passed by reference.
-
-### Pointers and References to Capabilities
-
-When returning a lock by pointer or reference it may be convenient or necessary
-to use a uniform type. Recall from earlier that instrumented locks are wrapped
-in a type that captures the containing type, the underlying lock type, and the
-line number to disambiguate locks belonging to different types
-(`::lockdep::LockDep<Class, Locktype, Index>`). This can lead to difficulty when
-returning a lock from a uniform (virtual) interface (e.g. kernel
-`Dispatcher::get_lock()`).
-
-Fortunately there is a straightforward solution: every instrumented lock is also
-a subclass of `::lockdep::Lock<LockType>` (or simply `Lock<LockType>` in the
-kernel). This type only depends on the underlying `LockType`, not the context in
-which the instrumented lock is declared, making it convenient to use as a
-pointer or reference type to refer to an instrumented lock more generically.
-This type may be used in type annotations as well.
-
-The following illustrates the pattern, which is similar to that employed by the
-kernel `Dispatcher` types.
-
-```C++
-#include <kernel/mutex.h>
-
-
-struct LockableInterface {
-	virtual ~LockableInterface() {}
-	virtual Lock<fbl::Mutex>* get_lock() = 0;
-	virtual void DoSomethingLocked() TA_REQ(get_lock()) = 0;
-};
-
-class A : public LockableInterface {
-public:
-	Lock<fbl::Mutex>* get_lock() override { return &lock_; }
-	void DoSomethingLocked() override {
-		data_++;
-	}
-	void DoSomething() {
-		Guard<fbl::Mutex> guard{get_lock()};
-		DoSomethingLocked();
-		// ...
-	}
-private:
-	mutable DECLARE_MUTEX(A) lock_;
-	int data_ TA_GUARDED(get_lock());
-};
-
-class B : public LockableInterface {
-public:
-	Lock<fbl::Mutex>* get_lock() override { return &lock_; }
-	void DoSomethingLocked() override {
-		// ...
-	}
-	void DoSomething() {
-		Guard<fbl::Mutex> guard{get_lock()};
-		DoSomethingLocked();
-		// ...
-	}
-private:
-	mutable DECLARE_MUTEX(B) lock_;
-	char data_[32] TA_GUARDED(get_lock());
-};
-```
-
-Note that the type of `A::lock_` is
-`::lockdep::LockDep<A, fbl::Mutex, __LINE__>` and the type of `B::lock_` is
-`::lockdep::LockDep<B, fbl::Mutex, __LINE__>`. However, both of these types are
-subclasses of `Lock<fbl::Mutex>`, so we can treat them uniformly as this type in
-pointer and reference expressions.
-
-While this is very convenient, a limitation in Clang static analysis prevents it
-from understanding that `LockableInterface::get_lock()` is equivalent to
-`A::lock_` or `B::lock_`, even in their local contexts. For this reason is it
-necessary to use `get_lock()` in all of the lock annotations.
-
-### Unlocking a Guard Passed by Reference
-
-In very rare circumstances it is useful to release a `Guard` instance held in
-a function from a callee of the function.
-
-**TODO(eieio): Complete documentation of this feature.**
-
-## Lock Validation Errors
-
-The lock validator detects and reports two broad classes of violations:
-
-1. Pair-wise violations reported at the point of acquisition.
-2. Multi-lock cycles reported asynchronously by a dedicated loop detection
-   thread.
-
-### Violations Reported at Acquisition
-
-When a violation is detected at the point of lock acquisition the validator
-produces a message like the following in the kernel log:
-
-```
-[00000.817] 04704.04716> ZIRCON KERNEL PANIC
-[00000.817] 04704.04716> Lock validation failed for thread 0xffffff800a5ffa98 pid 4704 tid 4716 (thermd:initial-thread):
-[00000.817] 04704.04716> Reason: Out Of Order
-[00000.817] 04704.04716> Bad lock: name=lockdep::LockClass<SoloDispatcher<PortDispatcher>, fbl::Mutex, 362, (lockdep::LockFlags)0> order=0
-[00000.817] 04704.04716> Conflict: name=lockdep::LockClass<VmObject, fbl::Mutex, 249, (lockdep::LockFlags)0> order=0
-[00000.817] 04704.04716> caller=0xffffffff00190837 frame=0xffffff98717f0970
-[00000.817] 04704.04716> BUILDID git-ce892d1b03c1a56799fb604d1d6303bb7b16e75a
-[00000.817] 04704.04716> dso: id=3ebe31f2ce250453f1210662d6f9d16e2595b9b8 base=0xffffffff00100000 name=zircon.elf
-[00000.817] 04704.04716> bt#00: 0xffffffff00190837
-[00000.817] 04704.04716> bt#01: 0xffffffff00163883
-[00000.817] 04704.04716> bt#02: 0xffffffff00165e58
-[00000.817] 04704.04716> bt#03: 0xffffffff0022a1d8
-[00000.817] 04704.04716> bt#04: 0xffffffff0022b759
-[00000.817] 04704.04716> bt#05: 0xffffffff00229eca
-[00000.817] 04704.04716> bt#06: 0xffffffff0022b759
-[00000.817] 04704.04716> bt#07: 0xffffffff00222787
-[00000.817] 04704.04716> bt#08: 0xffffffff00211f0c
-[00000.817] 04704.04716> bt#09: 0xffffffff0021d9d3
-[00000.817] 04704.04716> bt#10: 0xffffffff0019a059
-[00000.817] 04704.04716> bt#11: 0xffffffff0019ab8b
-[00000.817] 04704.04716> bt#12: 0xffffffff001a9448
-[00000.817] 04704.04716> bt#13: 0xffffffff0013f503
-[00000.817] 04704.04716> bt#14: 0xffffffff001af8be
-[00000.817] 04704.04716> bt#15: 0xffffffff001995e3
-[00000.817] 04704.04716> bt#16: end
-[00000.817] 04704.04716>
-```
-
-Although this is reported as a panic (required wording for `fx symbolize` to
-recognize the kernel stack trace) the error is informational and non-fatal. The
-first line identifies the thread and process where the kernel lock violation
-occurred. The next line identifies the type of violation. The next two lines
-identify which locks were found to be inconsistent with previous observations;
-the "Bad lock" is the lock that is about to be acquired, while "Conflict" is
-a lock that is already held by the current context and is the point of
-inconsistency with the lock that is about to be acquired. All of the lines
-following this are part of the stack trace leading up to the bad lock.
-
-### Multi-Lock Cycles
-
-Circular dependencies between three or more locks are detected with a dedicated
-loop detection thread. Because this detection happens in a separate context from
-the lock operations that caused the cycle a stack trace is not provided.
-
-Reports from the loop detection thread look like this:
-
-```
-[00002.000] 00000.00000> ZIRCON KERNEL OOPS
-[00002.000] 00000.00000> Circular lock dependency detected:
-[00002.000] 00000.00000>   lockdep::LockClass<VmObject, fbl::Mutex, 249, (lockdep::LockFlags)0>
-[00002.000] 00000.00000>   lockdep::LockClass<VmAspace, fbl::Mutex, 198, (lockdep::LockFlags)0>
-[00002.000] 00000.00000>   lockdep::LockClass<SoloDispatcher<VmObjectDispatcher>, fbl::Mutex, 362, (lockdep::LockFlags)0>
-[00002.000] 00000.00000>   lockdep::LockClass<SoloDispatcher<PortDispatcher>, fbl::Mutex, 362, (lockdep::LockFlags)0>
-```
-
-Each of the locks involved in the cycle are reported in a group. Frequently only
-two of the circularly-dependent locks are acquired by a single thread at any
-given time, making manual detection difficult or impossible. However, the
-potential for deadlock between three or more threads is real and should be
-addressed for long-term system stability.
-
-## Kernel Commands
-
-When the lock validator is enabled the following kernel commands are available:
-
-* `k lockdep dump` - dumps the dependency graph and connected sets (loops) for
-  all instrumented locks.
-* `k lockdep loop` - triggers a loop detection pass and reports any loops found
-  to the kernel log.
diff --git a/docs/makefile_options.md b/docs/makefile_options.md
deleted file mode 100644
index f04f361..0000000
--- a/docs/makefile_options.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Zircon Makefile Options
-
-The following options can be passed to **make** when building Zircon:
-
-* **BOOTFS_DEBUG_MODULES**: See [debugging tips](debugging/tips.md).
-
-* **DEBUG**: This specifies the debug level.  The default is 2.  Setting
-**DEBUG=1** will disable some debugging code (such as **DEBUG_ASSERT()**),
-while setting **DEBUG=0** will disable more debugging code.
-
-* **ENABLE_ACPI_DEBUG**: See [ACPI debugging](debugging/acpi.md).
-
-* **GLOBAL_DEBUGFLAGS**: See [debugging tips](debugging/tips.md).
-
-* **GOMACC**: Path to the Goma compiler wrapper, **gomacc**, for use within
-Google for distributed builds.  The default is not to use Goma.
-
-* **USE_ASAN**: Set **USE_ASAN=1** to enable using ASan (the address
-sanitizer).
-
-* **USE_CLANG**: Set **USE_CLANG=1** to enable building with Clang.
-Otherwise, the default is to use GCC as the compiler.
-
-* **V**: Set **V=1** to tell the build system to print each command that
-**make** executes.  Otherwise, the build system only prints a short summary
-of each build step.
diff --git a/docs/memory.md b/docs/memory.md
deleted file mode 100644
index 5454361..0000000
--- a/docs/memory.md
+++ /dev/null
@@ -1,310 +0,0 @@
-# Memory and resource usage
-
-This file contains information about memory and resource management in Zircon,
-and talks about ways to examine process and system memory usage.
-
-*** note
-**TODO**(dbort): Talk about the relationship between address spaces,
-[VMARs](objects/vm_address_region.md), [mappings](syscalls/vmar_map.md), and
-[VMOs](objects/vm_object.md)
-***
-
-[TOC]
-
-## Userspace memory
-
-Which processes are using all of the memory?
-
-### Dump total process memory usage
-
-Use the `ps` tool:
-
-```
-$ ps
-TASK           PSS PRIVATE  SHARED NAME
-j:1028       32.9M   32.8M         root
-  p:1043   1386.3k   1384k     28k bin/devmgr
-  j:1082     30.0M   30.0M         zircon-drivers
-    p:1209  774.3k    772k     28k /boot/bin/acpisvc
-    p:1565  250.3k    248k     28k devhost:root
-    p:1619  654.3k    652k     28k devhost:misc
-    p:1688  258.3k    256k     28k devhost:platform
-    p:1867 3878.3k   3876k     28k devhost:pci#1:1234:1111
-    p:1916   24.4M   24.4M     28k devhost:pci#3:8086:2922
-  j:1103   1475.7k   1464k         zircon-services
-    p:1104  298.3k    296k     28k crashlogger
-    p:1290  242.3k    240k     28k netsvc
-    p:2115  362.3k    360k     28k sh:console
-    p:2334  266.3k    264k     28k sh:vc
-    p:2441  306.3k    304k     28k /boot/bin/ps
-TASK           PSS PRIVATE  SHARED NAME
-```
-
-**PSS** (proportional shared state) is a number of bytes that estimates how much
-in-process mapped physical memory the process consumes. Its value is `PRIVATE +
-(SHARED / sharing-ratio)`, where `sharing-ratio` is based on the number of
-processes that share each of the pages in this process.
-
-The intent is that, e.g., if four processes share a single page, 1/4 of the
-bytes of that page is included in each of the four process's `PSS`. If two
-processes share a different page, then each gets 1/2 of that page's bytes.
-
-**PRIVATE** is the number of bytes that are mapped only by this process. I.e.,
-no other process maps this memory. Note that this does not account for private
-VMOs that are not mapped.
-
-**SHARED** is the number of bytes that are mapped by this process and at least
-one other process. Note that this does not account for shared VMOs that are not
-mapped. It also does not indicate how many processes share the memory: it could
-be 2, it could be 50.
-
-### Visualize memory usage
-
-If you have a Fuchsia build, you can use treemap to visualize memory usage by
-the system.
-
- 1. On your host machine, run the following command from the root of your
-    Fuchsia checkout:
-
-    ```./scripts/fx shell memgraph -vt | ./scripts/memory/treemap.py > mem.html```
- 2. Open `mem.html` in a browser.
-
-The `memgraph` tool generates a JSON description of system task and memory
-information, which is then parsed by the `treemap.py` script. `-vt` says
-to include VMOs and threads in the output.
-
-### Dump a process's detailed memory maps
-
-If you want to see why a specific process uses so much memory, you can run the
-`vmaps` tool on its koid (koid is the ID that shows up when running ps) to see
-what it has mapped into memory.
-
-```
-$ vmaps help
-Usage: vmaps <process-koid>
-
-Dumps a process's memory maps to stdout.
-
-First column:
-  "/A" -- Process address space
-  "/R" -- Root VMAR
-  "R"  -- VMAR (R for Region)
-  "M"  -- Mapping
-
-  Indentation indicates parent/child relationship.
-```
-
-Column tags:
-
--   `:sz`: The virtual size of the entry, in bytes. Not all pages are
-    necessarily backed by physical memory.
--   `:res`: The amount of memory "resident" in the entry, in bytes; i.e., the
-    amount of physical memory that backs the entry. This memory may be private
-    (only accessible by this process) or shared by multiple processes.
--   `:vmo`: The `koid` of the VMO mapped into this region.
-
-```
-$ vmaps 2470
-/A ________01000000-00007ffffffff000    128.0T:sz                    'proc:2470'
-/R ________01000000-00007ffffffff000    128.0T:sz                    'root'
-...
-# This 'R' region is a dynamic library. The r-x section is .text, the r--
-# section is .rodata, and the rw- section is .data + .bss.
-R  00000187bc867000-00000187bc881000      104k:sz                    'useralloc'
- M 00000187bc867000-00000187bc87d000 r-x   88k:sz   0B:res  2535:vmo 'libfdio.so'
- M 00000187bc87e000-00000187bc87f000 r--    4k:sz   4k:res  2537:vmo 'libfdio.so'
- M 00000187bc87f000-00000187bc881000 rw-    8k:sz   8k:res  2537:vmo 'libfdio.so'
-...
-# This 2MB anonymous mapping is probably part of the heap.
-M  0000246812b91000-0000246812d91000 rw-    2M:sz  76k:res  2542:vmo 'mmap-anonymous'
-...
-# This region looks like a stack: a big chunk of virtual space (:sz) with a
-# slightly-smaller mapping inside (accounting for a 4k guard page), and only a
-# small amount actually committed (:res).
-R  0000358923d92000-0000358923dd3000      260k:sz                    'useralloc'
- M 0000358923d93000-0000358923dd3000 rw-  256k:sz  16k:res  2538:vmo ''
-...
-# The stack for the initial thread, which is allocated differently.
-M  0000400cbba84000-0000400cbbac4000 rw-  256k:sz   4k:res  2513:vmo 'initial-stack'
-...
-# The vDSO, which only has .text and .rodata.
-R  000047e1ab874000-000047e1ab87b000       28k:sz                    'useralloc'
- M 000047e1ab874000-000047e1ab87a000 r--   24k:sz  24k:res  1031:vmo 'vdso/full'
- M 000047e1ab87a000-000047e1ab87b000 r-x    4k:sz   4k:res  1031:vmo 'vdso/full'
-...
-# The main binary for this process.
-R  000059f5c7068000-000059f5c708d000      148k:sz                    'useralloc'
- M 000059f5c7068000-000059f5c7088000 r-x  128k:sz   0B:res  2476:vmo '/boot/bin/sh'
- M 000059f5c7089000-000059f5c708b000 r--    8k:sz   8k:res  2517:vmo '/boot/bin/sh'
- M 000059f5c708b000-000059f5c708d000 rw-    8k:sz   8k:res  2517:vmo '/boot/bin/sh'
-...
-```
-
-### Dump all VMOs associated with a process
-
-```
-vmos <pid>
-```
-
-This will also show unmapped VMOs, which neither `ps` nor `vmaps` currently
-account for.
-
-It also shows whether a given VMO is a clone, along with its parent's koid.
-
-```
-$ vmos 1118
-rights  koid parent #chld #map #shr    size   alloc name
-rwxmdt  1170      -     0    1    1      4k      4k stack: msg of 0x5a
-r-xmdt  1031      -     2   28   14     28k     28k vdso/full
-     -  1298      -     0    1    1      2M     68k jemalloc-heap
-     -  1381      -     0    3    1    516k      8k self-dump-thread:0x12afe79c8b38
-     -  1233   1232     1    1    1   33.6k      4k libbacktrace.so
-     -  1237   1233     0    1    1      4k      4k data:libbacktrace.so
-...
-     -  1153   1146     1    1    1  883.2k     12k ld.so.1
-     -  1158   1153     0    1    1     16k     12k data:ld.so.1
-     -  1159      -     0    1    1     12k     12k bss:ld.so.1
-rights  koid parent #chld #map #shr    size   alloc name
-```
-
-Columns:
-
--   `rights`: If the process points to the VMO via a handle, this column shows
-    the rights that the handle has, zero or more of:
-    -   `r`: `ZX_RIGHT_READ`
-    -   `w`: `ZX_RIGHT_WRITE`
-    -   `x`: `ZX_RIGHT_EXECUTE`
-    -   `m`: `ZX_RIGHT_MAP`
-    -   `d`: `ZX_RIGHT_DUPLICATE`
-    -   `t`: `ZX_RIGHT_TRANSFER`
-    -   **NOTE**: Non-handle entries will have a single '-' in this column.
--   `koid`: The koid of the VMO, if it has one. Zero otherwise. A VMO without a
-    koid was created by the kernel, and has never had a userspace handle.
--   `parent`: The koid of the VMO's parent, if it's a clone.
--   `#chld`: The number of active clones (children) of the VMO.
--   `#map`: The number of times the VMO is currently mapped into VMARs.
--   `#shr`: The number of processes that map (share) the VMO.
--   `size`: The VMO's current size, in bytes.
--   `alloc`: The amount of physical memory allocated to the VMO, in bytes.
-    -   **NOTE**: If this column contains the value `phys`, it means that the
-        VMO points to a raw physical address range like a memory-mapped device.
-        `phys` VMOs do not consume RAM.
--   `name`: The name of the VMO, or `-` if its name is empty.
-
-To relate this back to `ps`: each VMO contributes, for its mapped portions
-(since not all or any of a VMO's pages may be mapped):
-
-```
-PRIVATE =  #shr == 1 ? alloc : 0
-SHARED  =  #shr  > 1 ? alloc : 0
-PSS     =  PRIVATE + (SHARED / #shr)
-```
-
-### Dump "hidden" (unmapped and kernel) VMOs
-
-> NOTE: This is a kernel command, and will print to the kernel console.
-
-```
-k zx vmos hidden
-```
-
-Similar to `vmos <pid>`, but dumps all VMOs in the system that are not mapped
-into any process:
--   VMOs that userspace has handles to but does not map
--   VMOs that are mapped only into kernel space
--   Kernel-only, unmapped VMOs that have no handles
-
-A `koid` value of zero means that only the kernel has a reference to that VMO.
-
-A `#map` value of zero means that the VMO is not mapped into any address space.
-
-**See also**: `k zx vmos all`, which dumps all VMOs in the system. **NOTE**:
-It's very common for this output to be truncated because of kernel console
-buffer limitations, so it's often better to combine the `k zx vmos hidden`
-output with a `vmaps` dump of each user process.
-
-### Limitations
-
-Neither `ps` nor `vmaps` currently account for:
-
--   VMOs or VMO subranges that are not mapped. E.g., you could create a VMO,
-    write 1G of data into it, and it won't show up here.
-
-None of the process-dumping tools account for:
-
--   Multiply-mapped pages. If you create multiple mappings using the same range
-    of a VMO, any committed pages of the VMO will be counted as many times as
-    those pages are mapped. This could be inside the same process, or could be
-    between processes if those processes share a VMO.
-
-    Note that "multiply-mapped pages" includes copy-on-write.
--   Underlying kernel memory overhead for resources allocated by a process.
-    E.g., a process could have a million handles open, and those handles consume
-    kernel memory.
-
-    You can look at process handle consumption with the `k zx ps` command; run
-    `k zx ps help` for a description of its columns.
--   Copy-on-write (COW) cloned VMOs. The clean (non-dirty, non-copied) pages of
-    a clone will not count towards "shared" for a process that maps the clone,
-    and those same pages may mistakenly count towards "private" of a process
-    that maps the parent (cloned) VMO.
-
-    TODO(dbort): Fix this; the tools were written before COW clones existed.
-
-## Kernel memory
-
-### Dump system memory arenas and kernel heap usage
-
-Running `kstats -m` will continuously dump information about physical memory
-usage and availability.
-
-```
-$ kstats -m
---- 2017-06-07T05:51:08.021Z ---
-     total       free       VMOs      kheap      kfree      wired        mmu
-   2046.9M    1943.8M      20.7M       1.1M       0.9M      72.6M       7.8M
-
---- 2017-06-07T05:51:09.021Z ---
-...
-```
-
-Fields:
-
--   `2017-06-07T05:51:08.021Z`: Timestamp of when the stats were collected, as
-    an ISO 8601 string.
--   `total`: The total amount of physical memory available to the system.
--   `free`: The amount of unallocated memory.
--   `VMOs`: The amount of memory committed to VMOs, both kernel and user. A
-    superset of all userspace memory. Does not include certain VMOs that fall
-    under `wired`.
--   `kheap`: The amount of kernel heap memory marked as allocated.
--   `kfree`: The amount of kernel heap memory marked as free.
--   `wired`: The amount of memory reserved by and mapped into the kernel for
-    reasons not covered by other fields in this struct. Typically for readonly
-    data like the ram disk and kernel image, and for early-boot dynamic memory.
--   `mmu`: The amount of memory used for architecture-specific MMU metadata like
-    page tables.
-
-### Dump the kernel address space
-
-> NOTE: This is a kernel command, and will print to the kernel console.
-
-```
-k zx asd kernel
-```
-
-Dumps the kernel's VMAR/mapping/VMO hierarchy, similar to the `vmaps` tool for
-user processes.
-
-```
-$ k zx asd kernel
-as 0xffffffff80252b20 [0xffffff8000000000 0xffffffffffffffff] sz 0x8000000000 fl 0x1 ref 71 'kernel'
-  vmar 0xffffffff802529a0 [0xffffff8000000000 0xffffffffffffffff] sz 0x8000000000 ref 1 'root'
-    map 0xffffff80015f89a0 [0xffffff8000000000 0xffffff8fffffffff] sz 0x1000000000 mmufl 0x18 vmo 0xffffff80015f8890/k0 off 0 p ages 0 ref 1 ''
-      vmo 0xffffff80015f8890/k0 size 0 pages 0 ref 1 parent k0
-    map 0xffffff80015f8b30 [0xffffff9000000000 0xffffff9000000fff] sz 0x1000 mmufl 0x18 vmo 0xffffff80015f8a40/k0 off 0 pages 0 ref 1 ''
-      object 0xffffff80015f8a40 base 0x7ffe2000 size 0x1000 ref 1
-    map 0xffffff80015f8cc0 [0xffffff9000001000 0xffffff9000001fff] sz 0x1000 mmufl 0x1a vmo 0xffffff80015f8bd0/k0 off 0 pages 0 ref 1 ''
-      object 0xffffff80015f8bd0 base 0xfed00000 size 0x1000 ref 1
-...
-```
diff --git a/docs/minfs.md b/docs/minfs.md
deleted file mode 100644
index 5bc9b44..0000000
--- a/docs/minfs.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# MinFS
-
-MinFS is a simple, unix-like filesystem built for Zircon.
-
-It currently supports files up to 4 GB in size.
-
-## Using MinFS
-
-### Host Device (QEMU Only)
-
- * Create a disk image which stores MinFS
-```shell
-(Linux)
-$ truncate --size=16G blk.bin
-(Mac)
-$ mkfile -n 16g blk.bin
-```
- * Execute the run zircon script on your platform with the '--' to pass
-   arguments directly to QEMU and then use '-hda' to point to the file. If you
-   wish to attach additional devices, you can supply them with '-hdb', '-hdc,
-   and so on.
-```shell
-$ ./scripts/run-zircon-x64 -- -hda blk.bin
-```
-
-### Target Device (QEMU and Real Hardware)
-
-**WARNING**: On real hardware, "/dev/class/block/..." refers to **REAL** storage
-devices (USBs, SSDs, etc).
-
-**BE CAREFUL NOT TO FORMAT THE WRONG DEVICE.** If in doubt, only run the
-following commands through QEMU.
-The `lsblk` command can be used to see more information about the devices
-accessible from Zircon.
-
- * Within zircon, 'lsblk' can be used to list the block devices currently on
-   the system. On this example system below, "/dev/class/block/000" is a raw
-   block device.
-```
-> lsblk
-ID  DEV      DRV      SIZE TYPE           LABEL
-000 block    block     16G
-```
- * Let's add a GPT to this block device.
-```
-> gpt init /dev/class/block/000
-...
-> lsblk
-ID  DEV      DRV      SIZE TYPE           LABEL
-002 block    block     16G
-```
- * Now that we have a GPT on this device, let's check what we can do with it.
-   (NOTE: after manipulating the gpt, the device number may change. Use lsblk
-   to keep track of how to refer to the block device).
-```
-> gpt dump /dev/class/block/002
-blocksize=512 blocks=33554432
-Partition table is valid
-GPT contains usable blocks from 34 to 33554398 (inclusive)
-Total: 0 partitions
-```
- * "gpt dump" tells us some important info: it tells us (1) How big blocks are,
-   and (2) which blocks we can actually use.
-   Let's fill part of the disk with a MinFS filesystem.
-```
-> gpt add 34 20000000 minfs /dev/class/block/002
-```
- * Within Zircon, format the partition as MinFS. Using 'lsblk' you should see
-   a block device which is the whole disk and a slightly smaller device which
-   is the partition. In the above output, the partition is device 003, and would
-   have the path '/dev/class/block/003'
-```
-> mkfs <PARTITION_PATH> minfs
-```
-
- * If you want the device to be mounted automatically on reboot, use the GPT
-   tool to set its type. As we did above, **you must** use 'lsblk' **again**
-   to locate the entry for the disk. We want to edit the type of the zero-th
-   partition.  Here we use the keyword 'DATA' to set the type GUID, but if you
-   wanted to use an arbitrary GUID you would supply it where 'DATA' is used.
-```
-> gpt edit 0 type DATA <DEVICE_PATH>
-```
-
- * On any future boots, the partition will be mounted automatically at /data.
-
- * If you don't want the partition to be mounted automatically, you can update
-   the visibility (or GUID) of the partition, and simply mount it manually.
-```
-> mount <PARTITION_PATH> /data
-```
-
- * Any files written to "/data" (the mount point for this GUID) will persist
-   across boots. To test this, try making a file on the new MinFS volume,
-   rebooting, and observing it still exists.
-```
-> touch /data/foobar
-> dm reboot
-> ls /data
-```
-
- * To find out which block device/file system is mounted at each subdirectory
-   under a given path, use the following command:
-```
-> df <PATH>
-```
diff --git a/docs/nand_testing.md b/docs/nand_testing.md
deleted file mode 100644
index 85dde42..0000000
--- a/docs/nand_testing.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Nand testing
-
-*** note
-__WARNING:__ Most of these tests are destructive in nature.
-***
-
-## Accessing the desired device
-
-In order to test a particular device, that device must not be in use by the rest
-of the system. There are two ways to make that happen:
-
-* Prevent other drivers from binding to the device. This may involve building
-  the system with modified binding rules for the driver that normally binds
-  to the desired device, or passing kernel command line arguments to disable
-  that driver.
-
-* Unbind devices that are bound to the desired device.
-
-For example, in order to use a test tool against the core nand driver, nandpart
-devices may be removed like so:
-
-```shell
-$ unbind /dev/sys/platform/05:00:d/aml-raw_nand/nand/fvm
-```
-
-*** note
-__WARNING:__ Before removing a particular device, remove its descendants. By
-extension, file systems must be unmounted before a block device is removed.
-Note that this requirement is likely to render a running system unusable, as
-the backing for the OS may be going away. Netboot may be the only viable option.
-***
-
-Note that all other devices created by nandpart must also be removed. Use `dm
-dump` to inspect the device tree.
-
-## Protocol testing
-
-*nand-test* is an integration test which performs basic tests of nand protocol
-drivers.
-
-For example, this command will test an existing ram-nand device making sure the
-test does not modify anything outside blocks [100, 109]:
-
-```shell
-$ /boot/test/sys/nand-test --device /dev/misc/nand-ctl/ram-nand-0 --first-block 100 --num-blocks 10
-```
-
-## Correctness testing
-
-*nand-util* is a troubleshooting tool that can perform a simple read-reliability
-test.
-
-```shell
-$ nand-util --device /dev/misc/nand-ctl/ram-nand-0 --check
-```
-
-## Inspection / manipulation
-
-```shell
-$ nand-util --device /dev/sys/platform/05:00:d/aml-raw_nand/nand --info
-```
-
-*nand-util* can also be used to grab an image of the nand contents:
-
-```shell
-$ nand-util --device /dev/sys/platform/05:00:d/aml-raw_nand/nand/fvm --save --file /tmp/image
-```
-
-Transfer the image file to the host:
-
-```shell
-$ zircon/build-x86/tools/netcp :/tmp/image /tmp/saved_image_file
-```
-
-## Replay
-
-A saved nand image can be loaded on top of a ram-nand device like so:
-
-```shell
-$ nand-loader saved_image_file
-```
diff --git a/docs/objects.md b/docs/objects.md
deleted file mode 100644
index f814b2c..0000000
--- a/docs/objects.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Zircon Kernel objects
-
-[TOC]
-
-Zircon is a object-based kernel. User mode code almost exclusively interacts
-with OS resources via object handles. A handle can be thought of as an active
-session with a specific OS subsystem scoped to a particular resource.
-
-Zircon actively manages the following resources:
-
-+ processor time
-+ memory and address spaces
-+ device-io memory
-+ interrupts
-+ signaling and waiting
-
-## Kernel objects for applications
-
-### IPC
-+ [Channel](objects/channel.md)
-+ [Socket](objects/socket.md)
-+ [FIFO](objects/fifo.md)
-
-### Tasks
-+ [Process](objects/process.md)
-+ [Thread](objects/thread.md)
-+ [Job](objects/job.md)
-+ [Task](objects/task.md)
-
-### Signaling
-+ [Event](objects/event.md)
-+ [Event Pair](objects/eventpair.md)
-+ [Futex](objects/futex.md)
-
-### Memory and address space
-+ [Virtual Memory Object](objects/vm_object.md)
-+ [Virtual Memory Address Region](objects/vm_address_region.md)
-+ [bus_transaction_initiator](objects/bus_transaction_initiator.md)
-
-### Waiting
-+ [Port](objects/port.md)
-+ [Timer](objects/timer.md)
-
-## Kernel objects for drivers
-
-+ [Interrupts](objects/interrupts.md)
-+ [Resource](objects/resource.md)
-+ [Debuglog](objects/debuglog.md)
-
-## Kernel Object and LK
-Some kernel objects wrap one or more LK-level constructs. For example the
-Thread object wraps one `thread_t`. However the Channel does not wrap
-any LK-level objects.
-
-## Kernel object lifetime
-Kernel objects are ref-counted. Most kernel objects are born during a syscall
-and are held alive at refcount = 1 by the handle which binds the handle value
-given as the output of the syscall. The handle object is held alive as long it
-is attached to a handle table. Handles are detached from the handle table
-closing them (for example via `sys_close()`) which decrements the refcount of
-the kernel object. Usually, when the last handle is closed the kernel object
-refcount will reach 0 which causes the destructor to be run.
-
-The refcount increases both when new handles (referring to the object) are
-created and when a direct pointer reference (by some kernel code) is acquired;
-therefore a kernel object lifetime might be longer than the lifetime of the
-process that created it.
-
-## Dispatchers
-A kernel object is implemented as a C++ class that derives from `Dispatcher`
-and that overrides the methods it implements. Thus, for example, the code
-of the Thread object is found in `ThreadDispatcher`. There is plenty of
-code that only cares about kernel objects in the generic sense, in that case
-the name you'll see is `fbl::RefPtr<Dispatcher>`.
-
-## Kernel Object security
-In principle, kernel objects do not have an intrinsic notion of security and
-do not do authorization checks; security rights are held by each handle. A
-single process can have two different handles to the same object with
-different rights.
-
-## See Also
-[Handles](handles.md)
diff --git a/docs/objects/bus_transaction_initiator.md b/docs/objects/bus_transaction_initiator.md
deleted file mode 100644
index 598648a..0000000
--- a/docs/objects/bus_transaction_initiator.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Bus Transaction Initiator
-
-## NAME
-
-bus_transaction_initiator - DMA configuration capability
-
-## SYNOPSIS
-
-Bus Transaction Initiators (BTIs) represent the bus mastering/DMA capability
-of a device, and can be used for granting a device access to memory.
-
-## DESCRIPTION
-
-Device drivers are provided one BTI for each bus transaction ID each of its
-devices can use.  A bus transaction ID in this context is a hardware transaction
-identifier that may be used by an IOMMU (e.g. PCI addresses on Intel's IOMMU
-and StreamIDs on ARM's SMMU).
-
-A BTI can be used to pin memory used in a Virtual Memory Object (VMO).
-If a caller pins memory from a VMO, they are given device-physical addresses
-that can be used to issue memory transactions to the VMO (provided the
-transaction has the correct bus transaction ID).  If transactions affecting
-these addresses are issued with a different transaction ID, the transaction
-may fail and the issuing device may need a reset in order to continue functioning.
-
-A BTI manages a list of quarantined PMTs.  If a PMT was created from a BTI using
-[`zx_bti_pin()`], and the PMT's handle is released without [`zx_pmt_unpin()`] being
-called, the PMT will be quarantined.  Quarantined PMTs will prevent their
-underlying physical memory from being released to the system for reuse, in order
-to prevent DMA to memory that has since been reallocated.  The quarantine may be
-cleared by invoking [`zx_bti_release_quarantine()`].
-
-TODO(teisenbe): Add details about failed transaction notification.
-
-## SEE ALSO
-
- - [pmt](pinned_memory_token.md) - Pinned Memory Tokens
- - [vm_object](vm_object.md) - Virtual Memory Objects
-
-## SYSCALLS
-
- - [`zx_bti_create()`] - create a new bus transaction initiator
- - [`zx_bti_pin()`] - pin memory and grant access to it to the BTI
- - [`zx_bti_release_quarantine()`] - release quarantined PMTs
- - [`zx_pmt_unpin()`] - revoke access and unpin memory
-
-[`zx_bti_create()`]: ../syscalls/bti_create.md)
-[`zx_bti_pin()`]: ../syscalls/bti_pin.md
-[`zx_bti_release_quarantine()`]: ../syscalls/bti_release_quarantine.md
-[`zx_pmt_unpin()`]: ../syscalls/pmt_unpin.md
diff --git a/docs/objects/channel.md b/docs/objects/channel.md
deleted file mode 100644
index 42889c1..0000000
--- a/docs/objects/channel.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# Channel
-
-## NAME
-
-channel - Bidirectional interprocess communication
-
-## SYNOPSIS
-
-A channel is a bidirectional transport of messages consisting of some
-amount of byte data and some number of handles.
-
-## DESCRIPTION
-
-Channels maintain an ordered queue of messages to be delivered in either
-direction. A message consists of some amount of data and some number of handles.
-A call to [`zx_channel_write()`] enqueues one message, and a call to
-[`zx_channel_read()`] dequeues one message (if any are queued). A thread can block
-until messages are pending via [`zx_object_wait_one()`] or other waiting
-mechanisms.
-
-Alternatively, a call to [`zx_channel_call()`] enqueues a message in one
-direction of the channel, waits for a corresponding response, and
-dequeues the response message. In call mode, corresponding responses
-are identified via the first 4 bytes of the message, called the
-transaction ID. The kernel supplies distinct transaction IDs (always with the
-high bit set) for messages written with [`zx_channel_call()`].
-
-The process of sending a message via a channel has two steps. The first is to
-atomically write the data into the channel and move ownership of all handles in
-the message into this channel. This operation always consumes the handles: at
-the end of the call, all handles either are all in the channel or are all
-discarded. The second operation is similar: after a channel read, all the
-handles in the next message to read are either atomically moved into the
-process's handle table, all remain in the channel, or are discarded (only when
-the **ZX_CHANNEL_READ_MAY_DISCARD** option is given).
-
-Unlike many other kernel object types, channels are not duplicatable. Thus there
-is only ever one handle associated to a handle endpoint and the process holding
-that handle is considered the owner. Only the owner can write messages or send
-the channel endpoint to another process.
-
-Furthermore, when ownership of a channel endpoint goes from one process to
-another, even if a write was in progress, the ordering of messages is guaranteed
-to be parsimonious; packets before the transfer event originate from the
-previous owner and packets after the transfer belong to the new owner. The same
-applies if a read was in progress when the endpoint was transferred.
-
-The above sequential guarantee is not provided for other kernel objects, even if
-the last remaining handle is stripped of the **ZX_RIGHT_DUPLICATE** right.
-
-## SYSCALLS
-
- - [`zx_channel_call()`] - synchronously send a message and receive a reply
- - [`zx_channel_create()`] - create a new channel
- - [`zx_channel_read()`] - receive a message from a channel
- - [`zx_channel_write()`] - write a message to a channel
-
-<br>
-
- - [`zx_object_wait_one()`] - wait for signals on one object
-
-## SEE ALSO
-
-+ [Zircon concepts](../concepts.md)
-+ [Handles](../handles.md)
-
-[`zx_channel_call()`]: ../syscalls/channel_call.md
-[`zx_channel_create()`]: ../syscalls/channel_create.md
-[`zx_channel_read()`]: ../syscalls/channel_read.md
-[`zx_channel_write()`]: ../syscalls/channel_write.md
-[`zx_object_wait_one()`]: ../syscalls/object_wait_one.md
diff --git a/docs/objects/debuglog.md b/docs/objects/debuglog.md
deleted file mode 100644
index 779af04..0000000
--- a/docs/objects/debuglog.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Log
-
-## NAME
-
-Debuglog - Kernel debuglog
-
-## SYNOPSIS
-
-Debuglog objects allow userspace to read and write to kernel debug logs.
-
-## DESCRIPTION
-
-TODO
-
-## NOTES
-
-Debuglog objects will likely cease being generally available to userspace
-processes in the future.
-
-## SYSCALLS
-
- - [`zx_debuglog_create()`] - create a kernel managed debuglog reader or writer
- - [`zx_debuglog_write()`] - write log entry to debuglog
- - [`zx_debuglog_read()`] - read log entries from debuglog
-
-[`zx_debuglog_create()`]: ../syscalls/debuglog_create.md
-[`zx_debuglog_read()`]: ../syscalls/debuglog_read.md
-[`zx_debuglog_write()`]: ../syscalls/debuglog_write.md
diff --git a/docs/objects/event.md b/docs/objects/event.md
deleted file mode 100644
index 3a89c8b..0000000
--- a/docs/objects/event.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Event
-
-## NAME
-
-event - Signalable event for concurrent programming
-
-## SYNOPSIS
-
-Events are user-signalable objects. The 8 signal bits reserved for
-userspace (**ZX_USER_SIGNAL_0** through **ZX_USER_SIGNAL_7**) may be set,
-cleared, and waited upon.
-
-## DESCRIPTION
-
-TODO
-
-## SYSCALLS
-
- - [`zx_event_create()`] - create an event
- - [`zx_object_signal()`] - set or clear the user signals on an object
-
-## SEE ALSO
-
- - [eventpair](eventpair.md) - linked pairs of signalable objects
-
-[`zx_event_create()`]: ../syscalls/event_create.md
-[`zx_object_signal()`]: ../syscalls/object_signal.md
diff --git a/docs/objects/eventpair.md b/docs/objects/eventpair.md
deleted file mode 100644
index 57e4697..0000000
--- a/docs/objects/eventpair.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Event Pair
-
-## NAME
-
-eventpair - Mutually signalable pair of events for concurrent programming
-
-## SYNOPSIS
-
-Event Pairs are linked pairs of user-signalable objects. The 8 signal
-bits reserved for userspace (**ZX_USER_SIGNAL_0** through
-**ZX_USER_SIGNAL_7**) may be set or cleared on the local or opposing
-endpoint of an Event Pair.
-
-## DESCRIPTION
-
-TODO
-
-## SYSCALLS
-
- - [`zx_eventpair_create()`] - create a connected pair of events
-
-<br>
-
- - [`zx_object_signal_peer()`] - set or clear the user signals in the opposite end
-
-[`zx_eventpair_create()`]: ../syscalls/eventpair_create.md
-[`zx_object_signal_peer()`]: ../syscalls/object_signal.md
diff --git a/docs/objects/fifo.md b/docs/objects/fifo.md
deleted file mode 100644
index 16ddf0a..0000000
--- a/docs/objects/fifo.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# FIFO
-
-## NAME
-
-FIFO - first-in first-out interprocess queue
-
-## SYNOPSIS
-
-FIFOs are intended to be the control plane for shared memory
-transports.  Their read and write operations are more efficient than
-[sockets](socket.md) or [channels](channel.md), but there are severe
-restrictions on the size of elements and buffers.
-
-## DESCRIPTION
-
-TODO
-
-## SYSCALLS
-
- - [`zx_fifo_create()`] - create a new fifo
- - [`zx_fifo_read()`] - read data from a fifo
- - [`zx_fifo_write()`] - write data to a fifo
-
-[`zx_fifo_create()`]: ../syscalls/fifo_create.md
-[`zx_fifo_read()`]: ../syscalls/fifo_read.md
-[`zx_fifo_write()`]: ../syscalls/fifo_write.md
diff --git a/docs/objects/futex.md b/docs/objects/futex.md
deleted file mode 100644
index f87ce54..0000000
--- a/docs/objects/futex.md
+++ /dev/null
@@ -1,182 +0,0 @@
-# Futex
-
-## NAME
-
-futex - A primitive for creating userspace synchronization tools.
-
-## SYNOPSIS
-
-A **futex** is a Fast Userspace muTEX. It is a low level
-synchronization primitive which is a building block for higher level
-APIs such as `pthread_mutex_t` and `pthread_cond_t`.
-
-Futexes are designed to not enter the kernel or allocate kernel
-resources in the uncontested case.
-
-## DESCRIPTION
-
-The zircon futex implementation currently supports three operations distributed
-over 6 syscalls:
-
-```C
-    zx_status_t zx_futex_wait(const zx_futex_t* value_ptr,
-                              int current_value,
-                              zx_handle_t new_futex_owner,
-                              zx_time_t deadline);
-    zx_status_t zx_futex_wake(const zx_futex_t* value_ptr, uint32_t wake_count);
-    zx_status_t zx_futex_wake_single_owner(const zx_futex_t* value_ptr);
-    zx_status_t zx_futex_requeue(const zx_futex_t* value_ptr,
-                                 uint32_t wake_count,
-                                 int current_value,
-                                 const zx_futex_t* requeue_ptr,
-                                 uint32_t requeue_count,
-                                 zx_handle_t new_requeue_owner);
-    zx_status_t zx_futex_requeue_single_owner(const zx_futex_t* value_ptr,
-                                              int current_value,
-                                              const zx_futex_t* requeue_ptr,
-                                              uint32_t requeue_count,
-                                              zx_handle_t new_requeue_owner);
-    zx_status_t zx_futex_get_owner(const zx_futex_t* value_ptr, uint64_t* koid);
-```
-
-All of these share a `value_ptr` parameter, which is the virtual
-address of an aligned userspace integer. This virtual address is the
-information used in kernel to track what futex given threads are
-waiting on. The kernel does not currently modify the value of
-`*value_ptr` (but see below for future operations which might do
-so). It is up to userspace code to correctly atomically modify this
-value across threads in order to build mutexes and so on.
-
-See the [`zx_futex_wait()`], [`zx_futex_wake()`], [`zx_futex_requeue()`], and
-[`zx_futex_get_owner()`] man pages for more details.
-
-## RIGHTS
-
-Futex objects do not have any rights associated with them.
-
-There are only 2 primitive operations which userspace code can perform on a
-futex: waiting and waking (requeue is a combination of the two).  Because
-futexes are strictly a process local concept, revoking access to either of these
-operations would make the futex functionally worthless.
-
-Additionally, from the kernel's perspective, futexes are ephemeral objects whose
-state only exists while the futex has waiters.  Without a more durable state
-present in the kernel, it is more or less impossible to have a persisted concept
-of rights for a futex.
-
-### Differences from Linux futexes
-
-Note that all of the zircon futex operations key off of the virtual
-address of an userspace pointer. This differs from the Linux
-implementation, which distinguishes private futex operations (which
-correspond to our in-process-only ones) from ones shared across
-address spaces.
-
-As noted above, all of our futex operations leave the value of the
-futex unmodified from the kernel. Other potential operations, such as
-Linux's `FUTEX_WAKE_OP`, requires atomic manipulation of the value
-from the kernel, which our current implementation does not require.
-
-### Ownership and Priority Inheritance
-
-#### Overview
-
-Some runtimes may need to implement synchronization primitives based on futexes
-which exhibit priority inheritance behavior.  In order to support these users,
-zircon futexes have a concept of 'ownership' which can be used to implement such
-primitives.  Use of this feature is optional.
-
-At any point in time, a futex may be either unowned, or owned by a single
-thread.  When a thread owns one or more futexes, its effective priority becomes
-the maximum of its base priority, and the priorities of all of the current
-waiters of all of the futexes currently owned by it.  As soon a thread no longer
-owns a futex, the pressure of the priorities of the futex's waiters disappears
-from the relationship above.  Once the thread no longer owns any futexes, its
-priority will relax back to its base priority.
-
-Signaling of the owner of a futex is the responsibility of the userspace code,
-as is applying the ownership concept properly when constructing a specific type
-of synchronization object which needs priority inheritance behavior.
-
-Zircon futexes have at most a single owner.  Multiple ownership of futexes for
-the purpose of priority inheritance is not supported.  The owner of a futex may
-never simultaneously be a waiter for the same futex.
-
-#### Assigning Ownership
-
-Ownership of a futex is assigned via each 'wait' or 'requeue' operation.  In the
-case of a requeue operation, the target futex is the requeue futex, not the
-wake_futex.  Users pass a handle to a thread indicating who the current owner of
-the futex should be, or **ZX_HANDLE_INVALID** if there should be no owner.
-
-+ Passing a valid handle to a thread to indicate the futex owner is the
-  responsibility of the userspace code.  Passing an invalid handle, or a handle
-  to a non-thread object will result in the wait/requeue operation failing.
-+ If the wait/requeue operation succeeds, the owner of the target futex will
-  _always_ be set to either the thread specified, or nothing if
-  **ZX_HANDLE_INVALID** is passed.
-+ In particular, if the wait/requeue operation fails because of a mismatch
-  between the expected futex value and the actual futex value, the owner of the
-  futex will remain unchanged.
-
-#### Transferring Ownership
-
-Ownership of a futex may be transferred by the kernel on behalf of the user
-during a wake operation or a requeue operation.  In the case of a requeue
-operation, the target of the transfer is the wake_futex, not the requeue_futex.
-Ownership transfer only takes place when using the
-[`zx_futex_wake_single_owner()`] or [`zx_futex_requeue_single_owner()`]
-variants of the wake/requeue operations.  The `single_owner` variants of
-these operations will release exactly one waiter, and
-assign ownership of the futex to the released thread.
-
-+ If there are _no_ waiters during the wake operation, then there is already no
-  owner.  This will remain unchanged.
-+ If a requeue operation fails because of a mismatch between the expected futex
-  value and the actual futex value, the owner of the futex will remain
-  unchanged.
-+ A successful call to either of the non-single_owner variants of the
-  wake/requeue operation will cause the target futex's owner to be set to
-  nothing.
-
-### Papers about futexes
-
-- [Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux](https://www.kernel.org/doc/ols/2002/ols2002-pages-479-495.pdf), Hubertus Franke and Rusty Russell
-
-    This is the original white paper describing the Linux futex. It
-    documents the history and design of the original implementation,
-    prior (failed) attempts at creating a fast userspace
-    synchronization primitive, and performance measurements.
-
-- [Futexes Are Tricky](https://www.akkadia.org/drepper/futex.pdf), Ulrich Drepper
-
-    This paper describes some gotchas and implementation details of
-    futexes in Linux. It discusses the kernel implementation, and goes
-    into more detail about correct and efficient userspace
-    implementations of mutexes, condition variables, and so on.
-
-- [Mutexes and Condition Variables using Futexes](http://locklessinc.com/articles/mutex_cv_futex/)
-
-    Further commentary on "Futexes are tricky", outlining a simple
-    implementation that avoids the need for `FUTEX_CMP_REQUEUE`
-
-- [Locking in WebKit](https://webkit.org/blog/6161/locking-in-webkit/), Filip Pizlo
-
-    An in-depth tour of the locking primitives in WebKit, complete with
-    benchmarks and analysis. Contains a detailed explanation of the "parking
-    lot" concept, which allows very compact representation of userspace
-    mutexes.
-
-## SYSCALLS
-
- - [`zx_futex_wait()`]
- - [`zx_futex_wake()`]
- - [`zx_futex_requeue()`]
- - [`zx_futex_get_owner()`]
-
-[`zx_futex_get_owner()`]: ../syscalls/futex_get_owner.md
-[`zx_futex_requeue()`]: ../syscalls/futex_requeue.md
-[`zx_futex_requeue_single_owner()`]: ../syscalls/futex_requeue_single_owner.md
-[`zx_futex_wait()`]: ../syscalls/futex_wait.md
-[`zx_futex_wake()`]: ../syscalls/futex_wake.md
-[`zx_futex_wake_single_owner()`]: ../syscalls/futex_wake_single_owner.md
diff --git a/docs/objects/interrupts.md b/docs/objects/interrupts.md
deleted file mode 100644
index 2844ca8..0000000
--- a/docs/objects/interrupts.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Interrupts
-
-## NAME
-
-interrupts - Usermode I/O interrupt delivery
-
-## SYNOPSIS
-
-Interrupt objects allow userspace to create, signal, and wait on
-hardware interrupts.
-
-## DESCRIPTION
-
-TODO
-
-## NOTES
-
-Interrupt Objects are private to the DDK and not generally available
-to userspace processes.
-
-## SYSCALLS
-
- - [`zx_interrupt_create()`] - Create an interrupt handle
- - [`zx_interrupt_destroy()`] - Destroy an interrupt handle
- - [`zx_interrupt_bind()`] - Bind an interrupt vector to interrupt handle
- - [`zx_interrupt_wait()`] - Wait for an interrupt on an interrupt handle
- - [`zx_interrupt_trigger()`] - Triggers a virtual interrupt on an interrupt handle
- - [`zx_interrupt_ack()`] - Acknowledge an interrupt and re-arm it
-
-[`zx_interrupt_ack()`]: ../syscalls/interrupt_ack.md
-[`zx_interrupt_bind()`]: ../syscalls/interrupt_bind.md
-[`zx_interrupt_create()`]: ../syscalls/interrupt_create.md
-[`zx_interrupt_destroy()`]: ../syscalls/interrupt_destroy.md
-[`zx_interrupt_trigger()`]: ../syscalls/interrupt_trigger.md
-[`zx_interrupt_wait()`]: ../syscalls/interrupt_wait.md
diff --git a/docs/objects/job.md b/docs/objects/job.md
deleted file mode 100644
index 9756e40..0000000
--- a/docs/objects/job.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Job
-
-## NAME
-
-job - Control a group of processes
-
-## SYNOPSIS
-
-A job is a group of processes and possibly other (child) jobs. Jobs are used to
-track privileges to perform kernel operations (i.e., make various syscalls,
-with various options), and track and limit basic resource (e.g., memory, CPU)
-consumption. Every process belongs to a single job. Jobs can also be nested,
-and every job except the root job also belongs to a single (parent) job.
-
-## DESCRIPTION
-
-A job is an object consisting of the following:
-+ a reference to a parent job
-+ a set of child jobs (each of whom has this job as parent)
-+ a set of member [processes](process.md)
-+ a set of policies [âš  not implemented]
-
-Jobs control "applications" that are composed of more than one process to be
-controlled as a single entity.
-
-## SYSCALLS
-
- - [`zx_job_create()`] - create a new child job.
- - [`zx_process_create()`] - create a new process within a job.
- - [`zx_job_set_policy()`] - set policy for new processes in the job.
- - [`zx_task_bind_exception_port()`] - attach an exception port to a task
- - [`zx_task_kill()`] - cause a task to stop running.
-
-[`zx_job_create()`]: ../syscalls/job_create.md
-[`zx_job_set_policy()`]: ../syscalls/job_set_policy.md
-[`zx_process_create()`]: ../syscalls/process_create.md
-[`zx_task_bind_exception_port()`]: ../syscalls/task_bind_exception_port.md
-[`zx_task_kill()`]: ../syscalls/task_kill.md
diff --git a/docs/objects/pinned_memory_token.md b/docs/objects/pinned_memory_token.md
deleted file mode 100644
index d58fea1..0000000
--- a/docs/objects/pinned_memory_token.md
+++ /dev/null
@@ -1,36 +0,0 @@
-# Pinned Memory Token
-
-## NAME
-
-pinned_memory_token - Representation of a device DMA grant
-
-## SYNOPSIS
-
-Pinned Memory Tokens (PMTs) represent an outstanding access grant to a device
-for performing DMA.
-
-## DESCRIPTION
-
-PMTs are obtained by [pinning memory with a BTI object](../syscalls/bti_pin.md).
-It is valid for the device associated with the BTI to access the memory represented
-by the PMT for as long as the PMT object is around.  When the PMT object is
-destroyed, either via [`zx_handle_close()`], [`zx_pmt_unpin()`], or process
-termination, access to the represented memory becomes illegal (this is
-enforced by hardware on systems with the capability to do so, such as IOMMUs).
-
-If a PMT object is destroyed by means other than [`zx_pmt_unpin()`], the
-underlying memory is *quarantined*.  See
-[bus_transaction_initiator](bus_transaction_initiator.md) for more details.
-
-## SEE ALSO
-
- - [bus_transaction_initiator](bus_transaction_initiator.md) - Bus Transaction Initiators
-
-## SYSCALLS
-
- - [`zx_bti_pin()`] - pin memory and grant access to it to the BTI
- - [`zx_pmt_unpin()`] - revoke access and unpin memory
-
-[`zx_bti_pin()`]: ../syscalls/bti_pin.md
-[`zx_handle_close()`]: ../syscalls/handle_close.md
-[`zx_pmt_unpin()`]: ../syscalls/pmt_unpin.md
diff --git a/docs/objects/port.md b/docs/objects/port.md
deleted file mode 100644
index 71811d8..0000000
--- a/docs/objects/port.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Port
-
-## NAME
-
-port - Signaling and mailbox primitive
-
-## SYNOPSIS
-
-Ports allow threads to wait for packets to be delivered from various
-events. These events include explicit queueing on the port,
-asynchronous waits on other handles bound to the port, and
-asynchronous message delivery from IPC transports.
-
-## DESCRIPTION
-
-TODO
-
-## SYSCALLS
-
- - [`zx_port_create()`] - create a port
- - [`zx_port_queue()`] - send a packet to a port
- - [`zx_port_wait()`] - wait for packets to arrive on a port
-
-[`zx_port_create()`]: ../syscalls/port_create.md
-[`zx_port_queue()`]: ../syscalls/port_queue.md
-[`zx_port_wait()`]: ../syscalls/port_wait.md
diff --git a/docs/objects/process.md b/docs/objects/process.md
deleted file mode 100644
index 4dbed9f..0000000
--- a/docs/objects/process.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Process
-
-## NAME
-
-process - Process abstraction
-
-## SYNOPSIS
-
-A zircon process is an instance of a program in the traditional
-sense: a set of instructions which will be executed by one or more
-threads, along with a collection of resources.
-
-## DESCRIPTION
-
-The process object is a container of the following resources:
-
-+ [Handles](../handles.md)
-+ [Virtual Memory Address Regions](vm_address_region.md)
-+ [Threads](thread.md)
-
-In general, it is associated with code which it is executing until it is
-forcefully terminated or the program exits.
-
-Processes are owned by [jobs](job.md) and allow an application that is
-composed by more than one process to be treated as a single entity, from the
-perspective of resource and permission limits, as well as lifetime control.
-
-### Lifetime
-A process is created via [`zx_process_create()`] and its execution begins with
-[`zx_process_start()`].
-
-The process stops execution when:
-+ the last thread is terminated or exits
-+ the process calls [`zx_process_exit()`]
-+ the parent job terminates the process
-+ the parent job is destroyed
-
-The call to [`zx_process_start()`] cannot be issued twice. New threads cannot
-be added to a process that was started and then its last thread has exited.
-
-## SYSCALLS
-
- - [`zx_process_create()`] - create a new process within a job
- - [`zx_process_read_memory()`] - read from a process's address space
- - [`zx_process_start()`] - cause a new process to start executing
- - [`zx_process_write_memory()`] - write to a process's address space
- - [`zx_process_exit()`] - exit the current process
-
-<br>
-
- - [`zx_job_create()`] - create a new job within a parent job
-
-<br>
-
- - [`zx_vmar_map()`] - Map memory into an address space range
- - [`zx_vmar_protect()`] - Change permissions on an address space range
- - [`zx_vmar_unmap()`] - Unmap memory from an address space range
-
-[`zx_job_create()`]: ../syscalls/job_create.md
-[`zx_process_create()`]: ../syscalls/process_create.md
-[`zx_process_exit()`]: ../syscalls/process_exit.md
-[`zx_process_read_memory()`]: ../syscalls/process_read_memory.md
-[`zx_process_start()`]: ../syscalls/process_start.md
-[`zx_process_write_memory()`]: ../syscalls/process_write_memory.md
-[`zx_vmar_map()`]: ../syscalls/vmar_map.md
-[`zx_vmar_protect()`]: ../syscalls/vmar_protect.md
-[`zx_vmar_unmap()`]: ../syscalls/vmar_unmap.md
diff --git a/docs/objects/resource.md b/docs/objects/resource.md
deleted file mode 100644
index eb2403e..0000000
--- a/docs/objects/resource.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Resource
-
-## NAME
-
-resource - Address space rights and accounting
-
-## SYNOPSIS
-
-A resource is an immutable object that is used to validate access to syscalls
-that create objects backed by address space, or permit access to address space.
-These include [vm objects](vm_object.md), [interrupts](interrupts.md), and x86
-ioports.
-
-## DESCRIPTION
-
-Resources are used to gate access to specific regions of address space and are
-required to create VMOs and IRQs, as well as accessing x86 ioports.
-
-A resource object consists of a single resource *kind*, with *base* address and
-*len* parameters that define a range of address space the holder of the resource
-is granted access to. The range covers *base* up to but not including *base* +
-*len*.  These objects are immutable after creation. Valid *kind*  values are
-**ZX_RSRC_KIND_ROOT**, **ZX_RSRC_KIND_HYPERVISOR**, **ZX_RSRC_KIND_MMIO**,
-**ZX_RSRC_KIND_IOPORT**, **ZX_RSRC_KIND_IRQ**, **ZX_RSRC_KIND_VMEX**, and
-**ZX_RSRC_KIND_SMC**. New resources may be created with a root resource by
-calling [`zx_resource_create()`]. An initial root
-resource is created by the kernel during boot and handed off to the first
-userspace process started by userboot.
-
-Resource allocations can be either *shared* or *exclusive*. A shared resource
-grants the permission to access the given address space, but does not reserve
-that address space exclusively for the owner of the resource. An exclusive
-resource grants access to the region to only the holder of the exclusive
-resource.  Exclusive and shared resource ranges may not overlap.
-
-Resources are lifecycle tracked and upon the last handle being closed will be
-freed. In the case of exclusive resources this means the given address range
-will be released back to the allocator for the given *kind* of resource. Objects
-created through a resource do not hold a reference to the resource and thus do
-not keep it alive.
-
-## NOTES
-
-Resources are typically private to the DDK and platform bus drivers. Presently,
-this means ACPI and platform bus hold the root resource respectively and hand
-out more fine-grained resources to other drivers.
-
-## SYSCALLS
-
- - [`zx_interrupt_create()`]
- - [`zx_ioports_request()`]
- - [`zx_resource_create()`]
- - [`zx_vmo_create_physical()`]
-
-[`zx_interrupt_create()`]: ../syscalls/interrupt_create.md
-[`zx_ioports_request()`]: ../syscalls/ioports_request.md
-[`zx_resource_create()`]: ../syscalls/resource_create.md
-[`zx_vmo_create_physical()`]: ../syscalls/vmo_create_physical.md
diff --git a/docs/objects/socket.md b/docs/objects/socket.md
deleted file mode 100644
index fa7b698..0000000
--- a/docs/objects/socket.md
+++ /dev/null
@@ -1,94 +0,0 @@
-# Socket
-
-## NAME
-
-Socket - Bidirectional streaming IPC transport
-
-## SYNOPSIS
-
-Sockets are a bidirectional stream transport. Unlike channels, sockets
-only move data (not handles).
-
-## DESCRIPTION
-
-Data is written into one end of a socket via [`zx_socket_write()`] and
-read from the opposing end via [`zx_socket_read()`].
-
-Upon creation, both ends of the socket are writable and readable. Via the
-**ZX_SOCKET_SHUTDOWN_READ** and **ZX_SOCKET_SHUTDOWN_WRITE** options to
-[`zx_socket_shutdown()`], one end of the socket can be closed for reading and/or
-writing.
-
-## PROPERTIES
-
-The following properties may be queried from a socket object:
-
-**ZX_PROP_SOCKET_RX_THRESHOLD** size of the read threshold of a socket, in
-bytes. When the bytes queued on the socket (available for reading) is equal to
-or greater than this value, the **ZX_SOCKET_READ_THRESHOLD** signal is asserted.
-Read threshold signalling is disabled by default (and when set, writing
-a value of 0 for this property disables it).
-
-**ZX_PROP_SOCKET_TX_THRESHOLD** size of the write threshold of a socket,
-in bytes. When the space available for writing on the socket is equal to or
-greater than this value, the **ZX_SOCKET_WRITE_THRESHOLD** signal is asserted.
-Write threshold signalling is disabled by default (and when set, writing a
-value of 0 for this property disables it).
-
-From the point of view of a socket handle, the receive buffer contains the data
-that is readable via [`zx_socket_read()`] from that handle (having been written
-from the opposing handle), and the transmit buffer contains the data that is
-written via [`zx_socket_write()`] to that handle (and readable from the opposing
-handle).
-
-## SIGNALS
-
-The following signals may be set for a socket object:
-
-**ZX_SOCKET_READABLE** data is available to read from the socket
-
-**ZX_SOCKET_WRITABLE** data may be written to the socket
-
-**ZX_SOCKET_PEER_CLOSED** the other endpoint of this socket has
-been closed.
-
-**ZX_SOCKET_PEER_WRITE_DISABLED** writing is disabled permanently for the other
-endpoint either because of passing **ZX_SOCKET_SHUTDOWN_READ** to this endpoint
-or passing **ZX_SOCKET_SHUTDOWN_WRITE** to the peer. Reads on a socket endpoint
-with this signal raised will succeed so long as there is data in the socket that
-was written before writing was disabled.
-
-**ZX_SOCKET_WRITE_DISABLED** writing is disabled permanently for this endpoint
-either because of passing **ZX_SOCKET_SHUTDOWN_WRITE** to this endpoint or
-passing **ZX_SOCKET_SHUTDOWN_READ** to the peer.
-
-**ZX_SOCKET_CONTROL_READABLE** data is available to read from the
-socket control plane.
-
-**ZX_SOCKET_CONTROL_WRITABLE** data may be written to the socket control plane.
-
-**ZX_SOCKET_SHARE** a socket may be sent via [`zx_socket_share()`].
-
-**ZX_SOCKET_ACCEPT** a socket may be received via [`zx_socket_accept()`].
-
-**ZX_SOCKET_READ_THRESHOLD** data queued up on socket for reading exceeds
-the read threshold.
-
-**ZX_SOCKET_WRITE_THRESHOLD** space available on the socket for writing exceeds
-the write threshold.
-
-## SYSCALLS
-
- - [`zx_socket_accept()`] - receive a socket via a socket
- - [`zx_socket_create()`] - create a new socket
- - [`zx_socket_read()`] - read data from a socket
- - [`zx_socket_share()`] - share a socket via a socket
- - [`zx_socket_shutdown()`] - prevent reading or writing
- - [`zx_socket_write()`] - write data to a socket
-
-[`zx_socket_accept()`]: ../syscalls/socket_accept.md
-[`zx_socket_create()`]: ../syscalls/socket_create.md
-[`zx_socket_read()`]: ../syscalls/socket_read.md
-[`zx_socket_share()`]: ../syscalls/socket_share.md
-[`zx_socket_shutdown()`]: ../syscalls/socket_shutdown.md
-[`zx_socket_write()`]: ../syscalls/socket_write.md
diff --git a/docs/objects/task.md b/docs/objects/task.md
deleted file mode 100644
index 57587e7..0000000
--- a/docs/objects/task.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Task
-
-## NAME
-
-Task - "Runnable" subclass of kernel objects (threads, processes, and jobs)
-
-## SYNOPSIS
-
-[Threads](thread.md), [processes](process.md), and [jobs](job.md) objects
-are all tasks. They share the ability to be suspended, resumed, and
-killed.
-
-## DESCRIPTION
-
-TODO
-
-## SYSCALLS
-
- - [`zx_task_bind_exception_port()`] - attach an exception port to a task
- - [`zx_task_kill()`] - cause a task to stop running
-
-[`zx_task_bind_exception_port()`]: ../syscalls/task_bind_exception_port.md
-[`zx_task_kill()`]: ../syscalls/task_kill.md
diff --git a/docs/objects/thread.md b/docs/objects/thread.md
deleted file mode 100644
index 3e444eb..0000000
--- a/docs/objects/thread.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# Thread
-
-## NAME
-
-thread - runnable / computation entity
-
-## SYNOPSIS
-
-TODO
-
-## DESCRIPTION
-
-The thread object is the construct that represents a time-shared CPU execution
-context. Thread objects live associated to a particular
-[Process Object](process.md) which provides the memory and the handles to other
-objects necessary for I/O and computation.
-
-### Lifetime
-Threads are created by calling [`zx_thread_create()`], but only start executing
-when either [`zx_thread_start()`] or [`zx_process_start()`] are called. Both syscalls
-take as an argument the entrypoint of the initial routine to execute.
-
-The thread passed to [`zx_process_start()`] should be the first thread to start execution
-on a process.
-
-A thread terminates execution:
-+ by calling [`zx_thread_exit()`]
-+ by calling [`zx_vmar_unmap_handle_close_thread_exit()`]
-+ by calling [`zx_futex_wake_handle_close_thread_exit()`]
-+ when the parent process terminates
-+ by calling [`zx_task_kill()`] with the thread's handle
-+ after generating an exception for which there is no handler or the handler
-decides to terminate the thread.
-
-Returning from the entrypoint routine does not terminate execution. The last
-action of the entrypoint should be to call [`zx_thread_exit()`] or one of the
-above mentioned `_exit()` variants.
-
-Closing the last handle to a thread does not terminate execution. In order to
-forcefully kill a thread for which there is no available handle, use
-[`zx_object_get_child()`] to obtain a handle to the thread. This method is strongly
-discouraged. Killing a thread that is executing might leave the process in a
-corrupt state.
-
-Fuchsia native threads are always *detached*. That is, there is no *join()* operation
-needed to do a clean termination. However, some runtimes above the kernel, such as
-C11 or POSIX might require threads to be joined.
-
-## SYSCALLS
-
- - [`zx_thread_create()`] - create a new thread within a process
- - [`zx_thread_exit()`] - exit the current thread
- - [`zx_thread_read_state()`] - read register state from a thread
- - [`zx_thread_start()`] - cause a new thread to start executing
- - [`zx_thread_write_state()`] - modify register state of a thread
-
-<br>
-
- - [`zx_task_bind_exception_port()`] - attach an exception port to a task
- - [`zx_task_kill()`] - cause a task to stop running
-
-[`zx_futex_wake_handle_close_thread_exit()`]: ../syscalls/futex_wake_handle_close_thread_exit.md
-[`zx_object_get_child()`]: ../syscalls/object_get_child.md
-[`zx_process_start()`]: ../syscalls/process_start.md
-[`zx_task_bind_exception_port()`]: ../syscalls/task_bind_exception_port.md
-[`zx_task_kill()`]: ../syscalls/task_kill.md
-[`zx_thread_create()`]: ../syscalls/thread_create.md
-[`zx_thread_exit()`]: ../syscalls/thread_exit.md
-[`zx_thread_read_state()`]: ../syscalls/thread_read_state.md
-[`zx_thread_write_state()`]: ../syscalls/thread_write_state.md
-[`zx_thread_start()`]: ../syscalls/thread_start.md
-[`zx_vmar_unmap_handle_close_thread_exit()`]: ../syscalls/vmar_unmap_handle_close_thread_exit.md
diff --git a/docs/objects/timer.md b/docs/objects/timer.md
deleted file mode 100644
index 81ff38c..0000000
--- a/docs/objects/timer.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# Timer
-
-## NAME
-
-timer - An object that may be signaled at some point in the future
-
-## SYNOPSIS
-
-A timer is used to wait until a specified point in time has occurred
-or the timer has been canceled.
-
-## DESCRIPTION
-
-Like other waitable objects, timers can be waited on via
-[`zx_object_wait_one()`], [`zx_object_wait_many()`], or
-[`zx_object_wait_async()`].
-
-A given timer can be used over and over.
-
-Once **ZX_TIMER_SIGNALED** is asserted, it will remain asserted until
-the timer is canceled ([`zx_timer_cancel()`]) or reset ([`zx_timer_set()`]).
-
-The typical lifecycle is:
-
-1. `zx_timer_create()`
-2. `zx_timer_set()`
-3. wait for the timer to be signaled
-4. optionally reset and reuse the timer (i.e. goto #2)
-5. `zx_handle_close()`
-
-## SYSCALLS
-
- - [`zx_timer_create()`] - create a timer
- - [`zx_timer_set()`] - set a timer
- - [`zx_timer_cancel()`] - cancel a timer
-
-## SEE ALSO
-
-+ [timer slack](../timer_slack.md)
-
-[`zx_object_wait_one()`]: ../syscalls/object_wait_one.md
-[`zx_object_wait_many()`]: ../syscalls/object_wait_many.md
-[`zx_object_wait_async()`]: ../syscalls/object_wait_async.md
-[`zx_timer_create()`]: ../syscalls/timer_create.md
-[`zx_timer_set()`]: ../syscalls/timer_set.md
-[`zx_timer_cancel()`]: ../syscalls/timer_cancel.md
diff --git a/docs/objects/vm_address_region.md b/docs/objects/vm_address_region.md
deleted file mode 100644
index 8bc4539..0000000
--- a/docs/objects/vm_address_region.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# Virtual Memory Address Region
-
-## NAME
-
-vm_address_region - A contiguous region of a virtual memory address space
-
-## SYNOPSIS
-
-Virtual Memory Address Regions (VMARs) represent contiguous parts of a virtual
-address space.
-
-## DESCRIPTION
-
-VMARs are used by the kernel and userspace to represent the allocation of an
-address space.
-
-Every process starts with a single VMAR (the root VMAR) that spans the entire
-address space (see [`zx_process_create()`]).  Each VMAR
-can be logically divided up into any number of non-overlapping parts, each
-representing a child VMARs, a virtual memory mapping, or a gap.  Child VMARs
-are created using [`zx_vmar_allocate()`].  VM mappings
-are created using [`zx_vmar_map()`].
-
-VMARs have a hierarchical permission model for allowable mapping permissions.
-For example, the root VMAR allows read, write, and executable mapping.  One
-could create a child VMAR that only allows read and write mappings, in which
-it would be illegal to create a child that allows executable mappings.
-
-When a VMAR is created using [`zx_vmar_allocate()`], its parent VMAR retains a reference
-to it.  Because of this, if all handles to the child VMAR are closed, the child
-and its descendants will remain active in the address space.  In order to
-disconnect the child from the address space, [`zx_vmar_destroy()`]
-must be called on a handle to the child.
-
-By default, all allocations of address space are randomized.  At VMAR
-creation time, the caller can choose which randomization algorithm is used.
-The default allocator attempts to spread allocations widely across the full
-width of the VMAR.  The alternate allocator, selected with
-**ZX_VM_COMPACT**, attempts to keep allocations close together within the
-VMAR, but at a random location within the range.  It is recommended to use
-the default allocator.
-
-VMARs optionally support a fixed-offset mapping mode (called specific mapping).
-This mode can be used to create guard pages or ensure the relative locations of
-mappings.  Each VMAR may have the **ZX_VM_CAN_MAP_SPECIFIC** permission,
-regardless of whether or not its parent VMAR had that permission.
-
-## EXAMPLE
-
-```c
-#include <zircon/syscalls.h>
-
-/* Map this VMO into the given VMAR, with |before| bytes of unmapped guard space
-   before it and |after| bytes after it.  */
-zx_status_t map_with_guard(zx_handle_t vmar, size_t before, size_t after,
-                           zx_handle_t vmo, uint64_t vmo_offset,
-                           size_t mapping_len, uintptr_t* mapped_addr,
-                           zx_handle_t* wrapping_vmar) {
-
-    /* wrap around check elided */
-    const size_t child_vmar_size = before + after + mapping_len;
-    const zx_vm_option_t child_vmar_options = ZX_VM_CAN_MAP_READ |
-                                              ZX_VM_CAN_MAP_WRITE |
-                                              ZX_VM_CAN_MAP_SPECIFIC;
-    const zx_vm_option_t mapping_options = ZX_VM_SPECIFIC |
-                                           ZX_VM_PERM_READ |
-                                           ZX_VM_PERM_WRITE;
-
-    uintptr_t child_vmar_addr;
-    zx_handle_t child_vmar;
-    zx_status_t status = zx_vmar_allocate(vmar, child_vmar_options, 0,
-                                          child_vmar_size,
-                                          &child_vmar,
-                                          &child_vmar_addr);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    status = zx_vmar_map(child_vmar, mapping_options, before, vmo, vmo_offset,
-                         mapping_len, mapped_addr);
-    if (status != ZX_OK) {
-        zx_vmar_destroy(child_vmar);
-        zx_handle_close(child_vmar);
-        return status;
-    }
-
-    *wrapping_vmar = child_vmar;
-    return ZX_OK;
-}
-```
-
-## SEE ALSO
-
- - [vm_object](vm_object.md) - Virtual Memory Objects
-
-## SYSCALLS
-
- - [`zx_vmar_allocate()`] - create a new child VMAR
- - [`zx_vmar_map()`] - map a VMO into a process
- - [`zx_vmar_unmap()`] - unmap a memory region from a process
- - [`zx_vmar_protect()`] - adjust memory access permissions
- - [`zx_vmar_destroy()`] - destroy a VMAR and all of its children
-
-[`zx_process_create()`]: ../syscalls/process_create.md
-[`zx_vmar_allocate()`]: ../syscalls/vmar_allocate.md
-[`zx_vmar_destroy()`]: ../syscalls/vmar_destroy.md
-[`zx_vmar_map()`]: ../syscalls/vmar_map.md
-[`zx_vmar_protect()`]: ../syscalls/vmar_protect.md
-[`zx_vmar_unmap()`]: ../syscalls/vmar_unmap.md
diff --git a/docs/objects/vm_object.md b/docs/objects/vm_object.md
deleted file mode 100644
index 8d45085..0000000
--- a/docs/objects/vm_object.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Virtual Memory Object
-
-## NAME
-
-vm\_object - Virtual memory containers
-
-## SYNOPSIS
-
-A Virtual Memory Object (VMO) represents a contiguous region of virtual memory
-that may be mapped into multiple address spaces.
-
-## DESCRIPTION
-
-VMOs are used in by the kernel and userspace to represent both paged and physical memory.
-They are the standard method of sharing memory between processes, as well as between the kernel and
-userspace.
-
-VMOs are created with [`zx_vmo_create()`] and basic I/O can be
-performed on them with [`zx_vmo_read()`] and [`zx_vmo_write()`].
-A VMO's size may be set using [`zx_vmo_set_size()`].
-Conversely, [`zx_vmo_get_size()`] will retrieve a VMO's current size.
-
-The size of a VMO will be rounded up to the next page size boundary by the kernel.
-
-Pages are committed (allocated) for VMOs on demand through [`zx_vmo_read()`], [`zx_vmo_write()`], or by writing to a mapping of the VMO created using [`zx_vmar_map()`]. Pages can be committed and decommitted from a VMO manually by calling
-[`zx_vmo_op_range()`] with the **ZX_VMO_OP_COMMIT** and **ZX_VMO_OP_DECOMMIT**
-operations, but this should be considered a low level operation. [`zx_vmo_op_range()`] can also be used for cache and locking operations against pages a VMO holds.
-
-Processes with special purpose use cases involving cache policy can use
-[`zx_vmo_set_cache_policy()`] to change the policy of a given VMO.
-This use case typically applies to device drivers.
-
-## SYSCALLS
-
- - [`zx_vmo_create()`] - create a new vmo
- - [`zx_vmo_read()`] - read from a vmo
- - [`zx_vmo_write()`] - write to a vmo
- - [`zx_vmo_get_size()`] - obtain the size of a vmo
- - [`zx_vmo_set_size()`] - adjust the size of a vmo
- - [`zx_vmo_op_range()`] - perform an operation on a range of a vmo
- - [`zx_vmo_set_cache_policy()`] - set the caching policy for pages held by a vmo
-
-<br>
-
- - [`zx_vmar_map()`] - map a VMO into a process
- - [`zx_vmar_unmap()`] - unmap memory from a process
-
-[`zx_vmar_map()`]: ../syscalls/vmar_map.md
-[`zx_vmar_unmap()`]: ../syscalls/vmar_unmap.md
-[`zx_vmo_create()`]: ../syscalls/vmo_create.md
-[`zx_vmo_get_size()`]: ../syscalls/vmo_get_size.md
-[`zx_vmo_op_range()`]: ../syscalls/vmo_op_range.md
-[`zx_vmo_read()`]: ../syscalls/vmo_read.md
-[`zx_vmo_set_cache_policy()`]: ../syscalls/vmo_set_cache_policy.md
-[`zx_vmo_set_size()`]: ../syscalls/vmo_set_size.md
-[`zx_vmo_write()`]: ../syscalls/vmo_write.md
diff --git a/docs/oom.md b/docs/oom.md
deleted file mode 100644
index c8ad614..0000000
--- a/docs/oom.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Out-of-memory (OOM) system
-
-This file contains information about the systems that watch for and respond to
-out-of-memory (OOM) events.
-
-[TOC]
-
-## Behavior
-
-When the system runs out of memory and the kernel OOM thread is running, you
-should see a series of log messages like:
-
-```
-OOM: 5915.8M free (+0B) / 8072.4M total
-OOM: oom_lowmem(shortfall_bytes=524288) called
-OOM: Process mapped committed bytes:
-OOM:   proc  1043  397M 'bin/devmgr'
-OOM:   proc  2107   88M 'devhost:pci#1:8086:1916'
-OOM:   proc  1297   12M 'virtual-console'
-OOM:   proc  3496   17M 'netstack'
-OOM:   proc  4157  170M 'flutter:userpicker_device_shell'
-OOM:   proc 28708  353M 'flutter:armadillo_user_... (+3)'
-OOM:   proc 31584    9M 'dart:weather_agent'
-OOM:   proc 32093   14M 'dart:mi_dashboard.dartx'
-OOM: Finding a job to kill...
-OOM:   (skip) job  57930 'story-8cf82cb9f742d9ecc77f1d449'
-OOM:   (skip) job  37434 'story-10293ae401bc0358b3ce52d2a'
-OOM:   *KILL* job  29254 'agent'
-OOM:        + proc 32093  run 'dart:mi_dashboard.dartx'
-OOM:        = 1 running procs (1 total), 0 jobs
-OOM:   (next) job  29247 'agent'
-OOM:   (next) job  29240 'agent'
-OOM:   (next) job  29233 'agent'
-```
-
-The first line shows the current state of system memory:
-
-```
-OOM: 45.8M free (-12.4M) / 8072.4M total
-```
-
-The next section prints a list of processes that are consuming large amounts of
-memory, in no particular order:
-
-```
-OOM: Process mapped committed bytes:
-OOM:   proc  1043  397M 'bin/devmgr'
-OOM:   proc  2107   88M 'devhost:pci#1:8086:1916'
-OOM:   proc  1297   12M 'virtual-console'
-OOM:   ...
-             ^koid  ^mem
-```
-
-The next section shows the walk through the ranked job list, printing skipped
-jobs (which don't have killable process descendants), the job that will be
-killed, and the next jobs on the chopping block:
-
-```
-OOM: Finding a job to kill...
-OOM:   (skip) job  57930 'story-8cf82cb9f742d9ecc77f1d449'
-OOM:   (skip) job  37434 'story-10293ae401bc0358b3ce52d2a'
-OOM:   *KILL* job  29254 'agent'
-OOM:        + proc 32093  run 'dart:mi_dashboard.dartx'
-OOM:        = 1 running procs (1 total), 0 jobs
-OOM:   (next) job  29247 'agent'
-OOM:   (next) job  29240 'agent'
-OOM:   (next) job  29233 'agent'
-
-                   ^koid ^name
-```
-
-The `*KILL*` entry will also show all process descendants of the to-be-killed
-job.
-
-## Components
-
-### Kernel OOM thread
-
-A kernel thread that periodically checks the amount of free memory in the
-system, and kills a job if the free amount is too low (below the "redline").
-
-Use `k oom info` to see the state of the OOM thread (on the kernel console):
-
-```
-$ k oom info
-OOM info:
-  running: true
-  printing: false
-  simulating lowmem: false
-  sleep duration: 1000ms
-  redline: 50M (52428800 bytes)
-```
-
-The redline, sleep duration, and auto-start values are controlled by
-`kernel.oom.*` [kernel commandline flags](kernel_cmdline.md).
-
-The thread can be started with `k oom start` and stopped with `k oom stop`.
-
-`k oom print` will toggle a flag that prints the current free and total memory
-every time the thread wakes up.
-
-`k oom lowmem` will trigger a false low-memory event the next time the thread
-wakes up, potentially killing a job.
-
-### OOM-ranker driver
-
-TODO(dbort/maniscalco): Implement and document.
diff --git a/docs/program_loading.md b/docs/program_loading.md
deleted file mode 100644
index b39bcc4..0000000
--- a/docs/program_loading.md
+++ /dev/null
@@ -1,416 +0,0 @@
-# Zircon program loading and dynamic linking
-
-In Zircon, the kernel is not directly involved in normal program loading.
-(The one necessary exception is bootstrapping the userspace environment at
-system startup; see [`userboot`](userboot.md).)  Instead, the kernel merely
-provides the building blocks
-([VMO](objects/vm_object.md), [process](objects/process.md),
-[VMAR](objects/vm_address_region.md), [thread](objects/thread.md)) from
-which userspace program loading is built.
-
-[TOC]
-
-## ELF and the system ABI
-
-The standard Zircon userspace environment uses
-the [ELF](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format)
-format for machine-code executable files, and provides a dynamic linker and
-C/C++ execution environment that are based on ELF.  Zircon processes can
-use [system calls](syscalls.md) only via the [vDSO](vdso.md), which is
-provided by the kernel in ELF format and uses the C/C++ calling conventions
-common to ELF-based systems for the machine.  Userspace code (given the
-appropriate capabilities) can use the [system call](syscalls.md) building
-blocks directly to create processes and load programs into them without
-using ELF.  But Zircon's standard ABI for machine code uses ELF as
-described here.
-
-## Background: traditional ELF program loading
-
-[ELF](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) was
-introduced with Unix System V Release 4 and became the common standard
-executable file format for most Unix-like systems, today including Linux and
-all the BSD variants as well as Solaris and many others.  In these systems,
-the kernel integrates program loading with filesystem access via the POSIX
-`execve` API.  There are some variations in how they load ELF programs, but
-most follow a pattern close to this:
-
- 1. The kernel loads the file by name, and checks whether it's ELF or some
-    other kind of file that system supports.  This is where `#!` script
-    handling is done, as well non-ELF format support when present.
- 2. The kernel maps the ELF image according to its `PT_LOAD` program
-    headers.  For an `ET_EXEC` file, this places the program's segments at
-    fixed addresses in memory specified in `p_vaddr`.  For an `ET_DYN`
-    file, the system chooses the base address where the program's first
-    `PT_LOAD` gets loaded, and following segments are placed according to
-    their `p_vaddr` relative to the first segment's `p_vaddr`.  Usually the
-    base address is chosen randomly (ASLR).
- 3. If there was a `PT_INTERP` program header, its contents (a range of
-    bytes in the ELF file given by `p_offset` and `p_filesz`) is looked up
-    as a file name to find another ELF file called the *ELF interpreter*.
-    This must be an `ET_DYN` file; the kernel loads it in the same way as it
-    loaded the executable, but always at a location of its own choosing.
-    The interpreter program is usually the ELF dynamic linker with a name
-    like `/lib/ld.so.1` or `/lib/ld-linux.so.2`, but the kernel loads
-    whatever file is named.
- 4. The kernel sets up the stack and registers for the initial thread, and
-    starts the thread running with the PC at the chosen entry point address.
-
-     * The entry point is the `e_entry` value from the ELF file header,
-       adjusted by base address.  When there was a `PT_INTERP`, the entry
-       point is that of the interepreter rather than the main executable.
-     * There is an assembly-level protocol of register and stack contents
-       that the kernel sets up for the program to receive its argument and
-       environment strings and an *auxiliary vector* of useful values.  When
-       there was a `PT_INTERP`, these include the base address, entry point,
-       and program header table address from the main executable's ELF
-       headers.  This information allows the dynamic linker to find the main
-       executable's ELF dynamic linking metadata in memory and do its work.
-       When dynamic linking startup is complete, the dynamic linker jumps to
-       the main executable's entry point address.
-
-Zircon program loading is inspired by this tradition, but does it somewhat
-differently.  A key reason for the traditional pattern of loading the
-executable before loading the dynamic linker is that the dynamic linker's
-randomly-chosen base address must not intersect with the fixed addresses
-used by an `ET_EXEC` executable file.  Zircon does not support
-fixed-address program loading (ELF `ET_EXEC` files) at all, only
-position-independent executables or *PIE*s, which are ELF `ET_DYN` files.
-
-## The **launchpad** library
-
-The main implementation of program loading resides in
-the [`launchpad` library](../system/ulib/launchpad/).  It has a C API
-in
-[`<launchpad/launchpad.h>`](../system/ulib/launchpad/include/launchpad/launchpad.h) but
-is not formally documented.  The `launchpad` API is not described here.  Its
-treatment of executable files and process startup forms the Zircon system
-ABI for program loading.
-The [lowest userspace layers of the system](userboot.md) implement the same
-protocols.  It's anticipated that in the future most process launching in
-the system will be done by a system service that uses `launchpad` in its
-implementation, rather than by direct use of the library.
-
-Filesystems are not part of the lower layers of Zircon API.  Instead,
-program loading is based on [VMOs](objects/vm_object.md) and on IPC
-protocols used via [channels](objects/channel.md).
-
-A program loading request starts with:
-
- * a handle to a VMO containing the executable file (`ZX_RIGHT_READ` and
-   `ZX_RIGHT_EXECUTE` rights are required)
- * a list of argument strings (to become `argv[]` in a C/C++ program)
- * a list of environment strings (to become `environ[]` in a C/C++ program)
- * a list of initial [handles](handles.md), each with
-   a [*handle info entry*](#handle-info-entry)
-
-Three types of file are handled:
-
-{#hashbang}
-* a script file starting with `#!`
-
-  The first line of the file starts with `#!` and must be no more than 127
-  characters long.  The first non-whitespace word following `#!` is the
-  *script interpreter name*.  If there's anything after that, it all
-  together becomes the *script interpreter argument*.
-
-   * The script interpreter name is prepended to the original argument
-     list (to become `argv[0]`).
-   * If there was a script interpreter argument, it's inserted between the
-     interpreter name and the original argument list (to become `argv[1]`,
-     with the original `argv[0]` becoming `argv[2]`).
-   * The program loader looks up the script interpreter name via
-     the [loader service](#the-loader-service) to get a new VMO.
-   * Program loading restarts on that script interpreter VMO with the
-     modified argument list but everything else the same.  The VMO handle
-     for the original executable is just closed; the script interpreter only
-     gets the original `argv[0]` string to work with, not the original VMO.
-     There is a maximum nesting limit (currently 5) constraining how many
-     such restarts will be allowed before program loading just fails.
-
-* an ELF `ET_DYN` file with no `PT_INTERP`
-
-  * The system chooses a random base address for the first `PT_LOAD` segment
-    and then maps in each `PT_LOAD` segment relative to that base address.
-    This is done by creating a [VMAR](objects/vm_address_region.md) covering
-    the whole range from the first page of the first segment to the last
-    page of the last segment.
-  * A VMO is created and mapped at another random address to hold the stack
-    for the initial thread.  If there was a `PT_GNU_STACK` program header
-    with a nonzero `p_memsz`, that determines the size of the stack (rounded
-    up to whole pages).  Otherwise, a reasonable default stack size is used.
-  * The [vDSO](vdso.md) is mapped into the process
-    (another VMO containing an ELF image), also at a random base address.
-  * A new thread is created in the process with [**thread_create**()](syscalls/thread_create.md).
-  * A new [channel](objects/channel.md) is created, called the *bootstrap
-    channel*.  The program loader writes into this channel a message
-    in [the `processargs` protocol](#the-processargs-protocol) format. This
-    *bootstrap message* includes the argument and environment strings and
-    the initial handles from the original request.  That list is augmented
-    with handles for:
-
-     * the new [process](objects/process.md) itself
-     * its root [VMAR](objects/vm_address_region.md)
-     * its initial [thread](objects/thread.md)
-     * the VMAR covering where the executable was loaded
-     * the VMO just created for the stack
-     * optionally, a default [job](objects/job.md) so the new
-       process itself can create more processes
-     * optionally, the vDSO VMO so the new process can let the processes
-       it creates make system calls themselves
-
-    The program loader then closes its end of the channel.
-   * The initial thread is launched with
-     the [**process_start**() system call](syscalls/process_start.md):
-
-      * `entry` sets the new thread's PC to `e_entry` from the executable's
-        ELF header, adjusted by base address.
-      * `stack` sets the new thread's stack pointer to the top of the
-        stack mapping.
-      * `arg1` transfers the handle to the *bootstrap channel* into the
-        first argument register in the C ABI.
-      * `arg2` passes the base address of the vDSO into the second argument
-        register in the C ABI.
-
-     Thus, the program entry point can be written as a C function:
-     ```c
-     noreturn void _start(zx_handle_t bootstrap_channel, uintptr_t vdso_base);
-     ```
-
-{#PT_INTERP}
-* an ELF `ET_DYN` file with a `PT_INTERP`
-
-  In this case, the program loader does not directly use the VMO containing
-  the ELF executable after reading its `PT_INTERP` header.  Instead, it
-  uses the `PT_INTERP` contents as the name of an *ELF interpreter*.  This
-  name is used in a request to the [loader service](#the-loader-service) to
-  get a new VMO containing the ELF interpreter, which is another ELF
-  `ET_DYN` file.  Then that VMO is loaded instead of the main executable's
-  VMO.  Startup is as described above, with these differences:
-
-   * An extra message
-     in [the `processargs` protocol](#the-processargs-protocol) is written
-     to the *bootstrap channel*, preceding the main bootstrap message.  The
-     ELF interpreter is expected to consume this *loader bootstrap message*
-     itself so that it can do its work, but then leave the second bootstrap
-     message in the channel and hand off the bootstrap channel handle to
-     the main program's entry point.  The *loader bootstrap message*
-     includes only the necessary handles added by the program loader, not
-     the full set that go into the main *bootstrap message*, plus these:
-
-      * the original VMO handle for main ELF executable
-      * a channel handle to the [loader service](#the-loader-service)
-
-     These allow the ELF interpreter to do its own loading of the
-     executable from the VMO and to use the loader service to get
-     additional VMOs for shared libraries to load.  The message also
-     includes the argument and environment strings, which lets the ELF
-     interpreter use `argv[0]` in its log messages, and check for
-     environment variables like `LD_DEBUG`.
-
-   * `PT_GNU_STACK` program headers are ignored.  Instead, the program
-     loader chooses a minimal stack size that is just large enough to
-     contain the *loader bootstrap message* plus some breathing room for
-     the ELF interpreter's startup code to use as call frames.  This
-     "breathing room" size is `PTHREAD_STACK_MIN` in the source, and is
-     tuned such that with a small bootstrap message size the whole stack is
-     only a single page, but a careful dynamic linker implementation has
-     enough space to work in.  The dynamic linker is expected to read the
-     main executable's `PT_GNU_STACK` and switch to a stack of reasonable
-     size for normal use before it jumps to the main executable's entry
-     point.
-
-*** aside
-
-The program loader chooses three randomly-placed chunks of the new
-process's address space before the program (or dynamic linker) gets
-control: the vDSO, the stack, and the dynamic linker itself.  To make it
-possible for the program's own startup to control its address space more
-fully, the program loader currently ensures that these random placements
-are always somewhere in the **upper half of the address space**.  This is
-for the convenience of sanitizer runtimes, which need to reserve some lower
-fraction of the address space.  This behavior will change in the future so
-there is some way to support the sanitizer cases but other processes will
-get fully random placement to maximize the benefits of ASLR.
-
-***
-
-## The **processargs** protocol
-
-[`<zircon/processargs.h>`](../system/public/zircon/processargs.h) defines
-the protocol for the *bootstrap message* sent on the *bootstrap channel* by
-the program loader.  When a process starts up, it has a handle to this
-bootstrap channel and it has access to [system calls](syscalls.md) via
-the [vDSO](vdso.md).  The process has only this one handle and so it can
-see only global system information and its own memory until it gets more
-information and handles via the bootstrap channel.
-
-The `processargs` protocol is a one-way protocol for messages sent on the
-bootstrap channel.  The new process is never expected to write back onto
-the channel.  The program loader usually sends its messages and then closes
-its end of the channel before the new process has even started.  These
-messages must communicate everything a new process will ever need, but the
-code that receives and decodes messages in this format must run in a very
-constrained environment.  Heap allocation is impossible and nontrivial
-library facilities may not be available.
-
-See the [header file](../system/public/zircon/processargs.h) for full
-details of the message format.  It's anticipated that this ad hoc protocol
-will be replaced with a formal IDL-based protocol eventually, but the
-format will be kept simple enough to be decoded by simple hand-written
-code.
-
-A bootstrap message conveys:
-
- * a list of initial [handles](handles.md)
- * a 32-bit *handle info entry* corresponding to each handle
- * a list of name strings that a *handle info entry* can refer to
- * a list of argument strings (to become `argv[]` in a C/C++ program)
- * a list of environment strings (to become `environ[]` in a C/C++ program)
-
-{#handle-info-entry}
-The handles serve many purposes, indicated by the *handle info entry* type:
-
- * essential handles for the process to make [system calls](syscalls.md):
-   [process](objects/process.md), [VMAR](objects/vm_address_region.md),
-   [thread](objects/thread.md), [job](objects/job.md)
- * [channel](objects/channel.md) to the [loader service](#the-loader-service)
- * [vDSO](vdso.md) [VMO](objects/vm_object.md)
- * filesystem-related handles: current directory, file descriptors, name
-   space bindings (these encode an index into the list of name strings)
- * special handles for system processes:
-   [resource](objects/resource.md), [VMO](objects/vm_object.md)
- * other types used for higher-layer or private protocol purposes
-
-Most of these are just passed through by the program loader,
-which does not need to know what they're for.
-
-## The **loader service**
-
-In dynamic linking systems, an executable file refers to and uses at
-runtime additional files containing shared libraries and plugins.  The
-dynamic linker is loaded as an [*ELF interpreter*](#PT_INTERP) and is
-responsible getting access to all these additional files to complete
-dynamic linking before the main program's entry point gets control.
-
-All of Zircon's standard userspace uses dynamic linking, down to the very
-first process loaded by [`userboot`](userboot.md).  Device drivers and
-filesystems are implemented by userspace programs loaded this way.  So
-program loading cannot be defined in terms of higher-layer abstractions
-such as a filesystem paradigm,
-as
-[traditional systems have done](#background_traditional-elf-program-loading).
-Instead, program loading is based only on [VMOs](objects/vm_object.md) and
-a simple [channel](objects/channel.md)-based protocol.
-
-This *loader service* protocol is how a dynamic linker acquires VMOs
-representing the additional files it needs to load as shared libraries.
-
-This is a simple RPC protocol, defined in
-[`<zircon/processargs.h>`](../system/public/zircon/processargs.h).
-As with [the `processargs` protocol](#the-processargs-protocol),
-it's anticipated that this ad hoc protocol will be replaced with a formal
-IDL-based protocol eventually, but the format will be kept simple enough to
-be decoded by simple hand-written code.  The code sending loader service
-requests and receiving their replies during dynamic linker startup may
-not have access to nontrivial library facilities.
-
-An ELF interpreter receives a channel handle for its loader service in its
-`processargs` bootstrap message, identified by the *handle info entry*
-`PA_HND(PA_LDSVC_LOADER, 0)`.  All requests are synchronous RPCs made
-with [**channel_call**()](syscalls/channel_call.md).  Both requests and
-replies start with the `zx_loader_svc_msg_t` header; some contain
-additional data; some contain a VMO handle.  Request opcodes are:
-
- * `LOADER_SVC_OP_LOAD_SCRIPT_INTERP`: *string* -> *VMO handle*
-
-   The program loader sends the *script interpreter name* from
-   a [`#!` script](#hashbang) and gets back a VMO to execute in place of
-   the script.
-
- * `LOADER_SVC_OP_LOAD_OBJECT`: *string* -> *VMO handle*
-
-   The dynamic linker sends the name of an *object* (shared library or
-   plugin) and gets back a VMO handle containing the file.
-
- * `LOADER_SVC_OP_CONFIG` : *string* -> `reply ignored`
-
-   The dynamic linker sends a string identifying its *load configuration*.
-   This is intended to affect how later `LOADER_SVC_OP_LOAD_OBJECT`
-   requests decide what particular implementation file to supply for a
-   given name.
-
- * `LOADER_SVC_OP_DEBUG_PRINT`: *string* -> `reply ignored`
-
-   This is a simple ad hoc logging facility intended for debugging the
-   dynamic linker and early program startup issues.  It's convenient
-   because the early startup code is using the loader service but doesn't
-   have access to many other handles or complex facilities yet.  This will
-   be replaced in the future with some simple-to-use logging facility that
-   does not go through the loader service.
-
- * `LOADER_SVC_OP_LOAD_DEBUG_CONFIG`: *string* -> *VMO handle*
-
-   **This is intended to be a developer-oriented feature and might not
-   ordinarily be available in production runs.**
-
-   The program runtime sends a string naming a *debug configuration* of
-   some kind and gets back a VMO to read configuration data from.  The
-   sanitizer runtimes use this to allow large options text to be stored in
-   a file rather than passed directly in environment strings.
-
- * `LOADER_SVC_OP_PUBLISH_DATA_SINK`: *string*, *VMO handle* -> `reply ignored`
-
-   **This is intended to be a developer-oriented feature and might not
-   ordinarily be available in production runs.**
-
-   The program runtime sends a string naming a *data sink* and transfers
-   the sole handle to a VMO it wants published there.  The *data sink*
-   string identifies a type of data, and the VMO's object name can
-   specifically identify the data set in this VMO.  The client must
-   transfer the only handle to the VMO (which prevents the VMO being
-   resized without the receiver's knowledge), but it might still have the
-   VMO mapped in and continue to write data to it.  Code instrumentation
-   runtimes use this to deliver large binary trace results.
-
-## Zircon's standard ELF dynamic linker
-
-The ELF conventions described above and
-the [`processargs`](#the-processargs-protocol)
-and [loader service](#the-loader-service) protocols are the permanent
-system ABI for program loading.  Programs can use any implementation of a
-machine code executable that meets the basic ELF format conventions.  The
-implementation can use the [vDSO](vdso.md) [system call](syscalls.md)
-ABI, the `processargs` data, and the loader service facilities as it sees
-fit.  The exact details of what handles and data they will receive via
-these protocols depend on the higher-layer program environment.  Zircon's
-system processes use an ELF interpreter that implements basic ELF dynamic
-linking, and a simple implementation of the loader service.
-
-Zircon's standard C library and dynamic linker have
-a [unified implementation](../third_party/ulib/musl/) originally derived
-from [`musl`](http://www.musl-libc.org/).  It's identified by the
-`PT_INTERP` string `ld.so.1`.  It uses the `DT_NEEDED` strings naming
-shared libraries as [loader service](#the-loader-service) *object* names.
-
-The simple loader service maps requests into filesystem access:
- * *script interpreter* and *debug configuration* names must start with `/`
-   and are used as absolute file names.
- * *data sink* names become subdirectories in `/tmp`, and each VMO
-   published becomes a file in that subdirectory with the VMO's object name
- * *object* names are searched for as files in system `lib/` directories.
- * *load configuration* strings are taken as a subdirectory name,
-   optionally preceded by a `!` character.  Subdirectories by that name in
-   system `lib/` directories searched are searched before `lib/` itself.
-   If there was a `!` prefix, *only* those subdirectories are searched.
-   For example, sanitizer runtimes use `asan` because that instrumentation
-   is compatible with uninstrumented library code, but `!dfsan` because
-   that instrumentation requires that all code in the process be
-   instrumented.
-
-A version of the standard runtime instrumented with
-LLVM [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
-is identified by the `PT_INTERP` string `asan/ld.so.1`.  This version sends
-the *load configuration* string `asan` before loading shared libraries.
-When [SanitizerCoverage](https://clang.llvm.org/docs/SanitizerCoverage.html)
-is enabled, it publishes a VMO to the *data sink* name `sancov` and uses a
-VMO name including the process KOID.
diff --git a/docs/qemu.md b/docs/qemu.md
deleted file mode 100644
index f835855..0000000
--- a/docs/qemu.md
+++ /dev/null
@@ -1,275 +0,0 @@
-# QEMU
-
-Zircon can [run under
-emulation](https://fuchsia.googlesource.com/docs/+/master/getting_started.md#Boot-from-QEMU)
-using QEMU. QEMU can either be installed via prebuilt binaries, or built
-locally.
-
-## Install Prebuilt QEMU
-
-QEMU is downloaded by the script that is used to download all Zircon
-prebuilts, including toolchains:
-
-```
-./scripts/download-prebuilt
-```
-
-This will download QEMU to the `prebuilt/downloads/qemu` directory. You
-can either add `prebuilt/downloads/qemu/bin` to your PATH, or specify
-`prebuilt/downloads/qemu/bin` using the -q flag to the run-zircon scripts
-(see below).
-
-## Build QEMU
-
-### Install Prerequisites
-
-Building QEMU on macOS requires a few packages. As of macOS 10.12.1:
-
-```
-# Using http://brew.sh
-brew install pkg-config glib automake libtool
-
-# Or use http://macports.org ("port install ...") or build manually
-```
-
-### Build
-
-```
-cd $SRC
-git clone --recursive https://fuchsia.googlesource.com/third_party/qemu
-cd qemu
-./configure --target-list=aarch64-softmmu,x86_64-softmmu
-make -j32
-sudo make install
-```
-
-If you don't want to install in /usr/local (the default), which will require you
-to be root, add --prefix=/path/to/install (perhaps $HOME/qemu). Then you'll
-either need to add /path/to/install/bin to your PATH or use -q /path/to/install
-when invoking run-zircon-{arch}.
-
-## Run Zircon under QEMU
-
-```
-# for aarch64
-./scripts/run-zircon-arm64
-
-# for x86
-./scripts/run-zircon-x64
-```
-
-If QEMU is not on your path, use -q <directory> to specify its location.
-
-The -h flag will list a number of options, including things like -b to rebuild
-first if necessary and -g to run with a graphical framebuffer.
-
-To exit qemu, enter Ctrl-a x. Use Ctrl-a h to see other commands.
-
-## Enabling Networking under QEMU
-
-The run-zircon script, when given the -N argument will attempt to create
-a network interface using the Linux tun/tap network device named "qemu".  QEMU
-does not need to be run with any special privileges for this, but you need to
-create a persistent tun/tap device ahead of time (which does require you be root):
-
-On Linux:
-
-```
-sudo apt-get install uml-utilities
-sudo tunctl -u $USER -t qemu
-sudo ifconfig qemu up
-```
-
-This is sufficient to enable link local IPv6 (as the loglistener tool uses).
-
-On macOS:
-
-macOS does not support tun/tap devices out of the box; however, there is a widely
-used set of kernel extensions called tuntaposx which can be downloaded
-[here](http://tuntaposx.sourceforge.net/download.xhtml). Once the installer
-completes, the extensions will create up to 16 tun/tap devices. The
-run-zircon-x64 script uses /dev/tap0.
-
-```
-sudo chown $USER /dev/tap0
-
-# Run zircon in QEMU, which will open /dev/tap0
-./scripts/run-zircon-x86 -N
-
-# (In a different window) bring up tap0 with a link local IPv6 address
-sudo ifconfig tap0 inet6 fc00::/7 up
-```
-
-**NOTE**: One caveat with tuntaposx is that the network interface will
-automatically go down when QEMU exits and closes the network device. So the
-network interface needs to be brought back up each time QEMU is restarted. To
-automate this, you can use the -u flag to run a script on qemu startup. An
-example startup script containing the above command is located in
-scripts/qemu-ifup-macos, so QEMU can be started with:
-
-```
-./scripts/run-zircon-x64 -Nu ./scripts/qemu-ifup-macos
-```
-
-## Using Emulated Disk under QEMU
-
-Please follow the minfs instructions on how to create a disk image
-[here][minfs-create-image].
-
-After creating the image, you can run zircon in QEMU with the disk image:
-```
-./scripts/run-zircon-x64 -d [-D <disk_image_path (default: "blk.bin")>]
-```
-
-
-## Debugging the kernel with GDB
-
-### Sample session
-
-Here is a sample session to get you started.
-
-In the shell you're running QEMU in:
-
-```
-shell1$ ./scripts/run-zircon-x64 -- -s -S
-[... some QEMU start up text ...]
-```
-
-This will start QEMU but freeze the system at startup,
-waiting for you to resume it with "continue" in GDB.
-If you want to run QEMU without GDB, but be able to attach with GDB later
-then start QEMU without "-S" in the above example:
-
-```
-shell1$ ./scripts/run-zircon-x64 -- -s
-[... some QEMU start up text ...]
-```
-
-And then in the shell you're running GDB in:
-[Commands here are fully spelled out, but remember most can be abbreviated.]
-
-```
-shell2$ gdb build-x86/zircon.elf
-(gdb) target extended-remote :1234
-Remote debugging using :1234
-0x000000000000fff0 in ?? ()
-(gdb) # Don't try to do too much at this point.
-(gdb) # GDB can't handle architecture switching in one session,
-(gdb) # and at this point the architecture is 16-bit x86.
-(gdb) break lk_main
-Breakpoint 1 at 0xffffffff8010cb58: file kernel/top/main.c, line 59.
-(gdb) continue
-Continuing.
-
-Breakpoint 1, lk_main (arg0=1, arg1=18446744071568293116, arg2=0, arg3=0)
-    at kernel/top/main.c:59
-59	{
-(gdb) continue
-```
-
-At this point Zircon boots and back in shell1 you'll be at the Zircon
-prompt.
-
-```
-mxsh>
-```
-
-If you Ctrl-C in shell2 at this point you can get back to GDB.
-
-```
-(gdb) # Having just done "continue"
-^C
-Program received signal SIGINT, Interrupt.
-arch_idle () at kernel/arch/x86/64/ops.S:32
-32	    ret
-(gdb) info threads
-  Id   Target Id         Frame
-  4    Thread 4 (CPU#3 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
-  3    Thread 3 (CPU#2 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
-  2    Thread 2 (CPU#1 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
-* 1    Thread 1 (CPU#0 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32
-```
-
-QEMU reports one thread to GDB for each CPU.
-
-### The zircon.elf-gdb.py script
-
-The scripts/zircon.elf-gdb.py script is automagically loaded by gdb.
-It provides several things:
-
-- Pretty-printers for zircon objects (alas none at the moment).
-
-- Several zircon specific commands, all with a "zircon" prefix. To see them:
-```
-(gdb) help info zircon
-(gdb) help set zircon
-(gdb) help show zircon
-```
-
-- Enhanced unwinder support for automagic unwinding through kernel faults.
-
-Heads up: This script isn't always updated as zircon changes.
-
-### Terminating the session
-
-To terminate QEMU you can send commands to QEMU from GDB:
-
-```
-(gdb) monitor quit
-(gdb) quit
-```
-
-### Interacting with QEMU from Gdb
-
-To see the list of QEMU commands you can execute from GDB:
-
-```
-(gdb) monitor help
-```
-
-### Saving system state for debugging
-
-If you have a crash that is difficult to debug, or that you need help
-with debugging, it's possible to save system state akin to a core dump.
-
-```
-bash$ qemu-img create -f qcow2 /tmp/my_snapshots.qcow2 32M
-```
-
-will create a "32M" block storage device.  Next launch QEMU and tell it
-about the device, but don't tell it to attach the device to the guest system.
-This is OK; we don't plan on using it to back up the disk state, we just want
-a core dump.  Note: all of this can be skipped if you are already emulating
-a block device and it is using the qcow2 format.
-
-```
-bash$ qemu <normal_launch_args> -drive if=none,format=qcow2,file=/tmp/my_snapshots.qcow2
-```
-
-When you get to a point where you want to save the core state, drop to the QEMU
-console using <C-a><C-c>.  You should get the (qemu) prompt at this point.
-From here, just say:
-
-```
-(qemu) savevm my_backup_tag_name
-```
-
-Later on, from an identical machine (one launched with the same args as before),
-you can drop to the console and run:
-
-```
-(qemu) loadvm my_backup_tag_name
-```
-
-to restore the state.  Alternatively, you can do it from the cmd line with:
-
-```
-bash$ qemu <normal_launch_args> -drive if=none,format=qcow2,file=/tmp/my_snapshots.qcow2 -loadvm my_backup_tag_name
-```
-
-In theory, you could package up the qcow2 image along with your build output
-directory and anyone should be able to restore your state and start to poke
-at stuff from the QEMU console.
-
-
-[minfs-create-image]: https://fuchsia.googlesource.com/zircon/+/master/docs/minfs.md#Host-Device-QEMU-Only
diff --git a/docs/rights.md b/docs/rights.md
deleted file mode 100644
index bfc79ff..0000000
--- a/docs/rights.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Rights
-
-## Basics
-
-Rights are associated with handles and convey privileges to perform actions on
-either the associated handle or the object associated with the handle.
-
-The [`<zircon/rights.h>`](../system/public/zircon/rights.h) header defines
-default rights for each object type, which can be reduced via
-`zx_handle_replace()` or `zx_handle_duplicate()`.
-
-| Right | Conferred Privileges |
-| ----- | -------------------- |
-| **ZX_RIGHT_DUPLICATE**      | Allows handle duplication via [*zx_handle_duplicate*](syscalls/handle_duplicate.md) |
-| **ZX_RIGHT_TRANSFER**       | Allows handle transfer via [*zx_channel_write*](syscalls/channel_write.md) |
-| **ZX_RIGHT_READ**           | **TO BE REMOVED** Allows inspection of object state |
-|                             | Allows reading of data from containers (channels, sockets, VM objects, etc) |
-|                             | Allows mapping as readable if **ZX_RIGHT_MAP** is also present |
-| **ZX_RIGHT_WRITE**          | **TO BE REMOVED** Allows modification of object state |
-|                             | Allows writing of data to containers (channels, sockets, VM objects, etc) |
-|                             | Allows mapping as writeable if **ZX_RIGHT_MAP** is also present |
-| **ZX_RIGHT_EXECUTE**        | Allows mapping as executable if **ZX_RIGHT_MAP** is also present |
-| **ZX_RIGHT_MAP**            | Allows mapping of a VM object into an address space. |
-| **ZX_RIGHT_GET_PROPERTY**   | Allows property inspection via [*zx_object_get_property*](syscalls/object_get_property.md) |
-| **ZX_RIGHT_SET_PROPERTY**   | Allows property modification via [*zx_object_set_property*](syscalls/object_set_property.md) |
-| **ZX_RIGHT_ENUMERATE**      | Allows enumerating child objects via [*zx_object_get_info*](syscalls/object_get_info.md) and [*zx_object_get_child*](syscalls/object_get_child.md) |
-| **ZX_RIGHT_DESTROY**        | Allows termination of task objects via [*zx_task_kill*](syscalls/task_kill.md)|
-| **ZX_RIGHT_SET_POLICY**     | Allows policy modification via [*zx_job_set_policy*](syscalls/job_set_policy.md)|
-| **ZX_RIGHT_GET_POLICY**     | Allows policy inspection via [*zx_job_get_policy*](syscalls/job_get_policy.md)|
-| **ZX_RIGHT_SIGNAL**         | Allows use of [*zx_object_signal*](syscalls/object_signal.md) |
-| **ZX_RIGHT_SIGNAL_PEER**    | Allows use of [*zx_object_signal_peer*](syscalls/object_signal.md) |
-| **ZX_RIGHT_WAIT**           | Allows use of [*zx_object_wait_one*](syscalls/object_wait_one.md), [*zx_object_wait_many*](syscalls/object_wait_many.md), and other waiting primitives |
-| **ZX_RIGHT_INSPECT**        | Allows inspection via [*zx_object_get_info*](syscalls/object_get_info.md) |
-| **ZX_RIGHT_MANAGE_JOB**     | **NOT YET IMPLEMENTED** Allows creation of processes, subjobs, etc. |
-| **ZX_RIGHT_MANAGE_PROCESS** | **NOT YET IMPLEMENTED** Allows creation of threads, etc |
-| **ZX_RIGHT_MANAGE_THREAD**  | **NOT YET IMPLEMENTED** Allows suspending/resuming threads, etc|
-
-## ZX_RIGHTS_BASIC
-
-The basic rights allow primitive manipulation of handles and are common to the
-majority of handle types by default. These are *ZX_RIGHT_DUPLICATE*,
-*ZX_RIGHT_TRANSFER*, *ZX_RIGHT_WAIT*, and *ZX_RIGHT_INSPECT*.
-
-These four rights are referred to as *ZX_RIGHTS_BASIC* when used together.
-
-## See also
-[Objects](objects.md),
-[Handles](handles.md)
diff --git a/docs/safestack.md b/docs/safestack.md
deleted file mode 100644
index b6ba688..0000000
--- a/docs/safestack.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# SafeStack in Zircon & Fuchsia
-
-## Introduction
-
-LLVM's [safe-stack feature](https://clang.llvm.org/docs/SafeStack.html)
-is a compiler mode intended to harden the generated code against
-stack-smashing attacks such as exploits of buffer overrun bugs.
-
-The Clang/LLVM documentation page linked above describes the general
-scheme.  The capsule summary is that that each thread has two stacks
-instead of the usual one: a "safe stack" and an "unsafe stack".  The
-unsafe stack is used for all purposes where a pointer into the stack
-memory might be used, while the safe stack is used only for purposes
-where no code should ever see a pointer into the stack memory.  So, the
-unsafe stack is used for arrays or variables that are passed by
-reference to another function or have their addresses stored in the
-heap--memory that could be subject to buffer overrun or use-after-free
-bugs and their exploits.  The safe stack is used for the compiler's
-register spills, and for the return address of a function call.  Thus,
-for example, a simple buffer overrun bug cannot be exploited to
-overwrite the return address of the containing function, which is the
-basis of exploits and attacks using the so-called *ROP*
-("return-oriented programming") technique.
-
-The **Compatibility** section of that page does not apply to Zircon (or
-Fuchsia).  In Zircon user-mode code (including all of Fuchsia), the
-runtime support for SafeStack is included directly in the standard C
-runtime library, and everything works fine in shared libraries (DSOs).
-
-## Interoperation and ABI Effects
-
-In general, safe-stack does not affect the ABI.  The machine-specific
-calling conventions are unchanged.  It works fine to have some
-functions in a program built with safe-stack and some not.  It doesn't
-matter if combining the two comes from directly compiled `.o` files,
-from archive libraries (`.a` files), or from shared libraries (`.so`
-files), in any combination.
-
-While there is some additional per-thread state (the *unsafe stack
-pointer*, see below under *Implementation details*), code not using
-safe-stack does not need to do anything about this state to keep it
-correct when calling, or being called by, code that does use
-safe-stack.  The only potential exceptions to this are for code that
-is implementing its own kinds of non-local exits or context-switching
-(e.g. coroutines).  The Zircon C library's `setjmp`/`longjmp` code
-saves and restores this additional state automatically, so anything
-that is based on `longjmp` already handles everything correctly even
-if the code calling `setjmp` and `longjmp` doesn't know about
-safe-stack.
-
-## Use in Zircon & Fuchsia
-
-This is enabled in the Clang compiler by the `-fsanitize=safe-stack`
-command-line option.  In the near future, this will be the default mode
-of the compiler for `*-fuchsia` targets, and to disable it for a
-specific compilation will require the `-fno-sanitize=safe-stack` option.
-
-Zircon supports safe-stack for both user-mode and kernel code.
-In the Zircon build, safe-stack is always enabled when building
-with Clang (pass `USE_CLANG=true` to `make`).
-
-## Implementation details
-
-The essential addition to support safe-stack code is the *unsafe stack
-pointer*.  In the abstract, this can be thought of as an additional
-register just like the machine's normal stack pointer register.  The
-machine's stack pointer register is used for the safe stack, just as it
-always has been.  The unsafe stack pointer is used as if it were another
-register with a fixed purpose in the ABI, but of course the machines
-don't actually have a new register, and for compatibility safe-stack
-does not change the basic machine-specific calling conventions that
-assign uses to all the machine registers.
-
-The C and C++ ABI for Zircon and Fuchsia stores the unsafe stack
-pointer in memory that's at a fixed offset from the thread pointer.
-The [`<zircon/tls.h>`](../system/public/zircon/tls.h) header defines
-the offset for each machine.
-
-For x86 user-mode, the thread pointer is the `fsbase`, meaning access
-in assembly code looks like `%fs:ZX_TLS_UNSAFE_SP_OFFSET`.
-For the x86 kernel, the thread pointer is the `gsbase`, meaning access
-in assembly code looks like `%gs:ZX_TLS_UNSAFE_SP_OFFSET`.
-
-For Aarch64 (ARM64), in C or C++ code, `__builtin_thread_pointer()`
-returns the thread pointer.  In user-mode, the thread pointer is in the
-`TPIDR_EL0` special register and must be fetched into a normal register
-(with `mrs *reg*, TPIDR_EL0`) to access the memory, so it's not a single
-instruction in assembly code.  In the kernel, it's just the same but
-using the `TPIDR_EL1` special register instead.
-
-### Notes for low-level and assembly code
-
-Most code, even in assembly, does not need to think about safe-stack
-issues at all.  The calling conventions are not changed.  Using the
-stack for saving registers, finding return addresses, etc. is all the
-same with or without safe-stack.  The main exception is code that is
-implementing something like a non-local exit or context switch.  Such
-code may need to save or restore the unsafe stack pointer.  Both the
-`longjmp` function and C++ `throw` already handle this directly, so
-C or C++ code using those constructs does not need to do anything new.
-
-The context-switch code in the kernel handles switching the unsafe stack
-pointer.  On x86, this is explicit in the code: `%gs` points to the
-`struct x86_percpu`, which has a member `kernel_unsafe_sp` at
-`ZX_TLS_UNSAFE_SP_OFFSET`; `arch_context_switch` copies this into the
-`unsafe_sp` field of the old thread's `struct arch_thread` and then
-copies the new thread's `unsafe_sp` into `kernel_unsafe_sp`.  On ARM64,
-this is implicitly done by `set_current_thread`, because that changes
-the `TPIDR_EL1` special register, which points directly into the
-per-thread `struct thread` rather than a per-CPU structure like on x86.
-
-New code implementing some new kind of non-local exit or context switch
-will need to handle the unsafe stack pointer similarly to how it handles
-the traditional machine stack pointer register.  Any such code should
-use `#if __has_feature(safe_stack)` to test at compile time whether
-safe-stack is being used in the particular build.  That preprocessor
-construct can be used in C, C++, or assembly (`.S`) source files.
diff --git a/docs/self_hosting.md b/docs/self_hosting.md
deleted file mode 100644
index 262fece..0000000
--- a/docs/self_hosting.md
+++ /dev/null
@@ -1,155 +0,0 @@
-# Fuchsia Self-Hosted Build
-## Build Fuchsia Native Tools
-* If not already cloned, check out the `gcc_none_toolchains` repository.
-```bash
-git clone https://fuchsia.googlesource.com/third_party/gcc_none_toolchains
-```
-* Build the Fuchsia-native tools.
-```bash
-cd <gcc_none_toolchains-dir>
-./do-build \
-	--host x86_64-fuchsia \
-	--target x86_64-fuchsia \
-	--sysroot <path-to-target-sysroot> \
-	--strip
-```
-By default, this will leave the compiler in the
-`x86_64-fuchsia-<gcc-ver>-native` subdirectory of the current directory.
-
-## Build Fuchsia-Hosted Bare-Metal Tools
-* In the same `gcc_none_toolchains` repository, build the fuchsia-hosted
-bare-metal tools:
-```bash
-./do-build \
-	--host x86_64-fuchsia \
-	--target x86_64-none \
-	--sysroot <path-to-target-sysroot> \
-	--strip
-```
-By default, this will leave the compiler in the
-`x86_64-elf-<gcc-ver>-Fuchsia-x86_64` subdirectory of the current directory.
-
-## Build GNU make
-* Checkout make sources, if needed:
-```bash
-git clone https://fuchsia.googlesource.com/third_party/make
-```
-
-* Follow the instructions provided in README.md of the GNU make sources
-to build a Fuchsia-hosted version of make.
-
-## Build utilities (Shouldn't be necessary)
-The following utilities are required by the build scripts. As long as your
-build manifest included the sbase project, these should have been installed
-with your Fuchsia build:
-```text
-uname
-which
-tr
-find
-mv
-cmp
-sort
-basename
-sed
-```
-
-## Build Zircon
-Follow standard Zircon/Fuchsia source configuration instructions. Note that
-you will want a minimum of `zircon` and `sbase`.
-
-In order for gcc-built executables to run in Fuchsia, we will need the gcc
-runtime libraries, built for Fuchsia. They were built as part of the Fuchsia
-native build, but we need them to be installed into one of the standard runtime
-library locations on the target. One way to do this is to add the libraries to
-the manifest lines in `zircon/kernel/engine.mk`:
-```code
-USER_MANIFEST_LINES += lib/libgcc_s.so.1=<path-to-gcc>/x86_64-fuchsia-6.3.0-native/lib/libgcc_s.so.1
-USER_MANIFEST_LINES += lib/libgcc_s.so=<path-to-gcc>/x86_64-fuchsia-6.3.0-native/lib/libgcc_s.so
-USER_MANIFEST_LINES += lib/libstdc++.so=<path-to-gcc>/x86_64-fuchsia-6.3.0-native/lib/libstdc++.so
-```
-Follow the standard Zircon/Fuchsia build instructions, and run the resulting
-image on the desired target.
-
-## Copy Files Onto Target
-Create a new empty directory in the target environment (for this example, we'll
-use /data). For your own sanity, this should be persistent storage of some
-sort. For this example, we'll use the following /data subdirectories:
-```text
-bin             Directory for miscellaneous tools not provided in Fuchsia or Zircon
-gcc             Native gcc installation
-gcc-bare-metal  Fuchsia-hosted bare-metal tools
-zircon         The Zircon source files
-sysroot         The sysroot of the installed Fuchsia
-```
-* Netcp all native gcc files into `/data/gcc`
-```bash
-cd <gcc-install-dir>/x86_64-fuchsia-<gcc-ver>-native
-for filename in `find . -type f`
-do
-  echo "Copying $filename"
-  netcp "$filename" ":/data/gcc/$filename"
-done
-```
-* Netcp all bare-metal gcc files into `/data/gcc-bare-metal`
-```bash
-cd <gcc-install-dir>/x86_64-elf-gcc-<gcc-ver>-Fuchsia-x86_64
-for filename in `find . -type f`
-do
-  echo "Copying $filename"
-  netcp "$filename" ":/data/gcc-bare-metal/$filename"
-done
-```
-* Netcp make to `/data/bin`
-```bash
-netcp <make-build-dir>/make :/data/bin
-```
-* Copy the zircon source code onto the target, either using netcp or a mounted
-image, or git. Note that if you are using the same source tree as was used to
-build the target image, you'll want to remove any modifications to
-kernel/engine.mk that were made for previous steps (or update them to reflect
-the target location of these files), otherwise the build will fail when trying
-to generate the bootfs image.
-```bash
-cd <path-to-zircon>
-for filename in `find . -name .git -prune \
-                        -o -path "./build-*" -prune \
-                        -o -path "./prebuilt*" \
-                        -o -type f -print`
-do
-  echo "Copying $filename" 
-  netcp $filename :/data/zircon/$filename
-done
-```
-* Copy the Zircon sysroot onto the target device in `/data/sysroot`
-```bash
-cd <zircon-sysroot>
-for filename in `find . -type f`
-do
-  echo "Copying $filename"
-  netcp $filename :/data/sysroot/$filename
-done
-```
-* Copy the compiler shared libraries into `/data/sysroot/lib`
-```bash
-cd <path-to-gcc>/x86_64-fuchsia-<gcc-ver>-native
-for filename in libstdc++.so libgcc_s.so libgcc_s.so.1
-do
-  echo "Copying $filename"
-  netcp lib/$filename :/data/sysroot/lib/$filename
-done
-```
-
-## Build Zircon
-On the Fuchsia target, add `/data/bin`, `/data/gcc/bin`, and `data/gcc-bare-metal/bin` to your `PATH`
-```bash
-export PATH="$PATH:/data/bin:/data/gcc/bin:/data/gcc-bare-metal/bin"
-```
-* Finally, start the build in the zircon directory:
-```bash
-cd zircon
-make \
-    HOST_SYSROOT=/data/sysroot \
-    ARCH_x86_64_TOOLCHAIN_PREFIX="x86_64-elf-" \
-    HOST_TOOLCHAIN_PREFIX=""
-```
diff --git a/docs/signals.md b/docs/signals.md
deleted file mode 100644
index 65b6efb..0000000
--- a/docs/signals.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Zircon Signals
-
-## Introduction
-
-A signal is a single bit of information that waitable zircon kernel objects expose to
-applications.  Each object can expose one or more signals; some are generic and some
-are specific to the type of object.
-
-For example, the signal *ZX_CHANNEL_READABLE* indicates "this channel endpoint has
-messages to read", and **ZX_PROCESS_TERMINATED** indicates "this process stopped running."
-
-The signals for an object are stored in a uint32 bitmask, and their values (which are
-object-specific) are defined in the header[`zircon/types.h`](../system/public/zircon/types.h).
-The typedef `zx_signals_t` is used to refer to signal bitmasks in syscalls and other APIs.
-
-Most objects are waitable.  Ports are an example of a non-waitable object.
-To determine if an object is waitable, call [object_get_info](syscalls/object_get_info.md)
-with **ZX_INFO_HANDLE_BASIC** topic and test for **ZX_OBJ_PROP_WAITABLE**.
-
-## State, State Changes and their Terminology
-
-A signal is said to be **Active** when its bit is 1 and **Inactive** when its bit is 0.
-
-A signal is said to be **Asserted** when it is made **Active** in response to an event
-(even if it was already **Active**), and is said to be **Deasserted** when it is made
-**Inactive** in response to an event (even if it was already **Inactive**).
-
-For example:  When a message is written into a Channel endpoint, the *ZX_CHANNEL_READABLE*
-signal of the opposing endpoint is **asserted** (which causes that signal to become **active**,
-if it were not already active).  When the last message in a Channel endpoint's
-queue is read from that endpoint, the *ZX_CHANNEL_READABLE* signal of that endpoint is
-**deasserted** (which causes that signal to become **inactive**)
-
-## Observing Signals
-
-The syscalls **zx_object_wait_one**(), **zx_object_wait_many**(), and **zx_object_wait_async**() (in
-combination with a Port), can be used to wait for specified signals on one or more objects.
-
-## Common Signals
-
-### ZX_SIGNAL_HANDLE_CLOSED
-
-This synthetic signal only exists in the results of [object_wait_one](syscalls/object_wait_one.md)
-or [object_wait_many](syscalls/object_wait_many.md) and indicates that a handle that was
-being waited upon has been been closed causing the wait operation to be aborted.
-
-This signal can only be obtained as a result of the above two wait calls when the wait itself
-returns with **ZX_ERR_CANCELED**.
-
-## User Signals
-
-There are eight User Signals (**ZX_USER_SIGNAL_0** through **ZX_USER_SIGNAL_7**) which may
-asserted or deasserted using the **zx_object_signal**() and **zx_object_signal_peer**() syscalls,
-provided the handle has the appropriate rights (**ZX_RIGHT_SIGNAL** or **ZX_RIGHT_SIGNAL_PEER**,
-respectively).  These User Signals are always initially inactive, and are only modified by
-the object signal syscalls.
-
-## See Also
-
-[object_signal](syscalls/object_signal.md),
-[object_signal_peer](syscalls/object_signal.md),
-[object_wait_async](syscalls/object_wait_async.md),
-[object_wait_many](syscalls/object_wait_many.md),
-[object_wait_one](syscalls/object_wait_one.md).
diff --git a/docs/static_analysis.md b/docs/static_analysis.md
deleted file mode 100644
index 40c71f3..0000000
--- a/docs/static_analysis.md
+++ /dev/null
@@ -1,144 +0,0 @@
-# Static Analysis in Zircon
-
-This document describes:
-
-* How to perform static analysis with the Clang Static Analyzer in Zircon;
-* How to enable ZirconHandleChecker;
-* How to add/modify annotate attributes to syscalls/functions and use annotate attributes to suppress false positives.
-
-## Steps to run Clang Static Analyzer
-
-Assuming you already obtained a local copy of Fuchsia workspace according to the instructions written in [getting_started.md](https://fuchsia.googlesource.com/docs/+/master/getting_started.md) and the source tree of fuchsia is located at `$LOCAL_DIR/fuchsia` and current working directory is `$LOCAL_DIR/fuchsia/zircon`. The Clang Static Analayzer can be run on Zircon by following commands:
-
-```sh
-./scripts/download-prebuilt
-./scripts/analyze-zircon
-```
-
-The Clang Static Analyzer will be run on Zircon code base with default checkers. After the finish of the analysis, you can see an outout in stdout similar to the one below:
-
-```
-scan-build: Run 'scan-view $LOCAL_DIR/fuchsia/zircon/AnalysisResult/scan-build-2017-08-08-11-26-25-914570-SKSE39' to examine bug reports.
-```
-
-Just type the command start with `scan-view` in a terminal and it will open your web browser and show the analysis reports.
-
-## Steps to enable ZirconHandleChecker
-
-At the time this document is written, all Zircon related checkers are still under review by upstream LLVM community:
-
- * MutexInInterruptContext [D27854](https://reviews.llvm.org/D27854)
- * SpinLockChecker [D26340](https://reviews.llvm.org/D26340)
- * MutexChecker [D26342](https://reviews.llvm.org/D26342)
- * ZirconHandleChecker [D35968](https://reviews.llvm.org/D35968) [D36022](https://reviews.llvm.org/D36022) [D36023](https://reviews.llvm.org/D36023) [D36024](https://reviews.llvm.org/D36024) [D36251](https://reviews.llvm.org/D36251) [D36475](https://reviews.llvm.org/D36475))
-
-They are enabled by default when you executed the 'analyze-zircon' script. We will update the 'analyze-zircon' script to enable them by default once they get landed.
-
-In the mean time, if you would like to try ZirconHandleChecker now, you can download the source code of LLVM with Clang and apply the patch from the diffs above and follow the instructions in [toolchain.md](https://fuchsia.googlesource.com/docs/+/master/development/build/toolchain.md) to build your own toolchain. Assuming you have built your own toolchain and it is located at `$LOCAL_TOOLCHAIN_PREFIX` and `$LOCAL_TOOLCHAIN_PREFIX/bin/clang` is the path to the `clang` command. The Clang Static Analyzer can be run with ZirconHandleChecker and other default checkers enabled by following command:
-
-```
-./scripts/analyze-zircon -p $LOCAL_TOOLCHAIN_PREFIX -m all
-```
-
-If you want to enable ZirconHandleChecker and disable other default checkers, please run following command:
-
-```
-./scripts/analyze-zircon -p $LOCAL_TOOLCHAIN_PREFIX -m zircon
-```
-
-The 'analyze-zircon' scripts have additional options such as changing the output directories and changing build targets, please refer the to help information printed by `./scripts/analyze-zircon -h`.
-
-## Steps to add/modify annotate attributes to syscalls/functions
-
-In Zircon code base, raw annotations like `__attribute__((annotate("string")))` should never be used in Zircon code base, all zircon related annotations should be wrapped by macros. In this section, we will discuss how to add or modify annotations in Zircon code base.
-
-### Annotations in syscall declaration
-
-As header files of Zircon syscalls are generated from syscalls.abigen, in order to add/modify annotations of syscalls, the syscalls.abigen should be modified directly.
-Let’s use `zx_channel_create syscall` as example. This syscall will allocate two handles when it is successfully executed. Without annotations, its declaration in abigen will be like:
-
-```c
-syscall channel_create
-    (options: uint32_t)
-    returns (zx_status_t, out0: zx_handle_t, out1: zx_handle_t);
-```
-
-As argument `out0` and `out1` will be allocated handles, we should add `handle_acquire` annotation to these arguments:
-
-```c
-syscall channel_create
-    (options: uint32_t)
-    returns (zx_status_t, out0: zx_handle_t handle_acquire,
-             out1: zx_handle_t handle_acquire);
-```
-
-This syscall declaration will be processed by abigen and converted to:
-
-```c
-extern zx_status_t zx_channel_create(
-uint32_t options,
-    ZX_SYSCALL_PARAM_ATTR(handle_acquire) zx_handle_t* out0,
-    ZX_SYSCALL_PARAM_ATTR(handle_acquire) zx_handle_t* out1));
-```
-
-The declaration of macro can be found in system/public/zircon/syscalls.h, which is:
-
-```c
-#if defined(__clang__)
-#define ZX_SYSCALL_PARAM_ATTR(x)   __attribute__((annotate("zx_" #x)))
-#else
-#define ZX_SYSCALL_PARAM_ATTR(x)   // no-op
-#endif
-```
-
-According to the definition of `ZX_SYSCALL_PARAM_ATTR`, the `zx_channel_create` will be parsed into:
-
-```c
-extern zx_status_t zx_channel_create(uint32_t options,
-__attribute__((annotate("zx_handle_acquire"))) zx_handle_t* out0,
-__attribute__((annotate("zx_handle_acquire"))) zx_handle_t* out1) __attribute__((__leaf__));;
-```
-
-The reason that we use macros to wrap these annotations is that annotate attribute is not supported by compilers other than Clang, e.g. GCC. Furthermore, it would be convenient if we decide to use annotation solutions other than the annotate attributes in the future. Otherwise we need to change each annotation one by one.
-
-### Annotations in other functions
-
-For functions other than syscalls, if `system/public/zircon/syscalls.h` is in current include path, you can use `ZX_SYSCALL_PARAM_ATTR` macro to wrap your annotations. If not, you should use macros similar to this one. The reason that functions other than syscalls may require annotations is that some functions contain known false positives and we can use annotation to suppress the warnings of these false positives. For example, in ZirconHandleChecker’s test file we have:
-
-```c
-#if defined(__clang__)
-#define ZX_ANALYZER_SUPPRESS   __attribute__((annotate("zx_suppress_warning)))
-#else
-#define ZX_ANALYZER_SUPPRESS   // no-op
-#endif
-void checkSuppressWarning() ZX_ANALYZER_SUPPRESS {
-  zx_handle_t sa, sb;
-  if (zx_channel_create(0, &sa, &sb) < 0) {
-    return;
-  }
-  zx_handle_close(sa); // Should not report any bugs here
-}
-```
-
-The analyzer will suppress the warnings on the bug it discovered in `checkSuppressWarning` function. If you don’t want to define your own macro for this purpose, and the `syscalls.h` is in the include path, you can use `_SYSCALL_PARAM_ATTR(suppress_warning)` instead, it will suppress the warnings of all bugs discovered in the functions with this annotation.
-
-Similar to `zx_suppress_warning` annotation, we have `zx_create_sink` annotation which currently used to suppress warnings on assertion failures. This annotation is unlikely to be used for other purpose, however, if you would like to know how it works, please refer to the discussions in CL[46428](https://fuchsia-review.googlesource.com/c/46428).
-
-To manually annotate non-syscall functions, the "ZX_SYSCALL_PARAM_ATTR" macro can be applied to function arguments, emulating the effect of the abigen attributes. For example, here, we annotate a regular function which might be used to call the "zx_create_channel" function without passing the "options" argument:
-
-```c
-zx_status_t create_channel(
-  ZX_SYSCALL_PARAM_ATTR(handle_acquire) zx_handle_t* out0,
-  ZX_SYSCALL_PARAM_ATTR(handle_acquire) zx_handle_t* out1);
-```
-Another example, we have another function `takeover_handle` that will take care the lifecycle of a handle if it is successfully executed and do nothing if it failed, we can declare this function in header file like this:
-
-```c
-zx_status_t takeover_handle(
-  ZX_SYSCALL_PARAM_ATTR(handle_escape) zx_handle_t in)
-  ZX_SYSCALL_PARAM_ATTR(may_fail);
-```
-
-The `zx_may_fail` annotation here will cause state bifurcation when ZirconHandleChecker is evaluating calls to this function. So both succeeded and failed states will be covered.
-
-If the `ZX_SYSCALL_PARAM_ATTR` is not available in the file that declares the function, you can define your own macros, as long as it will not expanded into annotate attribute if it is not compiled by Clang.
diff --git a/docs/symbolizer.md b/docs/symbolizer.md
deleted file mode 100644
index ebcb419..0000000
--- a/docs/symbolizer.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# Symbolizer
-
-This document outlines how to symbolize crashes and backtraces in Zircon.
-
-## Overview
-
-If you have some text that contains the required information, you can symbolize
-that text by piping it into `./scripts/symbolize`. You can run
-`./scripts/symbolize -h` to see how to use it.
-
-If you use `loglistener` on x64, this is quite simple. You can simply pipe
-directly into symbolize.
-
-```
-loglistener | ./scripts/symbolize
-```
-
-You can use the standard flags found in other scripts in Zircon to specify
-other builds than build-x64. For instance, if you want to symbolize an arm64
-build that was built with Clang you can run the following:
-
-```
-loglistener | ./scripts/symbolize -a arm64 -C
-```
-
-If you're familiar with what `ids.txt` is, and you know what you're doing you
-can also specify `ids.txt` directly.
-
-```
-loglistener | ./scripts/symbolize build-arm64-asan/ids.txt
-```
-
-## ASan with QEMU Example
-
-For a slightly more involved case we'll consider a complete workflow to compile
-and symbolize an ASan crash.
-
-First build (you can use `./scripts/build-zircon-x86 -A` as well):
-
-```
-make -j $JOBS USE_ASAN=true
-```
-
-Now you'll want to run this on QEMU, but if you just run it directly
-you'll be stuck copy pasting the output into a file. You can use `tee`
-to solve this:
-
-```
-./scripts/run-zircon-x86 -A | tee ~/log.txt
-```
-
-This will create a log.txt file in your home directory (feel free to place it
-anywhere) that will contain all output from your QEMU run. While QEMU is
-running, we'll need to create a crash. To get a handy ASan crash result we can
-use `crasher`
-
-```
-$ crasher use_after_free
-```
-
-Now just pipe the output thought the symbolizer
-
-```
-./scripts/symbolize -A < ~/log.txt
-```
-
-# TODO(TC-283): Remove this after TC-283 is solved.
-You might be wondering if you can just pipe QEMU directly into the symbolizer.
-Right now this won't cause an error but it is not really usable because the
-symbolizer buffers on a line by line basis. This may be possible in the future.
diff --git a/docs/symbolizer_markup.md b/docs/symbolizer_markup.md
deleted file mode 100644
index 01be6b2..0000000
--- a/docs/symbolizer_markup.md
+++ /dev/null
@@ -1,414 +0,0 @@
-# Symbolizer markup format #
-
-This document defines a text format for log messages that can be
-processed by a _symbolizing filter_.  The basic idea is that logging
-code emits text that contains raw address values and so forth, without
-the logging code doing any real work to convert those values to
-human-readable form.  Instead, logging text uses the markup format
-defined here to identify pieces of information that should be converted
-to human-readable form after the fact.  As with other markup formats,
-the expectation is that most of the text will be displayed as is, while
-the markup elements will be replaced with expanded text, or converted
-into active UI elements, that present more details in symbolic form.
-
-This means there is no need for symbol tables, DWARF debugging sections,
-or similar information to be directly accessible at runtime.  There is
-also no need at runtime for any logic intended to compute human-readable
-presentation of information, such as C++ symbol demangling.  Instead,
-logging must include markup elements that give the contextual
-information necessary to make sense of the raw data, such as memory
-layout details.
-
-This format identifies markup elements with a syntax that is both simple
-and distinctive.  It's simple enough to be matched and parsed with
-straightforward code.  It's distinctive enough that character sequences
-that look like the start or end of a markup element should rarely if
-ever appear incidentally in logging text.  It's specifically intended
-not to require sanitizing plain text, such as the HTML/XML requirement
-to replace `<` with `&lt;` and the like.
-
-## Scope and assumptions ##
-
-This specification defines a format standard for Zircon and Fuchsia.
-But there is nothing specific to Zircon or Fuchsia about the markup
-format.  A symbolizing filter implementation will be independent both of
-the _target_ operating system and machine architecture where the logs
-are generated and of the _host_ operating system and machine
-architecture where the filter runs.
-
-This format assumes that the symbolizing filter processes intact whole
-lines.  If long lines might be split during some stage of a logging
-pipeline, they must be reassembled to restore the original line breaks
-before feeding lines into the symbolizing filter.  Most markup elements
-must appear entirely on a single line (often with other text before
-and/or after the markup element).  There are some markup elements that
-are specified to span lines, with line breaks in the middle of the
-element.  Even in those cases, the filter is not expected to handle line
-breaks in arbitrary places inside a markup element, but only inside
-certain fields.
-
-This format assumes that the symbolizing filter processes a coherent
-stream of log lines from a single process address space context.  If a
-logging stream interleaves log lines from more than one process, these
-must be collated into separate per-process log streams and each stream
-processed by a separate instance of the symbolizing filter.  Because the
-kernel and user processes use disjoint address regions in most operating
-systems (including Zircon), a single user process address space plus
-the kernel address space can be treated as a single address space for
-symbolization purposes if desired.
-
-## Dependence on Build IDs ##
-
-The symbolizer markup scheme relies on contextual information about
-runtime memory address layout to make it possible to convert markup
-elements into useful symbolic form.  This relies on having an
-unmistakable identification of which binary was loaded at each address.
-
-An ELF Build ID is the payload of an ELF note with name `"GNU"` and type
-`NT_GNU_BUILD_ID`, a unique byte sequence that identifies a particular
-binary (executable, shared library, loadable module, or driver module).
-The linker generates this automatically based on a hash that includes
-the complete symbol table and debugging information, even if this is
-later stripped from the binary.
-
-This specification uses the ELF Build ID as the sole means of
-identifying binaries.  Each binary relevant to the log must have been
-linked with a unique Build ID.  The symbolizing filter must have some
-means of mapping a Build ID back to the original ELF binary (either the
-whole unstripped binary, or a stripped binary paired with a separate
-debug file).
-
-## Colorization ##
-
-The markup format supports a restricted subset of ANSI X3.64 SGR (Select
-Graphic Rendition) control sequences.  These are unlike other markup
-elements:
- * They specify presentation details (**bold** or colors) rather than
-   semantic information.  The assocation of semantic meaning with color
-   (e.g. red for errors) is chosen by the code doing the logging, rather
-   than by the UI presentation of the symbolizing filter.  This is a
-   concession to existing code (e.g. LLVM sanitizer runtimes) that use
-   specific colors and would require substantial changes to generate
-   semantic markup instead.
- * A single control sequence changes "the state", rather than being an
-   hierarchical structure that surrounds affected text.
-
-The filter processes ANSI SGR control sequences only within a single
-line.  If a control sequence to enter a **bold** or color state is
-encountered, it's expected that the control sequence to reset to default
-state will be encountered before the end of that line.  If a "dangling"
-state is left at the end of a line, the filter may reset to default
-state for the next line.
-
-An SGR control sequence is not interpreted inside any other markup element.
-However, other markup elements may appear between SGR control sequences and
-the color/**bold** state is expected to apply to the symbolic output that
-replaces the markup element in the filter's output.
-
-The accepted SGR control sequences all have the form `"\033[%um"`
-(expressed here using C string syntax), where `%u` is one of these:
-
-| Code | Effect | Notes |
-|:----:|:------:|-------|
-| `0`  | Reset to default formatting. | |
-| `1`  | Use **bold text**  | Combines with color states, doesn't reset them.|
-| `30` | Black foreground   | |
-| `31` | Red foreground     | |
-| `32` | Green foreground   | |
-| `33` | Yellow foreground  | |
-| `34` | Blue foreground    | |
-| `35` | Magenta foreground | |
-| `36` | Cyan foreground    | |
-| `37` | White foreground   | |
-
-## Common markup element syntax ##
-
-All the markup elements share a common syntactic structure to facilitate
-simple matching and parsing code.  Each element has the form:
-
-```
-{{{tag:fields}}}
-```
-
-`tag` identifies one of the element types described below, and is always
-a short alphabetic string that must be in lower case.  The rest of the
-element consists of one or more fields.  Fields are separated by `:` and
-cannot contain any `:` or `}` characters.  How many fields must be or
-may be present and what they contain is specified for each element type.
-
-No markup elements or ANSI SGR control sequences are interpreted inside the
-contents of a field.
-
-In the descriptions of each element type, `printf`-style placeholders
-indicate field contents:
-
-* `%s`
-
-  A string of printable characters, not including `:` or `}`.
-
-* `%p`
-
-  An address value represented by `0x` followed by an even number of
-  hexadecimal digits (using either lower-case or upper-case for
-  `A`..`F`).  If the digits are all `0` then the `0x` prefix may be
-  omitted.  No more than 16 hexadecimal digits are expected to appear in
-  a single value (64 bits).
-
-* `%u`
-
-  A nonnegative decimal integer.
-
-* `%x`
-
-  A sequence of an even number of hexadecimal digits (using either
-  lower-case or upper-case for `A`..`F`), with no `0x` prefix.
-  This represents an arbitrary sequence of bytes, such as an ELF Build ID.
-
-## Presentation elements ##
-
-These are elements that convey a specific program entity to be displayed
-in human-readable symbolic form.
-
-* `{{{symbol:%s}}}`
-
-  Here `%s` is the linkage name for a symbol or type.  It may require
-  demangling according to language ABI rules.  Even for unmangled names,
-  it's recommended that this markup element be used to identify a symbol
-  name so that it can be presented distinctively.
-
-  Examples:
-  ```
-  {{{symbol:_ZN7Mangled4NameEv}}}
-  {{{symbol:foobar}}}
-  ```
-
-* `{{{pc:%p}}}`
-
-  Here `%p` is the memory address of a code location.
-  It might be presented as a function name and source location.
-
-  Examples:
-  ```
-  {{{pc:0x12345678}}}
-  {{{pc:0xffffffff9abcdef0}}}
-  ```
-
-* `{{{data:%p}}}`
-
-  Here `%p` is the memory address of a data location.
-  It might be presented as the name of a global variable at that location.
-
-  Examples:
-  ```
-  {{{data:0x12345678}}}
-  {{{data:0xffffffff9abcdef0}}}
-  ```
-
-* `{{{bt:%u:%p}}}`
-
-  This represents one frame in a backtrace.  It usually appears on a
-  line by itself (surrounded only by whitespace), in a sequence of such
-  lines with ascending frame numbers.  So the human-readable output
-  might be formatted assuming that, such that it looks good for a
-  sequence of `bt` elements each alone on its line with uniform
-  indentation of each line.  But it can appear anywhere, so the filter
-  should not remove any non-whitespace text surrounding the element.
-
-  Here `%u` is the frame number, which starts at zero for the location
-  of the fault being identified, increments to one for the caller of
-  frame zero's call frame, to two for the caller of frame one, etc.
-  `%p` is the memory address of a code location.
-
-  In frames after frame zero, this code location identifies a call site.
-  Some emitters may subtract one byte or one instruction length from the
-  actual return address for the call site, with the intent that the
-  address logged can be translated directly to a source location for the
-  call site and not for the apparent return site thereafter (which can
-  be confusing).  It's recommended that emitters _not_ do this, so that
-  each frame's code location is the exact return address given to its
-  callee and e.g. could be highlighted in instruction-level disassembly.
-  The symbolizing filter can do the adjustment to the address it
-  translates into a source location.  Assuming that a call instruction
-  is longer than one byte on all supported machines, applying the
-  "subtract one byte" adjustment a second time still results in an
-  address somewhere in the call instruction, so a little sloppiness here
-  does no harm.
-
-  Examples:
-  ```
-  {{{bt:0:0x12345678}}}
-  {{{bt:1:0xffffffff9abcdef0}}}
-  ```
-
-* `{{{hexdict:...}}}`
-
-  This element can span multiple lines.  Here `...` is a sequence of
-  key-value pairs where a single `:` separates each key from its value,
-  and arbitrary whitespace separates the pairs.  The value (right-hand
-  side) of each pair either is one or more `0` digits, or is `0x`
-  followed by hexadecimal digits.  Each value might be a memory address
-  or might be some other integer (including an integer that looks like a
-  likely memory address but actually has an unrelated purpose).  When
-  the contextual information about the memory layout suggests that a
-  given value could be a code location or a global variable data
-  address, it might be presented as a source location or variable name
-  or with active UI that makes such interpretation optionally visible.
-
-  The intended use is for things like register dumps, where the emitter
-  doesn't know which values might have a symbolic interpretation but a
-  presentation that makes plausible symbolic interpretations available
-  might be very useful to someone reading the log.  At the same time,
-  a flat text presentation should usually avoid interfering too much
-  with the original contents and formatting of the dump.  For example,
-  it might use footnotes with source locations for values that appear
-  to be code locations.  An active UI presentation might show the dump
-  text as is, but highlight values with symbolic information available
-  and pop up a presentation of symbolic details when a value is selected.
-
-  Example:
-  ```
-  {{{hexdict:
-    CS:                   0 RIP:     0x6ee17076fb80 EFL:            0x10246 CR2:                  0
-    RAX:      0xc53d0acbcf0 RBX:     0x1e659ea7e0d0 RCX:                  0 RDX:     0x6ee1708300cc
-    RSI:                  0 RDI:     0x6ee170830040 RBP:     0x3b13734898e0 RSP:     0x3b13734898d8
-     R8:     0x3b1373489860  R9:         0x2776ff4f R10:     0x2749d3e9a940 R11:              0x246
-    R12:     0x1e659ea7e0f0 R13: 0xd7231230fd6ff2e7 R14:     0x1e659ea7e108 R15:      0xc53d0acbcf0
-  }}}
-  ```
-
-## Trigger elements ##
-
-These elements cause an external action and will be presented to the
-user in a human readable form. Generally they trigger an external
-action to occur that results in a linkable page. The link or some
-other informative information about the external action can then be
-presented to the user.
-
-* `{{{dumpfile:%s:%s}}}`
-
-  Here the first `%s` is an identifier for a type of dump and the
-  second `%s` is an identifier for a particular dump that's just been
-  published.  The types of dumps, the exact meaning of "published",
-  and the nature of the identifier are outside the scope of the markup
-  format per se.  In general it might correspond to writing a file by
-  that name or something similar.
-
-  This element may trigger additional post-processing work beyond
-  symbolizing the markup. It indicates that a dump file of some sort
-  has been published.  Some logic attached to the symbolizing filter may
-  understand certain types of dump file and trigger additional
-  post-processing of the dump file upon encountering this element (e.g.
-  generating visualizations, symbolization).  The expectation is that the
-  information collected from contextual elements (described below) in the
-  logging stream may be necessary to decode the content of the dump.  So
-  if the symbolizing filter triggers other processing, it may need to
-  feed some distilled form of the contextual information to those
-  processes.
-
-  On Zircon and Fuchsia in particular, "publish" means to call the
-  `__sanitizer_publish_data` function from `<zircon/sanitizer.h>`
-  with the "type" identifier as the "sink name" string.  The "dump
-  identifier" is the name attached to the Zircon VMO whose handle
-  was passed in the call to `__sanitizer_publish_data`.
-  **TODO(mcgrathr): Link to docs about `__sanitizer_publish_data` and
-  getting data dumps off the device.**
-
-  An example of a type identifier is `sancov`, for dumps from LLVM
-  [SanitizerCoverage](https://clang.llvm.org/docs/SanitizerCoverage.html).
-
-  Example:
-  ```
-  {{{dumpfile:sancov:sancov.8675}}}
-  ```
-
-## Contextual elements ##
-
-These are elements that supply information necessary to convert
-presentation elements to symbolic form.  Unlike presentation elements,
-they are not directly related to the surrounding text.  Contextual
-elements should appear alone on lines with no other non-whitespace
-text, so that the symbolizing filter might elide the whole line from
-its output without hiding any other log text.
-
-The contextual elements themselves do not necessarily need to be
-presented in human-readable output.  However, the information they
-impart may be essential to understanding the logging text even after
-symbolization.  So it's recommended that this information be preserved
-in some form when the original raw log with markup may no longer be
-readily accessible for whatever reason.
-
-Contextual elements should appear in the logging stream before they are
-needed.  That is, if some piece of context may affect how the
-symbolizing filter would interpret or present a later presentation
-element, the necessary contextual elements should have appeared
-somewhere earlier in the logging stream.  It should always be possible
-for the symbolizing filter to be implemented as a single pass over the
-raw logging stream, accumulating context and massaging text as it goes.
-
-* `{{{reset}}}`
-
-  This should be output before any other contextual element. The need
-  for this contextual element is to support implementations that handle
-  logs coming from multiple processes. Such implementations might not
-  know when a new process starts or ends. Because some identifying
-  information (like process IDs) might be the same between old and new
-  processes, a way is needed to distinguish two processes with such
-  identical identifying information. This element informs such
-  implementations to reset the state of a filter so that information
-  from a previous process's contextual elements is not assumed for new
-  process that just happens have the same identifying information.
-
-* `{{{module:%i:%s:%s:...}}}`
-
-  This element represents a so called "module". A "module" is a single
-  linked binary, such as a loaded ELF file. Usually each module occupies
-  a contiguous range of memory (always does on Zircon).
- 
-  Here `%i` is the Module ID which is used by other contextual elements
-  to refer to this module. The first `%s` is a human-readable identifier
-  for the module, such as an ELF `DT_SONAME` string or a file name; but
-  it might be empty. It's only for casual information. The Module ID
-  will be exclusivelly used to refer to this module in other contextual
-  elements. The second `%s` is the module type and it determines what
-  the remaining fields are. The following module types are supported:
-
-  * `elf:%x`
-
-    Here `%x` encodes an ELF Build ID. The Build ID should refer to a
-    single linked binary. The Build ID string is the sole way to identify
-    the binary from which this module was loaded.
-
-  Example:
-  ```
-  {{{module:1:libc.so:elf:83238ab56ba10497}}}
-  ```
-
-* `{{{mmap:%p:%x:...}}}`
-
-  This contextual element is used to give information about a particular
-  region in memory. `%p` is the starting address and `%x` gives the size
-  in hex of the region of memory. The `...` part can take different forms
-  to give different information about the specified region of memory. The
-  allowed forms are the following:
-
-  * `load:%i:%s:%p`
-
-    This subelement informs the filter that a segment was loaded from a
-    module. The module is identified by its module id `%i`. The `%s` is
-    one or more of the letters 'r', 'w', and 'x' (in that order and in
-    either upper or lower case) to indicate this segment of memory is
-    readable, writable, and/or executable. The symbolizing filter can use
-    this information to guess whether an address is a likely code address
-    or a likely data address in the given module. The remaining `%p` gives
-    the module relative address. For ELF files the module relative address
-    will be the `p_vaddr` of the associated program header. For example if
-    your module's executable segment has `p_vaddr=0x1000`, `p_memsz=0x1234`,
-    and was loaded at 0x7acba69d5000 then you need to subtract 0x7acba69d4000
-    from any address between 0x7acba69d5000 and 0x7acba69d6234 to get the
-    module relative address. The starting address will usually have been
-    rounded down to the active page size, and the size rounded up.
-
-  Example:
-  ```
-  {{{mmap:0x7acba69d5000:0x5a000:load:1:rx:0x1000}}}
-  ```
diff --git a/docs/syscalls.md b/docs/syscalls.md
deleted file mode 100644
index 519fe72..0000000
--- a/docs/syscalls.md
+++ /dev/null
@@ -1,162 +0,0 @@
-# Zircon System Calls
-
-## Handles
-+ [handle_close](syscalls/handle_close.md) - close a handle
-+ [handle_close_many](syscalls/handle_close_many.md) - close several handles
-+ [handle_duplicate](syscalls/handle_duplicate.md) - create a duplicate handle (optionally with reduced rights)
-+ [handle_replace](syscalls/handle_replace.md) - create a new handle (optionally with reduced rights) and destroy the old one
-
-## Objects
-+ [object_get_child](syscalls/object_get_child.md) - find the child of an object by its koid
-+ [object_get_cookie](syscalls/object_get_cookie.md) - read an object cookie
-+ [object_get_info](syscalls/object_get_info.md) - obtain information about an object
-+ [object_get_property](syscalls/object_get_property.md) - read an object property
-+ [object_set_cookie](syscalls/object_set_cookie.md) - write an object cookie
-+ [object_set_property](syscalls/object_set_property.md) - modify an object property
-+ [object_signal](syscalls/object_signal.md) - set or clear the user signals on an object
-+ [object_signal_peer](syscalls/object_signal_peer.md) - set or clear the user signals in the opposite end
-+ [object_wait_many](syscalls/object_wait_many.md) - wait for signals on multiple objects
-+ [object_wait_one](syscalls/object_wait_one.md) - wait for signals on one object
-+ [object_wait_async](syscalls/object_wait_async.md) - asynchronous notifications on signal change
-
-## Threads
-+ [thread_create](syscalls/thread_create.md) - create a new thread within a process
-+ [thread_exit](syscalls/thread_exit.md) - exit the current thread
-+ [thread_read_state](syscalls/thread_read_state.md) - read register state from a thread
-+ [thread_start](syscalls/thread_start.md) - cause a new thread to start executing
-+ [thread_write_state](syscalls/thread_write_state.md) - modify register state of a thread
-
-## Processes
-+ [process_create](syscalls/process_create.md) - create a new process within a job
-+ [process_read_memory](syscalls/process_read_memory.md) - read from a process's address space
-+ [process_start](syscalls/process_start.md) - cause a new process to start executing
-+ [process_write_memory](syscalls/process_write_memory.md) - write to a process's address space
-+ [process_exit](syscalls/process_exit.md) - exit the current process
-
-## Jobs
-+ [job_create](syscalls/job_create.md) - create a new job within a job
-+ [job_set_policy](syscalls/job_set_policy.md) - modify policies for a job and its descendants
-
-## Tasks (Thread, Process, or Job)
-+ [task_bind_exception_port](syscalls/task_bind_exception_port.md) - attach an exception port to a task
-+ [task_kill](syscalls/task_kill.md) - cause a task to stop running
-+ [task_resume_from_exception](syscalls/task_resume_from_exception.md) - resume a task from a previously caught exception
-+ [task_suspend](syscalls/task_suspend.md) - cause a task to be suspended
-
-## Channels
-+ [channel_call](syscalls/channel_call.md) - synchronously send a message and receive a reply
-+ [channel_create](syscalls/channel_create.md) - create a new channel
-+ [channel_read](syscalls/channel_read.md) - receive a message from a channel
-+ [channel_read_etc](syscalls/channel_read.md) - receive a message from a channel with handle information
-+ [channel_write](syscalls/channel_write.md) - write a message to a channel
-
-## Sockets
-+ [socket_accept](syscalls/socket_accept.md) - receive a socket via a socket
-+ [socket_create](syscalls/socket_create.md) - create a new socket
-+ [socket_read](syscalls/socket_read.md) - read data from a socket
-+ [socket_share](syscalls/socket_share.md) - share a socket via a socket
-+ [socket_shutdown](syscalls/socket_shutdown.md) - prevent reading or writing
-+ [socket_write](syscalls/socket_write.md) - write data to a socket
-
-## Fifos
-+ [fifo_create](syscalls/fifo_create.md) - create a new fifo
-+ [fifo_read](syscalls/fifo_read.md) - read data from a fifo
-+ [fifo_write](syscalls/fifo_write.md) - write data to a fifo
-
-## Events and Event Pairs
-+ [event_create](syscalls/event_create.md) - create an event
-+ [eventpair_create](syscalls/eventpair_create.md) - create a connected pair of events
-
-## Ports
-+ [port_create](syscalls/port_create.md) - create a port
-+ [port_queue](syscalls/port_queue.md) - send a packet to a port
-+ [port_wait](syscalls/port_wait.md) - wait for packets to arrive on a port
-+ [port_cancel](syscalls/port_cancel.md) - cancel notifications from async_wait
-
-## Futexes
-+ [futex_wait](syscalls/futex_wait.md) - wait on a futex
-+ [futex_wake](syscalls/futex_wake.md) - wake waiters on a futex
-+ [futex_requeue](syscalls/futex_requeue.md) - wake some waiters and requeue other waiters
-
-## Virtual Memory Objects (VMOs)
-+ [vmo_create](syscalls/vmo_create.md) - create a new vmo
-+ [vmo_read](syscalls/vmo_read.md) - read from a vmo
-+ [vmo_write](syscalls/vmo_write.md) - write to a vmo
-+ [vmo_clone](syscalls/vmo_clone.md) - clone a vmo
-+ [vmo_get_size](syscalls/vmo_get_size.md) - obtain the size of a vmo
-+ [vmo_set_size](syscalls/vmo_set_size.md) - adjust the size of a vmo
-+ [vmo_op_range](syscalls/vmo_op_range.md) - perform an operation on a range of a vmo
-+ [vmo_replace_as_executable](syscalls/vmo_replace_as_executable.md) - add execute rights to a vmo
-+ [vmo_create_physical](syscalls/vmo_create_physical.md) - create a VM object referring to a specific contiguous range of physical memory
-+ [vmo_clone](syscalls/vmo_clone.md) - clone a vmo
-+ [vmo_set_cache_policy](syscalls/vmo_set_cache_policy.md) - set the caching policy for pages held by a VMO.
-
-## Virtual Memory Address Regions (VMARs)
-+ [vmar_allocate](syscalls/vmar_allocate.md) - create a new child VMAR
-+ [vmar_map](syscalls/vmar_map.md) - map a VMO into a process
-+ [vmar_unmap](syscalls/vmar_unmap.md) - unmap a memory region from a process
-+ [vmar_protect](syscalls/vmar_protect.md) - adjust memory access permissions
-+ [vmar_destroy](syscalls/vmar_destroy.md) - destroy a VMAR and all of its children
-
-## Cryptographically Secure RNG
-+ [cprng_draw](syscalls/cprng_draw.md)
-+ [cprng_add_entropy](syscalls/cprng_add_entropy.md)
-
-## Time
-+ [nanosleep](syscalls/nanosleep.md) - sleep for some number of nanoseconds
-+ [clock_get](syscalls/clock_get.md) - read a system clock
-+ [clock_get_monotonic](syscalls/clock_get_monotonic.md) - read the monotonic system clock
-+ [ticks_get](syscalls/ticks_get.md) - read high-precision timer ticks
-+ [ticks_per_second](syscalls/ticks_per_second.md) - read the number of high-precision timer ticks in a second
-+ [deadline_after](syscalls/deadline_after.md) - Convert a time relative to now to an absolute deadline
-
-## Timers
-+ [timer_create](syscalls/timer_create.md) - create a timer object
-+ [timer_set](syscalls/timer_set.md) - start a timer
-+ [timer_cancel](syscalls/timer_cancel.md) - cancel a timer
-
-## Hypervisor guests
-+ [guest_create](syscalls/guest_create.md) - create a hypervisor guest
-+ [guest_set_trap](syscalls/guest_set_trap.md) - set a trap in a hypervisor guest
-
-## Virtual CPUs
-+ [vcpu_create](syscalls/vcpu_create.md) - create a virtual cpu
-+ [vcpu_resume](syscalls/vcpu_resume.md) - resume execution of a virtual cpu
-+ [vcpu_interrupt](syscalls/vcpu_interrupt.md) - raise an interrupt on a virtual cpu
-+ [vcpu_read_state](syscalls/vcpu_read_state.md) - read state from a virtual cpu
-+ [vcpu_write_state](syscalls/vcpu_write_state.md) - write state to a virtual cpu
-
-## Global system information
-+ [system_get_features](syscalls/system_get_features.md) - get hardware-specific features
-+ [system_get_num_cpus](syscalls/system_get_num_cpus.md) - get number of CPUs
-+ [system_get_physmem](syscalls/system_get_physmem.md) - get physical memory size
-+ [system_get_version](syscalls/system_get_version.md) - get version string
-
-## Debug Logging
-+ [debuglog_create](syscalls/debuglog_create.md) - create a kernel managed debuglog reader or writer
-+ [debuglog_write](syscalls/debuglog_write.md) - write log entry to debuglog
-+ [debuglog_read](syscalls/debuglog_read.md) - read log entries from debuglog
-
-## Multi-function
-+ [vmar_unmap_handle_close_thread_exit](syscalls/vmar_unmap_handle_close_thread_exit.md) - three-in-one
-+ [futex_wake_handle_close_thread_exit](syscalls/futex_wake_handle_close_thread_exit.md) - three-in-one
-
-## System
-+ [system_mexec](syscalls/system_mexec.md) - Soft reboot the system with a new kernel and bootimage
-+ [system_mexec_payload_get](syscalls/system_mexec_payload_get.md) - Return a ZBI containing ZBI entries necessary to boot this system
-
-## DDK
-+ [bti_create](syscalls/bti_create.md) - create a new bus transaction initiator
-+ [bti_pin](syscalls/bti_pin.md) - pin pages and grant devices access to them
-+ [bti_release_quarantine](syscalls/bti_release_quarantine.md) - releases all quarantined PMTs
-+ [cache_flush](syscalls/cache_flush.md) - Flush CPU data and/or instruction caches
-+ [interrupt_ack](syscalls/interrupt_ack.md) - Acknowledge an interrupt object
-+ [interrupt_bind](syscalls/interrupt_bind.md) - Bind an interrupt object to a port
-+ [interrupt_create](syscalls/interrupt_create.md) - Create a physical or virtual interrupt object
-+ [interrupt_destroy](syscalls/interrupt_destroy.md) - Destroy an interrupt object
-+ [interrupt_trigger](syscalls/interrupt_trigger.md) - Trigger a virtual interrupt object
-+ [interrupt_wait](syscalls/interrupt_wait.md) - Wait on an interrupt object
-+ [iommu_create](syscalls/iommu_create.md) - create a new IOMMU object in the kernel
-+ [pmt_unpin](syscalls/pmt_unpin.md) - unpin pages and revoke device access to them
-+ [resource_create](syscalls/resource_create.md) - create a resource object
-+ [smc_call](syscalls/smc_call.md) - Make an SMC call from user space
diff --git a/docs/syscalls/bti_create.md b/docs/syscalls/bti_create.md
deleted file mode 100644
index 2c823b7..0000000
--- a/docs/syscalls/bti_create.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# zx_bti_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-bti_create - create a new bus transaction initiator
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_bti_create(zx_handle_t iommu,
-                          uint32_t options,
-                          uint64_t bti_id,
-                          zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_bti_create()` creates a new [bus transaction initiator](../objects/bus_transaction_initiator.md)
-given a handle to an IOMMU and a hardware transaction identifier for a device
-downstream of that IOMMU.
-
-*options* must be 0 (reserved for future definition of creation flags).
-
-Upon success a handle for the new BTI is returned.  This handle will have rights
-**ZX_RIGHT_READ**, **ZX_RIGHT_WRITE**, **ZX_RIGHT_MAP**, **ZX_RIGHT_INSPECT**,
-**ZX_RIGHT_DUPLICATE**, and **ZX_RIGHT_TRANSFER**.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*iommu* must be of type **ZX_OBJ_TYPE_IOMMU** and have **ZX_RIGHT_NONE**.
-
-## RETURN VALUE
-
-`zx_bti_create()` returns **ZX_OK** and a handle to the new BTI
-(via *out*) on success.  In the event of failure, a negative error value
-is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *iommu* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *iommu* is not an iommu handle.
-
-**ZX_ERR_ACCESS_DENIED**  *iommu* handle does not have sufficient privileges.
-
-**ZX_ERR_INVALID_ARGS**  *bti_id* is invalid on the given IOMMU,
-*out* is an invalid pointer, or *options* is non-zero.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_bti_pin()`]
- - [`zx_bti_release_quarantine()`]
- - [`zx_pmt_unpin()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_bti_pin()`]: bti_pin.md
-[`zx_bti_release_quarantine()`]: bti_release_quarantine.md
-[`zx_pmt_unpin()`]: pmt_unpin.md
diff --git a/docs/syscalls/bti_pin.md b/docs/syscalls/bti_pin.md
deleted file mode 100644
index d2952f4..0000000
--- a/docs/syscalls/bti_pin.md
+++ /dev/null
@@ -1,132 +0,0 @@
-# zx_bti_pin
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-bti_pin - pin pages and grant devices access to them
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_bti_pin(zx_handle_t handle,
-                       uint32_t options,
-                       zx_handle_t vmo,
-                       uint64_t offset,
-                       uint64_t size,
-                       zx_paddr_t* addrs,
-                       size_t addrs_count,
-                       zx_handle_t* pmt);
-```
-
-## DESCRIPTION
-
-`zx_bti_pin()` pins pages of a VMO (i.e. prevents them from being decommitted
-with [`zx_vmo_op_range()`]) and grants the hardware
-transaction ID represented by the BTI the ability to access these pages,
-with the permissions specified in *options*.
-
-*offset* must be aligned to page boundaries.
-
-*options* is a bitfield that may contain one or more of **ZX_BTI_PERM_READ**,
-**ZX_BTI_PERM_WRITE**, **ZX_BTI_PERM_EXECUTE**, **ZX_BTI_COMPRESS**, and
-**ZX_BTI_CONTIGUOUS**.  In order for the call to succeed, *vmo* must have the
-READ/WRITE rights corresponding to the permissions flags set in *options*.
-(Note: **ZX_BTI_PERM_EXECUTE** requires **ZX_RIGHT_READ**, not **ZX_RIGHT_EXECUTE**.)
-**ZX_BTI_CONTIGUOUS** is only allowed if *vmo* was allocated via
-[`zx_vmo_create_contiguous()`] or [`zx_vmo_create_physical()`].
-**ZX_BTI_COMPRESS** and **ZX_BTI_CONTIGUOUS** are mutually exclusive.
-
-If the range in *vmo* specified by *offset* and *size* contains non-committed
-pages, a successful invocation of this function will result in those pages
-having been committed.  On failure, it is undefined whether they have been
-committed.
-
-*addrs* will be populated with the device-physical addresses of the requested
-VMO pages.  These addresses may be given to devices that issue memory
-transactions with the hardware transaction ID associated with the BTI.  The
-number of addresses returned depends on whether the **ZX_BTI_COMPRESS** or
-**ZX_BTI_CONTIGUOUS** options were given.  It number of addresses will be either
-1) If neither is set, one per page (`size*/*PAGE_SIZE`)
-2) If **ZX_BTI_COMPRESS** is set, `size/minimum-contiguity`, rounded up
-   (each address representing a run of *minimum-contiguity* run of bytes,
-   with the last one being potentially short if *size* is not a multiple of
-   *minimum-contiguity*).  It is guaranteed that all returned addresses will be
-   *minimum-contiguity*-aligned.  Note that *minimum-contiguity* is discoverable
-   via [`zx_object_get_info()`].
-3) If **ZX_BTI_CONTIGUOUS** is set, the single address of the start of the memory.
-
-*addrs_count* is the number of entries in the *addrs* array.  It is an error for
-*addrs_count* to not match the value calculated above.
-
-## OPTIONS
-
-- **ZX_BTI_PERM_READ**, **ZX_BTI_PERM_WRITE**, and **ZX_BTI_PERM_EXECUTE** define
-  the access types that the hardware bus transaction initiator will be allowed
-  to use.
-- **ZX_BTI_COMPRESS** causes the returned address list to contain one entry per
-  block of *minimum-contiguity* bytes, rather than one per *PAGE_SIZE*.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_BTI** and have **ZX_RIGHT_MAP**.
-
-*vmo* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_MAP**.
-
-If *options* & **ZX_BTI_PERM_READ**, *vmo* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_READ**.
-
-If *options* & **ZX_BTI_PERM_WRITE**, *vmo* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_WRITE**.
-
-If *options* & **ZX_BTI_PERM_EXECUTE**, *vmo* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-On success, `zx_bti_pin()` returns **ZX_OK**.  The device-physical addresses of the
-requested VMO pages will be written in *addrs*.  A handle to the created Pinned
-Memory Token is returned via *pmt*.  When the PMT is no longer needed,
-[`zx_pmt_unpin()`] should be invoked.
-
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* or *vmo* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a BTI handle or *vmo* is not a VMO handle.
-
-**ZX_ERR_ACCESS_DENIED** *handle* or *vmo* does not have the **ZX_RIGHT_MAP**, or
-*options* contained a permissions flag corresponding to a right that *vmo* does not have.
-
-**ZX_ERR_INVALID_ARGS** *options* is 0 or contains an undefined flag, either *addrs* or *pmt*
-is not a valid pointer, *addrs_count* is not the same as the number of entries that would be
-returned, or *offset* or *size* is not page-aligned.
-
-**ZX_ERR_OUT_OF_RANGE** *offset* + *size* is out of the bounds of *vmo*.
-
-**ZX_ERR_UNAVAILABLE** (Temporary) At least one page in the requested range could
-not be pinned at this time.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_bti_create()`]
- - [`zx_object_get_info()`]
- - [`zx_pmt_unpin()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_bti_create()`]: bti_create.md
-[`zx_object_get_info()`]: object_get_info.md
-[`zx_pmt_unpin()`]: pmt_unpin.md
-[`zx_vmo_create_contiguous()`]: vmo_create_contiguous.md
-[`zx_vmo_create_physical()`]: vmo_create_physical.md
-[`zx_vmo_op_range()`]: vmo_op_range.md
diff --git a/docs/syscalls/bti_release_quarantine.md b/docs/syscalls/bti_release_quarantine.md
deleted file mode 100644
index 9bdc4e8..0000000
--- a/docs/syscalls/bti_release_quarantine.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# zx_bti_release_quarantine
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-bti_release_quarantine - releases all quarantined PMTs
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_bti_release_quarantine(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-`zx_bti_release_quarantine()` releases all quarantined PMTs for the given BTI.
-This will release the PMTs' underlying references to VMOs and physical page
-pins.  The underlying physical pages may be eligible to be reallocated
-afterwards.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_BTI** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_bti_release_quarantine()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a BTI handle.
-
-**ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_WRITE** right.
-
-## SEE ALSO
-
- - [`zx_bti_pin()`]
- - [`zx_pmt_unpin()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_bti_pin()`]: bti_pin.md
-[`zx_pmt_unpin()`]: pmt_unpin.md
diff --git a/docs/syscalls/cache_flush.md b/docs/syscalls/cache_flush.md
deleted file mode 100644
index 34aa450..0000000
--- a/docs/syscalls/cache_flush.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# zx_cache_flush
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-cache_flush - Flush CPU data and/or instruction caches
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_cache_flush(const void* addr, size_t size, uint32_t options);
-```
-
-## DESCRIPTION
-
-`zx_cache_flush()` flushes CPU caches covering memory in the given
-virtual address range.  If that range of memory is not readable, then
-the thread may fault as it would for a data read.
-
-*options* is a bitwise OR of:
-
- * **ZX_CACHE_FLUSH_DATA**
-
-   Clean (write back) data caches, so previous writes on this CPU are
-   visible in main memory.
-
- * **ZX_CACHE_FLUSH_INVALIDATE**
-   (valid only when combined with **ZX_CACHE_FLUSH_DATA**)
-
-   Clean (write back) data caches and then invalidate data caches, so
-   previous writes on this CPU are visible in main memory and future
-   reads on this CPU see external changes to main memory.
-
- * **ZX_CACHE_FLUSH_INSN**
-
-   Synchronize instruction caches with data caches, so previous writes
-   on this CPU are visible to instruction fetches.  If this is combined
-   with **ZX_CACHE_FLUSH_DATA**, then previous writes will be visible to
-   main memory as well as to instruction fetches.
-
-At least one of **ZX_CACHE_FLUSH_DATA** and **ZX_CACHE_FLUSH_INSN**
-must be included in *options*.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_cache_flush()` returns **ZX_OK** on success, or an error code on failure.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS** *options* is invalid.
diff --git a/docs/syscalls/channel_call.md b/docs/syscalls/channel_call.md
deleted file mode 100644
index 69eaebd..0000000
--- a/docs/syscalls/channel_call.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# zx_channel_call
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-channel_call - send a message to a channel and await a reply
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_channel_call(zx_handle_t handle,
-                            uint32_t options,
-                            zx_time_t deadline,
-                            const zx_channel_call_args_t* args,
-                            uint32_t* actual_bytes,
-                            uint32_t* actual_handles);
-```
-
-## DESCRIPTION
-
-`zx_channel_call()` is like a combined [`zx_channel_write()`], [`zx_object_wait_one()`],
-and [`zx_channel_read()`], with the addition of a feature where a transaction id at
-the front of the message payload *bytes* is used to match reply messages with send
-messages, enabling multiple calling threads to share a channel without any additional
-userspace bookkeeping.
-
-The write and read phases of this operation behave like [`zx_channel_write()`] and
-[`zx_channel_read()`] with the difference that their parameters are provided via the
-`zx_channel_call_args_t` structure.
-
-The first four bytes of the written and read back messages are treated as a
-transaction ID of type `zx_txid_t`.  The kernel generates a txid for the
-written message, replacing that part of the message as read from userspace.
-The kernel generated txid will be between 0x80000000 and 0xFFFFFFFF, and will
-not collide with any txid from any other `zx_channel_call()` in progress against
-this channel endpoint.  If the written message has a length of fewer than four
-bytes, an error is reported.
-
-When the outbound message is written, simultaneously an interest is registered
-for inbound messages of the matching txid.
-
-*deadline* may be automatically adjusted according to the job's [timer slack]
-policy.
-
-While the slack-adjusted *deadline* has not passed, if an inbound message
-arrives with a matching txid, instead of being added to the tail of the general
-inbound message queue, it is delivered directly to the thread waiting in
-`zx_channel_call()`.
-
-If such a reply arrives after the slack-adjusted *deadline* has passed, it will
-arrive in the general inbound message queue, cause **ZX_CHANNEL_READABLE** to be
-signaled, etc.
-
-Inbound messages that are too large to fit in *rd_num_bytes* and *rd_num_handles*
-are discarded and **ZX_ERR_BUFFER_TOO_SMALL** is returned in that case.
-
-As with [`zx_channel_write()`], the handles in *handles* are always consumed by
-`zx_channel_call()` and no longer exist in the calling process.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_CHANNEL** and have **ZX_RIGHT_READ** and have **ZX_RIGHT_WRITE**.
-
-All wr_handles of *args* must have **ZX_RIGHT_TRANSFER**.
-
-## RETURN VALUE
-
-`zx_channel_call()` returns **ZX_OK** on success and the number of bytes and
-count of handles in the reply message are returned via *actual_bytes* and
-*actual_handles*, respectively.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle, any element in
-*handles* is not a valid handle, or there are duplicates among the handles
-in the *handles* array.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a channel handle.
-
-**ZX_ERR_INVALID_ARGS**  any of the provided pointers are invalid or null,
-or *wr_num_bytes* is less than four, or *options* is nonzero.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_WRITE** or
-any element in *handles* does not have **ZX_RIGHT_TRANSFER**.
-
-**ZX_ERR_PEER_CLOSED**  The other side of the channel was closed or became
-closed while waiting for the reply.
-
-**ZX_ERR_CANCELED**  *handle* was closed while waiting for a reply.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_OUT_OF_RANGE**  *wr_num_bytes* or *wr_num_handles* are larger than the
-largest allowable size for channel messages.
-
-**ZX_ERR_BUFFER_TOO_SMALL**  *rd_num_bytes* or *rd_num_handles* are too small
-to contain the reply message.
-
-**ZX_ERR_NOT_SUPPORTED**  one of the handles in *handles* was *handle*
-(the handle to the channel being written to).
-
-## NOTES
-
-The facilities provided by `zx_channel_call()` can interoperate with message dispatchers
-using [`zx_channel_read()`] and [`zx_channel_write()`] directly, provided the following rules
-are observed:
-
-1. A server receiving synchronous messages via [`zx_channel_read()`] should ensure that the
-txid of incoming messages is reflected back in outgoing responses via [`zx_channel_write()`]
-so that clients using `zx_channel_call()` can correctly route the replies.
-
-2. A client sending messages via [`zx_channel_write()`] that will be replied to should ensure
-that it uses txids between 0 and 0x7FFFFFFF only, to avoid colliding with other threads
-communicating via `zx_channel_call()`.
-
-If a `zx_channel_call()` returns due to **ZX_ERR_TIMED_OUT**, if the server eventually replies,
-at some point in the future, the reply *could* match another outbound request (provided about
-2^31 `zx_channel_call()`s have happened since the original request.  This syscall is designed
-around the expectation that timeouts are generally fatal and clients do not expect to continue
-communications on a channel that is timing out.
-
-## SEE ALSO
-
- - [timer slack]
- - [`zx_channel_create()`]
- - [`zx_channel_read()`]
- - [`zx_channel_write()`]
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
-
-[timer slack]: ../timer_slack.md
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_channel_create()`]: channel_create.md
-[`zx_channel_read()`]: channel_read.md
-[`zx_channel_write()`]: channel_write.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/channel_call_finish.md b/docs/syscalls/channel_call_finish.md
deleted file mode 100644
index 85a21d0..0000000
--- a/docs/syscalls/channel_call_finish.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_channel_call_finish
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-channel_call_finish - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_channel_call_finish(zx_time_t deadline,
-                                   const zx_channel_call_args_t* args,
-                                   uint32_t* actual_bytes,
-                                   uint32_t* actual_handles);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/channel_call_noretry.md b/docs/syscalls/channel_call_noretry.md
deleted file mode 100644
index bae8011..0000000
--- a/docs/syscalls/channel_call_noretry.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# zx_channel_call_noretry
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-channel_call_noretry - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_channel_call_noretry(zx_handle_t handle,
-                                    uint32_t options,
-                                    zx_time_t deadline,
-                                    const zx_channel_call_args_t* args,
-                                    uint32_t* actual_bytes,
-                                    uint32_t* actual_handles);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_CHANNEL** and have **ZX_RIGHT_READ** and have **ZX_RIGHT_WRITE**.
-
-All wr_handles of *args* must have **ZX_RIGHT_TRANSFER**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/channel_create.md b/docs/syscalls/channel_create.md
deleted file mode 100644
index ebcab9f..0000000
--- a/docs/syscalls/channel_create.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# zx_channel_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-channel_create - create a channel
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_channel_create(uint32_t options,
-                              zx_handle_t* out0,
-                              zx_handle_t* out1);
-```
-
-## DESCRIPTION
-
-`zx_channel_create()` creates a channel, a bi-directional
-datagram-style message transport capable of sending raw data bytes
-as well as handles from one side to the other.
-
-Two handles are returned on success, providing access to both sides
-of the channel.  Messages written to one handle may be read from
-the opposite.
-
-The handles will have **ZX_RIGHT_TRANSFER** (allowing them to be sent
-to another process via channel write), **ZX_RIGHT_WRITE** (allowing
-messages to be written to them), and **ZX_RIGHT_READ** (allowing messages
-to be read from them).
-
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_channel_create()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *out0* or *out1* is an invalid pointer or NULL or
-*options* is any value other than 0.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_channel_call()`]
- - [`zx_channel_read()`]
- - [`zx_channel_write()`]
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_channel_call()`]: channel_call.md
-[`zx_channel_read()`]: channel_read.md
-[`zx_channel_write()`]: channel_write.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/channel_read.md b/docs/syscalls/channel_read.md
deleted file mode 100644
index 22b934b..0000000
--- a/docs/syscalls/channel_read.md
+++ /dev/null
@@ -1,111 +0,0 @@
-# zx_channel_read
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-channel_read - read a message from a channel
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_channel_read(zx_handle_t handle,
-                            uint32_t options,
-                            void* bytes,
-                            zx_handle_t* handles,
-                            uint32_t num_bytes,
-                            uint32_t num_handles,
-                            uint32_t* actual_bytes,
-                            uint32_t* actual_handles);
-```
-
-## DESCRIPTION
-
-`zx_channel_read()` attempts to read the first message from the channel
-specified by *handle* into the provided *bytes* and/or *handles* buffers.
-
-The parameters *num_bytes* and *num_handles* are used to specify the
-size of the respective read buffers.
-
-Channel messages may contain both byte data and handle payloads and may
-only be read in their entirety.  Partial reads are not possible.
-
-The *bytes* buffer is written before the *handles* buffer. In the event of
-overlap between these two buffers, the contents written to *handles*
-will overwrite the portion of *bytes* it overlaps.
-
-When communicating to an untrusted party over a channel, it is recommended that
-the [`zx_channel_read_etc()`] form is used and each handle type
-and rights are validated against the expected values.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_CHANNEL** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-Both forms of read return **ZX_OK** on success, if *actual_bytes*
-and *actual_handles* (if non-NULL), contain the exact number of bytes
-and count of handles read.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a channel handle.
-
-**ZX_ERR_INVALID_ARGS**  If any of *bytes*, *handles*, *actual_bytes*, or
-*actual_handles* are non-NULL and an invalid pointer.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_READ**.
-
-**ZX_ERR_SHOULD_WAIT**  The channel contained no messages to read.
-
-**ZX_ERR_PEER_CLOSED**  The other side of the channel is closed.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_BUFFER_TOO_SMALL**  The provided *bytes* or *handles* buffers
-are too small (in which case, the minimum sizes necessary to receive
-the message will be written to *actual_bytes* and *actual_handles*,
-provided they are non-NULL). If *options* has **ZX_CHANNEL_READ_MAY_DISCARD**
-set, then the message is discarded.
-
-## NOTES
-
-*num_handles* and *actual_handles* are counts of the number of elements
-in the *handles* array, not its size in bytes.
-
-## SEE ALSO
-
- - [`zx_channel_call()`]
- - [`zx_channel_create()`]
- - [`zx_channel_read_etc()`]
- - [`zx_channel_write()`]
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_channel_call()`]: channel_call.md
-[`zx_channel_create()`]: channel_create.md
-[`zx_channel_read_etc()`]: channel_read_etc.md
-[`zx_channel_write()`]: channel_write.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/channel_read_etc.md b/docs/syscalls/channel_read_etc.md
deleted file mode 100644
index 0270ea7..0000000
--- a/docs/syscalls/channel_read_etc.md
+++ /dev/null
@@ -1,113 +0,0 @@
-# zx_channel_read_etc
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-channel_read_etc - read a message from a channel
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_channel_read_etc(zx_handle_t handle,
-                                uint32_t options,
-                                void* bytes,
-                                zx_handle_info_t* handles,
-                                uint32_t num_bytes,
-                                uint32_t num_handles,
-                                uint32_t* actual_bytes,
-                                uint32_t* actual_handles);
-```
-
-## DESCRIPTION
-
-See [`zx_channel_read()`] for a full description.
-
-Both forms of read behave the same except that [`zx_channel_read()`] returns an
-array of raw `zx_handle_t` handle values while `zx_channel_read_etc()` returns
-an array of `zx_handle_info_t` structures of the form:
-
-```
-typedef struct {
-    zx_handle_t handle;     // handle value
-    zx_obj_type_t type;     // type of object, see ZX_OBJ_TYPE_
-    zx_rights_t rights;     // handle rights
-    uint32_t unused;        // set to zero
-} zx_handle_info_t;
-```
-
-When communicating to an untrusted party over a channel, it is recommended
-that the `zx_channel_read_etc()` form is used and each handle type and rights
-are validated against the expected values.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_CHANNEL** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-Both forms of read return **ZX_OK** on success, if *actual_bytes*
-and *actual_handles* (if non-NULL), contain the exact number of bytes
-and count of handles read.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a channel handle.
-
-**ZX_ERR_INVALID_ARGS**  If any of *bytes*, *handles*, *actual_bytes*, or
-*actual_handles* are non-NULL and an invalid pointer.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_READ**.
-
-**ZX_ERR_SHOULD_WAIT**  The channel contained no messages to read.
-
-**ZX_ERR_PEER_CLOSED**  The other side of the channel is closed.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_BUFFER_TOO_SMALL**  The provided *bytes* or *handles* buffers
-are too small (in which case, the minimum sizes necessary to receive
-the message will be written to *actual_bytes* and *actual_handles*,
-provided they are non-NULL). If *options* has **ZX_CHANNEL_READ_MAY_DISCARD**
-set, then the message is discarded.
-
-## NOTES
-
-*num_handles* and *actual_handles* are counts of the number of elements
-in the *handles* array, not its size in bytes.
-
-## SEE ALSO
-
- - [`zx_channel_call()`]
- - [`zx_channel_create()`]
- - [`zx_channel_read()`]
- - [`zx_channel_write()`]
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_channel_call()`]: channel_call.md
-[`zx_channel_create()`]: channel_create.md
-[`zx_channel_read()`]: channel_read.md
-[`zx_channel_write()`]: channel_write.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/channel_write.md b/docs/syscalls/channel_write.md
deleted file mode 100644
index b3fb590..0000000
--- a/docs/syscalls/channel_write.md
+++ /dev/null
@@ -1,115 +0,0 @@
-# zx_channel_write
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-channel_write - write a message to a channel
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_channel_write(zx_handle_t handle,
-                             uint32_t options,
-                             const void* bytes,
-                             uint32_t num_bytes,
-                             const zx_handle_t* handles,
-                             uint32_t num_handles);
-```
-
-## DESCRIPTION
-
-`zx_channel_write()` attempts to write a message of *num_bytes*
-bytes and *num_handles* handles to the channel specified by
-*handle*.  The pointers *handles* and *bytes* may be NULL if their
-respective sizes are zero.
-
-On success, all *num_handles* of the handles in the *handles* array
-are no longer accessible to the caller's process -- they are attached
-to the message and will become available to the reader of that message
-from the opposite end of the channel.  On any failure, all handles
-are discarded rather than transferred.
-
-It is invalid to include *handle* (the handle of the channel being written
-to) in the *handles* array (the handles being sent in the message).
-
-The maximum number of handles which may be sent in a message is
-**ZX_CHANNEL_MAX_MSG_HANDLES**, which is 64.
-
-The maximum number of bytes which may be sent in a message is
-**ZX_CHANNEL_MAX_MSG_BYTES**, which is 65536.
-
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_CHANNEL** and have **ZX_RIGHT_WRITE**.
-
-Every entry of *handles* must have **ZX_RIGHT_TRANSFER**.
-
-## RETURN VALUE
-
-`zx_channel_write()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle, any element in
-*handles* is not a valid handle, or there are duplicates among the handles
-in the *handles* array.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a channel handle.
-
-**ZX_ERR_INVALID_ARGS**  *bytes* is an invalid pointer, *handles*
-is an invalid pointer, or *options* is nonzero.
-
-**ZX_ERR_NOT_SUPPORTED**  *handle* was found in the *handles* array, or
-one of the handles in *handles* was *handle* (the handle to the
-channel being written to).
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_WRITE** or
-any element in *handles* does not have **ZX_RIGHT_TRANSFER**.
-
-**ZX_ERR_PEER_CLOSED**  The other side of the channel is closed.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_OUT_OF_RANGE**  *num_bytes* or *num_handles* are larger than the
-largest allowable size for channel messages.
-
-## NOTES
-
-*num_handles* is a count of the number of elements in the *handles*
-array, not its size in bytes.
-
-The byte size limitation on messages is not yet finalized.
-
-## SEE ALSO
-
- - [`zx_channel_call()`]
- - [`zx_channel_create()`]
- - [`zx_channel_read()`]
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_channel_call()`]: channel_call.md
-[`zx_channel_create()`]: channel_create.md
-[`zx_channel_read()`]: channel_read.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/clock_adjust.md b/docs/syscalls/clock_adjust.md
deleted file mode 100644
index 244a462..0000000
--- a/docs/syscalls/clock_adjust.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_clock_adjust
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-clock_adjust - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_clock_adjust(zx_handle_t handle,
-                            zx_clock_t clock_id,
-                            int64_t offset);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/clock_get.md b/docs/syscalls/clock_get.md
deleted file mode 100644
index 72820f4..0000000
--- a/docs/syscalls/clock_get.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# zx_clock_get
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-clock_get - Acquire the current time.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_time_t zx_clock_get(zx_clock_t clock_id);
-```
-
-## DESCRIPTION
-
-`zx_clock_get()` returns the current time of *clock_id*, or 0 if *clock_id* is
-invalid.
-
-## SUPPORTED CLOCK IDS
-
-**ZX_CLOCK_MONOTONIC** number of nanoseconds since the system was powered on.
-
-**ZX_CLOCK_UTC** number of wall clock nanoseconds since the Unix epoch (midnight on January 1 1970) in UTC
-
-**ZX_CLOCK_THREAD** number of nanoseconds the current thread has been running for.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-On success, `zx_clock_get()` returns the current time according to the given clock ID.
-
-## ERRORS
-
-On error, `zx_clock_get()` returns 0.
diff --git a/docs/syscalls/clock_get_monotonic.md b/docs/syscalls/clock_get_monotonic.md
deleted file mode 100644
index e16b23d..0000000
--- a/docs/syscalls/clock_get_monotonic.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# zx_clock_get_monotonic
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-clock_get_monotonic - Acquire the current monotonic time.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_time_t zx_clock_get_monotonic(void);
-```
-
-## DESCRIPTION
-
-`zx_clock_get_monotonic()` returns the current time in the system
-monotonic clock. This is the number of nanoseconds since the system was
-powered on.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-[`zx_clock_get()`] returns the current monotonic time.
-
-## ERRORS
-
-`zx_clock_get_monotonic()` cannot fail.
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_clock_get()`]: clock_get.md
diff --git a/docs/syscalls/clock_get_new.md b/docs/syscalls/clock_get_new.md
deleted file mode 100644
index fe59fe5..0000000
--- a/docs/syscalls/clock_get_new.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# zx_clock_get_new
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-clock_get_new - Acquire the current time.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_clock_get_new(zx_clock_t clock_id, zx_time_t* out);
-```
-
-## DESCRIPTION
-
-`zx_clock_get_new()` returns the current time of *clock_id* via
-*out*, and returns whether *clock_id* was valid.
-
-## SUPPORTED CLOCK IDS
-
-**ZX_CLOCK_MONOTONIC** number of nanoseconds since the system was powered on.
-
-**ZX_CLOCK_UTC** number of wall clock nanoseconds since the Unix epoch (midnight on January 1 1970) in UTC
-
-**ZX_CLOCK_THREAD** number of nanoseconds the current thread has been running for.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-On success, `zx_clock_get_new()` returns **ZX_OK**.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *clock_id* is not a valid clock id, or *out* is an invalid pointer.
diff --git a/docs/syscalls/cprng_add_entropy.md b/docs/syscalls/cprng_add_entropy.md
deleted file mode 100644
index e4cfc32..0000000
--- a/docs/syscalls/cprng_add_entropy.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_cprng_add_entropy
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-cprng_add_entropy - Add entropy to the kernel CPRNG
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_cprng_add_entropy(const void* buffer, size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_cprng_add_entropy()` mixes the given entropy into the kernel CPRNG.
-a privileged operation.  It will accept at most **ZX_CPRNG_ADD_ENTROPY_MAX_LEN**
-bytes of entropy at a time.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_cprng_add_entropy()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS** *buffer_size* is too large, or *buffer* is not a valid
-userspace pointer.
-
-## BUGS
-
-This syscall should be very privileged.
diff --git a/docs/syscalls/cprng_draw.md b/docs/syscalls/cprng_draw.md
deleted file mode 100644
index 5dcf44b..0000000
--- a/docs/syscalls/cprng_draw.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# zx_cprng_draw
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-cprng_draw - Draw from the kernel's CPRNG
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-void zx_cprng_draw(void* buffer, size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_cprng_draw()` draws random bytes from the kernel CPRNG.  This data should
-be suitable for cryptographic applications.
-
-Clients that require a large volume of randomness should consider using these
-bytes to seed a user-space random number generator for better performance.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## NOTES
-
-`zx_cprng_draw()` triggers terminates the calling process if **buffer** is not
-a valid userspace pointer.
-
-There are no other error conditions.  If its arguments are valid,
-`zx_cprng_draw()` will succeed.
diff --git a/docs/syscalls/cprng_draw_once.md b/docs/syscalls/cprng_draw_once.md
deleted file mode 100644
index a81268b..0000000
--- a/docs/syscalls/cprng_draw_once.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_cprng_draw_once
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-cprng_draw_once - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_cprng_draw_once(void* buffer, size_t buffer_size);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/deadline_after.md b/docs/syscalls/deadline_after.md
deleted file mode 100644
index 72423c9..0000000
--- a/docs/syscalls/deadline_after.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# zx_deadline_after
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-deadline_after - Convert a time relative to now to an absolute deadline
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_time_t zx_deadline_after(zx_duration_t nanoseconds);
-```
-
-## DESCRIPTION
-
-`zx_deadline_after()` is a utility for converting from now-relative durations
-to absolute deadlines. If *nanoseconds* plus the current time is bigger than the
-maximum value for `zx_time_t`, the output is clamped to **ZX_TIME_INFINITE**.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_deadline_after()` returns the absolute time (with respect to **ZX_CLOCK_MONOTONIC**)
-that is *nanoseconds* nanoseconds from now.
-
-## ERRORS
-
-`zx_deadline_after()` does not report any error conditions.
-
-## EXAMPLES
-
-```
-// Sleep 50 milliseconds
-zx_time_t deadline = zx_deadline_after(ZX_MSEC(50));
-zx_nanosleep(deadline);
-```
-
-## SEE ALSO
-
-
-[ticks_get](ticks_get.md)
diff --git a/docs/syscalls/debug_read.md b/docs/syscalls/debug_read.md
deleted file mode 100644
index 2ce7165..0000000
--- a/docs/syscalls/debug_read.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_debug_read
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-debug_read - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_debug_read(zx_handle_t handle,
-                          char* buffer,
-                          size_t* buffer_size);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/debug_send_command.md b/docs/syscalls/debug_send_command.md
deleted file mode 100644
index dc8cff9..0000000
--- a/docs/syscalls/debug_send_command.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_debug_send_command
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-debug_send_command - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_debug_send_command(zx_handle_t resource,
-                                  const char* buffer,
-                                  size_t buffer_size);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/debug_write.md b/docs/syscalls/debug_write.md
deleted file mode 100644
index 8b4bf17..0000000
--- a/docs/syscalls/debug_write.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_debug_write
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-debug_write - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_debug_write(const char* buffer, size_t buffer_size);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/debuglog_create.md b/docs/syscalls/debuglog_create.md
deleted file mode 100644
index 6292322..0000000
--- a/docs/syscalls/debuglog_create.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_debuglog_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-debuglog_create - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_debuglog_create(zx_handle_t resource,
-                               uint32_t options,
-                               zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/debuglog_read.md b/docs/syscalls/debuglog_read.md
deleted file mode 100644
index d8bd290..0000000
--- a/docs/syscalls/debuglog_read.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_debuglog_read
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-debuglog_read - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_debuglog_read(zx_handle_t handle,
-                             uint32_t options,
-                             void* buffer,
-                             size_t buffer_size);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_LOG** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/debuglog_write.md b/docs/syscalls/debuglog_write.md
deleted file mode 100644
index 1968282..0000000
--- a/docs/syscalls/debuglog_write.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_debuglog_write
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-debuglog_write - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_debuglog_write(zx_handle_t handle,
-                              uint32_t options,
-                              const void* buffer,
-                              size_t buffer_size);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_LOG** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/event_create.md b/docs/syscalls/event_create.md
deleted file mode 100644
index c432fd6..0000000
--- a/docs/syscalls/event_create.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# zx_event_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-event_create - create an event
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_event_create(uint32_t options, zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_event_create()` creates an event, which is an object that is signalable. That
-is, its **ZX_USER_SIGNAL_n** (where *n* is 0 through 7) signals can be
-manipulated using [`zx_object_signal()`].
-
-The newly-created handle will have the [basic
-rights](../rights.md#zx_rights_basic) plus **ZX_RIGHT_SIGNAL**.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_event_create()` returns **ZX_OK** and a valid event handle (via *out*) on success.
-On failure, an error value is returned.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *out* is an invalid pointer, or *options* is nonzero.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_eventpair_create()`]
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_signal()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_eventpair_create()`]: eventpair_create.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_signal()`]: object_signal.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/eventpair_create.md b/docs/syscalls/eventpair_create.md
deleted file mode 100644
index bc6812d..0000000
--- a/docs/syscalls/eventpair_create.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# zx_eventpair_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-eventpair_create - create an event pair
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_eventpair_create(uint32_t options,
-                                zx_handle_t* out0,
-                                zx_handle_t* out1);
-```
-
-## DESCRIPTION
-
-`zx_eventpair_create()` creates an event pair, which is a pair of objects that
-are mutually signalable.
-
-The signals **ZX_EVENTPAIR_SIGNALED** and **ZX_USER_SIGNAL_n** (where *n* is 0 through 7)
-may be set or cleared using [`zx_object_signal()`] (modifying the signals on the
-object itself), or [`zx_object_signal_peer()`] (modifying the signals on its
-counterpart).
-
-When all the handles to one of the objects have been closed, the
-**ZX_EVENTPAIR_PEER_CLOSED** signal will be asserted on the opposing object.
-
-The newly-created handles will have the **ZX_RIGHT_TRANSFER**,
-**ZX_RIGHT_DUPLICATE**, **ZX_RIGHT_READ**, **ZX_RIGHT_WRITE**, **ZX_RIGHT_SIGNAL**,
-and **ZX_RIGHT_SIGNAL_PEER** rights.
-
-Currently, no options are supported, so *options* must be set to 0.
-
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_eventpair_create()` returns **ZX_OK** on success. On failure, a (negative)
-error code is returned.
-
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *out0* or *out1* is an invalid pointer or NULL.
-
-**ZX_ERR_NOT_SUPPORTED**  *options* has an unsupported flag set (i.e., is not 0).
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-
-## SEE ALSO
-
- - [`zx_event_create()`]
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_signal()`]
- - [`zx_object_signal_peer()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_event_create()`]: event_create.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_signal()`]: object_signal.md
-[`zx_object_signal_peer()`]: object_signal_peer.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/fifo_create.md b/docs/syscalls/fifo_create.md
deleted file mode 100644
index 8474f5a..0000000
--- a/docs/syscalls/fifo_create.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# zx_fifo_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-fifo_create - create a fifo
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_fifo_create(size_t elem_count,
-                           size_t elem_size,
-                           uint32_t options,
-                           zx_handle_t* out0,
-                           zx_handle_t* out1);
-```
-
-## DESCRIPTION
-
-`zx_fifo_create()` creates a fifo, which is actually a pair of fifos
-of *elem_count* entries of *elem_size* bytes.  Two endpoints are
-returned.  Writing to one endpoint enqueues an element into the fifo
-that the opposing endpoint reads from.
-
-Fifos are intended to be the control plane for shared memory transports.
-Their read and write operations are more efficient than *sockets* or
-*channels*, but there are severe restrictions on the size of elements
-and buffers.
-
-The *elem_count* must be a power of two.  The total size of each fifo
-(`elem_count * elem_size`) may not exceed 4096 bytes.
-
-The *options* argument must be 0.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_fifo_create()` returns **ZX_OK** on success. In the event of
-failure, one of the following values is returned.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *out0* or *out1* is an invalid pointer or NULL or
-*options* is any value other than 0.
-
-**ZX_ERR_OUT_OF_RANGE**  *elem_count* or *elem_size* is zero, or *elem_count*
-is not a power of two, or *elem_count* * *elem_size* is greater than 4096.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-
-## SEE ALSO
-
- - [`zx_fifo_read()`]
- - [`zx_fifo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_fifo_read()`]: fifo_read.md
-[`zx_fifo_write()`]: fifo_write.md
diff --git a/docs/syscalls/fifo_read.md b/docs/syscalls/fifo_read.md
deleted file mode 100644
index b026ff1..0000000
--- a/docs/syscalls/fifo_read.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# zx_fifo_read
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-fifo_read - read data from a fifo
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_fifo_read(zx_handle_t handle,
-                         size_t elem_size,
-                         void* data,
-                         size_t count,
-                         size_t* actual_count);
-```
-
-## DESCRIPTION
-
-`zx_fifo_read()` attempts to read up to *count* elements from the fifo
-*handle* into *data*.
-
-Fewer elements may be read than requested if there are insufficient
-elements in the fifo to fulfill the entire request. The number of
-elements actually read is returned via *actual_count*.
-
-The element size specified by *elem_size* must match the element size
-that was passed into [`zx_fifo_create()`].
-
-*data* must have a size of at least `count * elem_size` bytes.
-
-*actual_count* is allowed to be NULL. This is useful when reading
-a single element: if *count* is 1 and `zx_fifo_read()` returns **ZX_OK**,
-*actual_count* is guaranteed to be 1 and thus can be safely ignored.
-
-It is not legal to read zero elements.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_FIFO** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_fifo_read()` returns **ZX_OK** on success, and returns
-the number of elements read (at least one) via *actual_count*.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a fifo handle.
-
-**ZX_ERR_INVALID_ARGS**  *data* is an invalid pointer or *actual_count*
-is an invalid pointer.
-
-**ZX_ERR_OUT_OF_RANGE**  *count* is zero or *elem_size* is not equal
-to the element size of the fifo.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_READ**.
-
-**ZX_ERR_PEER_CLOSED**  The other side of the fifo is closed.
-
-**ZX_ERR_SHOULD_WAIT**  The fifo is empty.
-
-
-## SEE ALSO
-
- - [`zx_fifo_create()`]
- - [`zx_fifo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_fifo_create()`]: fifo_create.md
-[`zx_fifo_write()`]: fifo_write.md
diff --git a/docs/syscalls/fifo_write.md b/docs/syscalls/fifo_write.md
deleted file mode 100644
index fce35fc..0000000
--- a/docs/syscalls/fifo_write.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# zx_fifo_write
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-fifo_write - write data to a fifo
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_fifo_write(zx_handle_t handle,
-                          size_t elem_size,
-                          const void* data,
-                          size_t count,
-                          size_t* actual_count);
-```
-
-## DESCRIPTION
-
-`zx_fifo_write()` attempts to write up to *count* elements
-(`count * elem_size` bytes) from *data* to the fifo specified by *handle*.
-
-Fewer elements may be written than requested if there is insufficient
-room in the fifo to contain all of them. The number of
-elements actually written is returned via *actual_count*.
-
-The element size specified by *elem_size* must match the element size
-that was passed into [`zx_fifo_create()`].
-
-*actual_count* is allowed to be NULL. This is useful when writing
-a single element: if *count* is 1 and `zx_fifo_write()` returns **ZX_OK**,
-*actual_count* is guaranteed to be 1 and thus can be safely ignored.
-
-It is not legal to write zero elements.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_FIFO** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_fifo_write()` returns **ZX_OK** on success, and returns
-the number of elements written (at least one) via *actual_count*.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a fifo handle.
-
-**ZX_ERR_INVALID_ARGS**  *data* is an invalid pointer or *actual_count*
-is an invalid pointer.
-
-**ZX_ERR_OUT_OF_RANGE**  *count* is zero or *elem_size* is not equal
-to the element size of the fifo.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_PEER_CLOSED**  The other side of the fifo is closed.
-
-**ZX_ERR_SHOULD_WAIT**  The fifo is full.
-
-
-## SEE ALSO
-
- - [`zx_fifo_create()`]
- - [`zx_fifo_read()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_fifo_create()`]: fifo_create.md
-[`zx_fifo_read()`]: fifo_read.md
diff --git a/docs/syscalls/framebuffer_get_info.md b/docs/syscalls/framebuffer_get_info.md
deleted file mode 100644
index 71459cd..0000000
--- a/docs/syscalls/framebuffer_get_info.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# zx_framebuffer_get_info
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-framebuffer_get_info - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_framebuffer_get_info(zx_handle_t resource,
-                                    uint32_t* format,
-                                    uint32_t* width,
-                                    uint32_t* height,
-                                    uint32_t* stride);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/framebuffer_set_range.md b/docs/syscalls/framebuffer_set_range.md
deleted file mode 100644
index 6519e5f..0000000
--- a/docs/syscalls/framebuffer_set_range.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# zx_framebuffer_set_range
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-framebuffer_set_range - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_framebuffer_set_range(zx_handle_t resource,
-                                     zx_handle_t vmo,
-                                     uint32_t len,
-                                     uint32_t format,
-                                     uint32_t width,
-                                     uint32_t height,
-                                     uint32_t stride);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/futex_get_owner.md b/docs/syscalls/futex_get_owner.md
deleted file mode 100644
index 56c3c6b..0000000
--- a/docs/syscalls/futex_get_owner.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# zx_futex_get_owner
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_get_owner - Fetch the koid current owner of a futex, if any.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_futex_get_owner(const zx_futex_t* value_ptr, zx_koid_t* koid);
-```
-
-## DESCRIPTION
-
-Fetch the koid of the current owner of the futex identified by *value_ptr*, or
-**ZX_KOID_INVALID** if there is no current owner.  Knowledge of the ownership of
-a futex typically serves no purpose when building synchronization primitives
-from futexes.  This syscall is used primarily for testing.
-
-See *Ownership and Priority Inheritance* in [futex](../objects/futex.md) for
-details.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_futex_get_owner()` returns **ZX_OK** on success, and koids hold the owner of
-the futex at the time of the syscall, or **ZX_KOID_INVALID** if there was no
-owner.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  One of the following is true:
-+ *value_ptr* is not a valid userspace pointer.
-+ *value_ptr* is not aligned to a `sizeof(zx_futex_t)` boundary.
-+ *koid* is not a valid userspace pointer.
-
-## SEE ALSO
-
-
-[futex objects](../objects/futex.md)
diff --git a/docs/syscalls/futex_requeue.md b/docs/syscalls/futex_requeue.md
deleted file mode 100644
index 7eefea7..0000000
--- a/docs/syscalls/futex_requeue.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# zx_futex_requeue
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_requeue - Wake some number of threads waiting on a futex, and move more waiters to another wait queue.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_futex_requeue(const zx_futex_t* value_ptr,
-                             uint32_t wake_count,
-                             zx_futex_t current_value,
-                             const zx_futex_t* requeue_ptr,
-                             uint32_t requeue_count,
-                             zx_handle_t new_requeue_owner);
-```
-
-## DESCRIPTION
-
-Requeuing is a generalization of waking. First, the kernel verifies
-that the value in *current_value* matches the value of the futex at
-*value_ptr*, and if not reports **ZX_ERR_BAD_STATE**. After waking *wake_count*
-threads, *requeue_count* threads are moved from the original futex's
-wait queue to the wait queue corresponding to *requeue_ptr*, another
-futex.
-
-This requeueing behavior may be used to avoid thundering herds on wake.
-
-## OWNERSHIP
-
-A requeue operation targets two futexes, the _wake futex_ and the _requeue
-futex_.  The ownership implications for each are discussed separately.
-Generally, if the call fails for any reason, no changes to ownership for either
-futex are made.
-
-See *Ownership and Priority Inheritance* in [futex](../objects/futex.md) for
-details.
-
-### Effects on the _wake futex_ target
-
-A successful call to `zx_futex_requeue()` results in the owner of the futex being
-set to nothing, regardless of the wake count.  In order to transfer ownership of
-a futex, use the [`zx_futex_requeue_single_owner()`] variant instead.
-[`zx_futex_requeue_single_owner()`] will attempt to wake exactly one thread from the
-futex wait queue.  If there is at least one thread to wake, the owner of the futex will be
-set to the thread which was woken.  Otherwise, the futex
-will have no owner.
-
-### Effects on the _requeue futex_ target
-
-A successful call to `zx_futex_requeue()` or [`zx_futex_requeue_single_owner()`]
-results in the owner of the futex being set to the thread referenced by the
-*new_requeue_owner* handle, or to nothing if *new_requeue_owner* is
-**ZX_HANDLE_INVALID**.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_futex_requeue()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  One of the following is true:
-+ Either *value_ptr* or *requeue_ptr* is not a valid userspace pointer
-+ Either *value_ptr* or *requeue_ptr* is not aligned to a `sizeof(zx_futex_t)` boundary.
-+ *value_ptr* is the same futex as *requeue_ptr*
-+ *new_requeue_owner* is currently a member of the waiters for either *value_ptr* or *requeue_ptr*
-
-**ZX_ERR_BAD_HANDLE**  *new_requeue_owner* is not **ZX_HANDLE_INVALID**, and not a valid handle.
-**ZX_ERR_WRONG_TYPE**  *new_requeue_owner* is a valid handle, but is not a handle to a thread.
-**ZX_ERR_BAD_STATE**  *current_value* does not match the value at *value_ptr*.
-
-## SEE ALSO
-
- - [futex objects](../objects/futex.md)
- - [`zx_futex_requeue_single_owner()`]
- - [`zx_futex_wait()`]
- - [`zx_futex_wake()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_futex_requeue_single_owner()`]: futex_requeue_single_owner.md
-[`zx_futex_wait()`]: futex_wait.md
-[`zx_futex_wake()`]: futex_wake.md
diff --git a/docs/syscalls/futex_requeue_deprecated.md b/docs/syscalls/futex_requeue_deprecated.md
deleted file mode 100644
index 8884b75..0000000
--- a/docs/syscalls/futex_requeue_deprecated.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# zx_futex_requeue_deprecated
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_requeue_deprecated - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_futex_requeue_deprecated(const zx_futex_t* wake_ptr,
-                                        uint32_t wake_count,
-                                        int32_t current_value,
-                                        const zx_futex_t* requeue_ptr,
-                                        uint32_t requeue_count);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/futex_requeue_single_owner.md b/docs/syscalls/futex_requeue_single_owner.md
deleted file mode 100644
index edf001d..0000000
--- a/docs/syscalls/futex_requeue_single_owner.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# zx_futex_requeue_single_owner
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_requeue_single_owner - Wake some number of threads waiting on a futex, and move more waiters to another wait queue.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_futex_requeue_single_owner(const zx_futex_t* value_ptr,
-                                          zx_futex_t current_value,
-                                          const zx_futex_t* requeue_ptr,
-                                          uint32_t requeue_count,
-                                          zx_handle_t new_requeue_owner);
-```
-
-## DESCRIPTION
-
-See [`zx_futex_requeue()`] for a full description.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_futex_requeue_single_owner()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  One of the following is true:
-+ Either *value_ptr* or *requeue_ptr* is not a valid userspace pointer
-+ Either *value_ptr* or *requeue_ptr* is not aligned to a `sizeof(zx_futex_t)` boundary.
-+ *value_ptr* is the same futex as *requeue_ptr*
-+ *new_requeue_owner* is currently a member of the waiters for either *value_ptr* or *requeue_ptr*
-
-**ZX_ERR_BAD_HANDLE**  *new_requeue_owner* is not **ZX_HANDLE_INVALID**, and not a valid handle.
-**ZX_ERR_WRONG_TYPE**  *new_requeue_owner* is a valid handle, but is not a handle to a thread.
-**ZX_ERR_BAD_STATE**  *current_value* does not match the value at *value_ptr*.
-
-## SEE ALSO
-
- - [futex objects](../objects/futex.md)
- - [`zx_futex_requeue()`]
- - [`zx_futex_wait()`]
- - [`zx_futex_wake()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_futex_requeue()`]: futex_requeue.md
-[`zx_futex_wait()`]: futex_wait.md
-[`zx_futex_wake()`]: futex_wake.md
diff --git a/docs/syscalls/futex_wait.md b/docs/syscalls/futex_wait.md
deleted file mode 100644
index 036f6c5..0000000
--- a/docs/syscalls/futex_wait.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# zx_futex_wait
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_wait - Wait on a futex.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_futex_wait(const zx_futex_t* value_ptr,
-                          zx_futex_t current_value,
-                          zx_handle_t new_futex_owner,
-                          zx_time_t deadline);
-```
-
-## DESCRIPTION
-
-`zx_futex_wait()` atomically verifies that *value_ptr* still contains the value
-*current_value* and sleeps until the futex is made available by a call to
-`zx_futex_wake`. Optionally, the thread can also be woken up after the
-*deadline* (with respect to **ZX_CLOCK_MONOTONIC**) passes. *deadline* may be
-automatically adjusted according to the job's [timer slack] policy.
-
-## SPURIOUS WAKEUPS
-
-A component that uses futexes should be prepared to handle spurious
-wakeups.  A spurious wakeup is a situation where `zx_futex_wait()`
-returns successfully even though the component did not wake the waiter
-by calling [`zx_futex_wake()`].
-
-Zircon's implementation of futexes currently does not generate
-spurious wakeups itself.  However, commonly-used algorithms that use
-futexes can sometimes generate spurious wakeups.  For example, the
-usual implementation of `mutex_unlock` can potentially produce a
-[`zx_futex_wake()`] call on a memory location after the location has been
-freed and reused for unrelated purposes.
-
-## OWNERSHIP
-
-A successful call to `zx_futex_wait()` results in the owner of the futex being
-set to the thread referenced by the *new_futex_owner* handle, or to nothing if
-*new_futex_owner* is **ZX_HANDLE_INVALID**.
-
-See *Ownership and Priority Inheritance* in [futex](../objects/futex.md) for
-details.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_futex_wait()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  One of the following is true:
-+ *value_ptr* is not a valid userspace pointer
-+ *value_ptr* is not aligned to a `sizeof(zx_futex_t)` boundary.
-+ *new_futex_owner* is currently a member of the waiters for *value_ptr*.
-
-**ZX_ERR_BAD_HANDLE**  *new_futex_owner* is not **ZX_HANDLE_INVALID**, and not a valid handle.
-**ZX_ERR_WRONG_TYPE**  *new_futex_owner* is a valid handle, but is not a handle to a thread.
-**ZX_ERR_BAD_STATE**  *current_value* does not match the value at *value_ptr*.
-**ZX_ERR_TIMED_OUT**  The thread was not woken before *deadline* passed.
-
-## SEE ALSO
-
- - [futex objects](../objects/futex.md)
- - [timer slack]
- - [`zx_futex_requeue()`]
- - [`zx_futex_wake()`]
-
-[timer slack]: ../timer_slack.md
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_futex_requeue()`]: futex_requeue.md
-[`zx_futex_wake()`]: futex_wake.md
diff --git a/docs/syscalls/futex_wait_deprecated.md b/docs/syscalls/futex_wait_deprecated.md
deleted file mode 100644
index 2f5b3ff..0000000
--- a/docs/syscalls/futex_wait_deprecated.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_futex_wait_deprecated
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_wait_deprecated - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_futex_wait_deprecated(const zx_futex_t* value_ptr,
-                                     int32_t current_value,
-                                     zx_time_t deadline);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/futex_wake.md b/docs/syscalls/futex_wake.md
deleted file mode 100644
index 872c125..0000000
--- a/docs/syscalls/futex_wake.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# zx_futex_wake
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_wake - Wake some number of threads waiting on a futex, optionally transferring ownership to the thread which was woken in the process.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_futex_wake(const zx_futex_t* value_ptr, uint32_t wake_count);
-```
-
-## DESCRIPTION
-
-Waking a futex causes *wake_count* threads waiting on the *value_ptr*
-futex to be woken up.
-
-Waking up zero threads is not an error condition.  Passing in an unallocated
-address for *value_ptr* is not an error condition.
-
-## OWNERSHIP
-
-A successful call to `zx_futex_wake()` results in the owner of the futex being
-set to nothing, regardless of the wake count.  In order to transfer ownership of
-a futex, use the [`zx_futex_wake_single_owner()`] variant instead.
-[`zx_futex_wake_single_owner()`] will attempt to wake exactly one thread from the
-futex wait queue.  If there is at least one thread to wake, the owner of the
-futex will be set to the thread which was woken.  Otherwise, the futex will have
-no owner.
-
-See *Ownership and Priority Inheritance* in [futex](../objects/futex.md) for
-details.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_futex_wake()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *value_ptr* is not aligned.
-
-## SEE ALSO
-
- - [futex objects](../objects/futex.md)
- - [`zx_futex_requeue()`]
- - [`zx_futex_wait()`]
- - [`zx_futex_wake_single_owner()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_futex_requeue()`]: futex_requeue.md
-[`zx_futex_wait()`]: futex_wait.md
-[`zx_futex_wake_single_owner()`]: futex_wake_single_owner.md
diff --git a/docs/syscalls/futex_wake_handle_close_thread_exit.md b/docs/syscalls/futex_wake_handle_close_thread_exit.md
deleted file mode 100644
index 0492a8b..0000000
--- a/docs/syscalls/futex_wake_handle_close_thread_exit.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# zx_futex_wake_handle_close_thread_exit
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_wake_handle_close_thread_exit - write to futex, wake futex, close handle, exit
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-[[noreturn]] void zx_futex_wake_handle_close_thread_exit(
-    const zx_futex_t* value_ptr,
-    uint32_t wake_count,
-    int32_t new_value,
-    zx_handle_t close_handle);
-```
-
-## DESCRIPTION
-
-`zx_futex_wake_handle_close_thread_exit()` does a sequence of four operations:
-1. `atomic_store_explicit(value_ptr, new_value, memory_order_release);`
-2. `zx_futex_wake(value_ptr, wake_count);`
-3. `zx_handle_close(close_handle);`
-4. `zx_thread_exit();`
-
-The expectation is that as soon as the first operation completes,
-other threads may unmap or reuse the memory containing the calling
-thread's own stack.  This is valid for this call, though it would be
-invalid for plain [`zx_futex_wake()`] or any other call.
-
-If any of the operations fail, then the thread takes a trap (as if by `__builtin_trap();`).
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_futex_wake_handle_close_thread_exit()` does not return.
-
-## ERRORS
-
-None.
-
-## NOTES
-
-The intended use for this is for a dying thread to alert another thread
-waiting for its completion, close its own thread handle, and exit.
-The thread handle cannot be closed beforehand because closing the last
-handle to a thread kills that thread.  The write to *value_ptr* can't be
-done before this call because any time after the write, a joining thread might
-reuse or deallocate this thread's stack, which may cause issues with calling
-conventions into this function.
-
-This call is used for joinable threads, while
-[`zx_vmar_unmap_handle_close_thread_exit()`]
-is used for detached threads.
-
-## SEE ALSO
-
- - [futex objects](../objects/futex.md)
- - [`zx_futex_wake()`]
- - [`zx_handle_close()`]
- - [`zx_thread_exit()`]
- - [`zx_vmar_unmap_handle_close_thread_exit()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_futex_wake()`]: futex_wake.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_thread_exit()`]: thread_exit.md
-[`zx_vmar_unmap_handle_close_thread_exit()`]: vmar_unmap_handle_close_thread_exit.md
diff --git a/docs/syscalls/futex_wake_single_owner.md b/docs/syscalls/futex_wake_single_owner.md
deleted file mode 100644
index 239a329..0000000
--- a/docs/syscalls/futex_wake_single_owner.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# zx_futex_wake_single_owner
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-futex_wake_single_owner - Wake some number of threads waiting on a futex, optionally transferring ownership to the thread which was woken in the process.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_futex_wake_single_owner(const zx_futex_t* value_ptr);
-```
-
-## DESCRIPTION
-
-See [`zx_futex_wake()`] for a full description.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_futex_wake_single_owner()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *value_ptr* is not aligned.
-
-## SEE ALSO
-
- - [futex objects](../objects/futex.md)
- - [`zx_futex_requeue()`]
- - [`zx_futex_wait()`]
- - [`zx_futex_wake()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_futex_requeue()`]: futex_requeue.md
-[`zx_futex_wait()`]: futex_wait.md
-[`zx_futex_wake()`]: futex_wake.md
diff --git a/docs/syscalls/guest_create.md b/docs/syscalls/guest_create.md
deleted file mode 100644
index 82156fd..0000000
--- a/docs/syscalls/guest_create.md
+++ /dev/null
@@ -1,93 +0,0 @@
-# zx_guest_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-guest_create - create a guest
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_guest_create(zx_handle_t resource,
-                            uint32_t options,
-                            zx_handle_t* guest_handle,
-                            zx_handle_t* vmar_handle);
-```
-
-## DESCRIPTION
-
-`zx_guest_create()` creates a guest, which is a virtual machine that can be run
-within the hypervisor, with *vmar_handle* used to represent the physical address
-space of the guest.
-
-To create a guest, a *resource* of **ZX_RSRC_KIND_HYPERVISOR** must be supplied.
-
-In order to begin execution within the guest, a VMO should be mapped into
-*vmar_handle* using [`zx_vmar_map()`], and a VCPU must be created using
-[`zx_vcpu_create()`], and then run using [`zx_vcpu_resume()`].
-
-Additionally, a VMO should be mapped into *vmar_handle* to provide a guest with
-physical memory.
-
-The following rights will be set on the handle *guest_handle* by default:
-
-**ZX_RIGHT_TRANSFER** &mdash; *guest_handle* may be transferred over a channel.
-
-**ZX_RIGHT_DUPLICATE** &mdash; *guest_handle* may be duplicated.
-
-**ZX_RIGHT_WRITE** &mdash; A trap to be may be set using [`zx_guest_set_trap()`].
-
-**ZX_RIGHT_MANAGE_PROCESS** &mdash; A VCPU may be created using [`zx_vcpu_create()`].
-
-See [`zx_vmo_create()`] for the set of rights applied to *vmar_handle*.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_HYPERVISOR**.
-
-## RETURN VALUE
-
-`zx_guest_create()` returns **ZX_OK** on success. On failure, an error value is
-returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** *resource* is not of **ZX_RSRC_KIND_HYPERVISOR**.
-
-**ZX_ERR_INVALID_ARGS** *guest_handle* or *vmar_handle* is an invalid pointer,
-or *options* is nonzero.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_WRONG_TYPE** *resource* is not a handle to a resource.
-
-## SEE ALSO
-
- - [`zx_guest_set_trap()`]
- - [`zx_vcpu_create()`]
- - [`zx_vcpu_interrupt()`]
- - [`zx_vcpu_read_state()`]
- - [`zx_vcpu_resume()`]
- - [`zx_vcpu_write_state()`]
- - [`zx_vmar_map()`]
- - [`zx_vmo_create()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_set_trap()`]: guest_set_trap.md
-[`zx_vcpu_create()`]: vcpu_create.md
-[`zx_vcpu_interrupt()`]: vcpu_interrupt.md
-[`zx_vcpu_read_state()`]: vcpu_read_state.md
-[`zx_vcpu_resume()`]: vcpu_resume.md
-[`zx_vcpu_write_state()`]: vcpu_write_state.md
-[`zx_vmar_map()`]: vmar_map.md
-[`zx_vmo_create()`]: vmo_create.md
diff --git a/docs/syscalls/guest_set_trap.md b/docs/syscalls/guest_set_trap.md
deleted file mode 100644
index 9fddf00..0000000
--- a/docs/syscalls/guest_set_trap.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# zx_guest_set_trap
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-guest_set_trap - sets a trap within a guest
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_guest_set_trap(zx_handle_t handle,
-                              uint32_t kind,
-                              zx_vaddr_t addr,
-                              size_t size,
-                              zx_handle_t port_handle,
-                              uint64_t key);
-```
-
-## DESCRIPTION
-
-`zx_guest_set_trap()` sets a trap within a guest, which generates a packet when
-there is an access by a VCPU within the address range defined by *addr* and
-*size*, within the address space defined by *kind*.
-
-*kind* may be either **ZX_GUEST_TRAP_BELL**, **ZX_GUEST_TRAP_MEM**, or
-**ZX_GUEST_TRAP_IO**. If **ZX_GUEST_TRAP_BELL** or **ZX_GUEST_TRAP_MEM** is
-specified, then *addr* and *size* must both be page-aligned.
-**ZX_GUEST_TRAP_BELL** is an asynchronous trap, and both **ZX_GUEST_TRAP_MEM**
-and **ZX_GUEST_TRAP_IO** are synchronous traps.
-
-Packets for synchronous traps will be delivered through [`zx_vcpu_resume()`] and
-packets for asynchronous traps will be delivered through *port_handle*.
-
-*port_handle* must be **ZX_HANDLE_INVALID** for synchronous traps. For
-asynchronous traps *port_handle* must be valid and a packet for the trap will be
-delivered through *port_handle* each time the trap is triggered. A fixed number
-of packets are pre-allocated per trap. If all the packets are exhausted,
-execution of the VCPU that caused the trap will be paused. When at least one
-packet is dequeued, execution of the VCPU will resume. To dequeue a packet from
-*port_handle*, use [`zx_port_wait()`]. Multiple threads may use
-[`zx_port_wait()`] to dequeue packets, enabling the use of a thread pool to
-handle traps.
-
-*key* is used to set the key field within `zx_port_packet_t`, and can be used to
-distinguish between packets for different traps.
-
-
-**ZX_GUEST_TRAP_BELL** is a type of trap that defines a door-bell. If there is
-an access to the memory region specified by the trap, then a packet is generated
-that does not fetch the instruction associated with the access. The packet will
-then be delivered asynchronously via *port_handle*.
-
-To identify what *kind* of trap generated a packet, use
-**ZX_PKT_TYPE_GUEST_MEM**, **ZX_PKT_TYPE_GUEST_IO**, **ZX_PKT_TYPE_GUEST_BELL**,
-and **ZX_PKT_TYPE_GUEST_VCPU**. **ZX_PKT_TYPE_GUEST_VCPU** is a special packet,
-not caused by a trap, that indicates that the guest requested to start an
-additional VCPU.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_GUEST** and have **ZX_RIGHT_WRITE**.
-
-*port_handle* must be of type **ZX_OBJ_TYPE_PORT** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_guest_set_trap()` returns **ZX_OK** on success. On failure, an error value is
-returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** *handle* or *port_handle* do not have the
-**ZX_RIGHT_WRITE** right.
-
-**ZX_ERR_ALREADY_EXISTS** A trap with the same *kind* and *addr* already exists.
-
-**ZX_ERR_BAD_HANDLE** *handle* or *port_handle* are invalid handles.
-
-**ZX_ERR_INVALID_ARGS** *kind* is not a valid address space, *addr* or *size*
-do not meet the requirements of *kind*, *size* is 0, or **ZX_GUEST_TRAP_MEM** was
-specified with a *port_handle*.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_OUT_OF_RANGE** The region specified by *addr* and *size* is outside of
-of the valid bounds of the address space *kind*.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a handle to a guest, or *port_handle* is
-not a handle to a port.
-
-## NOTES
-
-**ZX_GUEST_TRAP_BELL** shares the same address space as **ZX_GUEST_TRAP_MEM**.
-
-On x86-64, if *kind* is **ZX_GUEST_TRAP_BELL** or **ZX_GUEST_TRAP_MEM** and *addr*
-is the address of the local APIC, then *size* must be equivalent to the size of
-a page. This is due to a special page being mapped when a trap is requested at the
-address of the local APIC. This allows us to take advantage of hardware
-acceleration when available.
-
-## SEE ALSO
-
- - [`zx_guest_create()`]
- - [`zx_port_create()`]
- - [`zx_port_wait()`]
- - [`zx_vcpu_create()`]
- - [`zx_vcpu_interrupt()`]
- - [`zx_vcpu_read_state()`]
- - [`zx_vcpu_resume()`]
- - [`zx_vcpu_write_state()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_create()`]: guest_create.md
-[`zx_port_create()`]: port_create.md
-[`zx_port_wait()`]: port_wait.md
-[`zx_vcpu_create()`]: vcpu_create.md
-[`zx_vcpu_interrupt()`]: vcpu_interrupt.md
-[`zx_vcpu_read_state()`]: vcpu_read_state.md
-[`zx_vcpu_resume()`]: vcpu_resume.md
-[`zx_vcpu_write_state()`]: vcpu_write_state.md
diff --git a/docs/syscalls/handle_close.md b/docs/syscalls/handle_close.md
deleted file mode 100644
index 20549f8..0000000
--- a/docs/syscalls/handle_close.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# zx_handle_close
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-handle_close - close a handle
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_handle_close(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-`zx_handle_close()` closes a *handle*, causing the underlying object to be
-reclaimed by the kernel if no other handles to it exist.
-
-If the *handle* was used in a pending [`zx_object_wait_one()`] or a
-[`zx_object_wait_many()`] call, the wait will be aborted.
-
-It is not an error to close the special "never a valid handle" **ZX_HANDLE_INVALID**,
-similar to `free(NULL)` being a valid call.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_handle_close()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* isn't a valid handle.
-
-## SEE ALSO
-
- - [`zx_handle_close_many()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close_many()`]: handle_close_many.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/handle_close_many.md b/docs/syscalls/handle_close_many.md
deleted file mode 100644
index 94f7a86..0000000
--- a/docs/syscalls/handle_close_many.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# zx_handle_close_many
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-handle_close_many - close a number of handles
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_handle_close_many(const zx_handle_t* handles,
-                                 size_t num_handles);
-```
-
-## DESCRIPTION
-
-`zx_handle_close_many()` closes a number of handles, causing each
-underlying object to be reclaimed by the kernel if no other handles to
-it exist.
-
-If a handle was used in a pending [`zx_object_wait_one()`] or a
-[`zx_object_wait_many()`] call, the wait will be aborted.
-
-This operation closes all handles presented to it, even if one or more
-of the handles is duplicate or invalid.
-
-It is not an error to close the special "never a valid handle" **ZX_HANDLE_INVALID**,
-similar to `free(NULL)` being a valid call.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_handle_close_many()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  One of the *handles* isn't a valid handle, or the same handle is
-present multiple times.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/handle_duplicate.md b/docs/syscalls/handle_duplicate.md
deleted file mode 100644
index 74d9aa5..0000000
--- a/docs/syscalls/handle_duplicate.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# zx_handle_duplicate
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-handle_duplicate - duplicate a handle
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_handle_duplicate(zx_handle_t handle,
-                                zx_rights_t rights,
-                                zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_handle_duplicate()` creates a duplicate of *handle*, referring
-to the same underlying object, with new access rights *rights*.
-
-To duplicate the handle with the same rights use **ZX_RIGHT_SAME_RIGHTS**. If different
-rights are desired they must be strictly lesser than of the source handle. It is possible
-to specify no rights by using 0.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_DUPLICATE**.
-
-## RETURN VALUE
-
-`zx_handle_duplicate()` returns **ZX_OK** and the duplicate handle via *out* on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* isn't a valid handle.
-
-**ZX_ERR_INVALID_ARGS**  The *rights* requested are not a subset of *handle* rights or
-*out* is an invalid pointer.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_DUPLICATE** and may not be duplicated.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [rights](../rights.md)
- - [`zx_handle_close()`]
- - [`zx_handle_close_many()`]
- - [`zx_handle_replace()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_close_many()`]: handle_close_many.md
-[`zx_handle_replace()`]: handle_replace.md
diff --git a/docs/syscalls/handle_replace.md b/docs/syscalls/handle_replace.md
deleted file mode 100644
index c87b5ce..0000000
--- a/docs/syscalls/handle_replace.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# zx_handle_replace
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-handle_replace - replace a handle
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_handle_replace(zx_handle_t handle,
-                              zx_rights_t rights,
-                              zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_handle_replace()` creates a replacement for *handle*, referring to
-the same underlying object, with new access rights *rights*.
-
-*handle* is always invalidated.
-
-If *rights* is **ZX_RIGHT_SAME_RIGHTS**, the replacement handle will
-have the same rights as the original handle. Otherwise, *rights* must be
-a subset of original handle's rights.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_handle_replace()` returns **ZX_OK** and the replacement handle (via *out*)
-on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* isn't a valid handle.
-
-**ZX_ERR_INVALID_ARGS**  The *rights* requested are not a subset of
-*handle*'s rights or *out* is an invalid pointer.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_close_many()`]
- - [`zx_handle_duplicate()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_close_many()`]: handle_close_many.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
diff --git a/docs/syscalls/interrupt_ack.md b/docs/syscalls/interrupt_ack.md
deleted file mode 100644
index 507f65c..0000000
--- a/docs/syscalls/interrupt_ack.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# zx_interrupt_ack
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-interrupt_ack - Acknowledge an interrupt and re-arm it.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_interrupt_ack(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-`zx_interrupt_ack()` acknowledges an interrupt object, causing it to be eligible
-to trigger again (and delivering a packet to the port it is bound to).
-
-If the interrupt object is a physical interrupt, if it is a level interrupt and
-still asserted, or is an edge interrupt that has been asserted since it last
-triggered, the interrupt will trigger immediately, delivering a packet to the
-port it is bound to.
-
-Virtual interrupts behave as edge interrupts.
-
-This syscall only operates on interrupts which are bound to a port.  Interrupts
-being waited upon with [`zx_interrupt_wait()`] do not need to be re-armed with this
-call -- it happens automatically when [`zx_interrupt_wait()`] is called.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_INTERRUPT** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_interrupt_ack()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not an interrupt object.
-
-**ZX_ERR_BAD_STATE** *handle* is not bound to a port.
-
-**ZX_ERR_CANCELED**  [`zx_interrupt_destroy()`] was called on *handle*.
-
-**ZX_ERR_ACCESS_DENIED** *handle* lacks **ZX_RIGHT_WRITE**.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_interrupt_bind()`]
- - [`zx_interrupt_create()`]
- - [`zx_interrupt_destroy()`]
- - [`zx_interrupt_trigger()`]
- - [`zx_interrupt_wait()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_interrupt_bind()`]: interrupt_bind.md
-[`zx_interrupt_create()`]: interrupt_create.md
-[`zx_interrupt_destroy()`]: interrupt_destroy.md
-[`zx_interrupt_trigger()`]: interrupt_trigger.md
-[`zx_interrupt_wait()`]: interrupt_wait.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/interrupt_bind.md b/docs/syscalls/interrupt_bind.md
deleted file mode 100644
index 68b5173..0000000
--- a/docs/syscalls/interrupt_bind.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# zx_interrupt_bind
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-interrupt_bind - Bind an interrupt object to a port
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_interrupt_bind(zx_handle_t handle,
-                              zx_handle_t port_handle,
-                              uint64_t key,
-                              uint32_t options);
-```
-
-## DESCRIPTION
-
-`zx_interrupt_bind()` binds an interrupt object to a port.
-
-An interrupt object may only be bound to a single port and may only be bound once.
-The interrupt can only bind to a port which is created with **ZX_PORT_BIND_TO_INTERRUPT**
-option.
-
-When a bound interrupt object is triggered, a **ZX_PKT_TYPE_INTERRUPT** packet will
-be delivered to the port it is bound to, with the timestamp (relative to **ZX_CLOCK_MONOTONIC**)
-of when the interrupt was triggered in the `zx_packet_interrupt_t`.  The *key* used
-when binding the interrupt will be present in the `key` field of the `zx_port_packet_t`.
-
-Before another packet may be delivered, the bound interrupt must be re-armed using the
-[`zx_interrupt_ack()`] syscall.  This is (in almost all cases) best done after the interrupt
-packet has been fully processed.  Especially in the case of multiple threads reading
-packets from a port, if the processing thread re-arms the interrupt and it has triggered,
-a packet will immediately be delivered to a waiting thread.
-
-Interrupt packets are delivered via a dedicated queue on ports and are higher priority
-than non-interrupt packets.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_INTERRUPT** and have **ZX_RIGHT_READ**.
-
-*port_handle* must be of type **ZX_OBJ_TYPE_PORT** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_interrupt_bind()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* or *port_handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not an interrupt object or *port_handle* is not a port object.
-
-**ZX_ERR_CANCELED**  [`zx_interrupt_destroy()`] was called on *handle*.
-
-**ZX_ERR_BAD_STATE**  A thread is waiting on the interrupt using [`zx_interrupt_wait()`]
-
-**ZX_ERR_ACCESS_DENIED** the *handle* handle lacks **ZX_RIGHT_READ** or the *port_handle* handle
-lacks **ZX_RIGHT_WRITE**
-
-**ZX_ERR_ALREADY_BOUND** this interrupt object is already bound.
-
-**ZX_ERR_INVALID_ARGS** *options* contains a non-zero value.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_interrupt_ack()`]
- - [`zx_interrupt_create()`]
- - [`zx_interrupt_destroy()`]
- - [`zx_interrupt_trigger()`]
- - [`zx_interrupt_wait()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_interrupt_ack()`]: interrupt_ack.md
-[`zx_interrupt_create()`]: interrupt_create.md
-[`zx_interrupt_destroy()`]: interrupt_destroy.md
-[`zx_interrupt_trigger()`]: interrupt_trigger.md
-[`zx_interrupt_wait()`]: interrupt_wait.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/interrupt_bind_vcpu.md b/docs/syscalls/interrupt_bind_vcpu.md
deleted file mode 100644
index 691611c..0000000
--- a/docs/syscalls/interrupt_bind_vcpu.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# zx_interrupt_bind_vcpu
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-interrupt_bind_vcpu - bind an interrupt object to a VCPU
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_interrupt_bind_vcpu(zx_handle_t handle,
-                                   zx_handle_t vcpu,
-                                   uint32_t options);
-```
-
-## DESCRIPTION
-
-`zx_interrupt_bind_vcpu()` binds an interrupt object to a VCPU. When the
-interrupt object is triggered, the interrupt is redirected to the VCPU, in order
-to be processed by a guest with no host intervention.
-
-An interrupt object may be bound to multiple VCPUs, in order to distribute the
-interrupt. Simply invoke `zx_interrupt_bind_vcpu()` with the same *handle*, but
-different *vcpu*s. However, all VCPUs must belong to a single guest.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_INTERRUPT** and have **ZX_RIGHT_READ**.
-
-*vcpu* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_interrupt_bind_vcpu()` returns **ZX_OK** on success. On failure, an error value
-is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* or *vcpu* are not valid handles.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not an interrupt object or *vcpu* is not a
-VCPU.
-
-**ZX_ERR_CANCELED** [`zx_interrupt_destroy()`] was called on *handle*.
-
-**ZX_ERR_BAD_STATE**  a thread is waiting on the interrupt using
-[`zx_interrupt_wait()`].
-
-**ZX_ERR_ACCESS_DENIED** *handle* lacks **ZX_RIGHT_READ** or *vcpu* lacks
-**ZX_RIGHT_WRITE**.
-
-**ZX_ERR_ALREADY_BOUND** *handle* is already bound to another guest or to a
-port.
-
-**ZX_ERR_INVALID_ARGS** *vcpu* is bound to a different guest than previously
-bound VCPUs, or *options* is non-zero.
-
-## SEE ALSO
-
- - [`zx_guest_create()`]
- - [`zx_interrupt_create()`]
- - [`zx_vcpu_create()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_create()`]: guest_create.md
-[`zx_interrupt_create()`]: interrupt_create.md
-[`zx_interrupt_destroy()`]: interrupt_destroy.md
-[`zx_interrupt_wait()`]: interrupt_wait.md
-[`zx_vcpu_create()`]: vcpu_create.md
diff --git a/docs/syscalls/interrupt_create.md b/docs/syscalls/interrupt_create.md
deleted file mode 100644
index 7d2fa56..0000000
--- a/docs/syscalls/interrupt_create.md
+++ /dev/null
@@ -1,94 +0,0 @@
-# zx_interrupt_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-interrupt_create - create an interrupt object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_interrupt_create(zx_handle_t src_obj,
-                                uint32_t src_num,
-                                uint32_t options,
-                                zx_handle_t* out_handle);
-```
-
-## DESCRIPTION
-
-`zx_interrupt_create()` creates an interrupt object which represents a physical
-or virtual interrupt.
-
-If *options* is **ZX_INTERRUPT_VIRTUAL**, *src_obj* and *src_num* are ignored and
-a virtual interrupt is returned.
-
-Otherwise *src_obj* must be a suitable resource for creating platform interrupts
-or a PCI object, and *src_num* is the associated interrupt number.  This restricts
-the creation of interrupts to the internals of the DDK (driver development kit).
-Physical interrupts are obtained by drivers through various DDK APIs.
-
-Physical interrupts honor the options **ZX_INTERRUPT_EDGE_LOW**, **ZX_INTERRUPT_EDGE_HIGH**,
-**ZX_INTERRUPT_LEVEL_LOW**, **ZX_INTERRUPT_LEVEL_HIGH**, and **ZX_INTERRUPT_REMAP_IRQ**.
-
-The handles will have **ZX_RIGHT_INSPECT**, **ZX_RIGHT_DUPLICATE**, **ZX_RIGHT_TRANSFER**
-(allowing them to be sent to another process via channel write), **ZX_RIGHT_READ**,
-**ZX_RIGHT_WRITE** (required for [`zx_interrupt_ack()`]), **ZX_RIGHT_WAIT** (required for
-[`zx_interrupt_wait()`], and **ZX_RIGHT_SIGNAL** (required for [`zx_interrupt_trigger()`]).
-
-Interrupts are said to be "triggered" when the underlying physical interrupt occurs
-or when [`zx_interrupt_trigger()`] is called on a virtual interrupt.  A triggered interrupt,
-when bound to a port with [`zx_interrupt_bind()`], causes a packet to be delivered to the port.
-
-If not bound to a port, an interrupt object may be waited on with [`zx_interrupt_wait()`].
-
-Interrupts cannot be waited on with the `zx_object_wait_` family of calls.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*src_obj* must have resource kind **ZX_RSRC_KIND_IRQ**.
-
-## RETURN VALUE
-
-`zx_interrupt_create()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** the *src_obj* handle is invalid (if this is not a virtual interrupt)
-
-**ZX_ERR_WRONG_TYPE** the *src_obj* handle is not of an appropriate type to create an interrupt.
-
-**ZX_ERR_ACCESS_DENIED** the *src_obj* handle does not allow this operation.
-
-**ZX_ERR_INVALID_ARGS** *options* contains invalid flags or the *out_handle*
-parameter is an invalid pointer.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_interrupt_ack()`]
- - [`zx_interrupt_bind()`]
- - [`zx_interrupt_destroy()`]
- - [`zx_interrupt_wait()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_interrupt_ack()`]: interrupt_ack.md
-[`zx_interrupt_bind()`]: interrupt_bind.md
-[`zx_interrupt_destroy()`]: interrupt_destroy.md
-[`zx_interrupt_trigger()`]: interrupt_trigger.md
-[`zx_interrupt_wait()`]: interrupt_wait.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/interrupt_destroy.md b/docs/syscalls/interrupt_destroy.md
deleted file mode 100644
index 6612176..0000000
--- a/docs/syscalls/interrupt_destroy.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# zx_interrupt_destroy
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-interrupt_destroy - destroys an interrupt object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_interrupt_destroy(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-`zx_interrupt_destroy()` "destroys" an interrupt object, putting it in a state
-where any [`zx_interrupt_wait()`] operations on it will return **ZX_ERR_CANCELED**,
-and it is unbound from any ports it was bound to.
-
-This provides a clean shut down mechanism.  Closing the last handle to the
-interrupt object results in similar cancellation but could result in use-after-close
-of the handle.
-
-If the interrupt object is bound to a port when cancellation happens, if it
-has not yet triggered, or it has triggered but the packet has not yet been
-received by a caller of [`zx_port_wait()`], success is returned and any packets
-in flight are removed.  Otherwise, **ZX_ERR_NOT_FOUND** is returned, indicating
-that the packet has been read but the interrupt has not been re-armed by calling
-[`zx_interrupt_ack()`].
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_interrupt_destroy()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not an interrupt object.
-
-**ZX_ERR_NOT_FOUND**  *handle* was bound (and now no longer is) but was not
-being waited for.
-
-**ZX_ERR_ACCESS_DENIED** *handle* lacks **ZX_RIGHT_WRITE**.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_interrupt_ack()`]
- - [`zx_interrupt_bind()`]
- - [`zx_interrupt_create()`]
- - [`zx_interrupt_trigger()`]
- - [`zx_interrupt_wait()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_interrupt_ack()`]: interrupt_ack.md
-[`zx_interrupt_bind()`]: interrupt_bind.md
-[`zx_interrupt_create()`]: interrupt_create.md
-[`zx_interrupt_trigger()`]: interrupt_trigger.md
-[`zx_interrupt_wait()`]: interrupt_wait.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/interrupt_trigger.md b/docs/syscalls/interrupt_trigger.md
deleted file mode 100644
index 109788d..0000000
--- a/docs/syscalls/interrupt_trigger.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# zx_interrupt_trigger
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-interrupt_trigger - triggers a virtual interrupt object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_interrupt_trigger(zx_handle_t handle,
-                                 uint32_t options,
-                                 zx_time_t timestamp);
-```
-
-## DESCRIPTION
-
-`zx_interrupt_trigger()` is used to trigger a virtual interrupt interrupt object,
-causing an interrupt message packet to arrive on the bound port, if it is bound
-to a port, or [`zx_interrupt_wait()`] to return if it is waiting on this interrupt.
-
-*options* must be zero.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_INTERRUPT** and have **ZX_RIGHT_SIGNAL**.
-
-## RETURN VALUE
-
-`zx_interrupt_trigger()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not an interrupt object.
-
-**ZX_ERR_BAD_STATE** *handle* is not a virtual interrupt.
-
-**ZX_ERR_CANCELED**  [`zx_interrupt_destroy()`] was called on *handle*.
-
-**ZX_ERR_ACCESS_DENIED** *handle* lacks **ZX_RIGHT_SIGNAL**.
-
-**ZX_ERR_INVALID_ARGS** *options* is non-zero.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_interrupt_ack()`]
- - [`zx_interrupt_bind()`]
- - [`zx_interrupt_create()`]
- - [`zx_interrupt_destroy()`]
- - [`zx_interrupt_wait()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_interrupt_ack()`]: interrupt_ack.md
-[`zx_interrupt_bind()`]: interrupt_bind.md
-[`zx_interrupt_create()`]: interrupt_create.md
-[`zx_interrupt_destroy()`]: interrupt_destroy.md
-[`zx_interrupt_wait()`]: interrupt_wait.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/interrupt_wait.md b/docs/syscalls/interrupt_wait.md
deleted file mode 100644
index d4bd732..0000000
--- a/docs/syscalls/interrupt_wait.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# zx_interrupt_wait
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-interrupt_wait - wait for an interrupt
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_interrupt_wait(zx_handle_t handle, zx_time_t* out_timestamp);
-```
-
-## DESCRIPTION
-
-`zx_interrupt_wait()` is a blocking syscall which causes the caller to
-wait until an interrupt is triggered.  It can only be used on interrupt
-objects that have not been bound to a port with [`zx_interrupt_bind()`]
-
-It also, before the waiting begins, will acknowledge the interrupt object,
-as if [`zx_interrupt_ack()`] were called on it.
-
-The wait may be aborted with [`zx_interrupt_destroy()`] or by closing the handle.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_INTERRUPT** and have **ZX_RIGHT_WAIT**.
-
-## RETURN VALUE
-
-`zx_interrupt_wait()` returns **ZX_OK** on success, and *out_timestamp*, if
-non-NULL, returns the timestamp of when the interrupt was triggered (relative
-to **ZX_CLOCK_MONOTONIC**)
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a handle to an interrupt object.
-
-**ZX_ERR_BAD_STATE** the interrupt object is bound to a port.
-
-**ZX_ERR_ACCESS_DENIED** *handle* lacks **ZX_RIGHT_WAIT**.
-
-**ZX_ERR_CANCELED**  *handle* was closed while waiting or [`zx_interrupt_destroy()`] was called
-on it.
-
-**ZX_ERR_INVALID_ARGS** the *out_timestamp* parameter is an invalid pointer.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_interrupt_ack()`]
- - [`zx_interrupt_bind()`]
- - [`zx_interrupt_create()`]
- - [`zx_interrupt_destroy()`]
- - [`zx_interrupt_trigger()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_interrupt_ack()`]: interrupt_ack.md
-[`zx_interrupt_bind()`]: interrupt_bind.md
-[`zx_interrupt_create()`]: interrupt_create.md
-[`zx_interrupt_destroy()`]: interrupt_destroy.md
-[`zx_interrupt_trigger()`]: interrupt_trigger.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/iommu_create.md b/docs/syscalls/iommu_create.md
deleted file mode 100644
index 9f86d0f..0000000
--- a/docs/syscalls/iommu_create.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# zx_iommu_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-iommu_create - create a new IOMMU object in the kernel
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_iommu_create(zx_handle_t resource,
-                            uint32_t type,
-                            const void* desc,
-                            size_t desc_size,
-                            zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_iommu_create()` creates a new object in the kernel representing an IOMMU device.
-
-The value of *type* determines the interpretation of *desc*.  See below for
-details about the values of *type*.
-
-Upon success, a handle for the new IOMMU is returned.  This handle will have rights
-**ZX_RIGHT_DUPLICATE** and **ZX_RIGHT_TRANSFER**.
-
-### *type* = **ZX_IOMMU_TYPE_DUMMY**
-
-This type represents a no-op IOMMU.  It provides no hardware-level protections
-against unauthorized access to memory.  It does allow pinning of physical memory
-pages, to prevent the reuse of a page until the driver using the page says it is
-done with it.
-
-*desc* must be a valid pointer to a value of type `zx_iommu_desc_dummy_t`.
-*desc_size* must be `sizeof(zx_iommu_desc_dummy_t)`.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-`zx_iommu_create()` returns **ZX_OK** and a handle to the new IOMMU
-(via *out*) on success.  In the event of failure, a negative error value
-is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *resource* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *resource* is not a resource handle.
-
-**ZX_ERR_ACCESS_DENIED**  *resource* handle does not have sufficient privileges.
-
-**ZX_ERR_NOT_SUPPORTED** *type* is not a defined value or is not
-supported on this system.
-
-**ZX_ERR_INVALID_ARGS**  *desc_size* is larger than **ZX_IOMMU_MAX_DESC_LEN**,
-*desc* is an invalid pointer, *out* is an invalid pointer, or the contents of
-*desc* are not valid for the given *type*.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_bti_create()`]
- - [`zx_bti_pin()`]
- - [`zx_pmt_unpin()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_bti_create()`]: bti_create.md
-[`zx_bti_pin()`]: bti_pin.md
-[`zx_pmt_unpin()`]: pmt_unpin.md
diff --git a/docs/syscalls/ioports_request.md b/docs/syscalls/ioports_request.md
deleted file mode 100644
index b008433..0000000
--- a/docs/syscalls/ioports_request.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_ioports_request
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-ioports_request - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_ioports_request(zx_handle_t resource,
-                               uint16_t io_addr,
-                               uint32_t len);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_IOPORT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/job_create.md b/docs/syscalls/job_create.md
deleted file mode 100644
index c3e651a..0000000
--- a/docs/syscalls/job_create.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# zx_job_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-job_create - create a new job
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_job_create(zx_handle_t parent_job,
-                          uint32_t options,
-                          zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_job_create()` creates a new child [job object](../objects/job.md) given a
-parent job.
-
-Upon success a handle for the new job is returned.
-
-The kernel keeps track of and restricts the "height" of a job, which is its
-distance from the root job. It is illegal to create a job under a parent whose
-height exceeds an internal "max height" value. (It is, however, legal to create
-a process under such a job.)
-
-Job handles may be waited on (TODO(cpu): expand this)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*parent_job* must be of type **ZX_OBJ_TYPE_JOB** and have **ZX_RIGHT_MANAGE_JOB**.
-
-## RETURN VALUE
-
-`zx_job_create()` returns **ZX_OK** and a handle to the new job
-(via *out*) on success.  In the event of failure, a negative error value
-is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *parent_job* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *parent_job* is not a job handle.
-
-**ZX_ERR_INVALID_ARGS**  *options* is nonzero, or *out* is an invalid pointer.
-
-**ZX_ERR_ACCESS_DENIED**  *parent_job* does not have the **ZX_RIGHT_WRITE** or
-**ZX_RIGHT_MANAGE_JOB** right.
-
-**ZX_ERR_OUT_OF_RANGE**  The height of *parent_job* is too large to create a child job.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_BAD_STATE**  The parent job object is in the dead state.
-
-## SEE ALSO
-
- - [`zx_object_get_property()`]
- - [`zx_process_create()`]
- - [`zx_task_kill()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_get_property()`]: object_get_property.md
-[`zx_process_create()`]: process_create.md
-[`zx_task_kill()`]: task_kill.md
diff --git a/docs/syscalls/job_set_policy.md b/docs/syscalls/job_set_policy.md
deleted file mode 100644
index ecfd25d..0000000
--- a/docs/syscalls/job_set_policy.md
+++ /dev/null
@@ -1,181 +0,0 @@
-# zx_job_set_policy
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-job_set_policy - Set job security and resource policies.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_job_set_policy(zx_handle_t handle,
-                              uint32_t options,
-                              uint32_t topic,
-                              const void* policy,
-                              uint32_t count);
-```
-
-## DESCRIPTION
-
-Sets one or more security and/or resource policies to an empty job. The job's
-effective policies is the combination of the parent's effective policies and
-the policies specified in *policy*. The effect in the case of conflict between
-the existing policies and the new policies is controlled by *options* values:
-
-+ **ZX_JOB_POL_RELATIVE** : policy is applied for the conditions not specifically
-  overridden by the parent policy.
-+ **ZX_JOB_POL_ABSOLUTE** : policy is applied for all conditions in *policy* or
-  the syscall fails.
-
-After this call succeeds any new child process or child job will have the new
-effective policy applied to it.
-
-*topic* indicates the *policy* format. Supported values are **ZX_JOB_POL_BASIC**
-and **ZX_JOB_POL_TIMER_SLACK**.
-
-### **ZX_JOB_POL_BASIC**
-
-A *topic* of **ZX_JOB_POL_BASIC** indicates that *policy* is an array of *count*
-entries of:
-
-```
-typedef struct zx_policy_basic {
-    uint32_t condition;
-    uint32_t policy;
-} zx_policy_basic_t;
-
-```
-
-Where *condition* is one of
-+ **ZX_POL_BAD_HANDLE** a process under this job is attempting to
-  issue a syscall with an invalid handle.  In this case,
-  **ZX_POL_ACTION_ALLOW** and **ZX_POL_ACTION_DENY** are equivalent:
-  if the syscall returns, it will always return the error
-  **ZX_ERR_BAD_HANDLE**.
-+ **ZX_POL_WRONG_OBJECT** a process under this job is attempting to
-  issue a syscall with a handle that does not support such operation.
-+ **ZX_POL_VMAR_WX** a process under this job is attempting to map an
-  address region with write-execute access.
-+ **ZX_POL_NEW_VMO** a process under this job is attempting to create
-  a new vm object.
-+ **ZX_POL_NEW_CHANNEL** a process under this job is attempting to create
-  a new channel.
-+ **ZX_POL_NEW_EVENT** a process under this job is attempting to create
-  a new event.
-+ **ZX_POL_NEW_EVENTPAIR** a process under this job is attempting to create
-  a new event pair.
-+ **ZX_POL_NEW_PORT** a process under this job is attempting to create
-  a new port.
-+ **ZX_POL_NEW_SOCKET** a process under this job is attempting to create
-  a new socket.
-+ **ZX_POL_NEW_FIFO** a process under this job is attempting to create
-  a new fifo.
-+ **ZX_POL_NEW_TIMER** a process under this job is attempting to create
-  a new timer.
-+ **ZX_POL_NEW_PROCESS** a process under this job is attempting to create
-  a new process.
-+ **ZX_POL_NEW_ANY** is a special *condition* that stands for all of
-  the above **ZX_NEW** condtions such as **ZX_POL_NEW_VMO**,
-  **ZX_POL_NEW_CHANNEL**, **ZX_POL_NEW_EVENT**, **ZX_POL_NEW_EVENTPAIR**,
-  **ZX_POL_NEW_PORT**, **ZX_POL_NEW_SOCKET**, **ZX_POL_NEW_FIFO**,
-  and any future **ZX_NEW** policy. This will include any new
-  kernel objects which do not require a parent object for creation.
-
-Where *policy* is either
-+ **ZX_POL_ACTION_ALLOW**  allow *condition*.
-+ **ZX_POL_ACTION_DENY**  prevent *condition*.
-
-Optionally it can be augmented via OR with
-+ **ZX_POL_ACTION_EXCEPTION** generate an exception via the debug port. An
-  exception generated this way acts as a breakpoint. The thread may be
-  resumed after the exception.
-+ **ZX_POL_ACTION_KILL** terminate the process. It also
-implies **ZX_POL_ACTION_DENY**.
-
-### **ZX_JOB_POL_TIMER_SLACK**
-
-A *topic* of **ZX_JOB_POL_TIMER_SLACK** indicates that *policy* is:
-
-```
-typedef struct zx_policy_timer_slack {
-    zx_duration_t min_slack;
-    uint32_t default_mode;
-} zx_policy_timer_slack_t;
-
-```
-
-*min_slack* specifies the minimum amount of slack applied to timers and
-deadline-based events the job. Attempts to set a *min_slack* less than the
-parent job’s *min_slack* are ignored. In other words, a job’s *min_slack* is the
-maximum of the specified value and its parent job’s *min_slack*.
-
-*default_mode* specifies how slack will be applied when not otherwise indicated
-by the syscall arguments. A job’s *default_mode* may be set regardless of its
-parent job’s *default_mode*. The possible values for *default_mode* are:
-+ **ZX_TIMER_SLACK_CENTER**
-+ **ZX_TIMER_SLACK_EARLY**
-+ **ZX_TIMER_SLACK_LATE**
-
-See [timer slack](timer_slack.md) for more information.
-
-When setting timer slack policy, *options* must be **ZX_JOB_POL_RELATIVE** and
-**count** must be 1.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_JOB** and have **ZX_RIGHT_SET_POLICY**.
-
-## RETURN VALUE
-
-`zx_job_set_policy()` returns **ZX_OK** on success.  In the event of failure,
-a negative error value is returned.
-
-## NOTES
-
-The **ZX_POL_BAD_HANDLE** policy does not apply when calling [`zx_object_get_info()`]
-with the topic **ZX_INFO_HANDLE_VALID**.  All other topics and all other syscalls that
-take handles are subject to the policy.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *policy* was not a valid pointer, or *count* was 0,
-or *policy* was not **ZX_JOB_POL_RELATIVE** or **ZX_JOB_POL_ABSOLUTE**, or
-*topic* was not **ZX_JOB_POL_BASIC**.
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a job handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_POL_RIGHT_SET** right.
-
-**ZX_ERR_BAD_STATE**  the job has existing jobs or processes alive.
-
-**ZX_ERR_OUT_OF_RANGE** *count* is bigger than **ZX_POL_MAX** or *condition* is
-bigger than **ZX_POL_MAX**.
-
-**ZX_ERR_ALREADY_EXISTS** existing policy conflicts with the new policy.
-
-**ZX_ERR_NOT_SUPPORTED** an entry in *policy* has an invalid value.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_job_create()`]
- - [`zx_object_get_info()`]
- - [`zx_process_create()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_job_create()`]: job_create.md
-[`zx_object_get_info()`]: object_get_info.md
-[`zx_process_create()`]: process_create.md
diff --git a/docs/syscalls/ktrace_control.md b/docs/syscalls/ktrace_control.md
deleted file mode 100644
index 77847c3..0000000
--- a/docs/syscalls/ktrace_control.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_ktrace_control
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-ktrace_control - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_ktrace_control(zx_handle_t handle,
-                              uint32_t action,
-                              uint32_t options,
-                              void* ptr);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/ktrace_read.md b/docs/syscalls/ktrace_read.md
deleted file mode 100644
index bf556d9..0000000
--- a/docs/syscalls/ktrace_read.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# zx_ktrace_read
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-ktrace_read - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_ktrace_read(zx_handle_t handle,
-                           void* data,
-                           uint32_t offset,
-                           size_t data_size,
-                           size_t* actual);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/ktrace_write.md b/docs/syscalls/ktrace_write.md
deleted file mode 100644
index c6ae388..0000000
--- a/docs/syscalls/ktrace_write.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_ktrace_write
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-ktrace_write - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_ktrace_write(zx_handle_t handle,
-                            uint32_t id,
-                            uint32_t arg0,
-                            uint32_t arg1);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/mtrace_control.md b/docs/syscalls/mtrace_control.md
deleted file mode 100644
index 4856b13..0000000
--- a/docs/syscalls/mtrace_control.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# zx_mtrace_control
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-mtrace_control - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_mtrace_control(zx_handle_t handle,
-                              uint32_t kind,
-                              uint32_t action,
-                              uint32_t options,
-                              void* ptr,
-                              size_t ptr_size);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/nanosleep.md b/docs/syscalls/nanosleep.md
deleted file mode 100644
index a9a488d..0000000
--- a/docs/syscalls/nanosleep.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# zx_nanosleep
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-nanosleep - high resolution sleep
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_nanosleep(zx_time_t deadline);
-```
-
-## DESCRIPTION
-
-`zx_nanosleep()` suspends the calling thread execution until *deadline* passes
-on **ZX_CLOCK_MONOTONIC**. A *deadline* value less than or equal to **0** immediately
-yields the thread. *deadline* will be automatically adjusted according to the job's
-[timer slack] policy.
-
-To sleep for a duration, use [`zx_deadline_after()`] and the
-**ZX_\<time-unit\>** helpers:
-
-```
-#include <zircon/syscalls.h> // zx_deadline_after, zx_nanosleep
-#include <zircon/types.h> // ZX_MSEC et al.
-
-// Sleep 50 milliseconds
-zx_nanosleep(zx_deadline_after(ZX_MSEC(50)));
-```
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-None.
-
-## RETURN VALUE
-
-`zx_nanosleep()` always returns **ZX_OK**.
-
-## SEE ALSO
-
- - [timer slack]
- - [`zx_deadline_after()`]
- - [`zx_timer_cancel()`]
- - [`zx_timer_create()`]
- - [`zx_timer_set()`]
-
-[timer slack]: ../timer_slack.md
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_deadline_after()`]: deadline_after.md
-[`zx_timer_cancel()`]: timer_cancel.md
-[`zx_timer_create()`]: timer_create.md
-[`zx_timer_set()`]: timer_set.md
diff --git a/docs/syscalls/object_get_child.md b/docs/syscalls/object_get_child.md
deleted file mode 100644
index e70c2c8..0000000
--- a/docs/syscalls/object_get_child.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# zx_object_get_child
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_get_child - Given a kernel object with children objects, obtain a handle to the child specified by the provided kernel object id.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_get_child(zx_handle_t handle,
-                                uint64_t koid,
-                                zx_rights_t rights,
-                                zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_object_get_child()` attempts to find a child of the object referred to
-by *handle* which has the kernel object id specified by *koid*.  If such an
-object exists, and the requested *rights* are not greater than those provided
-by the *handle* to the parent, a new handle to the specified child object is
-returned.
-
-*rights* may be **ZX_RIGHT_SAME_RIGHTS** which will result in rights equivalent
-to the those on the *handle*.
-
-If the object is a *Process*, the *Threads* it contains may be obtained by
-this call.
-
-If the object is a *Job*, its (immediate) child *Jobs* and the *Processes*
-it contains may be obtained by this call.
-
-If the object is a *Resource*, its (immediate) child *Resources* may be
-obtained by this call.
-
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_ENUMERATE**.
-
-## RETURN VALUE
-
-On success, **ZX_OK** is returned and a handle to the desired child object is returned via *out*.
-
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a *Process*, *Job*, or *Resource*.
-
-**ZX_ERR_ACCESS_DENIED**   *handle* lacks the right **ZX_RIGHT_ENUMERATE** or *rights* specifies
-rights that are not present on *handle*.
-
-**ZX_ERR_NOT_FOUND**  *handle* does not have a child with the kernel object id *koid*.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_INVALID_ARGS**  *out* is an invalid pointer.
-
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_get_info()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_get_info()`]: object_get_info.md
diff --git a/docs/syscalls/object_get_cookie.md b/docs/syscalls/object_get_cookie.md
deleted file mode 100644
index e672cc7..0000000
--- a/docs/syscalls/object_get_cookie.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# zx_object_get_cookie
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_get_cookie - Get an object's cookie.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_get_cookie(zx_handle_t handle,
-                                 zx_handle_t scope,
-                                 uint64_t* cookie);
-```
-
-## DESCRIPTION
-
-Some objects (Events, Event pairs, Resources, VMOs) may have a cookie attached,
-which is a 64bit opaque value.  Initially the cookie is undefined and not readable.
-
-If the cookie has been set on an object, `zx_object_get_cookie()` may be
-called, using the same object as *scope* to obtain the cookie.
-
-Event pairs are special.  If one side of the pair is closed, the other side's
-cookie is invalidated. An invalidated cookie is not get-able or set-able with any scope.
-
-Cookies are useful for objects that will be passed to another process and
-later returned.  By setting the cookie with [`zx_object_set_cookie()`],
-using a *scope* that is not accessible by other processes, `zx_object_get_cookie()`
-may later be used to verify that a handle is referring to an object that was
-"created" by the calling process and simultaneously return an ID or pointer
-to local state for that object.
-
-When the object referenced by *scope* is destroyed or if a handle to that object
-is no longer available, the cookie may no longer be modified or obtained.
-
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_object_get_cookie()` returns **ZX_OK** and the *cookie* value on success.
-In the event of failure, a negative error value is returned.
-
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* or *scope* are not valid handles.
-
-**ZX_ERR_NOT_SUPPORTED**  *handle* is not a handle to an object that may have a cookie set.
-
-**ZX_ERR_ACCESS_DENIED**  The cookie has not been set, or *scope* is not the correct scope
-to obtain the set cookie.
-
-**ZX_ERR_INVALID_ARGS**  *cookie* is an invalid pointer.
-
-## SEE ALSO
-
- - [`zx_object_set_cookie()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_set_cookie()`]: object_set_cookie.md
diff --git a/docs/syscalls/object_get_info.md b/docs/syscalls/object_get_info.md
deleted file mode 100644
index aa71c73..0000000
--- a/docs/syscalls/object_get_info.md
+++ /dev/null
@@ -1,798 +0,0 @@
-# zx_object_get_info
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_get_info - query information about an object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_get_info(zx_handle_t handle,
-                               uint32_t topic,
-                               void* buffer,
-                               size_t buffer_size,
-                               size_t* actual,
-                               size_t* avail);
-```
-
-## DESCRIPTION
-
-`zx_object_get_info()` requests information about the provided handle (or the
-object the handle refers to). The *topic* parameter indicates what specific
-information is desired.
-
-*buffer* is a pointer to a buffer of size *buffer_size* to return the
-information.
-
-*actual* is an optional pointer to return the number of records that were
-written to buffer.
-
-*avail* is an optional pointer to return the number of records that are
-available to read.
-
-If the buffer is insufficiently large, *avail* will be larger than *actual*.
-
-[TOC]
-
-## TOPICS
-
-### ZX_INFO_HANDLE_VALID
-
-*handle* type: **Any**
-
-*buffer* type: **n/a**
-
-Returns **ZX_OK** if *handle* is valid, or **ZX_ERR_BAD_HANDLE** otherwise. No
-records are returned and *buffer* may be NULL.
-
-### ZX_INFO_HANDLE_BASIC
-
-*handle* type: **Any**
-
-*buffer* type: `zx_info_handle_basic_t[1]`
-
-```
-typedef struct zx_info_handle_basic {
-    // The unique id assigned by kernel to the object referenced by the
-    // handle.
-    zx_koid_t koid;
-
-    // The immutable rights assigned to the handle. Two handles that
-    // have the same koid and the same rights are equivalent and
-    // interchangeable.
-    zx_rights_t rights;
-
-    // The object type: channel, event, socket, etc.
-    uint32_t type;                // zx_obj_type_t;
-
-    // If the object referenced by the handle is related to another (such
-    // as the other end of a channel, or the parent of a job) then
-    // |related_koid| is the koid of that object, otherwise it is zero.
-    // This relationship is immutable: an object's |related_koid| does
-    // not change even if the related object no longer exists.
-    zx_koid_t related_koid;
-
-    // Set to ZX_OBJ_PROP_WAITABLE if the object referenced by the
-    // handle can be waited on; zero otherwise.
-    uint32_t props;               // zx_obj_props_t;
-} zx_info_handle_basic_t;
-```
-
-### ZX_INFO_HANDLE_COUNT
-
-*handle* type: **Any**
-
-*buffer* type: `zx_info_handle_count_t[1]`
-
-```
-typedef struct zx_info_handle_count {
-    // The number of outstanding handles to a kernel object.
-    uint32_t handle_count;
-} zx_info_handle_count_t;
-```
-The *handle_count* should only be used as a debugging aid. Do not use it
-to check that an untrusted processes cannot modify a kernel object. Due to
-asynchronous nature of the system scheduler, there might be a time window
-during which it is possible for an object to be modified by a previous handle
-owner even as the last handle is transferred from one process to another.
-
-### ZX_INFO_PROCESS_HANDLE_STATS
-
-*handle* type: **Process**
-
-*buffer* type: `zx_info_process_handle_stats_t[1]`
-
-```
-typedef struct zx_info_process_handle_stats {
-    // The number of outstanding handles to kernel objects of each type.
-    uint32_t handle_count[ZX_OBJ_TYPE_LAST];
-} zx_info_process_handle_stats_t;
-```
-
-### ZX_INFO_PROCESS
-
-*handle* type: **Process**
-
-*buffer* type: `zx_info_process_t[1]`
-
-```
-typedef struct zx_info_process {
-    // The process's return code; only valid if |exited| is true.
-    // Guaranteed to be non-zero if the process was killed by |zx_task_kill|.
-    int64_t return_code;
-
-    // True if the process has ever left the initial creation state,
-    // even if it has exited as well.
-    bool started;
-
-    // If true, the process has exited and |return_code| is valid.
-    bool exited;
-
-    // True if a debugger is attached to the process.
-    bool debugger_attached;
-} zx_info_process_t;
-```
-
-### ZX_INFO_PROCESS_THREADS
-
-*handle* type: **Process**
-
-*buffer* type: `zx_koid_t[n]`
-
-Returns an array of `zx_koid_t`, one for each running thread in the Process at
-that moment in time.
-
-N.B. Getting the list of threads is inherently racy.
-This can be somewhat mitigated by first suspending all the threads,
-but note that an external thread can create new threads.
-*actual* will contain the number of threads returned in *buffer*.
-*avail* will contain the total number of threads of the process at
-the time the list of threads was obtained, it could be larger than *actual*.
-
-### ZX_INFO_THREAD
-
-*handle* type: **Thread**
-
-*buffer* type: `zx_info_thread_t[1]`
-
-```
-typedef struct zx_info_thread {
-    // One of ZX_THREAD_STATE_* values.
-    uint32_t state;
-
-    // If |state| is ZX_THREAD_STATE_BLOCKED_EXCEPTION, the thread has gotten
-    // an exception and is waiting for the exception to be handled by the
-    // specified port.
-    // The value is one of ZX_EXCEPTION_PORT_TYPE_*.
-    uint32_t wait_exception_port_type;
-} zx_info_thread_t;
-```
-
-The values in this struct are mainly for informational and debugging
-purposes at the moment.
-
-The various **ZX_THREAD_STATE_** values are defined by
-
-```
-#include <zircon/syscalls/object.h>
-```
-
-*   **ZX_THREAD_STATE_NEW**: The thread has been created but it has not started running yet.
-*   **ZX_THREAD_STATE_RUNNING**: The thread is running user code normally.
-*   **ZX_THREAD_STATE_SUSPENDED**: Stopped due to [`zx_task_suspend()`].
-*   **ZX_THREAD_STATE_BLOCKED**: In a syscall or handling an exception.
-    This value is never returned by itself.
-	See **ZX_THREAD_STATE_BLOCKED_\*** below.
-*   **ZX_THREAD_STATE_DYING**: The thread is in the process of being terminated,
-    but it has not been stopped yet.
-*   **ZX_THREAD_STATE_DEAD**: The thread has stopped running.
-
-When a thread is stopped inside a blocking syscall, or stopped in an
-exception, the value returned in **state** is one of the following:
-
-*   **ZX_THREAD_STATE_BLOCKED_EXCEPTION**: The thread is stopped in an exception.
-*   **ZX_THREAD_STATE_BLOCKED_SLEEPING**: The thread is stopped in [`zx_nanosleep()`].
-*   **ZX_THREAD_STATE_BLOCKED_FUTEX**: The thread is stopped in [`zx_futex_wait()`].
-*   **ZX_THREAD_STATE_BLOCKED_PORT**: The thread is stopped in [`zx_port_wait()`].
-*   **ZX_THREAD_STATE_BLOCKED_CHANNEL**: The thread is stopped in [`zx_channel_call()`].
-*   **ZX_THREAD_STATE_BLOCKED_WAIT_ONE**: The thread is stopped in [`zx_object_wait_one()`].
-*   **ZX_THREAD_STATE_BLOCKED_WAIT_MANY**: The thread is stopped in [`zx_object_wait_many()`].
-*   **ZX_THREAD_STATE_BLOCKED_INTERRUPT**: The thread is stopped in [`zx_interrupt_wait()`].
-
-The various **ZX_EXCEPTION_PORT_TYPE_** values are defined by
-
-```
-#include <zircon/syscalls/exception.h>
-```
-
-*   **ZX_EXCEPTION_PORT_TYPE_NONE**
-*   **ZX_EXCEPTION_PORT_TYPE_DEBUGGER**
-*   **ZX_EXCEPTION_PORT_TYPE_THREAD**
-*   **ZX_EXCEPTION_PORT_TYPE_PROCESS**
-*   **ZX_EXCEPTION_PORT_TYPE_JOB**
-*   **ZX_EXCEPTION_PORT_TYPE_JOB_DEBUGGER**
-
-### ZX_INFO_THREAD_EXCEPTION_REPORT
-
-*handle* type: **Thread**
-
-*buffer* type: `zx_exception_report_t[1]`
-
-```
-#include <zircon/syscalls/exception.h>
-```
-
-If the thread is currently in an exception and is waiting for an exception
-response, then this returns the exception report as a single
-`zx_exception_report_t`, with status **ZX_OK**.
-
-Returns **ZX_ERR_BAD_STATE** if the thread is not in an exception and waiting for
-an exception response.
-
-### ZX_INFO_THREAD_STATS
-
-*handle* type: **Thread**
-
-*buffer* type: `zx_info_thread_stats[1]`
-
-```
-typedef struct zx_info_thread_stats {
-    // Total accumulated running time of the thread.
-    zx_duration_t total_runtime;
-} zx_info_thread_stats_t;
-```
-
-
-### ZX_INFO_CPU_STATS
-
-Note: many values of this topic are being retired in favor of a different mechanism.
-
-*handle* type: **Resource** (Specifically, the root resource)
-
-*buffer* type: `zx_info_cpu_stats_t[1]`
-
-```
-typedef struct zx_info_cpu_stats {
-    uint32_t cpu_number;
-    uint32_t flags;
-
-    zx_duration_t idle_time;
-
-    // kernel scheduler counters
-    uint64_t reschedules;
-    uint64_t context_switches;
-    uint64_t irq_preempts;
-    uint64_t preempts;
-    uint64_t yields;
-
-    // cpu level interrupts and exceptions
-    uint64_t ints;          // hardware interrupts, minus timer interrupts
-                            // inter-processor interrupts
-    uint64_t timer_ints;    // timer interrupts
-    uint64_t timers;        // timer callbacks
-    uint64_t page_faults;   // (deprecated, returns 0)
-    uint64_t exceptions;    // (deprecated, returns 0)
-    uint64_t syscalls;
-
-    // inter-processor interrupts
-    uint64_t reschedule_ipis;
-    uint64_t generic_ipis;
-} zx_info_cpu_stats_t;
-```
-
-### ZX_INFO_VMAR
-
-*handle* type: **VM Address Region**
-
-*buffer* type: `zx_info_vmar_t[1]`
-
-```
-typedef struct zx_info_vmar {
-    // Base address of the region.
-    uintptr_t base;
-
-    // Length of the region, in bytes.
-    size_t len;
-} zx_info_vmar_t;
-```
-
-This returns a single `zx_info_vmar_t` that describes the range of address
-space that the VMAR occupies.
-
-### ZX_INFO_VMO
-
-*handle* type: **VM Object**
-
-*buffer* type: `zx_info_vmo_t[1]`
-
-```
-typedef struct zx_info_vmo {
-    // The koid of this VMO.
-    zx_koid_t koid;
-
-    // The name of this VMO.
-    char name[ZX_MAX_NAME_LEN];
-
-    // The size of this VMO.
-    uint64_t size_bytes;
-
-    // If this VMO is a clone, the koid of its parent. Otherwise, zero.
-    zx_koid_t parent_koid;
-
-    // The number of clones of this VMO, if any.
-    size_t num_children;
-
-    // The number of times this VMO is currently mapped into VMARs.
-    size_t num_mappings;
-
-    // An estimate of the number of unique address spaces that
-    // this VMO is mapped into.
-    size_t share_count;
-
-    // Bitwise OR of ZX_INFO_VMO_* values.
-    uint32_t flags;
-
-    // If |ZX_INFO_VMO_TYPE(flags) == ZX_INFO_VMO_TYPE_PAGED|, the amount of
-    // memory currently allocated to this VMO.
-    uint64_t committed_bytes;
-
-    // If |flags & ZX_INFO_VMO_VIA_HANDLE|, the handle rights.
-    // Undefined otherwise.
-    zx_rights_t handle_rights;
-
-    // VMO creation options. This is a bitmask of
-    // kResizable    = (1u << 0);
-    // kContiguous   = (1u << 1);
-    uint32_t create_options;
-
-    // VMO mapping cache policy. One of ZX_CACHE_POLICY_*
-    uint32_t cache_policy;
-} zx_info_vmo_t;
-```
-
-This returns a single `zx_info_vmo_t` that describes various attributes of
-the VMO.
-
-### ZX_INFO_SOCKET
-
-*handle* type: **Socket**
-
-*buffer* type: `zx_info_socket_t[1]`
-
-```
-typedef struct zx_info_socket {
-    // The options passed to zx_socket_create().
-    uint32_t options;
-
-    // The maximum size of the receive buffer of a socket, in bytes.
-    //
-    // The receive buffer may become full at a capacity less than the maximum
-    // due to overhead.
-    size_t rx_buf_max;
-
-    // The size of the receive buffer of a socket, in bytes.
-    size_t rx_buf_size;
-
-    // The amount of data, in bytes, that is available for reading in a single
-    // zx_socket_read call.
-    //
-    // For stream sockets, this value will match |rx_buf_size|. For datagram
-    // sockets, this value will be the size of the next datagram in the receive
-    // buffer.
-    size_t rx_buf_available;
-
-    // The maximum size of the transmit buffer of a socket, in bytes.
-    //
-    // The transmit buffer may become full at a capacity less than the maximum
-    // due to overhead.
-    //
-    // Will be zero if the peer endpoint is closed.
-    size_t tx_buf_max;
-
-    // The size of the transmit buffer of a socket, in bytes.
-    //
-    // Will be zero if the peer endpoint is closed.
-    size_t tx_buf_size;
-} zx_info_socket_t;
-```
-
-### ZX_INFO_JOB_CHILDREN
-
-*handle* type: **Job**
-
-*buffer* type: `zx_koid_t[n]`
-
-Returns an array of `zx_koid_t`, one for each direct child Job of the provided
-Job handle.
-
-### ZX_INFO_JOB_PROCESSES
-
-*handle* type: **Job**
-
-*buffer* type: `zx_koid_t[n]`
-
-Returns an array of `zx_koid_t`, one for each direct child Process of the
-provided Job handle.
-
-### ZX_INFO_TASK_STATS
-
-*handle* type: **Process**
-
-*buffer* type: `zx_info_task_stats_t[1]`
-
-Returns statistics about resources (e.g., memory) used by a task.
-
-```
-typedef struct zx_info_task_stats {
-    // The total size of mapped memory ranges in the task.
-    // Not all will be backed by physical memory.
-    size_t mem_mapped_bytes;
-
-    // For the fields below, a byte is considered committed if it's backed by
-    // physical memory. Some of the memory may be double-mapped, and thus
-    // double-counted.
-
-    // Committed memory that is only mapped into this task.
-    size_t mem_private_bytes;
-
-    // Committed memory that is mapped into this and at least one other task.
-    size_t mem_shared_bytes;
-
-    // A number that estimates the fraction of mem_shared_bytes that this
-    // task is responsible for keeping alive.
-    //
-    // An estimate of:
-    //   For each shared, committed byte:
-    //   mem_scaled_shared_bytes += 1 / (number of tasks mapping this byte)
-    //
-    // This number is strictly smaller than mem_shared_bytes.
-    size_t mem_scaled_shared_bytes;
-} zx_info_task_stats_t;
-```
-
-Additional errors:
-
-*   **ZX_ERR_BAD_STATE**: If the target process has terminated
-
-### ZX_INFO_PROCESS_MAPS
-
-*handle* type: **Process** other than your own, with **ZX_RIGHT_READ**
-
-*buffer* type: `zx_info_maps_t[n]`
-
-The `zx_info_maps_t` array is a depth-first pre-order walk of the target
-process's Aspace/VMAR/Mapping tree. As per the pre-order traversal base
-addresses will be in ascending order.
-
-```
-typedef struct zx_info_maps {
-    // Name if available; empty string otherwise.
-    char name[ZX_MAX_NAME_LEN];
-    // Base address.
-    zx_vaddr_t base;
-    // Size in bytes.
-    size_t size;
-
-    // The depth of this node in the tree.
-    // Can be used for indentation, or to rebuild the tree from an array
-    // of zx_info_maps_t entries, which will be in depth-first pre-order.
-    size_t depth;
-    // The type of this entry; indicates which union entry is valid.
-    uint32_t type; // zx_info_maps_type_t
-    union {
-        zx_info_maps_mapping_t mapping;
-        // No additional fields for other types.
-    } u;
-} zx_info_maps_t;
-```
-
-The *depth* field of each entry describes its relationship to the nodes that
-come before it. Depth 0 is the root Aspace, depth 1 is the root VMAR, and all
-other entries have depth 2 or greater.
-
-To get a full picture of how a process uses its VMOs and how a VMO is used
-by various processes, you may need to combine this information with
-ZX_INFO_PROCESS_VMOS.
-
-See the `vmaps` command-line tool for an example user of this topic, and to dump
-the maps of arbitrary processes by koid.
-
-Additional errors:
-
-*   **ZX_ERR_ACCESS_DENIED**: If the appropriate rights are missing, or if a
-    process attempts to call this on a handle to itself. It's not safe to
-    examine yourself: *buffer* will live inside the Aspace being examined, and
-    the kernel can't safely fault in pages of the buffer while walking the
-    Aspace.
-*   **ZX_ERR_BAD_STATE**: If the target process has terminated, or if its
-    address space has been destroyed
-
-### ZX_INFO_PROCESS_VMOS
-
-*handle* type: **Process** other than your own, with **ZX_RIGHT_READ**
-
-*buffer* type: `zx_info_vmos_t[n]`
-
-The `zx_info_vmos_t` array is list of all VMOs pointed to by the target process.
-Some VMOs are mapped, some are pointed to by handles, and some are both.
-
-**Note**: The same VMO may appear multiple times due to multiple
-mappings/handles. Also, because VMOs can change as the target process runs,
-the same VMO may have different values each time it appears. It is the
-caller's job to resolve any duplicates.
-
-To get a full picture of how a process uses its VMOs and how a VMO is used
-by various processes, you may need to combine this information with
-ZX_INFO_PROCESS_MAPS.
-
-```
-// Describes a VMO.
-typedef struct zx_info_vmo {
-    // The koid of this VMO.
-    zx_koid_t koid;
-
-    // The name of this VMO.
-    char name[ZX_MAX_NAME_LEN];
-
-    // The size of this VMO; i.e., the amount of virtual address space it
-    // would consume if mapped.
-    uint64_t size_bytes;
-
-    // If this VMO is a clone, the koid of its parent. Otherwise, zero.
-    // See |flags| for the type of clone.
-    zx_koid_t parent_koid;
-
-    // The number of clones of this VMO, if any.
-    size_t num_children;
-
-    // The number of times this VMO is currently mapped into VMARs.
-    // Note that the same process will often map the same VMO twice,
-    // and both mappings will be counted here. (I.e., this is not a count
-    // of the number of processes that map this VMO; see share_count.)
-    size_t num_mappings;
-
-    // An estimate of the number of unique address spaces that
-    // this VMO is mapped into. Every process has its own address space,
-    // and so does the kernel.
-    size_t share_count;
-
-    // Bitwise OR of ZX_INFO_VMO_* values.
-    uint32_t flags;
-
-    // If |ZX_INFO_VMO_TYPE(flags) == ZX_INFO_VMO_TYPE_PAGED|, the amount of
-    // memory currently allocated to this VMO; i.e., the amount of physical
-    // memory it consumes. Undefined otherwise.
-    uint64_t committed_bytes;
-
-    // If |flags & ZX_INFO_VMO_VIA_HANDLE|, the handle rights.
-    // Undefined otherwise.
-    zx_rights_t handle_rights;
-} zx_info_vmo_t;
-```
-
-See the `vmos` command-line tool for an example user of this topic, and to dump
-the VMOs of arbitrary processes by koid.
-
-### ZX_INFO_KMEM_STATS
-
-*handle* type: **Resource** (Specifically, the root resource)
-
-*buffer* type: `zx_info_kmem_stats_t[1]`
-
-Returns information about kernel memory usage. It can be expensive to gather.
-
-```
-typedef struct zx_info_kmem_stats {
-    // The total amount of physical memory available to the system.
-    size_t total_bytes;
-
-    // The amount of unallocated memory.
-    size_t free_bytes;
-
-    // The amount of memory reserved by and mapped into the kernel for reasons
-    // not covered by other fields in this struct. Typically for readonly data
-    // like the ram disk and kernel image, and for early-boot dynamic memory.
-    size_t wired_bytes;
-
-    // The amount of memory allocated to the kernel heap.
-    size_t total_heap_bytes;
-
-    // The portion of |total_heap_bytes| that is not in use.
-    size_t free_heap_bytes;
-
-    // The amount of memory committed to VMOs, both kernel and user.
-    // A superset of all userspace memory.
-    // Does not include certain VMOs that fall under |wired_bytes|.
-    //
-    // TODO(dbort): Break this into at least two pieces: userspace VMOs that
-    // have koids, and kernel VMOs that don't. Or maybe look at VMOs
-    // mapped into the kernel aspace vs. everything else.
-    size_t vmo_bytes;
-
-    // The amount of memory used for architecture-specific MMU metadata
-    // like page tables.
-    size_t mmu_overhead_bytes;
-
-    // Non-free memory that isn't accounted for in any other field.
-    size_t other_bytes;
-} zx_info_kmem_stats_t;
-```
-
-### ZX_INFO_RESOURCE
-
-*handle* type: **Resource**
-
-*buffer* type: `zx_info_resource_t[1]`
-
-Returns information about a resource object via its handle.
-
-```
-typedef struct zx_info_resource {
-    // The resource kind
-    uint32_t kind;
-    // Resource's low value (inclusive)
-    uint64_t low;
-    // Resource's high value (inclusive)
-    uint64_t high;
-} zx_info_resource_t;
-```
-
-The resource kind is one of
-
-*   **ZX_RSRC_KIND_ROOT**
-*   **ZX_RSRC_KIND_MMIO**
-*   **ZX_RSRC_KIND_IOPORT**
-*   **ZX_RSRC_KIND_IRQ**
-*   **ZX_RSRC_KIND_HYPERVISOR**
-*   **ZX_RSRC_KIND_VMEX**
-*   **ZX_RSRC_KIND_SMC**
-
-### ZX_INFO_BTI
-
-*handle* type: **Bus Transaction Initiator**
-
-*buffer* type: `zx_info_bti_t[1]`
-
-```
-typedef struct zx_info_bti {
-    // zx_bti_pin will always be able to return addresses that are contiguous for at
-    // least this many bytes.  E.g. if this returns 1MB, then a call to
-    // zx_bti_pin() with a size of 2MB will return at most two physically-contiguous runs.
-    // If the size were 2.5MB, it will return at most three physically-contiguous runs.
-    uint64_t minimum_contiguity;
-
-    // The number of bytes in the device's address space (UINT64_MAX if 2^64).
-    uint64_t aspace_size;
-} zx_info_bti_t;
-```
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-If *topic* is **ZX_INFO_PROCESS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_PROCESS_THREADS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_ENUMERATE**.
-
-If *topic* is **ZX_INFO_JOB_CHILDREN**, *handle* must be of type **ZX_OBJ_TYPE_JOB** and have **ZX_RIGHT_ENUMERATE**.
-
-If *topic* is **ZX_INFO_JOB_PROCESSES**, *handle* must be of type **ZX_OBJ_TYPE_JOB** and have **ZX_RIGHT_ENUMERATE**.
-
-If *topic* is **ZX_INFO_THREAD**, *handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_THREAD_EXCEPTION_REPORT**, *handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_THREAD_STATS**, *handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_TASK_STATS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_PROCESS_MAPS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_PROCESS_VMOS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_VMO**, *handle* must be of type **ZX_OBJ_TYPE_VMO**.
-
-If *topic* is **ZX_INFO_VMAR**, *handle* must be of type **ZX_OBJ_TYPE_VMAR** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_CPU_STATS**, *handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-If *topic* is **ZX_INFO_KMEM_STATS**, *handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-If *topic* is **ZX_INFO_RESOURCE**, *handle* must be of type **ZX_OBJ_TYPE_RESOURCE** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_HANDLE_COUNT**, *handle* must have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_BTI**, *handle* must be of type **ZX_OBJ_TYPE_BTI** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_PROCESS_HANDLE_STATS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
-
-If *topic* is **ZX_INFO_SOCKET**, *handle* must be of type **ZX_OBJ_TYPE_SOCKET** and have **ZX_RIGHT_INSPECT**.
-
-## RETURN VALUE
-
-`zx_object_get_info()` returns **ZX_OK** on success. In the event of
-failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not an appropriate type for *topic*
-
-**ZX_ERR_ACCESS_DENIED**: If *handle* does not have the necessary rights for the
-operation.
-
-**ZX_ERR_INVALID_ARGS** *buffer*, *actual*, or *avail* are invalid pointers.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_BUFFER_TOO_SMALL** The *topic* returns a fixed number of records, but the
-provided buffer is not large enough for these records.
-
-**ZX_ERR_NOT_SUPPORTED** *topic* does not exist.
-
-## EXAMPLES
-
-```
-bool is_handle_valid(zx_handle_t handle) {
-    return zx_object_get_info(
-        handle, ZX_INFO_HANDLE_VALID, NULL, 0, NULL, NULL) == ZX_OK;
-}
-
-zx_koid_t get_object_koid(zx_handle_t handle) {
-    zx_info_handle_basic_t info;
-    if (zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC,
-                           &info, sizeof(info), NULL, NULL) != ZX_OK) {
-        return 0;
-    }
-    return info.koid;
-}
-
-void examine_threads(zx_handle_t proc) {
-    zx_koid_t threads[128];
-    size_t count, avail;
-
-    if (zx_object_get_info(proc, ZX_INFO_PROCESS_THREADS, threads,
-                           sizeof(threads), &count, &avail) != ZX_OK) {
-        // Error!
-    } else {
-        if (avail > count) {
-            // More threads than space in array;
-            // could call again with larger array.
-        }
-        for (size_t n = 0; n < count; n++) {
-            do_something(thread[n]);
-        }
-    }
-}
-```
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_get_child()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_channel_call()`]: channel_call.md
-[`zx_futex_wait()`]: futex_wait.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_interrupt_wait()`]: interrupt_wait.md
-[`zx_nanosleep()`]: nanosleep.md
-[`zx_object_get_child()`]: object_get_child.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
-[`zx_port_wait()`]: port_wait.md
-[`zx_task_suspend()`]: task_suspend.md
diff --git a/docs/syscalls/object_get_property.md b/docs/syscalls/object_get_property.md
deleted file mode 100644
index 934a529..0000000
--- a/docs/syscalls/object_get_property.md
+++ /dev/null
@@ -1,191 +0,0 @@
-# zx_object_get_property
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_get_property - Ask for various properties of various kernel objects.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_get_property(zx_handle_t handle,
-                                   uint32_t property,
-                                   void* value,
-                                   size_t value_size);
-```
-
-## DESCRIPTION
-
-`zx_object_get_property()` requests the value of a kernel object's property.
-Getting a property requires **ZX_RIGHT_GET_PROPERTY** rights on the handle.
-
-The *handle* parameter indicates the target kernel object. Different properties
-only work on certain types of kernel objects, as described below.
-
-The *property* parameter indicates which property to get/set. Property values
-have the prefix **ZX_PROP_**, and are described below.
-
-The *value* parameter holds the property value, and must be a pointer to a
-buffer of *value_size* bytes. Different properties expect different value
-types/sizes as described below.
-
-## PROPERTIES
-
-Property values have the prefix **ZX_PROP_**, and are defined in
-
-```
-#include <zircon/syscalls/object.h>
-```
-
-### ZX_PROP_NAME
-
-*handle* type: **(Most types)**
-
-*value* type: `char[ZX_MAX_NAME_LEN]`
-
-Allowed operations: **get**, **set**
-
-The name of the object, as a NUL-terminated string.
-
-### ZX_PROP_REGISTER_FS and ZX_PROP_REGISTER_GS
-
-*handle* type: **Thread**
-
-*value* type: `uintptr_t`
-
-Allowed operations: **set**
-
-The value of the x86 FS or GS segment register. `value` must be a
-canonical address, and must be a userspace address.
-
-Only defined for x86-64.
-
-### ZX_PROP_PROCESS_DEBUG_ADDR
-
-*handle* type: **Process**
-
-*value* type: `uintptr_t`
-
-Allowed operations: **get**, **set**
-
-The value of ld.so's `_dl_debug_addr`. This can be used by debuggers to
-interrogate the state of the dynamic loader.
-
-If this value is set to `ZX_PROCESS_DEBUG_ADDR_BREAK_ON_SET` on process
-creation, the loader will manually issue a debug breakpoint when the property
-has been set to its correct value. This gives an opportunity to read or modify
-the initial state of the program.
-
-### ZX_PROP_PROCESS_VDSO_BASE_ADDRESS
-
-*handle* type: **Process**
-
-*value* type: `uintptr_t`
-
-Allowed operations: **get**
-
-The base address of the vDSO mapping, or zero.
-
-### ZX_PROP_JOB_IMPORTANCE
-
-*handle* type: **Job**
-
-*value* type: `zx_job_importance_t`
-
-Allowed operations: **get**, **set**
-
-A hint about how important a job is; used to rank jobs for the out-of-memory
-(OOM) killer.
-
-Additional errors:
-
-*   **ZX_ERR_OUT_OF_RANGE**: If the importance value is not valid
-
-### ZX_PROP_SOCKET_RX_THRESHOLD
-
-*handle* type: **Socket**
-
-*value* type: `size_t`
-
-Allowed operations: **get**, **set**
-
-The size of the read threshold of a socket, in bytes. Setting this will
-assert ZX_SOCKET_READ_THRESHOLD if the amount of data that can be read
-is greater than or equal to the threshold. Setting this property to zero
-will result in the deasserting of ZX_SOCKET_READ_THRESHOLD.
-
-### ZX_PROP_SOCKET_TX_THRESHOLD
-
-*handle* type: **Socket**
-
-*value* type: `size_t`
-
-Allowed operations: **get**, **set**
-
-The size of the write threshold of a socket, in bytes. Setting this will
-assert ZX_SOCKET_WRITE_THRESHOLD if the amount of space available for writing
-is greater than or equal to the threshold. Setting this property to zero
-will result in the deasserting of ZX_SOCKET_WRITE_THRESHOLD. Setting the
-write threshold after the peer has closed is an error, and results in a
-ZX_ERR_PEER_CLOSED error being returned.
-
-### ZX_PROP_JOB_KILL_ON_OOM
-
-*handle* type: **Job**
-
-*value* type: `size_t`
-
-Allowed operations: **set**
-
-The value of 1 means the Job and its children will be terminated if the
-system finds itself in a system-wide low memory situation. Called with 0
-(which is the default) opts out the job from being terminated in this
-scenario.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_GET_PROPERTY**.
-
-If *property* is **ZX_PROP_PROCESS_DEBUG_ADDR**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS**.
-
-If *property* is **ZX_PROP_PROCESS_VDSO_BASE_ADDRESS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS**.
-
-If *property* is **ZX_PROP_SOCKET_RX_THRESHOLD**, *handle* must be of type **ZX_OBJ_TYPE_SOCKET**.
-
-If *property* is **ZX_PROP_SOCKET_TX_THRESHOLD**, *handle* must be of type **ZX_OBJ_TYPE_SOCKET**.
-
-## RETURN VALUE
-
-`zx_object_get_property()` returns **ZX_OK** on success. In the event of
-failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**: *handle* is not a valid handle
-
-**ZX_ERR_WRONG_TYPE**: *handle* is not an appropriate type for *property*
-
-**ZX_ERR_ACCESS_DENIED**: *handle* does not have the necessary rights for the
-operation
-
-**ZX_ERR_INVALID_ARGS**: *value* is an invalid pointer
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_BUFFER_TOO_SMALL**: *value_size* is too small for *property*
-
-**ZX_ERR_NOT_SUPPORTED**: *property* does not exist
-
-## SEE ALSO
-
-
-[object_set_property](object_set_property.md)
diff --git a/docs/syscalls/object_set_cookie.md b/docs/syscalls/object_set_cookie.md
deleted file mode 100644
index 2eb7c2b..0000000
--- a/docs/syscalls/object_set_cookie.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# zx_object_set_cookie
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_set_cookie - Set an object's cookie.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_set_cookie(zx_handle_t handle,
-                                 zx_handle_t scope,
-                                 uint64_t cookie);
-```
-
-## DESCRIPTION
-Some objects (Events, Event pairs, Resources, VMOs) may have a Cookie attached,
-which is a 64bit opaque value.  Initially the Cookie is undefined and not
-readable.
-
-Once `zx_object_set_cookie()` is called successfully, the cookie is set,
-and the Object referenced by the *scope* handle becomes the key necessary
-to read the cookie or modify it.  The *scope* may never be changed for the
-lifetime of the object.
-
-Event pairs are special.  If one side of the pair is closed, the other side's
-cookie is invalidated. An invalidated cookie is not get-able or set-able with any scope.
-
-Cookies are useful for objects that will be passed to another process and
-later returned.  By setting the cookie with `zx_object_set_cookie()`,
-using a *scope* that is not accessible by other processes, [`zx_object_get_cookie()`]
-may later be used to verify that a handle is referring to an object that was
-"created" by the calling process and simultaneously return an ID or pointer
-to local state for that object.
-
-When the object referenced by *scope* is destroyed or if a handle to that object
-is no longer available, the cookie may no longer be modified or obtained.
-
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_object_set_cookie()` returns **ZX_OK** on success.  In the event of failure,
-a negative error value is returned.
-
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* or *scope* are not valid handles.
-
-**ZX_ERR_NOT_SUPPORTED**  *handle* is not a handle to an object that may have a cookie set.
-
-**ZX_ERR_ACCESS_DENIED**  `zx_object_set_cookie()` was called previously with a different
-object as the *scope*, or the cookie has not been set.
-
-
-## SEE ALSO
-
- - [`zx_object_get_cookie()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_get_cookie()`]: object_get_cookie.md
diff --git a/docs/syscalls/object_set_profile.md b/docs/syscalls/object_set_profile.md
deleted file mode 100644
index 1ba2252..0000000
--- a/docs/syscalls/object_set_profile.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# zx_object_set_profile
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_set_profile - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_set_profile(zx_handle_t handle,
-                                  zx_handle_t profile,
-                                  uint32_t options);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_MANAGE_THREAD**.
-
-*profile* must be of type **ZX_OBJ_TYPE_PROFILE** and have **ZX_RIGHT_APPLY_PROFILE**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/object_set_property.md b/docs/syscalls/object_set_property.md
deleted file mode 100644
index 70f6362..0000000
--- a/docs/syscalls/object_set_property.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# zx_object_set_property
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_set_property - Set various properties of various kernel objects.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_set_property(zx_handle_t handle,
-                                   uint32_t property,
-                                   const void* value,
-                                   size_t value_size);
-```
-
-## DESCRIPTION
-
-`zx_object_set_property()` modifies the value of a kernel object's property.
-Setting a property requires **ZX_RIGHT_SET_PROPERTY** rights on the handle.
-
-See [`zx_object_get_property()`] for a full description.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_SET_PROPERTY**.
-
-If *property* is **ZX_PROP_PROCESS_DEBUG_ADDR**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS**.
-
-If *property* is **ZX_PROP_SOCKET_RX_THRESHOLD**, *handle* must be of type **ZX_OBJ_TYPE_SOCKET**.
-
-If *property* is **ZX_PROP_SOCKET_TX_THRESHOLD**, *handle* must be of type **ZX_OBJ_TYPE_SOCKET**.
-
-If *property* is **ZX_PROP_JOB_KILL_ON_OOM**, *handle* must be of type **ZX_OBJ_TYPE_JOB**.
-
-## SEE ALSO
-
- - [`zx_object_get_property()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_get_property()`]: object_get_property.md
diff --git a/docs/syscalls/object_signal.md b/docs/syscalls/object_signal.md
deleted file mode 100644
index 77a239c..0000000
--- a/docs/syscalls/object_signal.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# zx_object_signal
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_signal - signal an object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_signal(zx_handle_t handle,
-                             uint32_t clear_mask,
-                             uint32_t set_mask);
-```
-
-## DESCRIPTION
-
-`zx_object_signal()` asserts and deasserts the userspace-accessible signal
-bits on an object.
-
-Most of the 32 signals are reserved for system use and are assigned to
-per-object functions, like **ZX_CHANNEL_READABLE** or **ZX_TASK_TERMINATED**. There
-are 8 signal bits available for userspace processes to use as they see fit:
-**ZX_USER_SIGNAL_0** through **ZX_USER_SIGNAL_7**.
-
-*Event* objects also allow control over the **ZX_EVENT_SIGNALED** bit.
-
-*Eventpair* objects also allow control over the **ZX_EVENTPAIR_SIGNALED** bit.
-
-The *clear_mask* is first used to clear any bits indicated, and then the
-*set_mask* is used to set any bits indicated.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_SIGNAL**.
-
-## RETURN VALUE
-
-`zx_object_signal()` returns **ZX_OK** on success. In the event of failure, a
-negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* lacks the right **ZX_RIGHT_SIGNAL**.
-
-**ZX_ERR_INVALID_ARGS**  *clear_mask* or *set_mask* contain bits that are not allowed.
-
-## SEE ALSO
-
- - [`zx_event_create()`]
- - [`zx_eventpair_create()`]
- - [`zx_object_signal_peer()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_event_create()`]: event_create.md
-[`zx_eventpair_create()`]: eventpair_create.md
-[`zx_object_signal_peer()`]: object_signal_peer.md
diff --git a/docs/syscalls/object_signal_peer.md b/docs/syscalls/object_signal_peer.md
deleted file mode 100644
index 080bb31..0000000
--- a/docs/syscalls/object_signal_peer.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# zx_object_signal_peer
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_signal_peer - signal an object's peer
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_signal_peer(zx_handle_t handle,
-                                  uint32_t clear_mask,
-                                  uint32_t set_mask);
-```
-
-## DESCRIPTION
-
-`zx_object_signal_peer()` asserts and deasserts the userspace-accessible
-signal bits on the object's peer. A object peer is the opposite endpoint of a
-*channel*, *socket*, *fifo*, or *eventpair*.
-
-Most of the 32 signals are reserved for system use and are assigned to
-per-object functions, like **ZX_CHANNEL_READABLE** or **ZX_TASK_TERMINATED**. There
-are 8 signal bits available for userspace processes to use as they see fit:
-**ZX_USER_SIGNAL_0** through **ZX_USER_SIGNAL_7**.
-
-*Event* objects also allow control over the **ZX_EVENT_SIGNALED** bit.
-
-*Eventpair* objects also allow control over the **ZX_EVENTPAIR_SIGNALED** bit.
-
-The *clear_mask* is first used to clear any bits indicated, and then the
-*set_mask* is used to set any bits indicated.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_SIGNAL_PEER**.
-
-## RETURN VALUE
-
-`zx_object_signal_peer()` returns **ZX_OK** on success. In the event of
-failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* lacks the right **ZX_RIGHT_SIGNAL_PEER**.
-
-**ZX_ERR_INVALID_ARGS**  *clear_mask* or *set_mask* contain bits that are not allowed.
-
-**ZX_ERR_NOT_SUPPORTED**  Used on an object lacking a peer.
-
-**ZX_ERR_PEER_CLOSED**  Called on an object with a closed peer.
-
-## SEE ALSO
-
- - [`zx_event_create()`]
- - [`zx_eventpair_create()`]
- - [`zx_object_signal()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_event_create()`]: event_create.md
-[`zx_eventpair_create()`]: eventpair_create.md
-[`zx_object_signal()`]: object_signal.md
diff --git a/docs/syscalls/object_wait_async.md b/docs/syscalls/object_wait_async.md
deleted file mode 100644
index 290bcfe..0000000
--- a/docs/syscalls/object_wait_async.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# zx_object_wait_async
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_wait_async - subscribe for signals on an object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_wait_async(zx_handle_t handle,
-                                 zx_handle_t port,
-                                 uint64_t key,
-                                 zx_signals_t signals,
-                                 uint32_t options);
-```
-
-## DESCRIPTION
-
-`zx_object_wait_async()` is a non-blocking syscall which causes packets to be
-enqueued on *port* when the specified condition is met.
-Use [`zx_port_wait()`] to retrieve the packets.
-
-*handle* points to the object that is to be watched for changes and must be a waitable object.
-
-The *options* argument can be either **ZX_WAIT_ASYNC_ONCE** or **ZX_WAIT_ASYNC_REPEATING**.
-
-In both cases, *signals* indicates which signals on the object specified by *handle*
-will cause a packet to be enqueued, and if **any** of those signals are asserted when
-`zx_object_wait_async()` is called, or become asserted afterwards, a packet will be
-enqueued on *port* containing all of the currently-asserted signals (not just the ones
-listed in the *signals* argument).
-
-In the case of **ZX_WAIT_ASYNC_ONCE**, once a packet has been enqueued the asynchronous
-waiting ends.  No further packets will be enqueued.
-
-In the case of **ZX_WAIT_ASYNC_REPEATING** the asynchronous waiting continues until
-canceled. If any of *signals* are asserted and a packet is not currently in *port*'s
-queue on behalf of this wait, a packet is enqueued. If a packet is already in the
-queue, the packet's *observed* field is updated to include all of the currently-asserted
-signals (without removing the existing signals).
-
-In either mode, [`zx_port_cancel()`] will terminate the operation and if a packet was
-in the queue on behalf of the operation, that packet will be removed from the queue.
-
-If *handle* is closed, the operation will also be terminated, but packets already
-in the queue are not affected.
-
-Packets generated via this syscall will have *type* set to either **ZX_PKT_TYPE_SIGNAL_ONE**
-or **ZX_PKT_TYPE_SIGNAL_REP**, and the union is of type `zx_packet_signal_t`:
-
-```
-typedef struct zx_packet_signal {
-    zx_signals_t trigger;
-    zx_signals_t observed;
-    uint64_t count;
-} zx_packet_signal_t;
-```
-
-*trigger* is the signals used in the call to `zx_object_wait_async()`, *observed* is the
-signals actually observed, and *count* is a per object defined count of pending operations. Use
-the `zx_port_packet_t`'s *key* member to track what object this packet corresponds to and
-therefore match *count* with the operation.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_WAIT**.
-
-*port* must be of type **ZX_OBJ_TYPE_PORT** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_object_wait_async()` returns **ZX_OK** if the subscription succeeded.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *options* is not **ZX_WAIT_ASYNC_ONCE** or **ZX_WAIT_ASYNC_REPEATING**.
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle or *port* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *port* is not a Port handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_WAIT** or *port*
-does not have **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_NOT_SUPPORTED**  *handle* is a handle that cannot be waited on.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## NOTES
-
-See [signals](../signals.md) for more information about signals and their terminology.
-
-## SEE ALSO
-
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
- - [`zx_port_cancel()`]
- - [`zx_port_queue()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
-[`zx_port_cancel()`]: port_cancel.md
-[`zx_port_queue()`]: port_queue.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/object_wait_many.md b/docs/syscalls/object_wait_many.md
deleted file mode 100644
index ac6bf0f..0000000
--- a/docs/syscalls/object_wait_many.md
+++ /dev/null
@@ -1,115 +0,0 @@
-# zx_object_wait_many
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_wait_many - wait for signals on multiple objects
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_wait_many(zx_wait_item_t* items,
-                                size_t count,
-                                zx_time_t deadline);
-```
-
-## DESCRIPTION
-
-`zx_object_wait_many()` is a blocking syscall which causes the caller to
-wait until either the *deadline* passes or at least one of the specified
-signals is asserted by the object to which the associated handle refers.
-If an object is already asserting at least one of the specified signals,
-the wait ends immediately.
-
-```
-typedef struct {
-    zx_handle_t handle;
-    zx_signals_t waitfor;
-    zx_signals_t pending;
-} zx_wait_item_t;
-```
-
-The caller must provide *count* `zx_wait_item_t`s in the *items* array,
-containing the handle and signals bitmask to wait for for each item.
-
-The *deadline* parameter specifies a deadline with respect to
-**ZX_CLOCK_MONOTONIC** and will be automatically adjusted according to the job's
-[timer slack] policy.  **ZX_TIME_INFINITE** is a special value meaning wait
-forever.
-
-Upon return, the *pending* field of *items* is filled with bitmaps indicating
-which signals are pending for each item.
-
-The *pending* signals in *items* may not reflect the actual state of the object's
-signals if the state of the object was modified by another thread or
-process.  (For example, a Channel ceases asserting **ZX_CHANNEL_READABLE**
-once the last message in its queue is read).
-
-The maximum number of items that may be waited upon is **ZX_WAIT_MANY_MAX_ITEMS**,
-which is 8.  To wait on more things at once use [Ports](../objects/port.md).
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-Every entry of *items* must have a *handle* field with **ZX_RIGHT_WAIT**.
-
-## RETURN VALUE
-
-`zx_object_wait_many()` returns **ZX_OK** if any of *waitfor* signals were
-observed on their respective object before *deadline* passed.
-
-In the event of **ZX_ERR_TIMED_OUT**, *items* may reflect state changes
-that occurred after the deadline passed, but before the syscall returned.
-
-In the event of **ZX_ERR_CANCELED**, one or more of the items being waited
-upon have had their handles closed, and the *pending* field for those items
-will have the **ZX_SIGNAL_HANDLE_CLOSED** bit set.
-
-For any other return value, the *pending* fields of *items* are undefined.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *items* isn't a valid pointer.
-
-**ZX_ERR_OUT_OF_RANGE**  *count* is greater than **ZX_WAIT_MANY_MAX_ITEMS**.
-
-**ZX_ERR_BAD_HANDLE**  one of *items* contains an invalid handle.
-
-**ZX_ERR_ACCESS_DENIED**  One or more of the provided *handles* does not
-have **ZX_RIGHT_WAIT** and may not be waited upon.
-
-**ZX_ERR_CANCELED**  One or more of the provided *handles* was invalidated
-(e.g., closed) during the wait.
-
-**ZX_ERR_TIMED_OUT**  The specified deadline passed before any of the specified signals are
-observed on any of the specified handles.
-
-**ZX_ERR_NOT_SUPPORTED**  One of the *items* contains a handle that cannot
-be waited one (for example, a Port handle).
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## BUGS
-
-*pending* more properly should be called *observed*.
-
-## SEE ALSO
-
- - [timer slack]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_one()`]
-
-[timer slack]: ../timer_slack.md
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_one()`]: object_wait_one.md
diff --git a/docs/syscalls/object_wait_one.md b/docs/syscalls/object_wait_one.md
deleted file mode 100644
index b5f931d..0000000
--- a/docs/syscalls/object_wait_one.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# zx_object_wait_one
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-object_wait_one - wait for signals on an object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_object_wait_one(zx_handle_t handle,
-                               zx_signals_t signals,
-                               zx_time_t deadline,
-                               zx_signals_t* observed);
-```
-
-## DESCRIPTION
-
-`zx_object_wait_one()` is a blocking syscall which causes the caller to
-wait until either the *deadline* passes or the object to which *handle* refers
-asserts at least one of the specified *signals*. If the object is already
-asserting at least one of the specified *signals*, the wait ends immediately.
-
-Upon return, if non-NULL, *observed* is a bitmap of *all* of the
-signals which were observed asserted on that object while waiting.
-
-The *observed* signals may not reflect the actual state of the object's
-signals if the state of the object was modified by another thread or
-process.  (For example, a Channel ceases asserting **ZX_CHANNEL_READABLE**
-once the last message in its queue is read).
-
-The *deadline* parameter specifies a deadline with respect to
-**ZX_CLOCK_MONOTONIC** and will be automatically adjusted according to the job's
-[timer slack] policy.  **ZX_TIME_INFINITE** is a special value meaning wait
-forever.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_WAIT**.
-
-## RETURN VALUE
-
-`zx_object_wait_one()` returns **ZX_OK** if any of *signals* were observed
-on the object before *deadline* passes.
-
-In the event of **ZX_ERR_TIMED_OUT**, *observed* may reflect state changes
-that occurred after the deadline passed, but before the syscall returned.
-
-In the event of **ZX_ERR_CANCELED**, *handle* has been closed,
-and *observed* will have the **ZX_SIGNAL_HANDLE_CLOSED** bit set.
-
-For any other return value, *observed* is undefined.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *observed* is an invalid pointer.
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_WAIT** and may
-not be waited upon.
-
-**ZX_ERR_CANCELED**  *handle* was invalidated (e.g., closed) during the wait.
-
-**ZX_ERR_TIMED_OUT**  The specified deadline passed before any of the specified
-*signals* are observed on *handle*.
-
-**ZX_ERR_NOT_SUPPORTED**  *handle* is a handle that cannot be waited on
-(for example, a Port handle).
-
-## SEE ALSO
-
- - [timer slack]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
-
-[timer slack]: ../timer_slack.md
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
diff --git a/docs/syscalls/pager_create.md b/docs/syscalls/pager_create.md
deleted file mode 100644
index ce8e997..0000000
--- a/docs/syscalls/pager_create.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_pager_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pager_create - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pager_create(uint32_t options, zx_handle_t* out_pager);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pager_create_vmo.md b/docs/syscalls/pager_create_vmo.md
deleted file mode 100644
index 5de9ab3..0000000
--- a/docs/syscalls/pager_create_vmo.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# zx_pager_create_vmo
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pager_create_vmo - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pager_create_vmo(zx_handle_t pager,
-                                zx_handle_t port,
-                                uint64_t key,
-                                uint64_t size,
-                                uint32_t options,
-                                zx_handle_t* out_pager_vmo);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pc_firmware_tables.md b/docs/syscalls/pc_firmware_tables.md
deleted file mode 100644
index c94209c..0000000
--- a/docs/syscalls/pc_firmware_tables.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_pc_firmware_tables
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pc_firmware_tables - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pc_firmware_tables(zx_handle_t handle,
-                                  zx_paddr_t* acpi_rsdp,
-                                  zx_paddr_t* smbios);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_add_subtract_io_range.md b/docs/syscalls/pci_add_subtract_io_range.md
deleted file mode 100644
index 661a02f..0000000
--- a/docs/syscalls/pci_add_subtract_io_range.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# zx_pci_add_subtract_io_range
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_add_subtract_io_range - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_add_subtract_io_range(
-    zx_handle_t handle, bool mmio, uint64_t base, uint64_t len, bool add);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_cfg_pio_rw.md b/docs/syscalls/pci_cfg_pio_rw.md
deleted file mode 100644
index 666db9b..0000000
--- a/docs/syscalls/pci_cfg_pio_rw.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# zx_pci_cfg_pio_rw
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_cfg_pio_rw - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_cfg_pio_rw(zx_handle_t handle,
-                              uint8_t bus,
-                              uint8_t dev,
-                              uint8_t func,
-                              uint8_t offset,
-                              uint32_t* val,
-                              size_t width,
-                              bool write);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_config_read.md b/docs/syscalls/pci_config_read.md
deleted file mode 100644
index 35671c7..0000000
--- a/docs/syscalls/pci_config_read.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_pci_config_read
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_config_read - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_config_read(zx_handle_t handle,
-                               uint16_t offset,
-                               size_t width,
-                               uint32_t* out_val);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PCI_DEVICE** and have **ZX_RIGHT_READ** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_config_write.md b/docs/syscalls/pci_config_write.md
deleted file mode 100644
index d190b2e..0000000
--- a/docs/syscalls/pci_config_write.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_pci_config_write
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_config_write - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_config_write(zx_handle_t handle,
-                                uint16_t offset,
-                                size_t width,
-                                uint32_t val);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PCI_DEVICE** and have **ZX_RIGHT_READ** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_enable_bus_master.md b/docs/syscalls/pci_enable_bus_master.md
deleted file mode 100644
index 659e3b2..0000000
--- a/docs/syscalls/pci_enable_bus_master.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_pci_enable_bus_master
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_enable_bus_master - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_enable_bus_master(zx_handle_t handle, bool enable);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PCI_DEVICE** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_get_bar.md b/docs/syscalls/pci_get_bar.md
deleted file mode 100644
index cbcfec4..0000000
--- a/docs/syscalls/pci_get_bar.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_pci_get_bar
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_get_bar - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_get_bar(zx_handle_t handle,
-                           uint32_t bar_num,
-                           zx_pci_bar_t* out_bar,
-                           zx_handle_t* out_handle);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PCI_DEVICE** and have **ZX_RIGHT_READ** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_get_nth_device.md b/docs/syscalls/pci_get_nth_device.md
deleted file mode 100644
index d9ad821..0000000
--- a/docs/syscalls/pci_get_nth_device.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_pci_get_nth_device
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_get_nth_device - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_get_nth_device(zx_handle_t handle,
-                                  uint32_t index,
-                                  zx_pcie_device_info_t* out_info,
-                                  zx_handle_t* out_handle);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_init.md b/docs/syscalls/pci_init.md
deleted file mode 100644
index 31e7232..0000000
--- a/docs/syscalls/pci_init.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_pci_init
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_init - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_init(zx_handle_t handle,
-                        const zx_pci_init_arg_t* init_buf,
-                        uint32_t len);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_map_interrupt.md b/docs/syscalls/pci_map_interrupt.md
deleted file mode 100644
index 4e268f5..0000000
--- a/docs/syscalls/pci_map_interrupt.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_pci_map_interrupt
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_map_interrupt - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_map_interrupt(zx_handle_t handle,
-                                 int32_t which_irq,
-                                 zx_handle_t* out_handle);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PCI_DEVICE** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_query_irq_mode.md b/docs/syscalls/pci_query_irq_mode.md
deleted file mode 100644
index f8f5bd5..0000000
--- a/docs/syscalls/pci_query_irq_mode.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_pci_query_irq_mode
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_query_irq_mode - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_query_irq_mode(zx_handle_t handle,
-                                  uint32_t mode,
-                                  uint32_t* out_max_irqs);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PCI_DEVICE** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_reset_device.md b/docs/syscalls/pci_reset_device.md
deleted file mode 100644
index a07b06e..0000000
--- a/docs/syscalls/pci_reset_device.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_pci_reset_device
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_reset_device - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_reset_device(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PCI_DEVICE** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pci_set_irq_mode.md b/docs/syscalls/pci_set_irq_mode.md
deleted file mode 100644
index 0af19f3..0000000
--- a/docs/syscalls/pci_set_irq_mode.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_pci_set_irq_mode
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pci_set_irq_mode - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pci_set_irq_mode(zx_handle_t handle,
-                                uint32_t mode,
-                                uint32_t requested_irq_count);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PCI_DEVICE** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/pmt_unpin.md b/docs/syscalls/pmt_unpin.md
deleted file mode 100644
index be0ab60..0000000
--- a/docs/syscalls/pmt_unpin.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# zx_pmt_unpin
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-pmt_unpin - unpin pages and revoke device access to them
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_pmt_unpin(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-`zx_pmt_unpin()` unpins pages that were previously pinned by [`zx_bti_pin()`],
-and revokes the access that was granted by the pin call.
-
-Always consumes *handle*. It is invalid to use *handle* afterwards, including
-to call [`zx_handle_close()`] on it.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-On success, `zx_pmt_unpin()` returns **ZX_OK**.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a PMT handle.
-
-## SEE ALSO
-
- - [`zx_bti_create()`]
- - [`zx_bti_pin()`]
- - [`zx_bti_release_quarantine()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_bti_create()`]: bti_create.md
-[`zx_bti_pin()`]: bti_pin.md
-[`zx_bti_release_quarantine()`]: bti_release_quarantine.md
-[`zx_handle_close()`]: handle_close.md
diff --git a/docs/syscalls/port_cancel.md b/docs/syscalls/port_cancel.md
deleted file mode 100644
index 13b920a..0000000
--- a/docs/syscalls/port_cancel.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# zx_port_cancel
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-port_cancel - cancels async port notifications on an object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_port_cancel(zx_handle_t handle,
-                           zx_handle_t source,
-                           uint64_t key);
-```
-
-## DESCRIPTION
-
-`zx_port_cancel()` is a non-blocking syscall which cancels
-pending [`zx_object_wait_async()`] calls done with *source* and *key*.
-
-When this call succeeds no new packets from the object pointed by
-*source* with *key* will be delivered to *handle*, and pending queued
-packets that match *source* and *key* are removed from the port.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PORT** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_port_cancel()` returns **ZX_OK** if cancellation succeeded and
-either queued packets were removed or pending [`zx_object_wait_async()`] were
-canceled.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *source* or *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a port handle.
-
-**ZX_ERR_ACCESS_DENIED**  *source* or *handle* does not have **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_NOT_SUPPORTED**  *source* is a handle that cannot be waited on.
-
-**ZX_ERR_NOT_FOUND** if either no pending packets or pending
-[`zx_object_wait_async()`] calls with *source* and *key* were found.
-
-## SEE ALSO
-
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/port_create.md b/docs/syscalls/port_create.md
deleted file mode 100644
index 0522f7d..0000000
--- a/docs/syscalls/port_create.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# zx_port_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-port_create - create an IO port
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_port_create(uint32_t options, zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_port_create()` creates a port: a waitable object that can be used to read
-packets queued by kernel or by user-mode.
-
-If you need this port to be bound to an interrupt, pass **ZX_PORT_BIND_TO_INTERRUPT** to *options*,
-otherwise it should be **0**.
-
-In the case where a port is bound to an interrupt, the interrupt packets are delivered via a
-dedicated queue on ports and are higher priority than other non-interrupt packets.
-
-The returned handle will have:
-  * `ZX_RIGHT_TRANSFER`: allowing them to be sent to another process via channel write.
-  * `ZX_RIGHT_WRITE`: allowing packets to be *queued*.
-  * `ZX_RIGHT_READ`: allowing packets to be *read*.
-  * `ZX_RIGHT_DUPLICATE`: allowing them to be *duplicated*.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_port_create()` returns **ZX_OK** and a valid IO port handle via *out* on
-success. In the event of failure, an error value is returned.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS** *options* has an invalid value, or *out* is an
-invalid pointer or NULL.
-
-**ZX_ERR_NO_MEMORY** Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future builds this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_handle_replace()`]
- - [`zx_object_wait_async()`]
- - [`zx_port_queue()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_handle_replace()`]: handle_replace.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_port_queue()`]: port_queue.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/port_queue.md b/docs/syscalls/port_queue.md
deleted file mode 100644
index e4b4b37..0000000
--- a/docs/syscalls/port_queue.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# zx_port_queue
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-port_queue - queue a packet to an port
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-#include <zircon/syscalls/port.h>
-
-zx_status_t zx_port_queue(zx_handle_t handle, const zx_port_packet_t* packet);
-```
-
-## DESCRIPTION
-
-`zx_port_queue()` queues a *packet* to the port specified
-by *handle*.
-
-```
-typedef struct zx_port_packet {
-    uint64_t key;
-    uint32_t type;
-    zx_status_t status;
-    union {
-        zx_packet_user_t user;
-        zx_packet_signal_t signal;
-    };
-} zx_port_packet_t;
-
-```
-
-In *packet* *type* should be **ZX_PKT_TYPE_USER** and only the **user**
-union element is considered valid:
-
-```
-typedef union zx_packet_user {
-    uint64_t u64[4];
-    uint32_t u32[8];
-    uint16_t u16[16];
-    uint8_t   c8[32];
-} zx_packet_user_t;
-
-```
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PORT** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_port_queue()` returns **ZX_OK** on successful queue of a packet.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* isn't a valid handle
-
-**ZX_ERR_INVALID_ARGS** *packet* is an invalid pointer.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a port handle.
-
-**ZX_ERR_ACCESS_DENIED** *handle* does not have **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_SHOULD_WAIT** the port has too many pending packets. Once a thread
-has drained some packets a new `zx_port_queue()` call will likely succeed.
-
-## NOTES
-
-The queue is drained by calling [`zx_port_wait()`].
-
-
-## SEE ALSO
-
- - [`zx_port_create()`]
- - [`zx_port_wait()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_port_create()`]: port_create.md
-[`zx_port_wait()`]: port_wait.md
diff --git a/docs/syscalls/port_wait.md b/docs/syscalls/port_wait.md
deleted file mode 100644
index 951cd5b..0000000
--- a/docs/syscalls/port_wait.md
+++ /dev/null
@@ -1,133 +0,0 @@
-# zx_port_wait
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-port_wait - wait for a packet arrival in a port
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-#include <zircon/syscalls/port.h>
-
-zx_status_t zx_port_wait(zx_handle_t handle,
-                         zx_time_t deadline,
-                         zx_port_packet_t* packet);
-```
-
-## DESCRIPTION
-
-`zx_port_wait()` is a blocking syscall which causes the caller to wait until at least
-one packet is available.
-
-Upon return, if successful *packet* will contain the earliest (in FIFO order)
-available packet data.
-
-The *deadline* indicates when to stop waiting for a packet (with respect to
-**ZX_CLOCK_MONOTONIC**) and will be automatically adjusted according to the job's
-[timer slack] policy. If no packet has arrived by the deadline,
-**ZX_ERR_TIMED_OUT** is returned.  The value **ZX_TIME_INFINITE** will result in
-waiting forever.  A value in the past will result in an immediate timeout,
-unless a packet is already available for reading.
-
-Unlike [`zx_object_wait_one()`] and [`zx_object_wait_many()`] only one
-waiting thread is released (per available packet) which makes ports
-amenable to be serviced by thread pools.
-
-There are two classes of packets: packets queued by userspace with [`zx_port_queue()`]
-and packets queued by the kernel when objects a port is registered with change state. In both
-cases the packet is always of type `zx_port_packet_t`:
-
-```
-struct zx_port_packet_t {
-    uint64_t key;
-    uint32_t type;
-    zx_status_t status;
-    union {
-        zx_packet_user_t user;
-        zx_packet_signal_t signal;
-        zx_packet_exception_t exception;
-        zx_packet_guest_bell_t guest_bell;
-        zx_packet_guest_mem_t guest_mem;
-        zx_packet_guest_io_t guest_io;
-        zx_packet_guest_vcpu_t guest_vcpu;
-        zx_packet_interrupt_t interrupt;
-    };
-};
-```
-
-In the case of packets generated via [`zx_port_queue()`], *type* will be set to
-**ZX_PKT_TYPE_USER**, and the caller of [`zx_port_queue()`] controls all other values in the
-`zx_port_packet_t` structure. Access to the packet data is provided by the *user* member, with
-type `zx_packet_user_t`:
-
-```
-typedef union zx_packet_user {
-    uint64_t u64[4];
-    uint32_t u32[8];
-    uint16_t u16[16];
-    uint8_t   c8[32];
-} zx_packet_user_t;
-```
-
-For packets generated by the kernel, type can be one of the following values:
-
-**ZX_PKT_TYPE_SIGNAL_ONE** or **ZX_PKT_TYPE_SIGNAL_REP** - generated by objects registered
-via [`zx_object_wait_async()`].
-
-**ZX_PKT_TYPE_EXCEPTION(n)** - generated by objects registered via
-[`zx_task_bind_exception_port()`].
-
-**ZX_PKT_TYPE_GUEST_BELL**, **ZX_PKT_TYPE_GUEST_MEM**, **ZX_PKT_TYPE_GUEST_IO**,
-or **ZX_PKT_TYPE_GUEST_VCPU** - generated by objects registered via [`zx_guest_set_trap()`].
-
-**ZX_PKT_TYPE_INTERRUPT** - generated by objects registered via [`zx_interrupt_bind()`].
-
-All kernel queued packets will have *status* set to **ZX_OK** and *key* set to the
-value provided to the registration syscall. For details on how to interpret the union, see
-the corresponding registration syscall.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PORT** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_port_wait()` returns **ZX_OK** on successful packet dequeuing.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* is not a valid handle.
-
-**ZX_ERR_INVALID_ARGS** *packet* isn't a valid pointer
-
-**ZX_ERR_ACCESS_DENIED** *handle* does not have **ZX_RIGHT_READ** and may
-not be waited upon.
-
-**ZX_ERR_TIMED_OUT** *deadline* passed and no packet was available.
-
-## SEE ALSO
-
- - [timer slack]
- - [`zx_object_wait_async()`]
- - [`zx_port_create()`]
- - [`zx_port_queue()`]
-
-[timer slack]: ../timer_slack.md
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_set_trap()`]: guest_set_trap.md
-[`zx_interrupt_bind()`]: interrupt_bind.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
-[`zx_port_create()`]: port_create.md
-[`zx_port_queue()`]: port_queue.md
-[`zx_task_bind_exception_port()`]: task_bind_exception_port.md
diff --git a/docs/syscalls/process_create.md b/docs/syscalls/process_create.md
deleted file mode 100644
index abcc6bb..0000000
--- a/docs/syscalls/process_create.md
+++ /dev/null
@@ -1,98 +0,0 @@
-# zx_process_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-process_create - create a new process
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_process_create(zx_handle_t job,
-                              const char* name,
-                              size_t name_size,
-                              uint32_t options,
-                              zx_handle_t* proc_handle,
-                              zx_handle_t* vmar_handle);
-```
-
-## DESCRIPTION
-
-`zx_process_create()` creates a new process.
-
-Upon success, handles for the new process and the root of its address space
-are returned.  The thread will not start executing until [`zx_process_start()`] is
-called.
-
-*name* is silently truncated to a maximum of `ZX_MAX_NAME_LEN-1` characters.
-
-When the last handle to a process is closed, the process is destroyed.
-
-Process handles may be waited on and will assert the signal
-**ZX_PROCESS_TERMINATED** when the process exits.
-
-*job* is the controlling [job object](../objects/job.md) for the new
-process, which will become a child of that job.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*job* must be of type **ZX_OBJ_TYPE_JOB** and have **ZX_RIGHT_MANAGE_PROCESS**.
-
-## RETURN VALUE
-
-On success, `zx_process_create()` returns **ZX_OK**, a handle to the new process
-(via *proc_handle*), and a handle to the root of its address space (via
-*vmar_handle*).  In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *job* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *job* is not a job handle.
-
-**ZX_ERR_ACCESS_DENIED**  *job* does not have the **ZX_RIGHT_WRITE** right
-(only when not **ZX_HANDLE_INVALID**).
-
-**ZX_ERR_INVALID_ARGS**  *name*, *proc_handle*, or *vmar_handle*  was an invalid pointer,
-or *options* was non-zero.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_BAD_STATE**  The job object is in the dead state.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_job_create()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
- - [`zx_process_start()`]
- - [`zx_task_kill()`]
- - [`zx_thread_create()`]
- - [`zx_thread_exit()`]
- - [`zx_thread_start()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_job_create()`]: job_create.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
-[`zx_process_start()`]: process_start.md
-[`zx_task_kill()`]: task_kill.md
-[`zx_thread_create()`]: thread_create.md
-[`zx_thread_exit()`]: thread_exit.md
-[`zx_thread_start()`]: thread_start.md
diff --git a/docs/syscalls/process_exit.md b/docs/syscalls/process_exit.md
deleted file mode 100644
index 0bd55e2..0000000
--- a/docs/syscalls/process_exit.md
+++ /dev/null
@@ -1,47 +0,0 @@
-# zx_process_exit
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-process_exit - Exits the currently running process.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-[[noreturn]] void zx_process_exit(int64_t retcode);
-```
-
-## DESCRIPTION
-
-The `zx_process_exit()` call ends the calling process with the given
-return code. The return code of a process can be queried via the
-**ZX_INFO_PROCESS** request to [`zx_object_get_info()`].
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_process_exit()` does not return.
-
-## ERRORS
-
-`zx_process_exit()` cannot fail.
-
-## SEE ALSO
-
- - [`zx_object_get_info()`]
- - [`zx_process_create()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_get_info()`]: object_get_info.md
-[`zx_process_create()`]: process_create.md
diff --git a/docs/syscalls/process_read_memory.md b/docs/syscalls/process_read_memory.md
deleted file mode 100644
index cc926bb..0000000
--- a/docs/syscalls/process_read_memory.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# zx_process_read_memory
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-process_read_memory - Read from the given process's address space.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_process_read_memory(zx_handle_t handle,
-                                   zx_vaddr_t vaddr,
-                                   void* buffer,
-                                   size_t buffer_size,
-                                   size_t* actual);
-```
-
-## DESCRIPTION
-
-`zx_process_read_memory()` attempts to read memory of the specified process.
-
-This function will eventually be replaced with something vmo-centric.
-
-*vaddr* the address of the block of memory to read.
-
-*buffer* pointer to a user buffer to read bytes into.
-
-*buffer_size* number of bytes to attempt to read. *buffer* buffer must be large
-enough for at least this many bytes. *buffer_size* must be greater than zero
-and less than or equal to 64MB.
-
-*actual* the actual number of bytes read is stored here. Less bytes than
-requested may be returned if *vaddr*+*buffer_size* extends beyond the memory
-mapped in the process.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_READ** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_process_read_memory()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned, and the number of
-bytes written to *buffer* is undefined.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have the **ZX_RIGHT_READ** right
-or
-**ZX_WRITE_RIGHT** is needed for historical reasons.
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_BAD_STATE**  the process's memory is not accessible (e.g.,
-the process is being terminated),
-or the requested memory is not cacheable.
-
-**ZX_ERR_INVALID_ARGS** *buffer* is an invalid pointer or NULL,
-or *buffer_size* is zero or greater than 64MB.
-
-**ZX_ERR_NO_MEMORY** the process does not have any memory at the
-requested address.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a process handle.
-
-## SEE ALSO
-
-
-[process_write_memory](process_write_memory.md).
diff --git a/docs/syscalls/process_start.md b/docs/syscalls/process_start.md
deleted file mode 100644
index abfbdbb..0000000
--- a/docs/syscalls/process_start.md
+++ /dev/null
@@ -1,91 +0,0 @@
-# zx_process_start
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-process_start - start execution on a process
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_process_start(zx_handle_t handle,
-                             zx_handle_t thread,
-                             zx_vaddr_t entry,
-                             zx_vaddr_t stack,
-                             zx_handle_t arg1,
-                             uintptr_t arg2);
-```
-
-## DESCRIPTION
-
-`zx_process_start()` is similar to [`zx_thread_start()`], but is used for the
-purpose of starting the first thread in a process.
-
-`zx_process_start()` causes a thread to begin execution at the program
-counter specified by *entry* and with the stack pointer set to *stack*.
-The arguments *arg1* and *arg2* are arranged to be in the architecture
-specific registers used for the first two arguments of a function call
-before the thread is started.  All other registers are zero upon start.
-
-The first argument (*arg1*) is a handle, which will be transferred from
-the process of the caller to the process which is being started, and an
-appropriate handle value will be placed in arg1 for the newly started
-thread. If `zx_process_start()` returns an error, *arg1* is closed rather
-than transferred to the process being started.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_WRITE**.
-
-*thread* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_WRITE**.
-
-*arg1* must have **ZX_RIGHT_TRANSFER**.
-
-## RETURN VALUE
-
-`zx_process_start()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *process* or *thread* or *arg1* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *process* is not a process handle or *thread* is
-not a thread handle.
-
-**ZX_ERR_ACCESS_DENIED**  The handle *thread* lacks **ZX_RIGHT_WRITE** or *thread*
-does not belong to *process*, or the handle *process* lacks **ZX_RIGHT_WRITE** or
-*arg1* lacks **ZX_RIGHT_TRANSFER**.
-
-**ZX_ERR_BAD_STATE**  *process* is already running or has exited.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
- - [`zx_process_create()`]
- - [`zx_thread_create()`]
- - [`zx_thread_exit()`]
- - [`zx_thread_start()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
-[`zx_process_create()`]: process_create.md
-[`zx_thread_create()`]: thread_create.md
-[`zx_thread_exit()`]: thread_exit.md
-[`zx_thread_start()`]: thread_start.md
diff --git a/docs/syscalls/process_write_memory.md b/docs/syscalls/process_write_memory.md
deleted file mode 100644
index cc28411..0000000
--- a/docs/syscalls/process_write_memory.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# zx_process_write_memory
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-process_write_memory - Write into the given process's address space.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_process_write_memory(zx_handle_t handle,
-                                    zx_vaddr_t vaddr,
-                                    const void* buffer,
-                                    size_t buffer_size,
-                                    size_t* actual);
-```
-
-## DESCRIPTION
-
-`zx_process_write_memory()` attempts to write memory of the specified process.
-
-This function will eventually be replaced with something vmo-centric.
-
-*vaddr* the address of the block of memory to write.
-
-*buffer* pointer to a user buffer containing the bytes to write.
-
-*buffer_size* number of bytes to attempt to write. *buffer* buffer must be
-large enough for at least this many bytes. *buffer_size* must be greater than
-zero and less than or equal to 64MB.
-
-*actual_size* the actual number of bytes written is stored here. Less bytes
-than requested may be returned if *vaddr*+*buffer_size* extends beyond the
-memory mapped in the process.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_process_write_memory()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned, and the number of
-bytes written to *buffer* is undefined.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have the **ZX_RIGHT_WRITE** right.
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_BAD_STATE**  the process's memory is not accessible (e.g.,
-the process is being terminated),
-or the requested memory is not cacheable.
-
-**ZX_ERR_INVALID_ARGS** *buffer* is an invalid pointer or NULL,
-or *buffer_size* is zero or greater than 64MB.
-
-**ZX_ERR_NO_MEMORY** the process does not have any memory at the
-requested address.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a process handle.
-
-## SEE ALSO
-
-
-[process_read_memory](process_read_memory.md).
diff --git a/docs/syscalls/profile_create.md b/docs/syscalls/profile_create.md
deleted file mode 100644
index 2ba5512..0000000
--- a/docs/syscalls/profile_create.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_profile_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-profile_create - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_profile_create(zx_handle_t root_job,
-                              const zx_profile_info_t* profile,
-                              zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*root_job* must be of type **ZX_OBJ_TYPE_JOB** and have **ZX_RIGHT_MANAGE_PROCESS**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/resource_create.md b/docs/syscalls/resource_create.md
deleted file mode 100644
index 85e140d..0000000
--- a/docs/syscalls/resource_create.md
+++ /dev/null
@@ -1,103 +0,0 @@
-# zx_resource_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-resource_create - create a resource object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_resource_create(zx_handle_t parent_rsrc,
-                               uint32_t options,
-                               uint64_t base,
-                               size_t size,
-                               const char* name,
-                               size_t name_size,
-                               zx_handle_t* resource_out);
-```
-
-## DESCRIPTION
-
-`zx_resource_create()` creates an resource object for use with other DDK
-syscalls. Resources are typically handed out to bus drivers and rarely need to
-be interacted with directly by drivers using driver protocols. Resource objects
-grant access to an address space range starting at *base* up to but not
-including *base* + *size*. Two special values for *kind* exist:
-**ZX_RSRC_KIND_ROOT** and **ZX_RSRC_KIND_HYPERVISOR**. These resources have no
-range associated with them and are used as a privilege check.
-
-*parent_rsrc* must be a handle to a resource of *kind* **ZX_RSRC_KIND_ROOT**.
-
-*options* must specify which kind of resource to create and may contain optional
-flags. Valid kinds of resources are **ZX_RSRC_KIND_MMIO**, **ZX_RSRC_KIND_IRQ**,
-**ZX_RSRC_KIND_IOPORT** (x86 only), **ZX_RSRC_KIND_ROOT**,
-**ZX_RSRC_KIND_HYPERVISOR**, **ZX_RSRC_KIND_VMEX**, and **ZX_RSRC_KIND_SMC**
-(ARM only).
-**ZX_RSRC_KIND_ROOT**, **ZX_RSRC_KIND_HYPERVISOR**, and **ZX_RSRC_KIND_VMEX**
-must be paired with zero values for *base* and *size*, as they do not use
-an address space range.
-At this time the only optional flag is **ZX_RSRC_FLAG_EXCLUSIVE**. If
-**ZX_RSRC_FLAG_EXCLUSIVE** is provided then the syscall will attempt to
-exclusively reserve the requested address space region, preventing other
-resources creation from overlapping with it as long as it exists.
-
-*name* and *name_size* are optional and truncated to **ZX_MAX_NAME_LENGTH** - 1.
-This name is provided for debugging / tool use only and is not used by the
-kernel.
-
-On success, a valid resource handle is returned in *resource_out*.
-
-## RETURN VALUE
-
-`zx_resource_create()` returns **ZX_OK** on success. In the event of failure, a
-negative error value is returned.
-
-The returned handle will have **ZX_RIGHT_TRANSFER** (allowing it to be sent to
-another process via channel write), **ZX_RIGHT_DUPLICATE** (allowing the handle
-to be duplicated), **ZX_RIGHT_INSPECT** (to allow inspection of the object with
-[object_get_info](object_get_info.md) and **ZX_RIGHT_WRITE** which is checked by
-`zx_resource_create()` itself.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*parent_rsrc* must be of type **ZX_OBJ_TYPE_RESOURCE** and have **ZX_RIGHT_WRITE**.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** the *src_obj* handle is invalid.
-
-**ZX_ERR_WRONG_TYPE** the *src_obj* handle is not a resource handle.
-
-**ZX_ERR_ACCESS_DENIED** The *src_obj* handle is not a resource of *kind*
-**ZX_RSRC_KIND_ROOT**.
-
-**ZX_ERR_INVALID_ARGS** *options* contains an invalid kind or flag combination,
-*name* is an invalid pointer, or the kind specified is one of
-**ZX_RSRC_KIND_ROOT** or **ZX_RSRC_KIND_HYPERVISOR** but *base* and *size* are
-not 0.
-
-**ZX_ERR_NO_MEMORY** Failure due to lack of memory. There is no good way for
-userspace to handle this (unlikely) error. In a future build this error will no
-longer occur.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_interrupt_create()`]
- - [`zx_ioports_request()`]
- - [`zx_vmo_create_physical()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_interrupt_create()`]: interrupt_create.md
-[`zx_ioports_request()`]: ioports_request.md
-[`zx_vmo_create_physical()`]: vmo_create_physical.md
diff --git a/docs/syscalls/smc_call.md b/docs/syscalls/smc_call.md
deleted file mode 100644
index d4a8e2d..0000000
--- a/docs/syscalls/smc_call.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# zx_smc_call
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-smc_call - Make Secure Monitor Call (SMC) from user space
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-#include <zircon/syscalls/smc.h>
-
-zx_status_t zx_smc_call(zx_handle_t handle,
-                        const zx_smc_parameters_t* parameters,
-                        zx_smc_result_t* out_smc_result);
-```
-
-## DESCRIPTION
-
-`zx_smc_call()` makes a Secure Monitor Call (SMC) from user space. It supports the ARM SMC Calling
-Convention using the `zx_smc_parameters_t` input parameter and `zx_smc_result_t` output parameter.
-The input *handle* must be a resource object with sufficient privileges in order to be executed.
-
-The majority of the parameters are opaque from `zx_smc_call()` perspective because they are
-dependent upon the *func_id*. The *func_id* informs the Secure Monitor the service and function
-to be invoked. The *client_id* is an optional field intended for secure software to track and
-index the calling client OS. The *secure_os_id* is an optional field intended for use when there
-are multiple secure operating systems at S-EL1, so that the caller may specify the intended
-secure OS.
-
-More information is available in the [ARM SMC Calling Convention documentation](
-http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0028b/index.html).
-
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_smc_call()` returns **ZX_OK** if *handle* has sufficient privilege. The
-return value of the smc call is returned via **out_smc_result** on success. In the event of
-failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a resource handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have sufficient privileges.
-
-**ZX_ERR_NOT_SUPPORTED**  smc_call is not supported on this system.
-
-**ZX_ERR_INVALID_ARGS**  *parameters* or *out_smc_result* a null pointer
diff --git a/docs/syscalls/socket_accept.md b/docs/syscalls/socket_accept.md
deleted file mode 100644
index a2b3fd1..0000000
--- a/docs/syscalls/socket_accept.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# zx_socket_accept
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-socket_accept - receive another socket object via a socket
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_socket_accept(zx_handle_t handle, zx_handle_t* out_socket);
-```
-
-## DESCRIPTION
-
-`zx_socket_accept()` attempts to receive a new socket via an existing socket
-connection.  The signal **ZX_SOCKET_ACCEPT** is asserted when there is a new
-socket available.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_SOCKET** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_socket_accept()` returns **ZX_OK** on success and the received handle
-is returned via *out_socket*.  In the event of failure, one of the following
-values is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *socket* is invalid.
-
-**ZX_ERR_WRONG_TYPE**  *socket* is not a socket handle.
-
-**ZX_ERR_ACCESS_DENIED**  *socket* lacks **ZX_RIGHT_READ**.
-
-**ZX_ERR_INVALID_ARGS**  *out_socket* is an invalid pointer.
-
-**ZX_ERR_SHOULD_WAIT**  There is no new socket ready to be accepted.
-
-**ZX_ERR_NOT_SUPPORTED**  This socket does not support the transfer of sockets.
-It was not created with the **ZX_SOCKET_HAS_ACCEPT** option.
-
-## LIMITATIONS
-
-The socket accept queue is only one element deep.
-
-## SEE ALSO
-
- - [`zx_socket_create()`]
- - [`zx_socket_read()`]
- - [`zx_socket_share()`]
- - [`zx_socket_shutdown()`]
- - [`zx_socket_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_socket_create()`]: socket_create.md
-[`zx_socket_read()`]: socket_read.md
-[`zx_socket_share()`]: socket_share.md
-[`zx_socket_shutdown()`]: socket_shutdown.md
-[`zx_socket_write()`]: socket_write.md
diff --git a/docs/syscalls/socket_create.md b/docs/syscalls/socket_create.md
deleted file mode 100644
index de5e589..0000000
--- a/docs/syscalls/socket_create.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# zx_socket_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-socket_create - create a socket
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_socket_create(uint32_t options,
-                             zx_handle_t* out0,
-                             zx_handle_t* out1);
-```
-
-## DESCRIPTION
-
-`zx_socket_create()` creates a socket, a connected pair of
-bidirectional stream transports, that can move only data, and that
-have a maximum capacity.
-
-Data written to one handle may be read from the opposite.
-
-The *options* must set either the **ZX_SOCKET_STREAM** or
-**ZX_SOCKET_DATAGRAM** flag.
-
-The **ZX_SOCKET_HAS_CONTROL** flag may be set to enable the
-socket control plane.
-
-The **ZX_SOCKET_HAS_ACCEPT** flag may be set to enable transfer
-of sockets over this socket via [`zx_socket_share()`] and [`zx_socket_accept()`].
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_socket_create()` returns **ZX_OK** on success. In the event of
-failure, one of the following values is returned.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *out0* or *out1* is an invalid pointer or NULL or
-*options* is any value other than **ZX_SOCKET_STREAM** or **ZX_SOCKET_DATAGRAM**.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## LIMITATIONS
-
-The maximum capacity is not currently set-able.
-
-## SEE ALSO
-
- - [`zx_socket_accept()`]
- - [`zx_socket_read()`]
- - [`zx_socket_share()`]
- - [`zx_socket_shutdown()`]
- - [`zx_socket_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_socket_accept()`]: socket_accept.md
-[`zx_socket_read()`]: socket_read.md
-[`zx_socket_share()`]: socket_share.md
-[`zx_socket_shutdown()`]: socket_shutdown.md
-[`zx_socket_write()`]: socket_write.md
diff --git a/docs/syscalls/socket_read.md b/docs/syscalls/socket_read.md
deleted file mode 100644
index fa073b6..0000000
--- a/docs/syscalls/socket_read.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# zx_socket_read
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-socket_read - read data from a socket
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_socket_read(zx_handle_t handle,
-                           uint32_t options,
-                           void* buffer,
-                           size_t buffer_size,
-                           size_t* actual);
-```
-
-## DESCRIPTION
-
-`zx_socket_read()` attempts to read *buffer_size* bytes into *buffer*. If
-successful, the number of bytes actually read are return via
-*actual*.
-
-If a NULL *actual* is passed in, it will be ignored.
-
-If the socket was created with **ZX_SOCKET_DATAGRAM**, this syscall reads
-only the first available datagram in the socket (if one is present).
-If *buffer* is too small for the datagram, then the read will be
-truncated, and any remaining bytes in the datagram will be discarded.
-
-Supported *options* are:
-
-* **ZX_SOCKET_CONTROL** to read from the socket control plane.
-* **ZX_SOCKET_PEEK** to leave the message in the socket.
-
-To determine how many bytes are available to read, use the **rx_buf_available**
-field of the resulting `zx_info_socket_t`, which you can obtain using the
-**ZX_INFO_SOCKET** topic for [`zx_object_get_info()`].
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_SOCKET** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_socket_read()` returns **ZX_OK** on success, and writes into
-*actual* (if non-NULL) the exact number of bytes read.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_BAD_STATE** Either (a) *options* includes **ZX_SOCKET_CONTROL** and the
-socket was not created with **ZX_SOCKET_HAS_CONTROL**, or (b) reading has been
-disabled for this socket endpoint.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a socket handle.
-
-**ZX_ERR_INVALID_ARGS** If any of *buffer* or *actual* are non-NULL
-but invalid pointers, or if *buffer* is NULL, or if *options* is not either zero
-or **ZX_SOCKET_CONTROL**.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_READ**.
-
-**ZX_ERR_SHOULD_WAIT**  The socket contained no data to read.
-
-**ZX_ERR_PEER_CLOSED**  The other side of the socket is closed and no data is
-readable.
-
-## SEE ALSO
-
- - [`zx_socket_accept()`]
- - [`zx_socket_create()`]
- - [`zx_socket_share()`]
- - [`zx_socket_shutdown()`]
- - [`zx_socket_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_object_get_info()`]: object_get_info.md
-[`zx_socket_accept()`]: socket_accept.md
-[`zx_socket_create()`]: socket_create.md
-[`zx_socket_share()`]: socket_share.md
-[`zx_socket_shutdown()`]: socket_shutdown.md
-[`zx_socket_write()`]: socket_write.md
diff --git a/docs/syscalls/socket_share.md b/docs/syscalls/socket_share.md
deleted file mode 100644
index 9b2bdac..0000000
--- a/docs/syscalls/socket_share.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# zx_socket_share
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-socket_share - send another socket object via a socket
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_socket_share(zx_handle_t handle, zx_handle_t socket_to_share);
-```
-
-## DESCRIPTION
-
-`zx_socket_share()` attempts to send a new socket via an existing socket
-connection.  The signal **ZX_SOCKET_SHARE** is asserted when it is possible
-to send a socket.
-
-On success, the *socket_to_share* is placed into the *handle*'s share
-queue, and is no longer accessible to the caller's process. On any
-failure, *socket_to_share* is discarded rather than transferred.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_SOCKET** and have **ZX_RIGHT_WRITE**.
-
-*socket_to_share* must be of type **ZX_OBJ_TYPE_SOCKET** and have **ZX_RIGHT_TRANSFER**.
-
-## RETURN VALUE
-
-`zx_socket_share()` returns **ZX_OK** on success.  In the event of failure,
-one of the following values is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  The handle *handle* or *socket_to_share* is invalid.
-
-**ZX_ERR_WRONG_TYPE**  The handle *handle* or *socket_to_share* is not a socket handle.
-
-**ZX_ERR_ACCESS_DENIED**  The handle *handle* lacks **ZX_RIGHT_WRITE** or
-the handle *socket_to_share* lacks **ZX_RIGHT_TRANSFER**.
-
-**ZX_ERR_BAD_STATE**  The *socket_to_share* was a handle to the same socket
-as *handle* or to the other endpoint of *handle* or the *socket_to_share* itself
-is capable of sharing.
-
-**ZX_ERR_SHOULD_WAIT**  There is already a socket in the share queue.
-
-**ZX_ERR_NOT_SUPPORTED**  This socket does not support the transfer of sockets.
-It was not created with the **ZX_SOCKET_HAS_ACCEPT** option.
-
-**ZX_ERR_PEER_CLOSED** The socket endpoint's peer is closed.
-
-## LIMITATIONS
-
-The socket share queue is only one element deep.
-
-## SEE ALSO
-
- - [`zx_socket_accept()`]
- - [`zx_socket_create()`]
- - [`zx_socket_read()`]
- - [`zx_socket_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_socket_accept()`]: socket_accept.md
-[`zx_socket_create()`]: socket_create.md
-[`zx_socket_read()`]: socket_read.md
-[`zx_socket_write()`]: socket_write.md
diff --git a/docs/syscalls/socket_shutdown.md b/docs/syscalls/socket_shutdown.md
deleted file mode 100644
index 1622b08..0000000
--- a/docs/syscalls/socket_shutdown.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# zx_socket_shutdown
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-socket_shutdown - prevent reading or writing
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_socket_shutdown(zx_handle_t handle, uint32_t options);
-```
-
-## DESCRIPTION
-
-`zx_socket_shutdown()` attempts to prevent future reads or writes on a socket,
-where options can be a combination of **ZX_SOCKET_SHUTDOWN_READ** and
-**ZX_SOCKET_SHUTDOWN_WRITE**:
-
- * If **ZX_SOCKET_SHUTDOWN_READ** is passed to *options*, then reading is
-   disabled for the socket endpoint at *handle*. All data buffered in the socket
-   at the time of the call can be read, but further reads from this endpoint or
-   writes to the other endpoint of the socket will fail with
-   **ZX_ERR_BAD_STATE**.
-
- * If **ZX_SOCKET_SHUTDOWN_WRITE** is passed to *options*, then writing is
-   disabled for the socket endpoint at *handle*. Further writes to this endpoint
-   or reads from the other endpoint of the socket will fail with
-   **ZX_ERR_BAD_STATE**.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_SOCKET** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_socket_shutdown()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a socket handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_INVALID_ARGS** *options* contains an undefined flag.
-
-## SEE ALSO
-
- - [`zx_socket_accept()`]
- - [`zx_socket_create()`]
- - [`zx_socket_read()`]
- - [`zx_socket_share()`]
- - [`zx_socket_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_socket_accept()`]: socket_accept.md
-[`zx_socket_create()`]: socket_create.md
-[`zx_socket_read()`]: socket_read.md
-[`zx_socket_share()`]: socket_share.md
-[`zx_socket_write()`]: socket_write.md
diff --git a/docs/syscalls/socket_write.md b/docs/syscalls/socket_write.md
deleted file mode 100644
index bc995c6..0000000
--- a/docs/syscalls/socket_write.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# zx_socket_write
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-socket_write - write data to a socket
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_socket_write(zx_handle_t handle,
-                            uint32_t options,
-                            const void* buffer,
-                            size_t buffer_size,
-                            size_t* actual);
-```
-
-## DESCRIPTION
-
-`zx_socket_write()` attempts to write *buffer_size* bytes to the socket specified
-by *handle*. The pointer to *bytes* may be NULL if *buffer_size* is zero.
-
-If **ZX_SOCKET_CONTROL** is passed to *options*, then `zx_socket_write()`
-attempts to write into the socket control plane. A write to the control plane is
-never short. If the socket control plane has insufficient space for *buffer*, it
-writes nothing and returns **ZX_ERR_OUT_OF_RANGE**.
-
-If a NULL *actual* is passed in, it will be ignored.
-
-A **ZX_SOCKET_STREAM** socket write can be short if the socket does not have
-enough space for all of *buffer*. If a non-zero amount of data was written to
-the socket, the amount written is returned via *actual* and the call succeeds.
-Otherwise, if the socket was already full, the call returns
-**ZX_ERR_SHOULD_WAIT** and the client should wait (e.g., with
-[object_wait_one](object_wait_one.md) or
-[object_wait_async](object_wait_async.md)). For datagram sockets, attempting to
-write a packet larger than the socket's capacity will fail with
-**ZX_ERR_OUT_OF_RANGE**.
-
-A **ZX_SOCKET_DATAGRAM** socket write is never short. If the socket has
-insufficient space for *buffer*, it writes nothing and returns
-**ZX_ERR_SHOULD_WAIT**. If the write succeeds, *buffer_size* is returned via
-*actual*.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_SOCKET** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_socket_write()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_BAD_STATE**  *options* includes **ZX_SOCKET_CONTROL** and the
-socket was not created with **ZX_SOCKET_HAS_CONTROL**.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a socket handle.
-
-**ZX_ERR_INVALID_ARGS**  *buffer* is an invalid pointer.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_SHOULD_WAIT**  The buffer underlying the socket is full.
-
-**ZX_ERR_OUT_OF_RANGE**  The socket was created with **ZX_SOCKET_DATAGRAM** and
-*buffer* is larger than the remaining space in the socket.
-
-**ZX_ERR_BAD_STATE**  Writing has been disabled for this socket endpoint.
-
-**ZX_ERR_PEER_CLOSED**  The other side of the socket is closed.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_socket_accept()`]
- - [`zx_socket_create()`]
- - [`zx_socket_read()`]
- - [`zx_socket_share()`]
- - [`zx_socket_shutdown()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_socket_accept()`]: socket_accept.md
-[`zx_socket_create()`]: socket_create.md
-[`zx_socket_read()`]: socket_read.md
-[`zx_socket_share()`]: socket_share.md
-[`zx_socket_shutdown()`]: socket_shutdown.md
diff --git a/docs/syscalls/syscall_test_0.md b/docs/syscalls/syscall_test_0.md
deleted file mode 100644
index 842b527..0000000
--- a/docs/syscalls/syscall_test_0.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_0
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_0 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_0(void);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_1.md b/docs/syscalls/syscall_test_1.md
deleted file mode 100644
index a29abe2..0000000
--- a/docs/syscalls/syscall_test_1.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_1
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_1 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_1(int a);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_2.md b/docs/syscalls/syscall_test_2.md
deleted file mode 100644
index 9794f87..0000000
--- a/docs/syscalls/syscall_test_2.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_2
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_2 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_2(int a, int b);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_3.md b/docs/syscalls/syscall_test_3.md
deleted file mode 100644
index 435eed0..0000000
--- a/docs/syscalls/syscall_test_3.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_3
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_3 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_3(int a, int b, int c);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_4.md b/docs/syscalls/syscall_test_4.md
deleted file mode 100644
index 9a368c5..0000000
--- a/docs/syscalls/syscall_test_4.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_4
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_4 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_4(int a, int b, int c, int d);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_5.md b/docs/syscalls/syscall_test_5.md
deleted file mode 100644
index ec260a2..0000000
--- a/docs/syscalls/syscall_test_5.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_5
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_5 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_5(int a, int b, int c, int d, int e);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_6.md b/docs/syscalls/syscall_test_6.md
deleted file mode 100644
index 5feff4a..0000000
--- a/docs/syscalls/syscall_test_6.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_6
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_6 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_6(int a, int b, int c, int d, int e, int f);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_7.md b/docs/syscalls/syscall_test_7.md
deleted file mode 100644
index 7c82a8c..0000000
--- a/docs/syscalls/syscall_test_7.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_7
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_7 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_7(int a, int b, int c, int d, int e, int f, int g);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_8.md b/docs/syscalls/syscall_test_8.md
deleted file mode 100644
index fa5b210..0000000
--- a/docs/syscalls/syscall_test_8.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# zx_syscall_test_8
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_8 - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_8(
-    int a, int b, int c, int d, int e, int f, int g, int h);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/syscall_test_wrapper.md b/docs/syscalls/syscall_test_wrapper.md
deleted file mode 100644
index aa6178c..0000000
--- a/docs/syscalls/syscall_test_wrapper.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_syscall_test_wrapper
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-syscall_test_wrapper - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_syscall_test_wrapper(int a, int b, int c);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/system_get_dcache_line_size.md b/docs/syscalls/system_get_dcache_line_size.md
deleted file mode 100644
index 623e51b..0000000
--- a/docs/syscalls/system_get_dcache_line_size.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_system_get_dcache_line_size
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-system_get_dcache_line_size - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-uint32_t zx_system_get_dcache_line_size(void);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/system_get_features.md b/docs/syscalls/system_get_features.md
deleted file mode 100644
index 282ff67..0000000
--- a/docs/syscalls/system_get_features.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# zx_system_get_features
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-system_get_features - get supported hardware capabilities
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_system_get_features(uint32_t kind, uint32_t* features);
-```
-
-## DESCRIPTION
-
-`zx_system_get_features()` populates *features* with a bit mask of
-hardware-specific features.  *kind* indicates the specific type of features
-to retrieve, e.g. **ZX_FEATURE_KIND_CPU**.  The supported kinds and the meaning
-of individual feature bits is hardware-dependent.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_system_get_features()`  returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_NOT_SUPPORTED**  The requested feature kind is not available on this
-platform.
-
-## NOTES
-Refer to [Architecture Support](../architecture_support.md) for supported
-processor architectures.
-
-Refer to [zircon/features.h](../../system/public/zircon/features.h) for kinds
-of features and individual feature bits.
-
-## SEE ALSO
-
- - [`zx_system_get_num_cpus()`]
- - [`zx_system_get_physmem()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_system_get_num_cpus()`]: system_get_num_cpus.md
-[`zx_system_get_physmem()`]: system_get_physmem.md
diff --git a/docs/syscalls/system_get_num_cpus.md b/docs/syscalls/system_get_num_cpus.md
deleted file mode 100644
index 6f400c2..0000000
--- a/docs/syscalls/system_get_num_cpus.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# zx_system_get_num_cpus
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-system_get_num_cpus - get number of logical processors on the system
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-uint32_t zx_system_get_num_cpus(void);
-```
-
-## DESCRIPTION
-
-`zx_system_get_num_cpus()` returns the number of CPUs (logical processors)
-that exist on the system currently running.  This number cannot change
-during a run of the system, only at boot time.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_system_get_num_cpus()` returns the number of CPUs.
-
-## ERRORS
-
-`zx_system_get_num_cpus()` cannot fail.
-
-## NOTES
-
-## SEE ALSO
-
-
-[system_get_physmem](system_get_physmem.md).
diff --git a/docs/syscalls/system_get_physmem.md b/docs/syscalls/system_get_physmem.md
deleted file mode 100644
index 3827703..0000000
--- a/docs/syscalls/system_get_physmem.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# zx_system_get_physmem
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-system_get_physmem - get amount of physical memory on the system
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-uint64_t zx_system_get_physmem(void);
-```
-
-## DESCRIPTION
-
-`zx_system_get_physmem()` returns the total size of physical memory on
-the machine, in bytes.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_system_get_physmem()` returns a number in bytes.
-
-## ERRORS
-
-`zx_system_get_physmem()` cannot fail.
-
-## NOTES
-
-Currently the total size of physical memory cannot change during a run of
-the system, only at boot time.  This might change in the future.
-
-## SEE ALSO
-
-
-[system_get_num_cpus](system_get_num_cpus.md).
diff --git a/docs/syscalls/system_get_version.md b/docs/syscalls/system_get_version.md
deleted file mode 100644
index 636f578..0000000
--- a/docs/syscalls/system_get_version.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# zx_system_get_version
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-system_get_version - get version string for system
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_system_get_version(char* version, size_t version_size);
-```
-
-## DESCRIPTION
-
-`zx_system_get_version()` fills in the given character array with a string
-identifying the version of the Zircon system currently running.
-The provided size must be large enough for the complete string
-including its null terminator.
-
-The version string is guaranteed to never require more than 64 bytes of storage
-including the null terminator.
-
-The first four characters identify the version scheme. An example of the string
-returned is "git-8a07d52603404521038d8866b297f99de36f9162".
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_system_get_version()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BUFFER_TOO_SMALL**  *version_size* is too short.
-
-## NOTES
-
-## SEE ALSO
-
-
diff --git a/docs/syscalls/system_mexec.md b/docs/syscalls/system_mexec.md
deleted file mode 100644
index b212235..0000000
--- a/docs/syscalls/system_mexec.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# zx_system_mexec
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-system_mexec - Soft reboot the system with a new kernel and bootimage
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_system_mexec(zx_handle_t resource,
-                            zx_handle_t kernel_vmo,
-                            zx_handle_t bootimage_vmo);
-```
-
-## DESCRIPTION
-
-`zx_system_mexec()` accepts two vmo handles: *kernel_vmo* should contain a
-kernel image and *bootimage_vmo* should contain an initrd whose address shall
-be passed to the new kernel as a kernel argument.
-
-To supplant the running kernel, a *resource* of **ZX_RSRC_KIND_ROOT** must be
-supplied.
-
-Upon success, `zx_system_mexec()` shall supplant the currently running kernel
-image with the kernel image contained within *kernel_vmo*, load the ramdisk
-contained within *bootimage_vmo* to a location in physical memory and branch
-directly into the new kernel while providing the address of the loaded initrd
-to the new kernel.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-*kernel_vmo* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_READ**.
-
-*bootimage_vmo* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_system_mexec()` shall not return upon success.
-
-## SEE ALSO
-
-
-[system_mexec_payload_get](system_mexec_payload_get.md).
diff --git a/docs/syscalls/system_mexec_payload_get.md b/docs/syscalls/system_mexec_payload_get.md
deleted file mode 100644
index 791086c..0000000
--- a/docs/syscalls/system_mexec_payload_get.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# zx_system_mexec_payload_get
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-system_mexec_payload_get - Return a ZBI containing ZBI entries necessary to boot this system
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_system_mexec_payload_get(zx_handle_t resource,
-                                        void* buffer,
-                                        size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_system_mexec_payload_get()` accepts a resource handle and a
-pointer/length corresponding to an output buffer and fills the buffer with an
-incomplete ZBI containing a sequence of entries that should be appended to a
-ZBI before passing that image to [`zx_system_mexec()`].
-
-*resource* must be of type **ZX_RSRC_KIND_ROOT**.
-
-*buffer* and *buffer_size* must point to a buffer that is no longer than 16KiB.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-`zx_system_mexec_payload_get()` returns **ZX_OK** on success.
-
-## SEE ALSO
-
- - [`zx_system_mexec()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_system_mexec()`]: system_mexec.md
diff --git a/docs/syscalls/system_powerctl.md b/docs/syscalls/system_powerctl.md
deleted file mode 100644
index c12abb5..0000000
--- a/docs/syscalls/system_powerctl.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# zx_system_powerctl
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-system_powerctl - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_system_powerctl(zx_handle_t resource,
-                               uint32_t cmd,
-                               const zx_system_powerctl_arg_t* arg);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_ROOT**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/task_bind_exception_port.md b/docs/syscalls/task_bind_exception_port.md
deleted file mode 100644
index c7a69f5..0000000
--- a/docs/syscalls/task_bind_exception_port.md
+++ /dev/null
@@ -1,91 +0,0 @@
-# zx_task_bind_exception_port
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-task_bind_exception_port - Bind to, or unbind from, the exception port corresponding to a given job, process, or thread.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_task_bind_exception_port(zx_handle_t handle,
-                                        zx_handle_t port,
-                                        uint64_t key,
-                                        uint32_t options);
-```
-
-## DESCRIPTION
-
-`zx_task_bind_exception_port()` is used to bind (or unbind) a port to
-the exception port of a job, process, or thread.
-
-*port* is an IO port created by [`zx_port_create()`]. The same
-IO port can be bound to multiple objects.
-
-*key* is passed back in exception reports, and is part of the port
-message protocol.
-
-When a port is bound to the exception port of an object it participates
-in exception processing. See below for how exceptions are processed.
-
-### Unbinding
-
-To unbind from an exception port pass **ZX_HANDLE_INVALID** for *port*.
-This will remove the exception port from *handle* and *port* will no
-longer participate in exception processing for *handle*.
-
-The exception port will unbind automatically if all handles to *port*
-are closed while it is still bound.
-
-A thread may be currently waiting for a response from the program that
-bound *port* when it is unbound. Exception processing will continue as if
-*port* had never been bound.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*port* must be of type **ZX_OBJ_TYPE_PORT**.
-
-## RETURN VALUE
-
-`zx_task_bind_exception_port()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_ALREADY_BOUND** *handle* already has its exception port bound.
-
-**ZX_ERR_BAD_HANDLE** *handle* is not a valid handle,
-or *port* is not a valid handle. Note that when unbinding from an exception
-port *port* is **ZX_HANDLE_INVALID**.
-
-**ZX_ERR_BAD_STATE** Unbinding a port that is not currently bound.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not that of a job, process, or thread,
-and is not **ZX_HANDLE_INVALID**,
-or *port* is not that of a port and is not **ZX_HANDLE_INVALID**.
-
-**ZX_ERR_INVALID_ARGS** A bad value has been passed in *options*.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [exceptions](../exceptions.md)
- - [`zx_port_create()`]
- - [`zx_port_wait()`]
- - [`zx_task_resume_from_exception()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_port_create()`]: port_create.md
-[`zx_port_wait()`]: port_wait.md
-[`zx_task_resume_from_exception()`]: task_resume_from_exception.md
diff --git a/docs/syscalls/task_kill.md b/docs/syscalls/task_kill.md
deleted file mode 100644
index 6dfdc05..0000000
--- a/docs/syscalls/task_kill.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# zx_task_kill
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-task_kill - Kill the provided task (job, process, or thread).
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_task_kill(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-This asynchronously kills the given process, thread or job and its children
-recursively, until the entire task tree rooted at *handle* is dead.
-
-It is possible to wait for the task to be dead via the **ZX_TASK_TERMINATED**
-signal. When the procedure completes, as observed by the signal, the task and
-all its children are considered to be in the dead state and most operations
-will no longer succeed.
-
-If *handle* is a job and the syscall is successful, the job cannot longer be
-used to create new processes.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must have **ZX_RIGHT_DESTROY**.
-
-## RETURN VALUE
-
-On success, `zx_task_kill()` returns **ZX_OK**. If a process or thread uses
-this syscall to kill itself, this syscall does not return.
-
-## NOTES
-
-When using this syscall on a process, the return code for the process
-is -1 as reported by [`zx_object_get_info()`] via the **ZX_INFO_PROCESS** topic.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a task handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have the **ZX_RIGHT_DESTROY**
-right.
-
-## SEE ALSO
-
- - [`zx_job_create()`]
- - [`zx_process_create()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_job_create()`]: job_create.md
-[`zx_object_get_info()`]: object_get_info.md
-[`zx_process_create()`]: process_create.md
diff --git a/docs/syscalls/task_resume_from_exception.md b/docs/syscalls/task_resume_from_exception.md
deleted file mode 100644
index 064e795..0000000
--- a/docs/syscalls/task_resume_from_exception.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# zx_task_resume_from_exception
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-task_resume_from_exception - resume the given task after an exception has been reported
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_task_resume_from_exception(zx_handle_t handle,
-                                          zx_handle_t port,
-                                          uint32_t options);
-```
-
-## DESCRIPTION
-
-`zx_task_resume_from_exception()` causes the requested task to resume after an
-exception has been reported to the debug exception port. The port parameter
-should identify the [exception port](task_bind_exception_port.md) to which the
-exception being resumed from was delivered.
-
-Note that if a thread has any open [suspend tokens](task_suspend_token.md), it
-will remain suspended even when resumed from an exception.
-
-There are two ways to resume from an exception, depending on whether
-one wants the thread to resume where it left off, which in the case
-of an architectural exception generally means retrying the offending
-instruction, or give the next handler in the search order a chance
-to handle the exception.
-See [`zx_task_bind_exception_port()`] for a description of exception processing.
-
-To resume a thread where it left off, pass 0 for the options:
-
-```
-zx_status_t status = zx_task_resume_from_exception(thread, port, 0);
-```
-
-To pass the exception on to the next handler in the search order,
-pass **ZX_RESUME_TRY_NEXT** for the options.
-
-```
-zx_status_t status = zx_task_resume_from_exception(thread, port, ZX_RESUME_TRY_NEXT);
-```
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_THREAD**.
-
-*port* must be of type **ZX_OBJ_TYPE_PORT**.
-
-## RETURN VALUE
-
-`zx_task_resume_from_exception()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** *port* is not the port from which the exception
-report was sent.
-
-**ZX_ERR_BAD_HANDLE** Either *handle* or *port* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE** Either *handle* is not a thread handle,
-or *port* is not a port handle.
-
-**ZX_ERR_BAD_STATE**  The task is not in a state where resuming is possible,
-for example, it is dead or there is not an exception to resume from.
-
-**ZX_ERR_INVALID_ARGS** *options* is not valid.
-
-## LIMITATIONS
-
-Currently only thread handles are supported.
-
-## SEE ALSO
-
- - [`zx_task_bind_exception_port()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_task_bind_exception_port()`]: task_bind_exception_port.md
diff --git a/docs/syscalls/task_suspend.md b/docs/syscalls/task_suspend.md
deleted file mode 100644
index 5b69797..0000000
--- a/docs/syscalls/task_suspend.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# zx_task_suspend
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-task_suspend - suspend the given task. Currently only thread or process handles may be suspended.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_task_suspend(zx_handle_t handle, zx_handle_t* token);
-```
-
-## DESCRIPTION
-
-`zx_task_suspend()` causes the requested task to suspend
-execution. Task suspension is not synchronous and the task might not
-be suspended before the call returns. The task will be suspended soon
-after `zx_task_suspend()` is invoked, unless it is currently blocked in
-the kernel, in which case it will suspend after being unblocked.
-
-Tasks can be suspended and/or resumed before they are started. If a task is
-started while suspended, it will enter suspension before executing any code.
-Similarly, starting a new thread on a suspended process will suspend the thread
-before it executes any code.
-
-Invoking [`zx_task_kill()`] on a task that is suspended will successfully kill
-the task.
-
-A task cannot suspend itself or any of its parent tasks because it would never
-receive the suspend token and would be unable to resume execution.
-
-## RESUMING
-
-The allow the task to resume, close the suspend token handle. The task will
-remain suspended as long as there are any open suspend tokens. Like suspending,
-resuming is asynchronous so the thread may not be in a running state when the
-[`zx_handle_close()`] call returns, even if no other suspend tokens
-are open.
-
-## SIGNALS AND EXCEPTIONS
-
-There are two relevant signals that a thread can assert:
-
-- **ZX_THREAD_RUNNING**
-- **ZX_THREAD_SUSPENDED**
-
-Neither of these will be asserted until the thread is started via
-[`zx_process_start()`] or [`zx_thread_start()`]. When
-a thread starts, it will assert **ZX_THREAD_RUNNING** whether it is suspended
-or not, but if it is suspended will then switch to **ZX_THREAD_SUSPENDED**
-before executing any code.
-
-The **ZX_EXCP_PROCESS_STARTING** and **ZX_EXCP_THREAD_STARTING** debug
-exceptions will also be sent on start whether the task is suspended or not.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_THREAD** or **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_task_suspend()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a thread or process handle.
-
-**ZX_ERR_INVALID_ARGS**  *token*  was an invalid pointer.
-
-**ZX_ERR_BAD_STATE**  The task is already dying or dead and cannot be suspended.
-
-**ZX_ERR_NO_MEMORY**  Failed to allocate memory.
-
-**ZX_ERR_NOT_SUPPORTED**  The calling thread is attempting to suspend itself or
-                          one of its parent tasks.
-
-## LIMITATIONS
-
-Currently only thread and process handles are supported.
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_process_start()`]: process_start.md
-[`zx_task_kill()`]: task_kill.md
-[`zx_thread_start()`]: thread_start.md
diff --git a/docs/syscalls/task_suspend_token.md b/docs/syscalls/task_suspend_token.md
deleted file mode 100644
index 4972b46..0000000
--- a/docs/syscalls/task_suspend_token.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# zx_task_suspend_token
-
-This function replaces [task_suspend](task_suspend.md). When all callers are
-updated, [`zx_task_suspend()`] will be deleted and this function will be renamed
-[`zx_task_suspend()`].
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-task_suspend_token - suspend the given task. Currently only thread or process handles may be suspended.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_task_suspend_token(zx_handle_t handle, zx_handle_t* token);
-```
-
-## DESCRIPTION
-
-`zx_task_suspend_token()` causes the requested task to suspend execution. Task
-suspension is not synchronous and the task might not be suspended before the
-call returns. The task will be suspended soon after `zx_task_suspend_token()` is
-invoked, unless it is currently blocked in the kernel, in which case it will
-suspend after being unblocked.
-
-Invoking [`zx_task_kill()`] on a task that is suspended will successfully kill
-the task.
-
-## RESUMING
-
-The allow the task to resume, close the suspend token handle. The task will
-remain suspended as long as there are any open suspend tokens. Like suspending,
-resuming is asynchronous so the thread may not be in a running state when the
-[`zx_handle_close()`] call returns, even if no other suspend tokens
-are open.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_THREAD** or **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-[`zx_task_suspend()`] returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE** *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a thread handle.
-
-**ZX_ERR_INVALID_ARGS**  *token*  was an invalid pointer.
-
-**ZX_ERR_BAD_STATE**  The task is not in a state where suspending is possible.
-
-## LIMITATIONS
-
-Currently only thread handles are supported.
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_task_kill()`]: task_kill.md
-[`zx_task_suspend()`]: task_suspend.md
diff --git a/docs/syscalls/thread_create.md b/docs/syscalls/thread_create.md
deleted file mode 100644
index e350fe1..0000000
--- a/docs/syscalls/thread_create.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# zx_thread_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-thread_create - create a thread
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_thread_create(zx_handle_t process,
-                             const char* name,
-                             size_t name_size,
-                             uint32_t options,
-                             zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_thread_create()` creates a thread within the specified process.
-
-Upon success a handle for the new thread is returned.  The thread
-will not start executing until [`zx_thread_start()`] is called.
-
-*name* is silently truncated to a maximum of `ZX_MAX_NAME_LEN-1` characters.
-
-Thread handles may be waited on and will assert the signal
-**ZX_THREAD_TERMINATED** when the thread stops executing (due to
-[`zx_thread_exit()`] being called).
-
-*process* is the controlling [process object](../objects/process.md) for the
-new thread, which will become a child of that process.
-
-For thread lifecycle details see [thread object](../objects/thread.md).
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*process* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_MANAGE_THREAD**.
-
-## RETURN VALUE
-
-On success, `zx_thread_create()` returns **ZX_OK** and a handle (via *out*)
-to the new thread.  In the event of failure, a negative error value is
-returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *process* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *process* is not a process handle.
-
-**ZX_ERR_ACCESS_DENIED**  *process* does not have the **ZX_RIGHT_MANAGE_THREAD** right.
-
-**ZX_ERR_INVALID_ARGS**  *name* or *out* was an invalid pointer, or *options* was
-non-zero.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
- - [`zx_thread_exit()`]
- - [`zx_thread_start()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
-[`zx_thread_exit()`]: thread_exit.md
-[`zx_thread_start()`]: thread_start.md
diff --git a/docs/syscalls/thread_exit.md b/docs/syscalls/thread_exit.md
deleted file mode 100644
index 179a5f8..0000000
--- a/docs/syscalls/thread_exit.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# zx_thread_exit
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-thread_exit - terminate the current running thread
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-[[noreturn]] void zx_thread_exit(void);
-```
-
-## DESCRIPTION
-
-`zx_thread_exit()` causes the currently running thread to cease
-running and exit.
-
-The signal **ZX_THREAD_TERMINATED** will be asserted on the thread
-object upon exit and may be observed via [`zx_object_wait_one()`]
-or [`zx_object_wait_many()`] on a handle to the thread.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_thread_exit()` does not return.
-
-## SEE ALSO
-
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
- - [`zx_thread_create()`]
- - [`zx_thread_start()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
-[`zx_thread_create()`]: thread_create.md
-[`zx_thread_start()`]: thread_start.md
diff --git a/docs/syscalls/thread_read_state.md b/docs/syscalls/thread_read_state.md
deleted file mode 100644
index 2d8ed16..0000000
--- a/docs/syscalls/thread_read_state.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# zx_thread_read_state
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-thread_read_state - Read one aspect of thread state.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_thread_read_state(zx_handle_t handle,
-                                 uint32_t kind,
-                                 void* buffer,
-                                 size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_thread_read_state()` reads one aspect of state of the thread. The thread
-state may only be read when the thread is halted for an exception or the thread
-is suspended.
-
-The thread state is highly processor specific. See the structures in
-zircon/syscalls/debug.h for the contents of the structures on each platform.
-
-## STATES
-
-### ZX_THREAD_STATE_GENERAL_REGS
-
-The buffer must point to a `zx_thread_state_general_regs_t` structure that
-contains the general registers for the current architecture.
-
-### ZX_THREAD_STATE_FP_REGS
-
-The buffer must point to a `zx_thread_state_fp_regs_t` structure. On 64-bit
-ARM platforms, float point state is in the vector registers and this structure
-is empty.
-
-### ZX_THREAD_STATE_VECTOR_REGS
-
-The buffer must point to a `zx_thread_state_vector_regs_t` structure.
-
-### ZX_THREAD_STATE_DEBUG_REGS
-
-The buffer must point to a `zx_thread_state_debug_regs_t` structure. All input
-fields will be ignored and overwritten with the actual values for the thread.
-
-### ZX_THREAD_STATE_SINGLE_STEP
-
-The buffer must point to a `zx_thread_state_single_step_t` value which
-may contain either 0 (normal running), or 1 (single stepping enabled).
-
-### ZX_THREAD_X86_REGISTER_FS
-
-The buffer must point to a `zx_thread_x86_register_fs_t` structure which contains
-a uint64. This is only relevant on x86 platforms.
-
-### ZX_THREAD_X86_REGISTER_GS
-
-The buffer must point to a `zx_thread_x86_register_gs_t` structure which contains
-a uint64. This is only relevant on x86 platforms.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_thread_read_state()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not that of a thread.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* lacks **ZX_RIGHT_READ**.
-
-**ZX_ERR_INVALID_ARGS**  *kind* is not valid or *buffer* is an invalid pointer.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_BUFFER_TOO_SMALL**  The buffer length *buffer_size* is too small to
-hold the data required by *kind*.
-
-**ZX_ERR_BAD_STATE**  The thread is not stopped at a point where state
-is available. The thread state may only be read when the thread is stopped due
-to an exception.
-
-**ZX_ERR_NOT_SUPPORTED**  *kind* is not supported.
-This can happen, for example, when trying to read a register set that
-is not supported by the hardware the program is currently running on.
-
-## SEE ALSO
-
-
-[thread_write_state](thread_write_state.md).
diff --git a/docs/syscalls/thread_set_priority.md b/docs/syscalls/thread_set_priority.md
deleted file mode 100644
index 7c5439c..0000000
--- a/docs/syscalls/thread_set_priority.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# zx_thread_set_priority
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-thread_set_priority - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_thread_set_priority(int32_t prio);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/thread_start.md b/docs/syscalls/thread_start.md
deleted file mode 100644
index 6f06ffc..0000000
--- a/docs/syscalls/thread_start.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# zx_thread_start
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-thread_start - start execution on a thread
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_thread_start(zx_handle_t handle,
-                            zx_vaddr_t thread_entry,
-                            zx_vaddr_t stack,
-                            uintptr_t arg1,
-                            uintptr_t arg2);
-```
-
-## DESCRIPTION
-
-`zx_thread_start()` causes a thread to begin execution at the program counter
-specified by *thread_entry* and with the stack pointer set to *stack*. The
-arguments *arg1* and *arg2* are arranged to be in the architecture specific
-registers used for the first two arguments of a function call before the thread
-is started.  All other registers are zero upon start.
-
-When the last handle to a thread is closed, the thread is destroyed.
-
-Thread handles may be waited on and will assert the signal
-**ZX_THREAD_TERMINATED** when the thread stops executing (due to
-[`zx_thread_exit()`] being called).
-
-*thread_entry* shall point to a function that must call [`zx_thread_exit()`] or
-[`zx_futex_wake_handle_close_thread_exit()`] or
-[`zx_vmar_unmap_handle_close_thread_exit()`] before reaching the last instruction.
-Below is an example:
-
-```
-void thread_entry(uintptr_t arg1, uintptr_t arg2) __attribute__((noreturn)) {
-	// do work here.
-
-	zx_thread_exit();
-}
-```
-
-Failing to call one of the exit functions before reaching the end of
-the function will cause an architecture / toolchain specific exception.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_MANAGE_THREAD**.
-
-## RETURN VALUE
-
-`zx_thread_start()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *thread* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *thread* is not a thread handle.
-
-**ZX_ERR_ACCESS_DENIED**  The handle *thread* lacks **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_BAD_STATE**  *thread* is not ready to run or the process *thread*
-is part of is no longer alive.
-
-## SEE ALSO
-
- - [`zx_futex_wake_handle_close_thread_exit()`]
- - [`zx_handle_close()`]
- - [`zx_handle_duplicate()`]
- - [`zx_object_wait_async()`]
- - [`zx_object_wait_many()`]
- - [`zx_object_wait_one()`]
- - [`zx_thread_create()`]
- - [`zx_thread_exit()`]
- - [`zx_vmar_unmap_handle_close_thread_exit()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_futex_wake_handle_close_thread_exit()`]: futex_wake_handle_close_thread_exit.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_handle_duplicate()`]: handle_duplicate.md
-[`zx_object_wait_async()`]: object_wait_async.md
-[`zx_object_wait_many()`]: object_wait_many.md
-[`zx_object_wait_one()`]: object_wait_one.md
-[`zx_thread_create()`]: thread_create.md
-[`zx_thread_exit()`]: thread_exit.md
-[`zx_vmar_unmap_handle_close_thread_exit()`]: vmar_unmap_handle_close_thread_exit.md
diff --git a/docs/syscalls/thread_write_state.md b/docs/syscalls/thread_write_state.md
deleted file mode 100644
index b196331..0000000
--- a/docs/syscalls/thread_write_state.md
+++ /dev/null
@@ -1,94 +0,0 @@
-# zx_thread_write_state
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-thread_write_state - Write one aspect of thread state.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_thread_write_state(zx_handle_t handle,
-                                  uint32_t kind,
-                                  const void* buffer,
-                                  size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_thread_write_state()` writes one aspect of state of the thread. The thread
-state may only be written when the thread is halted for an exception or the
-thread is suspended.
-
-The thread state is highly processor specific. See the structures in
-zircon/syscalls/debug.h for the contents of the structures on each platform.
-
-## STATES
-
-See [`zx_thread_read_state()`] for the list of available states
-and their corresponding values.
-
-### ZX_THREAD_STATE_DEBUG_REGS
-
-#### ARM
-
-ARM has a variable amount of debug breakpoints and watchpoints. For this
-architecture, `zx_thread_state_debug_regs_t` is big enough to hold the maximum
-amount of breakpoints possible. But in most cases a given CPU implementation
-holds a lesser amount, meaning that the upper values beyond the limit are not
-used.
-
-The kernel will write all the available registers in the hardware independent of
-the given breakpoint/watchpoint count value. This means that all the correct
-state must be set for the call.
-
-You can get the current state of the registers by calling
-[`zx_thread_read_state()`](thread_read_state.md#zx_thread_state_debug_regs).
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_thread_write_state()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not that of a thread.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* lacks **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_INVALID_ARGS**  *kind* is not valid, *buffer* is an invalid pointer,
-*buffer_size* doesn't match the size of the structure expected for *kind* or
-the given values to set are not valid.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_BAD_STATE**  The thread is not stopped at a point where state
-is available. The thread state may only be read when the thread is stopped due
-to an exception.
-
-**ZX_ERR_NOT_SUPPORTED**  *kind* is not supported.
-This can happen, for example, when trying to read a register set that
-is not supported by the hardware the program is currently running on.
-
-## SEE ALSO
-
- - [`zx_thread_read_state()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_thread_read_state()`]: thread_read_state.md
diff --git a/docs/syscalls/ticks_get.md b/docs/syscalls/ticks_get.md
deleted file mode 100644
index ac5b043..0000000
--- a/docs/syscalls/ticks_get.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# zx_ticks_get
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-ticks_get - Read the number of high-precision timer ticks since boot.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_ticks_t zx_ticks_get(void);
-```
-
-## DESCRIPTION
-
-`zx_ticks_get()` returns the number of high-precision timer ticks since boot.
-
-These ticks may be processor cycles, high speed timer, profiling timer, etc.
-They are not guaranteed to continue advancing when the system is asleep.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_ticks_get()` returns the number of high-precision timer ticks since boot.
-
-## ERRORS
-
-`zx_ticks_get()` does not report any error conditions.
-
-## NOTES
-
-The returned value may be highly variable. Factors that can affect it include:
-- Changes in processor frequency
-- Migration between processors
-- Reset of the processor cycle counter
-- Reordering of instructions (if required, use a memory barrier)
-
-## SEE ALSO
-
-
-[ticks_per_second](ticks_per_second.md)
diff --git a/docs/syscalls/ticks_per_second.md b/docs/syscalls/ticks_per_second.md
deleted file mode 100644
index ce657d9..0000000
--- a/docs/syscalls/ticks_per_second.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# zx_ticks_per_second
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-ticks_per_second - Read the number of high-precision timer ticks in a second.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_ticks_t zx_ticks_per_second(void);
-```
-
-## DESCRIPTION
-
-`zx_ticks_per_second()` returns the number of high-precision timer ticks in a
-second.
-
-This can be used together with [`zx_ticks_get()`] to calculate the amount of
-time elapsed between two subsequent calls to [`zx_ticks_get()`].
-
-This value can vary from boot to boot of a given system. Once booted,
-this value is guaranteed not to change.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_ticks_per_second()` returns the number of high-precision timer ticks in a
-second.
-
-## ERRORS
-
-`zx_ticks_per_second()` does not report any error conditions.
-
-## EXAMPLES
-
-```
-zx_ticks_t ticks_per_second = zx_ticks_per_second();
-zx_ticks_t ticks_start = zx_ticks_get();
-
-// do some more work
-
-zx_ticks_t ticks_end = zx_ticks_get();
-double elapsed_seconds = (ticks_end - ticks_start) / (double)ticks_per_second;
-
-```
-
-## SEE ALSO
-
- - [`zx_ticks_get()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_ticks_get()`]: ticks_get.md
diff --git a/docs/syscalls/timer_cancel.md b/docs/syscalls/timer_cancel.md
deleted file mode 100644
index 4720e5b..0000000
--- a/docs/syscalls/timer_cancel.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# zx_timer_cancel
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-timer_cancel - cancel a timer
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_timer_cancel(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-`zx_timer_cancel()` cancels a pending timer that was started with
-[`zx_timer_set()`].
-
-Upon success the pending timer is canceled and the **ZX_TIMER_SIGNALED**
-signal is de-asserted. If a new pending timer is immediately needed
-rather than calling `zx_timer_cancel()` first, call [`zx_timer_set()`]
-with the new deadline.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_TIMER** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_timer_cancel()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* lacks the right **ZX_RIGHT_WRITE**.
-
-## NOTE
-
-Calling this function before [`zx_timer_set()`] has no effect.
-
-## SEE ALSO
-
- - [`zx_timer_create()`]
- - [`zx_timer_set()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_timer_create()`]: timer_create.md
-[`zx_timer_set()`]: timer_set.md
diff --git a/docs/syscalls/timer_create.md b/docs/syscalls/timer_create.md
deleted file mode 100644
index 13b849d..0000000
--- a/docs/syscalls/timer_create.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# zx_timer_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-timer_create - create a timer
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_timer_create(uint32_t options,
-                            zx_clock_t clock_id,
-                            zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_timer_create()` creates a timer, an object that can signal
-when a specified point in time has been reached. The only valid
-*clock_id* is **ZX_CLOCK_MONOTONIC**.
-
-The *options* value specifies the coalescing behavior which
-controls whether the system can fire the time earlier or later
-depending on other pending timers.
-
-The possible values are:
-
-+ **ZX_TIMER_SLACK_CENTER**
-+ **ZX_TIMER_SLACK_EARLY**
-+ **ZX_TIMER_SLACK_LATE**
-
-Passing 0 in options is equivalent to **ZX_TIMER_SLACK_CENTER**.
-
-See [timer slack](timer_slack.md) for more information.
-
-The returned handle has the **ZX_RIGHT_DUPLICATE**, **ZX_RIGHT_TRANSFER**,
-**ZX_RIGHT_READ** and **ZX_RIGHT_WRITE** right.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_timer_create()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *out* is an invalid pointer or NULL or
-*options* is not one of the **ZX_TIMER_SLACK** values or *clock_id* is
-any value other than **ZX_CLOCK_MONOTONIC**.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_deadline_after()`]
- - [`zx_handle_close()`]
- - [`zx_timer_cancel()`]
- - [`zx_timer_set()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_deadline_after()`]: deadline_after.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_timer_cancel()`]: timer_cancel.md
-[`zx_timer_set()`]: timer_set.md
diff --git a/docs/syscalls/timer_set.md b/docs/syscalls/timer_set.md
deleted file mode 100644
index 52be2fb..0000000
--- a/docs/syscalls/timer_set.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# zx_timer_set
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-timer_set - start a timer
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_timer_set(zx_handle_t handle,
-                         zx_time_t deadline,
-                         zx_duration_t slack);
-```
-
-## DESCRIPTION
-
-`zx_timer_set()` starts a one-shot timer that will fire when
-*deadline* passes. If a previous call to `zx_timer_set()` was
-pending, the previous timer is canceled and
-**ZX_TIMER_SIGNALED** is de-asserted as needed.
-
-The *deadline* parameter specifies a deadline with respect to
-**ZX_CLOCK_MONOTONIC**. To wait for a relative interval,
-use [`zx_deadline_after()`] returned value in *deadline*.
-
-To fire the timer immediately pass a *deadline* less than or equal to **0**.
-
-When the timer fires it asserts **ZX_TIMER_SIGNALED**. To de-assert this
-signal call [`zx_timer_cancel()`] or `zx_timer_set()` again.
-
-The *slack* parameter specifies a range from *deadline* - *slack* to
-*deadline* + *slack* during which the timer is allowed to fire. The system
-uses this parameter as a hint to coalesce nearby timers.
-
-The precise coalescing behavior is controlled by the *options* parameter
-specified when the timer was created. **ZX_TIMER_SLACK_EARLY** allows only
-firing in the *deadline* - *slack* interval and **ZX_TIMER_SLACK_LATE**
-allows only firing in the *deadline* + *slack* interval. The default
-option value of 0 is **ZX_TIMER_SLACK_CENTER** and allows both early and
-late firing with an effective interval of *deadline* - *slack* to
-*deadline* + *slack*
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_TIMER** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_timer_set()` returns **ZX_OK** on success.
-In the event of failure, a negative error value is returned.
-
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* lacks the right **ZX_RIGHT_WRITE**.
-
-**ZX_ERR_OUT_OF_RANGE**  *slack* is negative.
-
-## SEE ALSO
-
- - [`zx_deadline_after()`]
- - [`zx_timer_cancel()`]
- - [`zx_timer_create()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_deadline_after()`]: deadline_after.md
-[`zx_timer_cancel()`]: timer_cancel.md
-[`zx_timer_create()`]: timer_create.md
diff --git a/docs/syscalls/vcpu_create.md b/docs/syscalls/vcpu_create.md
deleted file mode 100644
index 583c832..0000000
--- a/docs/syscalls/vcpu_create.md
+++ /dev/null
@@ -1,95 +0,0 @@
-# zx_vcpu_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vcpu_create - create a VCPU
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vcpu_create(zx_handle_t guest,
-                           uint32_t options,
-                           zx_vaddr_t entry,
-                           zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_vcpu_create()` creates a VCPU within a guest, which allows for execution
-within the virtual machine. One or more VCPUs may be created per guest, where
-the number of VCPUs does not need to match the number of physical CPUs on the
-machine.
-
-*entry* is the instruction pointer used to indicate where in guest physical
-memory execution of the VCPU should start.
-
-*out* is bound to the thread that created it, and all syscalls that operate on
-it must be called from the same thread, with the exception of
-[`zx_vcpu_interrupt()`].
-
-N.B. VCPU is an abbreviation of virtual CPU.
-
-The following rights will be set on the handle *out* by default:
-
-**ZX_RIGHT_DUPLICATE** &mdash; *out* may be duplicated.
-
-**ZX_RIGHT_TRANSFER** &mdash; *out* may be transferred over a channel.
-
-**ZX_RIGHT_EXECUTE** &mdash; *out* may have its execution resumed (or begun)
-
-**ZX_RIGHT_SIGNAL** &mdash; *out* may be interrupted
-
-**ZX_RIGHT_READ** &mdash; *out* may have its state read
-
-**ZX_RIGHT_WRITE** &mdash; may have its state written
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*guest* must be of type **ZX_OBJ_TYPE_GUEST** and have **ZX_RIGHT_MANAGE_PROCESS**.
-
-## RETURN VALUE
-
-`zx_vcpu_create()` returns **ZX_OK** on success. On failure, an error value is
-returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** *guest* does not have the **ZX_RIGHT_MANAGE_PROCESS**
-right.
-
-**ZX_ERR_BAD_HANDLE** *guest* is an invalid handle.
-
-**ZX_ERR_INVALID_ARGS** *args* contains an invalid argument, or *out* is an
-invalid pointer, or *options* is nonzero.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_WRONG_TYPE** *guest* is not a handle to a guest.
-
-## SEE ALSO
-
- - [`zx_guest_create()`]
- - [`zx_guest_set_trap()`]
- - [`zx_vcpu_interrupt()`]
- - [`zx_vcpu_read_state()`]
- - [`zx_vcpu_resume()`]
- - [`zx_vcpu_write_state()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_create()`]: guest_create.md
-[`zx_guest_set_trap()`]: guest_set_trap.md
-[`zx_vcpu_interrupt()`]: vcpu_interrupt.md
-[`zx_vcpu_read_state()`]: vcpu_read_state.md
-[`zx_vcpu_resume()`]: vcpu_resume.md
-[`zx_vcpu_write_state()`]: vcpu_write_state.md
diff --git a/docs/syscalls/vcpu_interrupt.md b/docs/syscalls/vcpu_interrupt.md
deleted file mode 100644
index acc9da8..0000000
--- a/docs/syscalls/vcpu_interrupt.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# zx_vcpu_interrupt
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vcpu_interrupt - raise an interrupt on a VCPU
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vcpu_interrupt(zx_handle_t handle, uint32_t vector);
-```
-
-## DESCRIPTION
-
-`zx_vcpu_interrupt()` raises an interrupt of *vector* on *handle*, and may be
-called from any thread.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_SIGNAL**.
-
-## RETURN VALUE
-
-`zx_vcpu_interrupt()` returns **ZX_OK** on success. On failure, an error value is
-returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_SIGNAL** right.
-
-**ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
-
-**ZX_ERR_OUT_OF_RANGE** *vector* is outside of the range interrupts supported by
-the current architecture.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
-
-## SEE ALSO
-
- - [`zx_guest_create()`]
- - [`zx_guest_set_trap()`]
- - [`zx_vcpu_create()`]
- - [`zx_vcpu_read_state()`]
- - [`zx_vcpu_resume()`]
- - [`zx_vcpu_write_state()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_create()`]: guest_create.md
-[`zx_guest_set_trap()`]: guest_set_trap.md
-[`zx_vcpu_create()`]: vcpu_create.md
-[`zx_vcpu_read_state()`]: vcpu_read_state.md
-[`zx_vcpu_resume()`]: vcpu_resume.md
-[`zx_vcpu_write_state()`]: vcpu_write_state.md
diff --git a/docs/syscalls/vcpu_read_state.md b/docs/syscalls/vcpu_read_state.md
deleted file mode 100644
index 919800d..0000000
--- a/docs/syscalls/vcpu_read_state.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# zx_vcpu_read_state
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vcpu_read_state - read the state of a VCPU
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vcpu_read_state(zx_handle_t handle,
-                               uint32_t kind,
-                               void* buffer,
-                               size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_vcpu_read_state()` reads the state of *handle* as specified by *kind* into
-*buffer*. It is only valid to read the state of *handle* when execution has been
-paused.
-
-*kind* must be **ZX_VCPU_STATE**.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_vcpu_read_state()` returns **ZX_OK** on success. On failure, an error value is
-returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_READ** right.
-
-**ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
-
-**ZX_ERR_BAD_STATE** *handle* is in a bad state, and state can not be read.
-
-**ZX_ERR_INVALID_ARGS** *kind* does not name a known VCPU state, *buffer* is an
-invalid pointer, or *buffer_size* does not match the expected size of *kind*.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
-
-## SEE ALSO
-
- - [`zx_guest_create()`]
- - [`zx_guest_set_trap()`]
- - [`zx_vcpu_create()`]
- - [`zx_vcpu_interrupt()`]
- - [`zx_vcpu_resume()`]
- - [`zx_vcpu_write_state()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_create()`]: guest_create.md
-[`zx_guest_set_trap()`]: guest_set_trap.md
-[`zx_vcpu_create()`]: vcpu_create.md
-[`zx_vcpu_interrupt()`]: vcpu_interrupt.md
-[`zx_vcpu_resume()`]: vcpu_resume.md
-[`zx_vcpu_write_state()`]: vcpu_write_state.md
diff --git a/docs/syscalls/vcpu_resume.md b/docs/syscalls/vcpu_resume.md
deleted file mode 100644
index 9bfa916..0000000
--- a/docs/syscalls/vcpu_resume.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# zx_vcpu_resume
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vcpu_resume - resume execution of a VCPU
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-#include <zircon/syscalls/port.h>
-
-zx_status_t zx_vcpu_resume(zx_handle_t handle, zx_port_packet_t* packet);
-```
-
-## DESCRIPTION
-
-`zx_vcpu_resume()` begins or resumes execution of *handle*, and blocks until it has
-paused execution. On pause of execution, *packet* is populated with reason for
-the pause. After handling the reason, execution may be resumed by calling
-`zx_vcpu_resume()` again.
-
-N.B. Execution of a *handle* must be resumed on the same thread it was created on.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_EXECUTE**.
-
-## RETURN VALUE
-
-`zx_vcpu_resume()` returns **ZX_OK** on success. On failure, an error value is
-returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_EXECUTE** right.
-
-**ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
-
-**ZX_ERR_BAD_STATE** *handle* is in a bad state, and can not be executed.
-
-**ZX_ERR_CANCELED** *handle* execution was canceled while waiting on an event.
-
-**ZX_ERR_INTERNAL** There was an error executing *handle*.
-
-**ZX_ERR_INVALID_ARGS** *packet* is an invalid pointer.
-
-**ZX_ERR_NOT_SUPPORTED** An unsupported operation was encountered while
-executing *handle*.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
-
-## SEE ALSO
-
- - [`zx_guest_create()`]
- - [`zx_guest_set_trap()`]
- - [`zx_vcpu_create()`]
- - [`zx_vcpu_interrupt()`]
- - [`zx_vcpu_read_state()`]
- - [`zx_vcpu_write_state()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_create()`]: guest_create.md
-[`zx_guest_set_trap()`]: guest_set_trap.md
-[`zx_vcpu_create()`]: vcpu_create.md
-[`zx_vcpu_interrupt()`]: vcpu_interrupt.md
-[`zx_vcpu_read_state()`]: vcpu_read_state.md
-[`zx_vcpu_write_state()`]: vcpu_write_state.md
diff --git a/docs/syscalls/vcpu_write_state.md b/docs/syscalls/vcpu_write_state.md
deleted file mode 100644
index 294d162..0000000
--- a/docs/syscalls/vcpu_write_state.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# zx_vcpu_write_state
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vcpu_write_state - write the state of a VCPU
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vcpu_write_state(zx_handle_t handle,
-                                uint32_t kind,
-                                const void* buffer,
-                                size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_vcpu_write_state()` writes the state of *handle* as specified by *kind* from
-*buffer*. It is only valid to write the state of *handle* when execution has been
-paused.
-
-*kind* may be **ZX_VCPU_STATE** or **ZX_VCPU_IO**.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VCPU** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_vcpu_write_state()` returns **ZX_OK** on success. On failure, an error value is
-returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** *handle* does not have the **ZX_RIGHT_WRITE** right.
-
-**ZX_ERR_BAD_HANDLE** *handle* is an invalid handle.
-
-**ZX_ERR_BAD_STATE** *handle* is in a bad state, and state can not be written.
-
-**ZX_ERR_INVALID_ARGS** *kind* does not name a known VCPU state, *buffer* is an
-invalid pointer, or *buffer_size* does not match the expected size of *kind*.
-
-**ZX_ERR_WRONG_TYPE** *handle* is not a handle to a VCPU.
-
-## SEE ALSO
-
- - [`zx_guest_create()`]
- - [`zx_guest_set_trap()`]
- - [`zx_vcpu_create()`]
- - [`zx_vcpu_interrupt()`]
- - [`zx_vcpu_read_state()`]
- - [`zx_vcpu_resume()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_guest_create()`]: guest_create.md
-[`zx_guest_set_trap()`]: guest_set_trap.md
-[`zx_vcpu_create()`]: vcpu_create.md
-[`zx_vcpu_interrupt()`]: vcpu_interrupt.md
-[`zx_vcpu_read_state()`]: vcpu_read_state.md
-[`zx_vcpu_resume()`]: vcpu_resume.md
diff --git a/docs/syscalls/vmar_allocate.md b/docs/syscalls/vmar_allocate.md
deleted file mode 100644
index bc8945b..0000000
--- a/docs/syscalls/vmar_allocate.md
+++ /dev/null
@@ -1,115 +0,0 @@
-# zx_vmar_allocate
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_allocate - allocate a new subregion
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_allocate(zx_handle_t parent_vmar,
-                             zx_vm_option_t options,
-                             uint64_t offset,
-                             uint64_t size,
-                             zx_handle_t* child_vmar,
-                             zx_vaddr_t* child_addr);
-```
-
-## DESCRIPTION
-
-Creates a new VMAR within the one specified by *parent_vmar*.
-
-*options* is a bit vector that contains one more of the following:
-- **ZX_VM_COMPACT**  A hint to the kernel that allocations and mappings
-  within the newly created subregion should be kept close together.   See the
-  NOTES section below for discussion.
-- **ZX_VM_SPECIFIC**  Use the *offset* to place the mapping, invalid if
-  vmar does not have the **ZX_VM_CAN_MAP_SPECIFIC** permission.  *offset*
-  is an offset relative to the base address of the parent region.  It is an error
-  to specify an address range that overlaps with another VMAR or mapping.
-- **ZX_VM_CAN_MAP_SPECIFIC**  The new VMAR can have subregions/mappings
-  created with **ZX_VM_SPECIFIC**.  It is NOT an error if the parent does
-  not have **ZX_VM_CAN_MAP_SPECIFIC** permissions.
-- **ZX_VM_CAN_MAP_READ**  The new VMAR can contain readable mappings.
-  It is an error if the parent does not have **ZX_VM_CAN_MAP_READ** permissions.
-- **ZX_VM_CAN_MAP_WRITE**  The new VMAR can contain writable mappings.
-  It is an error if the parent does not have **ZX_VM_CAN_MAP_WRITE** permissions.
-- **ZX_VM_CAN_MAP_EXECUTE**  The new VMAR can contain executable mappings.
-  It is an error if the parent does not have **ZX_VM_CAN_MAP_EXECUTE** permissions.
-
-*offset* must be 0 if *options* does not have **ZX_VM_SPECIFIC** set.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-If *options* & **ZX_VM_CAN_MAP_READ**, *parent_vmar* must be of type **ZX_OBJ_TYPE_VMAR** and have **ZX_RIGHT_READ**.
-
-If *options* & **ZX_VM_CAN_MAP_WRITE**, *parent_vmar* must be of type **ZX_OBJ_TYPE_VMAR** and have **ZX_RIGHT_WRITE**.
-
-If *options* & **ZX_VM_CAN_MAP_EXECUTE**, *parent_vmar* must be of type **ZX_OBJ_TYPE_VMAR** and have **ZX_RIGHT_EXECUTE**.
-
-## RETURN VALUE
-
-`zx_vmar_allocate()` returns **ZX_OK**, the absolute base address of the
-subregion (via *child_addr*), and a handle to the new subregion (via
-*child_vmar*) on success.  The base address will be page-aligned and non-zero.
-In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *parent_vmar* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *parent_vmar* is not a VMAR handle.
-
-**ZX_ERR_BAD_STATE**  *parent_vmar* refers to a destroyed VMAR.
-
-**ZX_ERR_INVALID_ARGS**  *child_vmar* or *child_addr* are not valid, *offset* is
-non-zero when **ZX_VM_SPECIFIC** is not given, *offset* and *size* describe
-an unsatisfiable allocation due to exceeding the region bounds, *offset*
-or *size* is not page-aligned, or *size* is 0.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-**ZX_ERR_ACCESS_DENIED**  Insufficient privileges to make the requested allocation.
-
-## NOTES
-
-### Deallocation
-
-The address space occupied by a VMAR will remain allocated (within its
-parent VMAR) until the VMAR is destroyed by calling [`zx_vmar_destroy()`].
-
-Note that just closing the VMAR's handle does not deallocate the address
-space occupied by the VMAR.
-
-### The COMPACT flag
-
-The kernel interprets this flag as a request to reduce sprawl in allocations.
-While this does not necessitate reducing the absolute entropy of the allocated
-addresses, there will potentially be a very high correlation between allocations.
-This is a trade-off that the developer can make to increase locality of
-allocations and reduce the number of page tables necessary, if they are willing
-to have certain addresses be more correlated.
-
-## SEE ALSO
-
- - [`zx_vmar_destroy()`]
- - [`zx_vmar_map()`]
- - [`zx_vmar_protect()`]
- - [`zx_vmar_unmap()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmar_destroy()`]: vmar_destroy.md
-[`zx_vmar_map()`]: vmar_map.md
-[`zx_vmar_protect()`]: vmar_protect.md
-[`zx_vmar_unmap()`]: vmar_unmap.md
diff --git a/docs/syscalls/vmar_allocate_old.md b/docs/syscalls/vmar_allocate_old.md
deleted file mode 100644
index f4a4a8e..0000000
--- a/docs/syscalls/vmar_allocate_old.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# zx_vmar_allocate_old
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_allocate_old - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_allocate_old(zx_handle_t parent_vmar,
-                                 uint64_t offset,
-                                 uint64_t size,
-                                 uint32_t map_flags,
-                                 zx_handle_t* child_vmar,
-                                 zx_vaddr_t* child_addr);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/vmar_destroy.md b/docs/syscalls/vmar_destroy.md
deleted file mode 100644
index 8ed155d..0000000
--- a/docs/syscalls/vmar_destroy.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# zx_vmar_destroy
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_destroy - destroy a virtual memory address region
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_destroy(zx_handle_t handle);
-```
-
-## DESCRIPTION
-
-`zx_vmar_destroy()` unmaps all mappings within the given region, and destroys
-all sub-regions of the region.  Note that this operation is logically recursive.
-
-This operation does not close *handle*.  Any outstanding handles to this
-VMAR will remain valid handles, but all VMAR operations on them will fail.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_vmar_destroy()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a VMAR handle.
-
-**ZX_ERR_BAD_STATE**  This region is already destroyed.
-
-## NOTES
-
-## SEE ALSO
-
- - [`zx_vmar_allocate()`]
- - [`zx_vmar_map()`]
- - [`zx_vmar_protect()`]
- - [`zx_vmar_unmap()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmar_allocate()`]: vmar_allocate.md
-[`zx_vmar_map()`]: vmar_map.md
-[`zx_vmar_protect()`]: vmar_protect.md
-[`zx_vmar_unmap()`]: vmar_unmap.md
diff --git a/docs/syscalls/vmar_map.md b/docs/syscalls/vmar_map.md
deleted file mode 100644
index c7d67eb..0000000
--- a/docs/syscalls/vmar_map.md
+++ /dev/null
@@ -1,123 +0,0 @@
-# zx_vmar_map
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_map - add a memory mapping
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_map(zx_handle_t handle,
-                        zx_vm_option_t options,
-                        uint64_t vmar_offset,
-                        zx_handle_t vmo,
-                        uint64_t vmo_offset,
-                        uint64_t len,
-                        zx_vaddr_t* mapped_addr);
-```
-
-## DESCRIPTION
-
-Maps the given VMO into the given virtual memory address region.  The mapping
-retains a reference to the underlying virtual memory object, which means
-closing the VMO handle does not remove the mapping added by this function.
-
-*options* is a bit vector of the following:
-- **ZX_VM_SPECIFIC**  Use the *vmar_offset* to place the mapping, invalid if
-  *handle* does not have the **ZX_VM_CAN_MAP_SPECIFIC** permission.
-  *vmar_offset* is an offset relative to the base address of the given VMAR.
-  It is an error to specify a range that overlaps with another VMAR or mapping.
-- **ZX_VM_SPECIFIC_OVERWRITE**  Same as **ZX_VM_SPECIFIC**, but can
-  overlap another mapping.  It is still an error to partially-overlap another VMAR.
-  If the range meets these requirements, it will atomically (with respect to all
-  other map/unmap/protect operations) replace existing mappings in the area.
-- **ZX_VM_PERM_READ**  Map *vmo* as readable.  It is an error if *handle*
-  does not have **ZX_VM_CAN_MAP_READ** permissions, the *handle* does
-  not have the **ZX_RIGHT_READ** right, or the *vmo* handle does not have the
-  **ZX_RIGHT_READ** right.
-- **ZX_VM_PERM_WRITE**  Map *vmo* as writable.  It is an error if *handle*
-  does not have **ZX_VM_CAN_MAP_WRITE** permissions, the *handle* does
-  not have the **ZX_RIGHT_WRITE** right, or the *vmo* handle does not have the
-  **ZX_RIGHT_WRITE** right.
-- **ZX_VM_PERM_EXECUTE**  Map *vmo* as executable.  It is an error if *handle*
-  does not have **ZX_VM_CAN_MAP_EXECUTE** permissions, the *handle* handle does
-  not have the **ZX_RIGHT_EXECUTE** right, or the *vmo* handle does not have the
-  **ZX_RIGHT_EXECUTE** right.
-- **ZX_VM_MAP_RANGE**  Immediately page into the new mapping all backed
-  regions of the VMO.  This cannot be specified if
-  **ZX_VM_SPECIFIC_OVERWRITE** is used.
-- **ZX_VM_REQUIRE_NON_RESIZABLE** Maps the VMO only if the VMO is non-resizable,
-  that is, it was created with the **ZX_VMO_NON_RESIZABLE** option.
-
-*vmar_offset* must be 0 if *options* does not have **ZX_VM_SPECIFIC** or
-**ZX_VM_SPECIFIC_OVERWRITE** set.  If neither of those are set, then
-the mapping will be assigned an offset at random by the kernel (with an
-allocator determined by policy set on the target VMAR).
-
-*len* must be page-aligned.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VMAR**.
-
-*vmo* must be of type **ZX_OBJ_TYPE_VMO**.
-
-## RETURN VALUE
-
-`zx_vmar_map()` returns **ZX_OK** and the absolute base address of the
-mapping (via *mapped_addr*) on success.  The base address will be page-aligned
-and non-zero.  In the event of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* or *vmo* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* or *vmo* is not a VMAR or VMO handle, respectively.
-
-**ZX_ERR_BAD_STATE**  *handle* refers to a destroyed VMAR.
-
-**ZX_ERR_INVALID_ARGS** *mapped_addr* or *options* are not valid, *vmar_offset* is
-non-zero when neither **ZX_VM_SPECIFIC** nor
-**ZX_VM_SPECIFIC_OVERWRITE** are given,
-**ZX_VM_SPECIFIC_OVERWRITE** and **ZX_VM_MAP_RANGE** are both given,
-*vmar_offset* and *len* describe an unsatisfiable allocation due to exceeding the region bounds,
-*vmar_offset* or *vmo_offset* or *len* are not page-aligned,
-`vmo_offset + ROUNDUP(len, PAGE_SIZE)` overflows.
-
-**ZX_ERR_ACCESS_DENIED**  Insufficient privileges to make the requested mapping.
-
-**ZX_ERR_NOT_SUPPORTED** The VMO is resizable and **ZX_VM_REQUIRE_NON_RESIZABLE** was
-requested.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## NOTES
-
-The VMO that backs a memory mapping can be resized to a smaller size. This can cause the
-thread is reading or writing to the VMAR region to fault. To avoid this hazard, services
-that receive VMOs from clients should use **ZX_VM_REQUIRE_NON_RESIZABLE** when mapping
-the VMO.
-
-## SEE ALSO
-
- - [`zx_vmar_allocate()`]
- - [`zx_vmar_destroy()`]
- - [`zx_vmar_protect()`]
- - [`zx_vmar_unmap()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmar_allocate()`]: vmar_allocate.md
-[`zx_vmar_destroy()`]: vmar_destroy.md
-[`zx_vmar_protect()`]: vmar_protect.md
-[`zx_vmar_unmap()`]: vmar_unmap.md
diff --git a/docs/syscalls/vmar_map_old.md b/docs/syscalls/vmar_map_old.md
deleted file mode 100644
index 5df97ff..0000000
--- a/docs/syscalls/vmar_map_old.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# zx_vmar_map_old
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_map_old - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_map_old(zx_handle_t handle,
-                            uint64_t vmar_offset,
-                            zx_handle_t vmo,
-                            uint64_t vmo_offset,
-                            uint64_t len,
-                            uint32_t map_flags,
-                            zx_vaddr_t* mapped_addr);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/vmar_protect.md b/docs/syscalls/vmar_protect.md
deleted file mode 100644
index bd4ca15..0000000
--- a/docs/syscalls/vmar_protect.md
+++ /dev/null
@@ -1,88 +0,0 @@
-# zx_vmar_protect
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_protect - set protection of virtual memory pages
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_protect(zx_handle_t handle,
-                            zx_vm_option_t options,
-                            zx_vaddr_t addr,
-                            uint64_t len);
-```
-
-## DESCRIPTION
-
-`zx_vmar_protect()` alters the access protections for the memory mappings
-in the range of *len* bytes starting from *addr*. The *options* argument should
-be a bitwise-or of one or more of the following:
-- **ZX_VM_PERM_READ**  Map as readable.  It is an error if *handle*
-  does not have **ZX_VM_CAN_MAP_READ** permissions or *handle* does
-  not have the **ZX_RIGHT_READ** right.  It is also an error if the VMO handle
-  used to create the mapping did not have the **ZX_RIGHT_READ** right.
-- **ZX_VM_PERM_WRITE**  Map as writable.  It is an error if *handle*
-  does not have **ZX_VM_CAN_MAP_WRITE** permissions or *handle* does
-  not have the **ZX_RIGHT_WRITE** right.  It is also an error if the VMO handle
-  used to create the mapping did not have the **ZX_RIGHT_WRITE** right.
-- **ZX_VM_PERM_EXECUTE**  Map as executable.  It is an error if *handle*
-  does not have **ZX_VM_CAN_MAP_EXECUTE** permissions or *handle* does
-  not have the **ZX_RIGHT_EXECUTE** right.  It is also an error if the VMO handle
-  used to create the mapping did not have the **ZX_RIGHT_EXECUTE** right.
-
-*len* must be page-aligned.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-If *options* & **ZX_VM_PERM_READ**, *handle* must be of type **ZX_OBJ_TYPE_VMAR** and have **ZX_RIGHT_READ**.
-
-If *options* & **ZX_VM_PERM_WRITE**, *handle* must be of type **ZX_OBJ_TYPE_VMAR** and have **ZX_RIGHT_WRITE**.
-
-If *options* & **ZX_VM_PERM_EXECUTE**, *handle* must be of type **ZX_OBJ_TYPE_VMAR** and have **ZX_RIGHT_EXECUTE**.
-
-## RETURN VALUE
-
-`zx_vmar_protect()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a VMAR handle.
-
-**ZX_ERR_INVALID_ARGS**  *prot_flags* is an unsupported combination of flags
-(e.g., **ZX_VM_PERM_WRITE** but not **ZX_VM_PERM_READ**), *addr* is
-not page-aligned, *len* is 0, or some subrange of the requested range is
-occupied by a subregion.
-
-**ZX_ERR_NOT_FOUND**  Some subrange of the requested range is not mapped.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have the proper rights for the
-requested change, the original VMO handle used to create the mapping did not
-have the rights for the requested change, or the VMAR itself does not allow
-the requested change.
-
-## NOTES
-
-## SEE ALSO
-
- - [`zx_vmar_allocate()`]
- - [`zx_vmar_destroy()`]
- - [`zx_vmar_map()`]
- - [`zx_vmar_unmap()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmar_allocate()`]: vmar_allocate.md
-[`zx_vmar_destroy()`]: vmar_destroy.md
-[`zx_vmar_map()`]: vmar_map.md
-[`zx_vmar_unmap()`]: vmar_unmap.md
diff --git a/docs/syscalls/vmar_protect_old.md b/docs/syscalls/vmar_protect_old.md
deleted file mode 100644
index a31803d..0000000
--- a/docs/syscalls/vmar_protect_old.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_vmar_protect_old
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_protect_old - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_protect_old(zx_handle_t handle,
-                                zx_vaddr_t addr,
-                                uint64_t len,
-                                uint32_t prot_flags);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/vmar_unmap.md b/docs/syscalls/vmar_unmap.md
deleted file mode 100644
index 0fdcac8..0000000
--- a/docs/syscalls/vmar_unmap.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# zx_vmar_unmap
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_unmap - unmap virtual memory pages
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_unmap(zx_handle_t handle, zx_vaddr_t addr, uint64_t len);
-```
-
-## DESCRIPTION
-
-`zx_vmar_unmap()` unmaps all VMO mappings and destroys (as if [`zx_vmar_destroy()`]
-were called) all sub-regions within the absolute range including *addr* and ending
-before exclusively at `addr + len`.  Any sub-region that is in the range must
-be fully in the range (i.e. partial overlaps are an error).  If a mapping is
-only partially in the range, the mapping is split and the requested portion is
-unmapped.
-
-*len* must be page-aligned.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_vmar_unmap()` returns **ZX_OK** on success.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a VMAR handle.
-
-**ZX_ERR_INVALID_ARGS**  *addr* is not page-aligned, *len* is 0 or not page-aligned,
-or the requested range partially overlaps a sub-region.
-
-**ZX_ERR_BAD_STATE**  *handle* refers to a destroyed handle.
-
-**ZX_ERR_NOT_FOUND**  Could not find the requested mapping.
-
-## NOTES
-
-## SEE ALSO
-
- - [`zx_vmar_allocate()`]
- - [`zx_vmar_destroy()`]
- - [`zx_vmar_map()`]
- - [`zx_vmar_protect()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmar_allocate()`]: vmar_allocate.md
-[`zx_vmar_destroy()`]: vmar_destroy.md
-[`zx_vmar_map()`]: vmar_map.md
-[`zx_vmar_protect()`]: vmar_protect.md
diff --git a/docs/syscalls/vmar_unmap_handle_close_thread_exit.md b/docs/syscalls/vmar_unmap_handle_close_thread_exit.md
deleted file mode 100644
index ebcac23..0000000
--- a/docs/syscalls/vmar_unmap_handle_close_thread_exit.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# zx_vmar_unmap_handle_close_thread_exit
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmar_unmap_handle_close_thread_exit - unmap memory, close handle, exit
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmar_unmap_handle_close_thread_exit(zx_handle_t vmar_handle,
-                                                   zx_vaddr_t addr,
-                                                   size_t size,
-                                                   zx_handle_t close_handle);
-```
-
-## DESCRIPTION
-
-`zx_vmar_unmap_handle_close_thread_exit()` does a sequence of three operations:
-1. `zx_vmar_unmap(vmar_handle, addr, size)`
-2. `zx_handle_close(close_handle)`
-3. `zx_thread_exit()`
-
-The expectation is that the first operation unmaps a region including the
-calling thread's own stack.  (It's not required, but it's permitted.)  This
-is valid for this call, though it would be invalid for [`zx_vmar_unmap()`] or
-any other call.
-
-If the [`zx_vmar_unmap()`] operation is successful, then this call never returns.
-If *close_handle* is an invalid handle so that the [`zx_handle_close()`] operation
-fails, then the thread takes a trap (as if by `__builtin_trap();`).
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_vmar_unmap_handle_close_thread_exit()` does not return on success.
-
-## ERRORS
-
-Same as [`zx_vmar_unmap()`].
-
-## NOTES
-
-The intended use for this is for a dying thread to unmap its own stack,
-close its own thread handle, and exit.  The thread handle cannot be closed
-beforehand because closing the last handle to a thread kills that thread.
-The stack cannot be unmapped beforehand because the thread must have some
-stack space on which to make its final system calls.
-
-This call is used for detached threads, while
-[`zx_futex_wake_handle_close_thread_exit()`]
-is used for joinable threads.
-
-## SEE ALSO
-
- - [`zx_futex_wake_handle_close_thread_exit()`]
- - [`zx_handle_close()`]
- - [`zx_thread_exit()`]
- - [`zx_vmar_unmap()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_futex_wake_handle_close_thread_exit()`]: futex_wake_handle_close_thread_exit.md
-[`zx_handle_close()`]: handle_close.md
-[`zx_thread_exit()`]: thread_exit.md
-[`zx_vmar_unmap()`]: vmar_unmap.md
diff --git a/docs/syscalls/vmo_clone.md b/docs/syscalls/vmo_clone.md
deleted file mode 100644
index a031b90..0000000
--- a/docs/syscalls/vmo_clone.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# zx_vmo_clone
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_clone - create a clone of a VM Object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_clone(zx_handle_t handle,
-                         uint32_t options,
-                         uint64_t offset,
-                         uint64_t size,
-                         zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_vmo_clone()` creates a new virtual memory object (VMO) that clones a range
-of an existing vmo.
-
-One handle is returned on success, representing an object with the requested
-size.
-
-*options* must contain **ZX_VMO_CLONE_COPY_ON_WRITE** and zero or more flags to control
-clone creation.
-
-Valid flags:
-
-- **ZX_VMO_CLONE_COPY_ON_WRITE** - Create a copy-on-write clone. The cloned vmo will
-behave the same way the parent does, except that any write operation on the clone
-will bring in a copy of the page at the offset the write occurred. The new page in
-the cloned vmo is now a copy and may diverge from the parent. Any reads from
-ranges outside of the parent vmo's size will contain zeros, and writes will
-allocate new zero filled pages.  See the NOTES section below for details on
-VMO syscall interactions with clones.
-
-- **ZX_VMO_CLONE_NON_RESIZEABLE** - Create a non-resizeable clone VMO.
-
-*offset* must be page aligned.
-
-*offset* + *size* may not exceed the range of a 64bit unsigned value.
-
-Both offset and size may start or extend beyond the original VMO's size.
-
-The size of the VMO will be rounded up to the next page size boundary.
-
-By default the rights of the cloned handled will be the same as the
-original with a few exceptions. See [`zx_vmo_create()`] for a
-discussion of the details of each right.
-
-If *options* is **ZX_VMO_CLONE_COPY_ON_WRITE** the following rights are added:
-
-- **ZX_RIGHT_WRITE**
-
-## NOTES
-
-Cloning a VMO causes the existing (source) VMO **ZX_VMO_ZERO_CHILDREN** signal
-to become inactive. Only when the last clone is destroyed and no mappings
-of those clones into address spaces exist, will **ZX_VMO_ZERO_CHILDREN** become
-active again.
-
-### ZX_VMO_CLONE_COPY_ON_WRITE
-
-VMOs produced by this mode will interact with the VMO syscalls in the following
-ways:
-
-- The DECOMMIT and COMMIT modes of [`zx_vmo_op_range()`] on a clone will only affect pages
-  allocated to the clone, never its parent.
-- If a page in a clone is decommitted (e.g. with [`zx_vmo_op_range()`]), the parent's page will
-  become visible once again, still with copy-on-write semantics.
-- If a page is committed to a clone using the [`zx_vmo_op_range()`] COMMIT mode, a
-  the new page will have the same contents as the parent's corresponding page
-  (or zero-filled if no such page exists).
-- If the [`zx_vmo_op_range()`] LOOKUP mode is used, the parent's pages will be visible
-  where the clone has not modified them.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_DUPLICATE** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_vmo_clone()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ERR_BAD_TYPE**  Input handle is not a VMO.
-
-**ZX_ERR_ACCESS_DENIED**  Input handle does not have sufficient rights.
-
-**ZX_ERR_INVALID_ARGS**  *out* is an invalid pointer or NULL
-or the offset is not page aligned.
-
-**ZX_ERR_OUT_OF_RANGE**  *offset* + *size* is too large.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_vmar_map()`]
- - [`zx_vmo_create()`]
- - [`zx_vmo_get_size()`]
- - [`zx_vmo_op_range()`]
- - [`zx_vmo_read()`]
- - [`zx_vmo_set_size()`]
- - [`zx_vmo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmar_map()`]: vmar_map.md
-[`zx_vmo_create()`]: vmo_create.md
-[`zx_vmo_get_size()`]: vmo_get_size.md
-[`zx_vmo_op_range()`]: vmo_op_range.md
-[`zx_vmo_read()`]: vmo_read.md
-[`zx_vmo_set_size()`]: vmo_set_size.md
-[`zx_vmo_write()`]: vmo_write.md
diff --git a/docs/syscalls/vmo_create.md b/docs/syscalls/vmo_create.md
deleted file mode 100644
index 555edca..0000000
--- a/docs/syscalls/vmo_create.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# zx_vmo_create
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_create - create a VM object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_create(uint64_t size, uint32_t options, zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_vmo_create()` creates a new virtual memory object (VMO), which represents
-a container of zero to *size* bytes of memory managed by the operating
-system.
-
-The size of the VMO will be rounded up to the next page size boundary.
-Use [`zx_vmo_get_size()`] to return the current size of the VMO.
-
-One handle is returned on success, representing an object with the requested
-size.
-
-The following rights will be set on the handle by default:
-
-**ZX_RIGHT_DUPLICATE** - The handle may be duplicated.
-
-**ZX_RIGHT_TRANSFER** - The handle may be transferred to another process.
-
-**ZX_RIGHT_READ** - May be read from or mapped with read permissions.
-
-**ZX_RIGHT_WRITE** - May be written to or mapped with write permissions.
-
-**ZX_RIGHT_EXECUTE** - May be mapped with execute permissions.
-
-**ZX_RIGHT_MAP** - May be mapped.
-
-**ZX_RIGHT_GET_PROPERTY** - May get its properties using
-[object_get_property](object_get_property.md).
-
-**ZX_RIGHT_SET_PROPERTY** - May set its properties using
-[object_set_property](object_set_property.md).
-
-The *options* field can be 0 or **ZX_VMO_NON_RESIZABLE** to create a VMO
-that cannot change size. Clones of a non-resizable VMO can be resized.
-
-The **ZX_VMO_ZERO_CHILDREN** signal is active on a newly created VMO. It becomes
-inactive whenever a clone of the VMO is created and becomes active again when
-all clones have been destroyed and no mappings of those clones into address
-spaces exist.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_vmo_create()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_INVALID_ARGS**  *out* is an invalid pointer or NULL or *options* is
-any value other than 0.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_vmar_map()`]
- - [`zx_vmo_clone()`]
- - [`zx_vmo_get_size()`]
- - [`zx_vmo_op_range()`]
- - [`zx_vmo_read()`]
- - [`zx_vmo_set_size()`]
- - [`zx_vmo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmar_map()`]: vmar_map.md
-[`zx_vmo_clone()`]: vmo_clone.md
-[`zx_vmo_get_size()`]: vmo_get_size.md
-[`zx_vmo_op_range()`]: vmo_op_range.md
-[`zx_vmo_read()`]: vmo_read.md
-[`zx_vmo_set_size()`]: vmo_set_size.md
-[`zx_vmo_write()`]: vmo_write.md
diff --git a/docs/syscalls/vmo_create_contiguous.md b/docs/syscalls/vmo_create_contiguous.md
deleted file mode 100644
index 254a78d..0000000
--- a/docs/syscalls/vmo_create_contiguous.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# zx_vmo_create_contiguous
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_create_contiguous - TODO(ZX-3106)
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_create_contiguous(zx_handle_t bti,
-                                     size_t size,
-                                     uint32_t alignment_log2,
-                                     zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-TODO(ZX-3106)
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*bti* must be of type **ZX_OBJ_TYPE_BTI** and have **ZX_RIGHT_MAP**.
-
-## RETURN VALUE
-
-TODO(ZX-3106)
-
-## ERRORS
-
-TODO(ZX-3106)
-
-## SEE ALSO
-
-
-TODO(ZX-3106)
diff --git a/docs/syscalls/vmo_create_physical.md b/docs/syscalls/vmo_create_physical.md
deleted file mode 100644
index 5653905..0000000
--- a/docs/syscalls/vmo_create_physical.md
+++ /dev/null
@@ -1,93 +0,0 @@
-# zx_vmo_create_physical
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_create_physical - create a VM object referring to a specific contiguous range of physical memory
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_create_physical(zx_handle_t resource,
-                                   zx_paddr_t paddr,
-                                   size_t size,
-                                   zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_vmo_create_physical()` creates a new virtual memory object (VMO), which represents the
-*size* bytes of physical memory beginning at physical address *paddr*.
-
-One handle is returned on success, representing an object with the requested
-size.
-
-The following rights will be set on the handle by default:
-
-**ZX_RIGHT_DUPLICATE** - The handle may be duplicated.
-
-**ZX_RIGHT_TRANSFER** - The handle may be transferred to another process.
-
-**ZX_RIGHT_READ** - May be read from or mapped with read permissions.
-
-**ZX_RIGHT_WRITE** - May be written to or mapped with write permissions.
-
-**ZX_RIGHT_EXECUTE** - May be mapped with execute permissions.
-
-**ZX_RIGHT_MAP** - May be mapped.
-
-**ZX_RIGHT_GET_PROPERTY** - May get its properties using
-[object_get_property](object_get_property.md).
-
-**ZX_RIGHT_SET_PROPERTY** - May set its properties using
-[object_set_property](object_set_property.md).
-
-The **ZX_VMO_ZERO_CHILDREN** signal is active on a newly created VMO. It becomes
-inactive whenever a clone of the VMO is created and becomes active again when
-all clones have been destroyed and no mappings of those clones into address
-spaces exist.
-
-## NOTES
-
-The VMOs created by this syscall are not usable with [`zx_vmo_read()`] and
-[`zx_vmo_write()`].
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*resource* must have resource kind **ZX_RSRC_KIND_MMIO**.
-
-## RETURN VALUE
-
-`zx_vmo_create_physical()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZER_ERR_WRONG_TYPE** *resource* is not a handle to a Resource object.
-
-**ZER_ERR_ACCESS_DENIED** *resource* does not grant access to the requested
-range of memory.
-
-**ZX_ERR_INVALID_ARGS**  *out* is an invalid pointer or NULL, or *paddr* or
-*size* are not page-aligned.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_vmar_map()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmar_map()`]: vmar_map.md
-[`zx_vmo_read()`]: vmo_read.md
-[`zx_vmo_write()`]: vmo_write.md
diff --git a/docs/syscalls/vmo_get_size.md b/docs/syscalls/vmo_get_size.md
deleted file mode 100644
index bf3be66..0000000
--- a/docs/syscalls/vmo_get_size.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# zx_vmo_get_size
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_get_size - read the current size of a VMO object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_get_size(zx_handle_t handle, uint64_t* size);
-```
-
-## DESCRIPTION
-
-`zx_vmo_get_size()` returns the current size of the VMO.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-TODO(ZX-2399)
-
-## RETURN VALUE
-
-`zx_vmo_get_size()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a VMO handle.
-
-**ZX_ERR_INVALID_ARGS**  *size* is an invalid pointer or NULL.
-
-## SEE ALSO
-
- - [`zx_vmo_clone()`]
- - [`zx_vmo_create()`]
- - [`zx_vmo_op_range()`]
- - [`zx_vmo_read()`]
- - [`zx_vmo_set_size()`]
- - [`zx_vmo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmo_clone()`]: vmo_clone.md
-[`zx_vmo_create()`]: vmo_create.md
-[`zx_vmo_op_range()`]: vmo_op_range.md
-[`zx_vmo_read()`]: vmo_read.md
-[`zx_vmo_set_size()`]: vmo_set_size.md
-[`zx_vmo_write()`]: vmo_write.md
diff --git a/docs/syscalls/vmo_op_range.md b/docs/syscalls/vmo_op_range.md
deleted file mode 100644
index bc54c21..0000000
--- a/docs/syscalls/vmo_op_range.md
+++ /dev/null
@@ -1,115 +0,0 @@
-# zx_vmo_op_range
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_op_range - perform an operation on a range of a VMO
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_op_range(zx_handle_t handle,
-                            uint32_t op,
-                            uint64_t offset,
-                            uint64_t size,
-                            void* buffer,
-                            size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_vmo_op_range()` performs cache and memory operations against pages held by the VMO.
-
-*offset* byte offset specifying the starting location for *op* in the VMO's held memory.
-
-*size* length, in bytes, to perform the operation on.
-
-*op* the operation to perform:
-
-*buffer* and *buffer_size* are currently unused.
-
-**ZX_VMO_OP_COMMIT** - Commit *size* bytes worth of pages starting at byte *offset* for the VMO.
-More information can be found in the [vm object documentation](../objects/vm_object.md).
-Requires the **ZX_RIGHT_WRITE** right.
-
-**ZX_VMO_OP_DECOMMIT** - Release a range of pages previously committed to the VMO from *offset* to *offset*+*size*.
-Requires the **ZX_RIGHT_WRITE** right.
-
-**ZX_VMO_OP_LOCK** - Presently unsupported.
-
-**ZX_VMO_OP_UNLOCK** - Presently unsupported.
-
-**ZX_VMO_OP_CACHE_SYNC** - Performs a cache sync operation.
-Requires the **ZX_RIGHT_READ** right.
-
-**ZX_VMO_OP_CACHE_INVALIDATE** - Performs a cache invalidation operation.
-Requires the **ZX_RIGHT_WRITE** right.
-
-**ZX_VMO_OP_CACHE_CLEAN** - Performs a cache clean operation.
-Requires the **ZX_RIGHT_READ** right.
-
-**ZX_VMO_OP_CACHE_CLEAN_INVALIDATE** - Performs cache clean and invalidate operations together.
-Requires the **ZX_RIGHT_READ** right.
-
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-If *op* is **ZX_VMO_OP_COMMIT**, *handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_WRITE**.
-
-If *op* is **ZX_VMO_OP_DECOMMIT**, *handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_WRITE**.
-
-If *op* is **ZX_VMO_OP_CACHE_SYNC**, *handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_READ**.
-
-If *op* is **ZX_VMO_OP_CACHE_INVALIDATE**, *handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_WRITE**.
-
-If *op* is **ZX_VMO_OP_CACHE_CLEAN**, *handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_READ**.
-
-If *op* is **ZX_VMO_OP_CACHE_CLEAN_INVALIDATE**, *handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_vmo_op_range()` returns **ZX_OK** on success. In the event of failure, a negative error
-value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_OUT_OF_RANGE**  An invalid memory range specified by *offset* and *size*.
-
-**ZX_ERR_NO_MEMORY**  Allocations to commit pages for **ZX_VMO_OP_COMMIT** failed.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a VMO handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have sufficient rights to perform the operation.
-
-**ZX_ERR_INVALID_ARGS**  *out* is an invalid pointer, *op* is not a valid
-operation, or *size* is zero and *op* is a cache operation.
-
-**ZX_ERR_NOT_SUPPORTED**  *op* was **ZX_VMO_OP_LOCK** or **ZX_VMO_OP_UNLOCK**, or
-*op* was **ZX_VMO_OP_DECOMMIT** and the underlying VMO does not allow decommiting.
-
-## SEE ALSO
-
- - [`zx_vmo_clone()`]
- - [`zx_vmo_create()`]
- - [`zx_vmo_get_size()`]
- - [`zx_vmo_read()`]
- - [`zx_vmo_set_size()`]
- - [`zx_vmo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmo_clone()`]: vmo_clone.md
-[`zx_vmo_create()`]: vmo_create.md
-[`zx_vmo_get_size()`]: vmo_get_size.md
-[`zx_vmo_read()`]: vmo_read.md
-[`zx_vmo_set_size()`]: vmo_set_size.md
-[`zx_vmo_write()`]: vmo_write.md
diff --git a/docs/syscalls/vmo_read.md b/docs/syscalls/vmo_read.md
deleted file mode 100644
index 34b9676..0000000
--- a/docs/syscalls/vmo_read.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# zx_vmo_read
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_read - read bytes from the VMO
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_read(zx_handle_t handle,
-                        void* buffer,
-                        uint64_t offset,
-                        size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_vmo_read()` attempts to read exactly *buffer_size* bytes from a VMO at *offset*.
-
-*buffer* pointer to a user buffer to read bytes into.
-
-*buffer_size* number of bytes to attempt to read. *buffer* buffer should be large
-enough for at least this many bytes.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_READ**.
-
-## RETURN VALUE
-
-`zx_vmo_read()` returns **ZX_OK** on success, and exactly *buffer_size* bytes will
-have been written to *buffer*.
-In the event of failure, a negative error value is returned, and the number of
-bytes written to *buffer* is undefined.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a VMO handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have the **ZX_RIGHT_READ** right.
-
-**ZX_ERR_INVALID_ARGS**  *buffer* is an invalid pointer or NULL.
-
-**ZX_ERR_OUT_OF_RANGE**  *offset* starts at or beyond the end of the VMO,
-                         or VMO is shorter than *buffer_size*.
-
-**ZX_ERR_BAD_STATE**  VMO has been marked uncached and is not directly readable.
-
-## SEE ALSO
-
- - [`zx_vmo_clone()`]
- - [`zx_vmo_create()`]
- - [`zx_vmo_get_size()`]
- - [`zx_vmo_op_range()`]
- - [`zx_vmo_set_cache_policy()`]
- - [`zx_vmo_set_size()`]
- - [`zx_vmo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmo_clone()`]: vmo_clone.md
-[`zx_vmo_create()`]: vmo_create.md
-[`zx_vmo_get_size()`]: vmo_get_size.md
-[`zx_vmo_op_range()`]: vmo_op_range.md
-[`zx_vmo_set_cache_policy()`]: vmo_set_cache_policy.md
-[`zx_vmo_set_size()`]: vmo_set_size.md
-[`zx_vmo_write()`]: vmo_write.md
diff --git a/docs/syscalls/vmo_replace_as_executable.md b/docs/syscalls/vmo_replace_as_executable.md
deleted file mode 100644
index 107ab24..0000000
--- a/docs/syscalls/vmo_replace_as_executable.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# zx_vmo_replace_as_executable
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_replace_as_executable - add execute rights to a vmo
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_replace_as_executable(zx_handle_t handle,
-                                         zx_handle_t vmex,
-                                         zx_handle_t* out);
-```
-
-## DESCRIPTION
-
-`zx_vmo_replace_as_executable()` creates a replacement for *handle*, referring
-to the same underlying VM object, adding the right **ZX_RIGHT_EXECUTE**.
-
-*handle* is always invalidated.
-
-*vmex* may currently be **ZX_HANDLE_INVALID** to ease migration of new code,
-this is TODO(SEC-42) and will be removed.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VMO**.
-
-*vmex* must have resource kind **ZX_RSRC_KIND_VMEX**.
-
-## RETURN VALUE
-
-`zx_vmo_replace_as_executable()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* isn't a valid VM object handle, or
-*vmex* isn't a valid **ZX_RSRC_KIND_VMEX** resource handle.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
-There is no good way for userspace to handle this (unlikely) error.
-In a future build this error will no longer occur.
-
-## SEE ALSO
-
- - [`zx_resource_create()`]
- - [`zx_vmar_map()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_resource_create()`]: resource_create.md
-[`zx_vmar_map()`]: vmar_map.md
diff --git a/docs/syscalls/vmo_set_cache_policy.md b/docs/syscalls/vmo_set_cache_policy.md
deleted file mode 100644
index ebb3162..0000000
--- a/docs/syscalls/vmo_set_cache_policy.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# zx_vmo_set_cache_policy
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_set_cache_policy - set the caching policy for pages held by a VMO.
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_set_cache_policy(zx_handle_t handle, uint32_t cache_policy);
-```
-
-## DESCRIPTION
-
-`zx_vmo_set_cache_policy()` sets caching policy for a VMO. Generally used on VMOs
-that point directly at physical memory. Such VMOs are generally only handed to
-userspace via bus protocol interfaces, so this syscall will typically only be
-used by drivers dealing with device memory. This call can also be used on a
-regular memory backed VMO with similar limitations and uses.
-
-A handle must have the **ZX_RIGHT_MAP** right for this call to be
-permitted. Additionally, the VMO must not presently be mapped by any process,
-be cloned, be a clone itself, or have any memory committed.
-
-*cache_policy* cache flags to use:
-
-**ZX_CACHE_POLICY_CACHED** - Use hardware caching.
-
-**ZX_CACHE_POLICY_UNCACHED** - Disable caching.
-
-**ZX_CACHE_POLICY_UNCACHED_DEVICE** - Disable cache and treat as device memory.
-This is architecture dependent and may be equivalent to
-**ZX_CACHE_POLICY_UNCACHED** on some architectures.
-
-**ZX_CACHE_POLICY_WRITE_COMBINING** - Uncached with write combining.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_MAP**.
-
-## RETURN VALUE
-
-`zx_vmo_set_cache_policy()` returns **ZX_OK** on success. In the event of
-failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_ACCESS_DENIED** Cache policy has been configured for this VMO already and
-may not be changed, or *handle* lacks the **ZX_RIGHT_MAP** right.
-
-**ZX_ERR_BAD_HANDLE** *handle* is not a valid handle.
-
-**ZX_ERR_INVALID_ARGS** *cache_policy* contains flags outside of the ones listed
-above, or *cache_policy* contains an invalid mix of cache policy flags.
-
-**ZX_ERR_NOT_SUPPORTED** The VMO *handle* corresponds to is not one holding
-physical memory.
-
-**ZX_ERR_BAD_STATE** Cache policy cannot be changed because the VMO is presently
-mapped, cloned, a clone itself, or have any memory committed.
-
-## SEE ALSO
-
- - [`zx_vmo_create()`]
- - [`zx_vmo_get_size()`]
- - [`zx_vmo_op_range()`]
- - [`zx_vmo_read()`]
- - [`zx_vmo_set_size()`]
- - [`zx_vmo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmo_create()`]: vmo_create.md
-[`zx_vmo_get_size()`]: vmo_get_size.md
-[`zx_vmo_op_range()`]: vmo_op_range.md
-[`zx_vmo_read()`]: vmo_read.md
-[`zx_vmo_set_size()`]: vmo_set_size.md
-[`zx_vmo_write()`]: vmo_write.md
diff --git a/docs/syscalls/vmo_set_size.md b/docs/syscalls/vmo_set_size.md
deleted file mode 100644
index c26af1b..0000000
--- a/docs/syscalls/vmo_set_size.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# zx_vmo_set_size
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_set_size - resize a VMO object
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_set_size(zx_handle_t handle, uint64_t size);
-```
-
-## DESCRIPTION
-
-`zx_vmo_set_size()` sets the new size of a VMO object.
-
-The size will be rounded up to the next page size boundary.
-Subsequent calls to [`zx_vmo_get_size()`] will return the rounded up size.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_vmo_set_size()` returns **ZX_OK** on success. In the event
-of failure, a negative error value is returned.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a VMO handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have the **ZX_RIGHT_WRITE** right.
-
-**ZX_ERR_UNAVAILABLE** The VMO was created with **ZX_VMO_NON_RESIZABLE** option.
-
-**ZX_ERR_OUT_OF_RANGE**  Requested size is too large.
-
-**ZX_ERR_NO_MEMORY**  Failure due to lack of system memory.
-
-## SEE ALSO
-
- - [`zx_vmo_clone()`]
- - [`zx_vmo_create()`]
- - [`zx_vmo_get_size()`]
- - [`zx_vmo_op_range()`]
- - [`zx_vmo_read()`]
- - [`zx_vmo_write()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmo_clone()`]: vmo_clone.md
-[`zx_vmo_create()`]: vmo_create.md
-[`zx_vmo_get_size()`]: vmo_get_size.md
-[`zx_vmo_op_range()`]: vmo_op_range.md
-[`zx_vmo_read()`]: vmo_read.md
-[`zx_vmo_write()`]: vmo_write.md
diff --git a/docs/syscalls/vmo_write.md b/docs/syscalls/vmo_write.md
deleted file mode 100644
index 4599df9..0000000
--- a/docs/syscalls/vmo_write.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# zx_vmo_write
-
-## NAME
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-vmo_write - write bytes to the VMO
-
-## SYNOPSIS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-```
-#include <zircon/syscalls.h>
-
-zx_status_t zx_vmo_write(zx_handle_t handle,
-                         const void* buffer,
-                         uint64_t offset,
-                         size_t buffer_size);
-```
-
-## DESCRIPTION
-
-`zx_vmo_write()` attempts to write exactly *buffer_size* bytes to a VMO at *offset*.
-
-*buffer* pointer to a user buffer to write bytes from.
-
-*buffer_size* number of bytes to attempt to write.
-
-## RIGHTS
-
-<!-- Updated by update-docs-from-abigen, do not edit. -->
-
-*handle* must be of type **ZX_OBJ_TYPE_VMO** and have **ZX_RIGHT_WRITE**.
-
-## RETURN VALUE
-
-`zx_vmo_write()` returns **ZX_OK** on success, and exactly *buffer_size* bytes will
-have been written from *buffer*.
-In the event of failure, a negative error value is returned, and the number of
-bytes written from *buffer* is undefined.
-
-## ERRORS
-
-**ZX_ERR_BAD_HANDLE**  *handle* is not a valid handle.
-
-**ZX_ERR_WRONG_TYPE**  *handle* is not a VMO handle.
-
-**ZX_ERR_ACCESS_DENIED**  *handle* does not have the **ZX_RIGHT_WRITE** right.
-
-**ZX_ERR_INVALID_ARGS**  *buffer* is an invalid pointer or NULL.
-
-**ZX_ERR_NO_MEMORY**  Failure to allocate system memory to complete write.
-
-**ZX_ERR_OUT_OF_RANGE**  *offset* starts at or beyond the end of the VMO,
-                         or VMO is shorter than *buffer_size*.
-
-**ZX_ERR_BAD_STATE**  VMO has been marked uncached and is not directly writable.
-
-## SEE ALSO
-
- - [`zx_vmo_clone()`]
- - [`zx_vmo_create()`]
- - [`zx_vmo_get_size()`]
- - [`zx_vmo_op_range()`]
- - [`zx_vmo_read()`]
- - [`zx_vmo_set_cache_policy()`]
- - [`zx_vmo_set_size()`]
-
-<!-- References updated by update-docs-from-abigen, do not edit. -->
-
-[`zx_vmo_clone()`]: vmo_clone.md
-[`zx_vmo_create()`]: vmo_create.md
-[`zx_vmo_get_size()`]: vmo_get_size.md
-[`zx_vmo_op_range()`]: vmo_op_range.md
-[`zx_vmo_read()`]: vmo_read.md
-[`zx_vmo_set_cache_policy()`]: vmo_set_cache_policy.md
-[`zx_vmo_set_size()`]: vmo_set_size.md
diff --git a/docs/sysret_problem.md b/docs/sysret_problem.md
deleted file mode 100644
index 302569a..0000000
--- a/docs/sysret_problem.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Avoiding a problem with the SYSRET instruction
-
-On x86-64, the kernel uses the SYSRET instruction to return from system
-calls.  We must be careful not to use a non-canonical return address with
-SYSRET, at least on Intel CPUs, because this causes the SYSRET instruction
-to fault in kernel mode, which is potentially unsafe.  (In contrast, on AMD
-CPUs, SYSRET faults in user mode when used with a non-canonical return
-address.)
-
-Usually, the lowest non-negative non-canonical address is 0x0000800000000000
-(== 1 << 47).  One way that a user process could cause the syscall return
-address to be non-canonical is by mapping a 4k executable page immediately
-below that address (at 0x00007ffffffff000), putting a SYSCALL instruction
-at the end of that page, and executing the SYSCALL instruction.
-
-To avoid this problem:
-
-* We disallow mapping a page when the virtual address of the following page
-  will be non-canonical.
-
-* We disallow setting the RIP register to a non-canonical address using
-  **zx_thread_write_state**() when the address would be used with SYSRET.
-
-For more background, see "A Stitch In Time Saves Nine: A Case Of Multiple
-OS Vulnerability", Rafal Wojtczuk
-(https://media.blackhat.com/bh-us-12/Briefings/Wojtczuk/BH_US_12_Wojtczuk_A_Stitch_In_Time_WP.pdf).
diff --git a/docs/targets/acer12.md b/docs/targets/acer12.md
deleted file mode 100644
index b65b41c..0000000
--- a/docs/targets/acer12.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Acer Switch Alpha 12
-
-WARNING:  These are directions to configure the machine and boot an experimental, in-development OS on it.
-
-## Powering the Machine On
-To power on you must hold the power button (lefthand side, above the Volume rocker) for several seconds, then let go.  You can safely let go when the tiny blue light on the power button itself turns on (yes, this is really hard to see when you’re holding the power button), or when the display backlight turns on.  If you hold too long it may end up power right back off again.
-
-## Powering the Machine Off
-If you boot into Windows 10 or something hangs or crashes and you need to power things off, Press and Hold the power button until the display shuts off.  To be sure, hold for about 10 seconds total.
-
-## Entering the BIOS
-With the machine off, Press and hold Volume Up, then continue to hold while pressing and holding the Power button.  Let go of the Power button when the display backlight turns on.  Alternatively, hold F2 on an attached keyboard while powering the machine on.
-
-## Enabling Zircon Boot
-1. Boot the machine and enter the BIOS
-2. Select “Security” from the tabs at the left
-3. Tap the “[clean]” gray bar under “Supervisor Password Is”
-4. Enter a supervisor password, enter it again, press OK
-5. Select “Boot” from the tabs at the left
-6. Tap the “[Enabled]” gray bar under “Secure Boot”
-    (if there’s no gray bar, you have not set a supervisor password, go back and do that now)
-7. Select “Disabled” from the menu
-8. The “Boot priority order” list may be adjusted using the up/down arrows to the right of each item
-9. Order the list like so:
-- USB HDD
-- USB FDD
-- USB CDROM
-- HDD: <MFG> <SERIALNO>
-- Network Boot-IPV4
-- Network Boot-IPV6
-- Windows Boot Manager
-10. Select the “Main” tab on the left and set the time and date by pressing “[SetTime]” and “[SetDate]” buttons respectfully. This is necessary for proper network operation.
-11. (Optional)  Go back to the “Security” tab and set the supervisor password back to nothing.
-Otherwise you’ll need to enter the password every time you use the BIOS.
-A password is required to modify the secure boot setting, but “disabled” will persist without one.
-12. Select “Exit” from the tabs at the left
-13. Select “Exit Saving Changes”
-14. Continue to [Setup with USB flash drive](usb_setup.md)
-
-## What if you end up in the Windows 10 Setup?
-If you don’t enter the BIOS and haven’t installed another OS, You’ll end up on a blue background “Hi there” screen asking you to select country, language, etc.
-
-1. Press Power and Hold it for about 10 seconds (the screen will turn off after 2-3 seconds).
-2. Boot into the BIOS as described above.
-
-## What if you get stuck in Windows 10 Recovery?
-It’s possible to end up in a situation where the machine *really* wants to help you recover your failed boots into Windows 10 and dumps you into a recovery screen -- blue background, “Recovery” in the upper left, and some text saying “It looks like Windows didn’t load correctly”.
-
-1. Select “See advanced repair options”
-2. Select “Troubleshoot” (screwdriver and wrench icon)
-3. Select “Advanced options” (checkmarks and lines icon)
-4. Select “UEFI Firmware Settings” (integrated circuit and gear icon)
-5. When prompted “Restart to change UEFI firmware settings”, select “Restart”
-6. The machine should now reboot into the BIOS
-7. Check that “Windows Boot Manager” didn’t get moved to the top of the boot order, fix it if it did
-
-## Quirks
-It has been observed that USB initialization is racy on a cold boot.  So if you're starting from a cold boot and trying to boot to USB, you may find that you boot to disk instead.
-
-Mitigations:
-- It's useful to use a `cmdline` file to set `zircon.nodename=foo` to know during the boot screen whether you're booting from USB or disk.
-- If the Acer is booting from disk and you want to boot from USB, remove and reinsert the USB drive, then reboot with `ctrl-alt-del` (not the power button.)
-- You can tell from the bios whether USB has been initialized because it will name the USB device.
diff --git a/docs/targets/hikey960.md b/docs/targets/hikey960.md
deleted file mode 100644
index 9511b58..0000000
--- a/docs/targets/hikey960.md
+++ /dev/null
@@ -1,296 +0,0 @@
-#  Zircon on HiKey960 (96boards.org)
-Periodically check this file as the setup workflow will change/improve.
-
-
-## Requirements
-
-__The following hardware is required:__
-
-+ HiKey960 board
-+ Power adapter (most will require a DC plug converter -- more info
-  [here](http://www.96boards.org/product/hikey960/))
-+ USB-C cable (to connect to workstation for flashing the board)
-+ One of the following (to connect to workstation for serial console):
-  + (Recommended)
-    [Mezzanine board](https://www.seeedstudio.com/96Boards-UART-p-2525.html),
-    plus a micro-USB cable (not included with mezzanine board), or
-  + (Alternate) [1.8v FTDI Serial Adapter
-    cable](https://www.digikey.com/products/en?keywords=768-1070-ND)
-
-__The following software is required:__
-
-+ `fastboot`
-
-  To install on Ubuntu: `sudo apt-get install android-tools-fastboot`
-
-## Overview
-
-At a high level, these are the steps for getting a HiKey development environment
-fully working:
-
-+ Build a Zircon boot image
-+ Enable the serial console (useful for debugging subsequent steps)
-+ Flash the HiKey's low-level firmware
-+ Flash the Zircon boot image onto the HiKey (this image -- specifically
-  zedboot -- will receive and boot your subsequent Fuchsia builds)
-+ Build and boot Fuchsia
-
-Once the system is correctly configured, your development workflow should
-resemble a workflow on other hardware (repeated builds done with `fx build`,
-a persistent instance of `fx pave` to automatically update the hardware, and a
-persistent instance of `fx log` to capture console output).
-
-
-## Useful Information
-
-+ [HiKey960 Development Board User Manual](https://www.96boards.org/documentation/ConsumerEdition/HiKey960/HardwareDocs/HardwareUserManual.md.html)
-+ [96boards-hikey github page](https://github.com/96boards-hikey)
-+ [96boards Getting Started page](https://www.96boards.org/documentation/ConsumerEdition/HiKey960/GettingStarted/)
-+ [SoC Reference](https://github.com/96boards/documentation/raw/master/ConsumerEdition/HiKey960/HardwareDocs/HiKey960_SoC_Reference_Manual.pdf)
-+ [AOSP HiKey960 Information](https://source.android.com/source/devices#hikey960)
-+ [HiKey960 Schematic](http://www.lemaker.org/product-hikeysecond-download-62.html)
-
-## Building the Zircon boot image
-
-To build zircon, invoke the following command from the top level Zircon
-directory (ensure that you have checked out the ARM64 toolchains). For more
-information, see `docs/getting_started.md`:
-
-      make arm64
-
-
-## Setting up the serial console
-
-First, get the device to show up on your dev host machine as a serial device.
-Following that, install and configure a console app.
-
-#### Serial hardware setup
-
-If using a __mezzanine board__, follow the instructions included with it.
-Additional tips:
-
-  + Take care not to install the mezzanine board backwards on the connector. The
-  micro-USB port should face outward; the corner pushbutton should be in the
-  center of the HiKey board.
-
-  + Some standard micro-USB cables have a button to enable/disable the data
-  lines. When using one of these cables, ensure that these lines are enabled -
-  the LED should be _amber_ (not green).
-
-  + The mezzanine board receives power through the micro-USB cable, so power
-  need not be applied to the main HiKey board yet.
-
-If using a __FTDI-style serial adapter cable__:
-
-  + The signals are available on the 40 pin LS connector
-([reference](https://raw.githubusercontent.com/96boards/documentation/master/ConsumerEdition/HiKey960/AdditionalDocs/Images/Images_HWUserManual/HiKey960_Numbered_Front2.png))
-    + Pin 1  - GND
-    + Pin 11 - UART TX (HiKey960 --> Host)
-    + PIN 13 - UART RX (HiKey960 <-- Host)
-
-
-  + This means that for a common [FTDI style adapter](https://www.digikey.com/products/en?keywords=768-1070-ND):
-    + Black  --> Pin1
-    + Yellow --> Pin11
-    + Orange --> Pin13
-
-
-  + (Optional) an active low reset is available on pin 6 of the 40 pin LS
-  connector. A jumper wire intermittently shorted from this pin to GND (shields
-  of the connectors are all grounded) can provide an easy way to reset the board
-  and place it in fastboot mode.
-
-Once you have correctly configured the hardware (via either method), the device
-should appear to your host machine as a USB-connected UART, listed in your /dev
-directory as `/dev/ttyUSB0` (or USB1, etc). If this is _not_ the case, you may
-have forgotten to enable the data lines (LED should be amber), or you may have a
-bad micro-USB cable or mezzanine board. Regardless, do not proceed until your
-HiKey board is detected and enumerated in the `/dev` directory as a tty device.
-
-#### Serial console software
-
-Use a host application such as screen or putty to connect to the serial port and
-provide console functionality. Use a baud rate of 115200.
-
-Example commands using **screen**:
-  + `screen /dev/ttyUSB0 115200,-ixoff`
-  + `Ctrl-a, Esc` to enable scrolling (then k-up, j-down, q-done scrolling)
-  + `Ctrl-a, d` to detach from the session (`screen -r -d` to reattach)
-  + `Ctrl-a, \` to kill all screen sessions.
-
-If you receive an error when connecting to your tty/USBn, you may need to run
-your serial console application as `sudo`. Alternately, you can add a udev rule
-that allows applications to connect to this device:
-
-  + Create file `/etc/udev/rules.d/99-ttyusb.rules` containing the following:
-
-    `SUBSYSTEM=="tty", GROUP="dialout"`
-
-  + Then `sudo udevadm control --reload-rules`
-
-
-## Entering fastboot mode
-##### (needed for flashing low-level firmware and/or Zircon)
-
-Connect the power supply if you have not already. If the power plug doesn't
-seem to fit, you may have forgotten to get a DC adapter. The power plug for the
-HiKey boards has a 4.75mm diameter and 1.7mm center pin, whereas most DC power
-supplies in this class have a 5.5mm diameter and 2.1mm center pin.
-
-To flash the board, it must be connected to your workstation via the USB-C OTG
-connection on the HiKey960 main board. Additionally, the HiKey960 must be in
-fastboot mode. You can enter fastboot in one of two ways:
-
-+ __DIP Switch method__  Use the switches on the back of the board. (Older
-  HiKeys may have jumpers instead of DIP switches.) To boot into fastboot mode,
-  the switches should be in the following positions:
-
-        Auto Power up(Switch 1)   closed/ON
-        Recovery(Switch 2)        open/OFF
-        Fastboot(Switch 3)        closed/ON
-
-  Once the switches are in these positions, unplug/plug power or reset the
-  board. It will then boot into _fastboot_ mode, awaiting commands from the
-  host. If you are using the serial adapter cable, just a reminder that this can
-  be done with the jumper wire on pin 6, as mentioned earlier.
-
-  Note: after you have performed the last of your flash operations, you want the
-  device to boot normally going forward, so you should open (turn OFF) DIP
-  switch 3 _before_ your final boot (once firmware and Zircon updates are
-  complete, before booting into Zircon for the first time).
-
-+ __Double-Reset method__  Using the button on the mezzanine board, reset the
-  board, then reset it _again_ after seeing the following console messages:
-
-        C3R,V0x00000016 e:113
-        C0R,V0x00000017 e:66
-        C1R,V0x00000017 e:66
-        C2R,V0x00000017 e:66
-        C3R,V0x00000017 e:66
-
-  The second reset instructs the board to restart into fastboot __for the next
-  boot cycle only__. The timing on this double-reset is a little tricky, but you
-  will know you got the timing right if you see the following console messages
-  at the end of the boot spew:
-
-        usbloader: bootmode is 4
-        usb: [USBFINFO]USB RESET
-        usb: [USBFINFO]USB CONNDONE, highspeed
-        usb: [USBFINFO]USB RESET
-        usb: [USBFINFO]USB CONNDONE, highspeed
-        usbloader: usb: online (highspeed)
-        usb: [USBFINFO]usb enum done
-
-  These messages confirm that the device has restarted into fastboot mode. If
-  you do not see these messages, use the button to reset the board and try again
-  until you are successful.
-
-  As a reminder, with this method, the DIP switches on the HiKey should remain
-  in _normal_ mode (closed/ON open/OFF open/OFF), not the 'fastboot' mode
-  mentioned in the previous option.
-
-Once the board is in fastboot mode (regardless of which method you use), it is
-ready to be flashed with firmware updates and/or the Zircon boot image.
-
-## Install Firmware
-
-We have run into inconsistent behavior between different HiKey 960 boards,
-depending on the low level firmware came installed on the device. We recommend
-setting up your board with known good firmware from the Android AOSP project.
-
-To install firmware, put your board in fastboot mode and run the following:
-
-      ./scripts/flash-hikey -f
-
-## Recover the device
-
-If the hikey gets into a bad state you can try the recovery mechanism.
-The script should automate the process, including reinstalling the firmware. You
-first need to put the device into recovery mode:
-
-        Auto Power up(Switch 1)   closed/ON
-        Recovery(Switch 2)        closed/ON
-        Fastboot(Switch 3)        open/OFF
-
-Then run:
-
-      ./scripts/flash-hikey -r
-
-The recovery process communicates with the device over the USB-C cable, but it
-can be a bit flaky at times. If the script complains that it can't open the
-serial device first check what serial devices are connected (`ls
-/dev/serial/by-id/`) and make sure the script is using the correct device. You
-can specify which serial port to use with `-p`. Sometimes you just need to try a
-few times or power cycle the device. Occasionally the script will fail when
-attempting to install firmware, which can usually be fixed by starting again.
-
-## Installing Zircon
-
-Once the HiKey board is in fastboot mode, run the following script from the
-zircon root directory to flash the necessary files onto the board:
-
-      ./scripts/flash-hikey
-
-## Zedboot
-
-If you would like to boot future kernels via the network, instead of flashing
-them directly, then run the script with the `-m` option.
-
-      ./scripts/flash-hikey -m
-
-This is the last flash update, and all subsequent boots should use normal mode
-(not fastboot or recovery). If you used the DIP Switch method to place the board
-in fastboot mode, you should flip the fastboot switch (switch 3) back to
-open/OFF _before_ running this script, so that it will boot into Zircon after
-flashing (otherwise, it will boot back into fastboot mode).
-
-If you used the double-tap reset method to place the board into fastboot mode,
-no further reconfiguration is needed: the board will boot into the kernel after
-it completes flashing.
-
-For now, the ethernet connectivity needed for zedboot is actually provided by
-zircon via USB. This is automatically enabled on the HiKey USB-C connector, if
-it is changed from host mode into device mode. If all flash steps appear to
-complete successfully, but the device does not restart into Zedboot, you may
-need to manually place the device into USB 'device' mode. Enter the following
-command in your console:
-
-      usbctl mode device
-
-This step must be repeated each time the device is fully powered-down/up. At
-some point in the near future, the Fuchsia build will include support for USB
-NICs via USB-A, at which time this `usbctl` step will be unnecessary.
-
-Once your device restarts and displays 'Zedboot' in the console, the setup
-process is complete. You can now use your usual build, boot and log commands.
-When powering up (not simply resetting) the device, you may need to press the
-reset button for the device to show up again as /dev/ttyUSBn. Recall that this
-is needed before connecting the serial console and interacting with the device.
-
-
-## Manually Installing Low-Level Firmware
-
-Note: the following requires fastboot in your execution path.
-
-To install firmware, put your board in fastboot mode and run the following:
-
-      git clone https://android.googlesource.com/device/linaro/hikey hikey-firmware
-      git -C hikey-firmware checkout 972114436628f874ac9ca28ef38ba82862937fbf
-      fastboot flash ptable hikey-firmware/installer/hikey960/ptable.img
-      fastboot flash xloader hikey-firmware/installer/hikey960/sec_xloader.img
-      fastboot flash fastboot hikey-firmware/installer/hikey960/fastboot.img
-      fastboot flash nvme hikey-firmware/installer/hikey960/nvme.img
-      fastboot flash fw_lpm3 hikey-firmware/installer/hikey960/lpm3.img
-      fastboot flash trustfirmware hikey-firmware/installer/hikey960/bl31.bin
-
-This installs all the AOSP firmware except Android itself. To use a different
-bootloader altogether (not the one from AOSP), first complete the above commands
-and then install your bootloader.
-
-## Device support
-
-The console is especially important because the HiKey builds of Fuchsia do not
-yet support the HDMI port. Related to this, only USB is supported for audio
-input/output. NOTE: all USB audio devices must be High-Speed (not just USB 2.0
-compatible, which might be Full-Speed or High-Speed). If the USB audio device
-is enumerated as 12Mb/s, then it is Full-Speed.
diff --git a/docs/targets/imx8mevk.md b/docs/targets/imx8mevk.md
deleted file mode 100644
index f0e42f7..0000000
--- a/docs/targets/imx8mevk.md
+++ /dev/null
@@ -1,53 +0,0 @@
-#  Zircon on iMX8M EVK
-Periodically check this file as the setup workflow will change/improve.
-
-
-Please refer to the following documents for SoC and board related information:
-
-i.MX 8M EVK Board Hardawre User's Guide:
-https://www.nxp.com/docs/en/user-guide/IMX8MDQLQEVKHUG.pdf
-
-iMX8M Technical Reference Manual:
-https://www.nxp.com/docs/en/reference-manual/IMX8MDQLQRM.pdf
-
-u-Boot Source:
-https://source.codeaurora.org/external/imx/uboot-imx/
-https://source.codeaurora.org/external/imx/uboot-imx/log/?h=imx_v2017.03_4.9.51_imx8m_ga
-
-## Flashing Zircon on eMMC:
-
-The board will boot out of eMMC by default. In order to boot Zircon, a custom u-boot binary
-is needed. The binary can be found at: go/imx8m-bootloader
-
-First step involves flashing the board with the custom u-boot binary:
-
-# Requirements:
- + Linux Host Machine
- + For serial console: connect USB from your host to the Micro USB port on the board
- + For fastboot: connect USB cable from your host to the USB-C port on the board
- + Create a file under /etc/udev/rules.d/70-nxp.rules with the following content:
-
- SUBSYSTEM=="usb", ATTR{idVendor}=="0525", MODE="0664", GROUP="plugdev", TAG+="uaccess"
-
-
-# From Device (iMX8 EVK):
-
-+ Reboot board and in serial console press space to halt autoboot
-+ From u-boot command line do the following:
-    + fastboot 0
-
-# From Linux Host:
- + fastboot flash bootloader0 /PATH/TO/CUSTOM/UBOOT/u-boot.imx
- + fastboot reboot
-
- If successful, the new U-Boot prompt should be "zircon-u-boot=>"
-
-Once the custom U-Boot has been flashed, perform the following:
-+ Reboot board and press space to halt autoboot
-+ From u-boot command line do the following:
-    + fastboot 0
-
-From the host side, go to your zircon repository and run the following command:
-+ ./scripts/flash-nxp
-
-If successful, the board will reboot into Zircon.
diff --git a/docs/targets/khadas-vim.md b/docs/targets/khadas-vim.md
deleted file mode 100644
index c8c68fc..0000000
--- a/docs/targets/khadas-vim.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# Zircon on Khadas VIM2 Board
-
-This document describes running Zircon on the Khadas VIM2 board.
-Additional documentation can be found at [docs.khadas.com](http://docs.khadas.com/)
-
-When describing the location of buttons, pins and other items on the board,
-we will refer to the side with the USB, ethernet and HDMI connectors as the front of the board
-and the opposite side the back of the board.
-
-## Heat Sink
-
-Before you start, you need a heat sink. A passive chip heat sink will allow you
-to run 2 cores out of 8 at full speed before reaching 80C, the critical
-temperature at which cores have to be throttled down.
-
-## Setup
-
-- USB C port: Connect to host. Provides power and `fastboot`.
-- Ethernet: Connect cable directly to board (do not use a USB ethernet adapter).
-- HDMI: Optional. Connects to display.
-- Serial Console: Optional but very useful. See next section.
-
-## Serial Console
-
-The debug UART for the serial console is exposed on the 40 pin header at the back of the board.
-You may use a 3.3v FTDI USB to serial cable to access the serial console.
-On the front row of the header:
-
-- 2nd from right: TX (Yellow wire)
-- 3rd from right: RX (Orange wire)
-- 4th from right: Ground (Black wire)
-
-For FTDI serial cables with black, white, red and green wires, use this:
-
-- 2nd from right: TX (White wire)
-- 3rd from right: RX (Green wire)
-- 4th from right: Ground (Black wire)
-
-In [this diagram](http://docs.khadas.com/vim1/GPIOPinout.html) of the 40 pin header,
-these correspond to pins 17 through 19.
-
-## Buttons
-
-The VIM2 has 3 buttons on the left side of the board. On the board schematic, SW1 (switch closest to the USB plug) is the reset switch. SW3 (farthest away from the USB plug on the schematic) can be used for entering flashing mode. If SW3 is held down while the board is reset or power cycled , the bootloader will enter flashing mode instead of booting the kernel normally.
-
-## VIM2 Bootloader
-
-Booting Zircon on the VIM2 requires a custom bootloader.
-
-### [Googlers only]
-Within Google, this can be found at [go/vim2-bootloader](http://go/vim2-bootloader). Download the .bin file and follow the instructions in the document.
-
-If you are not at Google, hang on until we make this publicly available.
-
-To find out what version of the bootloader you have, grep for "fuchsia-bootloader"
-in the kernel boot log. You should see something like: "cmdline: fuchsia-bootloader=0.04"
-
-## Building Zircon
-
-```
-make -j32 arm64
-```
-
-Be sure you've already set up your network before proceeding to the next step.
-
-## Flashing Zircon
-
-First enter fastboot mode by holding down SW3 (leftmost button), pressing SW1 (rightmost button) quickly and keeping pressing SW3 for a few seconds.
-
-If you are working from the zircon layer, cd to the zircon directory and run:
-
-```
-scripts/flash-vim2 -m
-```
-
-The device should boot into zedboot by default.
-
-If you are working from the garnet layer of above, run the following:
-
-```
-fx flash vim2 --pave
-```
-
-In order to get into zedboot you can reboot into the recovery:
-
-```
-dm reboot-recovery
-```
-
-Alternatively, you can get to zedboot by resetting your vim2 by pressing SW1(rightmost button) quickly and keeping pressing SW2 for a few seconds.
-
-### netbooting
-
-To netboot zircon, enter zedboot and run the following under the zircon directory:
-
-```
-scripts/netboot-zircon ./build-arm64
-```
-
-To netboot garnet, run the following under the fuchsia directory:
-
-```
-fx set arm64 --netboot && fx full-build && fx netboot -1
-```
-
-You should be able to see "Issued boot command to ..." message printed out if this step is successful.
-
-### Paving
-
-Paving is available from garnet layers and above. Run the following under the fuchsia directory:
-
-```
-fx set arm64 && fx full-build && fx pave -1
-```
-
-### Fuchsia logo
-
-To update the boot splash screen to be the Fuchsia logo, do this in fastboot mode:
-```
-fastboot flash logo kernel/target/arm64/board/vim2/firmware/logo.img
-```
diff --git a/docs/targets/nuc.md b/docs/targets/nuc.md
deleted file mode 100644
index fdf7bc9..0000000
--- a/docs/targets/nuc.md
+++ /dev/null
@@ -1,116 +0,0 @@
-# Intel NUC (Kaby Lake, Skylake and Broadwell)
-
-*** note
-__WARNING:__ These are directions to configure a NUC machine to load and
-boot an experimental, in-development OS.
-***
-
-## NUC Setup & Configuration
-
-These instructions configure the NUC machine to boot from a USB flash drive.
-This is a necessary step for _network boot_, where the system on your USB
-drive pulls your freshly-built OS across the network, from host machine to NUC.
-
-1. Install memory (and optional SSD)
-    + Remove four bottom plate screws and bottom plate
-    + Install memory in the DIMM slot(s)
-    + (Optional) Install SSD in M.2 slot (SATA support only; NVMe lacks a driver)
-1. Boot the machine into Visual BIOS
-    + Reinstall the bottom plate, attach power, and start the machine
-    + Press F2 during startup to enter Visual BIOS setup
-    + Mouse will be required, due to the wonders of Visual BIOS
-1. Disable BIOS updates from internet (setting may not be present in newer NUCs)
-    + Select the Wrench menu (upper right), then Visual Bios Settings
-    + Deselect __Internet Updates__
-1. Verify that your memory (and SSD) are correctly installed and detected
-    + Select Advanced settings, then Main section
-    + Right-side Memory Information pane should list your memory
-    + Switch to Devices section
-    + Select PCI tab, verify that __M.2 Slot__ is enabled
-    + Select SATA tab, verify that __Chipset SATA__ is enabled
-    + Both tabs (PCI and SATA) should show your SSD
-1. Disable USB legacy and legacy boot
-    + Still in Devices section, select USB tab
-    + Deselect __USB Legacy__ support
-    + In Boot section, select Priority tab
-    + Deselect __Legacy Boot__ (in right-side Legacy Boot Priority pane)
-    + If you see a Secure Boot tab,
-    + Deselect Secure Boot in the tab (otherwise you will see an "Image
-      Authorization Fail" while booting USB).
-1. Configure boot ordering
-    + Select Boot Configuration tab
-    + Enable __Boot USB Devices First__, __Boot Network Devices Last__, and
-     __Unlimited Boot to Network Attempts__
-    + Network Boot (bottom left pane) should display _UEFI PXE & iSCSI_.
-      *** note
-      __WARNING__: DO NOT disable netbooting here or netbooting from Gigaboot and
-      Zedboot may not work.
-      ***
-1. Disable secure boot (on machines that support it)
-     + On the Boot section, Secure Boot tab, disable __Secure Boot__
-1. Save BIOS changes
-     + Press F10 (or click the top right (x) button) to Save and Exit, Y to confirm
-     + Device will automatically reboot and begin looking for a USB or network boot
-1. Power down the NUC
-1. Continue to [Setup with USB flash drive](usb_setup.md)
-
-*** promo
-Network booting only works with the NUC's *built-in* ethernet, netbooting via
-USB-ethernet dongle is unsupported.
-***
-
-## Remote management
-
-To enable remote management, including KVM, you also need to configure
-AMT.
-
-1. Enter Intel ME settings by pressing Ctrl+P on the boot screen
-    + The first time you need to set a password, the default one is "admin"
-      *** aside
-      Password must be at least 8 characters long, contain both lowercase and
-      uppercase characters, at least one digit and at least one non alpha-numeric
-      character.
-      ***
-1. Configure network
-    + Go to Network Setup > TCP/IP Settings > Wired LAN IPV4 Configuration
-    + Disable __DHCP Mode__ and set a static __IPV4 Address__
-    + Return to AMT Configuration and enable __Activate Network Access__
-    + Exit Intel ME settings and save your changes
-
-*** note
-__NOTE:__ This assumes you're using NUC connected to the EdgeRouter. If
-your networking setup is different, you may need a different network
-configuration.
-***
-
-#### Enabling Intel AMT / vPro KVM
-
-The Intel AMT / vPro KVM needs to be enabled before use. To do so, you
-can use the `wsman` command-line utility.
-
-The following commands assume you have set the `AMT_HOST` variable which
-contains the IPv4 address you configured in the Intel ME settings,
-`AMT_PASSWORD` which is the Intel ME password, and `VNC_PASSWORD` which
-is going to be the VNC password.
-
-*** aside
-Password must be _exactly_ 8 characters long, contain both lowercase and
-uppercase characters, at least one digit and at least one non alpha-numeric
-character.
-***
-
-```
-# set the VNC password
-wsman put http://intel.com/wbem/wscim/1/ips-schema/1/IPS_KVMRedirectionSettingData -h ${AMT_HOST} -P 16992 -u admin -p ${AMT_PASSWORD} -k RFBPassword=${VNC_PASSWORD}
-# enable KVM redirection to port 5900
-wsman put http://intel.com/wbem/wscim/1/ips-schema/1/IPS_KVMRedirectionSettingData -h ${AMT_HOST} -P 16992 -u admin -p ${AMT_PASSWORD} -k Is5900PortEnabled=true
-# disable opt-in policy (do not ask user for console access)
-wsman put http://intel.com/wbem/wscim/1/ips-schema/1/IPS_KVMRedirectionSettingData -h ${AMT_HOST} -P 16992 -u admin -p ${AMT_PASSWORD} -k OptInPolicy=false
-# disable session timeout
-wsman put http://intel.com/wbem/wscim/1/ips-schema/1/IPS_KVMRedirectionSettingData -h ${AMT_HOST} -P 16992 -u admin -p ${AMT_PASSWORD} -k SessionTimeout=0
-# enable KVM
-wsman invoke -a RequestStateChange http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_KVMRedirectionSAP -h ${AMT_HOST} -P 16992 -u admin -p ${AMT_PASSWORD} -k RequestedState=2
-```
-
-Now, you can remotely access the NUC using any VNC client, e.g.
-`vncviewer ${AMT_HOST}`.
diff --git a/docs/targets/toulouse.md b/docs/targets/toulouse.md
deleted file mode 100644
index a8f86b10..0000000
--- a/docs/targets/toulouse.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# Toulouse
-
-Toulouse is a nickname for a [Jetway PC](http://www.jetwayipc.com/product/hbjc130f731-series/) that
-Fuchsia developers use as a platform for writing networking software. It has multiple ethernet ports
-and mini-PCIe ports for adding wireless network adapters.
-
-## Toulouse Setup & Configuration
-
-You will need:
-- Toulouse hardware
-- Power supply (included with Toulouse)
-- Ethernet cable(s)
-- USB stick to get started
-- At least one of:
-  - Serial cable (e.g., StarTech USB null modem cable)
-  - HDMI + USB keyboard
-
-Tested Wifi/Bluetooth adapters include:
-* QCA6174A
-* QCA9880
-
-In your `fx set` commandline, add the following arguments:
-* `--board "garnet/boards/toulouse.gni"`
-* `--product "garnet/products/toulouse.gni"`
-* [optional] `--args "always_zedboot=true"`
-
-The last option will always boot to zedboot instead of booting off the paved image. You have to
-press 'm' before the timeout if you want to boot from disk, or re-pave without
-'always_zedboot=true'. One possible workaround is to use 'always_zedboot=true' when preparing the
-USB stick, and leaving the USB stick in when you want to netboot. Without the USB stick it will run
-off disk.
-
-By default the device boots from the internal storage first, and you cannot set USB drives as a
-generic default.
-
-Prepare a USB drive, using `fx mkzedboot` (see the [docs](usb_setup.md) for details, and see
-above for how to make a USB stick that can netboot).
-
-Insert the USB drive before powering on the device. Note: if the drive isn’t recognized, try using
-the other USB port. Some ports are flaky.
-
-On boot, press Esc or Del to enter the BIOS. This works over serial as well once the serial console
-is enabled (see below).
-
-In the "Boot" section, find the entry for USB UEFI and use the '+' key to move it to the top of the
-list. Press F4 to save and reset.
-
-To use the serial port on Debian/Ubuntu Linux, you may need to remove the 'brltty' program that
-wants to take over every serial port: `sudo apt-get remove brltty`. You will need to unplug/replug
-your serial cable after this to get it to work.
-
-## Serial consoles
-
-### Enabling serial for the BIOS
-
-In the "Advanced" section, open the "Serial Port Console Redirection" settings. Enable "Console
-Redirection" and ensure the "Console Redirection Settings" look similar to the following. (You may
-tune these to taste, if you know what you're doing.)
-* Terminal Type: VT-UTF8
-* Bits per second: 115200
-* Data Bits: 8
-* Parity: None
-* Stop Bits: 1
-* Flow Control: Off
-
-The other settings may be left at their default values.
-
-### Example Linux serial consoles (assumes a serial device at /dev/ttyUSB0)
-* screen /dev/ttyUSB0 115200
-* picocom -b 115200 /dev/ttyUSB0
-* miniterm.py /dev/ttyUSB0 115200
-* minicom -o -t vt100 -b 115200 -D /dev/ttyUSB0  (Supports control chars. Use Ctrl+a q to quit)
-
-### Serial console on MacOS
-Serial console will be at `/dev/tty.usbserial-XXXXXXXX` (eg. `/dev/tty.usbserial-AO003IN2`).
-`screen` is available by default. picocom and minicom can be installed through homebrew.
diff --git a/docs/targets/usb_setup.md b/docs/targets/usb_setup.md
deleted file mode 100644
index 1c74e10..0000000
--- a/docs/targets/usb_setup.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# Setup with a USB Flash Drive
-
-These instructions prepare a USB flash drive to be a bootable disk for your
-device: this procedure only enables you to netboot or pave, it won't put
-anything on your internal storage. This USB flash drive can then direct your
-device to boot from the freshly-built OS on your network-connected host
-development machine (or alternately from the OS on the flash drive itself).
-
-+ Execute `fx set x64` (if you haven't already)
-+ Create a __zedboot__ key using, `fx mkzedboot /path/to/your/device`. The
-`mkzedboot` command does the following:
-  + Creates a FAT partition continaing an EFI System Partition, containing
-    the Gigaboot EFI bootloader and a configuration that specifies to always
-    boot into Zedboot.
-  + Creates a ChromeOS bootable partition with a developer key signed Zedboot
-    kernel partition.
-+ On your host, run `fx full-build` (if you haven't already).
-+ If you wish to install Fuchsia to the target device (modifying the target
-  device harddisk), run `fx pave` on the host. IF you only wish to "netboot"
-  the target device, and avoid modifying any disk state, run `fx netboot` on
-  the host instead.
-+ Connect your device to your host via built-in ethernet, then power up the
-  device.
-
-## Manual Configuration
-
-It is also relatively easy to manually create an EFI boot key with particular
-properites, though this will only boot on EFI systems.
-
-+ Format the USB key with a blank FAT partition.
-+ Create a directory called `EFI/BOOT`.
-+ Copy `bootx64.efi` from `build-x64/bootloader` of a Zircon build into the
-  above directory.
-+ Copy `zircon.bin` from `build-x64` of a Zircon build into the root
-  directory of the FAT partition.
-+ Copy `zedboot.bin` from `build-x64` of a Zircon build into the root
-  directory of the FAT partition.
-+ Optionally: Create a file called `cmdline` in the root fo the FAT
-  partition. This file may contain any directives documented in 
-  [command line flags](kernel_cmdline.md).
-The created disk will by default boot from zircon.bin instead of the network.
-At the Gigaboot screen, press 'm' to boot zircon vs 'z' for zedboot, or set
-the default boot behavior with the `bootloader.default` flag in `cmdline`.
-
-See also:
-* [Setting up the Acer device](acer12.md)
-* [Setting up the NUC device](nuc.md)
-* [Command line flags](kernel_cmdline.md)
\ No newline at end of file
diff --git a/docs/testing.md b/docs/testing.md
deleted file mode 100644
index be7f887..0000000
--- a/docs/testing.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# Testing
-
-## Userspace Tests
-The test harness which runs on our bots (called "runtests") picks up all
-executables in the "/boot/test" and "/system/test" directories and runs them.
-If you provide a command-line argument, such as `runtests -S -m widget_test`,
-runtests will only run the single test requested -- in this case, `widget_test`.
-
-"runtests" takes command-line arguments to toggle classes of tests to execute.
-
-These classes are the following:
-
-* **Small**: Isolated tests for functions and classes. These must be totally
-  synchronous and single-threaded. These tests should be parallelizable; there
-  shouldn't be any shared resources between them.
-* **Medium**: Single-process integration tests. Ideally these are also synchronous
-  and single-threaded but they might run through a large chunk of code in each
-  test case, or they might use disk, making them a bit slower.
-* **Large**: Slow, multi-process, or particularly incomprehensible single-process
-  integration tests. These tests are often too slow / flaky to run in a CQ, and
-  we should try to limit how many we have.
-* **Performance**: Tests which are expected to pass, but which are measured
-  using other metrics (thresholds, statistical techniques) to identify
-  regressions.
-
-Since runtests doesn't really know what "class" is executing when it launches a
-test, it encodes this information in the environment variable
-`RUNTESTS_TEST_CLASS`, which is detailed in [the unittest
-header][unittest-header] , and lets the executable itself decide what to run /
-not run. This environment variable is a bitmask indicating which tests to run.
-
-For example, if a a test executable is run with "small" and "medium" tests,
-it will be executed ONCE with `RUNTESTS_TEST_CLASS` set to 00000003 (the
-hex bitwise OR of "TEST_SMALL" and "TEST_MEDIUM" -- though this information
-should be parsed using the [unittest header][unittest-header], as it may be
-updated in the future).
-
-### Zircon Tests (ulib/test, and/or using ulib/unittest)
-
-The following macros can be used to filter tests into these categories:
-```
-RUN_TEST_SMALL(widget_tiny_test)
-RUN_TEST_MEDIUM(widget_test)
-RUN_TEST_LARGE(widget_big_test)
-RUN_TEST_PERFORMANCE(widget_benchmark)
-```
-
-The legacy `RUN_TEST(widget_test)` is aliased to mean the same thing as
-`RUN_TEST_SMALL`.
-
-### Fuchsia Tests (not using ulib/unittest)
-
-The environment variable `RUNTESTS_TEST_CLASS` will still be available to all
-executables launched by runtests. The [unittest header][unittest-header] can be
-used to parse different categories of tests which the runtests harness attempted
-to run.
-
-### Runtests CLI
-
-By default, runtests will run both small and medium tests.
-
-To determine how to run a custom set of test categories, run `runtests -h`,
-which includes usage information.
-
-[unittest-header]: ../system/ulib/unittest/include/unittest/unittest.h "Unittest Header"
-
-
-## Kernel-mode Tests
-
-The kernel contains unit tests and diagnostics, which can be run using the `k`
-command. The output of the `k` command will only be shown on the
-console. Depending on your configuration, this might be the serial console, or
-the `debuglog` virtual terminal.
-
-### Unit tests
-
-Many parts of the kernel have unit tests, which report success/failure
-automatically. These unit tests are built using the primitives provided by [the
-kernel unit-test library](../kernel/lib/unittest). You can find these statically
-by searching for `UNITTEST_START_TESTCASE`.
-
-These tests can be run from the shell with `k ut`. `k ut all` will run all tests
-or you can use `k ut $TEST_NAME` to run a specific test.
-
-### Diagnostics
-
-Many parts of the kernel provide diagnostics, whose output requires manual
-inspection. Some of these diagnostics are used to verify correctness
-(e.g. [`timer_diag`](../kernel/tests/timer_tests.cpp)), while others simply
-stress test a part of the system
-(e.g. [`timer_stress`](../kernel/tests/timer_tests.cpp)).
-
-To run a diagnostic, simply pass its name to the `k` command. For example, to
-run the kernel's [builtin benchmarks](../kernel/tests/benchmarks.cpp), run `k
-bench`. To find the full set of kernel diagnostics statically, search for
-`STATIC_COMMAND`. To enumerate them dynamically, run `k help`.
-
-Diagnostic tests are intended to be run via serial console, or with physical
-access to the system. Some diagnostics may be destructive, and leave the system
-in a broken state.
diff --git a/docs/thread_annotations.md b/docs/thread_annotations.md
deleted file mode 100644
index cfaa195..0000000
--- a/docs/thread_annotations.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# Zircon thread safety annotations
-
-Zircon code takes advantage of clang's thread safety analysis feature to
-document and machine-verify some of our synchronization invariants. These
-annotations are checked when building for clang (see
-[getting started](getting_started.md) for instructions on building with
-clang).
-
-## How to use
-
-[Clang's documentation](https://clang.llvm.org/docs/ThreadSafetyAnalysis.html)
-
-In Zircon, we provide our own set of macros wrapping the annotations and have
-annotated our synchronization primitives. When writing new code involving
-synchronization or annotating existing code, in most cases you should use the
-thread annotation macros provided by
-[system/private/zircon/thread\_annotations.h](../system/private/zircon/thread_annotations.h). These macros all begin with
-the prefix `"TA_"` for thread analysis. The most commonly used ones are:
-
-* `TA_GUARDED(x)` the annotated variable is guarded by the capability (e.g. lock) `x`
-* `TA_ACQ(x...)` function acquires all of the mutexes in the set `x` and hold them after returning
-* `TA_REL(x...)` function releases all of the mutexes in the set `x`
-* `TA_REQ(x...)` function requires that the caller hold all of the mutexes in the set `x`
-* `TA_EXCL(x...)` function requires that the caller not be holding any of the mutexes in the set `x`
-
-For example, a class containing a member variable `'int foo_'` protected by a
-mutex would be annotated like so:
-
-```
-// example.h
-
-class Example {
-public:
-    // Public function has no locking requirements and thus needs no annotation.
-    int IncreaseFoo(int by);
-
-private:
-    // This is an internal helper routine that can only be called with |lock_|
-    // held. Calling this without holding |lock_| is a compile-time error.
-    // Annotations like TA_REQ, TA_ACQ, TA_REL, etc are part of the function's
-    // interface and must be on the function declaration, usually in the header,
-    // not the definition.
-    int IncreaseFooLocked(int by) TA_REQ(lock_);
-
-    // This internal routine requires that both |lock_| and |foo_lock_| be held by the
-    // caller.
-    int IncreaseFooAndBarLocked(int foo_by, int bar_by) TA_REQ(lock_) TA_REQ(bar_lock_);
-
-    // The TA_GUARDED(lock_) annotation on |foo_| means that |lock_| must be
-    // held to read or write from |foo_|.
-    int foo_ TA_GUARDED(lock_);
-
-    // |lock_| can be declared after annotations referencing it,
-    // if desired.
-    Mutex lock_;
-
-    Mutex bar_lock_;
-};
-
-// example.cpp
-
-int Example::IncreaseFoo(int by) {
-    int new_value;
-    {
-        AutoLock lock(&lock_);  // fbl::AutoLock is annotated
-        new_value = IncreaseFooLocked(by);
-    }
-    return new_value;
-}
-```
-
-Note that for annotations which allow sets of mutex objects, one may either
-apply the annotation multiple times, or provided a comma separated list to the
-annotation.  In other words, the following two declarations are equivalent.
-
-```
-    int IncreaseFooAndBarLocked(int foo_by, int bar_by) TA_REQ(lock_) TA_REQ(bar_lock_);
-    int IncreaseFooAndBarLocked(int foo_by, int bar_by) TA_REQ(lock_, bar_lock_);
-```
-
-Library code exposed through the sysroot must use the more awkwardly named
-macros provided by
-[system/public/zircon/compiler.h](../system/public/zircon/compiler.h) to
-avoid collisions with consumers of the sysroot.
-
-## Best practices
-
-Annotations should complement the comments and identifiers to make the code
-understandable. Annotations do not replace comments or clear names. Try to
-follow these best practices when writing code involving locking:
-
-* Group member variables protected by a lock with the lock. Where it makes
-sense, document what is protected by what with a comment in addition to the
-annotations. For example when several member variables are protected by one lock
-and several are protected by a different lock, a comment is easier to read than
-going through each annotation.
-
-* Name functions that require a lock be held with a 'Locked()' suffix. If there
-are multiple locks that could be plausibly held to call the function, consider
-making the choice clear in the function name. Keep in mind readers of calling
-code will not be able to see the annotations.
-
-## Limitations
-
-The thread safety analysis is a purely static check done at compile time and
-cannot understand conditionally held locks or locking patterns that span
-compilation units in ways not expressible via static annotations. In many
-situations, this analysis is still useful but there are situations that the
-analysis simply cannot understand. The main escape hatch for disabling analysis
-is to add the annotation `TA_NO_THREAD_SAFETY_ANALYSIS` to the function definition
-containing the code the analysis is confused by. Other escape mechanisms are
-available as well - see the Clang documentation for details. Situations that
-require disabling the analysis are likely to be complex for humans to understand
-as well as machines and should be accompanied by a comment indicating the
-invariants in use.
-
-The thread safety analysis can be defeated in a number of ways, for instance
-when using pointers.  For example, when taking the address of a guarded data
-member Clang looses track of the guard, e.g. for a foo_ protected by a lock_
-a call to `memset(&foo_, 0, sizeof(foo_))` without holding lock_ won't be caught
-as a violation.
diff --git a/docs/time.md b/docs/time.md
deleted file mode 100644
index 97bb3f8..0000000
--- a/docs/time.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Time units
-
-## Userspace exposed time units
-
-*zx\_time\_t* is in nanoseconds.
-
-Use [zx_clock_get()](syscalls/clock_get.md) to get the current time.
-
-## Kernel-internal time units
-
-*lk\_time\_t* is in nanoseconds.
-
-To get the current time since boot, use:
-
-```
-#include <platform.h>
-
-lk_time_t current_time(void);
-```
diff --git a/docs/timer_slack.md b/docs/timer_slack.md
deleted file mode 100644
index 8334a7a..0000000
--- a/docs/timer_slack.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Timer Slack
-
-[Timer objects](objects/timer.md) have a concept of slack. Slack
-defines how the system may alter the timer's deadline. Slack allows
-the system to internally coalesce timers and timer-like events to
-improve performance or efficiency.
-
-Slack is made up of two components, type and amount. Type describes
-how slack can be applied:
-
-+ **ZX_TIMER_SLACK_CENTER** coalescing is allowed with earlier and
-  later timers.
-+ **ZX_TIMER_SLACK_EARLY** coalescing is allowed only with earlier
-  timers.
-+ **ZX_TIMER_SLACK_LATE** coalescing is allowed only with later
-  timers.
-
-Amount is the allowed deviation from the deadline. For example, a
-timer with **ZX_TIMER_SLACK_EARLY** and 5us may fire up to 5us before
-its deadline. A timer with **ZX_TIMER_SLACK_CENTER** and 7ms may fire
-anywhere from 7ms before its deadline to 7ms after its deadline.
-
-## Timer-like Syscalls
-
-Slack may also be applied to blocking syscalls that accept a deadline
-argument, like [`zx_nanosleep()`](syscalls/nanosleep.md).
-
-## Defaults and Job Policy
-
-For Timer objects, slack is specified when creating and setting
-timers. For other syscalls that take a deadline, but no slack
-parameters, the slack type and amount are specified by the job's
-policy. See [`zx_job_set_policy()`](syscalls/job_set_policy.md).
diff --git a/docs/tls.md b/docs/tls.md
deleted file mode 100644
index 8610982..0000000
--- a/docs/tls.md
+++ /dev/null
@@ -1,326 +0,0 @@
-# Thread Local Storage #
-
-The ELF Thread Local Storage ABI (TLS) is a storage model for variables that
-allows each thread to have a unique copy of a global variable. This model
-is used to implement C++'s `thread_local` storage model. On thread creation the
-variable will be given its initial value from the initial TLS image. TLS
-variables are for instance useful as buffers in thread safe code or for per
-thread book keeping. C style errors like errno or dlerror can also be handled
-this way.
-
-TLS variables are much like any other global/static variable. In implementation
-their initial data winds up in the `PT_TLS` segment. The `PT_TLS` segment
-is inside of a read only `PT_LOAD` segment despite TLS variables being writable.
-This segment is then copied into the process for each thread in a unique
-writable location. The location the `PT_TLS` segment is copied to is influenced
-by the segment's alignment to ensure that the alignment of TLS variables is
-respected.
-
-## ABI ##
-
-The actual interface that the compiler, linker, and dynamic linker must adhere
-to is actually quite simple despite the details of the implementation being more
-complex. The compiler and the linker must emit code and dynamic relocations that
-use one of the 4 access models (described in a following section). The dynamic
-linker and thread implementation must then set everything up so that this
-actually works. Different architectures have different ABIs but they're similar
-enough at broad strokes that we can speak about most of them as if there was
-just one ABI. This document will assume that either x86-64 or AArch64 is being
-used and will point out differences when they occur.
-
-The TLS ABI makes use of a few terms:
-
-  * Thread Pointer: This is a unique address in each thread, generally stored
-    in a register. Thread local variables lie at offsets from the thread pointer.
-    Thread Pointer will be abbreviated and used as `$tp` in this document. `$tp`
-    is what `__builtin_thread_pointer()` returns on AArch64. On AArch64 `$tp`
-    is given by a special register named `TPIDR_EL0` that can be accessed using
-    `mrs <reg>, TPIDR_EL0`. On `x86_64` the `fs.base` segment base is used and
-    can be accessed with `%fs:` and can be loaded from `%fs:0` or `rdfsbase`
-    instruction.
-  * TLS Segment: This is the image of data in each module and specified by the
-    `PT_TLS` program header in each module. Not every module has a `PT_TLS`
-    program header and thus not every module has a TLS segment. Each module
-    has at most one TLS segment and correspondingly at most one `PT_TLS`
-    program header.
-  * Static TLS set: This is the sum total of modules that are known to the
-    dynamic linker at program start up time. It consists of the main executable
-    and every library transitively mentioned by `DT_NEEDED`. Modules that
-    require being in the Static TLS set have `DF_STATIC_TLS` set on their
-    `DT_FLAGS` entry in their dynamic table (given by the `PT_DYNAMIC` segment).
-  * TLS Region: This is a contiguous region of memory unique to each
-    thread. `$tp` will point to some point in this region. It contains the
-    TLS segment of every module in Static TLS set as well as some
-    implementation-private data which is sometimes called the TCB (Thread
-    Control Block). On AArch64 a 16-byte reserved space starting at `$tp` is
-    also sometimes called the TCB. We will refer to this space as the "ABI TCB"
-    in this doc.
-  * TLS Block: This is an individual thread's copy of a TLS segment. There is
-    one TLS block per TLS segment per thread.
-  * Module ID: The module ID is not statically known except for the main
-    executable's module ID which is always 1. Other module's module IDs are
-    chosen by the dynamic linker. It's just a unique non-zero ID for each
-    module. In theory it could be any non-zero 64-bit value that is unique to
-    the module like a hash or something. In practice it's just a simple counter
-    that the dynamic linker maintains.
-  * The main executable: This is the module that contains the start address. It,
-    is also treated in a special way in one of the access models. It always
-    has a Module ID of 1. This is the only module that can use fixed offsets
-    from `$tp` via the Local Exec model described below.
-
-To comply with the ABI all access models must be supported.
-
-#### Access Models ####
-
-There are 4 access models specified by the ABI:
-
-  * `global-dynamic`
-  * `local-dynamic`
-  * `initial-exec`
-  * `local-exec`
-
-These are the values that can be used for `-ftls-model=...` and
-`__attribute__((tls_model("...")))`
-
-Which model is used relates to:
-
-1. Which module is performing the access:
-  1. The main executable
-  2. A module in the static TLS set
-  3. A module that was loaded after startup, e.g. by `dlopen`
-2. Which module the variable being accessed is defined in:
-  1. Within the same module (i.e. `local-*`)
-  2. In a different module (i.e. `global-*`)
-
-* `global-dynamic` Can be used from anywhere, for any variable.
-* `local-dynamic` Can be used by any module, for any variable defined in that
-  same module.
-* `initial-exec` Can be used by any module for any variable defined in the static
-  TLS set.
-* `local-exec` Can be used by the main executable for variables defined in the
-  main executable.
-
-###### Global Dynamic ######
-
-Global dynamic is the most general access format. It is also the slowest.
-Any thread-local global variable should be accessible with this method. This
-access model *must* be used if a dynamic library accesses a symbol defined in
-another module (see exception in section on Initial Exec). Symbols defined
-within the executable need not use this access model. The main executable can
-also avoid using this access model. This is the default access model when
-compiling with `-fPIC` as is the norm for shared libraries.
-
-This access model works by calling a function defined in the dynamic linker.
-There are two ways functions might be called, via TLSDESC, or via
-`__tls_get_addr`.
-
-In the case of `__tls_get_addr` it is passed the pair of `GOT` entries
-associated with this symbol. Specifically it is passed the pointer to the first
-and the second entry comes right after it. For a given symbol `S`, the first
-entry, denoted `GOT_S[0]`, must contain the Module ID of the module in which
-`S` was defined. The second entry, denoted `GOT_S[1]`, must contain offset into
-TLS Block which is the same as the offset of the symbol in the `PT_TLS` segment
-of the associated module. The pointer to `S` is then computed using
-`__tls_get_addr(GOT_S)`. The implementation of `__tls_get_addr` will be
-discussed later.
-
-TLSDESC is an alternative ABI for `global-dynamic` access (and `local-dynamic`)
-where a different pair of `GOT` slots are used where the first `GOT` slot
-contains a function pointer. The second contains some dynamic linker defined
-auxiliary data. This allows the dynamic linker a choice over which function is
-called depending on circumstance.
-
-In both cases the calls to these functions must be implemented by a specific
-code sequence and a specific set of relocs. This allows the linker to recognize
-these accesses and potentially relax them to the `local-dynamic` access model.
-
-(NOTE: The following paragraph contains details about how the compiler upholds
-its end of the ABI. Skip this paragraph if you don't care about that.)
-
-For the compiler to emit code for this access model a call needs to be emitted
-against `__tls_get_addr` (defined by the dynamic linker) and a reference to the
-symbol name. Specifically the compiler the emits code for (minding the
-additional relocation needed for the GOT itself) `__tls_get_addr(GOT_S)`. The
-linker then emits two dynamic relocations when generating the GOT. On `x86_64`
-these are `R_X86_64_DTPMOD` and `R_X86_64_DTPOFF`. On AArch64 these are
-`R_AARCH64_DTPMOD` and `R_AARCH64_DTPOFF`. These relocations reference the symbol
-regardless of whether or not the module defines a symbol by that name or not.
-
-###### Local Dynamic ######
-
-Local dynamic the same as Global Dynamic but for local symbols. It can be
-thought of as a single `global-dynamic` access to the TLS block of this module.
-Then because every variable defined in the module is at fixed offsets from the
-TLS block the compiler can optimize multiple `global-dynamic` calls into one.
-The compiler will relax a `global-dynamic` access to a `local-dynamic` access
-whenever the variables are local/static or have hidden visibility. The linker
-may sometimes be able to relax some `global-dynamic` accesses to `local-dynamic`
-as well.
-
-The following gives an example of how the compiler might emit code for this
-access model:
-
-```
-
-static thread_local char buf[buf_cap];
-static thread_local size_t buf_size = 0;
-while(*str && buf_size < buf_cap) {
-  buf[buf_size++] = *str++;
-}
-```
-might be lowered to
-```
-
-// GOT_module[0] is the module ID of this module
-// GOT_module[1] is just 0
-// <X> denotes the offset of X in this module's TLS block
-tls = __tls_get_addr(GOT_module)
-while(*str && *(size_t*)(tls+<buf_size>) < buf_cap) {
-  (char*)(tls+<buf>)[*(size_t*)(tls+<buf_size>)++] = *str++;
-}
-```
-
-If this code used global dynamic it would have to make at least 2 calls, one to
-get the pointer for buf and the other to get the pointer for `buf_size`.
-
-###### Initial Exec ######
-
-This access model can be used anytime the compiler knows the module that the
-symbol being accessed is defined in will be loaded in the initial set of
-executables rather than opened using `dlopen`. This access model is generally
-only used when the main executable is accessing a global symbol with default
-visibility. This is because compiling an executable is the only time the
-compiler knows that any code generated will be in the initial executable set. If
-a DSO is compiled to make thread local accesses use this model then the DSO
-cannot be safely opened with `dlopen`. This is acceptable in performance
-critical applications and in cases where you know the binary will never be
-dlopen-ed such as in the case of libc. Modules compiled/linked this way have
-their `DF_STATIC_TLS` flag set.
-
-Initial Exec is the default when compiling without `-fPIC`.
-
-The compiler emits code without even calling `__tls_get_addr` for this access
-model. It does so using a single GOT entry which we'll denote `GOT_s` for symbol
-`s` which the compiler emits relocations for to ensure that
-
-```
-
-extern thread_local int a;
-extern thread_local int b;
-int main() {
-  return a + b;
-}
-```
-would be lowered to something like the following
-```
-
-int main() {
-  return *(int*)($tp + GOT[a]) + *(int*)($tp + GOT[b]);
-}
-```
-
-Note that on x86 architectures `GOT[s]` will actually resolve to a negative
-value.
-
-###### Local Exec ######
-
-This is the fastest access model and can only be used if the symbol is in the
-first TLS block which is the TLS block of the main executable. In practice only
-the main executable can use this access mode because any shared library can't
-(and normally wouldn't need to) know if it is accessing something from the main
-executable. The linker will relax `initial-exec` to `local-exec`. The compiler
-can't do this without explicit instructions via `-ftls-model` or
-`__attribute__((tls_model("...")))` because the compiler cannot know if the
-current translation unit is going to be linked into a main executable or a
-shared library.
-
-The precise details of how this offset is computed changes a bit
-from architecture to architecture.
-
-example code:
-```
-static thread_local int a;
-static thread_local int b;
-
-int main() {
-  return a + b;
-}
-```
-would be lowered to
-```
-int main() {
-  return (int*)($tp+TPOFF_a) + (int*)($tp+TPOFF_b));
-}
-```
-
-On AArch64 `TPOFF_a == max(16, p_align) + <a>` where `p_align` is exactly the
-`p_align` field of the main executable's `PT_TLS` segment and `<a>` is the
-offset of `a` from the beginning of the main executable's TLS segment.
-
-On `x86_64` `TPOFF_a == -<a>` where `<a>` is the offset of the `a` from the *end*
-of the main executable's TLS segment.
-
-The linker is aware of what `TPOFF_X` is for any given `X` and fills in this
-value.
-
-## Implementation ##
-
-This section discusses the implementation as it is implemented on Fuchsia. This
-said the broad strokes here are widely similar across different libc
-implementations including musl and glibc.
-
-The actual implementation of all of this introduces a few more details. Namely
-the so-called "DTV" (Dynamic Thread Vector) (denoted `dtv` in this doc) which
-indexes TLS blocks by module ID. The following diagram shows what the initial
-executable set looks like. In Fuchsia's implementation we actually store a
-bunch of meta information in a thread descriptor struct along with the
-ABI TCB (denoted `tcb` below). In our implementation we use the first 8 bytes
-of this space to point to the DTV. At first `tcb` points to `dtv` as shown in
-the below diagrams but after a dlopen this can change.
-
-arm64:
-```
-*------------------------------------------------------------------------------*
-| thread | tcb | X | tls1 | ... | tlsN | ... | tls_cnt | dtv[1] | ... | dtv[N] |
-*------------------------------------------------------------------------------*
-^         ^         ^             ^            ^
-td        tp      dtv[1]       dtv[n+1]       dtv
-```
-
-Here `X` has size `min(16, tls_align) - 16` where `tls_align` is the maximum
-alignment of all loaded TLS segments from the static TLS set. This is set by
-the static linker since the static linker resolves `TPOFF_*` values. This
-padding is set that so that if, as required, `$tp` is aligned to main
-executable's `PT_TLS` segment's `p_align` value then `tls1 - $tp` will be
-`max(16, p_align)`. This ensures that there is always at least a 16 byte space
-for the ABI TCB (denoted `tcb` in the diagram above).
-
-x86:
-```
-*-----------------------------------------------------------------------------*
-| tls_cnt | dtv[1] | ... | dtv[N] | ... | tlsN | ... | tls1 | tcb |  thread   |
-*-----------------------------------------------------------------------------*
-^                                       ^             ^       ^
-dtv                                  dtv[n+1]       dtv[1]  tp/td
-```
-
-Here `td` denotes the "thread descriptor pointer". In both implementations this
-points to the thread descriptor. A subtle point not made apparent in these
-diagrams is that `tcb` is actually a member of the thread descriptor struct in
-both cases but on AArch64 it is the last member and on `x86_64` it is the first
-member.
-
-#### dlopen ####
-
-This picture explains what happens for the initial executables but it doesn't
-explain what happens in the `dlopen` case. When `__tls_get_addr` is called it
-first checks to see if `tls_cnt` is such that the module ID (given by `GOT_s[0]`
-) is within the `dtv`. If it is then it simply looks up `dtv[GOT_s[0]] + GOT_s[1]`
-but if it isn't something more complicated happens. See the implementation of
-`__tls_get_new` in [dynlink.c](https://fuchsia.googlesource.com/zircon/+/master/third_party/ulib/musl/ldso/dynlink.c).
-In a nutshell a sufficiently large space was already allocated for a larger `dtv`
-on a call to `dlopen`. It is an invariant of the system that sufficient space
-will always exist somewhere already allocated. The larger space is then setup to
-be a proper `dtv`. `tcb` is then set to point to this new larger `dtv`. Future
-accesses will then use the simpler code path since `tls_cnt` will be large
-enough.
diff --git a/docs/tracing/design.md b/docs/tracing/design.md
deleted file mode 100644
index e27b6aa..0000000
--- a/docs/tracing/design.md
+++ /dev/null
@@ -1,367 +0,0 @@
-# Fuchsia Tracing System Design
-
-This document describes a mechanism for collecting diagnostic trace information
-from running applications on the Fuchsia operating system.
-
-## Overview
-
-The purpose of Fuchsia tracing is to provide a means to collect, aggregate,
-and visualize diagnostic tracing information from Fuchsia user space
-processes and from the Zircon kernel.
-
-## Design Goals
-
-- Lightweight Instrumentation
-  - Enabling tracing should not significantly affect the performance of running
-    applications.  Trace providers should not need to acquire locks, make
-    syscalls, or perform dynamic memory allocation required between the time
-    when tracing is activated and when it is disabled.
-- Compact Memory Footprint
-  - Trace records are stored compactly in memory so that buffers can remain
-    small but hold many events.
-- Crash-proof
-  - It is possible to collect partial traces even if trace providers
-    terminate (normally or abnormally) during trace collection.
-- Flexible and Universal
-  - Can trace code written in any language given a suitable implementation of
-    the tracing library.
-  - Trace points can be manually inserted by the developer or generated
-    dynamically by tools.
-- General
-  - The trace format defines general purpose record types which support a
-    wide range of data collection needs.
-  - Trace data can be transformed into other formats for visualization using
-    tools such as Catapult or TraceViz.
-- Extensible
-  - New record types can be added in the future without breaking existing tools.
-- Robust
-  - Enabling tracing does not compromise the integrity of running components
-    or expose them to manipulation by tracing clients.
-
-## Moving Parts
-
-### Trace Manager
-
-The trace manager is a system service which coordinates registration of
-trace providers.  It ensures that tracing proceeds in an orderly manner
-and isolates components which offer trace providers from trace clients.
-
-The trace manager implements two FIDL interfaces:
-
-- `TraceController`: Provides trace clients with the ability to enumerate
-  trace providers and collect trace data.
-- `TraceRegistry`: Provides trace providers with the ability to register
-  themselves at runtime so that they can be discovered by the tracing system.
-
-TODO: The `TraceRegistry` should be replaced by a `Namespace` based approach
-to publish trace providers from components.
-
-### Trace Providers
-
-Components which can be traced or offer tracing information to the system
-implement the `TraceProvider` FIDL interface and register it with the
-`TraceRegistry`.  Once registered, they will receive messages whenever
-tracing is started or stopped and will have the opportunity to provide
-trace data encoded in the [Fuchsia Trace Format](trace_format.md).
-
-#### Kernel Trace Provider
-
-The `ktrace_provider` program ingests kernel trace events and publishes
-trace records.  This allows kernel trace data to be captured and visualized
-together with userspace trace data.
-
-### Trace Client
-
-The `trace` program offers command-line access to tracing functionality
-for developers.  It also supports converting Fuchsia trace archives into
-other formats, such as Catapult JSON records which can be visualized
-using Catapult (aka. chrome:://tracing).
-
-Trace information can also be collected programmatically by using the
-`TraceController` FIDL interface directly.
-
-## Libraries
-
-### libtrace: The C and C++ Trace Event Library
-
-Provides macros and inline functions for instrumenting C and C++ programs
-with trace points for capturing trace data during trace execution.
-
-See `<trace/event.h>`.
-
-#### C++ Example
-
-This example records trace events marking the beginning and end of the
-execution of the "DoSomething" function together with its parameters.
-
-```c++
-#include <trace/event.h>
-
-void DoSomething(int a, std::string b) {
-  TRACE_DURATION("example", "DoSomething", "a", a, "b", b);
-
-  // Do something
-}
-```
-
-#### C Example
-
-This example records trace events marking the beginning and end of the
-execution of the "DoSomething" function together with its parameters.
-
-Unlike in C++, it is necessary to specify the type of each trace argument.
-In C++ such annotations are supported but are optional since the compiler
-can infer the type itself.
-
-```c
-#include <trace/event.h>
-
-void DoSomething(int a, const char* b) {
-  TRACE_DURATION("example", "DoSomething", "a", TA_INT32(a), "b", TA_STRING(b));
-
-  // Do something
-}
-```
-
-#### Suppressing Tracing Within a Compilation Unit
-
-To completely suppress tracing within a compilation unit, define the NTRACE
-macro prior to including the trace headers.  This causes the macros to
-behave as if tracing is always disabled so they will not produce trace
-records and they will have zero runtime overhead.
-
-```c
-#define NTRACE
-#include <trace/event.h>
-
-void DoSomething(void) {
-  // This will never produce trace records because the NTRACE macro was
-  // defined above.
-  TRACE_DURATION("example", "DoSomething");
-}
-```
-
-### libtrace-provider: Trace Provider Library
-
-This library provides C and C++ functions to register a process's trace
-engine with the Fuchsia tracing system.  For tracing to work in your process,
-you must initialize the trace provider at some point during its execution
-(or implement your own trace handler to register the trace engine some
-other way).
-
-The trace provider requires an asynchronous dispatcher to operate.
-
-#### C++ Example
-
-```c++
-#include <lib/async-loop/cpp/loop.h>
-#include <trace-provider/provider.h>
-
-int main(int argc, char** argv) {
-  // Create a message loop.
-   async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
-
-  // Start a thread for the loop to run on.
-  // We could instead use async_loop_run() to run on the current thread.
-  zx_status_t status = loop.StartThread();
-  if (status != ZX_OK) exit(1);
-
-  // Create the trace provider.
-  trace::TraceProvider trace_provider(loop.dispatcher());
-
-  // Do something...
-
-  // The loop and trace provider will shut down once the scope exits.
-  return 0;
-}
-```
-
-#### C Example
-
-```c
-#include <lib/async-loop/cpp/loop.h>
-#include <trace-provider/provider.h>
-
-int main(int argc, char** argv) {
-  zx_status_t status;
-  async_loop_t* loop;
-  trace_provider_t* trace_provider;
-
-  // Create a message loop.
-  status = async_loop_create(&kAsyncLoopConfigNoAttachToThread, &loop);
-  if (status != ZX_OK) exit(1);
-
-  // Start a thread for the loop to run on.
-  // We could instead use async_loop_run() to run on the current thread.
-  status = async_loop_start_thread(loop, "loop", NULL);
-  if (status != ZX_OK) exit(1);
-
-  // Create the trace provider.
-  async_dispatcher_t* dispatcher = async_loop_get_dispatcher(loop);
-  trace_provider = trace_provider_create(dispatcher);
-  if (!trace_provider) exit(1);
-
-  // Do something...
-
-  // Tear down.
-  trace_provider_destroy(trace_provider);
-  async_loop_shutdown(loop);
-  return 0;
-}
-```
-
-### libtrace-reader: Trace Reader Library
-
-Provides C++ types and functions for reading trace archives.
-
-See `<trace-reader/reader.h>`.
-
-## Transport Protocol
-
-When the developer initiates tracing, the trace manager asks all relevant
-trace providers to start tracing and provides each one with a trace buffer
-VMO into which they should write their trace records.
-
-While a trace is running, the trace manager continues watching for newly
-registered trace providers and activates them if needed.
-
-What happens when a trace provider's trace buffer becomes full while a trace
-is running depends on the buffering mode.
-See [Buffering Modes](#Buffering-Modes) below.
-
-When tracing finishes, the trace manager asks all of the active trace providers
-to stop tracing then waits a short time for them to acknowledge that they
-have finished writing out their trace events.
-
-The trace manager then reads and validates trace data written into the trace
-buffer VMOs by trace providers and creates a trace archive.  The trace manager
-can often recover partial data even when trace providers terminate abnormally
-as long as they managed to store some data into their trace buffers.
-Note that in streaming mode the trace manager only needs to save the
-currently active rolling buffer.
-See [Buffering Modes](#Buffering-Modes) below.
-
-The trace manager delivers the resulting trace archive to its client through
-a socket.  This data is guaranteed to be well-formed according to the
-Fuchsia trace format (but it may be nonsensical if trace providers
-deliberately emit garbage data).
-
-These are some important invariants of the transport protocol:
-- There are no synchronization points between the trace manager and trace
-  providers other than starting or stopping collection.
-- Trace providers (components being traced) only ever write to trace buffers;
-  they never read from them.
-- The trace manager only ever reads from trace buffers; it never writes to them.
-- Trace clients never see the original trace buffers; they receive trace
-  archives over a socket from the trace manager.  This protects trace providers
-  from manipulation by trace clients.
-
-## Buffering Modes
-
-There are three buffering modes: oneshot, circular, and streaming.
-They specify different behaviors when the trace buffer fills.
-
-Note that in all cases trace provider behavior is independent of each other.
-Other trace providers can continue to record trace events into their own
-buffers as usual until the trace stops, even as one provider's buffer fills.
-This may result in a partially incomplete trace.
-
-### Oneshot
-
-If the buffer becomes full then that trace provider will stop recording events.
-
-### Circular
-
-The trace buffer is effectively divided into three pieces: the "durable" buffer
-and two "rolling" buffers. The durable buffer is for records important enough
-that we don't want to risk dropping them. These include records for thread and
-string references.
-
-Tracing begins by writing to the first rolling buffer. Once one rolling buffer
-fills tracing continues by writing to the other one.
-
-If the durable buffer fills then tracing for the provider stops. Tracing in
-other providers continues as usual.
-
-### Streaming
-
-The trace buffer is effectively divided into three pieces: the "durable" buffer
-and two "rolling" buffers. The durable buffer is for records important enough
-that we don't want to risk dropping them. These include records for thread and
-string references.
-
-Tracing begins by writing to the first rolling buffer. Once one rolling buffer
-fills tracing continues by writing to the other one, if it is available, and
-notifying the trace manager that the buffer is full. If the other rolling
-buffer is not available, then records are dropped until it becomes available.
-The other rolling buffer is unavailable between the point when it filled and
-when the manager reports back that the buffer's contents have been saved.
-
-Whether records get dropped depends on the rate at which records are created
-vs the rate at which the trace manager can save the buffers. This can result
-in a partially incomplete trace, but is less important than perturbing program
-performance by waiting for a buffer to be saved.
-
-If the durable buffer fills then tracing for the provider stops. Tracing in
-other providers continues as usual.
-
-## Trace Manager/Provider FIFO Protocol
-
-Notification of trace provider startup and shutdown is done via a FIFO,
-the handle of which is passed from the trace manager to each trace provider
-as part of the initial "start tracing" request. The form of each message is
-defined in `<trace-provider/provider.h>`. Packets are fixed size with the
-following format:
-
-```cpp
-typedef struct trace_provider_packet {
-    // One of TRACE_PROVIDER_*.
-    uint16_t request;
-
-    // For alignment and future concerns, must be zero.
-    uint16_t reserved;
-
-    // Optional data for the request.
-    // The contents depend on the request.
-    // If unused they must be passed as zero.
-    uint32_t data32;
-    uint64_t data64;
-} trace_provider_packet_t;
-```
-
-### FIFO Packets
-
-The following packets are defined:
-
-**TRACE_PROVIDER_STARTED**
-
-Sent from trace providers to the trace manager.
-Notify the trace manager that the provider has received the "start tracing"
-request and is starting to collect trace data.
-The `data32` field of the packet contains the version number of the FIFO
-protocol that the provider is using. The value is specified by
-**TRACE_PROVIDER_FIFO_PROTOCOL_VERSION** in `<trace-provider/provider.h>`.
-If the trace manager sees a protocol it doesn't understand it will close
-its side of the FIFO and ignore all trace data from the provider.
-
-**TRACE_PROVIDER_SAVE_BUFFER**
-
-Sent from trace providers to the trace manager in streaming mode.
-Notify the trace manager that a buffer is full and needs saving.
-This request is only used in streaming mode.
-The `data32` field contains the "wrap count" which is the number of times
-writing has switched from one buffer to the next. The buffer that needs saving
-is `(data32 & 1)`.
-The `data64` field contains the offset of the end of data written to the
-"durable" buffer.
-
-Only one buffer save request may be sent at a time. The next one cannot be
-sent until **TRACE_PROVIDER_BUFFER_SAVED** is received acknowledging the
-previous request.
-
-**TRACE_PROVIDER_BUFFER_SAVED**
-
-Sent from the trace manager to trace providers in streaming mode.
-Notify the trace provider that the requested buffer has been saved.
-The `data32` and `data64` fields must have the same values from the
-originating **TRACE_PROVIDER_SAVE_BUFFER** request.
diff --git a/docs/tracing/trace_format.md b/docs/tracing/trace_format.md
deleted file mode 100644
index fed123f..0000000
--- a/docs/tracing/trace_format.md
+++ /dev/null
@@ -1,910 +0,0 @@
-# Fuchsia Trace Format
-
-This document describes the binary format used to collect, store, and
-transmit Fuchsia trace records.
-
-See [Fuchsia Tracing](design.md) for an overview.
-
-## Purpose
-
-While a trace is running, _trace providers_ write records into a trace buffer
-VMO shared with the trace manager using the binary format described in this
-document.
-
-The binary format is designed to introduce minimal impact upon the
-performance of the subject under trace while writing traces.  The records
-are also written sequentially so that if a trace terminates (normally or
-abnormally), the trace manager can still recover partial trace data already
-stored in the trace buffer by reading everything up to the last well-formed
-record.
-
-As the trace progresses, the _trace manager_ aggregates records from all
-trace providers which are participating in trace collection and concatenates
-them together with some special metadata records to form a trace archive.
-
-Once the trace completes, tools such as the `trace` command-line program
-can read the trace records within the trace archive to visualize the results
-or save them to a file for later consumption.
-
-## Features
-
-- Small footprint
-  - Trace records are compact, packing information into a small number of bits.
-  - Pooling strings, processes, and threads further compacts the trace data.
-- Memory aligned
-  - Trace records maintain an 8 byte alignment in memory to facilitate
-    writing them directly into memory mapped VMOs.
-- Variable size records
-  - Overall record size is limited to 32 KB.
-  - Large objects may need to be broken up into multiple records.
-- Extensible
-  - There’s room to define new record types as needed.
-  - Unrecognized or malformed trace records can be skipped.
-
-## Encoding Primitives
-
-### Records
-
-A trace record is a binary encoded piece of trace information consisting of
-a sequence of [atoms](#atoms).
-
-All records include a header word which contains the following basic
-information:
-
-- **Record Type**: A 4-bit field which identifies the type of the record
-  and the information it contains.  See [Record Types](#record-types).
-- **Record Size**: A 12-bit field which indicates the number of words
-  (multiples of 8 byte units) within the record _including the record
-  header itself_.  The maximum possible size of a record is 4095 words
-  (32760 bytes).  Very simple records may be just 1 word (8 bytes) long.
-
-Records are always a multiple of 8 bytes in length and are stored with
-8 byte alignment.
-
-### Atoms
-
-Each record is constructed as a sequence of atoms.
-
-Each atom is written with 8 byte alignment and has a size which is also a
-multiple of 8 bytes so as to preserve alignment.
-
-There are two kinds of atoms:
-
-- **Word**: A 64-bit value which may be further subdivided into bit fields.
-  Words are stored in machine word order (little-endian on all currently
-  supported architectures).
-- **Stream**: A sequence of bytes padded with zeros to the next 8 byte
-  boundary.  Streams are stored in byte order.  Streams which are an exact
-  multiple of 8 bytes long are not padded (there is no zero terminator).
-
-**Fields** are subdivisions of 64-bit **Words**, denoted
-`[<least significant bit> .. <most significant bit>]` where the first and
-last bit positions are inclusive.  All unused bits are reserved for future
-use and must be set to 0.
-
-**Words** and **Fields** store unsigned integers unless otherwise specified
-by the record format.
-
-**Streams** may store either UTF-8 strings or binary data, as specified by
-the record format.
-
-### Archives
-
-A trace archive is a sequence of trace records, concatenated end to end,
-which stores information collected by trace providers while a trace is
-running together with metadata records which identify and delimit sections
-of the trace produced by each trace provider.
-
-Trace archives are intended to be read sequentially since records which
-appear earlier in the trace may influence the interpretation of records
-which appear later in the trace.  The trace system provides tools for
-extracting information from trace archives and converting it into other
-forms for visualization.
-
-### Timestamps
-
-Timestamps are represented as 64-bit ticks derived from a hardware counter.
-The trace initialization record describes the number of ticks per second
-of real time.
-
-By default, we assume that 1 tick equals 1 nanosecond.
-
-### String References
-
-Strings are encoded as **String Refs** which are 16-bit values of the
-following form:
-
-- **Empty strings**: Value is zero.
-- **Indexed strings**: Most significant bit is zero.  The lower 15 bits
-  denote an index in the **string table** which was previously assigned using a
-  **String Record**.
-- **Inline strings**: Most significant bit is one.  The lower 15 bits
-  denote the length of the string in bytes.  The string's content appears
-  inline in another part of the record as specified by the record format.
-
-To make traces more compact, frequently referenced strings, such as event
-category and name constants, should be registered into the **string table**
-using **String Records** then referenced by index.
-
-There can be at most 32767 strings in the string table.  If this limit is
-reached, additional strings can be encoded by replacing existing entries
-or by encoding strings inline.
-
-String content itself is stored as a UTF-8 **Stream** without termination.
-
-The theoretical maximum length of a string is 32767 bytes but in practice this
-will be further reduced by the space required to store the rest of the record
-which contains it, so we set a conservative maximum string length limit of
-32000 bytes.
-
-### Thread References
-
-Thread and process kernel object ids (koids) are encoded as **Thread Refs**
-which are 8-bit values of the following form:
-
-- **Inline threads**: Value is zero.  The thread and process koid appears
-  inline in another part of the record as specified by the record format.
-- **Indexed threads**: Value is non-zero.  The value denotes an index in
-  the **thread table** which was previously assigned using a **Thread Record**.
-
-To make traces more compact, frequently referenced threads should be registered
-into the **thread table** using **Thread Records** then referenced by index.
-
-There can be at most 255 threads in the string table.  If this limit is
-reached, additional threads can be encoded by replacing existing entries
-or by encoding threads inline.
-
-### Userspace Object Information
-
-Traces can include annotations about userspace objects (anything that can be
-referenced using a pointer-like value such as a C++ or Dart object) in the
-form of **Userspace Object Records**.  Trace providers typically generate
-such records when the object is created.
-
-Thereafter, any **Pointer Arguments** which refer to the same pointer will
-be associated with the referent's annotations.
-
-This makes it easy to associate human-readable labels and other information
-with objects which appear later in the trace.
-
-### Kernel Object Information
-
-Traces can include annotations about kernel objects (anything that can be
-referenced using a Zircon koid such as a process, channel, or event)
-form of **Kernel Object Records**.  Trace providers typically generate such
-records when the object is created.
-
-Thereafter, any **Kernel Object Id Arguments** which refer to the same koid will
-be associated with the referent's annotations.
-
-This makes it easy to associate human-readable labels and other information
-with objects which appear later in the trace.
-
-In particular, this is how the tracing system associates names with process
-and thread koids.
-
-### Arguments
-
-Arguments are typed key value pairs.
-
-Many record types allow up to 15 arguments to be appended to the record to
-provide additional information from the developer.
-
-Arguments are size-prefixed like ordinary records so that unrecognized
-argument types can be skipped.
-
-See also [Argument Types](#argument-types).
-
-## Extending the Format
-
-The trace format can be extended in the following ways:
-
-- Defining new record types.
-- Storing new information in reserved fields of existing record types.
-- Appending new information to existing record types (the presence of this
-  information can be detected by examining the record's size and payload).
-- Defining new argument types.
-
-_To preserve compatibility as the trace format evolves, all extensions must be
-documented authoritatively in this file.  Currently there is no support for
-private extensions._
-
-## Notation
-
-In the record format descriptions which follow, each constituent atom
-is labeled in italics followed by a bullet-point description of its contents.
-
-## Record Types
-
-### Record Header
-
-All records include this header which specifies the record's type and size
-together with 48 bits of data whose usage varies by record type.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 63]`: varies by record type (must be zero if unused)
-
-### Metadata Record (record type = 0)
-
-Provides metadata about trace data which follows.
-
-This record type is reserved for use by the _trace manager_ when generating
-trace archives.  It must not be emitted by trace providers themselves.
-If the trace manager encounters a **Metadata Record** within a trace produced
-by a trace provider, it treats it as garbage and skips over it.
-
-There are several metadata record subtypes, each of which contain different
-information.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (0)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 19]`: metadata type
-- `[20 .. 63]`: varies by metadata type (must be zero if unused)
-
-#### Provider Info Metadata (metadata type = 1)
-
-This metadata identifies a trace provider which has contributed information to
-the trace.
-
-All data which follows until the next **Provider Section Metadata** or
-**Provider Info Metadata** is encountered must have been collected from the
-same provider.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (0)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 19]`: metadata type (1)
-- `[20 .. 51]`: provider id (token used to identify the provider in the trace)
-- `[52 .. 59]`: name length in bytes
-- `[60 .. 63]`: reserved (must be zero)
-
-_provider name stream_
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-#### Provider Section Metadata (metadata type = 2)
-
-This metadata delimits sections of the trace which have been obtained from
-different providers.
-
-All data which follows until the next **Provider Section Metadata** or
-**Provider Info Metadata** is encountered is assumed to have been collected
-from the same provider.
-
-When reading a trace consisting of an accumulation of traces from different
-trace providers, the reader must maintain state separately for each provider’s
-traces (such as the initialization data, string table, thread table,
-userspace object table, and kernel object table) and switch contexts
-whenever it encounters a new **Provider Section Metadata** record.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (0)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 19]`: metadata type (2)
-- `[20 .. 51]`: provider id (token used to identify the provider in the trace)
-- `[52 .. 63]`: reserved (must be zero)
-
-#### Provider Event Metadata (metadata type = 3)
-
-This metadata provides running notification of events that the provider
-wants to report.
-This record may appear anywhere in the output, and does not delimit what
-came before it or what comes after it.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (0)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 19]`: metadata type (3)
-- `[20 .. 51]`: provider id (token used to identify the provider in the trace)
-- `[52 .. 55]`: the event id
-- `[56 .. 63]`: reserved (must be zero)
-
-##### Events
-
-The following events are defined.
-
-- `0`: a buffer filled up, records were likely dropped
-
-### Initialization Record (record type = 1)
-
-Provides parameters needed to interpret the records which follow.  In absence
-of this record, the reader may assume that 1 tick is 1 nanosecond.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (1)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 63]`: reserved (must be zero)
-
-_tick multiplier word_
-- `[0 .. 63]`: number of ticks per second
-
-### String Record (record type = 2)
-
-Registers a string in the string table, assigning it a string index in the
-range `0x0001` to `0x7fff`.  The registration replaces any prior registration
-for the given string index when interpreting the records which follow.
-
-String records which attempt to set a value for string index `0x0000` must be
-ignored since this value is reserved to represent the empty string.
-
-String records which contain empty strings must be tolerated but they’re
-pointless since the empty string can simply be encoded as zero in a string ref.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (2)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 30]`: string index (range 0x0001 to 0x7fff)
-- `[31]`: always zero (0)
-- `[32 .. 46]`: string length in bytes (range 0x0000 to 0x7fff)
-- `[47]`: always zero (0)
-- `[48 .. 63]`: reserved (must be zero)
-
-_string value stream_
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-### Thread Record (record type = 3)
-
-Registers a process id and thread id pair in the thread table, assigning it a
-thread index in the range `0x01` to `0xff`.  The registration replaces any
-prior registration for the given thread index when interpreting the records
-which follow.
-
-Thread index `0x00` is reserved to denote the use of an inline thread id in
-a thread ref.  Thread records which attempt to set a value for this value
-must be ignored.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (3)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 23]`: thread index (never 0x00)
-- `[24 .. 63]`: reserved (must be zero)
-
-_process id word_
-- `[0 .. 63]`: process koid (kernel object id)
-
-_thread id word_
-- `[0 .. 63]`: thread koid (kernel object id)
-
-### Event Record (record type = 4)
-
-Describes a timestamped event.
-
-This record consists of some basic information about the event including
-when and where it happened followed by event arguments and event subtype
-specific data.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (4)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 19]`: event type
-- `[20 .. 23]`: number of arguments
-- `[24 .. 31]`: thread (thread ref)
-- `[32 .. 47]`: category (string ref)
-- `[48 .. 63]`: name (string ref)
-
-_timestamp word_
-- `[0 .. 63]`: number of ticks
-
-_process id word_ (omitted unless thread ref denotes inline thread)
-- `[0 .. 63]`: process koid (kernel object id)
-
-_thread id word_ (omitted unless thread ref denotes inline thread)
-- `[0 .. 63]`: thread koid (kernel object id)
-
-_category stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument data_ (repeats for each argument)
-- (see below)
-
-_event-type specific data_
-- (see below)
-
-#### Instant Event (event type = 0)
-
-Marks a moment in time on this thread.  These are equivalent to Zircon
-kernel probes.
-
-##### Format
-
-No event-type specific data required.
-
-#### Counter Event (event type = 1)
-
-Records sample values of each argument as data in a time series associated
-with the counter’s name and id.  The values may be presented graphically as a
-stacked area chart.
-
-##### Format
-
-_counter word_
-- `[0 .. 63]`: counter id
-
-#### Duration Begin Event (event type = 2)
-
-Marks the beginning of an operation on a particular thread.  Must be matched
-by a **Duration End Event**.  May be nested.
-
-##### Format
-
-No event-type specific data required.
-
-#### Duration End Event (event type = 3)
-
-Marks the end of an operation on a particular thread.
-
-##### Format
-
-No event-type specific data required.
-
-#### Duration Complete Event (event type = 4)
-
-Marks the beginning and end of an operation on a particular thread.
-
-##### Format
-
-_end time word_
-- `[0 .. 63]`: end time number of ticks
-
-#### Async Begin Event (event type = 5)
-
-Marks the beginning of an operation which may span threads.  Must be matched
-by an **Async End Event** using the same async correlation id.
-
-##### Format
-
-_async correlation word_
-- `[0 .. 63]`: async correlation id
-
-#### Async Instant Event (event type = 6)
-
-Marks a moment within an operation which may span threads.  Must appear
-between **Async Begin Event** and **Async End Event** using the same async
-correlation id.
-
-##### Format
-
-_async correlation word_
-- `[0 .. 63]`: async correlation id
-
-#### Async End Event (event type = 7)
-
-Marks the end of an operation which may span threads.
-
-##### Format
-
-_async correlation word_
-- `[0 .. 63]`: async correlation id
-
-#### Flow Begin Event (event type = 8)
-
-Marks the beginning of an operation which results in a sequence of actions
-which may span multiple threads or abstraction layers.  Must be matched by a
-**Flow End Event** using the same flow correlation id.  This can be envisioned
-as an arrow between duration events.
-
-The beginning of the flow is associated with the enclosing duration event
-for this thread; it begins where the enclosing **Duration Event** ends.
-
-##### Format
-
-_flow correlation word_
-- `[0 .. 63]`: flow correlation id
-
-#### Flow Step Event (event type = 9)
-
-Marks a point within a flow.
-
-The step is associated with the enclosing duration event for this thread;
-the flow resumes where the enclosing duration event begins then is suspended
-at the point where the enclosing **Duration Event** event ends.
-
-##### Format
-
-_flow correlation word_
-- `[0 .. 63]`: flow correlation id
-
-#### Flow End Event (event type = 10)
-
-Marks the end of a flow.
-
-The end of the flow is associated with the enclosing duration event for this
-thread; the flow resumes where the enclosing **Duration Event** begins.
-
-##### Format
-
-_flow correlation word_
-- `[0 .. 63]`: flow correlation id
-
-### Blob Record (record type = 5)
-
-Provides uninterpreted bulk data to be included in the trace.  This can be
-useful for embedding captured trace data in other formats.
-
-The blob name uniquely identifies separate blob data streams within the trace.
-By writing multiple blob records with the same name, additional chunks of
-data can be appended to a previously created blob.
-
-The blob type indicates the representation of the blob's content.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (5)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: blob name (string ref)
-- `[32 .. 46]`: blob payload size in bytes (excluding padding)
-- `[47 .. 47]`: reserved (must be zero)
-- `[48 .. 55]`: blob type
-- `[56 .. 63]`: reserved (must be zero)
-
-_blob name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_payload stream_ (variable size)
-- binary data, padded with zeros to 8 byte alignment
-
-##### Blob Types
-
-The following blob types are defined:
-- `0x01`: Raw untyped data. Consumer is expected to know how to consume it, perhaps based on context.
-- `0x02`: Last Branch Record of Intel Performance Monitor. The format
-is defined by the Cpuperf Trace Provider.
-
-### Userspace Object Record (record type = 6)
-
-Describes a userspace object, assigns it a label, and optionally associates
-key/value data with it as arguments.  Information about the object is added
-to a per-process userspace object table.
-
-When a trace consumer encounters an event with a **Pointer Argument** whose
-value matches an entry in the process’s object table, it can cross-reference
-the argument’s pointer value with a prior **Userspace Object Record** to find a
-description of the referent.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (6)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 23]`: process (thread ref)
-- `[24 .. 39]`: name (string ref)
-- `[40 .. 43]`: number of arguments
-- `[44 .. 63]`: reserved (must be zero)
-
-_pointer word_
-- `[0 .. 63]`: pointer value
-
-_process id word_ (omitted unless thread ref denotes inline thread)
-- `[0 .. 63]`: process koid (kernel object id)
-
-_name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument data_ (repeats for each argument)
-- (see below)
-
-### Kernel Object Record (record type = 7)
-
-Describes a kernel object, assigns it a label, and optionally associates
-key/value data with it as arguments.  Information about the object is added
-to a global kernel object table.
-
-When a trace consumer encounters an event with a **Koid Argument**
-whose value matches an entry in the kernel object table, it can
-cross-reference the argument’s koid value with a prior **Kernel Object Record**
-to find a description of the referent.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (7)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 23]`: kernel object type (one of the ZX_OBJ_TYPE_XXX constants from <zircon/syscalls/object.h>)
-- `[24 .. 39]`: name (string ref)
-- `[40 .. 43]`: number of arguments
-- `[44 .. 63]`: reserved (must be zero)
-
-_kernel object id word_
-- `[0 .. 63]`: koid (kernel object id)
-
-_name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument data_ (repeats for each argument)
-- (see below)
-
-##### Argument Conventions
-
-By convention, the trace writer should include the following named arguments
-when writing kernel object records about objects of particular types.  This
-helps trace consumers correlate relationships among kernel objects.
-
-_This information may not always be available._
-
-- `“process”`: for `ZX_OBJ_TYPE_THREAD` objects, specifies the koid of the
-  process which contains the thread
-
-### Context Switch Record (record type = 8)
-
-Describes a context switch during which a CPU handed off control from an
-outgoing thread to an incoming thread which resumes execution.
-
-The record specifies the new state of the outgoing thread following the
-context switch.  By definition, the new state of the incoming thread is
-"running" since it was just resumed.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (4)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 23]`: cpu number
-- `[24 .. 27]`: outgoing thread state (any of the values below except “running”)
-- `[28 .. 35]`: outgoing thread (thread ref)
-- `[36 .. 43]`: incoming thread (thread ref)
-- `[44 .. 51]`: outgoing thread priority
-- `[52 .. 59]`: incoming thread priority
-- `[60 .. 63]`: reserved
-
-_timestamp word_
-- `[0 .. 63]`: number of ticks
-
-_outgoing process id word_ (omitted unless outgoing thread ref denotes inline thread)
-- `[0 .. 63]`: process koid (kernel object id)
-
-_outgoing thread id word_ (omitted unless outgoing thread ref denotes inline thread)
-- `[0 .. 63]`: thread koid (kernel object id)
-
-_incoming process id word_ (omitted unless incoming thread ref denotes inline thread)
-- `[0 .. 63]`: process koid (kernel object id)
-
-_incoming thread id word_ (omitted unless incoming thread ref denotes inline thread)
-- `[0 .. 63]`: thread koid (kernel object id)
-
-##### Thread States
-
-The following thread states are defined:
-- `0`: new
-- `1`: running
-- `2`: suspended
-- `3`: blocked
-- `4`: dying
-- `5`: dead
-
-These values align with the `ZX_THREAD_STATE_XXX` constants from <zircon/syscalls/object.h>.
-
-### Log Record (record type = 9)
-
-Describes a message written to the log at a particular moment in time.
-
-##### Format
-
-_header word_
-- `[0 .. 3]`: record type (9)
-- `[4 .. 15]`: record size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 30]`: log message length in bytes (range 0x0000 to 0x7fff)
-- `[31]`: always zero (0)
-- `[32 .. 39]`: thread (thread ref)
-- `[40 .. 63]`: reserved (must be zero)
-
-_timestamp word_
-- `[0 .. 63]`: number of ticks
-
-_process id word_ (omitted unless thread ref denotes inline thread)
-- `[0 .. 63]`: process koid (kernel object id)
-
-_thread id word_ (omitted unless thread ref denotes inline thread)
-- `[0 .. 63]`: thread koid (kernel object id)
-
-_log message stream_
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-## Argument Types
-
-Arguments associate typed key/value data records.  They are used together
-with **Event Record** and **Userspace Object Record** and
-**Kernel Object Record**.
-
-Each argument consists of a one word header followed by a variable number
-words of payload.  In many cases, the header itself is sufficient to encode
-the content of the argument.
-
-### Argument Header
-
-All arguments include this header which specifies the argument's type,
-name, and size together with 32 bits of data whose usage varies by
-argument type.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: varies (must be zero if not used)
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-### Null Argument (argument type = 0)
-
-Represents an argument which appears in name only without a value.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (0)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: reserved (must be zero)
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-### 32-bit Signed Integer Argument (argument type = 1)
-
-Represents a 32-bit signed integer.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (1)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: 32-bit signed integer
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-### 32-bit Unsigned Integer Argument (argument type = 2)
-
-Represents a 32-bit unsigned integer.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (2)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: 32-bit unsigned integer
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-### 64-bit Signed Integer Argument (argument type = 3)
-
-Represents a 64-bit signed integer.  If a value will fit in 32-bits, prefer
-using the **32-bit Signed Integer Argument** type instead.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (3)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: reserved (must be zero)
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument value word_
-- `[0 .. 63]`: 64-bit signed integer
-
-### 64-bit Unsigned Integer Argument (argument type = 4)
-
-Represents a 64-bit unsigned integer.  If a value will fit in 32-bits, prefer
-using the **32-bit Unsigned Integer Argument** type instead.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (4)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: reserved (must be zero)
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument value word_
-- `[0 .. 63]`: 64-bit unsigned integer
-
-### Double-precision Floating Point Argument (argument type = 5)
-
-Represents a double-precision floating point number.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (5)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: reserved (must be zero)
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument value word_
-- `[0 .. 63]`: double-precision floating point number
-
-### String Argument (argument type = 6)
-
-Represents a string value.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (6)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 47]`: argument value (string ref)
-- `[48 .. 63]`: reserved (must be zero)
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument value stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-### Pointer Argument (argument type = 7)
-
-Represents a pointer value.  Additional information about the referent can
-be provided by a **Userspace Object Record** associated with the same pointer.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (7)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: reserved (must be zero)
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument value word_
-- `[0 .. 63]`: the pointer value
-
-### Kernel Object Id Argument (argument type = 8)
-
-Represents a koid (kernel object id).  Additional information about the
-referent can be provided by a **Kernel Object Record** associated with the
-same koid.
-
-##### Format
-
-_argument header word_
-- `[0 .. 3]`: argument type (8)
-- `[4 .. 15]`: argument size (inclusive of this word) as a multiple of 8 bytes
-- `[16 .. 31]`: argument name (string ref)
-- `[32 .. 63]`: reserved (must be zero)
-
-_argument name stream_ (omitted unless string ref denotes inline string)
-- UTF-8 string, padded with zeros to 8 byte alignment
-
-_argument value word_
-- `[0 .. 63]`: the koid (kernel object id)
diff --git a/docs/userboot.md b/docs/userboot.md
deleted file mode 100644
index 61fd39f..0000000
--- a/docs/userboot.md
+++ /dev/null
@@ -1,180 +0,0 @@
-# Zircon kernel to userspace bootstrapping (`userboot`)
-
-Zircon has a microkernel style of design.  A complexity for microkernel
-designs is how to bootstrap the initial userspace processes.  Often this
-is accomplished by having the kernel implement minimal versions of
-filesystem reading and program loading just for the purpose of
-bootstrapping, even when those kernel facilities are never used after boot
-time.  Zircon takes a different approach.
-
-[TOC]
-
-## Boot loader and kernel startup
-
-A boot loader loads the kernel into memory and transfers control to the
-kernel's startup code.  The details of the boot loader protocols are not
-described here.  The boot loaders used with Zircon load both the kernel
-image and a data blob in Zircon Boot Image format.
-The [ZBI format](../system/public/zircon/boot/image.h) is a
-simple container format that embeds items passed by the boot loader,
-including hardware-specific information,
-the [kernel "command line"](kernel_cmdline.md) giving boot options, and RAM
-disk images (which are usually compressed).  The kernel extracts some
-essential information for its own use in the early stages of booting.
-
-## BOOTFS
-
-One of the items embedded in the Zircon Boot Image is an initial RAM disk
-filesystem image.  The image is usually compressed using the **LZ4**
-format.  Once decompressed, the image is in **BOOTFS** format.  This is a
-trivial read-only filesystem format that simply lists file names, and for
-each file the offset and size within the BOOTFS image (both values must be
-page-aligned both fields and are limited to 32 bits).
-
-The primary BOOTFS image contains everything that the userspace system
-needs to run: executables, shared libraries, and data files.  These include
-the implementations of device drivers and more advanced filesystems that
-make it possible to read more code and data from storage or network
-devices.
-
-After the system has bootstrapped itself, the files in the primary
-BOOTFS become the read-only filesystem tree rooted at `/boot` (and served by
-bootsvc).
-
-## Kernel loads userboot
-
-The kernel does not include any code for decompressing LZ4 format, nor
-any code for interpreting the BOOTFS format.  Instead, all of this work
-is done by the first userspace process, called `userboot`.
-
-`userboot` is a normal userspace process.  It can only make the standard
-system calls through the [vDSO](vdso.md) like any other process would, and
-is subject to the full [vDSO enforcement](vdso.md#Enforcement) regime.
-What's special about `userboot` is the way it gets loaded.
-
-`userboot` is built as an ELF dynamic shared object, using the
-same [RODSO layout](vdso.md#Read_Only-Dynamic-Shared-Object-Layout) as
-the vDSO.  Like the vDSO, the `userboot` ELF image is embedded in the
-kernel at compile time.  Its simple layout means that loading it does
-not require the kernel to interpret ELF headers at boot time.  The
-kernel only needs to know three things: the size of the read-only
-segment, the size of the executable segment, and the address of the
-`userboot` entry point.  At compile time, these values are extracted
-from the `userboot` ELF image and used as constants in the kernel code.
-
-Like any other process, `userboot` must start with the vDSO already
-mapped into its address space so it can make system calls.  The kernel
-maps both `userboot` and the vDSO into the first user process, and then
-starts it running at the `userboot` entry point.
-
-## Kernel sends `processargs` message
-
-In normal [program loading](program_loading.md),
-a [*bootstrap message*](program_loading.md#the-processargs-protocol) is
-sent to each new process.  The process's first thread receives
-a [channel](objects/channel.md) handle in a register.  It can then read
-data and handles sent by its creator.
-
-The kernel uses the exact same protocol to start `userboot`.  The kernel
-command line is split into words that become the environment strings in the
-bootstrap message.  All the handles that `userboot` itself will need, and
-that the rest of the system will need to access kernel facilities, are
-included in this message.  Following the normal format, *handle info
-entries* describe the purpose of each handle.  These include
-the [`PA_VMO_VDSO` handle](vdso.md#pa_vmo_vdso-handle).
-
-## userboot finds system calls in the vDSO
-
-The [standard convention](vdso.md#process_start_argument) for informing
-a new process of its vDSO mapping requires the process to interpret the
-vDSO's ELF headers and symbol table to locate system call entry points.
-To avoid this complexity, `userboot` finds the entry points in the vDSO
-in a different way.
-
-When the kernel maps `userboot` into the first user process, it chooses
-a random location in memory, just as normal program loading does.
-However, when it maps the vDSO in it doesn't choose another random
-location as is normal.  Instead, it places the vDSO image immediately
-after the `userboot` image in memory.  This way, the vDSO code is always
-at fixed offsets from the `userboot` code.
-
-At compile time, the symbol table entries for all the system call entry
-points are extracted from the vDSO ELF image.  These are then massaged
-into linker script symbol definitions that use each symbol's fixed
-offset into the vDSO image to define that symbol at that fixed offset
-from the linker-provided `_end` symbol.  In this way, the `userboot`
-code can make direct calls to each vDSO entry point in the exact
-location it will appear in memory after the `userboot` image itself.
-
-## userboot decompresses BOOTFS
-
-The first thing `userboot` does is to read the bootstrap message sent by
-the kernel.  Among the handles it gets from the kernel is one with
-*handle info entry* `PA_HND(PA_VMO_BOOTDATA, 0)`.  This is
-a [VMO](objects/vm_object.md) containing the ZBI from the
-boot loader.  `userboot` reads the ZBI headers from this VMO
-looking for the first item with type `ZBI_TYPE_STORAGE_BOOTFS`.  That
-contains the [BOOTFS](#BOOTFS) image.  The item's ZBI header
-indicates if it's compressed, which it usually is.  `userboot` maps in
-this portion of the VMO.  `userboot` contains LZ4 format support code,
-which it uses to decompress the item into a fresh VMO.
-
-## userboot loads the first "real" user process from BOOTFS
-
-Next, `userboot` examines the environment strings it received from the
-kernel, which represent the kernel command line.  If there is a string
-`userboot=`*file* then *file* will be loaded as the first real user
-process.  If no such option is present, the default *file* is `bin/bootsvc`.
-The files are found in the BOOTFS image.
-
-To load the file, `userboot` implements a full-featured ELF program loader.
-Usually the file being loaded is a dynamically-linked executable with a
-`PT_INTERP` program header.  In this case, `userboot` looks for the file
-named in `PT_INTERP` and loads that instead.
-
-Then `userboot` loads the vDSO at a random address.  It starts the new
-process with the standard conventions, passing it a channel handle and the
-vDSO base address.  On that channel, `userboot` sends the
-standard [`processargs`](program_loading.md#the-processargs-protocol)
-messages.  It passes on all the important handles it received from the
-kernel (replacing specific handles such as the process-self and thread-self
-handles with those for the new process rather than for `userboot` itself).
-
-## userboot loader service
-
-Following the standard program loading protocol, when `userboot` loads a
-program via `PT_INTERP`, it sends an additional `processargs` message
-before the main message, intended for the use of the dynamic linker.  This
-message includes a `PA_LDSVC_LOADER` handle for a channel on which `userboot`
-provides a minimal implementation of the
-standard [loader service](program_loading.md#the-loader-service).
-
-`userboot` has only a single thread, which remains in a loop handling
-loader service requests until the channel is closed.  When it receives a
-`LOADER_SVC_OP_LOAD_OBJECT` request, it looks up the object name prefixed
-by `lib/` as a file in BOOTFS and returns a VMO of its contents.  Thus, the
-first "real" user process can be (and usually is) a dynamically linked
-executable needing various shared libraries.  The dynamic linker, the
-executable, and the shared libraries are all loaded from the same BOOTFS
-pages that will later appear as files in `/boot`.
-
-An executable that will be loaded by `userboot` (i.e. [`bootsvc`](bootsvc.md)) should
-normally close its loader service channel once it's completed startup.
-That lets `userboot` know that it's no longer needed.
-
-## userboot rides off into the sunset
-
-When the loader service channel is closed (or if the executable had no
-`PT_INTERP` and so no loader service was required, then as soon as the
-process has been started), `userboot` no longer has anything to do.
-
-If [the `userboot.shutdown` option was given on the kernel command line](kernel_cmdline.md#userboot_shutdown),
-then `userboot` waits for the process it started to exit, and then shuts
-down the system (as if by the `dm shutdown` command).  This can be useful
-to run a single test program and then shut down the machine (or emulator).
-For example, the command line `userboot=bin/core-tests userboot.shutdown`
-runs the Zircon core tests and then shuts down.
-
-Otherwise, `userboot` does not wait for the process to exit.  `userboot`
-exits immediately, leaving the first "real" user process in charge of
-bringing up and taking down the rest of the system.
diff --git a/docs/vdso.md b/docs/vdso.md
deleted file mode 100644
index e0775af..0000000
--- a/docs/vdso.md
+++ /dev/null
@@ -1,283 +0,0 @@
-# Zircon vDSO
-
-The Zircon vDSO is the sole means of access to [system calls](syscalls.md)
-in Zircon.  vDSO stands for *virtual Dynamic Shared Object*.  (*Dynamic
-Shared Object* is a term used for a shared library in the ELF format.)
-It's *virtual* because it's not loaded from an ELF file that sits in a
-filesystem.  Instead, the vDSO image is provided directly by the kernel.
-
-[TOC]
-
-## Using the vDSO
-
-### System Call ABI
-
-The vDSO is a shared library in the ELF format.  It's used in the normal
-way that ELF shared libraries are used, which is to look up entry points by
-symbol name in the ELF *dynamic symbol table* (the `.dynsym` section,
-located via `DT_SYMTAB`).  ELF defines a hash table format to optimize
-lookup by name in the symbol table (the `.hash` section, located via
-`DT_HASH`); GNU tools have defined an improved hash table format that makes
-lookups much more efficient (the `.gnu_hash` section, located via
-`DT_GNU_HASH`).  Fuchsia ELF shared libraries, including the vDSO, use the
-`DT_GNU_HASH` format exclusively.  (It's also possible to use the symbol
-table directly via linear search, ignoring the hash table.)
-
-The vDSO uses a [simplified layout](#Read_Only-Dynamic-Shared-Object-Layout)
-that has no writable segment and requires no dynamic relocations.  This
-makes it easier to use the system call ABI without implementing a
-general-purpose ELF loader and full ELF dynamic linking semantics.
-
-ELF symbol names are the same as C identifiers with external linkage.
-Each [system call](syscalls.md) corresponds to an ELF symbol in the vDSO,
-and has the ABI of a C function.  The vDSO functions use only the basic
-machine-specific C calling conventions governing the use of machine
-registers and the stack, which is common across many systems that use ELF,
-such as Linux and all the BSD variants.  They do not rely on complex
-features such as ELF Thread-Local Storage, nor on Fuchsia-specific ABI
-elements such as the [SafeStack](safestack.md) unsafe stack pointer.
-
-### vDSO Unwind Information
-
-The vDSO has an ELF program header of type `PT_GNU_EH_FRAME`.  This points
-to unwind information in the GNU `.eh_frame` format, which is a close
-relative of the standard DWARF Call Frame Information format.  This
-information makes it possible to recover the register values from call
-frames in the vDSO code, so that a complete stack trace can be reconstructed
-from any thread's register state with a PC value inside the vDSO code.
-These formats and their use are just the same in the vDSO as they are in any
-normal ELF shared library on Fuchsia or other systems using common GNU ELF
-extensions, such as Linux and all the BSD variants.
-
-### vDSO Build ID
-
-The vDSO has an ELF *Build ID*, as other ELF shared libraries and
-executables built with common GNU extensions do.  The Build ID is a unique
-bit string that identifies a specific build of that binary.  This is stored
-in ELF note format, pointed to by an ELF program header of type `PT_NOTE`.
-The payload of the note with name `"GNU"` and type `NT_GNU_BUILD_ID` is a
-sequence of bytes that constitutes the Build ID.
-
-One main use of Build IDs is to associate binaries with their debugging
-information and the source code they were built from.  The vDSO binary is
-innately tied to (and embedded within) the kernel binary and includes
-information specific to each kernel build, so the Build ID of the vDSO
-distinguishes kernels as well.
-
-### **process_start**() argument
-
-The [**process_start**()](syscalls/process_start.md) system call is how a
-program loader tells the kernel to start a new process's first thread
-executing.  The final argument (`arg2`
-in [the **process_start**() documentation](syscalls/process_start.md)) is a
-plain `uintptr_t` value passed to the new thread in a register.
-
-By convention, the program loader maps the vDSO into each new process's
-address space (at a random location chosen by the system) and passes the
-base address of the image to the new process's first thread in the `arg2`
-register.  This address is where the ELF file header can be found in memory,
-pointing to all the other ELF format elements necessary to look up symbol
-names and thus make system calls.
-
-### **PA_VMO_VDSO** handle
-
-The vDSO image is embedded in the kernel at compile time.  The kernel
-exposes it to userspace as a read-only [VMO](objects/vm_object.md).
-
-When a program loader sets up a new process, the only way to make it
-possible for that process to make system calls is for the program loader to
-map the vDSO into the new process's address space before its first thread
-starts running.  Hence, each process that will launch other processes
-capable of making system calls must have access to the vDSO VMO.
-
-By convention, a VMO handle for the vDSO is passed from process to process
-in the `zx_proc_args_t` bootstrap message sent to each new process
-(see [`<zircon/processargs.h>`](../system/public/zircon/processargs.h)).
-The VMO handle's entry in the handle table is identified by the *handle
-info entry* `PA_HND(PA_VMO_VDSO, 0)`.
-
-## vDSO Implementation Details
-
-### **abigen** tool
-
-The [`abigen` tool](../system/host/abigen/) generates both C/C++ function
-declarations that form the public [system call](syscalls.md) API, and some
-C++ and assembly code used in the implementation of the vDSO.  Both the
-public API and the private interface between the kernel and the vDSO code
-are specified by
-[`<zircon/syscalls.abigen>`](../system/public/zircon/syscalls.abigen),
-which is the input to `abigen`.
-
-The `syscall` entries in `syscalls.abigen` fall into the following groups,
-distinguished by the presence of attributes after the system call name:
-
- * Entries with neither `vdsocall` nor `internal` are the simple cases
-   (which are the majority of the system calls) where the public API and
-   the private API are exactly the same.  These are implemented entirely
-   by generated code.  The public API functions have names prefixed by
-   `_zx_` and `zx_` (aliases).
-
-* `vdsocall` entries are simply declarations for the public API.
-  These functions are implemented by normal, hand-written C++ code found
-  in [`system/ulib/zircon/`](../system/ulib/zircon/).  Those source
-  files `#include "private.h"` and then define the C++ function for the
-  system call with its name prefixed by `_zx_`.  Finally, they use the
-  `VDSO_INTERFACE_FUNCTION` macro on the system call's name prefixed by
-  `zx_` (no leading underscore).  This implementation code can call the
-  C++ function for any other system call entry (whether a public
-  generated call, a public hand-written `vdsocall`, or an `internal`
-  generated call), but must use its private entry point alias, which has
-  the `VDSO_zx_` prefix.  Otherwise the code is normal (minimal) C++,
-  but must be stateless and reentrant (use only its stack and registers).
-
- * `internal` entries are declarations of a private API used only by the
-   vDSO implementation code to enter the kernel (i.e., by other functions
-   implementing `vdsocall` system calls).  These produce functions in the
-   vDSO implementation with the same C signature that would be declared in
-   the public API given the signature of the system call entry.  However,
-   instead of being named with the `_zx_` and `zx_` prefixes, these are
-   available only via `#include "private.h"` with `VDSO_zx_` prefixes.
-
-### Read-Only Dynamic Shared Object Layout
-
-The vDSO is a normal ELF shared library and can be treated like any
-other.  But it's intentionally kept to a small subset of what an ELF
-shared library in general is allowed to do.  This has several benefits:
-
- * Mapping the ELF image into a process is straightforward and does not
-   involve any complex corner cases of general support for ELF `PT_LOAD`
-   program headers.  The vDSO's layout can be handled by special-case
-   code with no loops that reads only a few values from ELF headers.
- * Using the vDSO does not require full-featured ELF dynamic linking.
-   In particular, the vDSO has no dynamic relocations.  Mapping in the
-   ELF `PT_LOAD` segments is the only setup that needs to be done.
- * The vDSO code is stateless and reentrant.  It refers only to the
-   registers and stack with which it's called.  This makes it usable in
-   a wide variety of contexts with minimal constraints on how user code
-   organizes itself, which is appropriate for the mandatory ABI of an
-   operating system.  It also makes the code easier to reason about and
-   audit for robustness and security.
-
-The layout is simply two consecutive segments, each containing aligned
-whole pages:
-
- 1. The first segment is read-only, and includes the ELF headers and
-    metadata for dynamic linking along with constant data private to the
-    vDSO's implementation.
- 2. The second segment is executable, containing the vDSO code.
-
-The whole vDSO image consists of just these two segments' pages, present
-in the ELF image just as they should appear in memory.  To map in the
-vDSO requires only two values gleaned from the vDSO's ELF headers: the
-number of pages in each segment.
-
-### Boot-time Read-Only Data
-
-Some system calls simply return values that are constant throughout the
-runtime of the whole system, though the ABI of the system is that their
-values must be queried at runtime and cannot be compiled into user code.
-These values either are fixed in the kernel at compile time or are
-determined by the kernel at boot time from hardware or boot parameters.
-Examples include [**system_get_version**()](syscalls/system_get_version.md),
-[**system_get_num_cpus**()](syscalls/system_get_num_cpus.md), and
-[**ticks_per_second**()](syscalls/ticks_per_second.md).
-The last example is influenced by
-a [kernel command line option](kernel_cmdline.md#vdso_soft_ticks_bool).
-
-Because these values are constant, there is no need to pay the overhead
-of entering the kernel to read them.  Instead, the vDSO implementations
-of these are simple C++ functions that just return constants read from
-the vDSO's read-only data segment.  Values fixed at compile time (such
-as the system version string) are simply compiled into the vDSO.
-
-For the values determined at boot time, the kernel must modify the
-contents of the vDSO.  This is accomplished by the boot-time code that
-sets up the vDSO VMO, before it starts the first userspace process and
-gives it the VMO handle.  At compile time, the offset into the vDSO
-image of
-the [`vdso_constants`](../kernel/lib/vdso/include/lib/vdso-constants.h)
-data structure is extracted from the vDSO ELF file that will be embedded
-in the kernel.  At boot time, the kernel temporarily maps the pages of
-the VMO covering `vdso_constants` into its own address space long enough
-to initialize the structure with the right values for the current run of
-the system.
-
-### Enforcement
-
-The vDSO entry points are the only means to enter the kernel for system
-calls.  The machine-specific instructions used to enter the kernel
-(e.g. `syscall` on x86) are not part of the system ABI and it's invalid
-for user code to execute such instructions directly.  The interface
-between the kernel and the vDSO code is a private implementation detail.
-
-Because the vDSO is itself normal code that executes in userspace, the
-kernel must robustly handle all possible entries into kernel mode from
-userspace.  However, potential kernel bugs can be mitigated somewhat by
-enforcing that each kernel entry be made only from the proper vDSO code.
-This enforcement also avoids developers of userspace code circumventing
-the ABI rules (because of ignorance, malice, or misguided intent to work
-around some perceived limitation of the official ABI), which could lead
-to the private kernel-vDSO interface becoming a *de facto* ABI for
-application code.
-
-The kernel enforces correct use of the vDSO in two ways:
-
- 1. It constrains how the vDSO VMO can be mapped into a process.
-
-    When a [**vmar_map**()](syscalls/vmar_map.md) call is made using the
-    vDSO VMO and requesting `ZX_VM_PERM_EXECUTE`, the kernel
-    requires that the offset and size of the mapping exactly match the
-    vDSO's executable segment.  It also allows only one such mapping.
-    Once the valid vDSO mapping has been established in a process, it
-    cannot be removed.  Attempts to map the vDSO a second time into the
-    same process, to unmap the vDSO code from a process, or to make an
-    executable mapping of the vDSO that don't use the correct offset and
-    size, fail with `ZX_ERR_ACCESS_DENIED`.
-
-    At compile time, the offset and size of the vDSO's code segment are
-    extracted from the vDSO ELF file and used as constants in the
-    kernel's mapping enforcement code.
-
-    When the one valid vDSO mapping is established in a process, the
-    kernel records the address for that process so it can be checked
-    quickly.
-
- 2. It constrains what PC locations can be used to enter the kernel.
-
-    When a user thread enters the kernel for a system call, a register
-    indicates which low-level system call is being invoked.  The
-    low-level system calls are the private interface between the kernel
-    and the vDSO; many correspond directly the system calls in the
-    public ABI, but others do not.
-
-    For each low-level system call, there is a fixed set of PC locations
-    in the vDSO code that invoke that call.  The source code for the
-    vDSO defines internal symbols identifying each such location.  At
-    compile time, these locations are extracted from the vDSO's symbol
-    table and used to generate kernel code that defines a PC validity
-    predicate for each low-level system call.  Since there is only one
-    definition of the vDSO code used by all user processes in the
-    system, these predicates simply check for known, valid, constant
-    offsets from the beginning of the vDSO code segment.
-
-    On entry to the kernel for a system call, the kernel examines the PC
-    location of the `syscall` instruction on x86 (or equivalent
-    instruction on other machines).  It subtracts the base address of
-    the vDSO code recorded for the process at **vmar_map**() time from
-    the PC, and passes the resulting offset to the validity predicate
-    for the system call being invoked.  If the predicate rules the PC
-    invalid, the calling thread is not allowed to proceed with the
-    system call and instead takes a synthetic exception similar to the
-    machine exception that would result from invoking an undefined or
-    privileged machine instruction.
-
-### Variants
-
-**TODO(mcgrathr)**: vDSO *variants* are an experimental feature that is
-not yet in real use.  There is a proof-of-concept implementation and
-simple tests, but more work is required to implement the concept
-robustly and determine what variants will be made available.  The
-concept is to provide variants of the vDSO image that export only a
-subset of the full vDSO system call interface.  For example, system
-calls intended only for use by device drivers might be elided from the
-vDSO variant used for normal application code.
diff --git a/docs/zx_and_lk.md b/docs/zx_and_lk.md
deleted file mode 100644
index cf92621..0000000
--- a/docs/zx_and_lk.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Zircon and LK
-
-Zircon was born as a branch of [LK](https://github.com/littlekernel/lk) and even
-now many inner constructs are based on LK while the layers above are new. For
-example, Zircon has the concept of a process but LK does not. However, a Zircon
-process is made of LK-level constructs such as LK's ``thread_t``.
-
-LK is a Kernel designed for small systems typically used in embedded
-applications. It is a good alternative to commercial offerings like
-[FreeRTOS](http://www.freertos.org/) or [ThreadX](http://rtos.com/products/threadx/).
-Such systems often have a very limited amount of ram, a fixed set of peripherals
-and a bounded set of tasks.
-
-On the other hand, Zircon targets modern phones and modern personal computers
-with fast processors, non-trivial amounts of ram with arbitrary peripherals
-doing open ended computation.
-
-More specifically, some the visible differences are:
-
-+ LK can run in 32-bit systems. Zircon is 64-bit only.
-+ Zircon has first class user-mode support. LK does not.
-+ Zircon has a capability-based security model. In LK all code is trusted.
-
-Over time, even the low level constructs have changed to accommodate the new
-requirements and to better fit the rest of the system.
-
diff --git a/docs/zxcrypt.md b/docs/zxcrypt.md
deleted file mode 100644
index bb85d6e..0000000
--- a/docs/zxcrypt.md
+++ /dev/null
@@ -1,198 +0,0 @@
-# zxcrypt
-
-__<font color=red>ALERT: zxcrypt is not secure until [ZX-1130][zx1130] is resolved!</font>__
-
-## Overview
-zxcrypt is a block device filter driver that transparently encrypts data being written to and
-decrypts being read from data a block device.  The underlying block device that a zxcrypt device
-uses may be almost any block device, including raw disks, ramdisks, GPT partitions, FVM partitions
-or even other zxcrypt devices.  The only restriction is that the block size be page-aligned.  Once
-bound, the zxcrypt device will publish another block device in the device tree that consumers can
-interact with normally.
-
-## Usage
-zxcrypt contains both a [driver](../system/dev/block/zxcrypt) and [library](../system/ulib/zxcrypt)
-Provided by libzxcrypt.so are four functions for managing zxcrypt devices.  Each takes one or more
-`zxcrypt_key_t` keys, which associates the key data, length, and slot in the case of multiple keys.
-* The __zxcrypt_format__ function takes an open block device, and writes the necessary encrypted
-  metadata to make it a zxcrypt device.  The zxcrypt key provided does not protect the data on the
-  device directly, but is used to protect the data key material.
-```c++
-zx_status_t zxcrypt_format(int fd, const zxcrypt_key_t* key);
-```
-* The __zxcrypt_bind__ function instructs the driver to read the encrypted metadata and extract the
-  data key material to use in transparently transforming I/O data.
-```c++
-zx_status_t zxcrypt_bind(int fd, const zxcrypt_key_t *key);
-```
-* The __zxcrypt_rekey__ function uses the old key to first read the encrypted metadata, and the new
-  key to write it back.
-```c++
-zx_status_t zxcrypt_rekey(int fd, const zxcrypt_key_t* old_key, const zxcrypt_key_t* new_key);
-```
-* The __zxcrypt_shred__ function first verifies that the caller can access the data by using the key
-  provided to read the encrypted metadata.  If this succeeded, it then destroys the encrypted
-  metadata containing the data key material.  This prevents any future access to the data.
-```c++
-zx_status_t zxcrypt_shred(int fd, const zxcrypt_key_t* key);
-```
-
-## Technical Details
-### DDKTL Driver
-zxcrypt is written as a DDKTL device driver.  [ulib/ddktl](../system/ulib/ddktl) is a C++ framework
-for writing drivers in Fuchsia.  It allows authors to automatically supply the
-[ulib/ddk](../system/ulib/ddk) function pointers and callbacks by using templatized mix-ins.  In the
-case of zxcrypt, the [device](../system/dev/block/zxcrypt/device.h) is "Ioctlable",
-"IotxnQueueable", "GetSizable", "Unbindable", and implements the methods listed in DDKTL's
-[BlockProtocol](../system/ulib/ddktl/include/ddktl/protocol/block.h).
-
-There are two small pieces of functionality which cannot be written in DDKTL and C++:
-* The driver binding logic, written using the C preprocessor macros of DDK's
-  [binding.h](../system/public/zircon/driver/binding.h).
-* The completion routines of [ulib/sync](../system/ulib/sync), which are used for synchronous I/O
-  and are incompatible with C++ atomics.
-
-### Worker Threads
-The device starts [worker threads](../system/dev/block/zxcrypt/worker.h) that run for the duration
-of the device and create a pipeline for all I/O requests.  Each has a type of I/O it operates on, a
-queue of incoming requests I/O that it will wait on, and a data cipher.  When a request is received,
-if the opcode matches the one it is looking for, it will use its cipher to transform the data in the
-request before passing it along.
-
-The overall pipeline is as shown:
-```
-DdkIotxnQueue -+
-                \       Worker 1:        Underlying      Worker 2:        Original
-    BlockRead ---+--->  Encrypter   --->   Block   --->  Decrypter  ---> Completion
-                /     Acts on writes       Device      Acts on reads      Callback
-   BlockWrite -+
-```
-
-The "encrypter" worker encrypts the data in every I/O write request before sending it to the
-underlying block device, and the "decrypter" worker decrypts the data in every I/O read response
-coming from the underlying block device.  The
-[cipher](../system/ulib/crypto/include/crypto/cipher.h) must have a key length of at least 16 bytes,
-be semantically secure ([IND-CCA2][ind-cca2]) and incorporate the block offset as a
-"[tweak][tweak]".  Currently, [AES256-XTS][aes-xts] is in use.
-
-### Rings and Txns
-In order to keep the encryption and decryption of data transparent to original I/O requester, the
-workers must copy the data when transforming it.  The I/O request sent through the pipeline is not
-actually the original request, but instead a "shadow" request that encapsulates the original
-request.  These shadows requests are managed by the [Txn](../system/dev/block/zxcrypt/txn.h) class,
-and allocated from the [Ring](../system/dev/block/zxcrypt/ring.h) class. The Ring is an enormous,
-yet very sparse, [VMO](concepts.md#shared-memory-virtual-memory-objects-vmos-).
-
-As shadow requests are needed, they are allocated backed sequentially by pages in the VMO.  When the
-worker needs to transform the data it either encrypts data from the original, encapsulated write
-request into the shadow request, or decrypts data from the shadow request into the original,
-encapsulated read request.  As soon as the original request can be handed back to the original
-requester, the shadow request is deallocated and its page [decommitted](syscalls/vmo_op_range.md).
-This ensures no more memory is used than is needed for outstanding I/O requests.
-
-### Superblock Format
-The key material for encrypting and decrypting the data is referred to as the data key, and is
-stored in a reserved portion of the device called the
-[superblock](../system/ulib/zxcrypt/include/zxcrypt/superblock.h).  The presence of this superblock
-is critical; without it, it is impossible to recreate the data key and recover the data on the
-device.  As a result, the superblock is copied to multiple locations on the device for redundancy.
-These locations are not visible to zxcrypt block device consumers.  Whenever the zxcrypt driver
-successfully reads and validates a superblock from one location, it will copy this to all other
-superblock locations to help "self-heal" any corrupted superblock locations.
-
-The superblock format is as follows, with each field described in turn:
-```
-+----------------+----------------+----+-----...-----+----...----+------...------+
-| Type GUID      | Instance GUID  |Vers| Sealed Key  | Reserved  | HMAC          |
-| 16 bytes       | 16 bytes       | 4B | Key size    |    ...    | Digest length |
-+----------------+----------------+----+-----...-----+----...----+------...------+
-```
-* _Type [GUID][guid]_: Identifies this as a zxcrypt device. Compatible with
-  [GPT](../system/ulib/gpt/include/gpt/gpt.h).
-* _Instance GUID_: Per-device identifier, used as the KDF salt as explained below.
-* _Version_: Used to indicate which cryptographic algorithms to use.
-* _Sealed Key_: The data key, encrypted by the wrap key as describer below.
-* _Reserved_: Unused data to align the superblock with the block boundary.
-* [_HMAC_][hmac]: A keyed digest of the superblock up to this point (including the Reserved field).
-
-The wrap key, wrap [IV][iv], and HMAC key are all derived from a
-[KDF](../system/ulib/crypto/include/crypto/kdf.h).  This KDF is an [RFC 5869 HKDF][hkdf], which
-combines the key provided, the "salt" of the instance GUID and a per-use label such as "wrap" or
-"hmac".  The KDF does __NOT__ try to do any rate-limiting.  The KDF mitigates the risk of key reuse,
-as a new random instance salt will lead to new derived keys.  The
-[HMAC](../system/ulib/crypto/include/crypto/hmac.h) prevents accidental or malicious modification to
-go undetected, without leaking any useful information about the zxcrypt key.
-
-_NOTE: The KDF does __NOT__ do any [key stretching][stretch].  It is assumed that an attacker can
-remove a device and attempt the key derivations on their own, bypassing the HMAC check and any
-possible rate limits.  To prevent this, zxcrypt consumers should include properly rate-limited
-device keys, e.g. those from a [TPM][tpm], in deriving their zxcrypt key._
-
-## Future Work
-There are a number of areas where further work could, should, or must be done:
-* __Properly bind with keys__ ([bug][zx1130])
-
-  Currently, there is __NO__ way to inject a key at binding.  This forces zxcrypt to currently use a
-  __static key__, which catastrophically undermines its security.
-
-* __Unbind on-demand__ ([bug][zx1138])
-
-  Currently, there is no way to ask a zxcrypt driver to unbind on demand.  The only way currently is
-  to force the underlying device to unbind it, for example by issuing an `IOCTL_BLOCK_RR_PART`
-  command to a device that supports it.
-
-* __Surface hidden bind failures__
-
-  Currently, `zxcrypt_bind` may indicate success even though the device fails to initialize.
-  zxcrypt is __NOT__ synchronously adding the device to the device tree when the binding logic is
-  run.  It must do I/O and cannot block the call to `device_bind` from returning, so it spawn an
-  initializer thread and adds the device when complete.
-
-  As of 10/2017, this is an active area of DDK development and the policy is changing to requiring
-  the device to be added before return, with an additional call to publish that may come later.
-  With this it may be desirable to have the call to `zxcrypt_bind` block synchronously for callers
-  until the device is ready or has unambiguously failed to bind.
-
-* __Use AEAD instead of AES-XTS__
-
-  It is widely recognized that [AEADs][aead] provide superior cryptographic protection by validating
-  the integrity of their data before decrypting it.  This is desirable, but requires additional
-  per-block overhead.  This means either that consumers will need to consume non-page-aligned blocks
-  (once the in-line overhead is removed), or zxcrypt will need to store the overhead out-of-line and
-  handle [non-atomic write failures][atomic].
-
-* __Support multiple keys__
-
-  To facilitate [key escrow and/or recovery][escrow], it is straightforward to modify the superblock
-  format to have a series of cryptographic envelopes.  In anticipation of this, the libzxcrypt API
-  takes a variable number of keys, although the only length currently supported is 1, and the only
-  valid slot is 0.
-
-* __Adjust number of workers__
-
-  Currently there is one encrypter and one decrypter.  These are designed to work with an arbitrary
-  number of threads, so performance tuning may be need to find the optimal number of workers that
-  balances I/O bandwidth with [scheduler churn][thrash].
-
-* __Remove internal checks__
-
-  Currently, the zxcrypt code checks for many errors conditions at internal boundaries and returns
-  informative errors if those conditions aren't met.  For performance, those that arise from
-  programmer error only and not data from either the requester or underlying device could be
-  converted to "debug" assertions that are skipped in release mode.
-
-[ind-cca2]: https://en.wikipedia.org/wiki/Ciphertext_indistinguishability
-[tweak]: https://en.wikipedia.org/wiki/Block_cipher#Tweakable_block_ciphers
-[aes-xts]: https://en.wikipedia.org/wiki/Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29
-[guid]: https://en.wikipedia.org/wiki/Universally_unique_identifier
-[iv]: https://en.wikipedia.org/wiki/Initialization_vector
-[hkdf]: https://tools.ietf.org/html/rfc5869
-[hmac]: https://www.ietf.org/rfc/rfc2104.txt
-[stretch]: https://en.wikipedia.org/wiki/Key_stretching
-[tpm]: https://trustedcomputinggroup.org/work-groups/trusted-platform-module/
-[zx1130]: https://fuchsia.atlassian.net/browse/ZX-1130
-[zx1138]: https://fuchsia.atlassian.net/browse/ZX-1138
-[aead]: https://tools.ietf.org/html/rfc5116
-[atomic]: https://en.wikipedia.org/wiki/Atomic_commit
-[escrow]: https://en.wikipedia.org/wiki/Key_escrow
-[thrash]: https://en.wikipedia.org/wiki/Thrashing_(computer_science)#Other_uses
diff --git a/kernel/LICENSE b/kernel/LICENSE
deleted file mode 100644
index 8580f02..0000000
--- a/kernel/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright 2016 The Fuchsia Authors
-Copyright (c) 2008-2015 Travis Geiselbrecht
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files
-(the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of the Software,
-and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/kernel/MAINTAINERS b/kernel/MAINTAINERS
deleted file mode 100644
index 20fca4a..0000000
--- a/kernel/MAINTAINERS
+++ /dev/null
@@ -1,5 +0,0 @@
-cja@google.com
-maniscalco@google.com
-swetland@google.com
-teisenbe@google.com
-travisg@google.com
diff --git a/kernel/arch/arm64/arch.cpp b/kernel/arch/arm64/arch.cpp
deleted file mode 100644
index bc0470a..0000000
--- a/kernel/arch/arm64/arch.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014-2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch.h>
-#include <arch/arm64.h>
-#include <arch/arm64/feature.h>
-#include <arch/arm64/registers.h>
-#include <arch/arm64/mmu.h>
-#include <arch/mp.h>
-#include <arch/ops.h>
-#include <assert.h>
-#include <bits.h>
-#include <debug.h>
-#include <inttypes.h>
-#include <kernel/cmdline.h>
-#include <kernel/thread.h>
-#include <lk/init.h>
-#include <lk/main.h>
-#include <platform.h>
-#include <stdlib.h>
-#include <string.h>
-#include <trace.h>
-#include <zircon/errors.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-// Counter-timer Kernel Control Register, EL1.
-static constexpr uint64_t CNTKCTL_EL1_ENABLE_VIRTUAL_COUNTER = 1 << 1;
-
-// Initial value for MSDCR_EL1 when starting userspace, which disables all debug exceptions.
-// Instruction Breakpoint Exceptions (software breakpoints) cannot be disabled and MDSCR does not
-// affect single-step behaviour.
-// TODO(donosoc): Enable HW exceptions when debug context switch is implemented.
-static constexpr uint32_t MSDCR_EL1_INITIAL_VALUE = 0;
-
-// Performance Monitors Count Enable Set, EL0.
-static constexpr uint64_t PMCNTENSET_EL0_ENABLE = 1UL << 31;  // Enable cycle count register.
-
-// Performance Monitor Control Register, EL0.
-static constexpr uint64_t PMCR_EL0_ENABLE_BIT = 1 << 0;
-static constexpr uint64_t PMCR_EL0_LONG_COUNTER_BIT = 1 << 6;
-
-// Performance Monitors User Enable Regiser, EL0.
-static constexpr uint64_t PMUSERENR_EL0_ENABLE = 1 << 0;  // Enable EL0 access to cycle counter.
-
-// System Control Register, EL1.
-static constexpr uint64_t SCTLR_EL1_UCI = 1 << 26; // Allow certain cache ops in EL0.
-static constexpr uint64_t SCTLR_EL1_UCT = 1 << 15; // Allow EL0 access to CTR register.
-static constexpr uint64_t SCTLR_EL1_DZE = 1 << 14; // Allow EL0 to use DC ZVA.
-static constexpr uint64_t SCTLR_EL1_SA0 = 1 << 4;  // Enable Stack Alignment Check EL0.
-static constexpr uint64_t SCTLR_EL1_SA = 1 << 3;   // Enable Stack Alignment Check EL1.
-static constexpr uint64_t SCTLR_EL1_AC = 1 << 1;   // Enable Alignment Checking for EL1 EL0.
-
-struct arm64_sp_info_t {
-    uint64_t mpid;
-    void* sp;
-
-    // This part of the struct itself will serve temporarily as the
-    // fake arch_thread in the thread pointer, so that safe-stack
-    // and stack-protector code can work early.  The thread pointer
-    // (TPIDR_EL1) points just past arm64_sp_info_t.
-    uintptr_t stack_guard;
-    void* unsafe_sp;
-};
-
-static_assert(sizeof(arm64_sp_info_t) == 32,
-              "check arm64_get_secondary_sp assembly");
-static_assert(offsetof(arm64_sp_info_t, sp) == 8,
-              "check arm64_get_secondary_sp assembly");
-static_assert(offsetof(arm64_sp_info_t, mpid) == 0,
-              "check arm64_get_secondary_sp assembly");
-
-#define TP_OFFSET(field) \
-    ((int)offsetof(arm64_sp_info_t, field) - (int)sizeof(arm64_sp_info_t))
-static_assert(TP_OFFSET(stack_guard) == ZX_TLS_STACK_GUARD_OFFSET, "");
-static_assert(TP_OFFSET(unsafe_sp) == ZX_TLS_UNSAFE_SP_OFFSET, "");
-#undef TP_OFFSET
-
-// SMP boot lock.
-static spin_lock_t arm_boot_cpu_lock = (spin_lock_t){1};
-static volatile int secondaries_to_init = 0;
-
-// one for each secondary CPU, indexed by (cpu_num - 1).
-static thread_t _init_thread[SMP_MAX_CPUS - 1];
-
-// one for each CPU
-arm64_sp_info_t arm64_secondary_sp_list[SMP_MAX_CPUS];
-
-extern uint64_t arch_boot_el;  // Defined in start.S.
-
-uint64_t arm64_get_boot_el() {
-    return arch_boot_el >> 2;
-}
-
-zx_status_t arm64_create_secondary_stack(uint cpu_num, uint64_t mpid) {
-    // Allocate a stack, indexed by CPU num so that |arm64_secondary_entry| can find it.
-    DEBUG_ASSERT_MSG(cpu_num > 0 && cpu_num < SMP_MAX_CPUS, "cpu_num: %u", cpu_num);
-    kstack_t* stack = &_init_thread[cpu_num - 1].stack;
-    DEBUG_ASSERT(stack->base == 0);
-    zx_status_t status = vm_allocate_kstack(stack);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // Get the stack pointers.
-    void* sp = reinterpret_cast<void*>(stack->top);
-    void* unsafe_sp = nullptr;
-#if __has_feature(safe_stack)
-    DEBUG_ASSERT(stack->unsafe_base != 0);
-    unsafe_sp = reinterpret_cast<void*>(stack->unsafe_base + stack->size);
-#endif
-
-    // Find an empty slot for the low-level stack info.
-    uint32_t i = 0;
-    while ((i < SMP_MAX_CPUS) && (arm64_secondary_sp_list[i].mpid != 0)) {
-        i++;
-    }
-    if (i == SMP_MAX_CPUS)
-        return ZX_ERR_NO_RESOURCES;
-
-    // Store it.
-    LTRACEF("set mpid 0x%lx sp to %p\n", mpid, sp);
-#if __has_feature(safe_stack)
-    LTRACEF("set mpid 0x%lx unsafe-sp to %p\n", mpid, unsafe_sp);
-#endif
-    arm64_secondary_sp_list[i].mpid = mpid;
-    arm64_secondary_sp_list[i].sp = sp;
-    arm64_secondary_sp_list[i].stack_guard = get_current_thread()->arch.stack_guard;
-    arm64_secondary_sp_list[i].unsafe_sp = unsafe_sp;
-
-    return ZX_OK;
-}
-
-zx_status_t arm64_free_secondary_stack(uint cpu_num) {
-    DEBUG_ASSERT(cpu_num > 0 && cpu_num < SMP_MAX_CPUS);
-    kstack_t* stack = &_init_thread[cpu_num - 1].stack;
-    zx_status_t status = vm_free_kstack(stack);
-    return status;
-}
-
-static void arm64_cpu_early_init() {
-    // Make sure the per cpu pointer is set up.
-    arm64_init_percpu_early();
-
-    // Set the vector base.
-    __arm_wsr64("vbar_el1", (uint64_t)&arm64_el1_exception_base);
-    __isb(ARM_MB_SY);
-
-    // Set some control bits in sctlr.
-    uint64_t sctlr = __arm_rsr64("sctlr_el1");
-    sctlr |= SCTLR_EL1_UCI | SCTLR_EL1_UCT | SCTLR_EL1_DZE | SCTLR_EL1_SA0 | SCTLR_EL1_SA;
-    sctlr &= ~SCTLR_EL1_AC;  // Disable alignment checking for EL1, EL0.
-    __arm_wsr64("sctlr_el1", sctlr);
-    __isb(ARM_MB_SY);
-
-    // Save all of the features of the cpu.
-    arm64_feature_init();
-
-    // Enable cycle counter.
-    __arm_wsr64("pmcr_el0", PMCR_EL0_ENABLE_BIT | PMCR_EL0_LONG_COUNTER_BIT);
-    __isb(ARM_MB_SY);
-    __arm_wsr64("pmcntenset_el0", PMCNTENSET_EL0_ENABLE);
-    __isb(ARM_MB_SY);
-
-    // Enable user space access to cycle counter.
-    __arm_wsr64("pmuserenr_el0", PMUSERENR_EL0_ENABLE);
-    __isb(ARM_MB_SY);
-
-    // Enable Debug Exceptions by Disabling the OS Lock. The OSLAR_EL1 is a WO
-    // register with only the low bit defined as OSLK. Write 0 to disable.
-    __arm_wsr64("oslar_el1", 0x0);
-    __isb(ARM_MB_SY);
-
-    // Enable user space access to virtual counter (CNTVCT_EL0).
-    __arm_wsr64("cntkctl_el1", CNTKCTL_EL1_ENABLE_VIRTUAL_COUNTER);
-    __isb(ARM_MB_SY);
-
-    __arm_wsr64("mdscr_el1", MSDCR_EL1_INITIAL_VALUE);
-    __isb(ARM_MB_SY);
-
-    arch_enable_fiqs();
-}
-
-void arch_early_init() {
-    arm64_cpu_early_init();
-
-    platform_init_mmu_mappings();
-}
-
-void arch_init() TA_NO_THREAD_SAFETY_ANALYSIS {
-    arch_mp_init_percpu();
-
-    dprintf(INFO, "ARM boot EL%lu\n", arm64_get_boot_el());
-
-    arm64_feature_debug(true);
-
-    uint32_t max_cpus = arch_max_num_cpus();
-    uint32_t cmdline_max_cpus = cmdline_get_uint32("kernel.smp.maxcpus", max_cpus);
-    if (cmdline_max_cpus > max_cpus || cmdline_max_cpus <= 0) {
-        printf("invalid kernel.smp.maxcpus value, defaulting to %u\n", max_cpus);
-        cmdline_max_cpus = max_cpus;
-    }
-
-    secondaries_to_init = cmdline_max_cpus - 1;
-
-    lk_init_secondary_cpus(secondaries_to_init);
-
-    LTRACEF("releasing %d secondary cpus\n", secondaries_to_init);
-
-    // Release the secondary cpus.
-    spin_unlock(&arm_boot_cpu_lock);
-
-    // Flush the release of the lock, since the secondary cpus are running without cache on.
-    arch_clean_cache_range((addr_t)&arm_boot_cpu_lock, sizeof(arm_boot_cpu_lock));
-}
-
-__NO_RETURN int arch_idle_thread_routine(void*) {
-    for (;;)
-        __asm__ volatile("wfi");
-}
-
-// Switch to user mode, set the user stack pointer to user_stack_top, put the svc stack pointer to
-// the top of the kernel stack.
-void arch_enter_uspace(uintptr_t pc, uintptr_t sp, uintptr_t arg1, uintptr_t arg2) {
-    thread_t* ct = get_current_thread();
-
-    // Set up a default spsr to get into 64bit user space:
-    //  - Zeroed NZCV.
-    //  - No SS, no IL, no D.
-    //  - All interrupts enabled.
-    //  - Mode 0: EL0t.
-    //
-    // TODO: (hollande,travisg) Need to determine why some platforms throw an
-    //         SError exception when first switching to uspace.
-    uint32_t spsr = 1 << 8;  // Mask SError exceptions (currently unhandled).
-
-    arch_disable_ints();
-
-    LTRACEF("arm_uspace_entry(%#" PRIxPTR ", %#" PRIxPTR ", %#x, %#" PRIxPTR
-            ", %#" PRIxPTR ", 0, %#" PRIxPTR ")\n",
-            arg1, arg2, spsr, ct->stack.top, sp, pc);
-    arm64_uspace_entry(arg1, arg2, pc, sp, ct->stack.top, spsr, MSDCR_EL1_INITIAL_VALUE);
-    __UNREACHABLE;
-}
-
-// called from assembly.
-extern "C" void arm64_secondary_entry() {
-    arm64_cpu_early_init();
-
-    spin_lock(&arm_boot_cpu_lock);
-    spin_unlock(&arm_boot_cpu_lock);
-
-    uint cpu = arch_curr_cpu_num();
-    thread_secondary_cpu_init_early(&_init_thread[cpu - 1]);
-    // Run early secondary cpu init routines up to the threading level.
-    lk_init_level(LK_INIT_FLAG_SECONDARY_CPUS, LK_INIT_LEVEL_EARLIEST, LK_INIT_LEVEL_THREADING - 1);
-
-    arch_mp_init_percpu();
-
-    arm64_feature_debug(false);
-
-    lk_secondary_cpu_entry();
-}
diff --git a/kernel/arch/arm64/asm.S b/kernel/arch/arm64/asm.S
deleted file mode 100644
index 712f599..0000000
--- a/kernel/arch/arm64/asm.S
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/asm_macros.h>
-
-#define CURRENTEL_EL1           (0b01 << 2)
-#define CURRENTEL_EL2           (0b10 << 2)
-
-#define CPACR_EL1_FPEN          (0b11 << 20)
-#define ID_AA64PFR0_EL1_GIC     (0b1111 << 24)
-
-#define CNTHCTL_EL2_EL1PCEN     (1 << 1)
-#define CNTHCTL_EL2_EL1PCTEN    (1 << 0)
-#define CPTR_EL2_RES1           0x33ff
-#define HCR_EL2_RW              (1 << 31)
-#define ICC_SRE_EL2_SRE         (1 << 0)
-#define ICC_SRE_EL2_ENABLE      (1 << 3)
-
-#define SCR_EL3_HCE             (1 << 8)
-#define SCR_EL3_NS              (1 << 0)
-#define SCR_EL3_RW              (1 << 10)
-
-#define SPSR_ELX_DAIF           (0b1111 << 6)
-#define SPSR_ELX_EL1H           (0b0101)
-
-#define ICH_HCR_EL2             S3_4_C12_C11_0
-#define ICC_SRE_EL2             S3_4_C12_C9_5
-
-/* void arm64_context_switch(vaddr_t *old_sp, vaddr_t new_sp); */
-FUNCTION(arm64_context_switch)
-    /* save old frame */
-    /* This layout should match struct context_switch_frame */
-    push_regs x29, x30
-    push_regs x27, x28
-    push_regs x25, x26
-    push_regs x23, x24
-    push_regs x21, x22
-    push_regs x19, x20
-    mrs  x19, tpidr_el0
-    mrs  x20, tpidrro_el0
-    push_regs x19, x20
-
-    /* save old sp */
-    mov  x15, sp
-    str  x15, [x0]
-
-    /* load new sp */
-    mov  sp, x1
-
-    /* restore new frame */
-    pop_regs x19, x20
-    msr  tpidr_el0, x19
-    msr  tpidrro_el0, x20
-    pop_regs x19, x20
-    pop_regs x21, x22
-    pop_regs x23, x24
-    pop_regs x25, x26
-    pop_regs x27, x28
-    pop_regs x29, x30
-
-    ret
-END_FUNCTION(arm64_context_switch)
-
-FUNCTION(arm64_elX_to_el1)
-    mrs x9, CurrentEL
-
-    // Check the current exception level.
-    cmp x9, CURRENTEL_EL1
-    beq .Ltarget
-    cmp x9, CURRENTEL_EL2
-    beq .Lin_el2
-    // Otherwise, we are in EL3.
-
-    // Set EL2 to 64bit and enable the HVC instruction.
-    mrs x9, scr_el3
-    mov x10, SCR_EL3_NS | SCR_EL3_HCE | SCR_EL3_RW
-    orr x9, x9, x10
-    msr scr_el3, x9
-
-    // Set the return address and exception level.
-    adr x9, .Ltarget
-    msr elr_el3, x9
-    mov x9, SPSR_ELX_DAIF | SPSR_ELX_EL1H
-    msr spsr_el3, x9
-
-.Lin_el2:
-    // Set the init vector table for EL2.
-    adr_global x9, arm64_el2_init_table
-    msr vbar_el2, x9
-
-    // Disable EL1 timer traps and the timer offset.
-    mrs x9, cnthctl_el2
-    orr x9, x9, CNTHCTL_EL2_EL1PCEN | CNTHCTL_EL2_EL1PCTEN
-    msr cnthctl_el2, x9
-    msr cntvoff_el2, xzr
-
-    // Disable stage 2 translations.
-    msr vttbr_el2, xzr
-
-    // Disable EL2 coprocessor traps.
-    mov x9, CPTR_EL2_RES1
-    msr cptr_el2, x9
-
-    // Disable EL1 FPU traps.
-    mov x9, CPACR_EL1_FPEN
-    msr cpacr_el1, x9
-
-    // Check whether the GIC system registers are supported.
-    mrs x9, id_aa64pfr0_el1
-    and x9, x9, ID_AA64PFR0_EL1_GIC
-    cbz x9, .Lno_gic_sr
-
-    // Enable the GIC system registers in EL2, and allow their use in EL1.
-    mrs x9, ICC_SRE_EL2
-    mov x10, ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE
-    orr x9, x9, x10
-    msr ICC_SRE_EL2, x9
-
-    // Disable the GIC virtual CPU interface.
-    msr ICH_HCR_EL2, xzr
-
-.Lno_gic_sr:
-    // Set EL1 to 64bit.
-    mov x9, HCR_EL2_RW
-    msr hcr_el2, x9
-
-    // Set the return address and exception level.
-    adr x9, .Ltarget
-    msr elr_el2, x9
-    mov x9, SPSR_ELX_DAIF | SPSR_ELX_EL1H
-    msr spsr_el2, x9
-
-    isb
-    eret
-
-.Ltarget:
-    ret
-END_FUNCTION(arm64_elX_to_el1)
-
-FUNCTION(arm64_get_secondary_sp)
-    mrs     x9, mpidr_el1
-    ldr     x10, =0xff00ffffff  /* Mask for AFFx (cluster) ids */
-    and     x9, x9, x10
-    mov     x10, #SMP_MAX_CPUS
-
-    adr_global x11, arm64_secondary_sp_list
-
-.Lsp_loop:
-    ldr     x12, [x11, #0]
-    cmp     x12, x9
-    beq     .Lsp_found
-    add     x11, x11, #32
-    subs    x10, x10, #1
-    bne     .Lsp_loop
-    mov     x0, xzr
-    mov     x1, xzr
-    ret
-
-.Lsp_found:
-    ldr     x0, [x11, #8]
-    add     x1, x11, #32
-    ret
-END_FUNCTION(arm64_get_secondary_sp)
diff --git a/kernel/arch/arm64/boot-mmu.cpp b/kernel/arch/arm64/boot-mmu.cpp
deleted file mode 100644
index 1f32132..0000000
--- a/kernel/arch/arm64/boot-mmu.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/mmu.h>
-#include <inttypes.h>
-#include <string.h>
-#include <sys/types.h>
-#include <vm/bootalloc.h>
-#include <vm/physmap.h>
-
-// Early boot time page table creation code, called from start.S while running in physical address space
-// with the mmu disabled. This code should be position independent as long as it sticks to basic code.
-
-// this code only works on a 4K page granule, 48 bits of kernel address space
-static_assert(MMU_KERNEL_PAGE_SIZE_SHIFT == 12, "");
-static_assert(MMU_KERNEL_SIZE_SHIFT == 48, "");
-
-// 1GB pages
-const uintptr_t l1_large_page_size = 1UL << MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 1);
-const uintptr_t l1_large_page_size_mask = l1_large_page_size - 1;
-
-// 2MB pages
-const uintptr_t l2_large_page_size = 1UL << MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 2);
-const uintptr_t l2_large_page_size_mask = l2_large_page_size - 2;
-
-static size_t vaddr_to_l0_index(uintptr_t addr) {
-    return (addr >> MMU_KERNEL_TOP_SHIFT) & (MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP - 1);
-}
-
-static size_t vaddr_to_l1_index(uintptr_t addr) {
-    return (addr >> MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 1)) & (MMU_KERNEL_PAGE_TABLE_ENTRIES - 1);
-}
-
-static size_t vaddr_to_l2_index(uintptr_t addr) {
-    return (addr >> MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 2)) & (MMU_KERNEL_PAGE_TABLE_ENTRIES - 1);
-}
-
-static size_t vaddr_to_l3_index(uintptr_t addr) {
-    return (addr >> MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 3)) & (MMU_KERNEL_PAGE_TABLE_ENTRIES - 1);
-}
-
-// called from start.S to grab another page to back a page table from the boot allocator
-__NO_SAFESTACK
-extern "C" pte_t* boot_alloc_ptable() {
-    // allocate a page out of the boot allocator, asking for a physical address
-    pte_t* ptr = reinterpret_cast<pte_t*>(boot_alloc_page_phys());
-
-    // avoid using memset, since this relies on dc zva instruction, which isn't set up at
-    // this point in the boot process
-    // use a volatile pointer to make sure
-    volatile pte_t* vptr = ptr;
-    for (auto i = 0; i < MMU_KERNEL_PAGE_TABLE_ENTRIES; i++)
-        vptr[i] = 0;
-
-    return ptr;
-}
-
-// inner mapping routine passed two helper routines
-__NO_SAFESTACK
-static inline zx_status_t _arm64_boot_map(pte_t* kernel_table0,
-                                          const vaddr_t vaddr,
-                                          const paddr_t paddr,
-                                          const size_t len,
-                                          const pte_t flags,
-                                          paddr_t (*alloc_func)(),
-                                          pte_t* phys_to_virt(paddr_t)) {
-
-    // loop through the virtual range and map each physical page, using the largest
-    // page size supported. Allocates necessar page tables along the way.
-    size_t off = 0;
-    while (off < len) {
-        // make sure the level 1 pointer is valid
-        size_t index0 = vaddr_to_l0_index(vaddr + off);
-        pte_t* kernel_table1 = nullptr;
-        switch (kernel_table0[index0] & MMU_PTE_DESCRIPTOR_MASK) {
-        default: { // invalid/unused entry
-            paddr_t pa = alloc_func();
-
-            kernel_table0[index0] = (pa & MMU_PTE_OUTPUT_ADDR_MASK) |
-                                    MMU_PTE_L012_DESCRIPTOR_TABLE;
-            __FALLTHROUGH;
-        }
-        case MMU_PTE_L012_DESCRIPTOR_TABLE:
-            kernel_table1 = phys_to_virt(kernel_table0[index0] & MMU_PTE_OUTPUT_ADDR_MASK);
-            break;
-        case MMU_PTE_L012_DESCRIPTOR_BLOCK:
-            // not legal to have a block pointer at this level
-            return ZX_ERR_BAD_STATE;
-        }
-
-        // make sure the level 2 pointer is valid
-        size_t index1 = vaddr_to_l1_index(vaddr + off);
-        pte_t* kernel_table2 = nullptr;
-        switch (kernel_table1[index1] & MMU_PTE_DESCRIPTOR_MASK) {
-        default: { // invalid/unused entry
-            // a large page at this level is 1GB long, see if we can make one here
-            if ((((vaddr + off) & l1_large_page_size_mask) == 0) &&
-                (((paddr + off) & l1_large_page_size_mask) == 0) &&
-                (len - off) >= l1_large_page_size) {
-
-                // set up a 1GB page here
-                kernel_table1[index1] = ((paddr + off) & ~l1_large_page_size_mask) |
-                                        flags | MMU_PTE_L012_DESCRIPTOR_BLOCK;
-
-                off += l1_large_page_size;
-                continue;
-            }
-
-            paddr_t pa = alloc_func();
-
-            kernel_table1[index1] = (pa & MMU_PTE_OUTPUT_ADDR_MASK) |
-                                    MMU_PTE_L012_DESCRIPTOR_TABLE;
-            __FALLTHROUGH;
-        }
-        case MMU_PTE_L012_DESCRIPTOR_TABLE:
-            kernel_table2 = phys_to_virt(kernel_table1[index1] & MMU_PTE_OUTPUT_ADDR_MASK);
-            break;
-        case MMU_PTE_L012_DESCRIPTOR_BLOCK:
-            // not legal to have a block pointer at this level
-            return ZX_ERR_BAD_STATE;
-        }
-
-        // make sure the level 3 pointer is valid
-        size_t index2 = vaddr_to_l2_index(vaddr + off);
-        pte_t* kernel_table3 = nullptr;
-        switch (kernel_table2[index2] & MMU_PTE_DESCRIPTOR_MASK) {
-        default: { // invalid/unused entry
-            // a large page at this level is 2MB long, see if we can make one here
-            if ((((vaddr + off) & l2_large_page_size_mask) == 0) &&
-                (((paddr + off) & l2_large_page_size_mask) == 0) &&
-                (len - off) >= l2_large_page_size) {
-
-                // set up a 2MB page here
-                kernel_table2[index2] = ((paddr + off) & ~l2_large_page_size_mask) |
-                                        flags | MMU_PTE_L012_DESCRIPTOR_BLOCK;
-
-                off += l2_large_page_size;
-                continue;
-            }
-
-            paddr_t pa = alloc_func();
-
-            kernel_table2[index2] = (pa & MMU_PTE_OUTPUT_ADDR_MASK) |
-                                    MMU_PTE_L012_DESCRIPTOR_TABLE;
-            __FALLTHROUGH;
-        }
-        case MMU_PTE_L012_DESCRIPTOR_TABLE:
-            kernel_table3 = phys_to_virt(kernel_table2[index2] & MMU_PTE_OUTPUT_ADDR_MASK);
-            break;
-        case MMU_PTE_L012_DESCRIPTOR_BLOCK:
-            // not legal to have a block pointer at this level
-            return ZX_ERR_BAD_STATE;
-        }
-
-        // generate a standard page mapping
-        size_t index3 = vaddr_to_l3_index(vaddr + off);
-        kernel_table3[index3] = ((paddr + off) & MMU_PTE_OUTPUT_ADDR_MASK) | flags | MMU_PTE_L3_DESCRIPTOR_PAGE;
-
-        off += PAGE_SIZE;
-    }
-
-    return ZX_OK;
-}
-
-// called from start.S to configure level 1-3 page tables to map the kernel wherever it is located physically
-// to KERNEL_BASE
-__NO_SAFESTACK
-extern "C" zx_status_t arm64_boot_map(pte_t* kernel_table0,
-                                      const vaddr_t vaddr,
-                                      const paddr_t paddr,
-                                      const size_t len,
-                                      const pte_t flags) {
-
-    // the following helper routines assume that code is running in physical addressing mode (mmu off).
-    // any physical addresses calculated are assumed to be the same as virtual
-    auto alloc = []() -> paddr_t {
-        // allocate a page out of the boot allocator, asking for a physical address
-        paddr_t pa = boot_alloc_page_phys();
-
-        // avoid using memset, since this relies on dc zva instruction, which isn't set up at
-        // this point in the boot process
-        // use a volatile pointer to make sure the compiler doesn't emit a memset call
-        volatile pte_t* vptr = reinterpret_cast<volatile pte_t*>(pa);
-        for (auto i = 0; i < MMU_KERNEL_PAGE_TABLE_ENTRIES; i++)
-            vptr[i] = 0;
-
-        return pa;
-    };
-
-    auto phys_to_virt = [](paddr_t pa) -> pte_t* {
-        return reinterpret_cast<pte_t*>(pa);
-    };
-
-    return _arm64_boot_map(kernel_table0, vaddr, paddr, len, flags, alloc, phys_to_virt);
-}
-
-// called a bit later in the boot process once the kernel is in virtual memory to map early kernel data
-extern "C" zx_status_t arm64_boot_map_v(const vaddr_t vaddr,
-                                        const paddr_t paddr,
-                                        const size_t len,
-                                        const pte_t flags) {
-
-    // assumed to be running with virtual memory enabled, so use a slightly different set of routines
-    // to allocate and find the virtual mapping of memory
-    auto alloc = []() -> paddr_t {
-        // allocate a page out of the boot allocator, asking for a physical address
-        paddr_t pa = boot_alloc_page_phys();
-
-        // zero the memory using the physmap
-        void* ptr = paddr_to_physmap(pa);
-        memset(ptr, 0, MMU_KERNEL_PAGE_TABLE_ENTRIES * sizeof(pte_t));
-
-        return pa;
-    };
-
-    auto phys_to_virt = [](paddr_t pa) -> pte_t* {
-        return reinterpret_cast<pte_t*>(paddr_to_physmap(pa));
-    };
-
-    return _arm64_boot_map(arm64_get_kernel_ptable(), vaddr, paddr, len, flags, alloc, phys_to_virt);
-}
diff --git a/kernel/arch/arm64/cache-ops.S b/kernel/arch/arm64/cache-ops.S
deleted file mode 100644
index 1a891af..0000000
--- a/kernel/arch/arm64/cache-ops.S
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014, Google Inc. All rights reserved
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-
-#include <asm.h>
-#include <arch/ops.h>
-#include <arch/defines.h>
-
-.text
-
-.macro cache_range_op, cache op size_var
-    adrp    x16, \size_var
-    ldr     w4, [x16, :lo12:\size_var]  // cache line size in bytes
-
-    add     x2, x0, x1                  // calculate the end address
-
-    sub     x5, x4, #1                  // cache line size mask
-    bic     x3, x0, x5                  // cache align the start address by applying inverse mask
-
-.Lcache_range_op_loop\@:
-    \cache  \op, x3
-    add     x3, x3, x4
-    cmp     x3, x2
-    blo     .Lcache_range_op_loop\@
-    dsb     sy
-.endm
-
-    /* void arch_flush_cache_range(addr_t start, size_t len); */
-FUNCTION(arch_clean_cache_range)
-    cache_range_op dc cvac arm64_dcache_size // clean cache to PoC by MVA
-    ret
-END_FUNCTION(arch_clean_cache_range)
-
-    /* void arch_flush_invalidate_cache_range(addr_t start, size_t len); */
-FUNCTION(arch_clean_invalidate_cache_range)
-    cache_range_op dc civac arm64_dcache_size // clean & invalidate dcache to PoC by MVA
-    ret
-END_FUNCTION(arch_clean_invalidate_cache_range)
-
-    /* void arch_invalidate_cache_range(addr_t start, size_t len); */
-FUNCTION(arch_invalidate_cache_range)
-    cache_range_op dc ivac arm64_dcache_size // invalidate dcache to PoC by MVA
-    ret
-END_FUNCTION(arch_invalidate_cache_range)
-
-    /* void arch_sync_cache_range(addr_t start, size_t len); */
-FUNCTION(arch_sync_cache_range)
-    cache_range_op dc cvau arm64_dcache_size // clean dcache to PoU by MVA
-    cache_range_op ic ivau arm64_icache_size // invalidate icache to PoU by MVA
-    isb
-    ret
-END_FUNCTION(arch_sync_cache_range)
-
-/* void arch_invalidate_cache_all()
- *      should only be used early in boot, prior to enabling mmu/cache
- */
-FUNCTION(arch_invalidate_cache_all)
-    mrs     x0, clidr_el1
-    and     w3, w0, #0x07000000
-    lsr     w3, w3, #23
-    cbz     w3, finished
-    mov     w10, #0
-    mov     w8, #1
-loop1:
-    add     w2, w10, w10, lsr #1
-    lsr     w1, w0, w2
-    and     w1, w1, #0x7
-    cmp     w1, #2
-    b.lt    skip
-    msr     csselr_el1, x10
-    isb
-    mrs     x1, ccsidr_el1
-    and     w2, w1, #7
-    add     w2, w2, #4
-    ubfx    w4, w1, #3, #10
-    clz     w5, w4
-    lsl     w9, w4, w5
-
-    lsl     w16, w8, w5
-
-loop2:
-    ubfx    w7, w1, #13, #15
-    lsl     w7, w7, w2
-    lsl     w17, w8, w2
-loop3:
-    orr     w11, w10, w9
-    orr     w11, w11, w7
-    dc      isw, x11
-    subs    w7, w7, w17
-    b.ge    loop3
-
-    subs    x9, x9, x16
-    b.ge    loop2
-skip:
-    add     w10, w10, #2
-    cmp     w3, w10
-    dsb     sy
-    b.gt    loop1
-finished:
-    ic      iallu
-    ret
-END_FUNCTION(arch_invalidate_cache_all)
-
diff --git a/kernel/arch/arm64/debugger.cpp b/kernel/arch/arm64/debugger.cpp
deleted file mode 100644
index 1166791..0000000
--- a/kernel/arch/arm64/debugger.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64.h>
-#include <arch/arm64/registers.h>
-#include <arch/debugger.h>
-#include <err.h>
-#include <kernel/thread.h>
-#include <kernel/thread_lock.h>
-#include <string.h>
-#include <sys/types.h>
-#include <zircon/syscalls/debug.h>
-#include <zircon/types.h>
-
-// Only the NZCV flags (bits 31 to 28 respectively) of the CPSR are
-// readable and writable by userland on ARM64.
-static uint32_t kUserVisibleFlags = 0xf0000000;
-
-// SS (="Single Step") is bit 0 in MDSCR_EL1.
-static constexpr uint64_t kMdscrSSMask = 1;
-
-// Single Step for PSTATE, see ARMv8 Manual C5.2.18, enable Single step for Process
-static constexpr uint64_t kSSMaskSPSR = (1 << 21);
-
-zx_status_t arch_get_general_regs(struct thread* thread, zx_thread_state_general_regs_t* out) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Punt if registers aren't available. E.g.,
-    // ZX-563 (registers aren't available in synthetic exceptions)
-    if (thread->arch.suspended_general_regs == nullptr)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    struct arm64_iframe_long* in = thread->arch.suspended_general_regs;
-    DEBUG_ASSERT(in);
-
-    static_assert(sizeof(in->r) == sizeof(out->r), "");
-    memcpy(&out->r[0], &in->r[0], sizeof(in->r));
-    out->lr = in->lr;
-    out->sp = in->usp;
-    out->pc = in->elr;
-    out->cpsr = in->spsr & kUserVisibleFlags;
-
-    return ZX_OK;
-}
-
-zx_status_t arch_set_general_regs(struct thread* thread, const zx_thread_state_general_regs_t* in) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Punt if registers aren't available. E.g.,
-    // ZX-563 (registers aren't available in synthetic exceptions)
-    if (thread->arch.suspended_general_regs == nullptr)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    struct arm64_iframe_long* out = thread->arch.suspended_general_regs;
-    DEBUG_ASSERT(out);
-
-    static_assert(sizeof(out->r) == sizeof(in->r), "");
-    memcpy(&out->r[0], &in->r[0], sizeof(in->r));
-    out->lr = in->lr;
-    out->usp = in->sp;
-    out->elr = in->pc;
-    out->spsr = (out->spsr & ~kUserVisibleFlags) | (in->cpsr & kUserVisibleFlags);
-
-    return ZX_OK;
-}
-
-zx_status_t arch_get_single_step(struct thread* thread, bool* single_step) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Punt if registers aren't available. E.g.,
-    // ZX-563 (registers aren't available in synthetic exceptions)
-    if (thread->arch.suspended_general_regs == nullptr)
-        return ZX_ERR_NOT_SUPPORTED;
-    struct arm64_iframe_long* regs = thread->arch.suspended_general_regs;
-
-    const bool mdscr_ss_enable = !!(regs->mdscr & kMdscrSSMask);
-    const bool spsr_ss_enable = !!(regs->spsr & kSSMaskSPSR);
-
-    *single_step = mdscr_ss_enable && spsr_ss_enable;
-    return ZX_OK;
-}
-
-zx_status_t arch_set_single_step(struct thread* thread, bool single_step) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Punt if registers aren't available. E.g.,
-    // ZX-563 (registers aren't available in synthetic exceptions)
-    if (thread->arch.suspended_general_regs == nullptr)
-        return ZX_ERR_NOT_SUPPORTED;
-    struct arm64_iframe_long* regs = thread->arch.suspended_general_regs;
-    if (single_step) {
-        regs->mdscr |= kMdscrSSMask;
-        regs->spsr |= kSSMaskSPSR;
-    } else {
-        regs->mdscr &= ~kMdscrSSMask;
-        regs->spsr &= ~kSSMaskSPSR;
-    }
-    return ZX_OK;
-}
-
-zx_status_t arch_get_fp_regs(struct thread* thread, zx_thread_state_fp_regs* out) {
-    // There are no ARM fp regs.
-    (void)out;
-    return ZX_OK;
-}
-
-zx_status_t arch_set_fp_regs(struct thread* thread, const zx_thread_state_fp_regs* in) {
-    // There are no ARM fp regs.
-    (void)in;
-    return ZX_OK;
-}
-
-zx_status_t arch_get_vector_regs(struct thread* thread, zx_thread_state_vector_regs* out) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    const fpstate* in = &thread->arch.fpstate;
-    out->fpcr = in->fpcr;
-    out->fpsr = in->fpsr;
-    for (int i = 0; i < 32; i++) {
-        out->v[i].low = in->regs[i * 2];
-        out->v[i].high = in->regs[i * 2 + 1];
-    }
-
-    return ZX_OK;
-}
-
-zx_status_t arch_set_vector_regs(struct thread* thread, const zx_thread_state_vector_regs* in) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    fpstate* out = &thread->arch.fpstate;
-    out->fpcr = in->fpcr;
-    out->fpsr = in->fpsr;
-    for (int i = 0; i < 32; i++) {
-        out->regs[i * 2] = in->v[i].low;
-        out->regs[i * 2 + 1] = in->v[i].high;
-    }
-
-    return ZX_OK;
-}
-
-zx_status_t arch_get_debug_regs(struct thread* thread, zx_thread_state_debug_regs* out) {
-    *out = {};
-    out->hw_bps_count = arm64_hw_breakpoint_count();
-    out->hw_wps_count = arm64_hw_watchpoint_count();
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // The kernel ensures that this state is being kept up to date, so we can safely copy the
-    // information over.
-    for (size_t i = 0; i < out->hw_bps_count; i++) {
-        out->hw_bps[i].dbgbcr = thread->arch.debug_state.hw_bps[i].dbgbcr;
-        out->hw_bps[i].dbgbvr = thread->arch.debug_state.hw_bps[i].dbgbvr;
-    }
-
-    return ZX_OK;
-}
-
-zx_status_t arch_set_debug_regs(struct thread* thread, const zx_thread_state_debug_regs* in) {
-    arm64_debug_state_t state = {};
-
-    // We copy over the state from the input.
-    uint64_t bp_count = arm64_hw_breakpoint_count();
-    for (size_t i = 0; i < bp_count; i++) {
-        state.hw_bps[i].dbgbcr = in->hw_bps[i].dbgbcr;
-        state.hw_bps[i].dbgbvr = in->hw_bps[i].dbgbvr;
-    }
-
-    if (!arm64_validate_debug_state(&state)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-    thread->arch.track_debug_state = true;
-    thread->arch.debug_state = state;
-
-    return ZX_OK;
-}
-
-zx_status_t arch_get_x86_register_fs(struct thread* thread, uint64_t* out) {
-    // There are no FS register on ARM.
-    (void)out;
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t arch_set_x86_register_fs(struct thread* thread, const uint64_t* in) {
-    // There are no FS register on ARM.
-    (void)in;
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t arch_get_x86_register_gs(struct thread* thread, uint64_t* out) {
-    // There are no GS register on ARM.
-    (void)out;
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t arch_set_x86_register_gs(struct thread* thread, const uint64_t* in) {
-    // There are no GS register on ARM.
-    (void)in;
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
-uint8_t arch_get_hw_breakpoint_count() {
-  return arm64_hw_breakpoint_count();
-}
-
-uint8_t arch_get_hw_watchpoint_count() {
-  return arm64_hw_watchpoint_count();
-
-}
diff --git a/kernel/arch/arm64/exceptions.S b/kernel/arch/arm64/exceptions.S
deleted file mode 100644
index c43de4e..0000000
--- a/kernel/arch/arm64/exceptions.S
+++ /dev/null
@@ -1,497 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/asm_macros.h>
-#include <arch/arch_thread.h>
-#include <arch/arm64.h>
-#include <arch/arm64/exceptions.h>
-#include <zircon/zx-syscall-numbers.h>
-
-.section .text.boot.vectab,"ax",@progbits
-.align 12
-
-#define DW_REG_lr   30
-#define DW_REG_sp   31
-// The "current mode exception link register", which for our purposes is elr_el1.
-#define DW_REG_ELR_mode 33
-
-#define lr x30
-#define elr1 DW_REG_ELR_mode
-
-// offset where sp,elr,spsr,lr,mdscr goes in the iframe
-#define regsave_special_reg_offset (30 * 8)
-
-// offset where x20-x29 goes in the iframe
-#define regsave_high_reg_offset (20 * 8)
-
-.macro regsave_long
-// There are 5 regs @ regsave_special_reg_offset, plus one unused space = 6 to
-// maintain 16-byte padding.
-sub_from_sp (6*8)
-push_regs x28, x29
-push_regs x26, x27
-push_regs x24, x25
-push_regs x22, x23
-push_regs x20, x21
-push_regs x18, x19
-push_regs x16, x17
-push_regs x14, x15
-push_regs x12, x13
-push_regs x10, x11
-push_regs x8, x9
-push_regs x6, x7
-push_regs x4, x5
-push_regs x2, x3
-push_regs x0, x1
-// Preserve x0-x7 for syscall arguments
-mrs  x9, sp_el0
-// x10 (containing elr_el1) is used in syscall handler
-mrs  x10, elr_el1
-mrs  x11, spsr_el1
-mrs  x12, mdscr_el1
-stp  lr, x9, [sp, #regsave_special_reg_offset]
-.cfi_rel_offset lr, (regsave_special_reg_offset)
-.cfi_rel_offset sp, (regsave_special_reg_offset + 8)
-stp  x10, x11, [sp, #regsave_special_reg_offset + 16]
-.cfi_rel_offset elr1, (regsave_special_reg_offset + 16)
-str x12, [sp, #regsave_special_reg_offset + 32]
-.endm
-
-.macro regsave_short
-// Align the same as the long version above. The 10 extra words correspond to
-// x20 through x29 which are not saved here.
-sub_from_sp ((6*8) + (10*8))
-push_regs x18, x19
-push_regs x16, x17
-push_regs x14, x15
-push_regs x12, x13
-push_regs x10, x11
-push_regs x8, x9
-push_regs x6, x7
-push_regs x4, x5
-push_regs x2, x3
-push_regs x0, x1
-// Preserve x0-x7 to mirror regsave_long
-mrs  x9, sp_el0
-mrs  x10, elr_el1
-mrs  x11, spsr_el1
-stp  lr, x9, [sp, #regsave_special_reg_offset]
-.cfi_rel_offset lr, (regsave_special_reg_offset)
-.cfi_rel_offset sp, (regsave_special_reg_offset + 8)
-stp  x10, x11, [sp, #regsave_special_reg_offset + 16]
-.cfi_rel_offset elr1, (regsave_special_reg_offset + 16)
-.endm
-
-// convert a short iframe to a long one by patching in the additional 10 words to save
-.macro regsave_short_to_long
-stp  x20, x21, [sp, #regsave_high_reg_offset]
-stp  x22, x23, [sp, #regsave_high_reg_offset + 0x10]
-stp  x24, x25, [sp, #regsave_high_reg_offset + 0x20]
-stp  x26, x27, [sp, #regsave_high_reg_offset + 0x30]
-stp  x28, x29, [sp, #regsave_high_reg_offset + 0x40]
-mrs  x12, mdscr_el1
-str  x12, [sp, #regsave_special_reg_offset + 32]
-.endm
-
-// Once we pop the stack past the saved sp_el0, elr_el1 the userspace values
-// are inaccessible.
-.macro mark_lr_sp_inaccessible
-// TODO(dje): gdb tries to use some value for these even if "undefined",
-// as a workaround set their values to zero which will cause gdb to
-// terminate the backtrace. Need to revisit, file gdb bug if necessary.
-cfi_register_is_zero DW_REG_sp
-cfi_register_is_zero DW_REG_ELR_mode
-.endm
-
-.macro regrestore_long
-// Preserve x0-x1 for syscall returns (eventually x0-x7)
-ldp  lr, x9, [sp, #regsave_special_reg_offset]
-.cfi_same_value lr
-ldp  x10, x11, [sp, #regsave_special_reg_offset + 16]
-ldr  x12, [sp, #regsave_special_reg_offset + 32]
-msr  sp_el0, x9
-msr  elr_el1, x10
-msr  spsr_el1, x11
-msr  mdscr_el1, x12
-pop_regs x0, x1
-pop_regs x2, x3
-pop_regs x4, x5
-pop_regs x6, x7
-pop_regs x8, x9
-pop_regs x10, x11
-pop_regs x12, x13
-pop_regs x14, x15
-pop_regs x16, x17
-pop_regs x18, x19
-pop_regs x20, x21
-pop_regs x22, x23
-pop_regs x24, x25
-pop_regs x26, x27
-pop_regs x28, x29
-add_to_sp (6*8)
-mark_lr_sp_inaccessible
-.endm
-
-.macro regrestore_short
-// Preserve x0-x7 to mirror regrestore_long
-ldp  lr, x9, [sp, #regsave_special_reg_offset]
-.cfi_same_value lr
-ldp  x10, x11, [sp, #regsave_special_reg_offset + 16]
-msr  sp_el0, x9
-msr  elr_el1, x10
-msr  spsr_el1, x11
-pop_regs x0, x1
-pop_regs x2, x3
-pop_regs x4, x5
-pop_regs x6, x7
-pop_regs x8, x9
-pop_regs x10, x11
-pop_regs x12, x13
-pop_regs x14, x15
-pop_regs x16, x17
-pop_regs x18, x19
-add_to_sp ((6*8) + (10*8))
-mark_lr_sp_inaccessible
-.endm
-
-.macro start_isr_cfi
-    .cfi_startproc simple
-    .cfi_signal_frame
-    // The return address is in elr_el1, not lr.
-    .cfi_return_column elr1
-    .cfi_def_cfa sp, 0
-.endm
-
-.macro start_isr_func
-    start_isr_cfi
-    ALL_CFI_SAME_VALUE
-    .cfi_undefined elr1
-.endm
-
-.macro start_helper_cfi
-    .cfi_startproc simple
-    .cfi_signal_frame
-    .cfi_def_cfa sp, (regsave_special_reg_offset + 4 * 8)
-.endm
-
-// The CFA offset of integer register |regno| (regno = 0-29).
-#define REG_CFA_OFFSET(regno) .cfi_offset x##regno, -((4 * 8) + ((30 - (regno)) * 8))
-
-// Mark the locations of the registers based on the CFA so that the
-// location doesn't change as the regs are popped.
-.macro setup_short_helper_cfi
-    REG_CFA_OFFSET(0)
-    REG_CFA_OFFSET(1)
-    REG_CFA_OFFSET(2)
-    REG_CFA_OFFSET(3)
-    REG_CFA_OFFSET(4)
-    REG_CFA_OFFSET(5)
-    REG_CFA_OFFSET(6)
-    REG_CFA_OFFSET(7)
-    REG_CFA_OFFSET(8)
-    REG_CFA_OFFSET(9)
-    REG_CFA_OFFSET(10)
-    REG_CFA_OFFSET(11)
-    REG_CFA_OFFSET(12)
-    REG_CFA_OFFSET(13)
-    REG_CFA_OFFSET(14)
-    REG_CFA_OFFSET(15)
-    REG_CFA_OFFSET(16)
-    REG_CFA_OFFSET(17)
-    REG_CFA_OFFSET(18)
-    REG_CFA_OFFSET(19)
-    .cfi_offset sp, -(3 * 8)
-    .cfi_offset lr, -(4 * 8)
-.endm
-
-.macro setup_long_helper_cfi
-    setup_short_helper_cfi
-    REG_CFA_OFFSET(20)
-    REG_CFA_OFFSET(21)
-    REG_CFA_OFFSET(22)
-    REG_CFA_OFFSET(23)
-    REG_CFA_OFFSET(24)
-    REG_CFA_OFFSET(25)
-    REG_CFA_OFFSET(26)
-    REG_CFA_OFFSET(27)
-    REG_CFA_OFFSET(28)
-    REG_CFA_OFFSET(29)
-.endm
-
-.macro start_short_helper
-    start_helper_cfi
-    setup_short_helper_cfi
-.endm
-
-.macro start_long_helper
-    start_helper_cfi
-    setup_long_helper_cfi
-.endm
-
-.macro invalid_exception, which
-    start_isr_func
-    regsave_long
-    mov x1, #\which
-    mov x0, sp
-    bl  arm64_invalid_exception
-    b   .
-.endm
-
-.macro irq_exception, exception_flags
-    start_isr_func
-    regsave_short
-    msr daifclr, #1 /* reenable fiqs once elr and spsr have been saved */
-    mov x0, sp
-    mov x1, \exception_flags
-    bl  arm64_irq
-    cbnz x0, arm64_finish_user_irq_wrapper /* anything extra to do? */
-    msr daifset, #1 /* disable fiqs to protect elr and spsr restore */
-    b   arm64_exc_shared_restore_short
-.endm
-
-.macro sync_exception, exception_flags, from_lower_el_64=0
-    start_isr_func
-    regsave_long
-    mrs x9, esr_el1
-.if \from_lower_el_64
-    // If this is a syscall, x0-x7 contain args and x16 contains syscall num.
-    // x10 contains elr_el1.
-    lsr x11, x9, #26              // shift esr right 26 bits to get ec
-    cmp x11, #0x15                // check for 64-bit syscall
-    beq arm64_syscall_dispatcher  // and jump to syscall handler
-.endif
-    // Prepare the default sync_exception args
-    mov x0, sp
-    mov x1, \exception_flags
-    mov w2, w9
-    bl  arm64_sync_exception
-    b  arm64_exc_shared_restore_long
-.endm
-
-FUNCTION_LABEL(arm64_el1_exception_base)
-
-/* exceptions from current EL, using SP0 */
-.org 0x000
-LOCAL_FUNCTION_LABEL(arm64_el1_sync_exc_current_el_SP0)
-    invalid_exception 0
-END_FUNCTION(arm64_el1_sync_exc_current_el_SP0)
-
-.org 0x080
-LOCAL_FUNCTION_LABEL(arm64_el1_irq_current_el_SP0)
-    invalid_exception 1
-END_FUNCTION(arm64_el1_irq_current_el_SP0)
-
-.org 0x100
-LOCAL_FUNCTION_LABEL(arm64_el1_fiq_current_el_SP0)
-    invalid_exception 2
-END_FUNCTION(arm64_el1_fiq_current_el_SP0)
-
-.org 0x180
-LOCAL_FUNCTION_LABEL(arm64_el1_err_exc_current_el_SP0)
-    invalid_exception 3
-END_FUNCTION(arm64_el1_err_exc_current_el_SP0)
-
-/* exceptions from current EL, using SPx */
-.org 0x200
-LOCAL_FUNCTION_LABEL(arm64_el1_sync_exc_current_el_SPx)
-    sync_exception #0 /* same EL, arm64 */
-END_FUNCTION(arm64_el1_sync_exc_current_el_SPx)
-
-.org 0x280
-LOCAL_FUNCTION_LABEL(arm64_el1_irq_current_el_SPx)
-    irq_exception #0 /* same EL, arm64 */
-END_FUNCTION(arm64_el1_irq_current_el_SPx)
-
-.org 0x300
-LOCAL_FUNCTION_LABEL(arm64_el1_fiq_current_el_SPx)
-    start_isr_func
-    regsave_short
-    mov x0, sp
-    bl  platform_fiq
-    b  arm64_exc_shared_restore_short
-END_FUNCTION(arm64_el1_fiq_current_el_SPx)
-
-.org 0x380
-LOCAL_FUNCTION_LABEL(arm64_el1_err_exc_current_el_SPx)
-    invalid_exception 0x13
-END_FUNCTION(arm64_el1_err_exc_current_el_SPx)
-
-/* exceptions from lower EL, running arm64 */
-.org 0x400
-LOCAL_FUNCTION_LABEL(arm64_el1_sync_exc_lower_el_64)
-    sync_exception #(ARM64_EXCEPTION_FLAG_LOWER_EL), 1
-END_FUNCTION(arm64_el1_sync_exc_lower_el_64)
-
-.org 0x480
-LOCAL_FUNCTION_LABEL(arm64_el1_irq_lower_el_64)
-    irq_exception #(ARM64_EXCEPTION_FLAG_LOWER_EL)
-END_FUNCTION(arm64_el1_irq_lower_el_64)
-
-.org 0x500
-LOCAL_FUNCTION_LABEL(arm64_el1_fiq_lower_el_64)
-    start_isr_func
-    regsave_short
-    mov x0, sp
-    bl  platform_fiq
-    b  arm64_exc_shared_restore_short
-END_FUNCTION(arm64_el1_fiq_lower_el_64)
-
-.org 0x580
-LOCAL_FUNCTION_LABEL(arm64_el1_err_exc_lower_el_64)
-    invalid_exception 0x23
-END_FUNCTION(arm64_el1_err_exc_lower_el_64)
-
-/* exceptions from lower EL, running arm32 */
-.org 0x600
-LOCAL_FUNCTION_LABEL(arm64_el1_sync_exc_lower_el_32)
-    sync_exception #(ARM64_EXCEPTION_FLAG_LOWER_EL|ARM64_EXCEPTION_FLAG_ARM32)
-END_FUNCTION(arm64_el1_sync_exc_lower_el_32)
-
-.org 0x680
-LOCAL_FUNCTION_LABEL(arm64_el1_irq_lower_el_32)
-    irq_exception #(ARM64_EXCEPTION_FLAG_LOWER_EL|ARM64_EXCEPTION_FLAG_ARM32)
-END_FUNCTION(arm64_el1_irq_lower_el_32)
-
-.org 0x700
-LOCAL_FUNCTION_LABEL(arm64_el1_fiq_lower_el_32)
-    start_isr_func
-    regsave_short
-    mov x0, sp
-    bl  platform_fiq
-    b  arm64_exc_shared_restore_short
-END_FUNCTION(arm64_el1_fiq_lower_el_32)
-
-.org 0x780
-LOCAL_FUNCTION_LABEL(arm64_el1_err_exc_lower_el_32)
-    invalid_exception 0x33
-END_FUNCTION(arm64_el1_err_exc_lower_el_32)
-
-/* If an IRQ happened in userspace, and either the thread was signaled or
-   needs to be rescheduled, then we end up here after arm64_irq returns.
-   Suspending the thread requires constructing a long iframe in order to
-   provide the values of all regs to any debugger that wishes to access
-   them, but we can't do that until arm64_irq returns as we rely on the
-   compiler to save/restore callee-saved regs. */
-LOCAL_FUNCTION_LABEL(arm64_finish_user_irq_wrapper)
-    start_short_helper
-    /* if we're only here because of a need to reschedule then we don't
-       need to construct a long iframe */
-    cmp x0, #ARM64_IRQ_EXIT_RESCHEDULE
-    bne 1f
-    mov x1, #0 /* don't need an iframe, just pass NULL */
-    bl  arm64_finish_user_irq
-    msr daifset, #1 /* disable fiqs to protect elr and spsr restore */
-    b   arm64_exc_shared_restore_short
-1:
-    /* convert the short to a long frame */
-    regsave_short_to_long
-    mov x1, sp
-    bl  arm64_finish_user_irq
-    msr daifset, #1 /* disable fiqs to protect elr and spsr restore */
-    b   arm64_exc_shared_restore_long
-END_FUNCTION(arm64_finish_user_irq_wrapper)
-
-LOCAL_FUNCTION_LABEL(arm64_exc_shared_restore_long)
-    start_long_helper
-    regrestore_long
-    eret
-END_FUNCTION(arm64_exc_shared_restore_long)
-
-LOCAL_FUNCTION_LABEL(arm64_exc_shared_restore_short)
-    start_short_helper
-    regrestore_short
-    eret
-END_FUNCTION(arm64_exc_shared_restore_short)
-
-//
-// Syscall args are in x0-x7 already.
-// pc is in x10 and needs to go in the next available register,
-// or the stack if the regs are full.
-//
-.macro pre_args, nargs
-.if \nargs == 8
-    push_regs x10, x11 // push twice to maintain alignment
-.else
-    mov x\nargs, x10
-.endif
-.endm
-
-.macro post_args, nargs
-.if \nargs == 8
-    pop_regs x10, x11
-.endif
-    b .Lpost_syscall
-.endm
-
-//
-// Expected state prior to arm64_syscall_dispatcher branch...
-//
-// x0-x7 - contains syscall arguments
-// x9    - contains esr_el1
-// x10   - contains elr_el1
-// x16   - contains syscall_num
-// sp    - points to base of frame (frame->r[0])
-//
-// Expected state prior to unknown_syscall and wrapper_syscall...
-//
-// x0-x7  - contains syscall arguments
-// x10    - contains userspace pc
-//
-LOCAL_FUNCTION_LABEL(arm64_syscall_dispatcher)
-    start_isr_func
-    // Restore per cpu pointer
-    mrs  x11, tpidr_el1
-    ldr  x18, [x11, #CURRENT_PERCPU_PTR_OFFSET]
-    // Verify syscall number and call the unknown handler if bad.
-    cmp  x16, #ZX_SYS_COUNT
-    bhs  .Lunknown_syscall
-    // Jump to the right syscall wrapper.
-    // call_wrapper_table is 4096 byte aligned so just use adrp
-    adrp x12, call_wrapper_table
-    ldr  x12, [x12, x16, LSL#3]
-    br   x12
-.Lunknown_syscall:
-    mov  x0, x16
-    pre_args 1
-    bl   unknown_syscall
-    post_args 1
-.Lpost_syscall:
-    // Upon return from syscall, x0 = status, x1 = thread signalled
-    // Move the status to frame->r[0] for return to userspace.
-    str  x0, [sp]
-    // Check for pending signals. If none, just return.
-    cbz  x1, arm64_exc_shared_restore_long
-    mov  x0, sp
-    bl   arm64_thread_process_pending_signals
-    b    arm64_exc_shared_restore_long
-END_FUNCTION(arm64_syscall_dispatcher)
-
-// Adds a label for making the syscall and adds it to the jump table.
-.macro syscall_dispatch nargs, syscall
-    .pushsection .text.syscall-dispatch,"ax",%progbits
-    LOCAL_FUNCTION(.Lcall_\syscall\())
-        pre_args \nargs
-        bl wrapper_\syscall
-        post_args \nargs
-    END_FUNCTION(.Lcall_\syscall\())
-    .popsection
-    .pushsection .rodata.syscall-table,"a",%progbits
-        .quad .Lcall_\syscall
-    .popsection
-.endm
-
-// Adds the label for the jump table.
-.macro start_syscall_dispatch
-    .pushsection .rodata.syscall-table,"a",%progbits
-    // align on 4096 byte boundary to save an instruction on table lookup
-    .balign 4096
-    call_wrapper_table:
-    .popsection
-.endm
-
-#include <zircon/syscall-kernel-branches.S>
diff --git a/kernel/arch/arm64/exceptions_c.cpp b/kernel/arch/arm64/exceptions_c.cpp
deleted file mode 100644
index 9f459c7..0000000
--- a/kernel/arch/arm64/exceptions_c.cpp
+++ /dev/null
@@ -1,477 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arch_ops.h>
-#include <arch/arm64.h>
-#include <arch/arm64/exceptions.h>
-#include <arch/exception.h>
-#include <arch/user_copy.h>
-
-#include <bits.h>
-#include <debug.h>
-#include <inttypes.h>
-
-#include <kernel/interrupt.h>
-#include <kernel/thread.h>
-
-#include <platform.h>
-#include <stdio.h>
-#include <trace.h>
-#include <vm/fault.h>
-#include <vm/vm.h>
-
-#include <lib/counters.h>
-#include <lib/crashlog.h>
-
-#include <zircon/syscalls/exception.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-#define DFSC_ALIGNMENT_FAULT 0b100001
-
-static void dump_iframe(const struct arm64_iframe_long* iframe) {
-    printf("iframe %p:\n", iframe);
-    printf("x0  %#18" PRIx64 " x1  %#18" PRIx64 " x2  %#18" PRIx64 " x3  %#18" PRIx64 "\n", iframe->r[0], iframe->r[1], iframe->r[2], iframe->r[3]);
-    printf("x4  %#18" PRIx64 " x5  %#18" PRIx64 " x6  %#18" PRIx64 " x7  %#18" PRIx64 "\n", iframe->r[4], iframe->r[5], iframe->r[6], iframe->r[7]);
-    printf("x8  %#18" PRIx64 " x9  %#18" PRIx64 " x10 %#18" PRIx64 " x11 %#18" PRIx64 "\n", iframe->r[8], iframe->r[9], iframe->r[10], iframe->r[11]);
-    printf("x12 %#18" PRIx64 " x13 %#18" PRIx64 " x14 %#18" PRIx64 " x15 %#18" PRIx64 "\n", iframe->r[12], iframe->r[13], iframe->r[14], iframe->r[15]);
-    printf("x16 %#18" PRIx64 " x17 %#18" PRIx64 " x18 %#18" PRIx64 " x19 %#18" PRIx64 "\n", iframe->r[16], iframe->r[17], iframe->r[18], iframe->r[19]);
-    printf("x20 %#18" PRIx64 " x21 %#18" PRIx64 " x22 %#18" PRIx64 " x23 %#18" PRIx64 "\n", iframe->r[20], iframe->r[21], iframe->r[22], iframe->r[23]);
-    printf("x24 %#18" PRIx64 " x25 %#18" PRIx64 " x26 %#18" PRIx64 " x27 %#18" PRIx64 "\n", iframe->r[24], iframe->r[25], iframe->r[26], iframe->r[27]);
-    printf("x28 %#18" PRIx64 " x29 %#18" PRIx64 " lr  %#18" PRIx64 " usp %#18" PRIx64 "\n", iframe->r[28], iframe->r[29], iframe->lr, iframe->usp);
-    printf("elr  %#18" PRIx64 "\n", iframe->elr);
-    printf("spsr %#18" PRIx64 "\n", iframe->spsr);
-}
-
-KCOUNTER(exceptions_brkpt, "kernel.exceptions.breakpoint");
-KCOUNTER(exceptions_fpu, "kernel.exceptions.fpu");
-KCOUNTER(exceptions_page, "kernel.exceptions.page_fault");
-KCOUNTER(exceptions_irq, "kernel.exceptions.irq");
-KCOUNTER(exceptions_unhandled, "kernel.exceptions.unhandled");
-KCOUNTER(exceptions_user, "kernel.exceptions.user");
-KCOUNTER(exceptions_unknown, "kernel.exceptions.unknown");
-
-static zx_status_t try_dispatch_user_data_fault_exception(
-    zx_excp_type_t type, struct arm64_iframe_long* iframe,
-    uint32_t esr, uint64_t far) {
-    thread_t* thread = get_current_thread();
-    arch_exception_context_t context = {};
-    DEBUG_ASSERT(iframe != nullptr);
-    context.frame = iframe;
-    context.esr = esr;
-    context.far = far;
-
-    arch_enable_ints();
-    DEBUG_ASSERT(thread->arch.suspended_general_regs == nullptr);
-    thread->arch.suspended_general_regs = iframe;
-    zx_status_t status = dispatch_user_exception(type, &context);
-    thread->arch.suspended_general_regs = nullptr;
-    arch_disable_ints();
-    return status;
-}
-
-static zx_status_t try_dispatch_user_exception(
-    zx_excp_type_t type, struct arm64_iframe_long* iframe, uint32_t esr) {
-    return try_dispatch_user_data_fault_exception(type, iframe, esr, 0);
-}
-
-__NO_RETURN static void exception_die(struct arm64_iframe_long* iframe, uint32_t esr) {
-    platform_panic_start();
-
-    uint32_t ec = BITS_SHIFT(esr, 31, 26);
-    uint32_t il = BIT(esr, 25);
-    uint32_t iss = BITS(esr, 24, 0);
-
-    /* fatal exception, die here */
-    printf("ESR 0x%x: ec 0x%x, il 0x%x, iss 0x%x\n", esr, ec, il, iss);
-    dump_iframe(iframe);
-    crashlog.iframe = iframe;
-
-    platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
-}
-
-static void arm64_unknown_handler(struct arm64_iframe_long* iframe, uint exception_flags,
-                                  uint32_t esr) {
-    /* this is for a lot of reasons, but most of them are undefined instructions */
-    if (unlikely((exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) == 0)) {
-        /* trapped inside the kernel, this is bad */
-        printf("unknown exception in kernel: PC at %#" PRIx64 "\n", iframe->elr);
-        exception_die(iframe, esr);
-    }
-    try_dispatch_user_exception(ZX_EXCP_UNDEFINED_INSTRUCTION, iframe, esr);
-}
-
-static void arm64_brk_handler(struct arm64_iframe_long* iframe, uint exception_flags,
-                              uint32_t esr) {
-    if (unlikely((exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) == 0)) {
-        /* trapped inside the kernel, this is bad */
-        printf("BRK in kernel: PC at %#" PRIx64 "\n", iframe->elr);
-        exception_die(iframe, esr);
-    }
-    try_dispatch_user_exception(ZX_EXCP_SW_BREAKPOINT, iframe, esr);
-}
-
-static void arm64_hw_breakpoint_handler(struct arm64_iframe_long* iframe, uint exception_flags,
-                                        uint32_t esr) {
-    if (unlikely((exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) == 0)) {
-        /* trapped inside the kernel, this is bad */
-        printf("HW breakpoint in kernel: PC at %#" PRIx64 "\n", iframe->elr);
-        exception_die(iframe, esr);
-    }
-
-    // We don't need to save the debug state because it doesn't change by an exception. The only
-    // way to change the debug state is through the thread write syscall.
-
-    // NOTE: ARM64 Doesn't provide a good way to comunicate exception status (without exposing ESR
-    //       to userspace). This means a debugger will have to compare the registers with the PC
-    //       on the exceptions to find out which breakpoint triggered the exception.
-    try_dispatch_user_exception(ZX_EXCP_HW_BREAKPOINT, iframe, esr);
-}
-
-static void arm64_step_handler(struct arm64_iframe_long* iframe, uint exception_flags,
-                               uint32_t esr) {
-    if (unlikely((exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) == 0)) {
-        /* trapped inside the kernel, this is bad */
-        printf("software step in kernel: PC at %#" PRIx64 "\n", iframe->elr);
-        exception_die(iframe, esr);
-    }
-    // TODO(ZX-3037): Is it worth separating this into two separate exceptions?
-    try_dispatch_user_exception(ZX_EXCP_HW_BREAKPOINT, iframe, esr);
-}
-
-static void arm64_fpu_handler(struct arm64_iframe_long* iframe, uint exception_flags,
-                              uint32_t esr) {
-    if (unlikely((exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) == 0)) {
-        /* we trapped a floating point instruction inside our own EL, this is bad */
-        printf("invalid fpu use in kernel: PC at %#" PRIx64 "\n",
-               iframe->elr);
-        exception_die(iframe, esr);
-    }
-    arm64_fpu_exception(iframe, exception_flags);
-}
-
-static void arm64_instruction_abort_handler(struct arm64_iframe_long* iframe, uint exception_flags,
-                                            uint32_t esr) {
-    /* read the FAR register */
-    uint64_t far = __arm_rsr64("far_el1");
-    uint32_t ec = BITS_SHIFT(esr, 31, 26);
-    uint32_t iss = BITS(esr, 24, 0);
-    bool is_user = !BIT(ec, 0);
-
-    uint pf_flags = VMM_PF_FLAG_INSTRUCTION;
-    pf_flags |= is_user ? VMM_PF_FLAG_USER : 0;
-    /* Check if this was not permission fault */
-    if ((iss & 0b111100) != 0b001100) {
-        pf_flags |= VMM_PF_FLAG_NOT_PRESENT;
-    }
-
-    LTRACEF("instruction abort: PC at %#" PRIx64
-            ", is_user %d, FAR %" PRIx64 ", esr 0x%x, iss 0x%x\n",
-            iframe->elr, is_user, far, esr, iss);
-
-    arch_enable_ints();
-    kcounter_add(exceptions_page, 1);
-    CPU_STATS_INC(page_faults);
-    zx_status_t err = vmm_page_fault_handler(far, pf_flags);
-    arch_disable_ints();
-    if (err >= 0)
-        return;
-
-    // If this is from user space, let the user exception handler
-    // get a shot at it.
-    if (is_user) {
-        kcounter_add(exceptions_user, 1);
-        if (try_dispatch_user_data_fault_exception(ZX_EXCP_FATAL_PAGE_FAULT, iframe, esr, far) == ZX_OK)
-            return;
-    }
-
-    printf("instruction abort: PC at %#" PRIx64 ", is_user %d, FAR %" PRIx64 "\n",
-           iframe->elr, is_user, far);
-    exception_die(iframe, esr);
-}
-
-static void arm64_data_abort_handler(struct arm64_iframe_long* iframe, uint exception_flags,
-                                     uint32_t esr) {
-    /* read the FAR register */
-    uint64_t far = __arm_rsr64("far_el1");
-    uint32_t ec = BITS_SHIFT(esr, 31, 26);
-    uint32_t iss = BITS(esr, 24, 0);
-    bool is_user = !BIT(ec, 0);
-    bool WnR = BIT(iss, 6); // Write not Read
-    bool CM = BIT(iss, 8);  // cache maintenance op
-
-    uint pf_flags = 0;
-    // if it was marked Write but the cache maintenance bit was set, treat it as read
-    pf_flags |= (WnR && !CM) ? VMM_PF_FLAG_WRITE : 0;
-    pf_flags |= is_user ? VMM_PF_FLAG_USER : 0;
-    /* Check if this was not permission fault */
-    if ((iss & 0b111100) != 0b001100) {
-        pf_flags |= VMM_PF_FLAG_NOT_PRESENT;
-    }
-
-    LTRACEF("data fault: PC at %#" PRIx64
-            ", is_user %d, FAR %#" PRIx64 ", esr 0x%x, iss 0x%x\n",
-            iframe->elr, is_user, far, esr, iss);
-
-    uint32_t dfsc = BITS(iss, 5, 0);
-    if (likely(dfsc != DFSC_ALIGNMENT_FAULT)) {
-        arch_enable_ints();
-        kcounter_add(exceptions_page, 1);
-        zx_status_t err = vmm_page_fault_handler(far, pf_flags);
-        arch_disable_ints();
-        if (err >= 0) {
-            return;
-        }
-    }
-
-    // Check if the current thread was expecting a data fault and
-    // we should return to its handler.
-    thread_t* thr = get_current_thread();
-    if (thr->arch.data_fault_resume != NULL && is_user_address(far)) {
-        iframe->elr = (uintptr_t)thr->arch.data_fault_resume;
-        return;
-    }
-
-    // If this is from user space, let the user exception handler
-    // get a shot at it.
-    if (is_user) {
-        kcounter_add(exceptions_user, 1);
-        zx_excp_type_t excp_type = ZX_EXCP_FATAL_PAGE_FAULT;
-        if (unlikely(dfsc == DFSC_ALIGNMENT_FAULT)) {
-            excp_type = ZX_EXCP_UNALIGNED_ACCESS;
-        }
-        if (try_dispatch_user_data_fault_exception(excp_type, iframe, esr, far) == ZX_OK)
-            return;
-    }
-
-    /* decode the iss */
-    if (BIT(iss, 24)) { /* ISV bit */
-        printf("data fault: PC at %#" PRIx64
-               ", FAR %#" PRIx64 ", iss %#x (DFSC %#x)\n",
-               iframe->elr, far, iss, BITS(iss, 5, 0));
-    } else {
-        printf("data fault: PC at %#" PRIx64
-               ", FAR %#" PRIx64 ", iss 0x%x\n",
-               iframe->elr, far, iss);
-    }
-
-    exception_die(iframe, esr);
-}
-
-static inline void arm64_restore_percpu_pointer() {
-    arm64_write_percpu_ptr(get_current_thread()->arch.current_percpu_ptr);
-}
-
-/* called from assembly */
-extern "C" void arm64_sync_exception(
-    struct arm64_iframe_long* iframe, uint exception_flags, uint32_t esr) {
-    uint32_t ec = BITS_SHIFT(esr, 31, 26);
-
-    if (exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) {
-        // if we came from a lower level, restore the per cpu pointer
-        arm64_restore_percpu_pointer();
-    }
-
-    switch (ec) {
-    case 0b000000: /* unknown reason */
-        kcounter_add(exceptions_unknown, 1);
-        arm64_unknown_handler(iframe, exception_flags, esr);
-        break;
-    case 0b111000: /* BRK from arm32 */
-    case 0b111100: /* BRK from arm64 */
-        kcounter_add(exceptions_brkpt, 1);
-        arm64_brk_handler(iframe, exception_flags, esr);
-        break;
-    case 0b000111: /* floating point */
-        kcounter_add(exceptions_fpu, 1);
-        arm64_fpu_handler(iframe, exception_flags, esr);
-        break;
-    case 0b010001: /* syscall from arm32 */
-    case 0b010101: /* syscall from arm64 */
-        printf("syscalls should be handled in assembly\n");
-        exception_die(iframe, esr);
-        break;
-    case 0b100000: /* instruction abort from lower level */
-    case 0b100001: /* instruction abort from same level */
-        arm64_instruction_abort_handler(iframe, exception_flags, esr);
-        break;
-    case 0b100100: /* data abort from lower level */
-    case 0b100101: /* data abort from same level */
-        arm64_data_abort_handler(iframe, exception_flags, esr);
-        break;
-    case 0b110000: /* HW breakpoint from a lower level */
-    case 0b110001: /* HW breakpoint from same level */
-        arm64_hw_breakpoint_handler(iframe, exception_flags, esr);
-        break;
-    case 0b110010: /* software step from lower level */
-    case 0b110011: /* software step from same level */
-        arm64_step_handler(iframe, exception_flags, esr);
-        break;
-    default: {
-        /* TODO: properly decode more of these */
-        if (unlikely((exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) == 0)) {
-            /* trapped inside the kernel, this is bad */
-            printf("unhandled exception in kernel: PC at %#" PRIx64 "\n", iframe->elr);
-            exception_die(iframe, esr);
-        }
-        /* let the user exception handler get a shot at it */
-        kcounter_add(exceptions_unhandled, 1);
-        if (try_dispatch_user_exception(ZX_EXCP_GENERAL, iframe, esr) == ZX_OK)
-            break;
-        printf("unhandled synchronous exception\n");
-        exception_die(iframe, esr);
-    }
-    }
-
-    /* if we came from user space, check to see if we have any signals to handle */
-    if (unlikely(exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL)) {
-        /* in the case of receiving a kill signal, this function may not return,
-         * but the scheduler would have been invoked so it's fine.
-         */
-        arm64_thread_process_pending_signals(iframe);
-    }
-
-    /* if we're returning to kernel space, make sure we restore the correct x18 */
-    if ((exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) == 0) {
-        iframe->r[18] = (uint64_t)arm64_read_percpu_ptr();
-    }
-}
-
-/* called from assembly */
-extern "C" uint32_t arm64_irq(struct arm64_iframe_short* iframe, uint exception_flags) {
-    if (exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) {
-        // if we came from a lower level, restore the per cpu pointer
-        arm64_restore_percpu_pointer();
-    }
-
-    LTRACEF("iframe %p, flags 0x%x\n", iframe, exception_flags);
-
-    int_handler_saved_state_t state;
-    int_handler_start(&state);
-
-    kcounter_add(exceptions_irq, 1);
-    platform_irq(iframe);
-
-    bool do_preempt = int_handler_finish(&state);
-
-    /* if we came from user space, check to see if we have any signals to handle */
-    if (unlikely(exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL)) {
-        uint32_t exit_flags = 0;
-        if (thread_is_signaled(get_current_thread()))
-            exit_flags |= ARM64_IRQ_EXIT_THREAD_SIGNALED;
-        if (do_preempt)
-            exit_flags |= ARM64_IRQ_EXIT_RESCHEDULE;
-        return exit_flags;
-    }
-
-    /* preempt the thread if the interrupt has signaled it */
-    if (do_preempt)
-        thread_preempt();
-
-    /* if we're returning to kernel space, make sure we restore the correct x18 */
-    if ((exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL) == 0) {
-        iframe->r[18] = (uint64_t)arm64_read_percpu_ptr();
-    }
-
-    return 0;
-}
-
-/* called from assembly */
-extern "C" void arm64_finish_user_irq(uint32_t exit_flags, struct arm64_iframe_long* iframe) {
-    // we came from a lower level, so restore the per cpu pointer
-    arm64_restore_percpu_pointer();
-
-    /* in the case of receiving a kill signal, this function may not return,
-     * but the scheduler would have been invoked so it's fine.
-     */
-    if (unlikely(exit_flags & ARM64_IRQ_EXIT_THREAD_SIGNALED)) {
-        DEBUG_ASSERT(iframe != nullptr);
-        arm64_thread_process_pending_signals(iframe);
-    }
-
-    /* preempt the thread if the interrupt has signaled it */
-    if (exit_flags & ARM64_IRQ_EXIT_RESCHEDULE)
-        thread_preempt();
-}
-
-/* called from assembly */
-extern "C" void arm64_invalid_exception(struct arm64_iframe_long* iframe, unsigned int which) {
-    // restore the percpu pointer (x18) unconditionally
-    arm64_restore_percpu_pointer();
-
-    printf("invalid exception, which 0x%x\n", which);
-    dump_iframe(iframe);
-
-    platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
-}
-
-/* called from assembly */
-extern "C" void arm64_thread_process_pending_signals(struct arm64_iframe_long* iframe) {
-    thread_t* thread = get_current_thread();
-    DEBUG_ASSERT(iframe != nullptr);
-    DEBUG_ASSERT(thread->arch.suspended_general_regs == nullptr);
-
-    thread->arch.suspended_general_regs = iframe;
-    thread_process_pending_signals();
-    thread->arch.suspended_general_regs = nullptr;
-}
-
-void arch_dump_exception_context(const arch_exception_context_t* context) {
-    uint32_t ec = BITS_SHIFT(context->esr, 31, 26);
-    uint32_t iss = BITS(context->esr, 24, 0);
-
-    switch (ec) {
-    case 0b100000: /* instruction abort from lower level */
-    case 0b100001: /* instruction abort from same level */
-        printf("instruction abort: PC at %#" PRIx64
-               ", address %#" PRIx64 " IFSC %#x %s\n",
-               context->frame->elr, context->far,
-               BITS(context->esr, 5, 0),
-               BIT(ec, 0) ? "" : "user ");
-
-        break;
-    case 0b100100: /* data abort from lower level */
-    case 0b100101: /* data abort from same level */
-        printf("data abort: PC at %#" PRIx64
-               ", address %#" PRIx64 " %s%s\n",
-               context->frame->elr, context->far,
-               BIT(ec, 0) ? "" : "user ",
-               BIT(iss, 6) ? "write" : "read");
-    }
-
-    dump_iframe(context->frame);
-
-    // try to dump the user stack
-    if (is_user_address(context->frame->usp)) {
-        uint8_t buf[256];
-        if (arch_copy_from_user(buf, (void*)context->frame->usp, sizeof(buf)) == ZX_OK) {
-            printf("bottom of user stack at 0x%lx:\n", (vaddr_t)context->frame->usp);
-            hexdump_ex(buf, sizeof(buf), context->frame->usp);
-        }
-    }
-}
-
-void arch_fill_in_exception_context(const arch_exception_context_t* arch_context, zx_exception_report_t* report) {
-    zx_exception_context_t* zx_context = &report->context;
-
-    zx_context->arch.u.arm_64.esr = arch_context->esr;
-
-    // If there was a fatal page fault, fill in the address that caused the fault.
-    if (ZX_EXCP_FATAL_PAGE_FAULT == report->header.type) {
-        zx_context->arch.u.arm_64.far = arch_context->far;
-    } else {
-        zx_context->arch.u.arm_64.far = 0;
-    }
-}
-
-zx_status_t arch_dispatch_user_policy_exception(void) {
-    struct arm64_iframe_long frame = {};
-    arch_exception_context_t context = {};
-    context.frame = &frame;
-    return dispatch_user_exception(ZX_EXCP_POLICY_ERROR, &context);
-}
diff --git a/kernel/arch/arm64/feature.cpp b/kernel/arch/arm64/feature.cpp
deleted file mode 100644
index 54065b6..0000000
--- a/kernel/arch/arm64/feature.cpp
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/feature.h>
-
-#include <arch/arm64.h>
-#include <bits.h>
-#include <fbl/algorithm.h>
-#include <inttypes.h>
-
-// saved feature bitmap
-uint32_t arm64_features;
-
-static arm64_cache_info_t cache_info[SMP_MAX_CPUS];
-
-// cache size parameters cpus, default to a reasonable minimum
-uint32_t arm64_zva_size = 32;
-uint32_t arm64_icache_size = 32;
-uint32_t arm64_dcache_size = 32;
-
-static void parse_ccsid(arm64_cache_desc_t* desc, uint64_t ccsid) {
-    desc->write_through = BIT(ccsid, 31) > 0;
-    desc->write_back = BIT(ccsid, 30) > 0;
-    desc->read_alloc = BIT(ccsid, 29) > 0;
-    desc->write_alloc = BIT(ccsid, 28) > 0;
-    desc->num_sets = (uint32_t)BITS_SHIFT(ccsid, 27, 13) + 1;
-    desc->associativity = (uint32_t)BITS_SHIFT(ccsid, 12, 3) + 1;
-    desc->line_size = 1u << (BITS(ccsid, 2, 0) + 4);
-}
-
-void arm64_get_cache_info(arm64_cache_info_t* info) {
-    uint64_t temp = 0;
-
-    uint64_t sysreg = __arm_rsr64("clidr_el1");
-    info->inner_boundary = (uint8_t)BITS_SHIFT(sysreg, 32, 30);
-    info->lou_u = (uint8_t)BITS_SHIFT(sysreg, 29, 27);
-    info->loc = (uint8_t)BITS_SHIFT(sysreg, 26, 24);
-    info->lou_is = (uint8_t)BITS_SHIFT(sysreg, 23, 21);
-    for (int i = 0; i < 7; i++) {
-        uint8_t ctype = (sysreg >> (3 * i)) & 0x07;
-        if (ctype == 0) {
-            info->level_data_type[i].ctype = 0;
-            info->level_inst_type[i].ctype = 0;
-        } else if (ctype == 4) {                               // Unified
-            __arm_wsr64("csselr_el1", (int64_t)(i << 1)); // Select cache level
-            __isb(ARM_MB_SY);
-            temp = __arm_rsr64("ccsidr_el1");
-            info->level_data_type[i].ctype = 4;
-            parse_ccsid(&(info->level_data_type[i]), temp);
-        } else {
-            if (ctype & 0x02) {
-                __arm_wsr64("csselr_el1", (int64_t)(i << 1));
-                __isb(ARM_MB_SY);
-                temp = __arm_rsr64("ccsidr_el1");
-                info->level_data_type[i].ctype = 2;
-                parse_ccsid(&(info->level_data_type[i]), temp);
-            }
-            if (ctype & 0x01) {
-                __arm_wsr64("csselr_el1", (int64_t)(i << 1) | 0x01);
-                __isb(ARM_MB_SY);
-                temp = __arm_rsr64("ccsidr_el1");
-                info->level_inst_type[i].ctype = 1;
-                parse_ccsid(&(info->level_inst_type[i]), temp);
-            }
-        }
-    }
-}
-
-void arm64_dump_cache_info(uint32_t cpu) {
-
-    arm64_cache_info_t* info = &(cache_info[cpu]);
-    printf("==== ARM64 CACHE INFO CORE %u ====\n", cpu);
-    printf("Inner Boundary = L%u\n", info->inner_boundary);
-    printf("Level of Unification Uniprocessor = L%u\n", info->lou_u);
-    printf("Level of Coherence = L%u\n", info->loc);
-    printf("Level of Unification Inner Shareable = L%u\n", info->lou_is);
-    for (int i = 0; i < 7; i++) {
-        printf("L%d Details:", i + 1);
-        if ((info->level_data_type[i].ctype == 0) && (info->level_inst_type[i].ctype == 0)) {
-            printf("\tNot Implemented\n");
-        } else {
-            if (info->level_data_type[i].ctype == 4) {
-                printf("\tUnified Cache, sets=%u, associativity=%u, line size=%u bytes\n",
-                       info->level_data_type[i].num_sets,
-                       info->level_data_type[i].associativity,
-                       info->level_data_type[i].line_size);
-            } else {
-                if (info->level_data_type[i].ctype & 0x02) {
-                    printf("\tData Cache, sets=%u, associativity=%u, line size=%u bytes\n",
-                           info->level_data_type[i].num_sets,
-                           info->level_data_type[i].associativity,
-                           info->level_data_type[i].line_size);
-                }
-                if (info->level_inst_type[i].ctype & 0x01) {
-                    if (info->level_data_type[i].ctype & 0x02) {
-                        printf("\t");
-                    }
-                    printf("\tInstruction Cache, sets=%u, associativity=%u, line size=%u bytes\n",
-                           info->level_inst_type[i].num_sets,
-                           info->level_inst_type[i].associativity,
-                           info->level_inst_type[i].line_size);
-                }
-            }
-        }
-    }
-}
-
-static void midr_to_core(uint32_t midr, char* str, size_t len) {
-    __UNUSED uint32_t implementer = BITS_SHIFT(midr, 31, 24);
-    __UNUSED uint32_t variant = BITS_SHIFT(midr, 23, 20);
-    __UNUSED uint32_t architecture = BITS_SHIFT(midr, 19, 16);
-    __UNUSED uint32_t partnum = BITS_SHIFT(midr, 15, 4);
-    __UNUSED uint32_t revision = BITS_SHIFT(midr, 3, 0);
-
-    const char* partnum_str = "unknown";
-    if (implementer == 'A') {
-        // ARM cores
-        switch (partnum) {
-        case 0xd03:
-            partnum_str = "ARM Cortex-a53";
-            break;
-        case 0xd04:
-            partnum_str = "ARM Cortex-a35";
-            break;
-        case 0xd05:
-            partnum_str = "ARM Cortex-a55";
-            break;
-        case 0xd07:
-            partnum_str = "ARM Cortex-a57";
-            break;
-        case 0xd08:
-            partnum_str = "ARM Cortex-a72";
-            break;
-        case 0xd09:
-            partnum_str = "ARM Cortex-a73";
-            break;
-        case 0xd0a:
-            partnum_str = "ARM Cortex-a75";
-            break;
-        default:
-            goto unknown;
-        }
-    } else if (implementer == 'C') {
-        // Cavium
-        switch (partnum) {
-        case 0xa1:
-            partnum_str = "Cavium CN88XX";
-            break;
-        case 0xaf:
-            partnum_str = "Cavium CN99XX";
-            break;
-        default:
-            goto unknown;
-        }
-    } else {
-unknown:
-        snprintf(str, len, "Unknown implementer %c partnum 0x%x r%up%u",
-                (char)implementer, partnum, variant, revision);
-        return;
-    }
-
-    snprintf(str, len, "%s r%up%u", partnum_str, variant, revision);
-}
-
-static void print_cpu_info() {
-    uint32_t midr = (uint32_t)__arm_rsr64("midr_el1");
-    char cpu_name[128];
-    midr_to_core(midr, cpu_name, sizeof(cpu_name));
-
-    uint64_t mpidr = __arm_rsr64("mpidr_el1");
-
-    dprintf(INFO, "ARM cpu %u: midr %#x '%s' mpidr %#" PRIx64 " aff %u:%u:%u:%u\n",
-            arch_curr_cpu_num(), midr, cpu_name, mpidr,
-            (uint32_t)((mpidr & MPIDR_AFF3_MASK) >> MPIDR_AFF3_SHIFT),
-            (uint32_t)((mpidr & MPIDR_AFF2_MASK) >> MPIDR_AFF2_SHIFT),
-            (uint32_t)((mpidr & MPIDR_AFF1_MASK) >> MPIDR_AFF1_SHIFT),
-            (uint32_t)((mpidr & MPIDR_AFF0_MASK) >> MPIDR_AFF0_SHIFT));
-}
-
-// call on every cpu to save features
-void arm64_feature_init() {
-    // set up some global constants based on the boot cpu
-    cpu_num_t cpu = arch_curr_cpu_num();
-    if (cpu == 0) {
-        // read the block size of DC ZVA
-        uint64_t dczid = __arm_rsr64("dczid_el0");
-        uint32_t arm64_zva_shift = 0;
-        if (BIT(dczid, 4) == 0) {
-            arm64_zva_shift = (uint32_t)(__arm_rsr64("dczid_el0") & 0xf) + 2;
-        }
-        ASSERT(arm64_zva_shift != 0); // for now, fail if DC ZVA is unavailable
-        arm64_zva_size = (1u << arm64_zva_shift);
-
-        // read the dcache and icache line size
-        uint64_t ctr = __arm_rsr64("ctr_el0");
-        uint32_t arm64_dcache_shift = (uint32_t)BITS_SHIFT(ctr, 19, 16) + 2;
-        arm64_dcache_size = (1u << arm64_dcache_shift);
-        uint32_t arm64_icache_shift = (uint32_t)BITS(ctr, 3, 0) + 2;
-        arm64_icache_size = (1u << arm64_icache_shift);
-
-        // parse the ISA feature bits
-        arm64_features |= ZX_HAS_CPU_FEATURES;
-        uint64_t isar0 = __arm_rsr64("id_aa64isar0_el1");
-        if (BITS_SHIFT(isar0, 7, 4) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_AES;
-        }
-        if (BITS_SHIFT(isar0, 7, 4) >= 2) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_PMULL;
-        }
-        if (BITS_SHIFT(isar0, 11, 8) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_SHA1;
-        }
-        if (BITS_SHIFT(isar0, 15, 12) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_SHA2;
-        }
-        if (BITS_SHIFT(isar0, 19, 16) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_CRC32;
-        }
-        if (BITS_SHIFT(isar0, 23, 20) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_ATOMICS;
-        }
-        if (BITS_SHIFT(isar0, 31, 28) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_RDM;
-        }
-        if (BITS_SHIFT(isar0, 35, 32) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_SHA3;
-        }
-        if (BITS_SHIFT(isar0, 39, 36) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_SM3;
-        }
-        if (BITS_SHIFT(isar0, 43, 40) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_SM4;
-        }
-        if (BITS_SHIFT(isar0, 47, 44) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_DP;
-        }
-
-        uint64_t isar1 = __arm_rsr64("id_aa64isar1_el1");
-        if (BITS_SHIFT(isar1, 3, 0) >= 1) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_DPB;
-        }
-
-        uint64_t pfr0 = __arm_rsr64("id_aa64pfr0_el1");
-        if (BITS_SHIFT(pfr0, 19, 16) < 0b1111) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_FP;
-        }
-        if (BITS_SHIFT(pfr0, 23, 20) < 0b1111) {
-            arm64_features |= ZX_ARM64_FEATURE_ISA_ASIMD;
-        }
-    }
-
-    // read the cache info for each cpu
-    arm64_get_cache_info(&(cache_info[cpu]));
-
-    // check to make sure implementation supports 16 bit asids
-    uint64_t mmfr0 = __arm_rsr64("id_aa64mmfr0_el1");
-    ASSERT((mmfr0 & ARM64_MMFR0_ASIDBITS_MASK) == ARM64_MMFR0_ASIDBITS_16);
-}
-
-static void print_feature() {
-    const struct {
-        uint32_t bit;
-        const char* name;
-    } features[] = {
-        {ZX_ARM64_FEATURE_ISA_FP, "fp"},
-        {ZX_ARM64_FEATURE_ISA_ASIMD, "asimd"},
-        {ZX_ARM64_FEATURE_ISA_AES, "aes"},
-        {ZX_ARM64_FEATURE_ISA_PMULL, "pmull"},
-        {ZX_ARM64_FEATURE_ISA_SHA1, "sha1"},
-        {ZX_ARM64_FEATURE_ISA_SHA2, "sha2"},
-        {ZX_ARM64_FEATURE_ISA_CRC32, "crc32"},
-        {ZX_ARM64_FEATURE_ISA_ATOMICS, "atomics"},
-        {ZX_ARM64_FEATURE_ISA_RDM, "rdm"},
-        {ZX_ARM64_FEATURE_ISA_SHA3, "sha3"},
-        {ZX_ARM64_FEATURE_ISA_SM3, "sm3"},
-        {ZX_ARM64_FEATURE_ISA_SM4, "sm4"},
-        {ZX_ARM64_FEATURE_ISA_DP, "dp"},
-        {ZX_ARM64_FEATURE_ISA_DPB, "dpb"},
-    };
-
-    printf("ARM Features: ");
-    uint col = 0;
-    for (uint i = 0; i < fbl::count_of(features); ++i) {
-        if (arm64_feature_test(features[i].bit))
-            col += printf("%s ", features[i].name);
-        if (col >= 80) {
-            printf("\n");
-            col = 0;
-        }
-    }
-    if (col > 0)
-        printf("\n");
-}
-
-// dump the feature set
-// print additional information if full is passed
-void arm64_feature_debug(bool full) {
-    print_cpu_info();
-
-    if (full) {
-        print_feature();
-        dprintf(INFO, "ARM cache line sizes: icache %u dcache %u zva %u\n",
-                arm64_icache_size, arm64_dcache_size, arm64_zva_size);
-        if (LK_DEBUGLEVEL > 0) {
-            arm64_dump_cache_info(arch_curr_cpu_num());
-        }
-    }
-}
diff --git a/kernel/arch/arm64/fpu.cpp b/kernel/arch/arm64/fpu.cpp
deleted file mode 100644
index a338622..0000000
--- a/kernel/arch/arm64/fpu.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2015 Google Inc. All rights reserved
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64.h>
-#include <assert.h>
-#include <bits.h>
-#include <kernel/thread.h>
-#include <trace.h>
-
-#define LOCAL_TRACE 0
-
-/* FPEN bits in the cpacr register
- * 0 means all fpu instructions fault
- * 3 means no faulting at all EL levels
- * other values are not useful to us
- */
-#define FPU_ENABLE_MASK (3 << 20)
-
-static inline bool is_fpu_enabled(uint32_t cpacr) {
-    return !!(BITS(cpacr, 21, 20) != 0);
-}
-
-static void arm64_fpu_load_state(struct thread* t) {
-    struct fpstate* fpstate = &t->arch.fpstate;
-
-    LTRACEF("cpu %u, thread %s, load fpstate %p\n", arch_curr_cpu_num(), t->name, fpstate);
-
-    static_assert(sizeof(fpstate->regs) == 16 * 32, "");
-    __asm__ volatile("ldp     q0, q1, [%0, #(0 * 32)]\n"
-                     "ldp     q2, q3, [%0, #(1 * 32)]\n"
-                     "ldp     q4, q5, [%0, #(2 * 32)]\n"
-                     "ldp     q6, q7, [%0, #(3 * 32)]\n"
-                     "ldp     q8, q9, [%0, #(4 * 32)]\n"
-                     "ldp     q10, q11, [%0, #(5 * 32)]\n"
-                     "ldp     q12, q13, [%0, #(6 * 32)]\n"
-                     "ldp     q14, q15, [%0, #(7 * 32)]\n"
-                     "ldp     q16, q17, [%0, #(8 * 32)]\n"
-                     "ldp     q18, q19, [%0, #(9 * 32)]\n"
-                     "ldp     q20, q21, [%0, #(10 * 32)]\n"
-                     "ldp     q22, q23, [%0, #(11 * 32)]\n"
-                     "ldp     q24, q25, [%0, #(12 * 32)]\n"
-                     "ldp     q26, q27, [%0, #(13 * 32)]\n"
-                     "ldp     q28, q29, [%0, #(14 * 32)]\n"
-                     "ldp     q30, q31, [%0, #(15 * 32)]\n"
-                     "msr     fpcr, %1\n"
-                     "msr     fpsr, %2\n" ::"r"(fpstate->regs),
-                     "r"((uint64_t)fpstate->fpcr),
-                     "r"((uint64_t)fpstate->fpsr));
-}
-
-__NO_SAFESTACK static void arm64_fpu_save_state(struct thread* t) {
-    struct fpstate* fpstate = &t->arch.fpstate;
-
-    LTRACEF("cpu %u, thread %s, save fpstate %p\n", arch_curr_cpu_num(), t->name, fpstate);
-
-    __asm__ volatile("stp     q0, q1, [%0, #(0 * 32)]\n"
-                     "stp     q2, q3, [%0, #(1 * 32)]\n"
-                     "stp     q4, q5, [%0, #(2 * 32)]\n"
-                     "stp     q6, q7, [%0, #(3 * 32)]\n"
-                     "stp     q8, q9, [%0, #(4 * 32)]\n"
-                     "stp     q10, q11, [%0, #(5 * 32)]\n"
-                     "stp     q12, q13, [%0, #(6 * 32)]\n"
-                     "stp     q14, q15, [%0, #(7 * 32)]\n"
-                     "stp     q16, q17, [%0, #(8 * 32)]\n"
-                     "stp     q18, q19, [%0, #(9 * 32)]\n"
-                     "stp     q20, q21, [%0, #(10 * 32)]\n"
-                     "stp     q22, q23, [%0, #(11 * 32)]\n"
-                     "stp     q24, q25, [%0, #(12 * 32)]\n"
-                     "stp     q26, q27, [%0, #(13 * 32)]\n"
-                     "stp     q28, q29, [%0, #(14 * 32)]\n"
-                     "stp     q30, q31, [%0, #(15 * 32)]\n" ::"r"(fpstate->regs));
-
-    // These are 32-bit values, but the msr instruction always uses a
-    // 64-bit destination register.
-    uint64_t fpcr, fpsr;
-    __asm__("mrs %0, fpcr\n"
-            : "=r"(fpcr));
-    __asm__("mrs %0, fpsr\n"
-            : "=r"(fpsr));
-    fpstate->fpcr = (uint32_t)fpcr;
-    fpstate->fpsr = (uint32_t)fpsr;
-
-    LTRACEF("thread %s, fpcr %x, fpsr %x\n", t->name, fpstate->fpcr, fpstate->fpsr);
-}
-
-/* save fpu state if the thread had dirtied it and disable the fpu */
-__NO_SAFESTACK void arm64_fpu_context_switch(struct thread* oldthread,
-                                             struct thread* newthread) {
-    uint64_t cpacr = __arm_rsr64("cpacr_el1");
-    if (is_fpu_enabled((uint32_t)cpacr)) {
-        LTRACEF("saving state on thread %s\n", oldthread->name);
-
-        /* save the state */
-        arm64_fpu_save_state(oldthread);
-
-        /* disable the fpu again */
-        __arm_wsr64("cpacr_el1", cpacr & ~FPU_ENABLE_MASK);
-        __isb(ARM_MB_SY);
-    }
-}
-
-/* called because of a fpu instruction used exception */
-void arm64_fpu_exception(struct arm64_iframe_long* iframe, uint exception_flags) {
-    LTRACEF("cpu %u, thread %s, flags 0x%x\n", arch_curr_cpu_num(), get_current_thread()->name, exception_flags);
-
-    /* only valid to be called if exception came from lower level */
-    DEBUG_ASSERT(exception_flags & ARM64_EXCEPTION_FLAG_LOWER_EL);
-
-    uint64_t cpacr = __arm_rsr64("cpacr_el1");
-    DEBUG_ASSERT(!is_fpu_enabled((uint32_t)cpacr));
-
-    /* enable the fpu */
-    cpacr |= FPU_ENABLE_MASK;
-    __arm_wsr64("cpacr_el1", cpacr);
-    __isb(ARM_MB_SY);
-
-    /* load the state from the current cpu */
-    thread_t* t = get_current_thread();
-    if (likely(t))
-        arm64_fpu_load_state(t);
-}
diff --git a/kernel/arch/arm64/hypervisor/MAINTAINERS b/kernel/arch/arm64/hypervisor/MAINTAINERS
deleted file mode 100644
index 3d9d155..0000000
--- a/kernel/arch/arm64/hypervisor/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-abdulla@google.com
-alexlegg@google.com
diff --git a/kernel/arch/arm64/hypervisor/el2.S b/kernel/arch/arm64/hypervisor/el2.S
deleted file mode 100644
index e41e136..0000000
--- a/kernel/arch/arm64/hypervisor/el2.S
+++ /dev/null
@@ -1,585 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/hypervisor/el2_state.h>
-#include <arch/arm64/mmu.h>
-#include <arch/asm_macros.h>
-#include <asm.h>
-#include <zircon/errors.h>
-
-#define CNTHCTL_EL2_EL1PCTEN            BIT_32(0)
-#define CNTHCTL_EL2_EL1PCEN             BIT_32(1)
-
-#define CPTR_EL2_TFP_SHIFT              10
-#define CPTR_EL2_TFP                    BIT_32(CPTR_EL2_TFP_SHIFT)
-#define CPTR_EL2_RES1                   0x33ff
-
-#define ESR_EL2_EC_FP                   0x07
-#define ESR_EL2_EC_HVC                  0x16
-#define ESR_EL2_EC_SHIFT                26
-#define ESR_EL2_ISS_MASK                0x01ffffff
-
-#define XTCR_EL2_PS_SHIFT               16
-
-#define MDCR_EL2_TDOSA                  BIT_32(10)
-
-// NOTE(abdulla): This excludes the top bit, as it is too large for VTCR_EL2.PS.
-#define ID_AA64MMFR0_EL1_PARANGE_MASK   0x07
-
-.section .text.el2,"ax",@progbits
-.align 12
-
-// Temporary registers to use.
-reg_xs  .req x9
-reg_xt  .req x10
-reg_xa  .req x11
-
-.macro fp_state inst, off
-    add reg_xs, reg_xs, \off
-    \inst q0, q1, [reg_xs, FS_Q(0)]
-    \inst q2, q3, [reg_xs, FS_Q(2)]
-    \inst q4, q5, [reg_xs, FS_Q(4)]
-    \inst q6, q7, [reg_xs, FS_Q(6)]
-    \inst q8, q9, [reg_xs, FS_Q(8)]
-    \inst q10, q11, [reg_xs, FS_Q(10)]
-    \inst q12, q13, [reg_xs, FS_Q(12)]
-    \inst q14, q15, [reg_xs, FS_Q(14)]
-    \inst q16, q17, [reg_xs, FS_Q(16)]
-    \inst q18, q19, [reg_xs, FS_Q(18)]
-    \inst q20, q21, [reg_xs, FS_Q(20)]
-    \inst q22, q23, [reg_xs, FS_Q(22)]
-    \inst q24, q25, [reg_xs, FS_Q(24)]
-    \inst q26, q27, [reg_xs, FS_Q(26)]
-    \inst q28, q29, [reg_xs, FS_Q(28)]
-    \inst q30, q31, [reg_xs, FS_Q(30)]
-.ifc "\inst", "ldp"
-    ldr reg_xt, [reg_xs, FS_FPSR]
-    msr fpsr, reg_xt
-    ldr reg_xt, [reg_xs, FS_FPCR]
-    msr fpcr, reg_xt
-.else
-    mrs reg_xt, fpsr
-    str reg_xt, [reg_xs, FS_FPSR]
-    mrs reg_xt, fpcr
-    str reg_xt, [reg_xs, FS_FPCR]
-.endif
-    sub reg_xs, reg_xs, \off
-.endm
-
-.macro system_register inst, off, sysreg
-.ifc "\inst", "ldr"
-    ldr reg_xa, [reg_xt, \off]
-    msr \sysreg, reg_xa
-.else
-    mrs reg_xa, \sysreg
-    str reg_xa, [reg_xt, \off]
-.endif
-.endm
-
-.macro system_state inst, off
-    add reg_xt, reg_xs, \off
-    system_register \inst, SS_SP_EL0, sp_el0
-    system_register \inst, SS_TPIDR_EL0, tpidr_el0
-    system_register \inst, SS_TPIDRRO_EL0, tpidrro_el0
-
-    system_register \inst, SS_CNTKCTL_EL1, cntkctl_el1
-    system_register \inst, SS_CONTEXTIDR_EL1, contextidr_el1
-    system_register \inst, SS_CPACR_EL1, cpacr_el1
-    system_register \inst, SS_CSSELR_EL1, csselr_el1
-    system_register \inst, SS_ELR_EL1, elr_el1
-    system_register \inst, SS_ESR_EL1, esr_el1
-    system_register \inst, SS_FAR_EL1, far_el1
-    system_register \inst, SS_MAIR_EL1, mair_el1
-    system_register \inst, SS_MDSCR_EL1, mdscr_el1
-    system_register \inst, SS_PAR_EL1, par_el1
-    system_register \inst, SS_SCTLR_EL1, sctlr_el1
-    system_register \inst, SS_SP_EL1, sp_el1
-    system_register \inst, SS_SPSR_EL1, spsr_el1
-    system_register \inst, SS_TCR_EL1, tcr_el1
-    system_register \inst, SS_TPIDR_EL1, tpidr_el1
-    system_register \inst, SS_TTBR0_EL1, ttbr0_el1
-    system_register \inst, SS_TTBR1_EL1, ttbr1_el1
-    system_register \inst, SS_VBAR_EL1, vbar_el1
-
-    system_register \inst, SS_ELR_EL2, elr_el2
-    system_register \inst, SS_SPSR_EL2, spsr_el2
-    system_register \inst, SS_VMPIDR_EL2, vmpidr_el2
-.endm
-
-.macro host_state inst, off
-    add reg_xt, reg_xs, \off
-.ifc "\inst", "ldp"
-    ldr x18, [reg_xt, HS_X(0)]
-.else
-    str x18, [reg_xt, HS_X(0)]
-.endif
-    \inst x19, x20, [reg_xt, HS_X(1)]
-    \inst x21, x22, [reg_xt, HS_X(3)]
-    \inst x23, x24, [reg_xt, HS_X(5)]
-    \inst x25, x26, [reg_xt, HS_X(7)]
-    \inst x27, x28, [reg_xt, HS_X(9)]
-    \inst x29, x30, [reg_xt, HS_X(11)]
-.endm
-
-.macro guest_state inst
-    \inst x0, x1, [reg_xs, GS_X(0)]
-    \inst x2, x3, [reg_xs, GS_X(2)]
-    \inst x4, x5, [reg_xs, GS_X(4)]
-    \inst x6, x7, [reg_xs, GS_X(6)]
-    \inst x10, x11, [reg_xs, GS_X(10)]
-    \inst x12, x13, [reg_xs, GS_X(12)]
-    \inst x14, x15, [reg_xs, GS_X(14)]
-    \inst x16, x17, [reg_xs, GS_X(16)]
-    \inst x18, x19, [reg_xs, GS_X(18)]
-    \inst x20, x21, [reg_xs, GS_X(20)]
-    \inst x22, x23, [reg_xs, GS_X(22)]
-    \inst x24, x25, [reg_xs, GS_X(24)]
-    \inst x26, x27, [reg_xs, GS_X(26)]
-    \inst x28, x29, [reg_xs, GS_X(28)]
-.ifc "\inst", "ldp"
-    ldr x30, [reg_xs, GS_X(30)]
-.else
-    str x30, [reg_xs, GS_X(30)]
-.endif
-.endm
-
-.macro guest_xs_state inst, reg
-    \inst x8, \reg, [reg_xs, GS_X(8)]
-.endm
-
-.macro guest_enter_state
-    ldr reg_xt, [reg_xs, GS_CNTV_CVAL_EL0]
-    msr cntv_cval_el0, reg_xt
-    ldr reg_xt, [reg_xs, GS_CNTV_CTL_EL0]
-    msr cntv_ctl_el0, reg_xt
-.endm
-
-.macro guest_exit_state
-    mrs reg_xt, cntv_ctl_el0
-    str reg_xt, [reg_xs, GS_CNTV_CTL_EL0]
-    mrs reg_xt, cntv_cval_el0
-    str reg_xt, [reg_xs, GS_CNTV_CVAL_EL0]
-    mrs reg_xt, esr_el2
-    str reg_xt, [reg_xs, GS_ESR_EL2]
-    mrs reg_xt, far_el2
-    str reg_xt, [reg_xs, GS_FAR_EL2]
-    mrs reg_xt, hpfar_el2
-    // This is not described well in the manual, but HPFAR_EL2 does not contain
-    // the lower 8 bits of the IPA, so it must be shifted.
-    lsl reg_xt, reg_xt, 8
-    str reg_xt, [reg_xs, GS_HPFAR_EL2]
-.endm
-
-.macro switch_to_guest
-    msr vttbr_el2, x0
-    isb
-.endm
-
-.macro switch_to_host
-    msr vttbr_el2, xzr
-    isb
-.endm
-
-.macro exception_return literal
-    mov x0, \literal
-    eret
-.endm
-
-.macro pop_stack
-    add sp, sp, 16
-.endm
-
-.macro hvc_jump table size
-    mrs reg_xs, esr_el2
-
-    // Check ESR_EL2.EC to determine what caused the exception.
-    lsr reg_xt, reg_xs, ESR_EL2_EC_SHIFT
-    cmp reg_xt, ESR_EL2_EC_HVC
-    b.ne .Linvalid_args_for_\table
-
-    // Check ESR_EL2.ICC to determine whether the HVC index is in range.
-    and reg_xt, reg_xs, ESR_EL2_ISS_MASK
-    cmp reg_xt, \size
-    b.ge .Linvalid_args_for_\table
-
-    // Branch to the jump table.
-    adr reg_xs, \table
-    add reg_xs, reg_xs, reg_xt, lsl 2
-    br reg_xs
-
-.Linvalid_args_for_\table:
-    exception_return ZX_ERR_INVALID_ARGS
-.endm
-
-.macro guest_exit return_code
-    // We push reg_xs onto the stack so we have one scratch register. We only
-    // use reg_xs here, so that we don't accidentally trample the guest state.
-    str reg_xs, [sp, -16]!
-    mov reg_xs, \return_code
-    str reg_xs, [sp, 8]
-.endm
-
-.macro entry_init
-.align 7
-    hvc_jump .Linit_table 4
-.Linit_table:
-    b el2_hvc_psci
-    b el2_hvc_mexec
-    b el2_hvc_on
-    b el2_hvc_tlbi
-.endm
-
-.macro entry_sync return_code
-.align 7
-    guest_exit \return_code
-
-    // Check VTTBR_EL2 to determine whether the exception came from the guest or
-    // from the host.
-    mrs reg_xs, vttbr_el2
-    cbnz reg_xs, el2_guest_exit_or_fp_resume
-
-    // The exception came from the host, so there is no guest state to preserve.
-    pop_stack
-
-    // If we got to here, the exception came from the host or EL2.
-    // Continue execution through a jump table based on the HVC index.
-    hvc_jump .Lsync_table 7
-.Lsync_table:
-    b el2_hvc_psci
-    b el2_hvc_mexec
-    b el2_hvc_off
-    b el2_hvc_tlbi
-    b el2_hvc_resume
-    b el2_hvc_gich_state
-    b el2_hvc_gich_vtr
-.endm
-
-.macro entry_irq return_code
-.align 7
-    guest_exit \return_code
-    b el2_guest_exit
-.endm
-
-.macro entry_invalid_exception
-.align 7
-    // If we got to here, the exception came from the host or EL2.
-    // We reset, as something unexpected happened.
-    mov x0, xzr
-    b psci_system_reset
-.endm
-
-// We have two vector tables that we switch between, init and exec. The reason
-// is that we need to use the stack to temporarily save registers when we exit
-// from a guest. However, that stack may have not been set up, and therefore we
-// can not unconditionally use it. We use the init vector table to set up the
-// stack and hypervisor state, and we use the exec vector table to maintain
-// execution of the hypervisor.
-
-.align 10
-FUNCTION_LABEL(arm64_el2_init_table)
-    /* exceptions from current EL, using SP0 */
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-
-    /* exceptions from current EL, using SPx */
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-
-    /* exceptions from lower EL, running arm64 */
-    entry_init
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-
-    /* exceptions from lower EL, running arm32 */
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-
-.align 10
-FUNCTION_LABEL(arm64_el2_exec_table)
-    /* exceptions from current EL, using SP0 */
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-
-    /* exceptions from current EL, using SPx */
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-
-    /* exceptions from lower EL, running arm64 */
-    entry_sync ZX_OK
-    entry_irq ZX_ERR_NEXT
-    entry_invalid_exception
-    entry_invalid_exception
-
-    /* exceptions from lower EL, running arm32 */
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-    entry_invalid_exception
-
-// zx_status_t arm64_el2_on(zx_paddr_t ttbr0, zx_paddr_t stack_top);
-//
-// |stack_top| must point to the physical address of a contiguous stack.
-FUNCTION(arm64_el2_on)
-    hvc 2
-    ret
-END_FUNCTION(arm64_el2_on)
-FUNCTION_LABEL(el2_hvc_on)
-    // Setup the EL2 translation table.
-    msr ttbr0_el2, x0
-
-    // Setup the EL2 stack pointer.
-    mov sp, x1
-
-    // Load PARange from ID_AA64MMFR0_EL1.
-    mrs reg_xt, id_aa64mmfr0_el1
-    and reg_xt, reg_xt, ID_AA64MMFR0_EL1_PARANGE_MASK
-    lsl reg_xt, reg_xt, XTCR_EL2_PS_SHIFT
-
-    // Setup the virtualisation translation control.
-    movlit reg_xs, MMU_VTCR_EL2_FLAGS
-    // Combine MMU_VTCR_EL2_FLAGS with xTCR_EL2.PS.
-    orr reg_xs, reg_xs, reg_xt
-    msr vtcr_el2, reg_xs
-
-    // Setup the EL2 translation control.
-    movlit reg_xs, MMU_TCR_EL2_FLAGS
-    // Combine MMU_TCR_EL2_FLAGS with xTCR_EL2.PS.
-    orr reg_xs, reg_xs, reg_xt
-    msr tcr_el2, reg_xs
-
-    // Setup the EL2 memory attributes.
-    movlit reg_xs, MMU_MAIR_VAL
-    msr mair_el2, reg_xs
-    isb
-
-    // Invalidate all EL2 TLB entries.
-    tlbi alle2
-    dsb sy
-
-    // Enable the MMU, I-cache, D-cache, and stack alignment checking.
-    movlit reg_xs, SCTLR_ELX_M | SCTLR_ELX_C | SCTLR_ELX_SA | SCTLR_ELX_I | SCTLR_EL2_RES1
-    msr sctlr_el2, reg_xs
-    isb
-
-    // Setup the exec vector table for EL2.
-    adr_global reg_xs, arm64_el2_exec_table
-    msr vbar_el2, reg_xs
-
-    exception_return ZX_OK
-
-FUNCTION_LABEL(el2_hvc_psci)
-    smc 0
-    eret
-
-FUNCTION_LABEL(el2_hvc_mexec)
-    br x0
-
-// zx_status_t arm64_el2_off();
-FUNCTION(arm64_el2_off)
-    hvc 2
-    ret
-END_FUNCTION(arm64_el2_off)
-FUNCTION_LABEL(el2_hvc_off)
-    // Disable the MMU, but enable I-cache, D-cache, and stack alignment checking.
-    movlit reg_xs, SCTLR_ELX_C | SCTLR_ELX_SA | SCTLR_ELX_I | SCTLR_EL2_RES1
-    msr sctlr_el2, reg_xs
-    isb
-
-    // Invalidate all EL2 TLB entries.
-    tlbi alle2
-    isb
-
-    // Setup the init vector table for EL2.
-    adr_global reg_xs, arm64_el2_init_table
-    msr vbar_el2, reg_xs
-    isb
-
-    exception_return ZX_OK
-
-// zx_status_t arm64_el2_tlbi_ipa(zx_paddr_t vttbr, zx_vaddr_t addr, bool terminal);
-FUNCTION(arm64_el2_tlbi_ipa)
-    mov reg_xa, 0
-    hvc 3
-    ret
-END_FUNCTION(arm64_el2_tlbi_ipa)
-
-// zx_status_t arm64_el2_tlbi_vmid(zx_paddr_t vttbr);
-FUNCTION(arm64_el2_tlbi_vmid)
-    mov reg_xa, 1
-    hvc 3
-    ret
-END_FUNCTION(arm64_el2_tlbi_vmid)
-
-FUNCTION_LABEL(el2_hvc_tlbi)
-    switch_to_guest
-
-    cbz reg_xa, el2_hvc_tlbi_ipa
-    b el2_hvc_tlbi_vmid
-
-.Ltlbi_exit:
-    switch_to_host
-    exception_return ZX_OK
-
-FUNCTION_LABEL(el2_hvc_tlbi_ipa)
-    // TLBI IPAS2* instructions take bits [51:12] of the IPA.
-    lsr x1, x1, 12
-
-    // Invalidate IPA. Based on ARM DEN 0024A, page 12-5.
-    dsb ishst
-    cbnz x2, .Lterminal
-    tlbi ipas2e1is, x1
-    b .Lsync
-.Lterminal:
-    tlbi ipas2le1is, x1
-.Lsync:
-    dsb ish
-    tlbi vmalle1is
-    dsb ish
-    isb
-    b .Ltlbi_exit
-
-FUNCTION_LABEL(el2_hvc_tlbi_vmid)
-    // Invalidate VMID. Based on ARM DEN 0024A, page 12-5.
-    dsb ishst
-    tlbi vmalls12e1is
-    dsb ish
-    isb
-    b .Ltlbi_exit
-
-// zx_status_t arm64_el2_resume(zx_paddr_t vttbr, zx_paddr_t state, uint64_t hcr);
-FUNCTION(arm64_el2_resume)
-    hvc 4
-    ret
-END_FUNCTION(arm64_el2_resume)
-FUNCTION_LABEL(el2_hvc_resume)
-    switch_to_guest
-
-    // Save El2State into tpidr_el2.
-    msr tpidr_el2, x1
-    mov reg_xs, x1
-
-    // If the guest is being run for the first time, invalidate all VMID TLB
-    // entries in case the VMID has been used previously.
-    ldr reg_xt, [reg_xs, ES_RESUME]
-    cbnz reg_xt, .Lresume
-    tlbi vmalle1
-    mov reg_xt, 1
-    str reg_xt, [reg_xs, ES_RESUME]
-    dsb nshst
-
-.Lresume:
-    // Set the hypervisor control register.
-    msr hcr_el2, x2
-
-    // Disable access to physical timer.
-    mov reg_xt, CNTHCTL_EL2_EL1PCTEN
-    msr cnthctl_el2, reg_xt
-
-    // Trap any accesses to debug related registers in the guest
-    mov reg_xt, MDCR_EL2_TDOSA
-    msr mdcr_el2, reg_xt
-
-    // Enable floating-point traps.
-    movlit reg_xt, CPTR_EL2_RES1 | CPTR_EL2_TFP
-    msr cptr_el2, reg_xt
-    isb
-
-    host_state stp, HS_X18
-    system_state str, HS_SYSTEM_STATE
-    guest_enter_state
-    system_state ldr, GS_SYSTEM_STATE
-    guest_state ldp
-    guest_xs_state ldp, reg_xs
-
-    // Return to guest.
-    eret
-
-FUNCTION_LABEL(el2_guest_exit_or_fp_resume)
-    // Check ESR_EL2.EC to determine whether the exception was due to a
-    // floating-point trap.
-    mrs reg_xs, esr_el2
-    lsr reg_xs, reg_xs, ESR_EL2_EC_SHIFT
-    cmp reg_xs, ESR_EL2_EC_FP
-    b.eq el2_fp_resume
-
-FUNCTION_LABEL(el2_guest_exit)
-    // Load El2State from tpidr_el2.
-    mrs reg_xs, tpidr_el2
-
-    guest_state stp
-    // Load reg_xs from the stack, and save it in GuestState.
-    ldr reg_xt, [sp]
-    guest_xs_state stp, reg_xt
-    system_state str, GS_SYSTEM_STATE
-    guest_exit_state
-    system_state ldr, HS_SYSTEM_STATE
-    host_state ldp, HS_X18
-
-    mrs reg_xt, cptr_el2
-    tbnz reg_xt, CPTR_EL2_TFP_SHIFT, .Lfp_untrap
-
-    // Restore floating-point state if it was modified.
-    fp_state stp, GS_FP_STATE
-    fp_state ldp, HS_FP_STATE
-    b .Lfp_done
-
-.Lfp_untrap:
-    // Disable floating-point traps.
-    mov reg_xt, CPTR_EL2_RES1
-    msr cptr_el2, reg_xt
-
-.Lfp_done:
-    // Disable virtual timer set by guest, and enable access to physical timer.
-    msr cntv_ctl_el0, xzr
-    mov reg_xt, CNTHCTL_EL2_EL1PCTEN | CNTHCTL_EL2_EL1PCEN
-    msr cnthctl_el2, reg_xt
-
-    // Don't trap debug register access to EL2.
-    msr mdcr_el2, xzr
-
-    // Disable guest traps, and ensure EL1 is arm64.
-    mov reg_xt, HCR_EL2_RW
-    msr hcr_el2, reg_xt
-    isb
-
-    switch_to_host
-
-    // Return to host.
-    ldr x0, [sp, 8]
-    pop_stack
-    eret
-
-FUNCTION_LABEL(el2_fp_resume)
-    // Save reg_xt so we have an extra register to swap floating-point state.
-    // We're returning to the guest so we don't need the return code in [sp, 8].
-    str reg_xt, [sp, 8]
-
-    // Disable floating-point traps and reset exception syndrome.
-    mov reg_xs, CPTR_EL2_RES1
-    msr cptr_el2, reg_xs
-    msr esr_el2, xzr
-    isb
-
-    // Load El2State from tpidr_el2.
-    mrs reg_xs, tpidr_el2
-
-    fp_state stp, HS_FP_STATE
-    fp_state ldp, GS_FP_STATE
-
-    // Return to guest.
-    ldp reg_xs, reg_xt, [sp], 16
-    eret
diff --git a/kernel/arch/arm64/hypervisor/el2_cpu_state.cpp b/kernel/arch/arm64/hypervisor/el2_cpu_state.cpp
deleted file mode 100644
index 45c3d67..0000000
--- a/kernel/arch/arm64/hypervisor/el2_cpu_state.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include "el2_cpu_state_priv.h"
-
-#include <arch/arm64/mmu.h>
-#include <arch/hypervisor.h>
-#include <dev/interrupt.h>
-#include <fbl/auto_lock.h>
-#include <fbl/mutex.h>
-#include <ktl/move.h>
-#include <hypervisor/cpu.h>
-#include <vm/physmap.h>
-#include <vm/pmm.h>
-
-static fbl::Mutex guest_mutex;
-static size_t num_guests TA_GUARDED(guest_mutex) = 0;
-static ktl::unique_ptr<El2CpuState> el2_cpu_state TA_GUARDED(guest_mutex);
-
-zx_status_t El2TranslationTable::Init() {
-    zx_status_t status = l0_page_.Alloc(0);
-    if (status != ZX_OK) {
-        return status;
-    }
-    status = l1_page_.Alloc(0);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // L0: Point to a single L1 translation table.
-    pte_t* l0_pte = l0_page_.VirtualAddress<pte_t>();
-    *l0_pte = l1_page_.PhysicalAddress() | MMU_PTE_L012_DESCRIPTOR_TABLE;
-
-    // L1: Identity map the first 512GB of physical memory at.
-    pte_t* l1_pte = l1_page_.VirtualAddress<pte_t>();
-    for (size_t i = 0; i < PAGE_SIZE / sizeof(pte_t); i++) {
-        l1_pte[i] = i * (1u << 30) | MMU_PTE_ATTR_AF | MMU_PTE_ATTR_SH_INNER_SHAREABLE |
-                    MMU_PTE_ATTR_AP_P_RW_U_RW | MMU_PTE_ATTR_NORMAL_MEMORY |
-                    MMU_PTE_L012_DESCRIPTOR_BLOCK;
-    }
-
-    __dmb(ARM_MB_SY);
-    return ZX_OK;
-}
-
-zx_paddr_t El2TranslationTable::Base() const {
-    return l0_page_.PhysicalAddress();
-}
-
-zx_status_t El2Stack::Alloc() {
-    return page_.Alloc(0);
-}
-
-zx_paddr_t El2Stack::Top() const {
-    return page_.PhysicalAddress() + PAGE_SIZE;
-}
-
-zx_status_t El2CpuState::OnTask(void* context, uint cpu_num) {
-    auto cpu_state = static_cast<El2CpuState*>(context);
-    El2TranslationTable& table = cpu_state->table_;
-    El2Stack& stack = cpu_state->stacks_[cpu_num];
-    zx_status_t status = arm64_el2_on(table.Base(), stack.Top());
-    if (status != ZX_OK) {
-        dprintf(CRITICAL, "Failed to turn EL2 on for CPU %u\n", cpu_num);
-        return status;
-    }
-    unmask_interrupt(kMaintenanceVector);
-    unmask_interrupt(kTimerVector);
-    return ZX_OK;
-}
-
-static void el2_off_task(void* arg) {
-    mask_interrupt(kTimerVector);
-    mask_interrupt(kMaintenanceVector);
-    zx_status_t status = arm64_el2_off();
-    if (status != ZX_OK) {
-        dprintf(CRITICAL, "Failed to turn EL2 off for CPU %u\n", arch_curr_cpu_num());
-    }
-}
-
-// static
-zx_status_t El2CpuState::Create(ktl::unique_ptr<El2CpuState>* out) {
-    fbl::AllocChecker ac;
-    ktl::unique_ptr<El2CpuState> cpu_state(new (&ac) El2CpuState);
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    zx_status_t status = cpu_state->Init();
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // Initialise the EL2 translation table.
-    status = cpu_state->table_.Init();
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // Allocate EL2 stack for each CPU.
-    size_t num_cpus = arch_max_num_cpus();
-    El2Stack* stacks = new (&ac) El2Stack[num_cpus];
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    fbl::Array<El2Stack> el2_stacks(stacks, num_cpus);
-    for (auto& stack : el2_stacks) {
-        zx_status_t status = stack.Alloc();
-        if (status != ZX_OK) {
-            return status;
-        }
-    }
-    cpu_state->stacks_ = ktl::move(el2_stacks);
-
-    // Setup EL2 for all online CPUs.
-    cpu_state->cpu_mask_ = percpu_exec(OnTask, cpu_state.get());
-    if (cpu_state->cpu_mask_ != mp_get_online_mask()) {
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-
-    *out = ktl::move(cpu_state);
-    return ZX_OK;
-}
-
-El2CpuState::~El2CpuState() {
-    mp_sync_exec(MP_IPI_TARGET_MASK, cpu_mask_, el2_off_task, nullptr);
-}
-
-zx_status_t alloc_vmid(uint8_t* vmid) {
-    fbl::AutoLock lock(&guest_mutex);
-    if (num_guests == 0) {
-        zx_status_t status = El2CpuState::Create(&el2_cpu_state);
-        if (status != ZX_OK) {
-            return status;
-        }
-    }
-    num_guests++;
-    return el2_cpu_state->AllocId(vmid);
-}
-
-zx_status_t free_vmid(uint8_t vmid) {
-    fbl::AutoLock lock(&guest_mutex);
-    zx_status_t status = el2_cpu_state->FreeId(vmid);
-    if (status != ZX_OK) {
-        return status;
-    }
-    num_guests--;
-    if (num_guests == 0) {
-        el2_cpu_state.reset();
-    }
-    return ZX_OK;
-}
diff --git a/kernel/arch/arm64/hypervisor/el2_cpu_state_priv.h b/kernel/arch/arm64/hypervisor/el2_cpu_state_priv.h
deleted file mode 100644
index 8a55438..0000000
--- a/kernel/arch/arm64/hypervisor/el2_cpu_state_priv.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <fbl/array.h>
-#include <ktl/unique_ptr.h>
-#include <hypervisor/id_allocator.h>
-#include <hypervisor/page.h>
-#include <kernel/mp.h>
-
-class El2TranslationTable {
-public:
-    zx_status_t Init();
-    zx_paddr_t Base() const;
-
-private:
-    hypervisor::Page l0_page_;
-    hypervisor::Page l1_page_;
-};
-
-// Represents a stack for use with EL2/
-class El2Stack {
-public:
-    zx_status_t Alloc();
-    zx_paddr_t Top() const;
-
-private:
-    hypervisor::Page page_;
-};
-
-// Maintains the EL2 state for each CPU.
-class El2CpuState : public hypervisor::IdAllocator<uint8_t, 64> {
-public:
-    static zx_status_t Create(ktl::unique_ptr<El2CpuState>* out);
-    ~El2CpuState();
-
-private:
-    cpu_mask_t cpu_mask_ = 0;
-    El2TranslationTable table_;
-    fbl::Array<El2Stack> stacks_;
-
-    El2CpuState() = default;
-
-    static zx_status_t OnTask(void* context, uint cpu_num);
-};
-
-// Allocate and free virtual machine IDs.
-zx_status_t alloc_vmid(uint8_t* vmid);
-zx_status_t free_vmid(uint8_t vmid);
-
-// Allocate and free virtual processor IDs.
-zx_status_t alloc_vpid(uint8_t* vpid);
-zx_status_t free_vpid(uint8_t vpid);
diff --git a/kernel/arch/arm64/hypervisor/gic/el2.S b/kernel/arch/arm64/hypervisor/gic/el2.S
deleted file mode 100644
index ea1235c..0000000
--- a/kernel/arch/arm64/hypervisor/gic/el2.S
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/hypervisor/el2_state.h>
-#include <arch/asm_macros.h>
-#include <asm.h>
-#include <zircon/errors.h>
-
-// For details please refer to ARM Generic Interrupt Controller Architecture
-// Specification, version 3.0 and version 4.0. Table 8-6 Mapping of MSR and MRS
-// to virtual interface control registers, AArch64 state and Table 8-8 Mapping
-// of MCR and MRC to virtual interface control registers, AArch32 state.
-
-#define ICH_AP0R(x)         S3_4_C12_C8_ ## x
-#define ICH_AP1R(x)         S3_4_C12_C9_ ## x
-#define ICH_HCR_EL2         S3_4_C12_C11_0
-#define ICH_VTR_EL2         S3_4_C12_C11_1
-#define ICH_MISR_EL2        S3_4_C12_C11_2
-#define ICH_ELRSR_EL2       S3_4_C12_C11_5
-#define ICH_VMCR_EL2        S3_4_C12_C11_7
-#define ICH_LR0(x)          S3_4_C12_C12_ ## x
-#define ICH_LR8(x)          S3_4_C12_C13_ ## x
-
-#define ICH_LR0_EL2         ICH_LR0(0)
-#define ICH_LR1_EL2         ICH_LR0(1)
-#define ICH_LR2_EL2         ICH_LR0(2)
-#define ICH_LR3_EL2         ICH_LR0(3)
-#define ICH_LR4_EL2         ICH_LR0(4)
-#define ICH_LR5_EL2         ICH_LR0(5)
-#define ICH_LR6_EL2         ICH_LR0(6)
-#define ICH_LR7_EL2         ICH_LR0(7)
-#define ICH_LR8_EL2         ICH_LR8(0)
-#define ICH_LR9_EL2         ICH_LR8(1)
-#define ICH_LR10_EL2        ICH_LR8(2)
-#define ICH_LR11_EL2        ICH_LR8(3)
-#define ICH_LR12_EL2        ICH_LR8(4)
-#define ICH_LR13_EL2        ICH_LR8(5)
-#define ICH_LR14_EL2        ICH_LR8(6)
-#define ICH_LR15_EL2        ICH_LR8(7)
-
-#define ICH_LR(x)           ICH_LR ## x ## _EL2
-
-#define READ_SYSREG         0
-#define WRITE_SYSREG        1
-
-.section .text.el2,"ax",@progbits
-.align 12
-
-// Temporary registers to use.
-reg_xa  .req x11
-reg_xb  .req x12
-reg_wb  .req w12
-reg_xc  .req x13
-
-.macro read_sysreg sysreg, off
-    mrs reg_xa, \sysreg
-    str reg_xa, [x0, \off]
-.endm
-
-.macro write_sysreg sysreg, off
-    ldr reg_xa, [x0, \off]
-    msr \sysreg, reg_xa
-.endm
-
-// Calculate the jump table index from a value in memory:
-//   reg_xb = max - x0[off]
-.macro gic_index max, off
-    ldurb reg_wb, [x0, \off]
-    mov reg_xc, \max
-    sub reg_xb, reg_xc, reg_xb
-.endm
-
-// Branch to an address within a jump table, calculated as follows:
-//   address = table + (reg_xb << 3)
-.macro gic_jump table
-    adr reg_xc, \table
-    add reg_xc, reg_xc, reg_xb, lsl 3
-    br reg_xc
-.endm
-
-// void arm64_el2_gicv3_read_gich_state(zx_paddr_t state)
-FUNCTION(arm64_el2_gicv3_read_gich_state)
-    mov reg_xa, READ_SYSREG
-    hvc 5
-    ret
-END_FUNCTION(arm64_el2_gicv3_read_gich_state)
-
-// void arm64_el2_gicv3_write_gich_state(zx_paddr_t state, uint32_t hcr)
-FUNCTION(arm64_el2_gicv3_write_gich_state)
-    mov reg_xa, WRITE_SYSREG
-    hvc 5
-    ret
-END_FUNCTION(arm64_el2_gicv3_write_gich_state)
-
-FUNCTION_LABEL(el2_hvc_gich_state)
-    cbnz reg_xa, el2_hvc_write_gich_state
-
-FUNCTION_LABEL(el2_hvc_read_gich_state)
-    msr ICH_HCR_EL2, xzr
-    read_sysreg ICH_VMCR_EL2, IS_VMCR
-    read_sysreg ICH_MISR_EL2, IS_MISR
-    read_sysreg ICH_ELRSR_EL2, IS_ELRSR
-
-    gic_index 4, IS_NUM_APRS
-    gic_jump .Lread_ap0r
-.Lread_ap0r:
-    read_sysreg ICH_AP0R(3), IS_APR(0, 3)
-    read_sysreg ICH_AP0R(2), IS_APR(0, 2)
-    read_sysreg ICH_AP0R(1), IS_APR(0, 1)
-    read_sysreg ICH_AP0R(0), IS_APR(0, 0)
-
-    gic_jump .Lread_ap1r
-.Lread_ap1r:
-    read_sysreg ICH_AP1R(3), IS_APR(1, 3)
-    read_sysreg ICH_AP1R(2), IS_APR(1, 2)
-    read_sysreg ICH_AP1R(1), IS_APR(1, 1)
-    read_sysreg ICH_AP1R(0), IS_APR(1, 0)
-
-    gic_index 16, IS_NUM_LRS
-    gic_jump .Llr_read_lr
-.Llr_read_lr:
-    read_sysreg ICH_LR(15), IS_LR(15)
-    read_sysreg ICH_LR(14), IS_LR(14)
-    read_sysreg ICH_LR(13), IS_LR(13)
-    read_sysreg ICH_LR(12), IS_LR(12)
-    read_sysreg ICH_LR(11), IS_LR(11)
-    read_sysreg ICH_LR(10), IS_LR(10)
-    read_sysreg ICH_LR(9), IS_LR(9)
-    read_sysreg ICH_LR(8), IS_LR(8)
-    read_sysreg ICH_LR(7), IS_LR(7)
-    read_sysreg ICH_LR(6), IS_LR(6)
-    read_sysreg ICH_LR(5), IS_LR(5)
-    read_sysreg ICH_LR(4), IS_LR(4)
-    read_sysreg ICH_LR(3), IS_LR(3)
-    read_sysreg ICH_LR(2), IS_LR(2)
-    read_sysreg ICH_LR(1), IS_LR(1)
-    read_sysreg ICH_LR(0), IS_LR(0)
-
-    b el2_gicv3_done
-
-FUNCTION_LABEL(el2_hvc_write_gich_state)
-    msr ICH_HCR_EL2, x1
-    write_sysreg ICH_VMCR_EL2, IS_VMCR
-
-    gic_index 4, IS_NUM_APRS
-    gic_jump .Lwrite_ap0r
-.Lwrite_ap0r:
-    write_sysreg ICH_AP0R(3), IS_APR(0, 3)
-    write_sysreg ICH_AP0R(2), IS_APR(0, 2)
-    write_sysreg ICH_AP0R(1), IS_APR(0, 1)
-    write_sysreg ICH_AP0R(0), IS_APR(0, 0)
-
-    gic_jump .Lwrite_ap1r
-.Lwrite_ap1r:
-    write_sysreg ICH_AP1R(3), IS_APR(1, 3)
-    write_sysreg ICH_AP1R(2), IS_APR(1, 2)
-    write_sysreg ICH_AP1R(1), IS_APR(1, 1)
-    write_sysreg ICH_AP1R(0), IS_APR(1, 0)
-
-    gic_index 16, IS_NUM_LRS
-    gic_jump .Llr_write_lr
-.Llr_write_lr:
-    write_sysreg ICH_LR(15), IS_LR(15)
-    write_sysreg ICH_LR(14), IS_LR(14)
-    write_sysreg ICH_LR(13), IS_LR(13)
-    write_sysreg ICH_LR(12), IS_LR(12)
-    write_sysreg ICH_LR(11), IS_LR(11)
-    write_sysreg ICH_LR(10), IS_LR(10)
-    write_sysreg ICH_LR(9), IS_LR(9)
-    write_sysreg ICH_LR(8), IS_LR(8)
-    write_sysreg ICH_LR(7), IS_LR(7)
-    write_sysreg ICH_LR(6), IS_LR(6)
-    write_sysreg ICH_LR(5), IS_LR(5)
-    write_sysreg ICH_LR(4), IS_LR(4)
-    write_sysreg ICH_LR(3), IS_LR(3)
-    write_sysreg ICH_LR(2), IS_LR(2)
-    write_sysreg ICH_LR(1), IS_LR(1)
-    write_sysreg ICH_LR(0), IS_LR(0)
-
-    b el2_gicv3_done
-
-// uint32_t arm64_el2_gicv3_read_gich_vtr()
-FUNCTION(arm64_el2_gicv3_read_gich_vtr)
-    hvc 6
-    ret
-END_FUNCTION(arm64_el2_gicv3_read_gich_vtr)
-
-FUNCTION_LABEL(el2_hvc_gich_vtr)
-    mrs x0, ICH_VTR_EL2
-    b el2_gicv3_done
-
-FUNCTION_LABEL(el2_gicv3_done)
-    msr vttbr_el2, xzr
-    isb
-    eret
diff --git a/kernel/arch/arm64/hypervisor/gic/gicv2.cpp b/kernel/arch/arm64/hypervisor/gic/gicv2.cpp
deleted file mode 100644
index cc66c32..0000000
--- a/kernel/arch/arm64/hypervisor/gic/gicv2.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-#include <arch/arm64/hypervisor/el2_state.h>
-#include <arch/arm64/hypervisor/gic/gicv2.h>
-#include <dev/interrupt/arm_gic_hw_interface.h>
-#include <dev/interrupt/arm_gicv2_regs.h>
-#include <vm/pmm.h>
-
-static constexpr uint32_t kNumLrs = 64;
-
-// Representation of GICH registers. For details please refer to ARM Generic Interrupt
-// Controller Architecture Specification Version 2, 5.3 GIC virtual interface control
-// registers.
-typedef struct Gich {
-    uint32_t hcr;
-    uint32_t vtr;
-    uint32_t vmcr;
-    uint32_t reserved0;
-    uint32_t misr;
-    uint32_t reserved1[3];
-    uint32_t eisr0;
-    uint32_t eisr1;
-    uint32_t reserved2[2];
-    uint32_t elrsr0;
-    uint32_t elrsr1;
-    uint32_t reserved3[46];
-    uint32_t apr;
-    uint32_t reserved4[3];
-    uint32_t lr[kNumLrs];
-} __attribute__((__packed__)) Gich;
-
-static_assert(__offsetof(Gich, hcr) == 0x00, "");
-static_assert(__offsetof(Gich, vtr) == 0x04, "");
-static_assert(__offsetof(Gich, vmcr) == 0x08, "");
-static_assert(__offsetof(Gich, misr) == 0x10, "");
-static_assert(__offsetof(Gich, eisr0) == 0x20, "");
-static_assert(__offsetof(Gich, eisr1) == 0x24, "");
-static_assert(__offsetof(Gich, elrsr0) == 0x30, "");
-static_assert(__offsetof(Gich, elrsr1) == 0x34, "");
-static_assert(__offsetof(Gich, apr) == 0xf0, "");
-static_assert(__offsetof(Gich, lr) == 0x100, "");
-
-static volatile Gich* gich = NULL;
-
-static zx_status_t gicv2_get_gicv(paddr_t* gicv_paddr) {
-    // Check for presence of GICv2 virtualisation extensions.
-    if (GICV_OFFSET == 0) {
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-    *gicv_paddr = vaddr_to_paddr(reinterpret_cast<void*>(GICV_ADDRESS));
-    return ZX_OK;
-}
-
-static void giv2_read_gich_state(IchState* state) {
-    DEBUG_ASSERT(state->num_aprs == 1);
-    DEBUG_ASSERT(state->num_lrs <= kNumLrs);
-    gich->hcr = 0;
-    state->vmcr = gich->vmcr;
-    state->misr = gich->misr;
-    state->elrsr = gich->elrsr0 | (static_cast<uint64_t>(gich->elrsr1) << 32);
-    state->apr[0][0] = gich->apr;
-    for (uint8_t i = 0; i < state->num_lrs; i++) {
-        state->lr[i] = gich->lr[i];
-    }
-}
-
-static void giv2_write_gich_state(IchState* state, uint32_t hcr) {
-    DEBUG_ASSERT(state->num_aprs == 1);
-    DEBUG_ASSERT(state->num_lrs <= kNumLrs);
-    gich->hcr = hcr;
-    gich->vmcr = state->vmcr;
-    gich->apr = static_cast<uint32_t>(state->apr[0][0]);
-    for (uint8_t i = 0; i < state->num_lrs; i++) {
-        uint32_t lr = static_cast<uint32_t>(state->lr[i]);
-        if (lr & GICH_LR_HARDWARE) {
-            // We are adding a physical interrupt to a list register, therefore
-            // we mark the physical interrupt as active on the physical
-            // distributor so that the guest can deactivate it directly.
-            uint32_t vector = GICH_LR_VIRTUAL_ID(lr);
-            uint32_t reg = vector / 32;
-            uint32_t mask = 1u << (vector % 32);
-            GICREG(0, GICD_ISACTIVER(reg)) = mask;
-        }
-        gich->lr[i] = lr;
-    }
-}
-
-static uint32_t gicv2_default_gich_vmcr() {
-    return GICH_VMCR_VPMR | GICH_VMCR_VENG0;
-}
-
-static uint64_t gicv2_get_lr_from_vector(bool hw, uint8_t prio, uint32_t vector) {
-    uint64_t lr = GICH_LR_PENDING | GICH_LR_PRIORITY(prio) | GICH_LR_VIRTUAL_ID(vector);
-    if (hw) {
-        lr |= GICH_LR_HARDWARE | GICH_LR_PHYSICAL_ID(vector);
-    }
-    return lr;
-}
-
-static uint32_t gicv2_get_vector_from_lr(uint64_t lr) {
-    return lr & GICH_LR_VIRTUAL_ID(UINT64_MAX);
-}
-
-static uint8_t gicv2_get_num_pres() {
-    return static_cast<uint8_t>(GICH_VTR_PRES(gich->vtr));
-}
-
-static uint8_t gicv2_get_num_lrs() {
-    return static_cast<uint8_t>(GICH_VTR_LRS(gich->vtr));
-}
-
-static const struct arm_gic_hw_interface_ops gic_hw_register_ops = {
-    .get_gicv = gicv2_get_gicv,
-    .read_gich_state = giv2_read_gich_state,
-    .write_gich_state = giv2_write_gich_state,
-    .default_gich_vmcr = gicv2_default_gich_vmcr,
-    .get_lr_from_vector = gicv2_get_lr_from_vector,
-    .get_vector_from_lr = gicv2_get_vector_from_lr,
-    .get_num_pres = gicv2_get_num_pres,
-    .get_num_lrs = gicv2_get_num_lrs,
-};
-
-void gicv2_hw_interface_register() {
-    // Populate GICH
-    gich = reinterpret_cast<volatile Gich*>(GICH_ADDRESS);
-    arm_gic_hw_interface_register(&gic_hw_register_ops);
-}
diff --git a/kernel/arch/arm64/hypervisor/gic/gicv3.cpp b/kernel/arch/arm64/hypervisor/gic/gicv3.cpp
deleted file mode 100644
index da99cce..0000000
--- a/kernel/arch/arm64/hypervisor/gic/gicv3.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/hypervisor/el2_state.h>
-#include <arch/arm64/hypervisor/gic/el2.h>
-#include <arch/arm64/hypervisor/gic/gicv3.h>
-#include <arch/ops.h>
-#include <dev/interrupt/arm_gic_hw_interface.h>
-#include <dev/interrupt/arm_gicv3_regs.h>
-#include <vm/physmap.h>
-
-static constexpr uint32_t kNumAprs = 4;
-static constexpr uint32_t kNumLrs = 16;
-
-static zx_status_t gicv3_get_gicv(paddr_t* gicv_paddr) {
-    // Check for presence of GICv3 virtualisation extensions.
-    // We return ZX_ERR_NOT_FOUND since this API is used to get
-    // address of GICV base to map it to guest
-    // On GICv3 we do not need to map this region, since we use system registers
-    return ZX_ERR_NOT_FOUND;
-}
-
-static uint32_t gicv3_default_gich_vmcr() {
-    // From ARM GIC v3/v4, Section 8.4.8: VFIQEn - In implementations where the
-    // Non-secure copy of ICC_SRE_EL1.SRE is always 1, this bit is RES 1.
-    return ICH_VMCR_VPMR | ICH_VMCR_VFIQEN | ICH_VMCR_VENG1;
-}
-
-static void giv3_read_gich_state(IchState* state) {
-    DEBUG_ASSERT(state->num_aprs <= kNumAprs);
-    DEBUG_ASSERT(state->num_lrs <= kNumLrs);
-    arm64_el2_gicv3_read_gich_state(physmap_to_paddr(state));
-}
-
-static void giv3_write_gich_state(IchState* state, uint32_t hcr) {
-    DEBUG_ASSERT(state->num_aprs <= kNumAprs);
-    DEBUG_ASSERT(state->num_lrs <= kNumLrs);
-    cpu_num_t cpu_num = arch_curr_cpu_num();
-    for (uint8_t i = 0; i < state->num_lrs; i++) {
-        uint64_t lr = state->lr[i];
-        if (lr & ICH_LR_HARDWARE) {
-            // We are adding a physical interrupt to a list register, therefore we
-            // mark the physical interrupt as active on the physical distributor so
-            // that the guest can deactivate it directly.
-            uint32_t vector = ICH_LR_VIRTUAL_ID(lr);
-            uint32_t reg = vector / 32;
-            uint32_t mask = 1u << (vector % 32);
-            // Since we use affinity routing, if this vector is associated with an
-            // SGI or PPI, we should talk to the redistributor for the current CPU.
-            if (vector < 32) {
-                GICREG(0, GICR_ISACTIVER0(cpu_num)) = mask;
-            } else {
-                GICREG(0, GICD_ISACTIVER(reg)) = mask;
-            }
-        }
-    }
-    arm64_el2_gicv3_write_gich_state(physmap_to_paddr(state), hcr);
-}
-
-static uint64_t gicv3_get_lr_from_vector(bool hw, uint8_t prio, uint32_t vector) {
-    uint64_t lr = ICH_LR_PENDING | ICH_LR_GROUP1 | ICH_LR_PRIORITY(prio) |
-        ICH_LR_VIRTUAL_ID(vector);
-    if (hw) {
-        lr |= ICH_LR_HARDWARE | ICH_LR_PHYSICAL_ID(vector);
-    }
-    return lr;
-}
-
-static uint32_t gicv3_get_vector_from_lr(uint64_t lr) {
-    return lr & ICH_LR_VIRTUAL_ID(UINT64_MAX);
-}
-
-static uint8_t gicv3_get_num_pres() {
-    return static_cast<uint8_t>(ICH_VTR_PRES(arm64_el2_gicv3_read_gich_vtr()));
-}
-
-static uint8_t gicv3_get_num_lrs() {
-    return static_cast<uint8_t>(ICH_VTR_LRS(arm64_el2_gicv3_read_gich_vtr()));
-}
-
-static const struct arm_gic_hw_interface_ops gic_hw_register_ops = {
-    .get_gicv = gicv3_get_gicv,
-    .read_gich_state = giv3_read_gich_state,
-    .write_gich_state = giv3_write_gich_state,
-    .default_gich_vmcr = gicv3_default_gich_vmcr,
-    .get_lr_from_vector = gicv3_get_lr_from_vector,
-    .get_vector_from_lr = gicv3_get_vector_from_lr,
-    .get_num_pres = gicv3_get_num_pres,
-    .get_num_lrs = gicv3_get_num_lrs,
-};
-
-void gicv3_hw_interface_register() {
-    arm_gic_hw_interface_register(&gic_hw_register_ops);
-}
diff --git a/kernel/arch/arm64/hypervisor/guest.cpp b/kernel/arch/arm64/hypervisor/guest.cpp
deleted file mode 100644
index caea2b8..0000000
--- a/kernel/arch/arm64/hypervisor/guest.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/hypervisor.h>
-#include <dev/interrupt/arm_gic_hw_interface.h>
-#include <hypervisor/guest_physical_address_space.h>
-#include <vm/pmm.h>
-#include <zircon/syscalls/hypervisor.h>
-
-#include "el2_cpu_state_priv.h"
-
-static constexpr zx_gpaddr_t kGicvAddress = 0x800001000;
-static constexpr size_t kGicvSize = 0x2000;
-
-// static
-zx_status_t Guest::Create(ktl::unique_ptr<Guest>* out) {
-    if (arm64_get_boot_el() < 2) {
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-
-    uint8_t vmid;
-    zx_status_t status = alloc_vmid(&vmid);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    fbl::AllocChecker ac;
-    ktl::unique_ptr<Guest> guest(new (&ac) Guest(vmid));
-    if (!ac.check()) {
-        free_vmid(vmid);
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    fbl::AutoLock lock(&guest->vcpu_mutex_);
-    status = guest->vpid_allocator_.Init();
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    status = hypervisor::GuestPhysicalAddressSpace::Create(vmid, &guest->gpas_);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    zx_paddr_t gicv_paddr;
-    status = gic_get_gicv(&gicv_paddr);
-
-    // If status == ZX_ERR_NOT_FOUND, we are running GICv3
-    // There is no need to map GICV to the guest
-    // Handle other cases below
-    if (status == ZX_OK) {
-        status = guest->gpas_->MapInterruptController(kGicvAddress, gicv_paddr, kGicvSize);
-        if (status != ZX_OK) {
-            return status;
-        }
-    } else if (status == ZX_ERR_NOT_SUPPORTED) {
-        return status;
-    }
-
-    *out = ktl::move(guest);
-    return ZX_OK;
-}
-
-Guest::Guest(uint8_t vmid)
-    : vmid_(vmid) {}
-
-Guest::~Guest() {
-    free_vmid(vmid_);
-}
-
-zx_status_t Guest::SetTrap(uint32_t kind, zx_gpaddr_t addr, size_t len,
-                           fbl::RefPtr<PortDispatcher> port, uint64_t key) {
-    switch (kind) {
-    case ZX_GUEST_TRAP_MEM:
-        if (port) {
-            return ZX_ERR_INVALID_ARGS;
-        }
-        break;
-    case ZX_GUEST_TRAP_BELL:
-        if (!port) {
-            return ZX_ERR_INVALID_ARGS;
-        }
-        break;
-    case ZX_GUEST_TRAP_IO:
-        return ZX_ERR_NOT_SUPPORTED;
-    default:
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (SIZE_MAX - len < addr) {
-        return ZX_ERR_OUT_OF_RANGE;
-    } else if (!IS_PAGE_ALIGNED(addr) || !IS_PAGE_ALIGNED(len) || len == 0) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    zx_status_t status = gpas_->UnmapRange(addr, len);
-    if (status != ZX_OK) {
-        return status;
-    }
-    return traps_.InsertTrap(kind, addr, len, ktl::move(port), key);
-}
-
-zx_status_t Guest::AllocVpid(uint8_t* vpid) {
-    fbl::AutoLock lock(&vcpu_mutex_);
-    return vpid_allocator_.AllocId(vpid);
-}
-
-zx_status_t Guest::FreeVpid(uint8_t vpid) {
-    fbl::AutoLock lock(&vcpu_mutex_);
-    return vpid_allocator_.FreeId(vpid);
-}
diff --git a/kernel/arch/arm64/hypervisor/rules.mk b/kernel/arch/arm64/hypervisor/rules.mk
deleted file mode 100644
index 3700a02..0000000
--- a/kernel/arch/arm64/hypervisor/rules.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2017 The Fuchsia Authors
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS := \
-	$(LOCAL_DIR)/el2.S \
-	$(LOCAL_DIR)/el2_cpu_state.cpp \
-	$(LOCAL_DIR)/guest.cpp \
-	$(LOCAL_DIR)/vcpu.cpp \
-	$(LOCAL_DIR)/vmexit.cpp \
-	$(LOCAL_DIR)/gic/gicv2.cpp \
-	$(LOCAL_DIR)/gic/gicv3.cpp \
-	$(LOCAL_DIR)/gic/el2.S \
-
-include make/module.mk
diff --git a/kernel/arch/arm64/hypervisor/vcpu.cpp b/kernel/arch/arm64/hypervisor/vcpu.cpp
deleted file mode 100644
index f93bb4d..0000000
--- a/kernel/arch/arm64/hypervisor/vcpu.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/hypervisor.h>
-#include <arch/ops.h>
-#include <bits.h>
-#include <dev/interrupt/arm_gic_common.h>
-#include <dev/interrupt/arm_gic_hw_interface.h>
-#include <fbl/auto_call.h>
-#include <hypervisor/cpu.h>
-#include <hypervisor/guest_physical_address_space.h>
-#include <hypervisor/ktrace.h>
-#include <kernel/event.h>
-#include <kernel/mp.h>
-#include <lib/ktrace.h>
-#include <platform/timer.h>
-#include <vm/physmap.h>
-#include <vm/pmm.h>
-#include <zircon/errors.h>
-#include <zircon/syscalls/hypervisor.h>
-
-#include "el2_cpu_state_priv.h"
-#include "vmexit_priv.h"
-
-static constexpr uint32_t kGichHcrEn = 1u << 0;
-static constexpr uint32_t kGichHcrUie = 1u << 1;
-static constexpr uint32_t kGichMisrU = 1u << 1;
-static constexpr uint32_t kSpsrDaif = 0b1111 << 6;
-static constexpr uint32_t kSpsrEl1h = 0b0101;
-static constexpr uint32_t kSpsrNzcv = 0b1111 << 28;
-
-static uint64_t vmpidr_of(uint8_t vpid, uint64_t mpidr) {
-    return (vpid - 1) | (mpidr & 0xffffff00fe000000);
-}
-
-static void gich_maybe_interrupt(GichState* gich_state, IchState* ich_state) {
-    // From ARM GIC v3/v4, Section 4.8: If, on a particular CPU interface,
-    // multiple pending interrupts have the same priority, and have sufficient
-    // priority for the interface to signal them to the PE, it is IMPLEMENTATION
-    // DEFINED how the interface selects which interrupt to signal.
-    //
-    // If interrupts are of the same priority, we can choose whatever ordering
-    // we prefer when populating the LRs.
-    for (uint64_t elrsr = ich_state->elrsr; elrsr != 0;) {
-        uint32_t vector;
-        hypervisor::InterruptType type = gich_state->interrupt_tracker.Pop(&vector);
-        if (type == hypervisor::InterruptType::INACTIVE) {
-            // There are no more pending interrupts.
-            break;
-        } else if (gich_state->active_interrupts.GetOne(vector)) {
-            // Skip an interrupt if it was already active.
-            continue;
-        }
-        uint32_t lr_index = __builtin_ctzl(elrsr);
-        bool hw = type == hypervisor::InterruptType::PHYSICAL;
-        // From ARM GIC v3/v4, Section 4.8: If the GIC implements fewer than 256
-        // priority levels, the low-order bits of the priority fields are
-        // RAZ/WI.
-        // ...
-        // In the GIC prioritization scheme, lower numbers have higher priority.
-        //
-        // We may have as few as 16 priority levels, so step by 16 to the next
-        // lowest priority in order to prioritise SGIs and PPIs over SPIs.
-        uint8_t prio = vector < GIC_BASE_SPI ? 0 : 0x10;
-        uint64_t lr = gic_get_lr_from_vector(hw, prio, vector);
-        ich_state->lr[lr_index] = lr;
-        elrsr &= ~(1u << lr_index);
-    }
-}
-
-static void gich_active_interrupts(GichState* gich_state, IchState* ich_state) {
-    gich_state->active_interrupts.ClearAll();
-    for (uint32_t i = 0; i < ich_state->num_lrs; i++) {
-        if (BIT(ich_state->elrsr, i)) {
-            continue;
-        }
-        uint32_t vector = gic_get_vector_from_lr(ich_state->lr[i]);
-        gich_state->active_interrupts.SetOne(vector);
-    }
-}
-
-static VcpuExit vmexit_interrupt_ktrace_meta(uint32_t misr) {
-    if (misr & kGichMisrU) {
-        return VCPU_UNDERFLOW_MAINTENANCE_INTERRUPT;
-    }
-    return VCPU_PHYSICAL_INTERRUPT;
-}
-
-AutoGich::AutoGich(IchState* ich_state, bool pending)
-    : ich_state_(ich_state) {
-    // From ARM GIC v3/v4, Section 8.4.5: Underflow Interrupt Enable. Enables
-    // the signaling of a maintenance interrupt when the List registers are
-    // empty, or hold only one valid entry.
-    //
-    // We use it when there are not enough free LRs to inject all pending
-    // interrupts, so when guest finishes processing most of them, a maintenance
-    // interrupt will cause VM exit and will give us a chance to inject the
-    // remaining interrupts. The point of this is to reduce latency when
-    // processing interrupts.
-    uint32_t gich_hcr = kGichHcrEn;
-    if (pending && ich_state_->num_lrs > 1) {
-        gich_hcr |= kGichHcrUie;
-    }
-
-    DEBUG_ASSERT(!arch_ints_disabled());
-    arch_disable_ints();
-    arch_set_blocking_disallowed(true);
-    gic_write_gich_state(ich_state_, gich_hcr);
-}
-
-AutoGich::~AutoGich() {
-    DEBUG_ASSERT(arch_ints_disabled());
-    gic_read_gich_state(ich_state_);
-    arch_set_blocking_disallowed(false);
-    arch_enable_ints();
-}
-
-// Returns the number of active priorities registers, based on the number of
-// preemption bits.
-//
-// From ARM GIC v2, Section 5.3.2: In GICv2, the only valid value is 5 bits.
-//
-// From ARM GIC v3/v4, Section 8.4.2: If 5 bits of preemption are implemented
-// (bits [7:3] of priority), then there are 32 preemption levels... If 6 bits of
-// preemption are implemented (bits [7:2] of priority), then there are 64
-// preemption levels... If 7 bits of preemption are implemented (bits [7:1] of
-// priority), then there are 128 preemption levels...
-static uint8_t num_aprs(uint8_t num_pres) {
-    return static_cast<uint8_t>(1u << (num_pres - 5u));
-}
-
-// static
-zx_status_t Vcpu::Create(Guest* guest, zx_vaddr_t entry, ktl::unique_ptr<Vcpu>* out) {
-    hypervisor::GuestPhysicalAddressSpace* gpas = guest->AddressSpace();
-    if (entry >= gpas->size()) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    uint8_t vpid;
-    zx_status_t status = guest->AllocVpid(&vpid);
-    if (status != ZX_OK) {
-        return status;
-    }
-    auto auto_call = fbl::MakeAutoCall([guest, vpid]() { guest->FreeVpid(vpid); });
-
-    // For efficiency, we pin the thread to the CPU.
-    thread_t* thread = hypervisor::pin_thread(vpid);
-
-    fbl::AllocChecker ac;
-    ktl::unique_ptr<Vcpu> vcpu(new (&ac) Vcpu(guest, vpid, thread));
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    auto_call.cancel();
-
-    status = vcpu->el2_state_.Alloc();
-    if (status != ZX_OK) {
-        return status;
-    }
-    status = vcpu->gich_state_.interrupt_tracker.Init();
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    vcpu->el2_state_->guest_state.system_state.elr_el2 = entry;
-    vcpu->el2_state_->guest_state.system_state.spsr_el2 = kSpsrDaif | kSpsrEl1h;
-    const uint64_t mpidr = __arm_rsr64("mpidr_el1");
-    vcpu->el2_state_->guest_state.system_state.vmpidr_el2 = vmpidr_of(vpid, mpidr);
-    vcpu->el2_state_->host_state.system_state.vmpidr_el2 = mpidr;
-    const uint8_t num_lrs = gic_get_num_lrs();
-    vcpu->el2_state_->ich_state.num_aprs = num_aprs(gic_get_num_pres());
-    vcpu->el2_state_->ich_state.num_lrs = num_lrs;
-    vcpu->el2_state_->ich_state.vmcr = gic_default_gich_vmcr();
-    vcpu->el2_state_->ich_state.elrsr = (1ul << num_lrs) - 1;
-    vcpu->gich_state_.active_interrupts.Reset(kNumInterrupts);
-    vcpu->hcr_ = HCR_EL2_VM | HCR_EL2_PTW | HCR_EL2_FMO | HCR_EL2_IMO | HCR_EL2_DC | HCR_EL2_TWI |
-                 HCR_EL2_TWE | HCR_EL2_TSC | HCR_EL2_TVM | HCR_EL2_RW;
-
-    *out = ktl::move(vcpu);
-    return ZX_OK;
-}
-
-Vcpu::Vcpu(Guest* guest, uint8_t vpid, const thread_t* thread)
-    : guest_(guest), vpid_(vpid), thread_(thread), running_(false) {}
-
-Vcpu::~Vcpu() {
-    __UNUSED zx_status_t status = guest_->FreeVpid(vpid_);
-    DEBUG_ASSERT(status == ZX_OK);
-}
-
-zx_status_t Vcpu::Resume(zx_port_packet_t* packet) {
-    if (!hypervisor::check_pinned_cpu_invariant(vpid_, thread_))
-        return ZX_ERR_BAD_STATE;
-    const ArchVmAspace& aspace = *guest_->AddressSpace()->arch_aspace();
-    zx_paddr_t vttbr = arm64_vttbr(aspace.arch_asid(), aspace.arch_table_phys());
-    GuestState* guest_state = &el2_state_->guest_state;
-    IchState* ich_state = &el2_state_->ich_state;
-    zx_status_t status;
-    do {
-        timer_maybe_interrupt(guest_state, &gich_state_);
-        gich_maybe_interrupt(&gich_state_, ich_state);
-        {
-            AutoGich auto_gich(ich_state, gich_state_.interrupt_tracker.Pending());
-
-            ktrace(TAG_VCPU_ENTER, 0, 0, 0, 0);
-            running_.store(true);
-            status = arm64_el2_resume(vttbr, el2_state_.PhysicalAddress(), hcr_);
-            running_.store(false);
-        }
-        gich_active_interrupts(&gich_state_, ich_state);
-        if (status == ZX_ERR_NEXT) {
-            // We received a physical interrupt. If it was due to the thread
-            // being killed, then we should exit with an error, otherwise return
-            // to the guest.
-            ktrace_vcpu_exit(vmexit_interrupt_ktrace_meta(ich_state->misr),
-                             guest_state->system_state.elr_el2);
-            status = thread_->signals & THREAD_SIGNAL_KILL ? ZX_ERR_CANCELED : ZX_OK;
-        } else if (status == ZX_OK) {
-            status = vmexit_handler(&hcr_, guest_state, &gich_state_, guest_->AddressSpace(),
-                                    guest_->Traps(), packet);
-        } else {
-            ktrace_vcpu_exit(VCPU_FAILURE, guest_state->system_state.elr_el2);
-            dprintf(INFO, "VCPU resume failed: %d\n", status);
-        }
-    } while (status == ZX_OK);
-    return status == ZX_ERR_NEXT ? ZX_OK : status;
-}
-
-cpu_mask_t Vcpu::Interrupt(uint32_t vector, hypervisor::InterruptType type) {
-    bool signaled = false;
-    gich_state_.interrupt_tracker.Interrupt(vector, type, &signaled);
-    if (signaled || !running_.load()) {
-        return 0;
-    }
-    return cpu_num_to_mask(hypervisor::cpu_of(vpid_));
-}
-
-void Vcpu::VirtualInterrupt(uint32_t vector) {
-    cpu_mask_t mask = Interrupt(vector, hypervisor::InterruptType::VIRTUAL);
-    if (mask != 0) {
-        mp_interrupt(MP_IPI_TARGET_MASK, mask);
-    }
-}
-
-zx_status_t Vcpu::ReadState(uint32_t kind, void* buf, size_t len) const {
-    if (!hypervisor::check_pinned_cpu_invariant(vpid_, thread_)) {
-        return ZX_ERR_BAD_STATE;
-    } else if (kind != ZX_VCPU_STATE || len != sizeof(zx_vcpu_state_t)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    auto state = static_cast<zx_vcpu_state_t*>(buf);
-    memcpy(state->x, el2_state_->guest_state.x, sizeof(uint64_t) * GS_NUM_REGS);
-    state->sp = el2_state_->guest_state.system_state.sp_el1;
-    state->cpsr = el2_state_->guest_state.system_state.spsr_el2 & kSpsrNzcv;
-    return ZX_OK;
-}
-
-zx_status_t Vcpu::WriteState(uint32_t kind, const void* buf, size_t len) {
-    if (!hypervisor::check_pinned_cpu_invariant(vpid_, thread_)) {
-        return ZX_ERR_BAD_STATE;
-    } else if (kind != ZX_VCPU_STATE || len != sizeof(zx_vcpu_state_t)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    auto state = static_cast<const zx_vcpu_state_t*>(buf);
-    memcpy(el2_state_->guest_state.x, state->x, sizeof(uint64_t) * GS_NUM_REGS);
-    el2_state_->guest_state.system_state.sp_el1 = state->sp;
-    el2_state_->guest_state.system_state.spsr_el2 |= state->cpsr & kSpsrNzcv;
-    return ZX_OK;
-}
diff --git a/kernel/arch/arm64/hypervisor/vmexit.cpp b/kernel/arch/arm64/hypervisor/vmexit.cpp
deleted file mode 100644
index aea5224..0000000
--- a/kernel/arch/arm64/hypervisor/vmexit.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include "vmexit_priv.h"
-
-#include <bits.h>
-#include <platform.h>
-#include <trace.h>
-
-#include <arch/arm64/hypervisor/el2_state.h>
-#include <arch/hypervisor.h>
-#include <dev/psci.h>
-#include <dev/timer/arm_generic.h>
-#include <hypervisor/ktrace.h>
-#include <vm/fault.h>
-#include <vm/physmap.h>
-#include <zircon/syscalls/hypervisor.h>
-#include <zircon/syscalls/port.h>
-
-#define LOCAL_TRACE 0
-
-#define SET_SYSREG(sysreg)                                                      \
-    ({                                                                          \
-        guest_state->system_state.sysreg = reg;                                 \
-        LTRACEF("guest " #sysreg ": %#lx\n", guest_state->system_state.sysreg); \
-        next_pc(guest_state);                                                   \
-        ZX_OK;                                                                  \
-    })
-
-static constexpr size_t kPageTableLevelShift = 3;
-static constexpr uint16_t kSmcPsci = 0;
-
-enum TimerControl : uint32_t {
-    ENABLE = 1u << 0,
-    IMASK = 1u << 1,
-    ISTATUS = 1u << 2,
-};
-
-ExceptionSyndrome::ExceptionSyndrome(uint32_t esr) {
-    ec = static_cast<ExceptionClass>(BITS_SHIFT(esr, 31, 26));
-    iss = BITS(esr, 24, 0);
-}
-
-WaitInstruction::WaitInstruction(uint32_t iss) {
-    is_wfe = BIT(iss, 0);
-}
-
-SmcInstruction::SmcInstruction(uint32_t iss) {
-    imm = static_cast<uint16_t>(BITS(iss, 15, 0));
-}
-
-SystemInstruction::SystemInstruction(uint32_t iss) {
-    sysreg = static_cast<SystemRegister>(BITS(iss, 21, 10) >> 6 | BITS_SHIFT(iss, 4, 1));
-    xt = static_cast<uint8_t>(BITS_SHIFT(iss, 9, 5));
-    read = BIT(iss, 0);
-}
-
-SgiRegister::SgiRegister(uint64_t sgir) {
-    aff3 = static_cast<uint8_t>(BITS_SHIFT(sgir, 55, 48));
-    aff2 = static_cast<uint8_t>(BITS_SHIFT(sgir, 39, 32));
-    aff1 = static_cast<uint8_t>(BITS_SHIFT(sgir, 23, 16));
-    rs = static_cast<uint8_t>(BITS_SHIFT(sgir, 47, 44));
-    target_list = static_cast<uint8_t>(BITS_SHIFT(sgir, 15, 0));
-    int_id = static_cast<uint8_t>(BITS_SHIFT(sgir, 27, 24));
-    all_but_local = BIT(sgir, 40);
-}
-
-DataAbort::DataAbort(uint32_t iss) {
-    valid = BIT_SHIFT(iss, 24);
-    access_size = static_cast<uint8_t>(1u << BITS_SHIFT(iss, 23, 22));
-    sign_extend = BIT(iss, 21);
-    xt = static_cast<uint8_t>(BITS_SHIFT(iss, 20, 16));
-    read = !BIT(iss, 6);
-}
-
-static void next_pc(GuestState* guest_state) {
-    guest_state->system_state.elr_el2 += 4;
-}
-
-static bool timer_enabled(GuestState* guest_state) {
-    bool enabled = guest_state->cntv_ctl_el0 & TimerControl::ENABLE;
-    bool masked = guest_state->cntv_ctl_el0 & TimerControl::IMASK;
-    return enabled && !masked;
-}
-
-void timer_maybe_interrupt(GuestState* guest_state, GichState* gich_state) {
-    if (timer_enabled(guest_state) && current_ticks() >= guest_state->cntv_cval_el0 &&
-        !gich_state->active_interrupts.GetOne(kTimerVector)) {
-        gich_state->interrupt_tracker.Track(kTimerVector, hypervisor::InterruptType::PHYSICAL);
-    }
-}
-
-static zx_status_t handle_wfi_wfe_instruction(uint32_t iss, GuestState* guest_state,
-                                              GichState* gich_state) {
-    next_pc(guest_state);
-    const WaitInstruction wi(iss);
-    if (wi.is_wfe) {
-        ktrace_vcpu_exit(VCPU_WFE_INSTRUCTION, guest_state->system_state.elr_el2);
-        thread_reschedule();
-        return ZX_OK;
-    }
-    ktrace_vcpu_exit(VCPU_WFI_INSTRUCTION, guest_state->system_state.elr_el2);
-    zx_time_t deadline = ZX_TIME_INFINITE;
-    if (timer_enabled(guest_state)) {
-        if (current_ticks() >= guest_state->cntv_cval_el0) {
-            return ZX_OK;
-        }
-        deadline = cntpct_to_zx_time(guest_state->cntv_cval_el0);
-    }
-    return gich_state->interrupt_tracker.Wait(deadline, nullptr);
-}
-
-static zx_status_t handle_smc_instruction(uint32_t iss, GuestState* guest_state,
-                                          zx_port_packet_t* packet) {
-    const SmcInstruction si(iss);
-    if (si.imm != kSmcPsci)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    next_pc(guest_state);
-    switch (guest_state->x[0]) {
-    case PSCI64_CPU_ON:
-        memset(packet, 0, sizeof(*packet));
-        packet->type = ZX_PKT_TYPE_GUEST_VCPU;
-        packet->guest_vcpu.type = ZX_PKT_GUEST_VCPU_STARTUP;
-        packet->guest_vcpu.startup.id = guest_state->x[1];
-        packet->guest_vcpu.startup.entry = guest_state->x[2];
-        guest_state->x[0] = PSCI_SUCCESS;
-        return ZX_ERR_NEXT;
-    default:
-        guest_state->x[0] = PSCI_NOT_SUPPORTED;
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-}
-
-static void clean_invalidate_cache(zx_paddr_t table, size_t index_shift) {
-    // TODO(abdulla): Make this understand concatenated page tables.
-    auto* pte = static_cast<pte_t*>(paddr_to_physmap(table));
-    pte_t page = index_shift > MMU_GUEST_PAGE_SIZE_SHIFT ?
-                 MMU_PTE_L012_DESCRIPTOR_BLOCK : MMU_PTE_L3_DESCRIPTOR_PAGE;
-    for (size_t i = 0; i < PAGE_SIZE / sizeof(pte_t); i++) {
-        pte_t desc = pte[i] & MMU_PTE_DESCRIPTOR_MASK;
-        pte_t paddr = pte[i] & MMU_PTE_OUTPUT_ADDR_MASK;
-        if (desc == page) {
-            zx_vaddr_t vaddr = reinterpret_cast<zx_vaddr_t>(paddr_to_physmap(paddr));
-            arch_clean_invalidate_cache_range(vaddr, 1lu << index_shift);
-        } else if (desc != MMU_PTE_DESCRIPTOR_INVALID) {
-            size_t adjust_shift = MMU_GUEST_PAGE_SIZE_SHIFT - kPageTableLevelShift;
-            clean_invalidate_cache(paddr, index_shift - adjust_shift);
-        }
-    }
-}
-
-static zx_status_t handle_system_instruction(uint32_t iss, uint64_t* hcr, GuestState* guest_state,
-                                             hypervisor::GuestPhysicalAddressSpace* gpas,
-                                             zx_port_packet_t* packet) {
-    const SystemInstruction si(iss);
-    const uint64_t reg = guest_state->x[si.xt];
-
-    switch (si.sysreg) {
-    case SystemRegister::MAIR_EL1:
-        return SET_SYSREG(mair_el1);
-    case SystemRegister::SCTLR_EL1: {
-        if (si.read) {
-            return ZX_ERR_NOT_SUPPORTED;
-        }
-
-        // From ARM DDI 0487B.b, Section D10.2.89: If the value of HCR_EL2.{DC,
-        // TGE} is not {0, 0} then in Non-secure state the PE behaves as if the
-        // value of the SCTLR_EL1.M field is 0 for all purposes other than
-        // returning the value of a direct read of the field.
-        //
-        // Therefore if SCTLR_EL1.M is set to 1, we need to set HCR_EL2.DC to 0
-        // and invalidate the guest physical address space.
-        uint32_t sctlr_el1 = reg & UINT32_MAX;
-        if (sctlr_el1 & SCTLR_ELX_M) {
-            *hcr &= ~HCR_EL2_DC;
-            // Additionally, if the guest has also set SCTLR_EL1.C to 1, we no
-            // longer need to trap writes to virtual memory control registers,
-            // so we can set HCR_EL2.TVM to 0 to improve performance.
-            if (sctlr_el1 & SCTLR_ELX_C) {
-                *hcr &= ~HCR_EL2_TVM;
-            }
-            clean_invalidate_cache(gpas->arch_aspace()->arch_table_phys(), MMU_GUEST_TOP_SHIFT);
-        }
-        guest_state->system_state.sctlr_el1 = sctlr_el1;
-
-        LTRACEF("guest sctlr_el1: %#x\n", sctlr_el1);
-        LTRACEF("guest hcr_el2: %#lx\n", *hcr);
-        next_pc(guest_state);
-        return ZX_OK;
-    }
-    case SystemRegister::TCR_EL1:
-        return SET_SYSREG(tcr_el1);
-    case SystemRegister::TTBR0_EL1:
-        return SET_SYSREG(ttbr0_el1);
-    case SystemRegister::TTBR1_EL1:
-        return SET_SYSREG(ttbr1_el1);
-    case SystemRegister::OSLAR_EL1:
-    case SystemRegister::OSLSR_EL1:
-    case SystemRegister::OSDLR_EL1:
-    case SystemRegister::DBGPRCR_EL1:
-        next_pc(guest_state);
-        // These registers are RAZ/WI. Their state is dictated by the host.
-        if (si.read) {
-            guest_state->x[si.xt] = 0;
-        }
-        return ZX_OK;
-    case SystemRegister::ICC_SGI1R_EL1: {
-        if (si.read) {
-            // ICC_SGI1R_EL1 is write-only.
-            return ZX_ERR_INVALID_ARGS;
-        }
-        SgiRegister sgi(reg);
-        if (sgi.aff3 != 0 || sgi.aff2 != 0 || sgi.aff1 != 0 || sgi.rs != 0) {
-            return ZX_ERR_NOT_SUPPORTED;
-        }
-
-        memset(packet, 0, sizeof(*packet));
-        packet->type = ZX_PKT_TYPE_GUEST_VCPU;
-        packet->guest_vcpu.type = ZX_PKT_GUEST_VCPU_INTERRUPT;
-        if (sgi.all_but_local) {
-            auto vpid = BITS(guest_state->system_state.vmpidr_el2, 8, 0);
-            packet->guest_vcpu.interrupt.mask = ~(static_cast<uint64_t>(1) << vpid);
-        } else {
-            packet->guest_vcpu.interrupt.mask = sgi.target_list;
-        }
-        packet->guest_vcpu.interrupt.vector = sgi.int_id;
-        next_pc(guest_state);
-        return ZX_ERR_NEXT;
-    }
-    }
-
-    dprintf(CRITICAL, "Unhandled system register %#x\n", static_cast<uint16_t>(si.sysreg));
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
-static zx_status_t handle_instruction_abort(GuestState* guest_state,
-                                            hypervisor::GuestPhysicalAddressSpace* gpas) {
-    const zx_vaddr_t guest_paddr = guest_state->hpfar_el2;
-    zx_status_t status = gpas->PageFault(guest_paddr);
-    if (status != ZX_OK) {
-        dprintf(CRITICAL, "Unhandled instruction abort %#lx\n", guest_paddr);
-    }
-    return status;
-}
-
-static zx_status_t handle_data_abort(uint32_t iss, GuestState* guest_state,
-                                     hypervisor::GuestPhysicalAddressSpace* gpas,
-                                     hypervisor::TrapMap* traps,
-                                     zx_port_packet_t* packet) {
-    zx_vaddr_t guest_paddr = guest_state->hpfar_el2;
-    hypervisor::Trap* trap;
-    zx_status_t status = traps->FindTrap(ZX_GUEST_TRAP_BELL, guest_paddr, &trap);
-    switch (status) {
-    case ZX_ERR_NOT_FOUND:
-        status = gpas->PageFault(guest_paddr);
-        if (status != ZX_OK) {
-            dprintf(CRITICAL, "Unhandled data abort %#lx\n", guest_paddr);
-        }
-        return status;
-    case ZX_OK:
-        break;
-    default:
-        return status;
-    }
-    next_pc(guest_state);
-
-    // Combine the lower bits of FAR_EL2 with HPFAR_EL2 to get the exact IPA.
-    guest_paddr |= guest_state->far_el2 & (PAGE_SIZE - 1);
-    LTRACEF("guest far_el2: %#lx\n", guest_state->far_el2);
-
-    const DataAbort data_abort(iss);
-    switch (trap->kind()) {
-    case ZX_GUEST_TRAP_BELL:
-        if (data_abort.read)
-            return ZX_ERR_NOT_SUPPORTED;
-        *packet = {};
-        packet->key = trap->key();
-        packet->type = ZX_PKT_TYPE_GUEST_BELL;
-        packet->guest_bell.addr = guest_paddr;
-        if (!trap->HasPort())
-            return ZX_ERR_BAD_STATE;
-        return trap->Queue(*packet, nullptr);
-    case ZX_GUEST_TRAP_MEM:
-        if (!data_abort.valid)
-            return ZX_ERR_IO_DATA_INTEGRITY;
-        *packet = {};
-        packet->key = trap->key();
-        packet->type = ZX_PKT_TYPE_GUEST_MEM;
-        packet->guest_mem.addr = guest_paddr;
-        packet->guest_mem.access_size = data_abort.access_size;
-        packet->guest_mem.sign_extend = data_abort.sign_extend;
-        packet->guest_mem.xt = data_abort.xt;
-        packet->guest_mem.read = data_abort.read;
-        if (!data_abort.read)
-            packet->guest_mem.data = guest_state->x[data_abort.xt];
-        return ZX_ERR_NEXT;
-    default:
-        return ZX_ERR_BAD_STATE;
-    }
-}
-
-zx_status_t vmexit_handler(uint64_t* hcr, GuestState* guest_state, GichState* gich_state,
-                           hypervisor::GuestPhysicalAddressSpace* gpas, hypervisor::TrapMap* traps,
-                           zx_port_packet_t* packet) {
-    LTRACEF("guest esr_el1: %#x\n", guest_state->system_state.esr_el1);
-    LTRACEF("guest esr_el2: %#x\n", guest_state->esr_el2);
-    LTRACEF("guest elr_el2: %#lx\n", guest_state->system_state.elr_el2);
-    LTRACEF("guest spsr_el2: %#x\n", guest_state->system_state.spsr_el2);
-
-    ExceptionSyndrome syndrome(guest_state->esr_el2);
-    zx_status_t status;
-    switch (syndrome.ec) {
-    case ExceptionClass::WFI_WFE_INSTRUCTION:
-        LTRACEF("handling wfi/wfe instruction, iss %#x\n", syndrome.iss);
-        status = handle_wfi_wfe_instruction(syndrome.iss, guest_state, gich_state);
-        break;
-    case ExceptionClass::SMC_INSTRUCTION:
-        LTRACEF("handling smc instruction, iss %#x func %#lx\n", syndrome.iss, guest_state->x[0]);
-        ktrace_vcpu_exit(VCPU_SMC_INSTRUCTION, guest_state->system_state.elr_el2);
-        status = handle_smc_instruction(syndrome.iss, guest_state, packet);
-        break;
-    case ExceptionClass::SYSTEM_INSTRUCTION:
-        LTRACEF("handling system instruction\n");
-        ktrace_vcpu_exit(VCPU_SYSTEM_INSTRUCTION, guest_state->system_state.elr_el2);
-        status = handle_system_instruction(syndrome.iss, hcr, guest_state, gpas, packet);
-        break;
-    case ExceptionClass::INSTRUCTION_ABORT:
-        LTRACEF("handling instruction abort at %#lx\n", guest_state->hpfar_el2);
-        ktrace_vcpu_exit(VCPU_INSTRUCTION_ABORT, guest_state->system_state.elr_el2);
-        status = handle_instruction_abort(guest_state, gpas);
-        break;
-    case ExceptionClass::DATA_ABORT:
-        LTRACEF("handling data abort at %#lx\n", guest_state->hpfar_el2);
-        ktrace_vcpu_exit(VCPU_DATA_ABORT, guest_state->system_state.elr_el2);
-        status = handle_data_abort(syndrome.iss, guest_state, gpas, traps, packet);
-        break;
-    default:
-        LTRACEF("unhandled exception syndrome, ec %#x iss %#x\n",
-                static_cast<uint32_t>(syndrome.ec), syndrome.iss);
-        ktrace_vcpu_exit(VCPU_UNKNOWN, guest_state->system_state.elr_el2);
-        status = ZX_ERR_NOT_SUPPORTED;
-        break;
-    }
-    if (status != ZX_OK && status != ZX_ERR_NEXT && status != ZX_ERR_CANCELED) {
-        dprintf(CRITICAL, "VM exit handler for %u (%s) in EL%u at %#lx returned %d\n",
-                static_cast<uint32_t>(syndrome.ec),
-                exception_class_name(syndrome.ec),
-                BITS_SHIFT(guest_state->system_state.spsr_el2, 3, 2),
-                guest_state->system_state.elr_el2,
-                status);
-    }
-    return status;
-}
diff --git a/kernel/arch/arm64/hypervisor/vmexit_priv.h b/kernel/arch/arm64/hypervisor/vmexit_priv.h
deleted file mode 100644
index 43d4523..0000000
--- a/kernel/arch/arm64/hypervisor/vmexit_priv.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <hypervisor/guest_physical_address_space.h>
-#include <hypervisor/trap_map.h>
-#include <zircon/types.h>
-
-typedef struct zx_port_packet zx_port_packet_t;
-
-struct GuestState;
-struct GichState;
-
-// clang-format off
-
-// Exception class of an exception syndrome.
-enum class ExceptionClass : uint8_t {
-    WFI_WFE_INSTRUCTION = 0b000001,
-    SMC_INSTRUCTION     = 0b010111,
-    SYSTEM_INSTRUCTION  = 0b011000,
-    INSTRUCTION_ABORT   = 0b100000,
-    DATA_ABORT          = 0b100100,
-};
-
-static inline const char* exception_class_name(ExceptionClass exception_class) {
-#define EXCEPTION_CLASS_NAME(name) case ExceptionClass::name: return #name
-    switch (exception_class) {
-    EXCEPTION_CLASS_NAME(WFI_WFE_INSTRUCTION);
-    EXCEPTION_CLASS_NAME(SMC_INSTRUCTION);
-    EXCEPTION_CLASS_NAME(SYSTEM_INSTRUCTION);
-    EXCEPTION_CLASS_NAME(INSTRUCTION_ABORT);
-    EXCEPTION_CLASS_NAME(DATA_ABORT);
-#undef EXIT_REASON_NAME
-    default: return "UNKNOWN";
-    }
-}
-
-// Exception syndrome for a VM exit.
-struct ExceptionSyndrome {
-    ExceptionClass ec;
-    uint32_t iss;
-
-    ExceptionSyndrome(uint32_t esr);
-};
-
-// Wait instruction that caused a VM exit.
-struct WaitInstruction {
-    bool is_wfe;
-
-    WaitInstruction(uint32_t iss);
-};
-
-// SMC instruction that cause a VM exit.
-struct SmcInstruction {
-    uint16_t imm;
-
-    SmcInstruction(uint32_t iss);
-};
-
-// System register associated with a system instruction.
-enum class SystemRegister : uint16_t {
-    MAIR_EL1        = 0b11000000 << 8 /* op */ | 0b10100010 /* cr */,
-    SCTLR_EL1       = 0b11000000 << 8 /* op */ | 0b00010000 /* cr */,
-    TCR_EL1         = 0b11010000 << 8 /* op */ | 0b00100000 /* cr */,
-    TTBR0_EL1       = 0b11000000 << 8 /* op */ | 0b00100000 /* cr */,
-    TTBR1_EL1       = 0b11001000 << 8 /* op */ | 0b00100000 /* cr */,
-
-    // Debug Registers, trapped by MDCR_EL2.TDOSA = 1
-    OSLAR_EL1       = 0b10100000 << 8 /* op */ | 0b00010000 /* cr */,
-    OSLSR_EL1       = 0b10100000 << 8 /* op */ | 0b00010001 /* cr */,
-    OSDLR_EL1       = 0b10100000 << 8 /* op */ | 0b00010011 /* cr */,
-    DBGPRCR_EL1     = 0b10100000 << 8 /* op */ | 0b00010100 /* cr */,
-
-    // Interrupt Controller System Registers. See GIC v3/v4 Architecture Spec Section 8.2.
-    ICC_SGI1R_EL1   = 0b11101000 << 8 /* op */ | 0b11001011 /* cr */,
-};
-
-// System instruction that caused a VM exit.
-struct SystemInstruction {
-    SystemRegister sysreg;
-    uint8_t xt;
-    bool read;
-
-    SystemInstruction(uint32_t iss);
-};
-
-struct SgiRegister {
-    uint8_t aff3;
-    uint8_t aff2;
-    uint8_t aff1;
-    uint8_t rs;
-    uint16_t target_list;
-    uint8_t int_id;
-    bool all_but_local;
-
-    SgiRegister(uint64_t sgi);
-};
-
-// Data abort that caused a VM exit.
-struct DataAbort {
-    bool valid;
-    uint8_t access_size;
-    bool sign_extend;
-    uint8_t xt;
-    bool read;
-
-    DataAbort(uint32_t iss);
-};
-
-// clang-format on
-
-void timer_maybe_interrupt(GuestState* guest_state, GichState* gich_state);
-zx_status_t vmexit_handler(uint64_t* hcr, GuestState* guest_state, GichState* gich_state,
-                           hypervisor::GuestPhysicalAddressSpace* gpas, hypervisor::TrapMap* traps,
-                           zx_port_packet_t* packet);
diff --git a/kernel/arch/arm64/image.S b/kernel/arch/arm64/image.S
deleted file mode 100644
index 4d88938..0000000
--- a/kernel/arch/arm64/image.S
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <zircon/boot/image.h>
-
-
-// This file lays out the final kernel image seen by the boot loader.
-// It concatenates:
-//     1. the boot loader headers
-//     2. the actual kernel image (converted from the kernel ELF file)
-//     3. the fixup code to relocate the kernel image
-// The headers must tell the boot loader to load the whole combined image,
-// and leave enough space in memory after it for the bss.
-//
-// The label arithmetic to define the header fields only works because this
-// whole file is all in the same section (.text).  Because it's all just
-// one big section and there are no relocs to absolute locations within
-// this section, it really doesn't matter what memory layout the linker
-// thinks it's doing, but nonetheless image.ld produces an ELF segment
-// layout faithful to the physical memory picture (except that it's
-// actually position-independent).  The addresses in the ELF headers of the
-// final image.elf file are completely ignored because boot loaders don't
-// actually use that file.  It only exists to have the contents extracted
-// with objcopy -O binary.
-
-.text
-
-// ZBI file header (zbi_header_t)
-ZBI_CONTAINER_HEADER(_zbi_file_header, boot_load_end - _zbi_kernel_header)
-
-// ZBI kernel header (zbi_header_t)
-DATA(_zbi_kernel_header)
-    .int ZBI_TYPE_KERNEL_ARM64
-    .int boot_load_end - _zbi_kernel_payload
-    .int 0
-    .int ZBI_FLAG_VERSION
-    .int 0
-    .int 0
-    .int ZBI_ITEM_MAGIC
-    .int ZBI_ITEM_NO_CRC32
-END_DATA(_zbi_kernel_header)
-
-// ZBI_TYPE_KERNEL payload (zbi_kernel_t)
-DATA(_zbi_kernel_payload)
-    // The boot-shim code expects this to be an offset from the beginning
-    // of the load image, whatever the kernel's virtual address.
-    .quad IMAGE_ELF_ENTRY - _zbi_file_header
-    .quad IMAGE_MEMORY_END - boot_load_end
-END_DATA(_zbi_kernel_payload)
-
-// Pad out to the header size that was allocated in the kernel image layout.
-// This ensures that the kernel image is aligned correctly in memory.
-.org BOOT_HEADER_SIZE
-
-// Include the kernel image itself, skipping the padding left for the headers.
-DATA(kernel_image)
-.incbin KERNEL_IMAGE, BOOT_HEADER_SIZE
-DATA(kernel_image_end)
-END_DATA(kernel_image)
-
-// Immediately after the kernel image comes the fixup code.
-// The start.S code sees this address as __data_end.
-
-#define FIXUP_LOCATION(addr) (addr - KERNEL_BASE + IMAGE_LOAD_START)
-
-// This code must be purely position-independent and have no relocs.
-// This is called with the desired runtime address of __code_start in x0.
-FUNCTION(apply_fixups)
-    // This is the constant address the kernel was linked for.
-    movlit x9, KERNEL_BASE
-    sub x0, x0, x9
-
-// The generated kernel-fixups.inc invokes this macro for each run of fixups.
-.macro fixup addr, n, stride
-    adr x9, FIXUP_LOCATION(\addr)
-.if \n >= 4 && \stride == 8
-    // Do a loop handling adjacent pairs.
-    mov x16, #(\n / 2)
-0:  fixup_pair
-    subs x16, x16, #1
-    b.ne 0b
- .if \n % 2
-    // Handle the odd remainder after those pairs.
-    fixup_single 8
- .endif
-.elseif \n >= 2 && \stride == 8
-    // Do a single adjacent pair.
-    fixup_pair
- .if \n == 3
-    // Do the third adjacent one.
-    fixup_single 8
- .endif
-.elseif \n > 1
-    // Do a strided loop.
-    mov x16, #\n
-0:  fixup_single \stride
-    subs x16, x16, #1
-    b.ne 0b
-.else
-    // Do a singleton.
-    fixup_single 8
-.endif
-.endm
-
-.macro fixup_pair
-    ldp x10, x11, [x9]
-    add x10, x10, x0
-    add x11, x11, x0
-    stp x10, x11, [x9], #16
-.endm
-
-.macro fixup_single stride
-    ldr x10, [x9]
-    add x10, x10, x0
-    str x10, [x9], #\stride
-.endm
-
-#include "kernel-fixups.inc"
-
-    ret
-
-DATA(apply_fixups_end)
-END_FUNCTION(apply_fixups)
-
-.balign 8
-DATA(boot_load_end)
-
-// We don't use any scratch memory after the kernel's bss.
-.globl IMAGE_RESERVE_SIZE
-IMAGE_RESERVE_SIZE = 0
diff --git a/kernel/arch/arm64/include/arch/arch_ops.h b/kernel/arch/arm64/include/arch/arch_ops.h
deleted file mode 100644
index 2805b30..0000000
--- a/kernel/arch/arm64/include/arch/arch_ops.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2008-2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#ifndef __ASSEMBLER__
-
-#include <arch/arm64.h>
-#include <arch/arm64/feature.h>
-#include <arch/arm64/interrupt.h>
-#include <arch/arm64/mp.h>
-#include <reg.h>
-#include <stdbool.h>
-#include <zircon/compiler.h>
-
-__BEGIN_CDECLS
-
-#define ENABLE_CYCLE_COUNTER 1
-
-static inline void arch_spinloop_pause(void) {
-    __yield();
-}
-
-#define mb() __dsb(ARM_MB_SY)
-#define smp_mb() __dmb(ARM_MB_SY)
-
-static inline uint64_t arch_cycle_count(void) {
-    return __arm_rsr64("pmccntr_el0");
-}
-
-static inline uint32_t arch_cpu_features(void) {
-    return arm64_features;
-}
-
-static inline uint32_t arch_dcache_line_size(void) {
-    return arm64_dcache_size;
-}
-
-static inline uint32_t arch_icache_line_size(void) {
-    return arm64_icache_size;
-}
-
-// Log architecture-specific data for process creation.
-// This can only be called after the process has been created and before
-// it is running. Alas we can't use zx_koid_t here as the arch layer is at a
-// lower level than zircon.
-static inline void arch_trace_process_create(uint64_t pid, paddr_t tt_phys) {
-    // nothing to do
-}
-
-__END_CDECLS
-
-#endif // __ASSEMBLER__
diff --git a/kernel/arch/arm64/include/arch/arch_thread.h b/kernel/arch/arm64/include/arch/arch_thread.h
deleted file mode 100644
index bf12dd3..0000000
--- a/kernel/arch/arm64/include/arch/arch_thread.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#define CURRENT_PERCPU_PTR_OFFSET 16
-
-#ifndef __ASSEMBLER__
-
-#include <assert.h>
-#include <arch/arm64/registers.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <zircon/compiler.h>
-#include <zircon/tls.h>
-
-__BEGIN_CDECLS
-
-struct fpstate {
-    uint32_t fpcr;
-    uint32_t fpsr;
-    uint64_t regs[64];
-};
-
-struct arm64_percpu;
-
-struct arch_thread {
-    // The compiler (when it's Clang with -mcmodel=kernel) knows
-    // the position of these two fields relative to TPIDR_EL1,
-    // which is what __builtin_thread_pointer() returns.  TPIDR_EL1
-    // points just past these, i.e. to &abi[1].
-    uintptr_t stack_guard;
-    vaddr_t unsafe_sp;
-    union {
-        char thread_pointer_location;
-        vaddr_t sp;
-    };
-
-    // Debugger access to userspace general regs while suspended or stopped
-    // in an exception.
-    // The regs are saved on the stack and then a pointer is stored here.
-    // NULL if not suspended or stopped in an exception.
-    struct arm64_iframe_long* suspended_general_regs;
-
-    // Point to the current cpu pointer when the thread is running, used to
-    // restore x18 on exception entry. Swapped on context switch.
-    struct arm64_percpu* current_percpu_ptr;
-
-    // if non-NULL, address to return to on data fault
-    void* data_fault_resume;
-
-    // saved fpu state
-    struct fpstate fpstate;
-
-    // |track_debug_state| tells whether the kernel should keep track of the whole debug state for
-    // this thread. Normally this is set explicitly by an user that wants to make use of HW
-    // breakpoints or watchpoints.
-    // Userspace can still read the complete |debug_state| even if |track_debug_state| is false.
-    bool track_debug_state;
-    arm64_debug_state_t debug_state;
-};
-
-#define thread_pointer_offsetof(field)          \
-    ((int)offsetof(struct arch_thread, field) - \
-     (int)offsetof(struct arch_thread, thread_pointer_location))
-
-static_assert(
-    thread_pointer_offsetof(stack_guard) == ZX_TLS_STACK_GUARD_OFFSET,
-    "stack_guard field in wrong place");
-static_assert(
-    thread_pointer_offsetof(unsafe_sp) == ZX_TLS_UNSAFE_SP_OFFSET,
-    "unsafe_sp field in wrong place");
-static_assert(
-    thread_pointer_offsetof(current_percpu_ptr) == CURRENT_PERCPU_PTR_OFFSET,
-    "per cpu ptr offset in wrong place");
-
-__END_CDECLS
-
-#endif // __ASSEMBLER__
diff --git a/kernel/arch/arm64/include/arch/arm64.h b/kernel/arch/arm64/include/arch/arm64.h
deleted file mode 100644
index 32a7ba9..0000000
--- a/kernel/arch/arm64/include/arch/arm64.h
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#ifndef __ASSEMBLER__
-
-#include <arm_acle.h>
-#include <assert.h>
-#include <stdbool.h>
-#include <sys/types.h>
-
-#include <syscalls/syscalls.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-// Constants from ACLE section 8.3, used as the argument for __dmb(), __dsb(), and __isb()
-// in arm_acle.h. Values are the architecturally defined immediate values encoded in barrier
-// instructions DMB, DSB, and ISB.
-#define ARM_MB_OSHLD    0x1
-#define ARM_MB_OSHST    0x2
-#define ARM_MB_OSH      0x3
-
-#define ARM_MB_NSHLD    0x5
-#define ARM_MB_NSHST    0x6
-#define ARM_MB_NSH      0x7
-
-#define ARM_MB_ISHLD    0x9
-#define ARM_MB_ISHST    0xa
-#define ARM_MB_ISH      0xb
-
-#define ARM_MB_LD       0xd
-#define ARM_MB_ST       0xe
-#define ARM_MB_SY       0xf
-
-__BEGIN_CDECLS
-
-void arm64_context_switch(vaddr_t* old_sp, vaddr_t new_sp);
-void arm64_uspace_entry(uintptr_t arg1, uintptr_t arg2,
-                        uintptr_t pc, uintptr_t sp,
-                        vaddr_t kstack, uint32_t spsr,
-                        uint32_t mdscr) __NO_RETURN;
-
-typedef struct {
-    uint8_t ctype;
-    bool write_through;
-    bool write_back;
-    bool read_alloc;
-    bool write_alloc;
-    uint32_t num_sets;
-    uint32_t associativity;
-    uint32_t line_size;
-} arm64_cache_desc_t;
-
-typedef struct {
-    uint8_t inner_boundary;
-    uint8_t lou_u;
-    uint8_t loc;
-    uint8_t lou_is;
-    arm64_cache_desc_t level_data_type[7];
-    arm64_cache_desc_t level_inst_type[7];
-} arm64_cache_info_t;
-
-/* exception handling */
-struct arm64_iframe_long {
-    uint64_t r[30];
-    uint64_t lr;
-    uint64_t usp;
-    uint64_t elr;
-    uint64_t spsr;
-    uint64_t mdscr;
-    uint64_t pad2[1]; // Keep structure multiple of 16-bytes for stack alignment.
-};
-
-struct arm64_iframe_short {
-    uint64_t r[20];
-    // pad the short frame out so that it has the same general shape and size as a long
-    uint64_t pad[10];
-    uint64_t lr;
-    uint64_t usp;
-    uint64_t elr;
-    uint64_t spsr;
-    uint64_t pad2[2];
-};
-
-static_assert(sizeof(struct arm64_iframe_long) == sizeof(struct arm64_iframe_short), "");
-
-struct arch_exception_context {
-    struct arm64_iframe_long* frame;
-    uint64_t far;
-    uint32_t esr;
-};
-
-struct thread;
-extern void arm64_el1_exception_base(void);
-void arm64_el3_to_el1(void);
-void arm64_sync_exception(struct arm64_iframe_long* iframe, uint exception_flags, uint32_t esr);
-void arm64_thread_process_pending_signals(struct arm64_iframe_long* iframe);
-
-typedef struct arm64_iframe_long iframe_t;
-typedef struct arm64_iframe_short iframe;
-
-void platform_irq(iframe* frame);
-void platform_fiq(iframe* frame);
-
-/* fpu routines */
-void arm64_fpu_exception(struct arm64_iframe_long* iframe, uint exception_flags);
-void arm64_fpu_context_switch(struct thread* oldthread, struct thread* newthread);
-
-uint64_t arm64_get_boot_el(void);
-
-void arm_reset(void);
-
-/*
- * Creates a stack and sets the stack pointer for the specified secondary CPU.
- */
-zx_status_t arm64_create_secondary_stack(uint cpu_num, uint64_t mpid);
-
-/*
- * Frees a stack created by |arm64_create_secondary_stack|.
- */
-zx_status_t arm64_free_secondary_stack(uint cpu_num);
-
-__END_CDECLS
-
-#endif // __ASSEMBLER__
-
-/* used in above exception_flags arguments */
-#define ARM64_EXCEPTION_FLAG_LOWER_EL (1 << 0)
-#define ARM64_EXCEPTION_FLAG_ARM32 (1 << 1)
diff --git a/kernel/arch/arm64/include/arch/arm64/exceptions.h b/kernel/arch/arm64/include/arch/arm64/exceptions.h
deleted file mode 100644
index c7b99a1..0000000
--- a/kernel/arch/arm64/include/arch/arm64/exceptions.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// Flags passed back from arm64_irq() to the calling assembler.
-#define ARM64_IRQ_EXIT_THREAD_SIGNALED 1
-#define ARM64_IRQ_EXIT_RESCHEDULE 2
diff --git a/kernel/arch/arm64/include/arch/arm64/feature.h b/kernel/arch/arm64/include/arch/arm64/feature.h
deleted file mode 100644
index b014d86..0000000
--- a/kernel/arch/arm64/include/arch/arm64/feature.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/arm64.h>
-#include <stdint.h>
-#include <zircon/compiler.h>
-#include <zircon/features.h>
-
-__BEGIN_CDECLS
-
-extern uint32_t arm64_features;
-
-static inline bool arm64_feature_test(uint32_t feature) {
-
-    return arm64_features & feature;
-}
-
-/* block size of the dc zva instruction, dcache cache line and icache cache line */
-extern uint32_t arm64_zva_size;
-extern uint32_t arm64_icache_size;
-extern uint32_t arm64_dcache_size;
-
-// call on every cpu to initialize the feature set
-void arm64_feature_init(void);
-
-// dump the feature set
-void arm64_feature_debug(bool full);
-
-void arm64_get_cache_info(arm64_cache_info_t* info);
-void arm64_dump_cache_info(uint32_t cpu);
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/include/arch/arm64/hypervisor/el2_state.h b/kernel/arch/arm64/include/arch/arm64/hypervisor/el2_state.h
deleted file mode 100644
index 5466e01..0000000
--- a/kernel/arch/arm64/include/arch/arm64/hypervisor/el2_state.h
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/compiler.h>
-
-// clang-format off
-
-#ifndef __ASSEMBLER__
-#define BIT_32(bit)         (1u << bit)
-#define BIT_64(bit)         (1ul << bit)
-#else
-#define BIT_32(bit)         (0x1 << bit)
-#define BIT_64(bit)         (0x1 << bit)
-#endif
-
-#define HCR_EL2_VM          BIT_64(0)
-#define HCR_EL2_PTW         BIT_64(2)
-#define HCR_EL2_FMO         BIT_64(3)
-#define HCR_EL2_IMO         BIT_64(4)
-#define HCR_EL2_AMO         BIT_64(5)
-#define HCR_EL2_VI          BIT_64(7)
-#define HCR_EL2_DC          BIT_64(12)
-#define HCR_EL2_TWI         BIT_64(13)
-#define HCR_EL2_TWE         BIT_64(14)
-#define HCR_EL2_TSC         BIT_64(19)
-#define HCR_EL2_TVM         BIT_64(26)
-#define HCR_EL2_RW          BIT_64(31)
-
-#define SCTLR_ELX_M         BIT_32(0)
-#define SCTLR_ELX_A         BIT_32(1)
-#define SCTLR_ELX_C         BIT_32(2)
-#define SCTLR_ELX_SA        BIT_32(3)
-#define SCTLR_ELX_I         BIT_32(12)
-
-#define SCTLR_EL1_RES1      0x00500800
-#define SCTLR_EL2_RES1      0x30c50830
-
-#define FS_Q0               0
-#define FS_Q(num)           (FS_Q0 + ((num) * 16))
-#define FS_NUM_REGS         32
-#define FS_FPSR             FS_Q(FS_NUM_REGS)
-#define FS_FPCR             (FS_FPSR + 8)
-
-#define SS_SP_EL0           0
-#define SS_TPIDR_EL0        (SS_SP_EL0 + 8)
-#define SS_TPIDRRO_EL0      (SS_TPIDR_EL0 + 8)
-#define SS_CNTKCTL_EL1      (SS_TPIDRRO_EL0 + 8)
-#define SS_CONTEXTIDR_EL1   (SS_CNTKCTL_EL1 + 8)
-#define SS_CPACR_EL1        (SS_CONTEXTIDR_EL1 + 8)
-#define SS_CSSELR_EL1       (SS_CPACR_EL1 + 8)
-#define SS_ELR_EL1          (SS_CSSELR_EL1 + 8)
-#define SS_ESR_EL1          (SS_ELR_EL1 + 8)
-#define SS_FAR_EL1          (SS_ESR_EL1 + 8)
-#define SS_MAIR_EL1         (SS_FAR_EL1 + 8)
-#define SS_MDSCR_EL1        (SS_MAIR_EL1 + 8)
-#define SS_PAR_EL1          (SS_MDSCR_EL1 + 8)
-#define SS_SCTLR_EL1        (SS_PAR_EL1 + 8)
-#define SS_SP_EL1           (SS_SCTLR_EL1 + 8)
-#define SS_SPSR_EL1         (SS_SP_EL1 + 8)
-#define SS_TCR_EL1          (SS_SPSR_EL1 + 8)
-#define SS_TPIDR_EL1        (SS_TCR_EL1 + 8)
-#define SS_TTBR0_EL1        (SS_TPIDR_EL1 + 8)
-#define SS_TTBR1_EL1        (SS_TTBR0_EL1 + 8)
-#define SS_VBAR_EL1         (SS_TTBR1_EL1 + 8)
-#define SS_ELR_EL2          (SS_VBAR_EL1 + 8)
-#define SS_SPSR_EL2         (SS_ELR_EL2 + 8)
-#define SS_VMPIDR_EL2       (SS_SPSR_EL2 + 8)
-
-#define ES_RESUME           0
-
-#define GS_X0               (ES_RESUME + 16)
-#define GS_X(num)           (GS_X0 + ((num) * 8))
-#define GS_NUM_REGS         31
-#define GS_FP_STATE         (GS_X(GS_NUM_REGS) + 8)
-#define GS_SYSTEM_STATE     (GS_FP_STATE + FS_FPCR + 8)
-#define GS_CNTV_CTL_EL0     (GS_SYSTEM_STATE + SS_VMPIDR_EL2 + 8)
-#define GS_CNTV_CVAL_EL0    (GS_CNTV_CTL_EL0 + 8)
-#define GS_ESR_EL2          (GS_CNTV_CVAL_EL0 + 8)
-#define GS_FAR_EL2          (GS_ESR_EL2 + 8)
-#define GS_HPFAR_EL2        (GS_FAR_EL2 + 8)
-
-#define HS_X18              (GS_HPFAR_EL2 + 16)
-// NOTE(abdulla): This differs from GS_X in that it calculates a value relative
-// to host_state.x, and not relative to El2State.
-#define HS_X(num)           ((num) * 8)
-#define HS_NUM_REGS         13
-#define HS_FP_STATE         (HS_X18 + HS_X(HS_NUM_REGS) + 8)
-#define HS_SYSTEM_STATE     (HS_FP_STATE + FS_FPCR + 8)
-
-#define IS_NUM_APRS         0
-#define IS_NUM_LRS          (IS_NUM_APRS + 1)
-#define IS_VMCR             (IS_NUM_LRS + 7)
-#define IS_MISR             (IS_VMCR + 8)
-#define IS_ELRSR            (IS_MISR + 8)
-#define IS_AP0R0            (IS_ELRSR + 8)
-#define IS_MAX_APRS         4
-#define IS_APR(group, num)  (IS_AP0R0 + ((((group) * IS_MAX_APRS) + (num)) * 8))
-#define IS_MAX_APR_GROUPS   2
-#define IS_LR0              IS_APR(IS_MAX_APR_GROUPS - 1, IS_MAX_APRS)
-#define IS_LR(num)          (IS_LR0 + ((num) * 8))
-#define IS_MAX_LRS          64
-
-// clang-format on
-
-#ifndef __ASSEMBLER__
-
-#include <arch/defines.h>
-#include <zircon/types.h>
-
-typedef uint32_t __ALIGNED(8) algn32_t;
-
-struct FpState {
-    __uint128_t q[FS_NUM_REGS];
-    algn32_t fpsr;
-    algn32_t fpcr;
-};
-
-struct SystemState {
-    uint64_t sp_el0;
-    uint64_t tpidr_el0;
-    uint64_t tpidrro_el0;
-
-    algn32_t cntkctl_el1;
-    algn32_t contextidr_el1;
-    algn32_t cpacr_el1;
-    algn32_t csselr_el1;
-    uint64_t elr_el1;
-    algn32_t esr_el1;
-    uint64_t far_el1;
-    uint64_t mair_el1;
-    algn32_t mdscr_el1;
-    uint64_t par_el1;
-    algn32_t sctlr_el1;
-    uint64_t sp_el1;
-    algn32_t spsr_el1;
-    uint64_t tcr_el1;
-    uint64_t tpidr_el1;
-    uint64_t ttbr0_el1;
-    uint64_t ttbr1_el1;
-    uint64_t vbar_el1;
-
-    uint64_t elr_el2;
-    algn32_t spsr_el2;
-    uint64_t vmpidr_el2;
-};
-
-struct GuestState {
-    uint64_t x[GS_NUM_REGS];
-    FpState fp_state;
-    SystemState system_state;
-
-    // Exit state.
-    algn32_t cntv_ctl_el0;
-    uint64_t cntv_cval_el0;
-    algn32_t esr_el2;
-    uint64_t far_el2;
-    uint64_t hpfar_el2;
-};
-
-struct HostState {
-    // We only save X18 to X30 from the host, as the host is making an explicit
-    // call into the hypervisor, and therefore is saving the rest of its state.
-    uint64_t x[HS_NUM_REGS];
-    FpState fp_state;
-    SystemState system_state;
-};
-
-struct IchState {
-    uint8_t num_aprs;
-    uint8_t num_lrs;
-    algn32_t vmcr;
-    algn32_t misr;
-    uint64_t elrsr;
-    uint64_t apr[IS_MAX_APR_GROUPS][IS_MAX_APRS];
-    uint64_t lr[IS_MAX_LRS];
-};
-
-struct El2State {
-    bool resume;
-    GuestState guest_state;
-    HostState host_state;
-    IchState ich_state;
-};
-
-static_assert(sizeof(El2State) <= PAGE_SIZE);
-
-static_assert(offsetof(FpState, q) == FS_Q0);
-static_assert(offsetof(FpState, q[FS_NUM_REGS - 1]) == FS_Q(FS_NUM_REGS - 1));
-static_assert(offsetof(FpState, fpsr) == FS_FPSR);
-static_assert(offsetof(FpState, fpcr) == FS_FPCR);
-
-static_assert(offsetof(SystemState, sp_el0) == SS_SP_EL0);
-static_assert(offsetof(SystemState, tpidr_el0) == SS_TPIDR_EL0);
-static_assert(offsetof(SystemState, tpidrro_el0) == SS_TPIDRRO_EL0);
-static_assert(offsetof(SystemState, cntkctl_el1) == SS_CNTKCTL_EL1);
-static_assert(offsetof(SystemState, contextidr_el1) == SS_CONTEXTIDR_EL1);
-static_assert(offsetof(SystemState, cpacr_el1) == SS_CPACR_EL1);
-static_assert(offsetof(SystemState, csselr_el1) == SS_CSSELR_EL1);
-static_assert(offsetof(SystemState, elr_el1) == SS_ELR_EL1);
-static_assert(offsetof(SystemState, esr_el1) == SS_ESR_EL1);
-static_assert(offsetof(SystemState, far_el1) == SS_FAR_EL1);
-static_assert(offsetof(SystemState, mair_el1) == SS_MAIR_EL1);
-static_assert(offsetof(SystemState, mdscr_el1) == SS_MDSCR_EL1);
-static_assert(offsetof(SystemState, par_el1) == SS_PAR_EL1);
-static_assert(offsetof(SystemState, sctlr_el1) == SS_SCTLR_EL1);
-static_assert(offsetof(SystemState, sp_el1) == SS_SP_EL1);
-static_assert(offsetof(SystemState, spsr_el1) == SS_SPSR_EL1);
-static_assert(offsetof(SystemState, tcr_el1) == SS_TCR_EL1);
-static_assert(offsetof(SystemState, tpidr_el1) == SS_TPIDR_EL1);
-static_assert(offsetof(SystemState, ttbr0_el1) == SS_TTBR0_EL1);
-static_assert(offsetof(SystemState, ttbr1_el1) == SS_TTBR1_EL1);
-static_assert(offsetof(SystemState, vbar_el1) == SS_VBAR_EL1);
-static_assert(offsetof(SystemState, elr_el2) == SS_ELR_EL2);
-static_assert(offsetof(SystemState, spsr_el2) == SS_SPSR_EL2);
-static_assert(offsetof(SystemState, vmpidr_el2) == SS_VMPIDR_EL2);
-
-static_assert(offsetof(El2State, resume) == ES_RESUME);
-
-static_assert(offsetof(El2State, guest_state.x) == GS_X0);
-static_assert(offsetof(El2State, guest_state.x[GS_NUM_REGS - 1]) == GS_X(GS_NUM_REGS - 1));
-static_assert(offsetof(El2State, guest_state.fp_state) == GS_FP_STATE);
-static_assert(offsetof(El2State, guest_state.fp_state.q) == GS_FP_STATE + FS_Q0);
-static_assert(offsetof(El2State, guest_state.system_state) == GS_SYSTEM_STATE);
-static_assert(offsetof(El2State, guest_state.cntv_ctl_el0) == GS_CNTV_CTL_EL0);
-static_assert(offsetof(El2State, guest_state.cntv_cval_el0) == GS_CNTV_CVAL_EL0);
-static_assert(offsetof(El2State, guest_state.esr_el2) == GS_ESR_EL2);
-static_assert(offsetof(El2State, guest_state.far_el2) == GS_FAR_EL2);
-static_assert(offsetof(El2State, guest_state.hpfar_el2) == GS_HPFAR_EL2);
-
-static_assert(offsetof(El2State, host_state.x) == HS_X18);
-static_assert(offsetof(El2State, host_state.x[HS_NUM_REGS - 1]) == HS_X18 + HS_X(HS_NUM_REGS - 1));
-static_assert(offsetof(El2State, host_state.fp_state) == HS_FP_STATE);
-static_assert(offsetof(El2State, host_state.fp_state.q) == HS_FP_STATE + FS_Q0);
-static_assert(offsetof(El2State, host_state.system_state) == HS_SYSTEM_STATE);
-
-static_assert(offsetof(IchState, num_aprs) == IS_NUM_APRS);
-static_assert(offsetof(IchState, num_lrs) == IS_NUM_LRS);
-static_assert(offsetof(IchState, vmcr) == IS_VMCR);
-static_assert(offsetof(IchState, misr) == IS_MISR);
-static_assert(offsetof(IchState, elrsr) == IS_ELRSR);
-static_assert(offsetof(IchState, apr) == IS_AP0R0);
-static_assert(offsetof(IchState, apr[IS_MAX_APR_GROUPS - 1][IS_MAX_APRS - 1]) ==
-    IS_APR(IS_MAX_APR_GROUPS - 1, IS_MAX_APRS - 1));
-static_assert(offsetof(IchState, lr) == IS_LR0);
-static_assert(offsetof(IchState, lr[IS_MAX_LRS - 1]) == IS_LR(IS_MAX_LRS - 1));
-
-__BEGIN_CDECLS
-
-extern zx_status_t arm64_el2_on(zx_paddr_t ttbr0, zx_paddr_t stack_top);
-extern zx_status_t arm64_el2_off();
-extern zx_status_t arm64_el2_tlbi_ipa(zx_paddr_t vttbr, zx_vaddr_t addr, bool terminal);
-extern zx_status_t arm64_el2_tlbi_vmid(zx_paddr_t vttbr);
-extern zx_status_t arm64_el2_resume(zx_paddr_t vttbr, zx_paddr_t state, uint64_t hcr);
-
-__END_CDECLS
-
-#endif // __ASSEMBLER__
diff --git a/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/el2.h b/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/el2.h
deleted file mode 100644
index fd999db..0000000
--- a/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/el2.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-extern void arm64_el2_gicv3_read_gich_state(zx_paddr_t state);
-extern void arm64_el2_gicv3_write_gich_state(zx_paddr_t state, uint32_t hcr);
-extern uint32_t arm64_el2_gicv3_read_gich_vtr();
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/gicv2.h b/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/gicv2.h
deleted file mode 100644
index 0474eb0..0000000
--- a/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/gicv2.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// clang-format off
-
-#define GICH_LR_VIRTUAL_ID(id)  (id & 0x3ff)
-#define GICH_LR_PHYSICAL_ID(id) ((id & 0x3ff) << 10)
-#define GICH_LR_PRIORITY(prio)  ((prio & 0x1f) << 23)
-#define GICH_LR_PENDING         (1u << 28)
-#define GICH_LR_GROUP1          (1u << 30)
-#define GICH_LR_HARDWARE        (1u << 31)
-#define GICH_VMCR_VENG0         (1u << 0)
-#define GICH_VMCR_VPMR          (0x1fu << 27)
-#define GICH_VTR_PRES(vtr)      (((vtr & (0x7u << 26)) >> 26) + 1)
-#define GICH_VTR_LRS(vtr)       ((vtr & 0x3fu) + 1)
-
-// clang-format on
-
-void gicv2_hw_interface_register();
diff --git a/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/gicv3.h b/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/gicv3.h
deleted file mode 100644
index e168272..0000000
--- a/kernel/arch/arm64/include/arch/arm64/hypervisor/gic/gicv3.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// clang-format off
-
-#define ICH_LR_VIRTUAL_ID(id)   (id & UINT32_MAX)
-#define ICH_LR_PHYSICAL_ID(id)  ((id & 0x3fful) << 32)
-#define ICH_LR_PRIORITY(prio)   ((prio & 0xfful) << 48)
-#define ICH_LR_GROUP1           (1ul << 60)
-#define ICH_LR_HARDWARE         (1ul << 61)
-#define ICH_LR_PENDING          (1ul << 62)
-#define ICH_VMCR_VENG1          (1u << 1)
-#define ICH_VMCR_VFIQEN         (1u << 3)
-#define ICH_VMCR_VPMR           (0xffu << 24)
-#define ICH_VTR_PRES(vtr)       (((vtr & (0x7u << 26)) >> 26) + 1)
-#define ICH_VTR_LRS(vtr)        ((vtr & 0x1fu) + 1)
-
-// clang-format on
-
-void gicv3_hw_interface_register();
diff --git a/kernel/arch/arm64/include/arch/arm64/interrupt.h b/kernel/arch/arm64/include/arch/arm64/interrupt.h
deleted file mode 100644
index 0e799fc..0000000
--- a/kernel/arch/arm64/include/arch/arm64/interrupt.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#ifndef __ASSEMBLER__
-
-#include <kernel/atomic.h>
-
-__BEGIN_CDECLS
-
-// override of some routines
-static inline void arch_enable_ints(void) {
-    atomic_signal_fence();
-    __asm__ volatile("msr daifclr, #2" ::
-                         : "memory");
-}
-
-static inline void arch_disable_ints(void) {
-    __asm__ volatile("msr daifset, #2" ::
-                         : "memory");
-    atomic_signal_fence();
-}
-
-static inline bool arch_ints_disabled(void) {
-    unsigned long state;
-
-    __asm__ volatile("mrs %0, daif"
-                     : "=r"(state));
-    state &= (1 << 7);
-
-    return !!state;
-}
-
-static inline void arch_enable_fiqs(void) {
-    atomic_signal_fence();
-    __asm__ volatile("msr daifclr, #1" ::
-                         : "memory");
-}
-
-static inline void arch_disable_fiqs(void) {
-    __asm__ volatile("msr daifset, #1" ::
-                         : "memory");
-    atomic_signal_fence();
-}
-
-// XXX
-static inline bool arch_fiqs_disabled(void) {
-    unsigned long state;
-
-    __asm__ volatile("mrs %0, daif"
-                     : "=r"(state));
-    state &= (1 << 6);
-
-    return !!state;
-}
-
-__END_CDECLS
-
-#endif // __ASSEMBLER__
diff --git a/kernel/arch/arm64/include/arch/arm64/mmu.h b/kernel/arch/arm64/include/arch/arm64/mmu.h
deleted file mode 100644
index 62689e6..0000000
--- a/kernel/arch/arm64/include/arch/arm64/mmu.h
+++ /dev/null
@@ -1,417 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Google Inc. All rights reserved
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/defines.h>
-
-// clang-format off
-#define IFTE(c,t,e) (!!(c) * (t) | !(c) * (e))
-#define NBITS01(n)      IFTE(n, 1, 0)
-#define NBITS02(n)      IFTE((n) >>  1,  1 + NBITS01((n) >>  1), NBITS01(n))
-#define NBITS04(n)      IFTE((n) >>  2,  2 + NBITS02((n) >>  2), NBITS02(n))
-#define NBITS08(n)      IFTE((n) >>  4,  4 + NBITS04((n) >>  4), NBITS04(n))
-#define NBITS16(n)      IFTE((n) >>  8,  8 + NBITS08((n) >>  8), NBITS08(n))
-#define NBITS32(n)      IFTE((n) >> 16, 16 + NBITS16((n) >> 16), NBITS16(n))
-#define NBITS(n)        IFTE((n) >> 32, 32 + NBITS32((n) >> 32), NBITS32(n))
-
-#ifndef MMU_KERNEL_SIZE_SHIFT
-#define KERNEL_ASPACE_BITS (NBITS(0xffffffffffffffff-KERNEL_ASPACE_BASE))
-
-#if KERNEL_ASPACE_BITS < 25
-#define MMU_KERNEL_SIZE_SHIFT (25)
-#else
-#define MMU_KERNEL_SIZE_SHIFT (KERNEL_ASPACE_BITS)
-#endif
-#endif
-
-#ifndef MMU_USER_SIZE_SHIFT
-#define MMU_USER_SIZE_SHIFT 48
-#endif
-
-#ifndef MMU_IDENT_SIZE_SHIFT
-#define MMU_IDENT_SIZE_SHIFT 42 /* Max size supported by block mappings */
-#endif
-
-// See ARM DDI 0487B.b, Table D4-25 for the maximum IPA range that can be used.
-// This size is based on a 4KB granule and a starting level of 1. We chose this
-// size due to the 40-bit physical address range on Cortex-A53.
-#define MMU_GUEST_SIZE_SHIFT 36
-
-#define MMU_MAX_PAGE_SIZE_SHIFT 48
-
-#define MMU_KERNEL_PAGE_SIZE_SHIFT      (PAGE_SIZE_SHIFT)
-#define MMU_USER_PAGE_SIZE_SHIFT        (USER_PAGE_SIZE_SHIFT)
-#define MMU_GUEST_PAGE_SIZE_SHIFT       (USER_PAGE_SIZE_SHIFT)
-
-#if MMU_IDENT_SIZE_SHIFT < 25
-#error MMU_IDENT_SIZE_SHIFT too small
-#elif MMU_IDENT_SIZE_SHIFT <= 29 /* Use 2MB block mappings (4K page size) */
-#define MMU_IDENT_PAGE_SIZE_SHIFT       (SHIFT_4K)
-#elif MMU_IDENT_SIZE_SHIFT <= 30 /* Use 512MB block mappings (64K page size) */
-#define MMU_IDENT_PAGE_SIZE_SHIFT       (SHIFT_64K)
-#elif MMU_IDENT_SIZE_SHIFT <= 39 /* Use 1GB block mappings (4K page size) */
-#define MMU_IDENT_PAGE_SIZE_SHIFT       (SHIFT_4K)
-#elif MMU_IDENT_SIZE_SHIFT <= 42 /* Use 512MB block mappings (64K page size) */
-#define MMU_IDENT_PAGE_SIZE_SHIFT       (SHIFT_64K)
-#else
-#error MMU_IDENT_SIZE_SHIFT too large
-#endif
-
-/*
- * TCR TGx values
- *
- * Page size:   4K      16K     64K
- * TG0:         0       2       1
- * TG1:         2       1       3
- */
-
-#define MMU_TG0(page_size_shift) ((((page_size_shift == 14) & 1) << 1) | \
-                                  ((page_size_shift == 16) & 1))
-
-#define MMU_TG1(page_size_shift) ((((page_size_shift == 12) & 1) << 1) | \
-                                  ((page_size_shift == 14) & 1) | \
-                                  ((page_size_shift == 16) & 1) | \
-                                  (((page_size_shift == 16) & 1) << 1))
-
-#define MMU_LX_X(page_shift, level) ((4 - (level)) * ((page_shift) - 3) + 3)
-
-#if MMU_USER_SIZE_SHIFT > MMU_LX_X(MMU_USER_PAGE_SIZE_SHIFT, 0)
-#define MMU_USER_TOP_SHIFT MMU_LX_X(MMU_USER_PAGE_SIZE_SHIFT, 0)
-#elif MMU_USER_SIZE_SHIFT > MMU_LX_X(MMU_USER_PAGE_SIZE_SHIFT, 1)
-#define MMU_USER_TOP_SHIFT MMU_LX_X(MMU_USER_PAGE_SIZE_SHIFT, 1)
-#elif MMU_USER_SIZE_SHIFT > MMU_LX_X(MMU_USER_PAGE_SIZE_SHIFT, 2)
-#define MMU_USER_TOP_SHIFT MMU_LX_X(MMU_USER_PAGE_SIZE_SHIFT, 2)
-#elif MMU_USER_SIZE_SHIFT > MMU_LX_X(MMU_USER_PAGE_SIZE_SHIFT, 3)
-#define MMU_USER_TOP_SHIFT MMU_LX_X(MMU_USER_PAGE_SIZE_SHIFT, 3)
-#else
-#error User address space size must be larger than page size
-#endif
-#define MMU_USER_PAGE_TABLE_ENTRIES_TOP (0x1 << (MMU_USER_SIZE_SHIFT - MMU_USER_TOP_SHIFT))
-#define MMU_USER_PAGE_TABLE_ENTRIES (0x1 << (MMU_USER_PAGE_SIZE_SHIFT - 3))
-
-#if MMU_KERNEL_SIZE_SHIFT > MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 0)
-#define MMU_KERNEL_TOP_SHIFT MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 0)
-#elif MMU_KERNEL_SIZE_SHIFT > MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 1)
-#define MMU_KERNEL_TOP_SHIFT MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 1)
-#elif MMU_KERNEL_SIZE_SHIFT > MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 2)
-#define MMU_KERNEL_TOP_SHIFT MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 2)
-#elif MMU_KERNEL_SIZE_SHIFT > MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 3)
-#define MMU_KERNEL_TOP_SHIFT MMU_LX_X(MMU_KERNEL_PAGE_SIZE_SHIFT, 3)
-#else
-#error Kernel address space size must be larger than page size
-#endif
-#define MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP (0x1 << (MMU_KERNEL_SIZE_SHIFT - MMU_KERNEL_TOP_SHIFT))
-#define MMU_KERNEL_PAGE_TABLE_ENTRIES (0x1 << (MMU_KERNEL_PAGE_SIZE_SHIFT - 3))
-
-#if MMU_IDENT_SIZE_SHIFT > MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 0)
-#define MMU_IDENT_TOP_SHIFT MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 0)
-#elif MMU_IDENT_SIZE_SHIFT > MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 1)
-#define MMU_IDENT_TOP_SHIFT MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 1)
-#elif MMU_IDENT_SIZE_SHIFT > MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 2)
-#define MMU_IDENT_TOP_SHIFT MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 2)
-#elif MMU_IDENT_SIZE_SHIFT > MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 3)
-#define MMU_IDENT_TOP_SHIFT MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 3)
-#else
-#error Ident address space size must be larger than page size
-#endif
-#define MMU_PAGE_TABLE_ENTRIES_IDENT_SHIFT (MMU_IDENT_SIZE_SHIFT - MMU_IDENT_TOP_SHIFT)
-#define MMU_PAGE_TABLE_ENTRIES_IDENT (0x1 << MMU_PAGE_TABLE_ENTRIES_IDENT_SHIFT)
-
-#if MMU_GUEST_SIZE_SHIFT > MMU_LX_X(MMU_GUEST_PAGE_SIZE_SHIFT, 0)
-#define MMU_GUEST_TOP_SHIFT MMU_LX_X(MMU_GUEST_PAGE_SIZE_SHIFT, 0)
-#elif MMU_GUEST_SIZE_SHIFT > MMU_LX_X(MMU_GUEST_PAGE_SIZE_SHIFT, 1)
-#define MMU_GUEST_TOP_SHIFT MMU_LX_X(MMU_GUEST_PAGE_SIZE_SHIFT, 1)
-#elif MMU_GUEST_SIZE_SHIFT > MMU_LX_X(MMU_GUEST_PAGE_SIZE_SHIFT, 2)
-#define MMU_GUEST_TOP_SHIFT MMU_LX_X(MMU_GUEST_PAGE_SIZE_SHIFT, 2)
-#elif MMU_GUEST_SIZE_SHIFT > MMU_LX_X(MMU_GUEST_PAGE_SIZE_SHIFT, 3)
-#define MMU_GUEST_TOP_SHIFT MMU_LX_X(MMU_GUEST_PAGE_SIZE_SHIFT, 3)
-#else
-#error Guest physical address space size must be larger than page size
-#endif
-#define MMU_GUEST_PAGE_TABLE_ENTRIES_TOP (0x1 << (MMU_GUEST_SIZE_SHIFT - MMU_GUEST_TOP_SHIFT))
-#define MMU_GUEST_PAGE_TABLE_ENTRIES (0x1 << (MMU_GUEST_PAGE_SIZE_SHIFT - 3))
-
-#define MMU_PTE_DESCRIPTOR_BLOCK_MAX_SHIFT      (30)
-
-#ifndef __ASSEMBLER__
-#define BM(base, count, val) (((val) & ((1UL << (count)) - 1)) << (base))
-#else
-#define BM(base, count, val) (((val) & ((0x1 << (count)) - 1)) << (base))
-#endif
-
-#define MMU_SH_NON_SHAREABLE                    (0)
-#define MMU_SH_OUTER_SHAREABLE                  (2)
-#define MMU_SH_INNER_SHAREABLE                  (3)
-
-#define MMU_RGN_NON_CACHEABLE                   (0)
-#define MMU_RGN_WRITE_BACK_ALLOCATE             (1)
-#define MMU_RGN_WRITE_THROUGH_NO_ALLOCATE       (2)
-#define MMU_RGN_WRITE_BACK_NO_ALLOCATE          (3)
-
-#define MMU_TCR_TBI1                            BM(38, 1, 1)
-#define MMU_TCR_TBI0                            BM(37, 1, 1)
-#define MMU_TCR_AS                              BM(36, 1, 1)
-#define MMU_TCR_IPS(size)                       BM(32, 3, (size))
-#define MMU_TCR_TG1(granule_size)               BM(30, 2, (granule_size))
-#define MMU_TCR_SH1(shareability_flags)         BM(28, 2, (shareability_flags))
-#define MMU_TCR_ORGN1(cache_flags)              BM(26, 2, (cache_flags))
-#define MMU_TCR_IRGN1(cache_flags)              BM(24, 2, (cache_flags))
-#define MMU_TCR_EPD1                            BM(23, 1, 1)
-#define MMU_TCR_A1                              BM(22, 1, 1)
-#define MMU_TCR_T1SZ(size)                      BM(16, 6, (size))
-#define MMU_TCR_TG0(granule_size)               BM(14, 2, (granule_size))
-#define MMU_TCR_SH0(shareability_flags)         BM(12, 2, (shareability_flags))
-#define MMU_TCR_ORGN0(cache_flags)              BM(10, 2, (cache_flags))
-#define MMU_TCR_IRGN0(cache_flags)              BM( 8, 2, (cache_flags))
-#define MMU_TCR_EPD0                            BM( 7, 1, 1)
-#define MMU_TCR_T0SZ(size)                      BM( 0, 6, (size))
-
-#define MMU_TCR_EL2_RES1                        (BM(31, 1, 1) | BM(23, 1, 1))
-
-#define MMU_VTCR_EL2_RES1                       BM(31, 1, 1)
-#define MMU_VTCR_EL2_SL0(starting_level)        BM( 6, 2, (starting_level))
-
-#define MMU_MAIR_ATTR(index, attr)              BM(index * 8, 8, (attr))
-
-
-/* L0/L1/L2/L3 descriptor types */
-#define MMU_PTE_DESCRIPTOR_INVALID              BM(0, 2, 0)
-#define MMU_PTE_DESCRIPTOR_MASK                 BM(0, 2, 3)
-
-/* L0/L1/L2 descriptor types */
-#define MMU_PTE_L012_DESCRIPTOR_BLOCK           BM(0, 2, 1)
-#define MMU_PTE_L012_DESCRIPTOR_TABLE           BM(0, 2, 3)
-
-/* L3 descriptor types */
-#define MMU_PTE_L3_DESCRIPTOR_PAGE              BM(0, 2, 3)
-
-/* Output address mask */
-#define MMU_PTE_OUTPUT_ADDR_MASK                BM(12, 36, 0xfffffffff)
-
-/* Table attrs */
-#define MMU_PTE_ATTR_NS_TABLE                   BM(63, 1, 1)
-#define MMU_PTE_ATTR_AP_TABLE_NO_WRITE          BM(62, 1, 1)
-#define MMU_PTE_ATTR_AP_TABLE_NO_EL0            BM(61, 1, 1)
-#define MMU_PTE_ATTR_UXN_TABLE                  BM(60, 1, 1)
-#define MMU_PTE_ATTR_PXN_TABLE                  BM(59, 1, 1)
-
-/* Block/Page attrs */
-#define MMU_PTE_ATTR_RES_SOFTWARE               BM(55, 4, 0xf)
-#define MMU_PTE_ATTR_UXN                        BM(54, 1, 1)
-#define MMU_PTE_ATTR_PXN                        BM(53, 1, 1)
-#define MMU_PTE_ATTR_CONTIGUOUS                 BM(52, 1, 1)
-
-#define MMU_PTE_ATTR_NON_GLOBAL                 BM(11, 1, 1)
-#define MMU_PTE_ATTR_AF                         BM(10, 1, 1)
-
-#define MMU_PTE_ATTR_SH_NON_SHAREABLE           BM(8, 2, 0)
-#define MMU_PTE_ATTR_SH_OUTER_SHAREABLE         BM(8, 2, 2)
-#define MMU_PTE_ATTR_SH_INNER_SHAREABLE         BM(8, 2, 3)
-
-#define MMU_PTE_ATTR_AP_P_RW_U_NA               BM(6, 2, 0)
-#define MMU_PTE_ATTR_AP_P_RW_U_RW               BM(6, 2, 1)
-#define MMU_PTE_ATTR_AP_P_RO_U_NA               BM(6, 2, 2)
-#define MMU_PTE_ATTR_AP_P_RO_U_RO               BM(6, 2, 3)
-#define MMU_PTE_ATTR_AP_MASK                    BM(6, 2, 3)
-
-#define MMU_PTE_ATTR_NON_SECURE                 BM(5, 1, 1)
-
-#define MMU_PTE_ATTR_ATTR_INDEX(attrindex)      BM(2, 3, attrindex)
-#define MMU_PTE_ATTR_ATTR_INDEX_MASK            MMU_PTE_ATTR_ATTR_INDEX(7)
-
-#define MMU_PTE_PERMISSION_MASK                 (MMU_PTE_ATTR_AP_MASK | \
-                                                 MMU_PTE_ATTR_UXN | \
-                                                 MMU_PTE_ATTR_PXN)
-
-#define MMU_S2_PTE_ATTR_XN                      BM(53, 2, 2)
-
-#define MMU_S2_PTE_ATTR_S2AP_RO                 BM(6, 2, 1)
-#define MMU_S2_PTE_ATTR_S2AP_RW                 BM(6, 2, 3)
-
-#define MMU_S2_PTE_ATTR_ATTR_INDEX_MASK         BM(2, 4, 0xf)
-/* Normal, Outer Write-Back Cacheable, Inner Write-Back Cacheable. */
-#define MMU_S2_PTE_ATTR_NORMAL_MEMORY           BM(2, 4, 0xf)
-/* Normal, Outer Non-cacheable, Inner Non-cacheable. */
-#define MMU_S2_PTE_ATTR_NORMAL_UNCACHED         BM(2, 4, 0x5)
-/* Device, Device-nGnRnE memory. */
-#define MMU_S2_PTE_ATTR_STRONGLY_ORDERED        BM(2, 4, 0x0)
-/* Device, Device-nGnRE memory. */
-#define MMU_S2_PTE_ATTR_DEVICE                  BM(2, 4, 0x1)
-
-/* Default configuration for main kernel page table:
- *    - do cached translation walks
- */
-
-/* Device-nGnRnE memory */
-#define MMU_MAIR_ATTR0                  MMU_MAIR_ATTR(0, 0x00)
-#define MMU_PTE_ATTR_STRONGLY_ORDERED   MMU_PTE_ATTR_ATTR_INDEX(0)
-
-/* Device-nGnRE memory */
-#define MMU_MAIR_ATTR1                  MMU_MAIR_ATTR(1, 0x04)
-#define MMU_PTE_ATTR_DEVICE             MMU_PTE_ATTR_ATTR_INDEX(1)
-
-/* Normal Memory, Outer Write-back non-transient Read/Write allocate,
- * Inner Write-back non-transient Read/Write allocate
- */
-#define MMU_MAIR_ATTR2                  MMU_MAIR_ATTR(2, 0xff)
-#define MMU_PTE_ATTR_NORMAL_MEMORY      MMU_PTE_ATTR_ATTR_INDEX(2)
-
-/* Normal Memory, Inner/Outer uncached, Write Combined */
-#define MMU_MAIR_ATTR3                  MMU_MAIR_ATTR(3, 0x44)
-#define MMU_PTE_ATTR_NORMAL_UNCACHED    MMU_PTE_ATTR_ATTR_INDEX(3)
-
-#define MMU_MAIR_ATTR4                  (0)
-#define MMU_MAIR_ATTR5                  (0)
-#define MMU_MAIR_ATTR6                  (0)
-#define MMU_MAIR_ATTR7                  (0)
-
-#define MMU_MAIR_VAL                    (MMU_MAIR_ATTR0 | MMU_MAIR_ATTR1 | \
-                                         MMU_MAIR_ATTR2 | MMU_MAIR_ATTR3 | \
-                                         MMU_MAIR_ATTR4 | MMU_MAIR_ATTR5 | \
-                                         MMU_MAIR_ATTR6 | MMU_MAIR_ATTR7 )
-
-#define MMU_TCR_IPS_DEFAULT MMU_TCR_IPS(2) /* TODO: read at runtime, or configure per platform */
-
-/* Enable cached page table walks:
- * inner/outer (IRGN/ORGN): write-back + write-allocate
- */
-#define MMU_TCR_FLAGS1 (MMU_TCR_TG1(MMU_TG1(MMU_KERNEL_PAGE_SIZE_SHIFT)) | \
-                        MMU_TCR_SH1(MMU_SH_INNER_SHAREABLE) | \
-                        MMU_TCR_ORGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \
-                        MMU_TCR_IRGN1(MMU_RGN_WRITE_BACK_ALLOCATE) | \
-                        MMU_TCR_T1SZ(64 - MMU_KERNEL_SIZE_SHIFT))
-#define MMU_TCR_FLAGS0 (MMU_TCR_TG0(MMU_TG0(MMU_USER_PAGE_SIZE_SHIFT)) | \
-                        MMU_TCR_SH0(MMU_SH_INNER_SHAREABLE) | \
-                        MMU_TCR_ORGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
-                        MMU_TCR_IRGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
-                        MMU_TCR_T0SZ(64 - MMU_USER_SIZE_SHIFT))
-#define MMU_TCR_FLAGS0_IDENT \
-                       (MMU_TCR_TG0(MMU_TG0(MMU_IDENT_PAGE_SIZE_SHIFT)) | \
-                        MMU_TCR_SH0(MMU_SH_INNER_SHAREABLE) | \
-                        MMU_TCR_ORGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
-                        MMU_TCR_IRGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
-                        MMU_TCR_T0SZ(64 - MMU_IDENT_SIZE_SHIFT))
-#define MMU_TCR_FLAGS_IDENT (MMU_TCR_IPS_DEFAULT | MMU_TCR_FLAGS1 | \
-                        MMU_TCR_FLAGS0_IDENT | MMU_TCR_AS | MMU_TCR_A1)
-
-#define MMU_TCR_FLAGS_KERNEL (MMU_TCR_IPS_DEFAULT | \
-                              MMU_TCR_FLAGS1 | \
-                              MMU_TCR_FLAGS0 | \
-                              MMU_TCR_EPD0 | \
-                              MMU_TCR_AS | \
-                              MMU_TCR_A1)
-
-#define MMU_TCR_FLAGS_USER (MMU_TCR_IPS_DEFAULT | \
-                            MMU_TCR_FLAGS1 | \
-                            MMU_TCR_FLAGS0 | \
-                            MMU_TCR_AS)
-
-#define MMU_VTCR_FLAGS_GUEST \
-                       (MMU_TCR_TG0(MMU_TG0(MMU_GUEST_PAGE_SIZE_SHIFT)) | \
-                        MMU_TCR_SH0(MMU_SH_INNER_SHAREABLE) | \
-                        MMU_TCR_ORGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
-                        MMU_TCR_IRGN0(MMU_RGN_WRITE_BACK_ALLOCATE) | \
-                        MMU_TCR_T0SZ(64 - MMU_GUEST_SIZE_SHIFT))
-
-#define MMU_TCR_EL2_FLAGS (MMU_TCR_EL2_RES1 | MMU_TCR_FLAGS0)
-
-// See ARM DDI 0487B.b, Table D4-7 for details on how to configure SL0. We chose
-// a starting level of 1, due to our use of a 4KB granule and a 40-bit PARange.
-#define MMU_VTCR_EL2_SL0_DEFAULT MMU_VTCR_EL2_SL0(1)
-
-// NOTE(abdulla): VTCR_EL2.PS still must be set, based upon ID_AA64MMFR0_EL1.
-// Furthermore, this only covers what's required by ARMv8.0.
-#define MMU_VTCR_EL2_FLAGS (MMU_VTCR_EL2_RES1 | MMU_VTCR_EL2_SL0_DEFAULT | MMU_VTCR_FLAGS_GUEST)
-
-#define MMU_PTE_KERNEL_RWX_FLAGS \
-    (MMU_PTE_ATTR_AF | \
-     MMU_PTE_ATTR_SH_INNER_SHAREABLE | \
-     MMU_PTE_ATTR_NORMAL_MEMORY | \
-     MMU_PTE_ATTR_AP_P_RW_U_NA)
-
-#define MMU_PTE_KERNEL_RO_FLAGS \
-    (MMU_PTE_ATTR_UXN | \
-     MMU_PTE_ATTR_AF | \
-     MMU_PTE_ATTR_SH_INNER_SHAREABLE | \
-     MMU_PTE_ATTR_NORMAL_MEMORY | \
-     MMU_PTE_ATTR_AP_P_RO_U_NA)
-
-#define MMU_PTE_KERNEL_DATA_FLAGS \
-    (MMU_PTE_ATTR_UXN | \
-     MMU_PTE_ATTR_PXN | \
-     MMU_PTE_ATTR_AF | \
-     MMU_PTE_ATTR_SH_INNER_SHAREABLE | \
-     MMU_PTE_ATTR_NORMAL_MEMORY | \
-     MMU_PTE_ATTR_AP_P_RW_U_NA)
-
-#define MMU_INITIAL_MAP_STRONGLY_ORDERED \
-    (MMU_PTE_ATTR_UXN | \
-     MMU_PTE_ATTR_PXN | \
-     MMU_PTE_ATTR_AF | \
-     MMU_PTE_ATTR_STRONGLY_ORDERED | \
-     MMU_PTE_ATTR_AP_P_RW_U_NA)
-
-#define MMU_INITIAL_MAP_DEVICE \
-    (MMU_PTE_ATTR_UXN | \
-     MMU_PTE_ATTR_PXN | \
-     MMU_PTE_ATTR_AF | \
-     MMU_PTE_ATTR_DEVICE | \
-     MMU_PTE_ATTR_AP_P_RW_U_NA)
-
-#if MMU_IDENT_SIZE_SHIFT > MMU_LX_X(MMU_IDENT_PAGE_SIZE_SHIFT, 2)
-#define MMU_PTE_IDENT_DESCRIPTOR MMU_PTE_L012_DESCRIPTOR_BLOCK
-#else
-#define MMU_PTE_IDENT_DESCRIPTOR MMU_PTE_L3_DESCRIPTOR_PAGE
-#endif
-#define MMU_PTE_IDENT_FLAGS \
-    (MMU_PTE_IDENT_DESCRIPTOR | \
-     MMU_PTE_KERNEL_RWX_FLAGS)
-// clang-format on
-
-#ifndef __ASSEMBLER__
-
-#include <sys/types.h>
-#include <assert.h>
-#include <zircon/compiler.h>
-#include <arch/arm64.h>
-
-typedef uint64_t pte_t;
-
-__BEGIN_CDECLS
-
-#define ARM64_TLBI_NOADDR(op)            \
-    ({                                   \
-        __asm__ volatile("tlbi " #op::); \
-        __isb(ARM_MB_SY);                             \
-    })
-
-#define ARM64_TLBI(op, val)                                          \
-    ({                                                               \
-        __asm__ volatile("tlbi " #op ", %0" ::"r"((uint64_t)(val))); \
-        __isb(ARM_MB_SY);                                                         \
-    })
-
-const size_t MMU_ARM64_ASID_BITS = 16;
-const uint16_t MMU_ARM64_GLOBAL_ASID = (1u << MMU_ARM64_ASID_BITS) - 1;
-const uint16_t MMU_ARM64_UNUSED_ASID = 0;
-const uint16_t MMU_ARM64_FIRST_USER_ASID = 1;
-const uint16_t MMU_ARM64_MAX_USER_ASID = MMU_ARM64_GLOBAL_ASID - 1;
-
-pte_t* arm64_get_kernel_ptable();
-
-zx_status_t arm64_boot_map_v(const vaddr_t vaddr,
-                             const paddr_t paddr,
-                             const size_t len,
-                             const pte_t flags);
-
-// use built-in virtual to physical translation instructions to query
-// the physical address of a virtual address
-zx_status_t arm64_mmu_translate(vaddr_t va, paddr_t* pa, bool user, bool write);
-
-__END_CDECLS
-#endif /* __ASSEMBLER__ */
diff --git a/kernel/arch/arm64/include/arch/arm64/mp.h b/kernel/arch/arm64/include/arch/arm64/mp.h
deleted file mode 100644
index 27a78e7..0000000
--- a/kernel/arch/arm64/include/arch/arm64/mp.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/arm64.h>
-#include <kernel/align.h>
-#include <kernel/cpu.h>
-#include <reg.h>
-#include <zircon/compiler.h>
-
-__BEGIN_CDECLS
-
-// bits for mpidr register
-#define MPIDR_AFF0_MASK 0xFFULL
-#define MPIDR_AFF0_SHIFT 0
-#define MPIDR_AFF1_MASK (0xFFULL << 8)
-#define MPIDR_AFF1_SHIFT 8
-#define MPIDR_AFF2_MASK (0xFFULL << 16)
-#define MPIDR_AFF2_SHIFT 16
-#define MPIDR_AFF3_MASK (0xFFULL << 32)
-#define MPIDR_AFF3_SHIFT 32
-
-// construct a ARM MPID from cluster (AFF1) and cpu number (AFF0)
-#define ARM64_MPID(cluster, cpu) (((cluster << MPIDR_AFF1_SHIFT) & MPIDR_AFF1_MASK) | \
-                                  ((cpu << MPIDR_AFF0_SHIFT) & MPIDR_AFF0_MASK))
-
-// TODO: add support for AFF2 and AFF3
-
-// Per cpu structure, pointed to by x18 while in kernel mode.
-// Aligned on the maximum architectural cache line to avoid cache
-// line sharing between cpus.
-struct arm64_percpu {
-    // cpu number
-    uint32_t cpu_num;
-
-    // Whether blocking is disallowed.  See arch_blocking_disallowed().
-    uint32_t blocking_disallowed;
-} __CPU_ALIGN;
-
-void arch_init_cpu_map(uint cluster_count, const uint* cluster_cpus);
-void arch_register_mpid(uint cpu_id, uint64_t mpid);
-void arm64_init_percpu_early(void);
-
-// Use the x18 register to always point at the local cpu structure to allow fast access
-// a per cpu structure.
-// Do not directly access fields of this structure
-register struct arm64_percpu* __arm64_percpu __asm("x18");
-
-static inline void arm64_write_percpu_ptr(struct arm64_percpu* percpu) {
-    __arm64_percpu = percpu;
-}
-
-static inline struct arm64_percpu* arm64_read_percpu_ptr(void) {
-    return __arm64_percpu;
-}
-
-static inline uint32_t arm64_read_percpu_u32(size_t offset) {
-    uint32_t val;
-
-    // mark as volatile to force a read of the field to make sure
-    // the compiler always emits a read when asked and does not cache
-    // a copy between
-    __asm__ volatile("ldr %w[val], [x18, %[offset]]"
-                     : [val] "=r"(val)
-                     : [offset] "Ir"(offset));
-    return val;
-}
-
-static inline void arm64_write_percpu_u32(size_t offset, uint32_t val) {
-    __asm__("str %w[val], [x18, %[offset]]"
-            ::[val] "r"(val), [offset] "Ir"(offset)
-            : "memory");
-}
-
-static inline cpu_num_t arch_curr_cpu_num(void) {
-    return arm64_read_percpu_u32(offsetof(struct arm64_percpu, cpu_num));
-}
-
-// TODO(ZX-3068) get num_cpus from topology.
-// This needs to be set very early (before arch_init).
-static inline void arch_set_num_cpus(uint cpu_count) {
-    extern uint arm_num_cpus;
-    arm_num_cpus = cpu_count;
-}
-
-static inline uint arch_max_num_cpus(void) {
-    extern uint arm_num_cpus;
-
-    return arm_num_cpus;
-}
-
-// translate a cpu number back to the cluster ID (AFF1)
-static inline uint arch_cpu_num_to_cluster_id(uint cpu) {
-    extern uint arm64_cpu_cluster_ids[SMP_MAX_CPUS];
-
-    return arm64_cpu_cluster_ids[cpu];
-}
-
-// translate a cpu number back to the MP cpu number within a cluster (AFF0)
-static inline uint arch_cpu_num_to_cpu_id(uint cpu) {
-    extern uint arm64_cpu_cpu_ids[SMP_MAX_CPUS];
-
-    return arm64_cpu_cpu_ids[cpu];
-}
-
-cpu_num_t arch_mpid_to_cpu_num(uint cluster, uint cpu);
-
-#define READ_PERCPU_FIELD32(field) \
-    arm64_read_percpu_u32(offsetof(struct arm64_percpu, field))
-
-#define WRITE_PERCPU_FIELD32(field, value) \
-    arm64_write_percpu_u32(offsetof(struct arm64_percpu, field), (value))
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/include/arch/arm64/periphmap.h b/kernel/arch/arm64/include/arch/arm64/periphmap.h
deleted file mode 100644
index dbb8e26..0000000
--- a/kernel/arch/arm64/include/arch/arm64/periphmap.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <sys/types.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-// adds a new peripheral range
-zx_status_t add_periph_range(paddr_t base_phys, size_t length);
-
-// called after virtual memory is started to reserve peripheral ranges
-// in the kernel's address space
-void reserve_periph_ranges(void);
-
-// translates peripheral physical address to virtual address in the big kernel map
-vaddr_t periph_paddr_to_vaddr(paddr_t paddr);
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/include/arch/arm64/registers.h b/kernel/arch/arm64/include/arch/arm64/registers.h
deleted file mode 100644
index 4841034..0000000
--- a/kernel/arch/arm64/include/arch/arm64/registers.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// MDSCR_EL1
-// Monitor Debug System Control Register. It's the main control register fot the debug
-// implementation.
-
-#define ARM64_MDSCR_EL1_SS (1u << 0)
-#define ARM64_MDSCR_EL1_ERR (1u << 6)
-#define ARM64_MDSCR_EL1_TDCC (1u << 12)
-#define ARM64_MDSCR_EL1_KDE (1u << 13)
-#define ARM64_MDSCR_EL1_HDE (1u << 14)
-#define ARM64_MDSCR_EL1_MDE (1u << 15)
-#define ARM64_MDSCR_EL1_RAZ_WI 0x000e0000lu
-#define ARM64_MDSCR_EL1_RAZ_WI_SHIFT 16
-#define ARM64_MDSCR_EL1_TDA (1u << 21)
-#define ARM64_MDSCR_EL1_INTDIS = 0x000c0000
-#define ARM64_MDSCR_EL1_INTDIS_SHIFT 22
-#define ARM64_MDSCR_EL1_TXU (1u << 26)
-#define ARM64_MDSCR_EL1_RXO (1u << 27)
-#define ARM64_MDSCR_EL1_TXfull (1u << 29)
-#define ARM64_MDSCR_EL1_RXfull (1u << 30)
-
-// ID_AA64DFR0
-// Debug Feature Register 0. This register is used to query the system for the debug
-// capabilites present within the chip.
-
-#define ARM64_ID_AADFR0_EL1_DEBUG_VER   0x0000000000000Flu
-#define ARM64_ID_AADFR0_EL1_TRACE_VER   0x000000000000F0lu
-#define ARM64_ID_AADFR0_EL1_PMU_VER `   0x00000000000F00lu
-// Defines the amount of HW breakpoints.
-#define ARM64_ID_AADFR0_EL1_BRPS        0x0000000000F000lu
-#define ARM64_ID_AADFR0_EL1_BRPS_SHIFT  12lu
-// Defines the amount of HW data watchpoints.
-#define ARM64_ID_AADFR0_EL1_WRPS        0x00000000F00000lu
-#define ARM64_ID_AADFR0_EL1_WRPS_SHIFT  20lu
-#define ARM64_ID_AADFR0_EL1_CTX_CMP     0x000000F0000000lu
-#define ARM64_ID_AADFR0_EL1_PMS_VER     0x00000F00000000lu
-
-// DBGBCR<n>
-// Control register for HW breakpoints. There is one foreach HW breakpoint present within the
-// system. They go numbering by DBGBCR0, DBGBCR1, ... until the value defined in ID_AADFR0_EL1.
-
-#define ARM64_DBGBCR_E          (1u << 0)
-#define ARM64_DBGBCR_PMC        (0b11u << 1)  // Bits 1-2.
-#define ARM64_DBGBCR_PMC_SHIFT  1u
-#define ARM64_DBGBCR_BAS        (0b1111u << 5)  // Bits 5-8.
-#define ARM64_DBGGCR_BAS_SHIFT  5u
-#define ARM64_DBGBCR_HMC        (1u << 13)
-#define ARM64_DBGBCR_HMC_SHIFT  13u
-#define ARM64_DBGBCR_SSC        (0b111u << 14) // Bits 14-15.
-#define ARM64_DBGBCR_SSC_SHIFT  14u
-#define ARM64_DBGBCR_LBN        (0b1111u << 16) // Bits 16-19.
-#define ARM64_DBGBCR_LBN_SHIFT  16u
-#define ARM64_DBGBCR_BT         (0b1111u << 20) // Bits 20-23.
-#define ARM64_DBGBCR_BY_SHIFT   20u
-
-// The user can only activate/deactivate breakpoints.
-#define ARM64_DBGBCR_USER_MASK (ARM64_DBGBCR_E)
-
-// This is the mask that we validate for a breakpoint control.
-// PMC [0b10]
-// BAS [0b1111]: Match on complete address.
-// HMC [0]
-// SSC [0]
-// LBN [0]: No breakpoint linking.
-// BT [0]: Unliked instruction address match.
-//
-// The PMC, HMC, SSC values configured here enable debug exceptions to be thrown in EL0.
-#define ARM64_DBGBCR_MASK ((0b10u << ARM64_DBGBCR_PMC_SHIFT) | \
-                           ARM64_DBGBCR_BAS)
-
-// ARMv8 assures at least 2 hw registers.
-#define ARM64_MIN_HW_BREAKPOINTS 2
-#define ARM64_MAX_HW_BREAKPOINTS 16
-#define ARM64_MIN_HW_WATCHPOINTS 2
-#define ARM64_MAX_HW_WATCHPOINTS 16
-
-#include <zircon/compiler.h>
-#include <sys/types.h>
-
-__BEGIN_CDECLS
-
-/* Kernel tracking of the current state of the debug registers for a particular thread.
- * ARMv8 can have from 2 to 16 HW breakpoints and 2 to 16 HW watchpoints.
- *
- * This struct can potentially hold all of them. If the platform has fewer of those
- * breakpoints available, it will fill from the lower index up to correct amount.
- * The other indices should never be accessed. */
-typedef struct arm64_debug_state {
-  struct {
-    uint32_t dbgbcr;
-    uint64_t dbgbvr;
-  } hw_bps[ARM64_MAX_HW_BREAKPOINTS];
-  // TODO(donosoc): Do watchpoint integration.
-} arm64_debug_state_t;
-
-
-/* Enable/disable the HW debug functionalities for the current thread. */
-void arm64_disable_debug_state();
-void arm64_enable_debug_state();
-
-/* Checks whether the given state is valid to install on a running thread.
- * Will mask out reserved values on DBGBCR<n>. This is for the caller convenience, considering
- * that we don't have a good mechanism to communicate back to the user what went wrong with the
- * call. */
-bool arm64_validate_debug_state(arm64_debug_state_t *debug_state);
-
-/* Returns the amount of HW breakpoints present in this CPU. */
-uint8_t arm64_hw_breakpoint_count();
-uint8_t arm64_hw_watchpoint_count();
-
-/* Read from the CPU registers into |debug_state|. */
-void arm64_read_hw_debug_regs(arm64_debug_state_t* debug_state);
-
-/* Write from the |debug_state| into the CPU registers.
- *
- * IMPORTANT: This function is used in the context switch, so no validation is done, just writing.
- *            In any other context (eg. setting debug values from a syscall), you *MUST* call
- *            arm64_validate_debug_state first. */
-void arm64_write_hw_debug_regs(const arm64_debug_state_t* debug_state);
-
-/* Handles the context switch for debug HW functionality.
- * Will only copy over state if it's enabled (non-zero) for |new_thread|. */
-void arm64_debug_state_context_switch(thread* old_thread, thread* new_thread);
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/include/arch/arm64/smccc.h b/kernel/arch/arm64/include/arch/arm64/smccc.h
deleted file mode 100644
index b81f957..0000000
--- a/kernel/arch/arm64/include/arch/arm64/smccc.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-// ARM Secure Monitor Call Calling Convention (SMCCC)
-//
-// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0028b/index.html
-
-typedef struct arm_smccc_result {
-    uint64_t x0;
-    uint64_t x1;
-    uint64_t x2;
-    uint64_t x3;
-} arm_smccc_result_t;
-
-arm_smccc_result_t arm_smccc_smc(uint32_t w0,              // Function Identifier
-                                 uint64_t x1, uint64_t x2, // Parameters
-                                 uint64_t x3, uint64_t x4, // Parameters
-                                 uint64_t x5, uint64_t x6, // Parameters
-                                 uint32_t w7);             // Client ID[15:0], Secure OS ID[31:16]
-
-arm_smccc_result_t arm_smccc_hvc(uint32_t w0,              // Function Identifier
-                                 uint64_t x1, uint64_t x2, // Parameters
-                                 uint64_t x3, uint64_t x4, // Parameters
-                                 uint64_t x5, uint64_t x6, // Parameters
-                                 uint32_t w7);             // Secure OS ID[31:16]
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/include/arch/arm64/user_copy.h b/kernel/arch/arm64/include/arch/arm64/user_copy.h
deleted file mode 100644
index f23ccbd..0000000
--- a/kernel/arch/arm64/include/arch/arm64/user_copy.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-// This is the same as memcpy, except that it takes the additional
-// argument of &current_thread()->arch.data_fault_resume, where it
-// temporarily stores the fault recovery PC for bad page faults to user
-// addresses during the call.  arch_copy_from_user and arch_copy_to_user
-// should be the only callers of this.
-zx_status_t _arm64_user_copy(
-    void* dst,
-    const void* src,
-    size_t len,
-    void** fault_return);
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/include/arch/asm_macros.h b/kernel/arch/arm64/include/arch/asm_macros.h
deleted file mode 100644
index afb0941..0000000
--- a/kernel/arch/arm64/include/arch/asm_macros.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// clang-format off
-
-.macro movlit reg, literal
-mov \reg, #((\literal) & 0xffff)
-.ifne (((\literal) >> 16) & 0xffff)
-movk \reg, #(((\literal) >> 16) & 0xffff), lsl #16
-.endif
-.ifne (((\literal) >> 32) & 0xffff)
-movk \reg, #(((\literal) >> 32) & 0xffff), lsl #32
-.endif
-.ifne (((\literal) >> 48) & 0xffff)
-movk \reg, #(((\literal) >> 48) & 0xffff), lsl #48
-.endif
-.endm
-
-// GAS doesn't support xzr in .cfi directives.
-
-.macro push_regs ra, rb
-stp \ra, \rb, [sp,#-16]!
-.cfi_adjust_cfa_offset 16
-.ifnes "\ra", "xzr"
-.cfi_rel_offset \ra, 0
-.endif
-.ifnes "\rb", "xzr"
-.cfi_rel_offset \rb, 8
-.endif
-.endm
-
-.macro pop_regs ra, rb
-ldp \ra, \rb, [sp], #16
-.cfi_adjust_cfa_offset -16
-.ifnes "\ra", "xzr"
-.cfi_same_value \ra
-.endif
-.ifnes "\rb", "xzr"
-.cfi_same_value \rb
-.endif
-.endm
-
-.macro sub_from_sp value
-sub sp, sp, #\value
-.cfi_adjust_cfa_offset \value
-.endm
-
-.macro add_to_sp value
-add sp, sp, #\value
-.cfi_adjust_cfa_offset -\value
-.endm
-
-.macro adr_global reg, symbol
-adrp \reg, \symbol
-add \reg, \reg, #:lo12:\symbol
-.endm
-
-.macro movabs reg, symbol
-// TODO(mcgrathr): Remove this workaround when the upstream LLVM assembler
-// bug http://bugs.llvm.org/show_bug.cgi?id=32527 is fixed.
-#ifdef __clang__
-ldr \reg, =\symbol
-#else
-movz \reg, #:abs_g0_nc:\symbol
-movk \reg, #:abs_g1_nc:\symbol
-movk \reg, #:abs_g2_nc:\symbol
-movk \reg, #:abs_g3:\symbol
-#endif
-.endm
-
-.macro tbzmask, reg, mask, label, shift=0
-.if \shift >= 64
-    .error "tbzmask: unsupported mask, \mask"
-.elseif \mask == 1 << \shift
-    tbz     \reg, #\shift, \label
-.else
-    tbzmask \reg, \mask, \label, "(\shift + 1)"
-.endif
-.endm
-
-.macro tbnzmask, reg, mask, label, shift=0
-.if \shift >= 64
-    .error "tbnzmask: unsupported mask, \mask"
-.elseif \mask == 1 << \shift
-    tbnz     \reg, #\shift, \label
-.else
-    tbnzmask \reg, \mask, \label, "(\shift + 1)"
-.endif
-.endm
-
-// For "functions" that are not normal functions in the ABI sense.
-// Treat all previous frame registers as having the same value.
-
-#define ALL_CFI_SAME_VALUE \
-    .cfi_same_value x0 ; \
-    .cfi_same_value x1 ; \
-    .cfi_same_value x2 ; \
-    .cfi_same_value x3 ; \
-    .cfi_same_value x4 ; \
-    .cfi_same_value x5 ; \
-    .cfi_same_value x6 ; \
-    .cfi_same_value x7 ; \
-    .cfi_same_value x8 ; \
-    .cfi_same_value x9 ; \
-    .cfi_same_value x10 ; \
-    .cfi_same_value x11 ; \
-    .cfi_same_value x12 ; \
-    .cfi_same_value x13 ; \
-    .cfi_same_value x14 ; \
-    .cfi_same_value x15 ; \
-    .cfi_same_value x16 ; \
-    .cfi_same_value x17 ; \
-    .cfi_same_value x18 ; \
-    .cfi_same_value x19 ; \
-    .cfi_same_value x20 ; \
-    .cfi_same_value x21 ; \
-    .cfi_same_value x22 ; \
-    .cfi_same_value x23 ; \
-    .cfi_same_value x24 ; \
-    .cfi_same_value x25 ; \
-    .cfi_same_value x26 ; \
-    .cfi_same_value x27 ; \
-    .cfi_same_value x28 ; \
-    .cfi_same_value x29
diff --git a/kernel/arch/arm64/include/arch/aspace.h b/kernel/arch/arm64/include/arch/aspace.h
deleted file mode 100644
index 277b218..0000000
--- a/kernel/arch/arm64/include/arch/aspace.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2015-2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/arm64/mmu.h>
-#include <fbl/canary.h>
-#include <fbl/mutex.h>
-#include <vm/arch_vm_aspace.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-class ArmArchVmAspace final : public ArchVmAspaceInterface {
-public:
-    ArmArchVmAspace();
-    virtual ~ArmArchVmAspace();
-
-    zx_status_t Init(vaddr_t base, size_t size, uint mmu_flags) override;
-
-    zx_status_t Destroy() override;
-
-    // main methods
-    zx_status_t Map(vaddr_t vaddr, paddr_t* phys, size_t count, uint mmu_flags,
-                    size_t* mapped) override;
-    zx_status_t MapContiguous(vaddr_t vaddr, paddr_t paddr, size_t count,
-                              uint mmu_flags, size_t* mapped) override;
-
-    zx_status_t Unmap(vaddr_t vaddr, size_t count, size_t* unmapped) override;
-
-    zx_status_t Protect(vaddr_t vaddr, size_t count, uint mmu_flags) override;
-
-    zx_status_t Query(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags) override;
-
-    vaddr_t PickSpot(vaddr_t base, uint prev_region_mmu_flags,
-                     vaddr_t end, uint next_region_mmu_flags,
-                     vaddr_t align, size_t size, uint mmu_flags) override;
-
-    paddr_t arch_table_phys() const override { return tt_phys_; }
-    uint16_t arch_asid() const { return asid_; }
-    void arch_set_asid(uint16_t asid) { asid_ = asid; }
-
-    static void ContextSwitch(ArmArchVmAspace* from, ArmArchVmAspace* to);
-
-private:
-    inline bool IsValidVaddr(vaddr_t vaddr) {
-        return (vaddr >= base_ && vaddr <= base_ + size_ - 1);
-    }
-
-    // Page table management.
-    volatile pte_t* GetPageTable(vaddr_t index, uint page_size_shift,
-                                 volatile pte_t* page_table) TA_REQ(lock_);
-
-    zx_status_t AllocPageTable(paddr_t* paddrp, uint page_size_shift) TA_REQ(lock_);
-
-    void FreePageTable(void* vaddr, paddr_t paddr, uint page_size_shift) TA_REQ(lock_);
-
-    ssize_t MapPageTable(vaddr_t vaddr_in, vaddr_t vaddr_rel_in,
-                         paddr_t paddr_in, size_t size_in, pte_t attrs,
-                         uint index_shift, uint page_size_shift,
-                         volatile pte_t* page_table) TA_REQ(lock_);
-
-    ssize_t UnmapPageTable(vaddr_t vaddr, vaddr_t vaddr_rel, size_t size,
-                           uint index_shift, uint page_size_shift,
-                           volatile pte_t* page_table) TA_REQ(lock_);
-
-    int ProtectPageTable(vaddr_t vaddr_in, vaddr_t vaddr_rel_in, size_t size_in,
-                         pte_t attrs, uint index_shift, uint page_size_shift,
-                         volatile pte_t* page_table) TA_REQ(lock_);
-
-    void MmuParamsFromFlags(uint mmu_flags,
-                            pte_t* attrs, vaddr_t* vaddr_base,
-                            uint* top_size_shift, uint* top_index_shift,
-                            uint* page_size_shift);
-    ssize_t MapPages(vaddr_t vaddr, paddr_t paddr, size_t size, pte_t attrs,
-                     vaddr_t vaddr_base, uint top_size_shift, uint top_index_shift,
-                     uint page_size_shift) TA_REQ(lock_);
-
-    ssize_t UnmapPages(vaddr_t vaddr, size_t size, vaddr_t vaddr_base,
-                       uint top_size_shift, uint top_index_shift,
-                       uint page_size_shift) TA_REQ(lock_);
-
-    zx_status_t ProtectPages(vaddr_t vaddr, size_t size, pte_t attrs,
-                             vaddr_t vaddr_base, uint top_size_shift,
-                             uint top_index_shift, uint page_size_shift) TA_REQ(lock_);
-    zx_status_t QueryLocked(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags) TA_REQ(lock_);
-
-    void FlushTLBEntry(vaddr_t vaddr, bool terminal) TA_REQ(lock_);
-
-    fbl::Canary<fbl::magic("VAAS")> canary_;
-
-    fbl::Mutex lock_;
-
-    uint16_t asid_ = MMU_ARM64_UNUSED_ASID;
-
-    // Pointer to the translation table.
-    paddr_t tt_phys_ = 0;
-    volatile pte_t* tt_virt_ = nullptr;
-
-    // Upper bound of the number of pages allocated to back the translation
-    // table.
-    size_t pt_pages_ = 0;
-
-    uint flags_ = 0;
-
-    // Range of address space.
-    vaddr_t base_ = 0;
-    size_t size_ = 0;
-};
-
-static inline paddr_t arm64_vttbr(uint16_t vmid, paddr_t baddr) {
-    return static_cast<paddr_t>(vmid) << 48 | baddr;
-}
-
-using ArchVmAspace = ArmArchVmAspace;
diff --git a/kernel/arch/arm64/include/arch/current_thread.h b/kernel/arch/arm64/include/arch/current_thread.h
deleted file mode 100644
index c85d6a5..0000000
--- a/kernel/arch/arm64/include/arch/current_thread.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-__BEGIN_CDECLS
-
-/* use the cpu local thread context pointer to store current_thread */
-static inline struct thread* get_current_thread(void) {
-#ifdef __clang__
-    // Clang with --target=aarch64-fuchsia -mcmodel=kernel reads
-    // TPIDR_EL1 for __builtin_thread_pointer (instead of the usual
-    // TPIDR_EL0 for user mode).  Using the intrinsic instead of asm
-    // lets the compiler understand what it's doing a little better,
-    // which conceivably could let it optimize better.
-    char* tp = (char*)__builtin_thread_pointer();
-#else
-    char* tp = (char*)__arm_rsr64("tpidr_el1");
-#endif
-    tp -= offsetof(struct thread, arch.thread_pointer_location);
-    return (struct thread*)tp;
-}
-
-static inline void set_current_thread(struct thread* t) {
-    __arm_wsr64("tpidr_el1", (uint64_t)&t->arch.thread_pointer_location);
-    __isb(ARM_MB_SY);
-}
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/include/arch/defines.h b/kernel/arch/arm64/include/arch/defines.h
deleted file mode 100644
index 676dae9..0000000
--- a/kernel/arch/arm64/include/arch/defines.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2008 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#define SHIFT_4K (12)
-#define SHIFT_16K (14)
-#define SHIFT_64K (16)
-
-/* arm specific stuff */
-#ifdef ARM64_LARGE_PAGESIZE_64K
-#define PAGE_SIZE_SHIFT (SHIFT_64K)
-#elif ARM64_LARGE_PAGESIZE_16K
-#define PAGE_SIZE_SHIFT (SHIFT_16K)
-#else
-#define PAGE_SIZE_SHIFT (SHIFT_4K)
-#endif
-#define USER_PAGE_SIZE_SHIFT SHIFT_4K
-
-#define PAGE_SIZE (1L << PAGE_SIZE_SHIFT)
-#define PAGE_MASK (PAGE_SIZE - 1)
-
-#define USER_PAGE_SIZE (1L << USER_PAGE_SIZE_SHIFT)
-#define USER_PAGE_MASK (USER_PAGE_SIZE - 1)
-
-/* the maximum cache line seen on any known ARM hardware */
-#define MAX_CACHE_LINE 128
-
-#ifndef __ASSEMBLER__
-#define BM(base, count, val) (((val) & ((1UL << (count)) - 1)) << (base))
-#else
-#define BM(base, count, val) (((val) & ((0x1 << (count)) - 1)) << (base))
-#endif
-
-#define ARM64_MMFR0_ASIDBITS_16 BM(4, 4, 2)
-#define ARM64_MMFR0_ASIDBITS_8 BM(4, 4, 0)
-#define ARM64_MMFR0_ASIDBITS_MASK BM(4, 4, 15)
-
-#define ARCH_DEFAULT_STACK_SIZE 8192
-
-/* map 512GB at the base of the kernel. this is the max that can be mapped with a
- * single level 1 page table using 1GB pages.
- */
-#ifndef __ASSEMBLER__
-#define ARCH_PHYSMAP_SIZE (1UL << 39)
-#else
-#define ARCH_PHYSMAP_SIZE (0x1 << 39)
-#endif
diff --git a/kernel/arch/arm64/include/arch/hypervisor.h b/kernel/arch/arm64/include/arch/hypervisor.h
deleted file mode 100644
index 9f6fd38..0000000
--- a/kernel/arch/arm64/include/arch/hypervisor.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/arm64/hypervisor/el2_state.h>
-#include <fbl/ref_ptr.h>
-#include <ktl/unique_ptr.h>
-#include <hypervisor/guest_physical_address_space.h>
-#include <hypervisor/id_allocator.h>
-#include <hypervisor/interrupt_tracker.h>
-#include <hypervisor/page.h>
-#include <hypervisor/trap_map.h>
-#include <kernel/event.h>
-#include <kernel/spinlock.h>
-#include <zircon/types.h>
-
-static constexpr uint8_t kNumGroups = 2;
-// See CoreLink GIC-400, Section 2.3.2 PPIs.
-static constexpr uint32_t kMaintenanceVector = 25;
-static constexpr uint32_t kTimerVector = 27;
-static constexpr uint16_t kNumInterrupts = 256;
-static_assert(kMaintenanceVector < kNumInterrupts, "Maintenance vector is out of range");
-static_assert(kTimerVector < kNumInterrupts, "Timer vector is out of range");
-
-typedef struct zx_port_packet zx_port_packet_t;
-class PortDispatcher;
-
-class Guest {
-public:
-    static zx_status_t Create(ktl::unique_ptr<Guest>* out);
-    ~Guest();
-    DISALLOW_COPY_ASSIGN_AND_MOVE(Guest);
-
-    zx_status_t SetTrap(uint32_t kind, zx_vaddr_t addr, size_t len,
-                        fbl::RefPtr<PortDispatcher> port, uint64_t key);
-
-    hypervisor::GuestPhysicalAddressSpace* AddressSpace() const { return gpas_.get(); }
-    hypervisor::TrapMap* Traps() { return &traps_; }
-    uint8_t Vmid() const { return vmid_; }
-
-    zx_status_t AllocVpid(uint8_t* vpid);
-    zx_status_t FreeVpid(uint8_t vpid);
-
-private:
-    ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas_;
-    hypervisor::TrapMap traps_;
-    const uint8_t vmid_;
-
-    fbl::Mutex vcpu_mutex_;
-    // TODO(alexlegg): Find a good place for this constant to live (max vcpus).
-    hypervisor::IdAllocator<uint8_t, 8> TA_GUARDED(vcpu_mutex_) vpid_allocator_;
-
-    explicit Guest(uint8_t vmid);
-};
-
-// Stores the state of the GICH across VM exits.
-struct GichState {
-    // Tracks pending interrupts.
-    hypervisor::InterruptTracker<kNumInterrupts> interrupt_tracker;
-    // Tracks active interrupts.
-    bitmap::RawBitmapGeneric<bitmap::FixedStorage<kNumInterrupts>> active_interrupts;
-};
-
-// Loads GICH within a given scope.
-class AutoGich {
-public:
-    AutoGich(IchState* ich_state, bool pending);
-    ~AutoGich();
-
-private:
-    IchState* ich_state_;
-};
-
-class Vcpu {
-public:
-    static zx_status_t Create(Guest* guest, zx_vaddr_t entry, ktl::unique_ptr<Vcpu>* out);
-    ~Vcpu();
-    DISALLOW_COPY_ASSIGN_AND_MOVE(Vcpu);
-
-    zx_status_t Resume(zx_port_packet_t* packet);
-    cpu_mask_t Interrupt(uint32_t vector, hypervisor::InterruptType type);
-    void VirtualInterrupt(uint32_t vector);
-    zx_status_t ReadState(uint32_t kind, void* buf, size_t len) const;
-    zx_status_t WriteState(uint32_t kind, const void* buf, size_t len);
-
-private:
-    Guest* guest_;
-    const uint8_t vpid_;
-    const thread_t* thread_;
-    fbl::atomic_bool running_;
-    // We allocate El2State in its own page as it is passed between EL1 and EL2,
-    // which have different address space mappings. This ensures that El2State
-    // will not cross a page boundary and be incorrectly accessed in EL2.
-    hypervisor::PagePtr<El2State> el2_state_;
-    GichState gich_state_;
-    uint64_t hcr_;
-
-    Vcpu(Guest* guest, uint8_t vpid, const thread_t* thread);
-};
diff --git a/kernel/arch/arm64/include/arch/spinlock.h b/kernel/arch/arm64/include/arch/spinlock.h
deleted file mode 100644
index 21fb0e3..0000000
--- a/kernel/arch/arm64/include/arch/spinlock.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/arm64/interrupt.h>
-#include <arch/arm64/mp.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <zircon/compiler.h>
-#include <zircon/thread_annotations.h>
-
-__BEGIN_CDECLS
-
-#define SPIN_LOCK_INITIAL_VALUE \
-    (spin_lock_t) { 0 }
-
-typedef struct TA_CAP("mutex") spin_lock {
-    unsigned long value;
-} spin_lock_t;
-
-typedef unsigned int spin_lock_saved_state_t;
-typedef unsigned int spin_lock_save_flags_t;
-
-void arch_spin_lock(spin_lock_t* lock) TA_ACQ(lock);
-int arch_spin_trylock(spin_lock_t* lock) TA_TRY_ACQ(false, lock);
-void arch_spin_unlock(spin_lock_t* lock) TA_REL(lock);
-
-static inline uint arch_spin_lock_holder_cpu(spin_lock_t* lock) {
-    return (uint)__atomic_load_n(&lock->value, __ATOMIC_RELAXED) - 1;
-}
-
-static inline bool arch_spin_lock_held(spin_lock_t* lock) {
-    return arch_spin_lock_holder_cpu(lock) == arch_curr_cpu_num();
-}
-
-enum {
-    /* Possible future flags:
-     * SPIN_LOCK_FLAG_PMR_MASK         = 0x000000ff,
-     * SPIN_LOCK_FLAG_PREEMPTION       = 0x10000000,
-     * SPIN_LOCK_FLAG_SET_PMR          = 0x20000000,
-     */
-
-    /* ARM specific flags */
-    SPIN_LOCK_FLAG_IRQ = 0x40000000,
-    SPIN_LOCK_FLAG_FIQ = 0x80000000, /* Do not use unless IRQs are already disabled */
-    SPIN_LOCK_FLAG_IRQ_FIQ = SPIN_LOCK_FLAG_IRQ | SPIN_LOCK_FLAG_FIQ,
-
-    /* default arm flag is to just disable plain irqs */
-    ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS = SPIN_LOCK_FLAG_IRQ
-};
-
-enum {
-    /* private */
-    SPIN_LOCK_STATE_RESTORE_IRQ = 1,
-    SPIN_LOCK_STATE_RESTORE_FIQ = 2,
-};
-
-static inline void
-arch_interrupt_save(spin_lock_saved_state_t* statep, spin_lock_save_flags_t flags) {
-    spin_lock_saved_state_t state = 0;
-    if ((flags & SPIN_LOCK_FLAG_IRQ) && !arch_ints_disabled()) {
-        state |= SPIN_LOCK_STATE_RESTORE_IRQ;
-        arch_disable_ints();
-    }
-    if ((flags & SPIN_LOCK_FLAG_FIQ) && !arch_fiqs_disabled()) {
-        state |= SPIN_LOCK_STATE_RESTORE_FIQ;
-        arch_disable_fiqs();
-    }
-    *statep = state;
-}
-
-static inline void
-arch_interrupt_restore(spin_lock_saved_state_t old_state, spin_lock_save_flags_t flags) {
-    if ((flags & SPIN_LOCK_FLAG_FIQ) && (old_state & SPIN_LOCK_STATE_RESTORE_FIQ))
-        arch_enable_fiqs();
-    if ((flags & SPIN_LOCK_FLAG_IRQ) && (old_state & SPIN_LOCK_STATE_RESTORE_IRQ))
-        arch_enable_ints();
-}
-
-__END_CDECLS
diff --git a/kernel/arch/arm64/mexec.S b/kernel/arch/arm64/mexec.S
deleted file mode 100644
index 6e07b8f..0000000
--- a/kernel/arch/arm64/mexec.S
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/asm_macros.h>
-#include <arch/defines.h>
-#include <asm.h>
-#include <mexec.h>
-
-/* Arguments Passed via x0 through x8 inclusive */
-bootarg0                .req x25
-bootarg1                .req x26
-bootarg2                .req x27
-boot_el                 .req x28
-
-// This is a null terminated list of memory regions to copy.
-copy_list               .req x23
-
-// This is the address to branch to once the copy is completed.
-new_kernel_addr         .req x24
-
-tmp                     .req x9
-
-.section .text
-FUNCTION(mexec_asm)
-
-// Turn off the caches and MMU
-    mrs     tmp, sctlr_el1      // Read the SCTLR into a temp
-    bic     tmp, tmp, #(1<<12)  // Disable icache
-    bic     tmp, tmp, #(1<<2)   // Disable dcache/ucache
-    bic     tmp, tmp, #(1<<0)   // Disable the MMU
-    msr     sctlr_el1, tmp      // Write the temp back to the control register
-
-// Stash the boot arguments to pass to the next kernel since we expect to trash
-// x0 - x5
-    mov     bootarg0, x0
-    mov     bootarg1, x1
-    mov     bootarg2, x2
-
-// Stash the boot el, as we will need it later
-    mov     boot_el,  x3
-
-// This list contains the memmove operations that we need to perform.
-    mov     copy_list, x4
-
-// This is the address of the kernel that we eventueally want to jump to.
-    mov     new_kernel_addr, x5
-
-    // If we were originally booted in EL2, transition back into EL2
-    cmp  boot_el, #2
-    b.lt cplt_transition_to_boot_el  // We booted in EL1, no need to transition up
-    adr  x0, cplt_transition_to_boot_el
-    hvc  #1     // Branch into an EL2 trampoline that bounces to cplt_transition_to_boot_el
-
- cplt_transition_to_boot_el:
-
-    // Clean/Invalidate the cache early on.
-    // We want to make sure that there are no dirty cache entries hanging around
-    // in the cache before we start the memcpy.
-    // If these cache entries were to get written back later, they would corrupt
-    // the state of the system so we clean/invalidate them up front.
-    bl      mexec_arch_clean_invalidate_cache_all
-
-/* Mempy the new kernel over the old kernel. Keep in mind that since the MMU
- * is disabled, unaligned accesses are no longer legal. All accesses must be
- * word aligned.
- */
-.Lcopy:
-    // Load a copy operation into memory
-    ldr     x0, [copy_list, MEMMOV_OPS_DST_OFFSET]
-    ldr     x1, [copy_list, MEMMOV_OPS_SRC_OFFSET]
-    ldr     x2, [copy_list, MEMMOV_OPS_LEN_OFFSET]
-
-    // Determine if this is the end of the list by checking if all three elems
-    // in the copy list are null
-    orr     tmp, x0, x1
-    orr     tmp, tmp, x2
-    cbz     tmp, .Lfinish_copy
-
-    // The copy operation is not null, go ahead and memmove
-    bl      memmove_mexec
-
-    // Advance the pointer to the next copy operation.
-    add     copy_list, copy_list, 24
-
-    b       .Lcopy
-
-.Lfinish_copy:
-
-    bl mexec_arch_clean_invalidate_cache_all
-
-    // Restore the bootarguments for the next kernel.
-    mov     x0, bootarg0
-    mov     x1, bootarg1
-    mov     x2, bootarg2
-
-    // Get everything out of the pipeline before branching to the new kernel.
-    isb
-    dsb sy
-
-    // Branch to the next kernel.
-    br      new_kernel_addr
-END_FUNCTION(mexec_asm)
-
-LOCAL_FUNCTION(memmove_mexec)
-        // x6 contains the stride (1 word if we're copying forward
-        // -1 word if we're copying backwards)
-        mov     x6, 1
-
-        // x3 is the start index of the copy, this is the front of the array if
-        // we're copying forward or the back of the array if we're copying
-        // backwards.
-        mov     x3, 0
-
-        // Convert the length of the array from bytes to machine words
-        lsr     x2, x2, 3
-
-        // If the source address and the destination address are the same then
-        // we can return because there's nothing to be done.
-        cmp     x0, x1
-        beq     .done
-
-        // Decide if we need to copy backwards.
-        blt     .no_alias
-        mov     x6, -1          // Set the stride to backwards
-        mov     x3, x2          // Move the copy index to the back of the array
-        sub     x3, x3, 1       // i = (len_wrds - 1); to start at the last word
-
-.no_alias:
-        mov     x4, 0           // Loop iteration index
-.copy_loop:
-        // Copy one word of data
-        // dst[i << 3] = src[i << 3]
-        ldr     tmp, [x1, x3, lsl 3]
-        str     tmp, [x0, x3, lsl 3]
-
-        lsl     x7, x3, 3
-        add     x7, x7, x0
-
-        // Increment the array index by the stride (backwards or forwards).
-        // i += stride
-        add     x3, x3, x6
-
-        // Increment the number of words copied (we use this to decide when to
-        // stop)
-        // words_copied += 1
-        add     x4, x4, 1
-
-        // If we've copied the whole buffer, then finish.
-        // if (words_copied == words_to_copy) break;
-        cmp     x2, x4
-        bne     .copy_loop
-.done:
-        ret
-END_FUNCTION(memmove_mexec)
-
-// Perform a bulk clean/invalidate across the whole cache
-// Normally on ARM we can use the CIVAC, CVAC, CVAU and IVAC instructions to
-// manipulate the cache but these ops only work against virtual memory addresses
-// and since we have disabled the MMU, these instructions are no longer
-// meaningful.
-// As a result, we have to use the Level/Set/Way cache ops. Since the definition
-// of the cache set is left up to the implementation, the only portable (safe)
-// way to perform these cache ops is to operate against the whole cache.
-// The following op cleans and invalidates every entry in each level of the
-// cache.
-// The original implementation can be found in the ARMv8-A TRM or at the
-// following URL: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/BABJDBHI.html
-LOCAL_FUNCTION(mexec_arch_clean_invalidate_cache_all)
-         mrs x0, clidr_el1
-         and w3, w0, #0x07000000  // get 2 x level of coherence
-         lsr w3, w3, #23
-         cbz w3, finished2
-         mov w10, #0              // w10 = 2 x cache level
-         mov w8, #1               // w8 = constant 0b1
-  loop12: add w2, w10, w10, lsr #1 // calculate 3 x cache level
-         lsr w1, w0, w2           // extract 3-bit cache type for this level
-         and w1, w1, #0x7
-         cmp w1, #2
-         b.lt skip2                // no data or unified cache at this level
-         msr csselr_el1, x10      // select this cache level
-         isb                      // synchronize change of csselr
-         mrs x1, ccsidr_el1       // read ccsidr
-         and w2, w1, #7           // w2 = log2(linelen)-4
-         add w2, w2, #4           // w2 = log2(linelen)
-         ubfx w4, w1, #3, #10     // w4 = max way number, right aligned
-         clz w5, w4               /* w5 = 32-log2(ways), bit position of way in dc                                    operand */
-         lsl w9, w4, w5           /* w9 = max way number, aligned to position in dc
-                                     operand */
-         lsl w16, w8, w5          // w16 = amount to decrement way number per iteration
-  loop22: ubfx w7, w1, #13, #15    // w7 = max set number, right aligned
-         lsl w7, w7, w2           /* w7 = max set number, aligned to position in dc
-                                     operand */
-         lsl w17, w8, w2          // w17 = amount to decrement set number per iteration
-  loop33: orr w11, w10, w9         // w11 = combine way number and cache number...
-         orr w11, w11, w7         // ... and set number for dc operand
-         dc cisw, x11              // do data cache clean by set and way
-         subs w7, w7, w17         // decrement set number
-         b.ge loop33
-         subs x9, x9, x16         // decrement way number
-         b.ge loop22
-  skip2:  add w10, w10, #2         // increment 2 x cache level
-         cmp w3, w10
-         dsb sy                      /* ensure completion of previous cache maintenance
-                                    //  operation */
-         b.gt loop12
-  finished2:
-         ic iallu
-         isb
-         dsb sy
-
-         ret
-END_FUNCTION(mexec_arch_clean_invalidate_cache_all)
-
-
-/* This .ltorg emits any immediate constants here. We need to put this before
- * the mexec_asm_end symbol because we intend to relocate the assembly contained
- * within the mexec_asm[_end] block. Any constants needed by this block should
- * also be relocated so we need to ensure that they occur before mexec_asm_end.
- */
-.ltorg
-
-DATA(mexec_asm_end)
diff --git a/kernel/arch/arm64/mmu.cpp b/kernel/arch/arm64/mmu.cpp
deleted file mode 100644
index a8e96f7..0000000
--- a/kernel/arch/arm64/mmu.cpp
+++ /dev/null
@@ -1,1208 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Google Inc. All rights reserved
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/hypervisor/el2_state.h>
-#include <arch/arm64/mmu.h>
-#include <arch/aspace.h>
-#include <arch/mmu.h>
-#include <assert.h>
-#include <bitmap/raw-bitmap.h>
-#include <bitmap/storage.h>
-#include <bits.h>
-#include <debug.h>
-#include <err.h>
-#include <fbl/atomic.h>
-#include <fbl/auto_call.h>
-#include <fbl/auto_lock.h>
-#include <inttypes.h>
-#include <kernel/mutex.h>
-#include <lib/heap.h>
-#include <lib/ktrace.h>
-#include <rand.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <trace.h>
-#include <vm/arch_vm_aspace.h>
-#include <vm/physmap.h>
-#include <vm/pmm.h>
-#include <vm/vm.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-#define TRACE_CONTEXT_SWITCH 0
-
-/* ktraces just local to this file */
-#define LOCAL_KTRACE 0
-
-#if LOCAL_KTRACE
-#define LOCAL_KTRACE0(probe) ktrace_probe0(probe)
-#define LOCAL_KTRACE2(probe, x, y) ktrace_probe2(probe, x, y)
-#define LOCAL_KTRACE64(probe, x) ktrace_probe64(probe, x)
-#else
-#define LOCAL_KTRACE0(probe)
-#define LOCAL_KTRACE2(probe, x, y)
-#define LOCAL_KTRACE64(probe, x)
-#endif
-
-static_assert(((long)KERNEL_BASE >> MMU_KERNEL_SIZE_SHIFT) == -1, "");
-static_assert(((long)KERNEL_ASPACE_BASE >> MMU_KERNEL_SIZE_SHIFT) == -1, "");
-static_assert(MMU_KERNEL_SIZE_SHIFT <= 48, "");
-static_assert(MMU_KERNEL_SIZE_SHIFT >= 25, "");
-
-// Static relocated base to prepare for KASLR. Used at early boot and by gdb
-// script to know the target relocated address.
-// TODO(SEC-31): Choose it randomly.
-#if DISABLE_KASLR
-uint64_t kernel_relocated_base = KERNEL_BASE;
-#else
-uint64_t kernel_relocated_base = 0xffffffff10000000;
-#endif
-
-// The main translation table.
-pte_t arm64_kernel_translation_table[MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP] __ALIGNED(MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP * 8);
-
-pte_t* arm64_get_kernel_ptable() {
-    return arm64_kernel_translation_table;
-}
-
-namespace {
-
-class AsidAllocator {
-public:
-    AsidAllocator() { bitmap_.Reset(MMU_ARM64_MAX_USER_ASID + 1); }
-    ~AsidAllocator() = default;
-
-    zx_status_t Alloc(uint16_t* asid);
-    zx_status_t Free(uint16_t asid);
-
-private:
-    DISALLOW_COPY_ASSIGN_AND_MOVE(AsidAllocator);
-
-    fbl::Mutex lock_;
-    uint16_t last_ TA_GUARDED(lock_) = MMU_ARM64_FIRST_USER_ASID - 1;
-
-    bitmap::RawBitmapGeneric<bitmap::FixedStorage<MMU_ARM64_MAX_USER_ASID + 1>> bitmap_ TA_GUARDED(lock_);
-
-    static_assert(MMU_ARM64_ASID_BITS <= 16, "");
-};
-
-zx_status_t AsidAllocator::Alloc(uint16_t* asid) {
-    uint16_t new_asid;
-
-    // use the bitmap allocator to allocate ids in the range of
-    // [MMU_ARM64_FIRST_USER_ASID, MMU_ARM64_MAX_USER_ASID]
-    // start the search from the last found id + 1 and wrap when hitting the end of the range
-    {
-        fbl::AutoLock al(&lock_);
-
-        size_t val;
-        bool notfound = bitmap_.Get(last_ + 1, MMU_ARM64_MAX_USER_ASID + 1, &val);
-        if (unlikely(notfound)) {
-            // search again from the start
-            notfound = bitmap_.Get(MMU_ARM64_FIRST_USER_ASID, MMU_ARM64_MAX_USER_ASID + 1, &val);
-            if (unlikely(notfound)) {
-                TRACEF("ARM64: out of ASIDs\n");
-                return ZX_ERR_NO_MEMORY;
-            }
-        }
-        bitmap_.SetOne(val);
-
-        DEBUG_ASSERT(val <= UINT16_MAX);
-
-        new_asid = (uint16_t)val;
-        last_ = new_asid;
-    }
-
-    LTRACEF("new asid %#x\n", new_asid);
-
-    *asid = new_asid;
-
-    return ZX_OK;
-}
-
-zx_status_t AsidAllocator::Free(uint16_t asid) {
-    LTRACEF("free asid %#x\n", asid);
-
-    fbl::AutoLock al(&lock_);
-
-    bitmap_.ClearOne(asid);
-
-    return ZX_OK;
-}
-
-AsidAllocator asid;
-
-} // namespace
-
-// Convert user level mmu flags to flags that go in L1 descriptors.
-static pte_t mmu_flags_to_s1_pte_attr(uint flags) {
-    pte_t attr = MMU_PTE_ATTR_AF;
-
-    switch (flags & ARCH_MMU_FLAG_CACHE_MASK) {
-    case ARCH_MMU_FLAG_CACHED:
-        attr |= MMU_PTE_ATTR_NORMAL_MEMORY | MMU_PTE_ATTR_SH_INNER_SHAREABLE;
-        break;
-    case ARCH_MMU_FLAG_WRITE_COMBINING:
-        attr |= MMU_PTE_ATTR_NORMAL_UNCACHED | MMU_PTE_ATTR_SH_INNER_SHAREABLE;
-        break;
-    case ARCH_MMU_FLAG_UNCACHED:
-        attr |= MMU_PTE_ATTR_STRONGLY_ORDERED;
-        break;
-    case ARCH_MMU_FLAG_UNCACHED_DEVICE:
-        attr |= MMU_PTE_ATTR_DEVICE;
-        break;
-    default:
-        PANIC_UNIMPLEMENTED;
-    }
-
-    switch (flags & (ARCH_MMU_FLAG_PERM_USER | ARCH_MMU_FLAG_PERM_WRITE)) {
-    case 0:
-        attr |= MMU_PTE_ATTR_AP_P_RO_U_NA;
-        break;
-    case ARCH_MMU_FLAG_PERM_WRITE:
-        attr |= MMU_PTE_ATTR_AP_P_RW_U_NA;
-        break;
-    case ARCH_MMU_FLAG_PERM_USER:
-        attr |= MMU_PTE_ATTR_AP_P_RO_U_RO;
-        break;
-    case ARCH_MMU_FLAG_PERM_USER | ARCH_MMU_FLAG_PERM_WRITE:
-        attr |= MMU_PTE_ATTR_AP_P_RW_U_RW;
-        break;
-    }
-
-    if (!(flags & ARCH_MMU_FLAG_PERM_EXECUTE)) {
-        attr |= MMU_PTE_ATTR_UXN | MMU_PTE_ATTR_PXN;
-    }
-    if (flags & ARCH_MMU_FLAG_NS) {
-        attr |= MMU_PTE_ATTR_NON_SECURE;
-    }
-
-    return attr;
-}
-
-static void s1_pte_attr_to_mmu_flags(pte_t pte, uint* mmu_flags) {
-    switch (pte & MMU_PTE_ATTR_ATTR_INDEX_MASK) {
-    case MMU_PTE_ATTR_STRONGLY_ORDERED:
-        *mmu_flags |= ARCH_MMU_FLAG_UNCACHED;
-        break;
-    case MMU_PTE_ATTR_DEVICE:
-        *mmu_flags |= ARCH_MMU_FLAG_UNCACHED_DEVICE;
-        break;
-    case MMU_PTE_ATTR_NORMAL_UNCACHED:
-        *mmu_flags |= ARCH_MMU_FLAG_WRITE_COMBINING;
-        break;
-    case MMU_PTE_ATTR_NORMAL_MEMORY:
-        *mmu_flags |= ARCH_MMU_FLAG_CACHED;
-        break;
-    default:
-        PANIC_UNIMPLEMENTED;
-    }
-
-    *mmu_flags |= ARCH_MMU_FLAG_PERM_READ;
-    switch (pte & MMU_PTE_ATTR_AP_MASK) {
-    case MMU_PTE_ATTR_AP_P_RW_U_NA:
-        *mmu_flags |= ARCH_MMU_FLAG_PERM_WRITE;
-        break;
-    case MMU_PTE_ATTR_AP_P_RW_U_RW:
-        *mmu_flags |= ARCH_MMU_FLAG_PERM_USER | ARCH_MMU_FLAG_PERM_WRITE;
-        break;
-    case MMU_PTE_ATTR_AP_P_RO_U_NA:
-        break;
-    case MMU_PTE_ATTR_AP_P_RO_U_RO:
-        *mmu_flags |= ARCH_MMU_FLAG_PERM_USER;
-        break;
-    }
-
-    if (!((pte & MMU_PTE_ATTR_UXN) && (pte & MMU_PTE_ATTR_PXN))) {
-        *mmu_flags |= ARCH_MMU_FLAG_PERM_EXECUTE;
-    }
-    if (pte & MMU_PTE_ATTR_NON_SECURE) {
-        *mmu_flags |= ARCH_MMU_FLAG_NS;
-    }
-}
-
-static pte_t mmu_flags_to_s2_pte_attr(uint flags) {
-    pte_t attr = MMU_PTE_ATTR_AF;
-
-    switch (flags & ARCH_MMU_FLAG_CACHE_MASK) {
-    case ARCH_MMU_FLAG_CACHED:
-        attr |= MMU_S2_PTE_ATTR_NORMAL_MEMORY | MMU_PTE_ATTR_SH_INNER_SHAREABLE;
-        break;
-    case ARCH_MMU_FLAG_WRITE_COMBINING:
-        attr |= MMU_S2_PTE_ATTR_NORMAL_UNCACHED | MMU_PTE_ATTR_SH_INNER_SHAREABLE;
-        break;
-    case ARCH_MMU_FLAG_UNCACHED:
-        attr |= MMU_S2_PTE_ATTR_STRONGLY_ORDERED;
-        break;
-    case ARCH_MMU_FLAG_UNCACHED_DEVICE:
-        attr |= MMU_S2_PTE_ATTR_DEVICE;
-        break;
-    default:
-        PANIC_UNIMPLEMENTED;
-    }
-
-    if (flags & ARCH_MMU_FLAG_PERM_WRITE) {
-        attr |= MMU_S2_PTE_ATTR_S2AP_RW;
-    } else {
-        attr |= MMU_S2_PTE_ATTR_S2AP_RO;
-    }
-    if (!(flags & ARCH_MMU_FLAG_PERM_EXECUTE)) {
-        attr |= MMU_S2_PTE_ATTR_XN;
-    }
-
-    return attr;
-}
-
-static void s2_pte_attr_to_mmu_flags(pte_t pte, uint* mmu_flags) {
-    switch (pte & MMU_S2_PTE_ATTR_ATTR_INDEX_MASK) {
-    case MMU_S2_PTE_ATTR_STRONGLY_ORDERED:
-        *mmu_flags |= ARCH_MMU_FLAG_UNCACHED;
-        break;
-    case MMU_S2_PTE_ATTR_DEVICE:
-        *mmu_flags |= ARCH_MMU_FLAG_UNCACHED_DEVICE;
-        break;
-    case MMU_S2_PTE_ATTR_NORMAL_UNCACHED:
-        *mmu_flags |= ARCH_MMU_FLAG_WRITE_COMBINING;
-        break;
-    case MMU_S2_PTE_ATTR_NORMAL_MEMORY:
-        *mmu_flags |= ARCH_MMU_FLAG_CACHED;
-        break;
-    default:
-        PANIC_UNIMPLEMENTED;
-    }
-
-    *mmu_flags |= ARCH_MMU_FLAG_PERM_READ;
-    switch (pte & MMU_PTE_ATTR_AP_MASK) {
-    case MMU_S2_PTE_ATTR_S2AP_RO:
-        break;
-    case MMU_S2_PTE_ATTR_S2AP_RW:
-        *mmu_flags |= ARCH_MMU_FLAG_PERM_WRITE;
-        break;
-    default:
-        PANIC_UNIMPLEMENTED;
-    }
-
-    if (pte & MMU_S2_PTE_ATTR_XN) {
-        *mmu_flags |= ARCH_MMU_FLAG_PERM_EXECUTE;
-    }
-}
-
-zx_status_t ArmArchVmAspace::Query(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags) {
-    fbl::AutoLock a(&lock_);
-    return QueryLocked(vaddr, paddr, mmu_flags);
-}
-
-zx_status_t ArmArchVmAspace::QueryLocked(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags) {
-    ulong index;
-    uint index_shift;
-    uint page_size_shift;
-    pte_t pte;
-    pte_t pte_addr;
-    uint descriptor_type;
-    volatile pte_t* page_table;
-    vaddr_t vaddr_rem;
-
-    canary_.Assert();
-    LTRACEF("aspace %p, vaddr 0x%lx\n", this, vaddr);
-
-    DEBUG_ASSERT(tt_virt_);
-
-    DEBUG_ASSERT(IsValidVaddr(vaddr));
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_OUT_OF_RANGE;
-
-    // Compute shift values based on if this address space is for kernel or user space.
-    if (flags_ & ARCH_ASPACE_FLAG_KERNEL) {
-        index_shift = MMU_KERNEL_TOP_SHIFT;
-        page_size_shift = MMU_KERNEL_PAGE_SIZE_SHIFT;
-
-        vaddr_t kernel_base = ~0UL << MMU_KERNEL_SIZE_SHIFT;
-        vaddr_rem = vaddr - kernel_base;
-
-        index = vaddr_rem >> index_shift;
-        ASSERT(index < MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP);
-    } else if (flags_ & ARCH_ASPACE_FLAG_GUEST) {
-        index_shift = MMU_GUEST_TOP_SHIFT;
-        page_size_shift = MMU_GUEST_PAGE_SIZE_SHIFT;
-
-        vaddr_rem = vaddr;
-        index = vaddr_rem >> index_shift;
-        ASSERT(index < MMU_GUEST_PAGE_TABLE_ENTRIES_TOP);
-    } else {
-        index_shift = MMU_USER_TOP_SHIFT;
-        page_size_shift = MMU_USER_PAGE_SIZE_SHIFT;
-
-        vaddr_rem = vaddr;
-        index = vaddr_rem >> index_shift;
-        ASSERT(index < MMU_USER_PAGE_TABLE_ENTRIES_TOP);
-    }
-
-    page_table = tt_virt_;
-
-    while (true) {
-        index = vaddr_rem >> index_shift;
-        vaddr_rem -= (vaddr_t)index << index_shift;
-        pte = page_table[index];
-        descriptor_type = pte & MMU_PTE_DESCRIPTOR_MASK;
-        pte_addr = pte & MMU_PTE_OUTPUT_ADDR_MASK;
-
-        LTRACEF("va %#" PRIxPTR ", index %lu, index_shift %u, rem %#" PRIxPTR
-                ", pte %#" PRIx64 "\n",
-                vaddr, index, index_shift, vaddr_rem, pte);
-
-        if (descriptor_type == MMU_PTE_DESCRIPTOR_INVALID)
-            return ZX_ERR_NOT_FOUND;
-
-        if (descriptor_type == ((index_shift > page_size_shift) ? MMU_PTE_L012_DESCRIPTOR_BLOCK : MMU_PTE_L3_DESCRIPTOR_PAGE)) {
-            break;
-        }
-
-        if (index_shift <= page_size_shift ||
-            descriptor_type != MMU_PTE_L012_DESCRIPTOR_TABLE) {
-            PANIC_UNIMPLEMENTED;
-        }
-
-        page_table = static_cast<volatile pte_t*>(paddr_to_physmap(pte_addr));
-        index_shift -= page_size_shift - 3;
-    }
-
-    if (paddr)
-        *paddr = pte_addr + vaddr_rem;
-    if (mmu_flags) {
-        *mmu_flags = 0;
-        if (flags_ & ARCH_ASPACE_FLAG_GUEST) {
-            s2_pte_attr_to_mmu_flags(pte, mmu_flags);
-        } else {
-            s1_pte_attr_to_mmu_flags(pte, mmu_flags);
-        }
-    }
-    LTRACEF("va 0x%lx, paddr 0x%lx, flags 0x%x\n",
-            vaddr, paddr ? *paddr : ~0UL, mmu_flags ? *mmu_flags : ~0U);
-    return 0;
-}
-
-zx_status_t ArmArchVmAspace::AllocPageTable(paddr_t* paddrp, uint page_size_shift) {
-    LTRACEF("page_size_shift %u\n", page_size_shift);
-
-    // currently we only support allocating a single page
-    DEBUG_ASSERT(page_size_shift == PAGE_SIZE_SHIFT);
-
-    vm_page_t* page;
-    zx_status_t status = pmm_alloc_page(0, &page, paddrp);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    page->state = VM_PAGE_STATE_MMU;
-    pt_pages_++;
-
-    LOCAL_KTRACE0("page table alloc");
-
-    LTRACEF("allocated 0x%lx\n", *paddrp);
-    return 0;
-}
-
-void ArmArchVmAspace::FreePageTable(void* vaddr, paddr_t paddr, uint page_size_shift) {
-    LTRACEF("vaddr %p paddr 0x%lx page_size_shift %u\n", vaddr, paddr, page_size_shift);
-
-    // currently we only support freeing a single page
-    DEBUG_ASSERT(page_size_shift == PAGE_SIZE_SHIFT);
-
-    vm_page_t* page;
-
-    LOCAL_KTRACE0("page table free");
-
-    page = paddr_to_vm_page(paddr);
-    if (!page) {
-        panic("bad page table paddr 0x%lx\n", paddr);
-    }
-    pmm_free_page(page);
-
-    pt_pages_--;
-}
-
-volatile pte_t* ArmArchVmAspace::GetPageTable(vaddr_t index, uint page_size_shift,
-                                              volatile pte_t* page_table) {
-    pte_t pte;
-    paddr_t paddr;
-    void* vaddr;
-
-    DEBUG_ASSERT(page_size_shift <= MMU_MAX_PAGE_SIZE_SHIFT);
-
-    pte = page_table[index];
-    switch (pte & MMU_PTE_DESCRIPTOR_MASK) {
-    case MMU_PTE_DESCRIPTOR_INVALID: {
-        zx_status_t ret = AllocPageTable(&paddr, page_size_shift);
-        if (ret) {
-            TRACEF("failed to allocate page table\n");
-            return NULL;
-        }
-        vaddr = paddr_to_physmap(paddr);
-
-        LTRACEF("allocated page table, vaddr %p, paddr 0x%lx\n", vaddr, paddr);
-        memset(vaddr, MMU_PTE_DESCRIPTOR_INVALID, 1U << page_size_shift);
-
-        // ensure that the zeroing is observable from hardware page table walkers
-        __dmb(ARM_MB_ISHST);
-
-        pte = paddr | MMU_PTE_L012_DESCRIPTOR_TABLE;
-        page_table[index] = pte;
-        LTRACEF("pte %p[%#" PRIxPTR "] = %#" PRIx64 "\n",
-                page_table, index, pte);
-        return static_cast<volatile pte_t*>(vaddr);
-    }
-    case MMU_PTE_L012_DESCRIPTOR_TABLE:
-        paddr = pte & MMU_PTE_OUTPUT_ADDR_MASK;
-        LTRACEF("found page table %#" PRIxPTR "\n", paddr);
-        return static_cast<volatile pte_t*>(paddr_to_physmap(paddr));
-
-    case MMU_PTE_L012_DESCRIPTOR_BLOCK:
-        return NULL;
-
-    default:
-        PANIC_UNIMPLEMENTED;
-    }
-}
-
-static bool page_table_is_clear(volatile pte_t* page_table, uint page_size_shift) {
-    int i;
-    int count = 1U << (page_size_shift - 3);
-    pte_t pte;
-
-    for (i = 0; i < count; i++) {
-        pte = page_table[i];
-        if (pte != MMU_PTE_DESCRIPTOR_INVALID) {
-            LTRACEF("page_table at %p still in use, index %d is %#" PRIx64 "\n",
-                    page_table, i, pte);
-            return false;
-        }
-    }
-
-    LTRACEF("page table at %p is clear\n", page_table);
-    return true;
-}
-
-// use the appropriate TLB flush instruction to globally flush the modified entry
-// terminal is set when flushing at the final level of the page table.
-void ArmArchVmAspace::FlushTLBEntry(vaddr_t vaddr, bool terminal) {
-    if (flags_ & ARCH_ASPACE_FLAG_GUEST) {
-        paddr_t vttbr = arm64_vttbr(asid_, tt_phys_);
-        __UNUSED zx_status_t status = arm64_el2_tlbi_ipa(vttbr, vaddr, terminal);
-        DEBUG_ASSERT(status == ZX_OK);
-    } else if (asid_ == MMU_ARM64_GLOBAL_ASID) {
-        // flush this address on all ASIDs
-        if (terminal) {
-            ARM64_TLBI(vaale1is, vaddr >> 12);
-        } else {
-            ARM64_TLBI(vaae1is, vaddr >> 12);
-        }
-    } else {
-        // flush this address for the specific asid
-        if (terminal) {
-            ARM64_TLBI(vale1is, vaddr >> 12 | (vaddr_t)asid_ << 48);
-        } else {
-            ARM64_TLBI(vae1is, vaddr >> 12 | (vaddr_t)asid_ << 48);
-        }
-    }
-}
-
-// NOTE: caller must DSB afterwards to ensure TLB entries are flushed
-ssize_t ArmArchVmAspace::UnmapPageTable(vaddr_t vaddr, vaddr_t vaddr_rel,
-                                        size_t size, uint index_shift,
-                                        uint page_size_shift,
-                                        volatile pte_t* page_table) {
-    volatile pte_t* next_page_table;
-    vaddr_t index;
-    size_t chunk_size;
-    vaddr_t vaddr_rem;
-    vaddr_t block_size;
-    vaddr_t block_mask;
-    pte_t pte;
-    paddr_t page_table_paddr;
-    size_t unmap_size;
-
-    LTRACEF("vaddr 0x%lx, vaddr_rel 0x%lx, size 0x%lx, index shift %u, page_size_shift %u, page_table %p\n",
-            vaddr, vaddr_rel, size, index_shift, page_size_shift, page_table);
-
-    unmap_size = 0;
-    while (size) {
-        block_size = 1UL << index_shift;
-        block_mask = block_size - 1;
-        vaddr_rem = vaddr_rel & block_mask;
-        chunk_size = MIN(size, block_size - vaddr_rem);
-        index = vaddr_rel >> index_shift;
-
-        pte = page_table[index];
-
-        if (index_shift > page_size_shift &&
-            (pte & MMU_PTE_DESCRIPTOR_MASK) == MMU_PTE_L012_DESCRIPTOR_TABLE) {
-            page_table_paddr = pte & MMU_PTE_OUTPUT_ADDR_MASK;
-            next_page_table = static_cast<volatile pte_t*>(paddr_to_physmap(page_table_paddr));
-            UnmapPageTable(vaddr, vaddr_rem, chunk_size,
-                           index_shift - (page_size_shift - 3),
-                           page_size_shift, next_page_table);
-            if (chunk_size == block_size ||
-                page_table_is_clear(next_page_table, page_size_shift)) {
-                LTRACEF("pte %p[0x%lx] = 0 (was page table)\n", page_table, index);
-                page_table[index] = MMU_PTE_DESCRIPTOR_INVALID;
-
-                // ensure that the update is observable from hardware page table walkers
-                __dmb(ARM_MB_ISHST);
-
-                // flush the non terminal TLB entry
-                FlushTLBEntry(vaddr, false);
-
-                FreePageTable(const_cast<pte_t*>(next_page_table), page_table_paddr,
-                              page_size_shift);
-            }
-        } else if (pte) {
-            LTRACEF("pte %p[0x%lx] = 0\n", page_table, index);
-            page_table[index] = MMU_PTE_DESCRIPTOR_INVALID;
-
-            // ensure that the update is observable from hardware page table walkers
-            __dmb(ARM_MB_ISHST);
-
-            // flush the terminal TLB entry
-            FlushTLBEntry(vaddr, true);
-        } else {
-            LTRACEF("pte %p[0x%lx] already clear\n", page_table, index);
-        }
-        vaddr += chunk_size;
-        vaddr_rel += chunk_size;
-        size -= chunk_size;
-        unmap_size += chunk_size;
-    }
-
-    return unmap_size;
-}
-
-// NOTE: caller must DSB afterwards to ensure TLB entries are flushed
-ssize_t ArmArchVmAspace::MapPageTable(vaddr_t vaddr_in, vaddr_t vaddr_rel_in,
-                                      paddr_t paddr_in, size_t size_in,
-                                      pte_t attrs, uint index_shift,
-                                      uint page_size_shift,
-                                      volatile pte_t* page_table) {
-    ssize_t ret;
-    volatile pte_t* next_page_table;
-    vaddr_t index;
-    vaddr_t vaddr = vaddr_in;
-    vaddr_t vaddr_rel = vaddr_rel_in;
-    paddr_t paddr = paddr_in;
-    size_t size = size_in;
-    size_t chunk_size;
-    vaddr_t vaddr_rem;
-    vaddr_t block_size;
-    vaddr_t block_mask;
-    pte_t pte;
-    size_t mapped_size;
-
-    LTRACEF("vaddr %#" PRIxPTR ", vaddr_rel %#" PRIxPTR ", paddr %#" PRIxPTR
-            ", size %#zx, attrs %#" PRIx64
-            ", index shift %u, page_size_shift %u, page_table %p\n",
-            vaddr, vaddr_rel, paddr, size, attrs,
-            index_shift, page_size_shift, page_table);
-
-    if ((vaddr_rel | paddr | size) & ((1UL << page_size_shift) - 1)) {
-        TRACEF("not page aligned\n");
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    mapped_size = 0;
-    while (size) {
-        block_size = 1UL << index_shift;
-        block_mask = block_size - 1;
-        vaddr_rem = vaddr_rel & block_mask;
-        chunk_size = MIN(size, block_size - vaddr_rem);
-        index = vaddr_rel >> index_shift;
-
-        if (((vaddr_rel | paddr) & block_mask) ||
-            (chunk_size != block_size) ||
-            (index_shift > MMU_PTE_DESCRIPTOR_BLOCK_MAX_SHIFT)) {
-            next_page_table = GetPageTable(index, page_size_shift, page_table);
-            if (!next_page_table)
-                goto err;
-
-            ret = MapPageTable(vaddr, vaddr_rem, paddr, chunk_size, attrs,
-                               index_shift - (page_size_shift - 3),
-                               page_size_shift, next_page_table);
-            if (ret < 0)
-                goto err;
-        } else {
-            pte = page_table[index];
-            if (pte) {
-                TRACEF("page table entry already in use, index %#" PRIxPTR ", %#" PRIx64 "\n",
-                       index, pte);
-                goto err;
-            }
-
-            pte = paddr | attrs;
-            if (index_shift > page_size_shift)
-                pte |= MMU_PTE_L012_DESCRIPTOR_BLOCK;
-            else
-                pte |= MMU_PTE_L3_DESCRIPTOR_PAGE;
-            if (!(flags_ & ARCH_ASPACE_FLAG_GUEST))
-                pte |= MMU_PTE_ATTR_NON_GLOBAL;
-            LTRACEF("pte %p[%#" PRIxPTR "] = %#" PRIx64 "\n",
-                    page_table, index, pte);
-            page_table[index] = pte;
-        }
-        vaddr += chunk_size;
-        vaddr_rel += chunk_size;
-        paddr += chunk_size;
-        size -= chunk_size;
-        mapped_size += chunk_size;
-    }
-
-    return mapped_size;
-
-err:
-    UnmapPageTable(vaddr_in, vaddr_rel_in, size_in - size, index_shift,
-                   page_size_shift, page_table);
-    return ZX_ERR_INTERNAL;
-}
-
-// NOTE: caller must DSB afterwards to ensure TLB entries are flushed
-int ArmArchVmAspace::ProtectPageTable(vaddr_t vaddr_in, vaddr_t vaddr_rel_in,
-                                      size_t size_in, pte_t attrs,
-                                      uint index_shift, uint page_size_shift,
-                                      volatile pte_t* page_table) {
-    int ret;
-    volatile pte_t* next_page_table;
-    vaddr_t index;
-    vaddr_t vaddr = vaddr_in;
-    vaddr_t vaddr_rel = vaddr_rel_in;
-    size_t size = size_in;
-    size_t chunk_size;
-    vaddr_t vaddr_rem;
-    vaddr_t block_size;
-    vaddr_t block_mask;
-    paddr_t page_table_paddr;
-    pte_t pte;
-
-    LTRACEF("vaddr %#" PRIxPTR ", vaddr_rel %#" PRIxPTR ", size %#" PRIxPTR
-            ", attrs %#" PRIx64
-            ", index shift %u, page_size_shift %u, page_table %p\n",
-            vaddr, vaddr_rel, size, attrs,
-            index_shift, page_size_shift, page_table);
-
-    if ((vaddr_rel | size) & ((1UL << page_size_shift) - 1)) {
-        TRACEF("not page aligned\n");
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    while (size) {
-        block_size = 1UL << index_shift;
-        block_mask = block_size - 1;
-        vaddr_rem = vaddr_rel & block_mask;
-        chunk_size = MIN(size, block_size - vaddr_rem);
-        index = vaddr_rel >> index_shift;
-        pte = page_table[index];
-
-        if (index_shift > page_size_shift &&
-            (pte & MMU_PTE_DESCRIPTOR_MASK) == MMU_PTE_L012_DESCRIPTOR_TABLE) {
-            page_table_paddr = pte & MMU_PTE_OUTPUT_ADDR_MASK;
-            next_page_table = static_cast<volatile pte_t*>(paddr_to_physmap(page_table_paddr));
-            ret = ProtectPageTable(vaddr, vaddr_rem, chunk_size, attrs,
-                                   index_shift - (page_size_shift - 3),
-                                   page_size_shift, next_page_table);
-            if (ret != 0) {
-                goto err;
-            }
-        } else if (pte) {
-            pte = (pte & ~MMU_PTE_PERMISSION_MASK) | attrs;
-            LTRACEF("pte %p[%#" PRIxPTR "] = %#" PRIx64 "\n",
-                    page_table, index, pte);
-            page_table[index] = pte;
-
-            // ensure that the update is observable from hardware page table walkers
-            __dmb(ARM_MB_ISHST);
-
-            // flush the terminal TLB entry
-            FlushTLBEntry(vaddr, true);
-        } else {
-            LTRACEF("page table entry does not exist, index %#" PRIxPTR
-                    ", %#" PRIx64 "\n",
-                    index, pte);
-        }
-        vaddr += chunk_size;
-        vaddr_rel += chunk_size;
-        size -= chunk_size;
-    }
-
-    return 0;
-
-err:
-    // TODO: Unroll any changes we've made, though in practice if we've reached
-    // here there's a programming bug since the higher level region abstraction
-    // should guard against us trying to change permissions on an umapped page
-    return ZX_ERR_INTERNAL;
-}
-
-// internal routine to map a run of pages
-ssize_t ArmArchVmAspace::MapPages(vaddr_t vaddr, paddr_t paddr, size_t size,
-                                  pte_t attrs, vaddr_t vaddr_base, uint top_size_shift,
-                                  uint top_index_shift, uint page_size_shift) {
-    vaddr_t vaddr_rel = vaddr - vaddr_base;
-    vaddr_t vaddr_rel_max = 1UL << top_size_shift;
-
-    LTRACEF("vaddr %#" PRIxPTR ", paddr %#" PRIxPTR ", size %#" PRIxPTR
-            ", attrs %#" PRIx64 ", asid %#x\n",
-            vaddr, paddr, size, attrs, asid_);
-
-    if (vaddr_rel > vaddr_rel_max - size || size > vaddr_rel_max) {
-        TRACEF("vaddr %#" PRIxPTR ", size %#" PRIxPTR " out of range vaddr %#" PRIxPTR ", size %#" PRIxPTR "\n",
-               vaddr, size, vaddr_base, vaddr_rel_max);
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    LOCAL_KTRACE64("mmu map", (vaddr & ~PAGE_MASK) | ((size >> PAGE_SIZE_SHIFT) & PAGE_MASK));
-    ssize_t ret = MapPageTable(vaddr, vaddr_rel, paddr, size, attrs,
-                               top_index_shift, page_size_shift, tt_virt_);
-    __dsb(ARM_MB_SY);
-    return ret;
-}
-
-ssize_t ArmArchVmAspace::UnmapPages(vaddr_t vaddr, size_t size,
-                                    vaddr_t vaddr_base,
-                                    uint top_size_shift,
-                                    uint top_index_shift,
-                                    uint page_size_shift) {
-    vaddr_t vaddr_rel = vaddr - vaddr_base;
-    vaddr_t vaddr_rel_max = 1UL << top_size_shift;
-
-    LTRACEF("vaddr 0x%lx, size 0x%lx, asid 0x%x\n", vaddr, size, asid_);
-
-    if (vaddr_rel > vaddr_rel_max - size || size > vaddr_rel_max) {
-        TRACEF("vaddr 0x%lx, size 0x%lx out of range vaddr 0x%lx, size 0x%lx\n",
-               vaddr, size, vaddr_base, vaddr_rel_max);
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    LOCAL_KTRACE64("mmu unmap", (vaddr & ~PAGE_MASK) | ((size >> PAGE_SIZE_SHIFT) & PAGE_MASK));
-
-    ssize_t ret = UnmapPageTable(vaddr, vaddr_rel, size, top_index_shift,
-                                 page_size_shift, tt_virt_);
-    __dsb(ARM_MB_SY);
-    return ret;
-}
-
-zx_status_t ArmArchVmAspace::ProtectPages(vaddr_t vaddr, size_t size, pte_t attrs,
-                                          vaddr_t vaddr_base, uint top_size_shift,
-                                          uint top_index_shift, uint page_size_shift) {
-    vaddr_t vaddr_rel = vaddr - vaddr_base;
-    vaddr_t vaddr_rel_max = 1UL << top_size_shift;
-
-    LTRACEF("vaddr %#" PRIxPTR ", size %#" PRIxPTR ", attrs %#" PRIx64
-            ", asid %#x\n",
-            vaddr, size, attrs, asid_);
-
-    if (vaddr_rel > vaddr_rel_max - size || size > vaddr_rel_max) {
-        TRACEF("vaddr %#" PRIxPTR ", size %#" PRIxPTR " out of range vaddr %#" PRIxPTR ", size %#" PRIxPTR "\n",
-               vaddr, size, vaddr_base, vaddr_rel_max);
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    LOCAL_KTRACE64("mmu protect", (vaddr & ~PAGE_MASK) | ((size >> PAGE_SIZE_SHIFT) & PAGE_MASK));
-
-    zx_status_t ret = ProtectPageTable(vaddr, vaddr_rel, size, attrs,
-                                       top_index_shift, page_size_shift,
-                                       tt_virt_);
-    __dsb(ARM_MB_SY);
-    return ret;
-}
-
-void ArmArchVmAspace::MmuParamsFromFlags(uint mmu_flags,
-                                         pte_t* attrs, vaddr_t* vaddr_base,
-                                         uint* top_size_shift, uint* top_index_shift,
-                                         uint* page_size_shift) {
-
-    if (flags_ & ARCH_ASPACE_FLAG_KERNEL) {
-        if (attrs) {
-            *attrs = mmu_flags_to_s1_pte_attr(mmu_flags);
-        }
-        *vaddr_base = ~0UL << MMU_KERNEL_SIZE_SHIFT;
-        *top_size_shift = MMU_KERNEL_SIZE_SHIFT;
-        *top_index_shift = MMU_KERNEL_TOP_SHIFT;
-        *page_size_shift = MMU_KERNEL_PAGE_SIZE_SHIFT;
-    } else if (flags_ & ARCH_ASPACE_FLAG_GUEST) {
-        if (attrs) {
-            *attrs = mmu_flags_to_s2_pte_attr(mmu_flags);
-        }
-        *vaddr_base = 0;
-        *top_size_shift = MMU_GUEST_SIZE_SHIFT;
-        *top_index_shift = MMU_GUEST_TOP_SHIFT;
-        *page_size_shift = MMU_GUEST_PAGE_SIZE_SHIFT;
-    } else {
-        if (attrs) {
-            *attrs = mmu_flags_to_s1_pte_attr(mmu_flags);
-        }
-        *vaddr_base = 0;
-        *top_size_shift = MMU_USER_SIZE_SHIFT;
-        *top_index_shift = MMU_USER_TOP_SHIFT;
-        *page_size_shift = MMU_USER_PAGE_SIZE_SHIFT;
-    }
-}
-
-zx_status_t ArmArchVmAspace::MapContiguous(vaddr_t vaddr, paddr_t paddr, size_t count,
-                                           uint mmu_flags, size_t* mapped) {
-    canary_.Assert();
-    LTRACEF("vaddr %#" PRIxPTR " paddr %#" PRIxPTR " count %zu flags %#x\n",
-            vaddr, paddr, count, mmu_flags);
-
-    DEBUG_ASSERT(tt_virt_);
-
-    DEBUG_ASSERT(IsValidVaddr(vaddr));
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_OUT_OF_RANGE;
-
-    if (!(mmu_flags & ARCH_MMU_FLAG_PERM_READ))
-        return ZX_ERR_INVALID_ARGS;
-
-    // paddr and vaddr must be aligned.
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(vaddr));
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(paddr));
-    if (!IS_PAGE_ALIGNED(vaddr) || !IS_PAGE_ALIGNED(paddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    if (count == 0)
-        return ZX_OK;
-
-    ssize_t ret;
-    {
-        fbl::AutoLock a(&lock_);
-        pte_t attrs;
-        vaddr_t vaddr_base;
-        uint top_size_shift, top_index_shift, page_size_shift;
-        MmuParamsFromFlags(mmu_flags, &attrs, &vaddr_base, &top_size_shift, &top_index_shift,
-                           &page_size_shift);
-        ret = MapPages(vaddr, paddr, count * PAGE_SIZE,
-                       attrs, vaddr_base, top_size_shift,
-                       top_index_shift, page_size_shift);
-    }
-
-    if (mapped) {
-        *mapped = (ret > 0) ? (ret / PAGE_SIZE) : 0u;
-        DEBUG_ASSERT(*mapped <= count);
-    }
-
-    return (ret < 0) ? (zx_status_t)ret : ZX_OK;
-}
-
-zx_status_t ArmArchVmAspace::Map(vaddr_t vaddr, paddr_t* phys, size_t count, uint mmu_flags,
-                                 size_t* mapped) {
-    canary_.Assert();
-    LTRACEF("vaddr %#" PRIxPTR " count %zu flags %#x\n",
-            vaddr, count, mmu_flags);
-
-    DEBUG_ASSERT(tt_virt_);
-
-    DEBUG_ASSERT(IsValidVaddr(vaddr));
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_OUT_OF_RANGE;
-    for (size_t i = 0; i < count; ++i) {
-        DEBUG_ASSERT(IS_PAGE_ALIGNED(phys[i]));
-        if (!IS_PAGE_ALIGNED(phys[i]))
-            return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (!(mmu_flags & ARCH_MMU_FLAG_PERM_READ))
-        return ZX_ERR_INVALID_ARGS;
-
-    // vaddr must be aligned.
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(vaddr));
-    if (!IS_PAGE_ALIGNED(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    if (count == 0)
-        return ZX_OK;
-
-    size_t total_mapped = 0;
-    {
-        fbl::AutoLock a(&lock_);
-        pte_t attrs;
-        vaddr_t vaddr_base;
-        uint top_size_shift, top_index_shift, page_size_shift;
-        MmuParamsFromFlags(mmu_flags, &attrs, &vaddr_base, &top_size_shift, &top_index_shift,
-                           &page_size_shift);
-
-        ssize_t ret;
-        size_t idx = 0;
-        auto undo = fbl::MakeAutoCall([&]() TA_NO_THREAD_SAFETY_ANALYSIS {
-            if (idx > 0) {
-                UnmapPages(vaddr, idx * PAGE_SIZE, vaddr_base, top_size_shift,
-                           top_index_shift, page_size_shift);
-            }
-        });
-
-        vaddr_t v = vaddr;
-        for (; idx < count; ++idx) {
-            paddr_t paddr = phys[idx];
-            DEBUG_ASSERT(IS_PAGE_ALIGNED(paddr));
-            // TODO: optimize by not DSBing inside each of these calls
-            ret = MapPages(v, paddr, PAGE_SIZE,
-                           attrs, vaddr_base, top_size_shift,
-                           top_index_shift, page_size_shift);
-            if (ret < 0) {
-                return static_cast<zx_status_t>(ret);
-            }
-
-            v += PAGE_SIZE;
-            total_mapped += ret / PAGE_SIZE;
-        }
-        undo.cancel();
-    }
-    DEBUG_ASSERT(total_mapped <= count);
-
-    if (mapped) {
-        *mapped = total_mapped;
-    }
-
-    return ZX_OK;
-}
-
-zx_status_t ArmArchVmAspace::Unmap(vaddr_t vaddr, size_t count, size_t* unmapped) {
-    canary_.Assert();
-    LTRACEF("vaddr %#" PRIxPTR " count %zu\n", vaddr, count);
-
-    DEBUG_ASSERT(tt_virt_);
-
-    DEBUG_ASSERT(IsValidVaddr(vaddr));
-
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_OUT_OF_RANGE;
-
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(vaddr));
-    if (!IS_PAGE_ALIGNED(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    fbl::AutoLock a(&lock_);
-
-    ssize_t ret;
-    {
-        vaddr_t vaddr_base;
-        uint top_size_shift, top_index_shift, page_size_shift;
-        MmuParamsFromFlags(0, nullptr, &vaddr_base, &top_size_shift, &top_index_shift,
-                           &page_size_shift);
-
-        ret = UnmapPages(vaddr, count * PAGE_SIZE,
-                         vaddr_base, top_size_shift,
-                         top_index_shift, page_size_shift);
-    }
-
-    if (unmapped) {
-        *unmapped = (ret > 0) ? (ret / PAGE_SIZE) : 0u;
-        DEBUG_ASSERT(*unmapped <= count);
-    }
-
-    return (ret < 0) ? (zx_status_t)ret : 0;
-}
-
-zx_status_t ArmArchVmAspace::Protect(vaddr_t vaddr, size_t count, uint mmu_flags) {
-    canary_.Assert();
-
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    if (!IS_PAGE_ALIGNED(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    if (!(mmu_flags & ARCH_MMU_FLAG_PERM_READ))
-        return ZX_ERR_INVALID_ARGS;
-
-    fbl::AutoLock a(&lock_);
-
-    int ret;
-    {
-        pte_t attrs;
-        vaddr_t vaddr_base;
-        uint top_size_shift, top_index_shift, page_size_shift;
-        MmuParamsFromFlags(mmu_flags, &attrs, &vaddr_base, &top_size_shift, &top_index_shift,
-                           &page_size_shift);
-
-        ret = ProtectPages(vaddr, count * PAGE_SIZE,
-                           attrs, vaddr_base,
-                           top_size_shift, top_index_shift, page_size_shift);
-    }
-
-    return ret;
-}
-
-zx_status_t ArmArchVmAspace::Init(vaddr_t base, size_t size, uint flags) {
-    canary_.Assert();
-    LTRACEF("aspace %p, base %#" PRIxPTR ", size 0x%zx, flags 0x%x\n",
-            this, base, size, flags);
-
-    fbl::AutoLock a(&lock_);
-
-    // Validate that the base + size is sane and doesn't wrap.
-    DEBUG_ASSERT(size > PAGE_SIZE);
-    DEBUG_ASSERT(base + size - 1 > base);
-
-    flags_ = flags;
-    if (flags & ARCH_ASPACE_FLAG_KERNEL) {
-        // At the moment we can only deal with address spaces as globally defined.
-        DEBUG_ASSERT(base == ~0UL << MMU_KERNEL_SIZE_SHIFT);
-        DEBUG_ASSERT(size == 1UL << MMU_KERNEL_SIZE_SHIFT);
-
-        base_ = base;
-        size_ = size;
-        tt_virt_ = arm64_kernel_translation_table;
-        tt_phys_ = vaddr_to_paddr(const_cast<pte_t*>(tt_virt_));
-        asid_ = (uint16_t)MMU_ARM64_GLOBAL_ASID;
-    } else {
-        if (flags & ARCH_ASPACE_FLAG_GUEST) {
-            DEBUG_ASSERT(base + size <= 1UL << MMU_GUEST_SIZE_SHIFT);
-        } else {
-            DEBUG_ASSERT(base + size <= 1UL << MMU_USER_SIZE_SHIFT);
-            if (asid.Alloc(&asid_) != ZX_OK)
-                return ZX_ERR_NO_MEMORY;
-        }
-
-        base_ = base;
-        size_ = size;
-
-        paddr_t pa;
-        vm_page_t* page;
-        zx_status_t status = pmm_alloc_page(0, &page, &pa);
-        if (status != ZX_OK) {
-            return status;
-        }
-        page->state = VM_PAGE_STATE_MMU;
-
-        volatile pte_t* va = static_cast<volatile pte_t*>(paddr_to_physmap(pa));
-
-        tt_virt_ = va;
-        tt_phys_ = pa;
-
-        // zero the top level translation table.
-        // XXX remove when PMM starts returning pre-zeroed pages.
-        arch_zero_page(const_cast<pte_t*>(tt_virt_));
-    }
-    pt_pages_ = 1;
-
-    LTRACEF("tt_phys %#" PRIxPTR " tt_virt %p\n", tt_phys_, tt_virt_);
-
-    return ZX_OK;
-}
-
-zx_status_t ArmArchVmAspace::Destroy() {
-    canary_.Assert();
-    LTRACEF("aspace %p\n", this);
-
-    fbl::AutoLock a(&lock_);
-
-    DEBUG_ASSERT((flags_ & ARCH_ASPACE_FLAG_KERNEL) == 0);
-
-    // XXX make sure it's not mapped
-
-    vm_page_t* page = paddr_to_vm_page(tt_phys_);
-    DEBUG_ASSERT(page);
-    pmm_free_page(page);
-
-    if (flags_ & ARCH_ASPACE_FLAG_GUEST) {
-        paddr_t vttbr = arm64_vttbr(asid_, tt_phys_);
-        __UNUSED zx_status_t status = arm64_el2_tlbi_vmid(vttbr);
-        DEBUG_ASSERT(status == ZX_OK);
-    } else {
-        ARM64_TLBI(ASIDE1IS, asid_);
-        asid.Free(asid_);
-        asid_ = MMU_ARM64_UNUSED_ASID;
-    }
-
-    return ZX_OK;
-}
-
-void ArmArchVmAspace::ContextSwitch(ArmArchVmAspace* old_aspace, ArmArchVmAspace* aspace) {
-    if (TRACE_CONTEXT_SWITCH)
-        TRACEF("aspace %p\n", aspace);
-
-    uint64_t tcr;
-    uint64_t ttbr;
-    if (aspace) {
-        aspace->canary_.Assert();
-        DEBUG_ASSERT((aspace->flags_ & (ARCH_ASPACE_FLAG_KERNEL | ARCH_ASPACE_FLAG_GUEST)) == 0);
-
-        tcr = MMU_TCR_FLAGS_USER;
-        ttbr = ((uint64_t)aspace->asid_ << 48) | aspace->tt_phys_;
-        __arm_wsr64("ttbr0_el1", ttbr);
-        __isb(ARM_MB_SY);
-
-        if (TRACE_CONTEXT_SWITCH)
-            TRACEF("ttbr %#" PRIx64 ", tcr %#" PRIx64 "\n", ttbr, tcr);
-
-    } else {
-        tcr = MMU_TCR_FLAGS_KERNEL;
-
-        if (TRACE_CONTEXT_SWITCH)
-            TRACEF("tcr %#" PRIx64 "\n", tcr);
-    }
-
-    __arm_wsr64("tcr_el1", tcr);
-    __isb(ARM_MB_SY);
-}
-
-void arch_zero_page(void* _ptr) {
-    uintptr_t ptr = (uintptr_t)_ptr;
-
-    uint32_t zva_size = arm64_zva_size;
-    uintptr_t end_ptr = ptr + PAGE_SIZE;
-    do {
-        __asm volatile("dc zva, %0" ::"r"(ptr));
-        ptr += zva_size;
-    } while (ptr != end_ptr);
-}
-
-zx_status_t arm64_mmu_translate(vaddr_t va, paddr_t* pa, bool user, bool write) {
-    // disable interrupts around this operation to make the at/par instruction combination atomic
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
-
-    if (user) {
-        if (write) {
-            __asm__ volatile("at s1e0w, %0" ::"r"(va)
-                             : "memory");
-        } else {
-            __asm__ volatile("at s1e0r, %0" ::"r"(va)
-                             : "memory");
-        }
-    } else {
-        if (write) {
-            __asm__ volatile("at s1e1w, %0" ::"r"(va)
-                             : "memory");
-        } else {
-            __asm__ volatile("at s1e1r, %0" ::"r"(va)
-                             : "memory");
-        }
-    }
-
-    uint64_t par = __arm_rsr64("par_el1");
-
-    arch_interrupt_restore(state, ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS);
-
-    // if bit 0 is clear, the translation succeeded
-    if (BIT(par, 0))
-        return ZX_ERR_NO_MEMORY;
-
-    // physical address is stored in bits [51..12], naturally aligned
-    *pa = BITS(par, 51, 12) | (va & (PAGE_SIZE - 1));
-
-    return ZX_OK;
-}
-
-ArmArchVmAspace::ArmArchVmAspace() {}
-
-ArmArchVmAspace::~ArmArchVmAspace() {
-    // TODO: check that we've destroyed the aspace
-}
-
-vaddr_t ArmArchVmAspace::PickSpot(vaddr_t base, uint prev_region_mmu_flags,
-                                  vaddr_t end, uint next_region_mmu_flags,
-                                  vaddr_t align, size_t size, uint mmu_flags) {
-    canary_.Assert();
-    return PAGE_ALIGN(base);
-}
diff --git a/kernel/arch/arm64/mp.cpp b/kernel/arch/arm64/mp.cpp
deleted file mode 100644
index e3e4d86..0000000
--- a/kernel/arch/arm64/mp.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/mp.h>
-
-#include <arch/ops.h>
-#include <assert.h>
-#include <dev/interrupt.h>
-#include <err.h>
-#include <kernel/event.h>
-#include <platform.h>
-#include <trace.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-namespace {
-// Mask the MPIDR register to only leave the AFFx ids.
-constexpr uint64_t kMpidAffMask = 0xFF00FFFFFF;
-
-struct MpidCpuidPair {
-    uint64_t mpid;
-    uint cpu_id;
-};
-
-// TODO(ZX-3068) Switch completely to list and remove map.
-bool use_cpu_map = true;
-
-// map of cluster/cpu to cpu_id
-uint arm64_cpu_map[SMP_CPU_MAX_CLUSTERS][SMP_CPU_MAX_CLUSTER_CPUS] = {{0}};
-MpidCpuidPair arm64_cpu_list[SMP_MAX_CPUS];
-size_t arm64_cpu_list_count = 0;
-
-} // namespace
-
-// cpu id to cluster and id within cluster map
-uint arm64_cpu_cluster_ids[SMP_MAX_CPUS] = {0};
-uint arm64_cpu_cpu_ids[SMP_MAX_CPUS] = {0};
-
-// total number of detected cpus
-uint arm_num_cpus = 1;
-
-// per cpu structures, each cpu will point to theirs using the x18 register
-arm64_percpu arm64_percpu_array[SMP_MAX_CPUS];
-
-// initializes cpu_map and arm_num_cpus
-void arch_init_cpu_map(uint cluster_count, const uint* cluster_cpus) {
-    ASSERT(cluster_count <= SMP_CPU_MAX_CLUSTERS);
-
-    // assign cpu_ids sequentially
-    uint cpu_id = 0;
-    for (uint cluster = 0; cluster < cluster_count; cluster++) {
-        uint cpus = *cluster_cpus++;
-        ASSERT(cpus <= SMP_CPU_MAX_CLUSTER_CPUS);
-        for (uint cpu = 0; cpu < cpus; cpu++) {
-            // given cluster:cpu, translate to global cpu id
-            arm64_cpu_map[cluster][cpu] = cpu_id;
-
-            // given global gpu_id, translate to cluster and cpu number within cluster
-            arm64_cpu_cluster_ids[cpu_id] = cluster;
-            arm64_cpu_cpu_ids[cpu_id] = cpu;
-
-            // set the per cpu structure's cpu id
-            arm64_percpu_array[cpu_id].cpu_num = cpu_id;
-
-            cpu_id++;
-        }
-    }
-    arm_num_cpus = cpu_id;
-    use_cpu_map = true;
-    smp_mb();
-}
-
-void arch_register_mpid(uint cpu_id, uint64_t mpid) {
-    // TODO(ZX-3068) transition off of these maps to the topology.
-    arm64_cpu_cluster_ids[cpu_id] = (mpid & 0xFF00) >> MPIDR_AFF1_SHIFT; // "cluster" here is AFF1.
-    arm64_cpu_cpu_ids[cpu_id] = mpid & 0xFF; // "cpu" here is AFF0.
-
-    arm64_percpu_array[cpu_id].cpu_num = cpu_id;
-
-    arm64_cpu_list[arm64_cpu_list_count++] = {.mpid = mpid, .cpu_id = cpu_id};
-
-    use_cpu_map = false;
-}
-
-// do the 'slow' lookup by mpidr to cpu number
-static uint arch_curr_cpu_num_slow() {
-    uint64_t mpidr = __arm_rsr64("mpidr_el1");
-    if (use_cpu_map) {
-        uint cluster = (mpidr & MPIDR_AFF1_MASK) >> MPIDR_AFF1_SHIFT;
-        uint cpu = (mpidr & MPIDR_AFF0_MASK) >> MPIDR_AFF0_SHIFT;
-
-        return arm64_cpu_map[cluster][cpu];
-    } else {
-        mpidr &= kMpidAffMask;
-        for (size_t i = 0; i < arm64_cpu_list_count; ++i) {
-            if (arm64_cpu_list[i].mpid == mpidr) {
-                return arm64_cpu_list[i].cpu_id;
-            }
-        }
-
-        // The only time we shouldn't find a cpu is when the list isn't
-        // defined yet during early boot, in this case the only processor up is 0
-        // so returning 0 is correct.
-        DEBUG_ASSERT(arm64_cpu_list_count == 0);
-
-        return 0;
-    }
-}
-
-cpu_num_t arch_mpid_to_cpu_num(uint cluster, uint cpu) {
-    return arm64_cpu_map[cluster][cpu];
-}
-
-void arch_prepare_current_cpu_idle_state(bool idle) {
-    // no-op
-}
-
-zx_status_t arch_mp_reschedule(cpu_mask_t mask) {
-    return arch_mp_send_ipi(MP_IPI_TARGET_MASK, mask, MP_IPI_RESCHEDULE);
-}
-
-zx_status_t arch_mp_send_ipi(mp_ipi_target_t target, cpu_mask_t mask, mp_ipi_t ipi) {
-    LTRACEF("target %d mask %#x, ipi %d\n", target, mask, ipi);
-
-    // translate the high level target + mask mechanism into just a mask
-    switch (target) {
-    case MP_IPI_TARGET_ALL:
-        mask = (1ul << SMP_MAX_CPUS) - 1;
-        break;
-    case MP_IPI_TARGET_ALL_BUT_LOCAL:
-        mask = (1ul << SMP_MAX_CPUS) - 1;
-        mask &= ~cpu_num_to_mask(arch_curr_cpu_num());
-        break;
-    case MP_IPI_TARGET_MASK:;
-    }
-
-    return interrupt_send_ipi(mask, ipi);
-}
-
-void arm64_init_percpu_early(void) {
-    // slow lookup the current cpu id and setup the percpu structure
-    uint cpu = arch_curr_cpu_num_slow();
-
-    arm64_write_percpu_ptr(&arm64_percpu_array[cpu]);
-}
-
-void arch_mp_init_percpu(void) {
-    interrupt_init_percpu();
-}
-
-void arch_flush_state_and_halt(event_t* flush_done) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    event_signal(flush_done, false);
-    platform_halt_cpu();
-    panic("control should never reach here\n");
-}
-
-zx_status_t arch_mp_prep_cpu_unplug(uint cpu_id) {
-    if (cpu_id == 0 || cpu_id >= arm_num_cpus) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    return ZX_OK;
-}
-
-zx_status_t arch_mp_cpu_unplug(uint cpu_id) {
-    // we do not allow unplugging the bootstrap processor
-    if (cpu_id == 0 || cpu_id >= arm_num_cpus) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    return ZX_OK;
-}
diff --git a/kernel/arch/arm64/periphmap.cpp b/kernel/arch/arm64/periphmap.cpp
deleted file mode 100644
index c25bb37..0000000
--- a/kernel/arch/arm64/periphmap.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/mmu.h>
-#include <arch/arm64/periphmap.h>
-#include <vm/vm.h>
-#include <vm/vm_aspace.h>
-
-#define PERIPH_RANGE_MAX    4
-
-typedef struct {
-    uint64_t base_phys;
-    uint64_t base_virt;
-    uint64_t length;
-} periph_range_t;
-
-static periph_range_t periph_ranges[PERIPH_RANGE_MAX] = {};
-
-zx_status_t add_periph_range(paddr_t base_phys, size_t length) {
-    // peripheral ranges are allocated below the kernel image.
-    uint64_t base_virt = (uint64_t)__code_start;
-
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(base_phys));
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(length));
-
-    for (auto& range : periph_ranges) {
-        if (range.length == 0) {
-            base_virt -= length;
-            auto status = arm64_boot_map_v(base_virt, base_phys, length, MMU_INITIAL_MAP_DEVICE);
-            if (status == ZX_OK) {
-                range.base_phys = base_phys;
-                range.base_virt = base_virt;
-                range.length = length;
-            }
-            return status;
-        } else {
-            base_virt -= range.length;
-        }
-    }
-    return ZX_ERR_OUT_OF_RANGE;
-}
-
-void reserve_periph_ranges() {
-    for (auto& range : periph_ranges) {
-        if (range.length == 0) {
-            break;
-        }
-        VmAspace::kernel_aspace()->ReserveSpace("periph", range.length, range.base_virt);
-    }
-}
-
-vaddr_t periph_paddr_to_vaddr(paddr_t paddr) {
-    for (auto& range : periph_ranges) {
-        if (range.length == 0) {
-            break;
-        } else if (paddr >= range.base_phys) {
-            uint64_t offset = paddr - range.base_phys;
-            if (offset < range.length) {
-                return range.base_virt + offset;
-            }
-        }
-    }
-    return 0;
-}
diff --git a/kernel/arch/arm64/registers.cpp b/kernel/arch/arm64/registers.cpp
deleted file mode 100644
index 1db0fbf..0000000
--- a/kernel/arch/arm64/registers.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64.h>
-#include <arch/arm64/registers.h>
-#include <vm/vm.h>
-
-void arm64_disable_debug_state() {
-    // The KDE bit enables and disables debug exceptions for the current execution.
-    // Instruction Breakpoint Exceptions (software breakpoints) cannot be deactivated.
-    uint32_t mdscr_val = __arm_rsr("mdscr_el1") & ~ARM64_MDSCR_EL1_KDE;
-    __arm_wsr("mdscr_el1", mdscr_val);
-    __isb(ARM_MB_SY);
-}
-
-void arm64_enable_debug_state() {
-    // The KDE bit enables and disables debug exceptions for the current execution.
-    // Instruction Breakpoint Exceptions (software breakpoints) cannot be deactivated.
-    uint32_t mdscr_val = __arm_rsr("mdscr_el1") | ARM64_MDSCR_EL1_KDE;
-    __arm_wsr("mdscr_el1", mdscr_val);
-    __isb(ARM_MB_SY);
-}
-
-bool arm64_validate_debug_state(arm64_debug_state_t* state) {
-    // Validate that the addresses are valid.
-    size_t hw_bp_count = arm64_hw_breakpoint_count();
-    for (size_t i = 0; i < hw_bp_count; i++) {
-        uint64_t addr = state->hw_bps[i].dbgbvr;
-        if (addr != 0 && !is_user_address(addr)) {
-            return false;
-        }
-
-        // Mask out the fields that userspace is not allowed to modify.
-        uint32_t masked_user_bcr = state->hw_bps[i].dbgbcr & ARM64_DBGBCR_USER_MASK;
-        state->hw_bps[i].dbgbcr = ARM64_DBGBCR_MASK | masked_user_bcr;
-    }
-
-    return true;
-}
-
-uint8_t arm64_hw_breakpoint_count() {
-    uint64_t dfr0 = __arm_rsr64("id_aa64dfr0_el1");
-    uint8_t count = (uint8_t)(((dfr0 & ARM64_ID_AADFR0_EL1_BRPS) >>
-                               ARM64_ID_AADFR0_EL1_BRPS_SHIFT) + 1lu);
-    // ARMv8 assures at least 2 hw registers.
-    DEBUG_ASSERT(count >= ARM64_MIN_HW_BREAKPOINTS &&
-                 count <= ARM64_MAX_HW_BREAKPOINTS);
-    return count;
-}
-
-uint8_t arm64_hw_watchpoint_count() {
-    uint64_t dfr0 = __arm_rsr64("id_aa64dfr0_el1");
-    uint8_t count = (uint8_t)(((dfr0 & ARM64_ID_AADFR0_EL1_WRPS) >>
-                               ARM64_ID_AADFR0_EL1_WRPS_SHIFT) + 1lu);
-    // ARMv8 assures at least 2 hw registers.
-    DEBUG_ASSERT(count >= ARM64_MIN_HW_WATCHPOINTS &&
-                 count <= ARM64_MAX_HW_WATCHPOINTS);
-    return count;
-}
-
-// Read Debug State ------------------------------------------------------------------------------
-
-static void arm64_read_hw_breakpoint_by_index(arm64_debug_state_t* debug_state,
-                                              unsigned int index) {
-    DEBUG_ASSERT(index < arm64_hw_breakpoint_count());
-
-    switch (index) {
-    case 0:
-        debug_state->hw_bps[0].dbgbcr = __arm_rsr("dbgbcr0_el1");
-        debug_state->hw_bps[0].dbgbvr = __arm_rsr64("dbgbvr0_el1");
-        break;
-    case 1:
-        debug_state->hw_bps[1].dbgbcr = __arm_rsr("dbgbcr1_el1");
-        debug_state->hw_bps[1].dbgbvr = __arm_rsr64("dbgbvr1_el1");
-        break;
-    case 2:
-        debug_state->hw_bps[2].dbgbcr = __arm_rsr("dbgbcr2_el1");
-        debug_state->hw_bps[2].dbgbvr = __arm_rsr64("dbgbvr2_el1");
-        break;
-    case 3:
-        debug_state->hw_bps[3].dbgbcr = __arm_rsr("dbgbcr3_el1");
-        debug_state->hw_bps[3].dbgbvr = __arm_rsr64("dbgbvr3_el1");
-        break;
-    case 4:
-        debug_state->hw_bps[4].dbgbcr = __arm_rsr("dbgbcr4_el1");
-        debug_state->hw_bps[4].dbgbvr = __arm_rsr64("dbgbvr4_el1");
-        break;
-    case 5:
-        debug_state->hw_bps[5].dbgbcr = __arm_rsr("dbgbcr5_el1");
-        debug_state->hw_bps[5].dbgbvr = __arm_rsr64("dbgbvr5_el1");
-        break;
-    case 6:
-        debug_state->hw_bps[6].dbgbcr = __arm_rsr("dbgbcr6_el1");
-        debug_state->hw_bps[6].dbgbvr = __arm_rsr64("dbgbvr6_el1");
-        break;
-    case 7:
-        debug_state->hw_bps[7].dbgbcr = __arm_rsr("dbgbcr7_el1");
-        debug_state->hw_bps[7].dbgbvr = __arm_rsr64("dbgbvr7_el1");
-        break;
-    case 8:
-        debug_state->hw_bps[8].dbgbcr = __arm_rsr("dbgbcr8_el1");
-        debug_state->hw_bps[8].dbgbvr = __arm_rsr64("dbgbvr8_el1");
-        break;
-    case 9:
-        debug_state->hw_bps[9].dbgbcr = __arm_rsr("dbgbcr9_el1");
-        debug_state->hw_bps[9].dbgbvr = __arm_rsr64("dbgbvr9_el1");
-        break;
-    case 10:
-        debug_state->hw_bps[10].dbgbcr = __arm_rsr("dbgbcr10_el1");
-        debug_state->hw_bps[10].dbgbvr = __arm_rsr64("dbgbvr10_el1");
-        break;
-    case 11:
-        debug_state->hw_bps[11].dbgbcr = __arm_rsr("dbgbcr11_el1");
-        debug_state->hw_bps[11].dbgbvr = __arm_rsr64("dbgbvr11_el1");
-        break;
-    case 12:
-        debug_state->hw_bps[12].dbgbcr = __arm_rsr("dbgbcr12_el1");
-        debug_state->hw_bps[12].dbgbvr = __arm_rsr64("dbgbvr12_el1");
-        break;
-    case 13:
-        debug_state->hw_bps[13].dbgbcr = __arm_rsr("dbgbcr13_el1");
-        debug_state->hw_bps[13].dbgbvr = __arm_rsr64("dbgbvr13_el1");
-        break;
-    case 14:
-        debug_state->hw_bps[14].dbgbcr = __arm_rsr("dbgbcr14_el1");
-        debug_state->hw_bps[14].dbgbvr = __arm_rsr64("dbgbvr14_el1");
-        break;
-    case 15:
-        debug_state->hw_bps[15].dbgbcr = __arm_rsr("dbgbcr15_el1");
-        debug_state->hw_bps[15].dbgbvr = __arm_rsr64("dbgbvr15_el1");
-        break;
-    default:
-        DEBUG_ASSERT(false);
-    }
-}
-
-void arm64_read_hw_debug_regs(arm64_debug_state_t* debug_state) {
-    uint8_t count = arm64_hw_breakpoint_count();
-    for (unsigned int i = 0; i < count; i++) {
-        arm64_read_hw_breakpoint_by_index(debug_state, i);
-    }
-}
-
-// Writing Debug State ---------------------------------------------------------------------------
-
-static void arm64_write_hw_breakpoint_by_index(const arm64_debug_state_t* debug_state,
-                                               unsigned int index) {
-    DEBUG_ASSERT(index < arm64_hw_breakpoint_count());
-
-    switch (index) {
-    case 0:
-        __arm_wsr("dbgbcr0_el1", debug_state->hw_bps[0].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr0_el1", debug_state->hw_bps[0].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 1:
-        __arm_wsr("dbgbcr1_el1", debug_state->hw_bps[1].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr1_el1", debug_state->hw_bps[1].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 2:
-        __arm_wsr("dbgbcr2_el1", debug_state->hw_bps[2].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr2_el1", debug_state->hw_bps[2].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 3:
-        __arm_wsr("dbgbcr3_el1", debug_state->hw_bps[3].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr3_el1", debug_state->hw_bps[3].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 4:
-        __arm_wsr("dbgbcr4_el1", debug_state->hw_bps[4].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr4_el1", debug_state->hw_bps[4].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 5:
-        __arm_wsr("dbgbcr5_el1", debug_state->hw_bps[5].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr5_el1", debug_state->hw_bps[5].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 6:
-        __arm_wsr("dbgbcr6_el1", debug_state->hw_bps[6].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr6_el1", debug_state->hw_bps[6].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 7:
-        __arm_wsr("dbgbcr7_el1", debug_state->hw_bps[7].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr7_el1", debug_state->hw_bps[7].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 8:
-        __arm_wsr("dbgbcr8_el1", debug_state->hw_bps[8].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr8_el1", debug_state->hw_bps[8].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 9:
-        __arm_wsr("dbgbcr9_el1", debug_state->hw_bps[9].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr9_el1", debug_state->hw_bps[9].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 10:
-        __arm_wsr("dbgbcr10_el1", debug_state->hw_bps[10].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr10_el1", debug_state->hw_bps[10].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 11:
-        __arm_wsr("dbgbcr11_el1", debug_state->hw_bps[11].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr11_el1", debug_state->hw_bps[11].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 12:
-        __arm_wsr("dbgbcr12_el1", debug_state->hw_bps[12].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr12_el1", debug_state->hw_bps[12].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 13:
-        __arm_wsr("dbgbcr13_el1", debug_state->hw_bps[13].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr13_el1", debug_state->hw_bps[13].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 14:
-        __arm_wsr("dbgbcr14_el1", debug_state->hw_bps[14].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr14_el1", debug_state->hw_bps[14].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    case 15:
-        __arm_wsr("dbgbcr15_el1", debug_state->hw_bps[15].dbgbcr);
-        __isb(ARM_MB_SY);
-        __arm_wsr64("dbgbvr15_el1", debug_state->hw_bps[15].dbgbvr);
-        __isb(ARM_MB_SY);
-        break;
-    default:
-        DEBUG_ASSERT(false);
-    }
-}
-
-void arm64_write_hw_debug_regs(const arm64_debug_state_t* debug_state) {
-    uint64_t bps_count = arm64_hw_breakpoint_count();
-    for (unsigned int i = 0; i < bps_count; i++) {
-        arm64_write_hw_breakpoint_by_index(debug_state, i);
-    }
-}
diff --git a/kernel/arch/arm64/rules.mk b/kernel/arch/arm64/rules.mk
deleted file mode 100644
index cb72d2d..0000000
--- a/kernel/arch/arm64/rules.mk
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/arch.cpp \
-	$(LOCAL_DIR)/asm.S \
-	$(LOCAL_DIR)/boot-mmu.cpp \
-	$(LOCAL_DIR)/cache-ops.S \
-	$(LOCAL_DIR)/debugger.cpp \
-	$(LOCAL_DIR)/exceptions.S \
-	$(LOCAL_DIR)/exceptions_c.cpp \
-	$(LOCAL_DIR)/feature.cpp \
-	$(LOCAL_DIR)/fpu.cpp \
-	$(LOCAL_DIR)/mexec.S \
-	$(LOCAL_DIR)/mmu.cpp \
-	$(LOCAL_DIR)/periphmap.cpp \
-	$(LOCAL_DIR)/registers.cpp \
-	$(LOCAL_DIR)/smccc.S \
-	$(LOCAL_DIR)/spinlock.cpp \
-	$(LOCAL_DIR)/start.S \
-	$(LOCAL_DIR)/sysreg.cpp \
-	$(LOCAL_DIR)/thread.cpp \
-	$(LOCAL_DIR)/user_copy.S \
-	$(LOCAL_DIR)/user_copy_c.cpp \
-	$(LOCAL_DIR)/uspace_entry.S
-
-MODULE_DEPS += \
-	kernel/dev/iommu/dummy \
-	kernel/lib/bitmap \
-	kernel/lib/crashlog \
-	kernel/object \
-
-KERNEL_DEFINES += \
-	ARM_ISA_ARMV8=1 \
-	ARM_ISA_ARMV8A=1
-
-SMP_MAX_CPUS ?= 16
-
-SMP_CPU_MAX_CLUSTERS ?= 2
-SMP_CPU_MAX_CLUSTER_CPUS ?= $(SMP_MAX_CPUS)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/mp.cpp
-
-KERNEL_DEFINES += \
-	SMP_MAX_CPUS=$(SMP_MAX_CPUS) \
-	SMP_CPU_MAX_CLUSTERS=$(SMP_CPU_MAX_CLUSTERS) \
-	SMP_CPU_MAX_CLUSTER_CPUS=$(SMP_CPU_MAX_CLUSTER_CPUS) \
-
-KERNEL_ASPACE_BASE ?= 0xffff000000000000
-KERNEL_ASPACE_SIZE ?= 0x0001000000000000
-USER_ASPACE_BASE   ?= 0x0000000001000000
-USER_ASPACE_SIZE   ?= 0x0000fffffe000000
-
-GLOBAL_DEFINES += \
-	KERNEL_ASPACE_BASE=$(KERNEL_ASPACE_BASE) \
-	KERNEL_ASPACE_SIZE=$(KERNEL_ASPACE_SIZE) \
-	USER_ASPACE_BASE=$(USER_ASPACE_BASE) \
-	USER_ASPACE_SIZE=$(USER_ASPACE_SIZE)
-
-# kernel is linked to run at the arbitrary address of -4GB
-# peripherals will be mapped just below this mark
-KERNEL_BASE := 0xffffffff00000000
-BOOT_HEADER_SIZE ?= 0x50
-
-KERNEL_DEFINES += \
-	KERNEL_BASE=$(KERNEL_BASE) \
-
-# try to find the toolchain
-include $(LOCAL_DIR)/toolchain.mk
-TOOLCHAIN_PREFIX := $(ARCH_$(ARCH)_TOOLCHAIN_PREFIX)
-
-ARCH_COMPILEFLAGS += $(ARCH_$(ARCH)_COMPILEFLAGS)
-
-# generate code for the fairly generic cortex-a53
-ARCH_COMPILEFLAGS += -mcpu=cortex-a53
-
-CLANG_ARCH := aarch64
-ifeq ($(call TOBOOL,$(USE_CLANG)),true)
-GLOBAL_LDFLAGS += -m aarch64elf
-GLOBAL_MODULE_LDFLAGS += -m aarch64elf
-endif
-GLOBAL_LDFLAGS += -z max-page-size=4096
-
-# The linker writes instructions to work around a CPU bug.
-GLOBAL_LDFLAGS += --fix-cortex-a53-843419
-
-# kernel hard disables floating point
-KERNEL_COMPILEFLAGS += -mgeneral-regs-only
-
-# See engine.mk.
-KEEP_FRAME_POINTER_COMPILEFLAGS += -mno-omit-leaf-frame-pointer
-
-KERNEL_COMPILEFLAGS += -fPIE -include kernel/include/hidden.h
-
-# Clang needs -mcmodel=kernel to tell it to use the right safe-stack ABI for
-# the kernel.
-ifeq ($(call TOBOOL,$(USE_CLANG)),true)
-KERNEL_COMPILEFLAGS += -mcmodel=kernel
-endif
-
-# x18 is reserved in the Fuchsia userland ABI so it can be used
-# for things like -fsanitize=shadow-call-stack.  In the kernel,
-# it's reserved so we can use it to point at the per-CPU structure.
-ARCH_COMPILEFLAGS += -ffixed-x18
-
-include make/module.mk
diff --git a/kernel/arch/arm64/smccc.S b/kernel/arch/arm64/smccc.S
deleted file mode 100644
index 4254319..0000000
--- a/kernel/arch/arm64/smccc.S
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/asm_macros.h>
-
-// The ARM SMCCC v1.0 calling convention provides the following guarantees about registers:
-//
-//  Register     Modified    Return State
-//  X0...X3      Yes         Result values
-//  X4...X17     Yes         Unpredictable
-//  X18...X30    No          Preserved
-//  SP_EL0       No          Preserved
-//  SP_ELx       No          Preserved
-//
-
-// The arm_smccc_smc/hvc functions are almost direct calls to EL3/EL2. The AAPCS64 places the
-// function parameters in x0-x7, which matches the SMCCC input parameters. The return value type
-// is greater than 16 bytes, so the indirect result location register (x8) must be used to
-// populate the result. Since this register is not preserved across the SMC call, it must be
-// stored on the stack. For the purposes of AAPCS64 compatibility, the frame pointer (x29) is
-// also stored on the stack.
-
-// arm_smccc_result_t arm_smccc_smc(uint32_t w0, uint64_t x1, uint64_t x2, uint64_t x3,
-//                                  uint64_t x4, uint64_t x5, uint64_t x6, uint32_t w7);
-FUNCTION(arm_smccc_smc)
-    push_regs x8, x29
-    smc       #0
-    pop_regs  x8, x29
-    stp       x0, x1, [x8]
-    stp       x2, x3, [x8, #16]
-    ret
-END_FUNCTION(arm_smccc_smc)
-
-// arm_smccc_result_t arm_smccc_hvc(uint32_t w0, uint64_t x1, uint64_t x2, uint64_t x3,
-//                                  uint64_t x4, uint64_t x5, uint64_t x6, uint32_t w7);
-FUNCTION(arm_smccc_hvc)
-    push_regs x8, x29
-    hvc       #0
-    pop_regs  x8, x29
-    stp       x0, x1, [x8]
-    stp       x2, x3, [x8, #16]
-    ret
-END_FUNCTION(arm_smccc_hvc)
-
diff --git a/kernel/arch/arm64/spinlock.cpp b/kernel/arch/arm64/spinlock.cpp
deleted file mode 100644
index ac17f15..0000000
--- a/kernel/arch/arm64/spinlock.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/ops.h>
-#include <arch/spinlock.h>
-#include <kernel/atomic.h>
-
-// We need to disable thread safety analysis in this file, since we're
-// implementing the locks themselves.  Without this, the header-level
-// annotations cause Clang to detect violations.
-
-void arch_spin_lock(spin_lock_t* lock) TA_NO_THREAD_SAFETY_ANALYSIS {
-    unsigned long val = arch_curr_cpu_num() + 1;
-    uint64_t temp;
-
-    __asm__ volatile(
-        "sevl;"
-        "1: wfe;"
-        "ldaxr   %[temp], [%[lock]];"
-        "cbnz    %[temp], 1b;"
-        "stxr    %w[temp], %[val], [%[lock]];"
-        "cbnz    %w[temp], 1b;"
-        : [temp] "=&r"(temp)
-        : [lock] "r"(&lock->value), [val] "r"(val)
-        : "cc", "memory");
-}
-
-int arch_spin_trylock(spin_lock_t* lock) TA_NO_THREAD_SAFETY_ANALYSIS {
-    unsigned long val = arch_curr_cpu_num() + 1;
-    uint64_t out;
-
-    __asm__ volatile(
-        "ldaxr   %[out], [%[lock]];"
-        "cbnz    %[out], 1f;"
-        "stxr    %w[out], %[val], [%[lock]];"
-        "1:"
-        : [out] "=&r"(out)
-        : [lock] "r"(&lock->value), [val] "r"(val)
-        : "cc", "memory");
-
-    return (int)out;
-}
-
-void arch_spin_unlock(spin_lock_t* lock) TA_NO_THREAD_SAFETY_ANALYSIS {
-    __atomic_store_n(&lock->value, 0UL, __ATOMIC_SEQ_CST);
-}
diff --git a/kernel/arch/arm64/start.S b/kernel/arch/arm64/start.S
deleted file mode 100644
index 4999aa3..0000000
--- a/kernel/arch/arm64/start.S
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/arm64/mmu.h>
-#include <arch/arm64.h>
-#include <arch/asm_macros.h>
-#include <arch/defines.h>
-#include <zircon/tls.h>
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-/*
- * Register use:
- *  x0-x3   Arguments
- *  x9-x15  Scratch
- *  x19-x28 Globals
- */
-tmp                     .req x9
-tmp2                    .req x10
-wtmp2                   .req w10
-
-cpuid                   .req x19
-page_table0             .req x20
-page_table1             .req x21
-kernel_vaddr            .req x22
-
-// This code is purely position-independent and generates no relocations
-// that need boot-time fixup; gen-kaslr-fixup.sh ensures this (and would
-// ignore it if this code were in .text.boot, so don't put it there).
-.text
-FUNCTION(_start)
-    /* Save the Boot info for the primary CPU only */
-    mrs     cpuid, mpidr_el1
-    ubfx    cpuid, cpuid, #0, #15 /* mask Aff0 and Aff1 fields */
-    cbnz    cpuid, .Lno_save_bootinfo
-    /* save x0 in zbi_paddr */
-    adrp    tmp, zbi_paddr
-    str     x0, [tmp, #:lo12:zbi_paddr]
-    /* save entry point physical address in kernel_entry_paddr */
-    adrp    tmp, kernel_entry_paddr
-    adr     tmp2, _start
-    str     tmp2, [tmp, #:lo12:kernel_entry_paddr]
-    adrp    tmp2, arch_boot_el
-    mrs     x2, CurrentEL
-    str     x2, [tmp2, #:lo12:arch_boot_el]
-.Lno_save_bootinfo:
-
-    bl      arm64_elX_to_el1
-    bl      arch_invalidate_cache_all
-
-    /* enable caches so atomics and spinlocks work */
-    mrs     tmp, sctlr_el1
-    orr     tmp, tmp, #(1<<12) /* Enable icache */
-    orr     tmp, tmp, #(1<<2)  /* Enable dcache/ucache */
-    msr     sctlr_el1, tmp
-
-    // This can be any arbitrary (page-aligned) address >= KERNEL_ASPACE_BASE.
-    // TODO(SEC-31): Choose it randomly.
-    adr_global  tmp, kernel_relocated_base
-    ldr     kernel_vaddr, [tmp]
-
-    // Load the base of the translation tables.
-    adr_global page_table0, tt_trampoline
-    adr_global page_table1, arm64_kernel_translation_table
-
-    // Send secondary cpus over to a waiting spot for the primary to finish.
-    cbnz    cpuid, .Lmmu_enable_secondary
-
-    // The fixup code appears right after the kernel image (at __data_end in
-    // our view).  Note this code overlaps with the kernel's bss!  It
-    // expects x0 to contain the actual runtime address of __code_start.
-    mov     x0, kernel_vaddr
-    bl      __data_end
-
-    /* clear out the kernel's bss using current physical location */
-    /* NOTE: Relies on __bss_start and _end being 16 byte aligned */
-.Ldo_bss:
-    adr_global tmp, __bss_start
-    adr_global tmp2, _end
-    sub     tmp2, tmp2, tmp
-    cbz     tmp2, .Lbss_loop_done
-.Lbss_loop:
-    sub     tmp2, tmp2, #16
-    stp     xzr, xzr, [tmp], #16
-    cbnz    tmp2, .Lbss_loop
-.Lbss_loop_done:
-
-    /* set up a functional stack pointer */
-    adr_global tmp, boot_cpu_kstack_end
-    mov     sp, tmp
-
-    /* make sure the boot allocator is given a chance to figure out where
-     * we are loaded in physical memory. */
-    bl      boot_alloc_init
-
-    /* save the physical address the kernel is loaded at */
-    adr_global x0, __code_start
-    adr_global x1, kernel_base_phys
-    str     x0, [x1]
-
-    /* set up the mmu according to mmu_initial_mappings */
-
-    /* clear out the kernel translation table */
-    mov     tmp, #0
-.Lclear_top_page_table_loop:
-    str     xzr, [page_table1, tmp, lsl #3]
-    add     tmp, tmp, #1
-    cmp     tmp, #MMU_KERNEL_PAGE_TABLE_ENTRIES_TOP
-    bne     .Lclear_top_page_table_loop
-
-    /* void arm64_boot_map(pte_t* kernel_table0, vaddr_t vaddr, paddr_t paddr, size_t len, pte_t flags); */
-
-    /* map a large run of physical memory at the base of the kernel's address space */
-    mov     x0, page_table1
-    mov     x1, KERNEL_ASPACE_BASE
-    mov     x2, 0
-    mov     x3, ARCH_PHYSMAP_SIZE
-    movlit  x4, MMU_PTE_KERNEL_DATA_FLAGS
-    bl      arm64_boot_map
-
-    /* map the kernel to a fixed address */
-    /* note: mapping the kernel here with full rwx, this will get locked down later in vm initialization; */
-    mov     x0, page_table1
-    mov     x1, kernel_vaddr
-    adr_global x2, __code_start
-    adr_global x3, _end
-    sub     x3, x3, x2
-    mov     x4, MMU_PTE_KERNEL_RWX_FLAGS
-    bl      arm64_boot_map
-
-    /* Prepare tt_trampoline page table.
-     * this will identity map the 1GB page holding the physical address of this code.
-     * Used to temporarily help us get switched to the upper virtual address. */
-
-    /* Zero tt_trampoline translation tables */
-    mov     tmp, #0
-.Lclear_tt_trampoline:
-    str     xzr, [page_table0, tmp, lsl#3]
-    add     tmp, tmp, #1
-    cmp     tmp, #MMU_PAGE_TABLE_ENTRIES_IDENT
-    blt     .Lclear_tt_trampoline
-
-    /* Setup mapping at phys -> phys */
-    adr     tmp, .Lmmu_on_pc
-    lsr     tmp, tmp, #MMU_IDENT_TOP_SHIFT    /* tmp = paddr index */
-    movlit  tmp2, MMU_PTE_IDENT_FLAGS
-    add     tmp2, tmp2, tmp, lsl #MMU_IDENT_TOP_SHIFT  /* tmp2 = pt entry */
-
-    str     tmp2, [page_table0, tmp, lsl #3]  /* tt_trampoline[paddr index] = pt entry */
-
-    /* mark page tables as set up, so secondary cpus can fall through */
-    adr_global tmp, page_tables_not_ready
-    str     wzr, [tmp]
-    b       .Lpage_tables_ready
-
-.Lmmu_enable_secondary:
-    adr_global tmp, page_tables_not_ready
-    /* trap any secondary cpus until the primary has set up the page tables */
-.Lpage_tables_not_ready:
-    ldr     wtmp2, [tmp]
-    cbnz    wtmp2, .Lpage_tables_not_ready
-.Lpage_tables_ready:
-
-    /* set up the mmu */
-
-    /* Invalidate TLB */
-    tlbi    vmalle1is
-    isb
-    dsb     sy
-
-    /* Initialize Memory Attribute Indirection Register */
-    movlit  tmp, MMU_MAIR_VAL
-    msr     mair_el1, tmp
-
-    /* Initialize TCR_EL1 */
-    /* set cacheable attributes on translation walk */
-    /* (SMP extensions) non-shareable, inner write-back write-allocate */
-    movlit  tmp, MMU_TCR_FLAGS_IDENT
-    msr     tcr_el1, tmp
-
-    isb
-
-    /* Write ttbr with phys addr of the translation table */
-    msr     ttbr0_el1, page_table0
-    msr     ttbr1_el1, page_table1
-    isb
-
-    /* Read SCTLR */
-    mrs     tmp, sctlr_el1
-
-    /* Turn on the MMU */
-    orr     tmp, tmp, #0x1
-
-    /* Write back SCTLR */
-    msr     sctlr_el1, tmp
-.Lmmu_on_pc:
-    isb
-
-    // Map our current physical PC to the virtual PC and jump there.
-    // PC = next_PC - __code_start + kernel_vaddr
-    adr     tmp, .Lmmu_on_vaddr
-    adr     tmp2, __code_start
-    sub     tmp, tmp, tmp2
-    add     tmp, tmp, kernel_vaddr
-    br      tmp
-
-.Lmmu_on_vaddr:
-
-    /* Disable trampoline page-table in ttbr0 */
-    movlit  tmp, MMU_TCR_FLAGS_KERNEL
-    msr     tcr_el1, tmp
-    isb
-
-    /* Invalidate TLB */
-    tlbi    vmalle1
-    isb
-
-    cbnz    cpuid, .Lsecondary_boot
-
-    // set up the boot stack for real
-    adr_global tmp, boot_cpu_kstack_end
-    mov     sp, tmp
-
-    // Set the thread pointer early so compiler-generated references
-    // to the stack-guard and unsafe-sp slots work.  This is not a
-    // real 'struct thread' yet, just a pointer to (past, actually)
-    // the two slots used by the ABI known to the compiler.  This avoids
-    // having to compile-time disable safe-stack and stack-protector
-    // code generation features for all the C code in the bootstrap
-    // path, which (unlike on x86, e.g.) is enough to get annoying.
-    adr_global tmp, boot_cpu_fake_thread_pointer_location
-    msr     tpidr_el1, tmp
-
-    // set the per cpu pointer for cpu 0
-    adr_global x18, arm64_percpu_array
-
-    // Choose a good (ideally random) stack-guard value as early as possible.
-    bl      choose_stack_guard
-    mrs     tmp, tpidr_el1
-    str     x0, [tmp, #ZX_TLS_STACK_GUARD_OFFSET]
-    // Don't leak the value to other code.
-    mov     x0, xzr
-
-    bl  lk_main
-    b   .
-
-.Lsecondary_boot:
-    bl      arm64_get_secondary_sp
-    cbz     x0, .Lunsupported_cpu_trap
-    mov     sp, x0
-    msr     tpidr_el1, x1
-
-    bl      arm64_secondary_entry
-
-.Lunsupported_cpu_trap:
-    wfe
-    b       .Lunsupported_cpu_trap
-END_FUNCTION(_start)
-
-.ltorg
-
-// These are logically .bss (uninitialized data).  But they're set before
-// clearing the .bss, so put them in .data so they don't get zeroed.
-.data
-    .balign 64
-DATA(arch_boot_el)
-    .quad 0xdeadbeef00ff00ff
-END_DATA(arch_boot_el)
-DATA(zbi_paddr)
-    .quad -1
-END_DATA(zbi_paddr)
-DATA(kernel_entry_paddr)
-    .quad -1
-END_DATA(kernel_entry_paddr)
-
-DATA(page_tables_not_ready)
-    .long       1
-END_DATA(page_tables_not_ready)
-
-    .balign 8
-LOCAL_DATA(boot_cpu_fake_arch_thread)
-    .quad 0xdeadbeef1ee2d00d // stack_guard
-#if __has_feature(safe_stack)
-    .quad boot_cpu_unsafe_kstack_end
-#else
-    .quad 0
-#endif
-LOCAL_DATA(boot_cpu_fake_thread_pointer_location)
-END_DATA(boot_cpu_fake_arch_thread)
-
-.bss
-LOCAL_DATA(boot_cpu_kstack)
-    .skip ARCH_DEFAULT_STACK_SIZE
-    .balign 16
-LOCAL_DATA(boot_cpu_kstack_end)
-END_DATA(boot_cpu_kstack)
-
-#if __has_feature(safe_stack)
-LOCAL_DATA(boot_cpu_unsafe_kstack)
-    .skip ARCH_DEFAULT_STACK_SIZE
-    .balign 16
-LOCAL_DATA(boot_cpu_unsafe_kstack_end)
-END_DATA(boot_cpu_unsafe_kstack)
-#endif
-
-.section .bss.prebss.translation_table, "aw", @nobits
-.align 3 + MMU_PAGE_TABLE_ENTRIES_IDENT_SHIFT
-DATA(tt_trampoline)
-    .skip 8 * MMU_PAGE_TABLE_ENTRIES_IDENT
-END_DATA(tt_trampoline)
-
-// This symbol is used by image.S
-.global IMAGE_ELF_ENTRY
-IMAGE_ELF_ENTRY = _start
-
-// This symbol is used by gdb python to know the base of the kernel module
-.global KERNEL_BASE_ADDRESS
-KERNEL_BASE_ADDRESS = KERNEL_BASE
diff --git a/kernel/arch/arm64/sysreg.cpp b/kernel/arch/arm64/sysreg.cpp
deleted file mode 100644
index 73b7fc4..0000000
--- a/kernel/arch/arm64/sysreg.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64.h>
-#include <debug.h>
-#include <err.h>
-#include <inttypes.h>
-#include <platform.h>
-#include <stdio.h>
-#include <string.h>
-
-#if ARCH_ARM64
-#include <lib/console.h>
-
-#define SYSREG_READ_COMMAND(sysreg_string)                               \
-    if (!strncasecmp(regname, sysreg_string, sizeof(sysreg_string))) {   \
-        printf(sysreg_string " = %016lx\n", __arm_rsr64(sysreg_string)); \
-        return 0;                                                        \
-    } else
-
-static uint64_t read_sysregs(const char* regname) {
-    SYSREG_READ_COMMAND("actlr_el1")
-    SYSREG_READ_COMMAND("ccsidr_el1")
-    SYSREG_READ_COMMAND("clidr_el1")
-    SYSREG_READ_COMMAND("csselr_el1")
-    SYSREG_READ_COMMAND("midr_el1")
-    SYSREG_READ_COMMAND("mpidr_el1")
-    SYSREG_READ_COMMAND("sctlr_el1")
-    SYSREG_READ_COMMAND("spsr_el1")
-    SYSREG_READ_COMMAND("tcr_el1")
-    SYSREG_READ_COMMAND("tpidrro_el0")
-    SYSREG_READ_COMMAND("tpidr_el1")
-    SYSREG_READ_COMMAND("ttbr0_el1")
-    SYSREG_READ_COMMAND("ttbr1_el1")
-    SYSREG_READ_COMMAND("vbar_el1")
-
-    //Generic Timer regs
-    SYSREG_READ_COMMAND("cntfrq_el0")
-    SYSREG_READ_COMMAND("cntkctl_el1")
-    SYSREG_READ_COMMAND("cntpct_el0")
-    SYSREG_READ_COMMAND("cntps_ctl_el1")
-    SYSREG_READ_COMMAND("cntps_cval_el1")
-    SYSREG_READ_COMMAND("cntps_tval_el1")
-    SYSREG_READ_COMMAND("cntp_ctl_el0")
-    SYSREG_READ_COMMAND("cntp_cval_el0")
-    SYSREG_READ_COMMAND("cntp_tval_el0")
-    SYSREG_READ_COMMAND("cntvct_el0")
-    SYSREG_READ_COMMAND("cntv_ctl_el0")
-    SYSREG_READ_COMMAND("cntv_cval_el0")
-    SYSREG_READ_COMMAND("cntv_tval_el0") {
-        printf("Could not find register %s in list (you may need to add it to kernel/kernel/sysreg.c)\n", regname);
-    }
-    return 0;
-}
-
-static int cmd_sysreg(int argc, const cmd_args* argv, uint32_t flags);
-
-STATIC_COMMAND_START
-STATIC_COMMAND("sysreg", "read armv8 system register", &cmd_sysreg)
-STATIC_COMMAND_END(kernel);
-
-static int cmd_sysreg(int argc, const cmd_args* argv, uint32_t flags) {
-    if (argc < 2) {
-        printf("not enough arguments\n");
-        return -1;
-    }
-    read_sysregs(argv[1].str);
-    return 0;
-}
-
-#endif // ARCH_ARM64
diff --git a/kernel/arch/arm64/thread.cpp b/kernel/arch/arm64/thread.cpp
deleted file mode 100644
index 5ee9bfd..0000000
--- a/kernel/arch/arm64/thread.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2008 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64.h>
-#include <arch/arm64/mp.h>
-#include <debug.h>
-#include <kernel/thread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <trace.h>
-
-#define LOCAL_TRACE 0
-
-// Register state layout used by arm64_context_switch().
-struct context_switch_frame {
-    uint64_t tpidr_el0;
-    uint64_t tpidrro_el0;
-    uint64_t r19;
-    uint64_t r20;
-    uint64_t r21;
-    uint64_t r22;
-    uint64_t r23;
-    uint64_t r24;
-    uint64_t r25;
-    uint64_t r26;
-    uint64_t r27;
-    uint64_t r28;
-    uint64_t r29;
-    uint64_t lr;
-};
-
-// assert that the context switch frame is a multiple of 16 to maintain
-// stack alignment requirements per ABI
-static_assert(sizeof(context_switch_frame) % 16 == 0, "");
-
-extern void arm64_context_switch(addr_t* old_sp, addr_t new_sp);
-
-void arch_thread_initialize(thread_t* t, vaddr_t entry_point) {
-    // zero out the entire arch state
-    t->arch = {};
-
-    // create a default stack frame on the stack
-    vaddr_t stack_top = t->stack.top;
-
-    // make sure the top of the stack is 16 byte aligned for EABI compliance
-    stack_top = ROUNDDOWN(stack_top, 16);
-    t->stack.top = stack_top;
-
-    struct context_switch_frame* frame = (struct context_switch_frame*)(stack_top);
-    frame--;
-
-    // fill in the entry point
-    frame->lr = entry_point;
-
-    // This is really a global (boot-time) constant value.
-    // But it's stored in each thread struct to satisfy the
-    // compiler ABI (TPIDR_EL1 + ZX_TLS_STACK_GUARD_OFFSET).
-    t->arch.stack_guard = get_current_thread()->arch.stack_guard;
-
-    // set the stack pointer
-    t->arch.sp = (vaddr_t)frame;
-#if __has_feature(safe_stack)
-    t->arch.unsafe_sp =
-        ROUNDDOWN(t->stack.unsafe_base + t->stack.size, 16);
-#endif
-
-    // Initialize the debug state to a valid initial state.
-    for (size_t i = 0; i < ARM64_MAX_HW_BREAKPOINTS; i++) {
-        t->arch.debug_state.hw_bps[i].dbgbcr =(0b10u << ARM64_DBGBCR_PMC_SHIFT) | ARM64_DBGBCR_BAS;
-        t->arch.debug_state.hw_bps[i].dbgbvr = 0;
-    }
-}
-
-__NO_SAFESTACK void arch_thread_construct_first(thread_t* t) {
-    // Propagate the values from the fake arch_thread that the thread
-    // pointer points to now (set up in start.S) into the real thread
-    // structure being set up now.
-    thread_t* fake = get_current_thread();
-    t->arch.stack_guard = fake->arch.stack_guard;
-    t->arch.unsafe_sp = fake->arch.unsafe_sp;
-
-    // make sure the thread saves a copy of the current cpu pointer
-    t->arch.current_percpu_ptr = arm64_read_percpu_ptr();
-
-    // Force the thread pointer immediately to the real struct.  This way
-    // our callers don't have to avoid safe-stack code or risk losing track
-    // of the unsafe_sp value.  The caller's unsafe_sp value is visible at
-    // TPIDR_EL1 + ZX_TLS_UNSAFE_SP_OFFSET as expected, though TPIDR_EL1
-    // happens to have changed.  (We're assuming that the compiler doesn't
-    // decide to cache the TPIDR_EL1 value across this function call, which
-    // would be pointless since it's just one instruction to fetch it afresh.)
-    set_current_thread(t);
-}
-
-__NO_SAFESTACK void arch_context_switch(thread_t* oldthread,
-                                        thread_t* newthread) {
-    LTRACEF("old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name);
-    __dsb(ARM_MB_SY); /* broadcast tlb operations in case the thread moves to another cpu */
-
-    /* set the current cpu pointer in the new thread's structure so it can be
-     * restored on exception entry.
-     */
-    newthread->arch.current_percpu_ptr = arm64_read_percpu_ptr();
-
-    arm64_fpu_context_switch(oldthread, newthread);
-    arm64_debug_state_context_switch(oldthread, newthread);
-    arm64_context_switch(&oldthread->arch.sp, newthread->arch.sp);
-}
-
-void arch_dump_thread(thread_t* t) {
-    if (t->state != THREAD_RUNNING) {
-        dprintf(INFO, "\tarch: ");
-        dprintf(INFO, "sp 0x%lx\n", t->arch.sp);
-    }
-}
-
-void* arch_thread_get_blocked_fp(struct thread* t) {
-    if (!WITH_FRAME_POINTERS)
-        return nullptr;
-
-    struct context_switch_frame* frame = (struct context_switch_frame*)t->arch.sp;
-
-    return (void*)frame->r29;
-}
-
-void arm64_debug_state_context_switch(thread *old_thread, thread *new_thread) {
-    // If the new thread has debug state, then install it, replacing the current contents.
-    if (unlikely(new_thread->arch.track_debug_state)) {
-        arm64_write_hw_debug_regs(&new_thread->arch.debug_state);
-        arm64_enable_debug_state();
-        return;
-    }
-
-    // If the old thread had debug state running and the new one doesn't use it, disable the
-    // debug capabilities. We don't need to clear the state because if a new thread being
-    // scheduled needs them, then it will overwrite the state.
-    if (unlikely(old_thread->arch.track_debug_state)) {
-        arm64_disable_debug_state();
-    }
-}
diff --git a/kernel/arch/arm64/toolchain.mk b/kernel/arch/arm64/toolchain.mk
deleted file mode 100644
index 7b469c2..0000000
--- a/kernel/arch/arm64/toolchain.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-# arm64 GCC toolchain
-ifndef ARCH_arm64_TOOLCHAIN_INCLUDED
-ARCH_arm64_TOOLCHAIN_INCLUDED := 1
-
-ifndef ARCH_arm64_TOOLCHAIN_PREFIX
-ARCH_arm64_TOOLCHAIN_PREFIX := aarch64-elf-
-endif
-FOUNDTOOL=$(shell which $(ARCH_arm64_TOOLCHAIN_PREFIX)gcc)
-
-endif # ifndef ARCH_arm64_TOOLCHAIN_INCLUDED
-
-# Clang
-ifeq ($(call TOBOOL,$(USE_CLANG)),true)
-FOUNDTOOL=$(shell which $(CLANG_TOOLCHAIN_PREFIX)clang)
-endif # USE_CLANG==true
-
-ifeq ($(FOUNDTOOL),)
-$(error cannot find toolchain, please set ARCH_arm64_TOOLCHAIN_PREFIX, \
-        CLANG_TOOLCHAIN_PREFIX, or add either to your path)
-endif
diff --git a/kernel/arch/arm64/user_copy.S b/kernel/arch/arm64/user_copy.S
deleted file mode 100644
index 7ce7cd9..0000000
--- a/kernel/arch/arm64/user_copy.S
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <err.h>
-
-lr .req x30
-dst .req x0
-src .req x1
-len .req x2
-fault_return_ptr .req x3
-temp .req x15
-
-// NOTE! We know here that the memcpy code doesn't touch these registers,
-// so we can use them to save values.  But they are call-clobbered in the
-// C ABI, so we don't need a stack frame.
-saved_fault_return_ptr .req x16
-saved_lr .req x17
-
-// zx_status_t _arm64_user_copy(void *dst, const void *src, size_t len, void **fault_return)
-.section .text._arm64_user_copy,"ax"
-.balign 64 // Align to cache line.  This code fits in one cache line.
-FUNCTION(_arm64_user_copy)
-
-    adr temp, .Lfault_from_user
-
-    mov saved_fault_return_ptr, fault_return_ptr
-    .cfi_register fault_return_ptr, saved_fault_return_ptr
-    mov saved_lr, lr
-    .cfi_register lr, saved_lr
-
-    // Just call our normal memcpy.  The caller has ensured that the
-    // address range is in the user portion of the address space.
-    // While fault_return_ptr is set, userspace data faults will be
-    // redirected to .Lfault_from_user, below.
-    //
-    // NOTE! We make important assumptions here about what the memcpy
-    // code does: it never moves the stack pointer, and it never touches
-    // the registers we're using for saved_fault_return_ptr and saved_lr.
-    str temp, [fault_return_ptr]
-    bl memcpy
-    mov x0, #ZX_OK
-
-.Luser_copy_return:
-    str xzr, [saved_fault_return_ptr]
-    mov lr, saved_lr
-    .cfi_same_value lr
-    ret
-END_FUNCTION(_arm64_user_copy)
-
-.section .text.cold._arm64_user_copy,"ax"
-.Lfault_from_user:
-    .cfi_startproc
-    .cfi_register fault_return_ptr, saved_fault_return_ptr
-    .cfi_register lr, saved_lr
-    mov x0, #ZX_ERR_INVALID_ARGS
-    b .Luser_copy_return
-    .cfi_endproc
diff --git a/kernel/arch/arm64/user_copy_c.cpp b/kernel/arch/arm64/user_copy_c.cpp
deleted file mode 100644
index 06d4c06..0000000
--- a/kernel/arch/arm64/user_copy_c.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/user_copy.h>
-#include <arch/user_copy.h>
-#include <kernel/thread.h>
-#include <vm/vm.h>
-
-zx_status_t arch_copy_from_user(void* dst, const void* src, size_t len) {
-    // The assembly code just does memcpy with fault handling.  This is
-    // the security check that an address from the user is actually a
-    // valid userspace address so users can't access kernel memory.
-    if (!is_user_address_range((vaddr_t)src, len)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    return _arm64_user_copy(dst, src, len,
-                            &get_current_thread()->arch.data_fault_resume);
-}
-
-zx_status_t arch_copy_to_user(void* dst, const void* src, size_t len) {
-    if (!is_user_address_range((vaddr_t)dst, len)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    return _arm64_user_copy(dst, src, len,
-                            &get_current_thread()->arch.data_fault_resume);
-}
diff --git a/kernel/arch/arm64/uspace_entry.S b/kernel/arch/arm64/uspace_entry.S
deleted file mode 100644
index 75894a3..0000000
--- a/kernel/arch/arm64/uspace_entry.S
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-
-// void arm64_uspace_entry(uintptr_t arg1, uintptr_t arg2, uintptr_t pc, uintptr_t sp, vaddr_t kstack, uint32_t spsr, uint32_t mdscr) __NO_RETURN;
-FUNCTION(arm64_uspace_entry)
-    mov sp, x4
-    msr sp_el0, x3
-    msr elr_el1, x2
-    msr spsr_el1, x5
-    msr mdscr_el1, x6
-
-    mov x2, xzr
-    mov x3, xzr
-    mov x4, xzr
-    mov x5, xzr
-    mov x6, xzr
-    mov x7, xzr
-    mov x8, xzr
-    mov x9, xzr
-    mov x10, xzr
-    mov x11, xzr
-    mov x12, xzr
-    mov x13, xzr
-    mov x14, xzr
-    mov x15, xzr
-    mov x16, xzr
-    mov x17, xzr
-    mov x18, xzr
-    mov x19, xzr
-    mov x20, xzr
-    mov x21, xzr
-    mov x22, xzr
-    mov x23, xzr
-    mov x24, xzr
-    mov x25, xzr
-    mov x26, xzr
-    mov x27, xzr
-    mov x28, xzr
-    mov x29, xzr
-    mov x30, xzr
-
-    // Lazy loading of the FPU means we don't need to zero the simd registers
-    eret
-END_FUNCTION(arm64_uspace_entry)
diff --git a/kernel/arch/x86/MAINTAINERS b/kernel/arch/x86/MAINTAINERS
deleted file mode 100644
index 8f569d1..0000000
--- a/kernel/arch/x86/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-teisenbe@google.com
-travisg@google.com
diff --git a/kernel/arch/x86/acpi.S b/kernel/arch/x86/acpi.S
deleted file mode 100644
index 3a03af4..0000000
--- a/kernel/arch/x86/acpi.S
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-//
-
-#include <asm.h>
-
-/*
-struct x86_realmode_entry_data_registers {
-    uint64_t rdi, rsi, rbp, rbx, rdx, rcx, rax;
-    uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
-    uint64_t rsp, rip;
-};
-*/
-.code64
-.section .text
-// ACPI_STATUS x86_acpi_transition_s_state(struct x86_realmode_entry_data_registers* reg,
-//                                         uint8_t target_s_state, uint8_t sleep_type_a,
-//                                         uint8_t sleep_type_b)
-FUNCTION_LABEL(x86_acpi_transition_s_state)
-    // We do not need to save floating point registers, since this method must be called
-    // by a kernel thread if the system is expected to return from the S-state.
-    mov %rdi, (%rdi)
-    mov %rsi, 8(%rdi)
-    mov %rbp, 16(%rdi)
-    mov %rbx, 24(%rdi)
-    mov %rdx, 32(%rdi)
-    mov %rcx, 40(%rdi)
-    // Stash 0 as rax, so we return AE_OK if we do suspend
-    movq $0, 48(%rdi)
-    mov %r8, 56(%rdi)
-    mov %r9, 64(%rdi)
-    mov %r10, 72(%rdi)
-    mov %r11, 80(%rdi)
-    mov %r12, 88(%rdi)
-    mov %r13, 96(%rdi)
-    mov %r14, 104(%rdi)
-    mov %r15, 112(%rdi)
-    mov %rsp, 120(%rdi)
-
-    // Set up our return IP, in case the S-state needs it (jumped to by _x86_suspend_wakeup())
-    leaq .Lafter_sleep(%rip), %rax
-    movq %rax, 128(%rdi)
-
-    // Enter the sleep state
-    sub $8, %rsp
-    mov %rsi, %rdi
-    mov %rdx, %rsi
-    mov %rcx, %rdx
-    call AcpiHwLegacySleepFinal
-    add $8, %rsp
-.Lafter_sleep:
-    ret
diff --git a/kernel/arch/x86/arch.cpp b/kernel/arch/x86/arch.cpp
deleted file mode 100644
index 1df5b20..0000000
--- a/kernel/arch/x86/arch.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2015 Intel Corporation
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch.h>
-#include <arch/mmu.h>
-#include <arch/mp.h>
-#include <arch/ops.h>
-#include <arch/x86.h>
-#include <arch/x86/apic.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/mmu_mem_types.h>
-#include <arch/x86/mp.h>
-#include <arch/x86/proc_trace.h>
-#include <arch/x86/tsc.h>
-#include <assert.h>
-#include <assert.h>
-#include <debug.h>
-#include <err.h>
-#include <inttypes.h>
-#include <lib/console.h>
-#include <lk/init.h>
-#include <lk/main.h>
-#include <platform.h>
-#include <string.h>
-#include <sys/types.h>
-#include <trace.h>
-#include <vm/vm.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-/* save a pointer to the bootdata, if present */
-void* _zbi_base;
-
-void arch_early_init(void) {
-    x86_mmu_early_init();
-}
-
-void arch_init(void) {
-    const struct x86_model_info* model = x86_get_model();
-    printf("Processor Model Info: type %#x family %#x model %#x stepping %#x\n",
-           model->processor_type, model->family, model->model, model->stepping);
-    printf("\tdisplay_family %#x display_model %#x\n",
-           model->display_family, model->display_model);
-
-    x86_feature_debug();
-
-    x86_mmu_init();
-
-    gdt_setup();
-    idt_setup_readonly();
-
-    x86_processor_trace_init();
-}
-
-void arch_enter_uspace(uintptr_t entry_point, uintptr_t sp,
-                       uintptr_t arg1, uintptr_t arg2) {
-    LTRACEF("entry %#" PRIxPTR " user stack %#" PRIxPTR "\n", entry_point, sp);
-    LTRACEF("kernel stack %#" PRIxPTR "\n", x86_get_percpu()->default_tss.rsp0);
-
-    arch_disable_ints();
-
-    /* default user space flags:
-     * IOPL 0
-     * Interrupts enabled
-     */
-    ulong flags = (0 << X86_FLAGS_IOPL_SHIFT) | X86_FLAGS_IF;
-
-    /* check that we're probably still pointed at the kernel gs */
-    DEBUG_ASSERT(is_kernel_address(read_msr(X86_MSR_IA32_GS_BASE)));
-
-    /* check that the kernel stack is set properly */
-    DEBUG_ASSERT(is_kernel_address(x86_get_percpu()->default_tss.rsp0));
-
-    /* set up user's fs: gs: base */
-    write_msr(X86_MSR_IA32_FS_BASE, 0);
-
-    /* set the KERNEL_GS_BASE msr here, because we're going to swapgs below */
-    write_msr(X86_MSR_IA32_KERNEL_GS_BASE, 0);
-
-    x86_uspace_entry(arg1, arg2, sp, entry_point, flags);
-    __UNREACHABLE;
-}
-
-void arch_suspend(void) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    apic_io_save();
-    x86_tsc_store_adjustment();
-}
-
-void arch_resume(void) {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    x86_init_percpu(0);
-    x86_mmu_percpu_init();
-    x86_pat_sync(cpu_num_to_mask(0));
-
-    apic_local_init();
-
-    // Ensure the CPU that resumed was assigned the correct percpu object.
-    DEBUG_ASSERT(apic_local_id() == x86_get_percpu()->apic_id);
-
-    apic_io_restore();
-}
-
-[[ noreturn, gnu::noinline ]] static void finish_secondary_entry(
-    volatile int* aps_still_booting, thread_t* thread, uint cpu_num) {
-
-    // Signal that this CPU is initialized.  It is important that after this
-    // operation, we do not touch any resources associated with bootstrap
-    // besides our thread_t and stack, since this is the checkpoint the
-    // bootstrap process uses to identify completion.
-    int old_val = atomic_and(aps_still_booting, ~(1U << cpu_num));
-    if (old_val == 0) {
-        // If the value is already zero, then booting this CPU timed out.
-        goto fail;
-    }
-
-    // Defer configuring memory settings until after the atomic_and above.
-    // This ensures that we were in no-fill cache mode for the duration of early
-    // AP init.
-    DEBUG_ASSERT(x86_get_cr0() & X86_CR0_CD);
-    x86_mmu_percpu_init();
-
-    // Load the appropriate PAT/MTRRs.  This must happen after init_percpu, so
-    // that this CPU is considered online.
-    x86_pat_sync(1U << cpu_num);
-
-    /* run early secondary cpu init routines up to the threading level */
-    lk_init_level(LK_INIT_FLAG_SECONDARY_CPUS, LK_INIT_LEVEL_EARLIEST, LK_INIT_LEVEL_THREADING - 1);
-
-    thread_secondary_cpu_init_early(thread);
-    // The thread stacks and struct are from a single allocation, free it
-    // when we exit into the scheduler.
-    thread->flags |= THREAD_FLAG_FREE_STRUCT;
-
-    lk_secondary_cpu_entry();
-
-// lk_secondary_cpu_entry only returns on an error, halt the core in this
-// case.
-fail:
-    arch_disable_ints();
-    while (1) {
-        x86_hlt();
-    }
-}
-
-// This is called from assembly, before any other C code.
-// The %gs.base is not set up yet, so we have to trust that
-// this function is simple enough that the compiler won't
-// want to generate stack-protector prologue/epilogue code,
-// which would use %gs.
-__NO_SAFESTACK __NO_RETURN void x86_secondary_entry(volatile int* aps_still_booting,
-                                                    thread_t* thread) {
-    // Would prefer this to be in init_percpu, but there is a dependency on a
-    // page mapping existing, and the BP calls that before the VM subsystem is
-    // initialized.
-    apic_local_init();
-
-    uint32_t local_apic_id = apic_local_id();
-    int cpu_num = x86_apic_id_to_cpu_num(local_apic_id);
-    if (cpu_num < 0) {
-        // If we could not find our CPU number, do not proceed further
-        arch_disable_ints();
-        while (1) {
-            x86_hlt();
-        }
-    }
-
-    DEBUG_ASSERT(cpu_num > 0);
-
-    // Set %gs.base to our percpu struct.  This has to be done before
-    // calling x86_init_percpu, which initializes most of that struct, so
-    // that x86_init_percpu can use safe-stack and/or stack-protector code.
-    struct x86_percpu* const percpu = &ap_percpus[cpu_num - 1];
-    write_msr(X86_MSR_IA32_GS_BASE, (uintptr_t)percpu);
-
-    // Copy the stack-guard value from the boot CPU's perpcu.
-    percpu->stack_guard = bp_percpu.stack_guard;
-
-#if __has_feature(safe_stack)
-    // Set up the initial unsafe stack pointer.
-    x86_write_gs_offset64(
-        ZX_TLS_UNSAFE_SP_OFFSET,
-        ROUNDDOWN(thread->stack.unsafe_base + thread->stack.size, 16));
-#endif
-
-    x86_init_percpu((uint)cpu_num);
-
-    // Now do the rest of the work, in a function that is free to
-    // use %gs in its code.
-    finish_secondary_entry(aps_still_booting, thread, cpu_num);
-}
-
-static int cmd_cpu(int argc, const cmd_args* argv, uint32_t flags) {
-    if (argc < 2) {
-        printf("not enough arguments\n");
-    usage:
-        printf("usage:\n");
-        printf("%s features\n", argv[0].str);
-        printf("%s unplug <cpu_id>\n", argv[0].str);
-        printf("%s hotplug <cpu_id>\n", argv[0].str);
-        return ZX_ERR_INTERNAL;
-    }
-
-    if (!strcmp(argv[1].str, "features")) {
-        x86_feature_debug();
-    } else if (!strcmp(argv[1].str, "unplug")) {
-        if (argc < 3) {
-            printf("specify a cpu_id\n");
-            goto usage;
-        }
-        zx_status_t status = mp_unplug_cpu((uint)argv[2].u);
-        printf("CPU %lu unplugged: %d\n", argv[2].u, status);
-    } else if (!strcmp(argv[1].str, "hotplug")) {
-        if (argc < 3) {
-            printf("specify a cpu_id\n");
-            goto usage;
-        }
-        zx_status_t status = mp_hotplug_cpu((uint)argv[2].u);
-        printf("CPU %lu hotplugged: %d\n", argv[2].u, status);
-    } else {
-        printf("unknown command\n");
-        goto usage;
-    }
-
-    return ZX_OK;
-}
-
-STATIC_COMMAND_START
-#if LK_DEBUGLEVEL > 0
-STATIC_COMMAND("cpu", "cpu test commands", &cmd_cpu)
-#endif
-STATIC_COMMAND_END(cpu);
diff --git a/kernel/arch/x86/asm.S b/kernel/arch/x86/asm.S
deleted file mode 100644
index 8ca25f3..0000000
--- a/kernel/arch/x86/asm.S
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2015 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/defines.h>
-
-/* void x86_64_context_switch(uint64_t *oldsp, uint64_t newsp) */
-FUNCTION(x86_64_context_switch)
-    /* save the old context and restore the new */
-    /* This layout should match struct x86_64_context_switch_frame */
-    push_reg %rbx
-    push_reg %rbp
-    push_reg %r12
-    push_reg %r13
-    push_reg %r14
-    push_reg %r15
-
-    movq %rsp,(%rdi)
-    movq %rsi,%rsp
-
-    pop_reg %r15
-    pop_reg %r14
-    pop_reg %r13
-    pop_reg %r12
-    pop_reg %rbp
-    pop_reg %rbx
-
-    retq
-END_FUNCTION(x86_64_context_switch)
-
-#include <arch/x86/mp.h>
-
-/* void arch_spin_lock(unsigned long *lock) */
-FUNCTION(arch_spin_lock)
-    /* fetch the current cpu number + 1 */
-    mov %gs:PERCPU_CPU_NUM_OFFSET, %rsi
-    inc %rsi
-
-.Ltake_lock:
-    xor %rax, %rax
-    lock cmpxchg %rsi, (%rdi)
-    jnz .Lspin
-    ret
-
-.Lspin:
-    pause
-    cmpq $0, (%rdi)
-    je .Ltake_lock
-    jmp .Lspin
-END_FUNCTION(arch_spin_lock)
-
-/* int arch_spin_trylock(unsigned long *lock) */
-FUNCTION(arch_spin_trylock)
-    /* fetch the current cpu number + 1 */
-    mov %gs:PERCPU_CPU_NUM_OFFSET, %rsi
-    inc %rsi
-
-    xor %rax, %rax
-    lock cmpxchg %rsi, (%rdi)
-    /* we return 0 to indicate success. %rax contains the value found by cmpxchg,
-     * which is already 0 if we got the lock */
-    ret
-END_FUNCTION(arch_spin_trylock)
-
-/* void arch_spin_unlock(spin_lock_t *lock) */
-FUNCTION(arch_spin_unlock)
-    movq $0, (%rdi)
-    ret
-END_FUNCTION(arch_spin_unlock)
-
-/* rep stos version of page zero */
-FUNCTION(arch_zero_page)
-    xorl    %eax, %eax /* set %rax = 0 */
-    mov     $PAGE_SIZE >> 3, %rcx
-    cld
-
-    rep     stosq
-
-    ret
-END_FUNCTION(arch_zero_page)
-
-// This clobbers %rax and memory below %rsp, but preserves all other registers.
-FUNCTION(load_startup_idt)
-    lea _idt_startup(%rip), %rax
-    movw $(16 * 256) - 1, -16(%rsp)
-    movq %rax, -16+2(%rsp)
-    lidt -16(%rsp)
-    ret
-END_FUNCTION(load_startup_idt)
diff --git a/kernel/arch/x86/bootstrap16.cpp b/kernel/arch/x86/bootstrap16.cpp
deleted file mode 100644
index ac3d7f2..0000000
--- a/kernel/arch/x86/bootstrap16.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/mmu.h>
-#include <arch/x86.h>
-#include <arch/x86/apic.h>
-#include <arch/x86/bootstrap16.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/mp.h>
-#include <assert.h>
-#include <err.h>
-#include <fbl/algorithm.h>
-#include <fbl/auto_call.h>
-#include <fbl/mutex.h>
-#include <string.h>
-#include <trace.h>
-#include <vm/pmm.h>
-#include <vm/vm.h>
-#include <zircon/thread_annotations.h>
-#include <zircon/types.h>
-
-static paddr_t bootstrap_phys_addr = UINT64_MAX;
-static fbl::Mutex bootstrap_lock;
-
-void x86_bootstrap16_init(paddr_t bootstrap_base) {
-    DEBUG_ASSERT(!IS_PAGE_ALIGNED(bootstrap_phys_addr));
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(bootstrap_base));
-    DEBUG_ASSERT(bootstrap_base <= (1024 * 1024) - 2 * PAGE_SIZE);
-    bootstrap_phys_addr = bootstrap_base;
-}
-
-zx_status_t x86_bootstrap16_acquire(uintptr_t entry64, fbl::RefPtr<VmAspace>* temp_aspace,
-                                    void** bootstrap_aperature, paddr_t* instr_ptr)
-    TA_NO_THREAD_SAFETY_ANALYSIS {
-    // Make sure x86_bootstrap16_init has been called, and bail early if not.
-    if (!IS_PAGE_ALIGNED(bootstrap_phys_addr)) {
-        return ZX_ERR_BAD_STATE;
-    }
-
-    // Make sure the entrypoint code is in the bootstrap code that will be
-    // loaded
-    if (entry64 < (uintptr_t)x86_bootstrap16_start ||
-        entry64 >= (uintptr_t)x86_bootstrap16_end) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    VmAspace* kernel_aspace = VmAspace::kernel_aspace();
-    fbl::RefPtr<VmAspace> bootstrap_aspace = VmAspace::Create(VmAspace::TYPE_LOW_KERNEL,
-                                                              "bootstrap16");
-    if (!bootstrap_aspace) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    void* bootstrap_virt_addr = nullptr;
-
-    // Ensure only one caller is using the bootstrap region
-    bootstrap_lock.Acquire();
-
-    // add an auto caller to clean up the address space on the way out
-    auto ac = fbl::MakeAutoCall([&]() TA_NO_THREAD_SAFETY_ANALYSIS {
-        bootstrap_aspace->Destroy();
-        if (bootstrap_virt_addr) {
-            kernel_aspace->FreeRegion(reinterpret_cast<vaddr_t>(bootstrap_virt_addr));
-        }
-        bootstrap_lock.Release();
-    });
-
-    // Actual GDT address.
-    extern uint8_t _temp_gdt;
-    extern uint8_t _temp_gdt_end;
-
-    // Compute what needs to go into the mappings
-    paddr_t gdt_phys_page =
-        vaddr_to_paddr((void*)ROUNDDOWN((uintptr_t)&_temp_gdt, PAGE_SIZE));
-    uintptr_t gdt_region_len =
-        ROUNDUP((uintptr_t)&_temp_gdt_end, PAGE_SIZE) - ROUNDDOWN((uintptr_t)&_temp_gdt, PAGE_SIZE);
-
-    // Temporary aspace needs 5 regions mapped:
-    struct map_range page_mappings[] = {
-        // 1) The bootstrap code page (identity mapped)
-        // 2) The bootstrap data page (identity mapped)
-        {.start_vaddr = bootstrap_phys_addr, .start_paddr = bootstrap_phys_addr, .size = 2 * PAGE_SIZE},
-        // 3) The page containing the GDT (identity mapped)
-        {.start_vaddr = (vaddr_t)gdt_phys_page, .start_paddr = gdt_phys_page, .size = gdt_region_len},
-        // These next two come implicitly from the shared kernel aspace:
-        // 4) The kernel's version of the bootstrap code page (matched mapping)
-        // 5) The page containing the aps_still_booting counter (matched mapping)
-    };
-    for (unsigned int i = 0; i < fbl::count_of(page_mappings); ++i) {
-        void* vaddr = (void*)page_mappings[i].start_vaddr;
-        zx_status_t status = bootstrap_aspace->AllocPhysical(
-            "bootstrap_mapping",
-            page_mappings[i].size,
-            &vaddr,
-            PAGE_SIZE_SHIFT,
-            page_mappings[i].start_paddr,
-            VmAspace::VMM_FLAG_VALLOC_SPECIFIC,
-            ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE | ARCH_MMU_FLAG_PERM_EXECUTE);
-        if (status != ZX_OK) {
-            TRACEF("Failed to create wakeup bootstrap aspace\n");
-            return status;
-        }
-    }
-
-    // Map the AP bootstrap page and a low mem data page to configure
-    // the AP processors with
-    zx_status_t status = kernel_aspace->AllocPhysical(
-        "bootstrap16_aperture",
-        PAGE_SIZE * 2,                                       // size
-        &bootstrap_virt_addr,                                // requested virtual address
-        PAGE_SIZE_SHIFT,                                     // alignment log2
-        bootstrap_phys_addr,                                 // physical address
-        0,                                                   // vmm flags
-        ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE); // arch mmu flags
-    if (status != ZX_OK) {
-        TRACEF("could not allocate AP bootstrap page: %d\n", status);
-        return status;
-    }
-    DEBUG_ASSERT(bootstrap_virt_addr != nullptr);
-    uintptr_t bootstrap_code_len = (uintptr_t)x86_bootstrap16_end -
-                                   (uintptr_t)x86_bootstrap16_start;
-    DEBUG_ASSERT(bootstrap_code_len <= PAGE_SIZE);
-    // Copy the bootstrap code in
-    memcpy(bootstrap_virt_addr, (const void*)x86_bootstrap16_start, bootstrap_code_len);
-
-    // Configuration data shared with the APs to get them to 64-bit mode
-    struct x86_bootstrap16_data* bootstrap_data =
-        (struct x86_bootstrap16_data*)((uintptr_t)bootstrap_virt_addr + 0x1000);
-
-    uintptr_t long_mode_entry = bootstrap_phys_addr +
-                                (entry64 - (uintptr_t)x86_bootstrap16_start);
-    ASSERT(long_mode_entry <= UINT32_MAX);
-
-    uint64_t phys_bootstrap_pml4 = bootstrap_aspace->arch_aspace().pt_phys();
-    uint64_t phys_kernel_pml4 = VmAspace::kernel_aspace()->arch_aspace().pt_phys();
-    if (phys_bootstrap_pml4 > UINT32_MAX) {
-        // TODO(ZX-978): Once the pmm supports it, we should request that this
-        // VmAspace is backed by a low mem PML4, so we can avoid this issue.
-        TRACEF("bootstrap PML4 was not allocated out of low mem\n");
-        return ZX_ERR_NO_MEMORY;
-    }
-    ASSERT(phys_kernel_pml4 <= UINT32_MAX);
-
-    bootstrap_data->phys_bootstrap_pml4 = static_cast<uint32_t>(phys_bootstrap_pml4);
-    bootstrap_data->phys_kernel_pml4 = static_cast<uint32_t>(phys_kernel_pml4);
-    bootstrap_data->phys_gdtr_limit =
-        static_cast<uint16_t>(&_temp_gdt_end - &_temp_gdt - 1);
-    bootstrap_data->phys_gdtr_base =
-        reinterpret_cast<uintptr_t>(&_temp_gdt) -
-        reinterpret_cast<uintptr_t>(__code_start) +
-        get_kernel_base_phys();
-    bootstrap_data->phys_long_mode_entry = static_cast<uint32_t>(long_mode_entry);
-    bootstrap_data->long_mode_cs = CODE_64_SELECTOR;
-
-    *bootstrap_aperature = (void*)((uintptr_t)bootstrap_virt_addr + 0x1000);
-    *temp_aspace = bootstrap_aspace;
-    *instr_ptr = bootstrap_phys_addr;
-
-    // Cancel the cleanup autocall, since we're returning the new aspace and region
-    // NOTE: Since we cancel the autocall, we are not releasing
-    // |bootstrap_lock|.  This is released in x86_bootstrap16_release() when the
-    // caller is done with the bootstrap region.
-    ac.cancel();
-
-    return ZX_OK;
-}
-
-void x86_bootstrap16_release(void* bootstrap_aperature) TA_NO_THREAD_SAFETY_ANALYSIS {
-    DEBUG_ASSERT(bootstrap_aperature);
-    DEBUG_ASSERT(bootstrap_lock.IsHeld());
-    VmAspace* kernel_aspace = VmAspace::kernel_aspace();
-    uintptr_t addr = reinterpret_cast<uintptr_t>(bootstrap_aperature) - 0x1000;
-    kernel_aspace->FreeRegion(addr);
-
-    bootstrap_lock.Release();
-}
diff --git a/kernel/arch/x86/cache.cpp b/kernel/arch/x86/cache.cpp
deleted file mode 100644
index 8aab6d7..0000000
--- a/kernel/arch/x86/cache.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/ops.h>
-#include <arch/x86.h>
-#include <arch/x86/feature.h>
-
-uint32_t arch_dcache_line_size(void) {
-    return x86_get_clflush_line_size();
-}
-
-uint32_t arch_icache_line_size(void) {
-    return x86_get_clflush_line_size();
-}
-
-void arch_sync_cache_range(addr_t start, size_t len) {
-    // Invoke cpuid to act as a serializing instruction.  This will ensure we
-    // see modifications to future parts of the instruction stream.  See
-    // Intel Volume 3, 8.1.3 "Handling Self- and Cross-Modifying Code".  cpuid
-    // is the more conservative approach suggested in this section.
-    uint32_t v;
-    cpuid(0, &v, &v, &v, &v);
-}
-
-void arch_invalidate_cache_range(addr_t start, size_t len) {
-}
-
-void arch_clean_cache_range(addr_t start, size_t len) {
-    // TODO: consider wiring up clwb if present
-    arch_clean_invalidate_cache_range(start, len);
-}
-
-void arch_clean_invalidate_cache_range(addr_t start, size_t len) {
-    if (unlikely(!x86_feature_test(X86_FEATURE_CLFLUSH))) {
-        __asm__ volatile("wbinvd");
-        return;
-    }
-
-    // clflush/clflushopt is present
-    const vaddr_t clsize = x86_get_clflush_line_size();
-    addr_t end = start + len;
-    addr_t ptr = ROUNDDOWN(start, clsize);
-
-    // TODO: use run time patching to merge these two paths
-    if (likely(x86_feature_test(X86_FEATURE_CLFLUSHOPT))) {
-        while (ptr < end) {
-            __asm__ volatile("clflushopt %0" ::"m"(*(char*)ptr));
-            ptr += clsize;
-        }
-    } else {
-        while (ptr < end) {
-            __asm__ volatile("clflush %0" ::"m"(*(char*)ptr));
-            ptr += clsize;
-        }
-    }
-
-    __asm__ volatile("mfence");
-}
diff --git a/kernel/arch/x86/cpu_topology.cpp b/kernel/arch/x86/cpu_topology.cpp
deleted file mode 100644
index a754489..0000000
--- a/kernel/arch/x86/cpu_topology.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/ops.h>
-#include <arch/x86/cpu_topology.h>
-#include <arch/x86/feature.h>
-#include <bits.h>
-#include <pow2.h>
-#include <stdio.h>
-#include <string.h>
-#include <trace.h>
-
-#define LOCAL_TRACE 0
-
-// Use various methods to decode the apic id to different levels of cpu topology.
-//
-// The heirarchy is currently
-// package (socket) : node (die within the socket) : core (within the die) : thread
-
-// Default to all bits, so that the topology system fails towards
-// distinguishing all CPUs
-static uint32_t package_mask = ~0;
-static uint32_t package_shift = 0;
-
-static uint32_t node_mask = 0;
-static uint32_t node_shift = 0;
-
-static uint32_t core_mask = 0;
-static uint32_t core_shift = 0;
-
-static uint32_t smt_mask = 0;
-
-static void legacy_topology_init();
-static void modern_intel_topology_init();
-static void extended_amd_topology_init();
-
-void x86_cpu_topology_init() {
-    static int initialized;
-
-    if (atomic_swap(&initialized, 1)) {
-        return;
-    }
-
-    if (x86_vendor == X86_VENDOR_INTEL && x86_get_cpuid_leaf(X86_CPUID_BASE)->a >= X86_CPUID_TOPOLOGY) {
-        modern_intel_topology_init();
-    } else if (x86_vendor == X86_VENDOR_AMD) {
-        extended_amd_topology_init();
-    } else {
-        legacy_topology_init();
-    }
-}
-
-static void modern_intel_topology_init() {
-    // This is based off of Intel 3A's Example 8-18 "Support Routine for
-    // Identifying Package, Core, and Logical Processors from 32-bit x2APIC ID"
-    struct x86_topology_level info;
-    if (!x86_topology_enumerate(0, &info)) {
-        return;
-    }
-
-    if (info.type == X86_TOPOLOGY_SMT) {
-        smt_mask = (1 << info.right_shift) - 1;
-        core_shift = info.right_shift;
-    }
-
-    for (uint8_t level = 0; x86_topology_enumerate(level, &info); ++level) {
-        if (info.type == X86_TOPOLOGY_CORE) {
-            core_mask = ((1 << info.right_shift) - 1) ^ smt_mask;
-            package_shift = info.right_shift;
-            package_mask = ~(core_mask | smt_mask);
-            break;
-        }
-    }
-}
-
-static void extended_amd_topology_init() {
-    // Described in AMD CPUID Specification, version 2.34, section 3.2
-    const struct cpuid_leaf* leaf = x86_get_cpuid_leaf(X86_CPUID_ADDR_WIDTH);
-    if (!leaf)
-        return;
-
-    // width of the core part of the apic id
-    uint32_t apic_id_core_id_size = BITS_SHIFT(leaf->c, 15, 12);
-    if (apic_id_core_id_size == 0) {
-        legacy_topology_init();
-        return;
-    }
-
-    // initial state of variables that are optionally set below
-    // smt_mask = 0;
-    // core_shift = 0;
-    // node_shift = 0;
-    // node_mask = 0;
-
-    uint32_t node_size = 0;
-
-    // check to see if AMD topology extensions are enabled
-    if (x86_feature_test(X86_FEATURE_AMD_TOPO)) {
-        leaf = x86_get_cpuid_leaf(X86_CPUID_AMD_TOPOLOGY);
-        if (!leaf)
-            return;
-
-        uint32_t cores_per_compute_unit = BITS_SHIFT(leaf->b, 15, 8) + 1;
-        if (cores_per_compute_unit == 2) {
-            // SMT is enabled, the bottom bit of the APIC id is the SMT id
-            // This is according to the BKDG and PPR for family 15h-17h
-            smt_mask = 1;
-            core_shift = 1;
-        } else if (cores_per_compute_unit > 2) {
-            // not sure how to handle this, display message and move on
-            TRACEF("WARNING: cores per compute unit > 2 (%u), unhandled\n", cores_per_compute_unit);
-        }
-
-        uint32_t nodes_per_processor = BITS_SHIFT(leaf->c, 10, 8) + 1;
-        if (nodes_per_processor > 0 && ispow2(nodes_per_processor)) {
-            // a pow2 number of bits between the core number and package number refer to node
-            node_size = log2_uint_floor(nodes_per_processor);
-            node_shift = apic_id_core_id_size - node_size;
-            node_mask = (nodes_per_processor - 1) << node_shift;
-
-            // node number chews in to the core number, so subtract node_size off
-            // apic_id_core_id_size so that it computes the core mask properly
-            apic_id_core_id_size -= node_size;
-        }
-    }
-
-    // core is the mask of the bottom half of the APIC id space
-    core_mask = (1u << apic_id_core_id_size) - 1;
-
-    // package soaks up all the high bits of APIC id space
-    package_shift = node_size + apic_id_core_id_size;
-    package_mask = UINT32_MAX << (node_size + apic_id_core_id_size);
-}
-
-static void legacy_topology_init() {
-    const struct cpuid_leaf* leaf = x86_get_cpuid_leaf(X86_CPUID_MODEL_FEATURES);
-    if (!leaf) {
-        return;
-    }
-
-    bool pkg_size_valid = !!(leaf->d & (1 << 28));
-    if (!pkg_size_valid) {
-        return;
-    }
-
-    // Get the maximum number of addressable IDs at the sub-package level.
-    uint8_t max_num_subpackage = (leaf->b >> 16) & 0xff;
-
-    leaf = x86_get_cpuid_leaf(X86_CPUID_CACHE_V2);
-    if (!leaf) {
-        return;
-    }
-
-    // Get the maximum number of addressable cores with a package.
-    uint max_num_core = (leaf->a >> 26) + 1;
-    uint max_num_ht = max_num_subpackage / max_num_core;
-
-    package_mask = ~(max_num_subpackage - 1);
-    package_shift = __builtin_ctz(package_mask);
-
-    smt_mask = max_num_ht - 1;
-    core_shift = __builtin_ctz(~smt_mask);
-    core_mask = ~package_mask ^ smt_mask;
-}
-
-void x86_cpu_topology_decode(uint32_t apic_id, x86_cpu_topology_t* topo) {
-    *topo = {};
-
-    LTRACEF("id 0x%x: package shift/mask %u:%#x node shift/mask %u:%#x "
-            "core shift/mask %u:%#x smt mask %#x\n",
-            apic_id, package_shift, package_mask, node_shift, node_mask,
-            core_shift, core_mask, smt_mask);
-
-    topo->package_id = (apic_id & package_mask) >> package_shift;
-    topo->node_id = (apic_id & node_mask) >> node_shift;
-    topo->core_id = (apic_id & core_mask) >> core_shift;
-    topo->smt_id = apic_id & smt_mask;
-}
diff --git a/kernel/arch/x86/cpuid/cpuid.cpp b/kernel/arch/x86/cpuid/cpuid.cpp
deleted file mode 100644
index c66c4c0..0000000
--- a/kernel/arch/x86/cpuid/cpuid.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <arch/x86/cpuid.h>
-
-#include <memory>
-
-namespace cpu_id {
-namespace {
-
-inline uint8_t BaseFamilyFromEax(uint64_t eax) {
-    return (eax & 0xF00) >> 8;
-}
-
-Registers CallCpuId(uint32_t leaf, uint32_t subleaf = 0) {
-    Registers result;
-    // Set EAX and ECX to the initial values, call cpuid and copy results into
-    // the result object.
-    asm volatile(
-        "cpuid"
-        : "=a"(result.reg[Registers::EAX]),
-          "=b"(result.reg[Registers::EBX]),
-          "=c"(result.reg[Registers::ECX]),
-          "=d"(result.reg[Registers::EDX])
-        : "a"(leaf), "c"(subleaf));
-    return result;
-}
-
-// Convert power of two value to a shift_width.
-uint8_t ToShiftWidth(size_t value) {
-    if (value == 0) {
-        return 0;
-    }
-
-    uint8_t count = 0;
-    while (!((value >> count++) & 1))
-        ;
-    return --count; // an extra increment was added before testing.
-}
-
-} // namespace
-
-ManufacturerInfo CpuId::ReadManufacturerInfo() const {
-    return ManufacturerInfo(CallCpuId(0));
-}
-
-ProcessorId CpuId::ReadProcessorId() const {
-    return ProcessorId(CallCpuId(1));
-}
-
-Features CpuId::ReadFeatures() const {
-    return Features(CallCpuId(1), CallCpuId(7), CallCpuId(0x80000001));
-}
-
-Topology CpuId::ReadTopology() const {
-    Registers leafB[] = {
-        CallCpuId(11, 0),
-        CallCpuId(11, 1),
-        CallCpuId(11, 2)};
-    return Topology(ReadManufacturerInfo(), ReadFeatures(), CallCpuId(4), leafB);
-}
-
-ManufacturerInfo::ManufacturerInfo(Registers registers)
-    : registers_(registers) {}
-
-ManufacturerInfo::Manufacturer ManufacturerInfo::manufacturer() const {
-    char buffer[kManufacturerIdLength + 1] = {0};
-    manufacturer_id(buffer);
-    if (strcmp("GenuineIntel", buffer) == 0) {
-        return INTEL;
-    } else if (strcmp("AuthenticAMD", buffer) == 0) {
-        return AMD;
-    } else {
-        return OTHER;
-    }
-}
-
-void ManufacturerInfo::manufacturer_id(char* buffer) const {
-    union {
-        uint32_t regs[3];
-        char string[13];
-    } translator = {.regs = {registers_.ebx(), registers_.edx(), registers_.ecx()}};
-
-    memcpy(buffer, translator.string, kManufacturerIdLength);
-}
-
-size_t ManufacturerInfo::highest_cpuid_leaf() const {
-    return registers_.eax();
-}
-
-ProcessorId::ProcessorId(Registers registers)
-    : registers_(registers) {}
-
-uint8_t ProcessorId::stepping() const {
-    return registers_.eax() & 0xF;
-}
-
-uint16_t ProcessorId::model() const {
-    const uint8_t base = (registers_.eax() >> 4) & 0xF;
-    const uint8_t extended = (registers_.eax() >> 16) & 0xF;
-
-    const uint8_t family = BaseFamilyFromEax(registers_.eax());
-    if (family == 0xF || family == 0x6) {
-        return static_cast<uint16_t>((extended << 4) + base);
-    } else {
-        return base;
-    }
-}
-
-uint16_t ProcessorId::family() const {
-    const uint8_t base = BaseFamilyFromEax(registers_.eax());
-    const uint8_t extended = (registers_.eax() >> 20) & 0xFF;
-    if (base == 0xF) {
-        return static_cast<uint16_t>(base + extended);
-    } else {
-        return base;
-    }
-}
-
-uint8_t ProcessorId::local_apic_id() const {
-    return static_cast<uint8_t>((registers_.ebx() >> 24) & 0xFF);
-}
-
-Features::Features(Registers leaf1, Registers leaf7, Registers leaf8_01)
-    : leaves_{leaf1, leaf7, leaf8_01} {}
-
-uint8_t Features::max_logical_processors_in_package() const {
-    return (leaves_[LEAF1].ebx() >> 16) & 0x7F;
-}
-
-Topology::Topology(ManufacturerInfo info, Features features, Registers leaf4, Registers* leafB)
-    : info_(info), features_(features), leaf4_(leaf4), leafB_{leafB[0], leafB[1], leafB[2]} {}
-
-std::optional<Topology::Levels> Topology::IntelLevels() const {
-    Topology::Levels levels;
-    if (info_.highest_cpuid_leaf() >= 11) {
-        int nodes_under_previous_level = 0;
-        int bits_in_previous_levels = 0;
-        for (int i = 0; i < 3; i++) {
-            const uint8_t width = leafB_[i].eax() & 0xF;
-            if (width) {
-                uint8_t raw_type = (leafB_[i].ecx() & 0xFF00) >> 8;
-
-                LevelType type = LevelType::INVALID;
-                if (raw_type == 1) {
-                    type = LevelType::SMT;
-                } else if (raw_type == 2) {
-                    type = LevelType::CORE;
-                } else if (i == 2) {
-                    // Package is defined as the "last" level.
-                    type = LevelType::PACKAGE;
-                }
-
-                // This actually contains total logical processors in all
-                // subtrees of this level of the topology.
-                const uint16_t nodes_under_level = leafB_[i].ebx() & 0xFF;
-                const uint8_t node_count = static_cast<uint8_t>(
-                    nodes_under_level / ((nodes_under_previous_level == 0) ? 1 : nodes_under_previous_level));
-                const uint8_t shift_width = static_cast<uint8_t>(width - bits_in_previous_levels);
-
-                levels.levels[levels.level_count++] = {
-                    .type = type,
-                    // Dividing by logical processors under last level will give
-                    // us the nodes that are at this level.
-                    .node_count = node_count,
-                    .shift_width = shift_width,
-                };
-                nodes_under_previous_level += nodes_under_level;
-                bits_in_previous_levels += shift_width;
-            }
-        }
-    } else if (info_.highest_cpuid_leaf() >= 4) {
-        const bool single_core = !features_.HasFeature(Features::HTT);
-        if (single_core) {
-            levels.levels[levels.level_count++] = {
-                .type = LevelType::PACKAGE,
-                .node_count = 1,
-                .shift_width = 0,
-            };
-        } else {
-            const auto logical_in_package = features_.max_logical_processors_in_package();
-            const auto cores_in_package = ((leaf4_.eax() >> 26) & 0x3F) + 1;
-            const auto logical_per_core = logical_in_package / cores_in_package;
-            if (logical_per_core > 1) {
-                levels.levels[levels.level_count++] = {
-                    .type = LevelType::SMT,
-                    .shift_width = ToShiftWidth(logical_per_core),
-                };
-            }
-
-            if (cores_in_package > 1) {
-                levels.levels[levels.level_count++] = {
-                    .type = LevelType::CORE,
-                    .shift_width = ToShiftWidth(cores_in_package),
-                };
-            }
-        }
-    } else {
-        // If this is an intel CPU then cpuid leaves are disabled on the system
-        // IA32_MISC_ENABLES[22] == 1. This can be set to 0, usually in the BIOS,
-        // the kernel can change it too but we prefer to stay read-only here.
-        return std::nullopt;
-    }
-
-    return {levels};
-}
-
-std::optional<Topology::Levels> Topology::levels() const {
-    auto levels = IntelLevels();
-    if (levels) {
-        return levels;
-    }
-
-    // If Intel approach didn't work try the AMD approach, even on AMD chips the
-    // intel approach may work, there are hypervisor cases that populate it.
-    // TODO(edcoyne): Implement AMD approach.
-    printf("WARNING: AMD processors are not yet supported. \n");
-
-    printf("WARNING: Unable to parse topology from CPUID. If this is an Intel chip, "
-           "ensure IA32_MISC_ENABLES[22] is off.\n");
-    return std::nullopt;
-}
-
-} // namespace cpu_id
diff --git a/kernel/arch/x86/cpuid/cpuid_test.cpp b/kernel/arch/x86/cpuid/cpuid_test.cpp
deleted file mode 100644
index 77f4528..0000000
--- a/kernel/arch/x86/cpuid/cpuid_test.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <arch/x86/cpuid.h>
-
-#include <initializer_list>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <lib/unittest/unittest.h>
-
-namespace {
-using cpu_id::CpuId;
-using cpu_id::Features;
-using cpu_id::ManufacturerInfo;
-using cpu_id::ProcessorId;
-using cpu_id::Registers;
-using cpu_id::Topology;
-
-} // namespace
-
-struct TestDataSet {
-    Features::Feature features[200];
-    Features::Feature missing_features[200];
-    Registers leaf0;
-    Registers leaf1;
-    Registers leaf4;
-    Registers leaf7;
-    Registers leafB[3];
-    Registers leaf80000001;
-};
-
-// Queried from a Intel Xeon E5-2690v4.
-const TestDataSet Xeon2690v4Data = {
-    .features = {Features::FPU, Features::VME, Features::DE, Features::PSE, Features::TSC,
-                 Features::MSR, Features::PAE, Features::MCE, Features::CX8, Features::APIC, Features::SEP,
-                 Features::MTRR, Features::PGE, Features::MCA, Features::CMOV, Features::PAT,
-                 Features::PSE36, Features::ACPI, Features::MMX, Features::FSGSBASE,
-                 Features::FXSR, Features::SSE, Features::SSE2, Features::SS, Features::HTT, Features::TM,
-                 Features::PBE, Features::SYSCALL, Features::XD, Features::PDPE1GB, Features::RDTSCP,
-                 Features::PCLMULQDQ, Features::DTES64, Features::MONITOR, Features::DS_CPL, Features::VMX,
-                 Features::SMX, Features::EST, Features::TM2, Features::SSSE3, Features::SDBG,
-                 Features::FMA, Features::CX16, Features::XTPR, Features::PDCM, Features::PCID,
-                 Features::DCA, Features::SSE4_1, Features::SSE4_2, Features::X2APIC, Features::MOVBE,
-                 Features::POPCNT, Features::AES, Features::XSAVE, Features::AVX, Features::F16C,
-                 Features::RDRAND, Features::LAHF, Features::BMI1, Features::HLE, Features::AVX2,
-                 Features::SMEP, Features::BMI2, Features::ERMS, Features::INVPCID, Features::RTM,
-                 Features::RDSEED, Features::ADX, Features::SMAP, Features::INTEL_PT},
-    .missing_features = {Features::PSN, Features::AVX512VNNI},
-    .leaf0 = {.reg = {0x14, 0x756E6547, 0x6C65746E, 0x49656E69}},
-    .leaf1 = {.reg = {0x406F1, 0x12200800, 0x7FFEFBFF, 0xBFEBFBFF}},
-    .leaf4 = {.reg = {0x3C004121, 0x1C0003F, 0x3F, 0x0}},
-    .leaf7 = {.reg = {0x0, 0x21CBFBB, 0x0, 0x9C000000}},
-    .leafB = {{.reg = {0x1, 0x2, 0x100, 0x28}},
-              {.reg = {0x5, 0x1C, 0x201, 0x29}},
-              {.reg = {0x0, 0x0, 0x2, 0x38}}},
-    .leaf80000001 = {.reg = {0x0, 0x0, 0x121, 0x2C100800}},
-};
-
-bool test_feature_flags() {
-    BEGIN_TEST;
-
-    auto data = Xeon2690v4Data;
-    Features features(data.leaf1, data.leaf7, data.leaf80000001);
-
-    // Features we know this processor has.
-    for (auto feature : data.features) {
-        if (feature.leaf == Features::INVALID_SET)
-            continue;
-
-        const bool result = features.HasFeature(feature);
-        if (!result) {
-            printf("Missing Feature: set:%u reg:%u bit:%u\n",
-                   feature.leaf, feature.reg, feature.bit);
-        }
-        EXPECT_TRUE(result, "");
-    }
-
-    // Some features we know it doesn't.
-    for (auto feature : data.missing_features) {
-        if (feature.leaf == Features::INVALID_SET)
-            continue;
-
-        const bool result = features.HasFeature(feature);
-        if (result) {
-            printf("Extra Feature: set:%u reg:%u bit:%u\n",
-                   feature.leaf, feature.reg, feature.bit);
-        }
-        EXPECT_FALSE(result, "");
-    }
-
-    END_TEST;
-}
-
-bool test_max_logical_processors() {
-    BEGIN_TEST;
-
-    auto data = Xeon2690v4Data;
-    Features features(data.leaf1, data.leaf7, data.leaf80000001);
-
-    EXPECT_EQ(32, features.max_logical_processors_in_package(), "");
-
-    END_TEST;
-}
-
-bool test_manufacturer_info() {
-    BEGIN_TEST;
-    auto data = Xeon2690v4Data;
-
-    char buffer[ManufacturerInfo::kManufacturerIdLength + 1] = {0};
-    auto info = ManufacturerInfo(data.leaf0);
-    info.manufacturer_id(buffer);
-
-    EXPECT_TRUE(strcmp("GenuineIntel", buffer) == 0, buffer);
-    EXPECT_EQ(ManufacturerInfo::INTEL, info.manufacturer(), "");
-    EXPECT_EQ(20u, info.highest_cpuid_leaf(), "");
-
-    END_TEST;
-}
-
-bool test_processor_id() {
-    BEGIN_TEST;
-    auto data = Xeon2690v4Data;
-
-    ProcessorId proc(data.leaf1);
-    EXPECT_EQ(6, proc.family(), "");
-    EXPECT_EQ(79, proc.model(), "");
-    EXPECT_EQ(1, proc.stepping(), "");
-
-    END_TEST;
-}
-
-bool test_topology() {
-    BEGIN_TEST;
-    auto data = Xeon2690v4Data;
-
-    Topology topology(ManufacturerInfo(data.leaf0),
-                      Features(data.leaf1, data.leaf7, data.leaf80000001),
-                      data.leaf4, data.leafB);
-
-    const auto levels_opt = topology.levels();
-    ASSERT_TRUE(levels_opt, "");
-
-    const auto& levels = *levels_opt;
-    EXPECT_EQ(Topology::LevelType::SMT, levels.levels[0].type, "");
-    EXPECT_EQ(2u, levels.levels[0].node_count, "");
-    EXPECT_EQ(1u, levels.levels[0].shift_width, "");
-
-    EXPECT_EQ(Topology::LevelType::CORE, levels.levels[1].type, "");
-    EXPECT_EQ(14u, levels.levels[1].node_count, "");
-    EXPECT_EQ(4u, levels.levels[1].shift_width, "");
-
-    EXPECT_EQ(Topology::LevelType::INVALID, levels.levels[2].type, "");
-
-    END_TEST;
-}
-
-// Tests other intel path, using leaf4 instead of extended leafB.
-bool test_topology_intel_leaf4() {
-    BEGIN_TEST;
-    auto data = Xeon2690v4Data;
-
-    // We need to report that we don't support leafB.
-    auto modifiedLeaf0 = data.leaf0;
-    modifiedLeaf0.reg[Registers::EAX] = 4;
-    auto manufacturer = ManufacturerInfo(modifiedLeaf0);
-    EXPECT_EQ(4u, manufacturer.highest_cpuid_leaf(), "");
-
-    Topology topology(manufacturer,
-                      Features(data.leaf1, data.leaf7, data.leaf80000001),
-                      data.leaf4, data.leafB);
-
-    const auto levels_opt = topology.levels();
-    ASSERT_TRUE(levels_opt, "");
-
-    const auto& levels = *levels_opt;
-    EXPECT_EQ(Topology::LevelType::SMT, levels.levels[0].type, "");
-    EXPECT_EQ(Topology::kInvalidCount, levels.levels[0].node_count, "");
-    EXPECT_EQ(1u, levels.levels[0].shift_width, "");
-
-    EXPECT_EQ(Topology::LevelType::CORE, levels.levels[1].type, "");
-    EXPECT_EQ(Topology::kInvalidCount, levels.levels[1].node_count, "");
-    EXPECT_EQ(4u, levels.levels[1].shift_width, "");
-
-    EXPECT_EQ(Topology::LevelType::INVALID, levels.levels[2].type, "");
-
-    END_TEST;
-}
-
-UNITTEST_START_TESTCASE(cpuid_tests)
-UNITTEST("Parse feature flags from static data.", test_feature_flags)
-UNITTEST("Parse maximum logical processors from static data.", test_max_logical_processors)
-UNITTEST("Parse manufacturer info from static data.", test_manufacturer_info)
-UNITTEST("Parse processor id from static data.", test_processor_id)
-UNITTEST("Parse topology from static data.", test_topology)
-UNITTEST("Parse topology from static data, using leaf4.", test_topology_intel_leaf4)
-UNITTEST_END_TESTCASE(cpuid_tests, "cpuid", "Test parsing of cpuid values.");
diff --git a/kernel/arch/x86/cpuid/include/arch/x86/cpuid.h b/kernel/arch/x86/cpuid/include/arch/x86/cpuid.h
deleted file mode 100644
index fd9725b..0000000
--- a/kernel/arch/x86/cpuid/include/arch/x86/cpuid.h
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright 2019 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef KERNEL_ARCH_X86_CPUID_H_
-#define KERNEL_ARCH_X86_CPUID_H_
-
-#include <cstdint>
-#include <cstring>
-#include <optional>
-
-#include <assert.h>
-
-namespace cpu_id {
-
-struct Registers {
-    enum {
-        EAX = 0,
-        EBX = 1,
-        ECX = 2,
-        EDX = 3,
-    };
-
-    inline uint32_t eax() const {
-        return reg[EAX];
-    }
-    inline uint32_t ebx() const {
-        return reg[EBX];
-    }
-    inline uint32_t edx() const {
-        return reg[EDX];
-    }
-    inline uint32_t ecx() const {
-        return reg[ECX];
-    }
-
-    uint32_t reg[4];
-};
-
-// Extracts the manufacturer id string from call with EAX=0.
-class ManufacturerInfo {
-public:
-    enum Manufacturer {
-        INTEL,
-        AMD,
-        OTHER
-    };
-
-    // How many chars are in a manufacturer id.
-    static constexpr size_t kManufacturerIdLength = 12;
-
-    ManufacturerInfo(Registers leaf0);
-
-    Manufacturer manufacturer() const;
-
-    // Reads the manufacturer id and writes it into the buffer, buffer should be
-    // at least kManufacturerIdLength in length. This will not null-terminate the
-    // string.
-    void manufacturer_id(char* buffer) const;
-
-    // Highest leaf (EAX parameter to cpuid) that this processor supports.
-    size_t highest_cpuid_leaf() const;
-
-private:
-    const Registers registers_;
-};
-
-// Extracts the processor signature/id from call with EAX=1.
-class ProcessorId {
-public:
-    ProcessorId(Registers registers);
-
-    // Stepping, or revision, of this model.
-    uint8_t stepping() const;
-
-    // Model inside of the given family.
-    uint16_t model() const;
-
-    // Family of processors to which this chip belongs.
-    uint16_t family() const;
-
-    // APIC ID of the processor on which this object was generated. Note this
-    // class uses a cached copy of registers so if this object was generated on
-    // a differnet processor this value could be misleading.
-    uint8_t local_apic_id() const;
-
-private:
-    const Registers registers_;
-};
-
-// Extracts feature flags from EAX=1 call and extended feature flags calls.
-// See docs for full listing of possible features, this class is not
-// comprehensive, things are added as they are required.
-class Features {
-public:
-    enum LeafIndex {
-        LEAF1,
-        LEAF7,
-        LEAF8_01,
-        INVALID_SET = 254,
-    };
-
-    struct Feature {
-        uint8_t leaf = INVALID_SET;
-        uint8_t reg;
-        uint8_t bit;
-    };
-
-    // Feature "enum".
-    static constexpr Feature FPU = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 0};
-    static constexpr Feature VME = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 1};
-    static constexpr Feature DE = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 2};
-    static constexpr Feature PSE = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 3};
-    static constexpr Feature TSC = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 4};
-    static constexpr Feature MSR = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 5};
-    static constexpr Feature PAE = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 6};
-    static constexpr Feature MCE = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 7};
-    static constexpr Feature CX8 = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 8};
-    static constexpr Feature APIC = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 9};
-    static constexpr Feature SEP = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 11};
-    static constexpr Feature MTRR = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 12};
-    static constexpr Feature PGE = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 13};
-    static constexpr Feature MCA = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 14};
-    static constexpr Feature CMOV = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 15};
-    static constexpr Feature PAT = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 16};
-    static constexpr Feature PSE36 = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 17};
-    static constexpr Feature PSN = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 18};
-    static constexpr Feature CLFSH = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 19};
-    static constexpr Feature DS = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 21};
-    static constexpr Feature ACPI = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 22};
-    static constexpr Feature MMX = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 23};
-    static constexpr Feature FXSR = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 24};
-    static constexpr Feature SSE = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 25};
-    static constexpr Feature SSE2 = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 26};
-    static constexpr Feature SS = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 27};
-    static constexpr Feature HTT = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 28};
-    static constexpr Feature TM = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 29};
-    static constexpr Feature PBE = {.leaf = LEAF1, .reg = Registers::EDX, .bit = 31};
-    static constexpr Feature SSE3 = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 0};
-    static constexpr Feature PCLMULQDQ = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 1};
-    static constexpr Feature DTES64 = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 2};
-    static constexpr Feature MONITOR = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 3};
-    static constexpr Feature DS_CPL = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 4};
-    static constexpr Feature VMX = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 5};
-    static constexpr Feature SMX = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 6};
-    static constexpr Feature EST = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 7};
-    static constexpr Feature TM2 = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 8};
-    static constexpr Feature SSSE3 = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 9};
-    static constexpr Feature CNXT_ID = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 10};
-    static constexpr Feature SDBG = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 11};
-    static constexpr Feature FMA = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 12};
-    static constexpr Feature CX16 = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 13};
-    static constexpr Feature XTPR = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 14};
-    static constexpr Feature PDCM = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 15};
-    static constexpr Feature PCID = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 17};
-    static constexpr Feature DCA = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 18};
-    static constexpr Feature SSE4_1 = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 19};
-    static constexpr Feature SSE4_2 = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 20};
-    static constexpr Feature X2APIC = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 21};
-    static constexpr Feature MOVBE = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 22};
-    static constexpr Feature POPCNT = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 23};
-    static constexpr Feature TSC_DEADLINE = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 24};
-    static constexpr Feature AES = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 25};
-    static constexpr Feature XSAVE = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 26};
-    static constexpr Feature OSXSAVE = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 27};
-    static constexpr Feature AVX = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 28};
-    static constexpr Feature F16C = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 29};
-    static constexpr Feature RDRAND = {.leaf = LEAF1, .reg = Registers::ECX, .bit = 30};
-
-    static constexpr Feature FSGSBASE = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 0};
-    static constexpr Feature SGX = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 2};
-    static constexpr Feature BMI1 = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 3};
-    static constexpr Feature HLE = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 4};
-    static constexpr Feature AVX2 = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 5};
-    static constexpr Feature SMEP = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 7};
-    static constexpr Feature BMI2 = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 8};
-    static constexpr Feature ERMS = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 9};
-    static constexpr Feature INVPCID = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 10};
-    static constexpr Feature RTM = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 11};
-    static constexpr Feature PQM = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 12};
-    static constexpr Feature MPX = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 14};
-    static constexpr Feature PQE = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 15};
-    static constexpr Feature AVX512F = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 16};
-    static constexpr Feature AVX512DQ = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 17};
-    static constexpr Feature RDSEED = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 18};
-    static constexpr Feature ADX = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 19};
-    static constexpr Feature SMAP = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 20};
-    static constexpr Feature AVX512IFMA = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 21};
-    static constexpr Feature PCOMMIT = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 22};
-    static constexpr Feature CLWB = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 24};
-    static constexpr Feature INTEL_PT = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 25};
-    static constexpr Feature AVX512PF = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 26};
-    static constexpr Feature AVX512ER = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 27};
-    static constexpr Feature AVX512CD = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 28};
-    static constexpr Feature SHA = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 29};
-    static constexpr Feature AVX512BW = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 30};
-    static constexpr Feature AVX512VL = {.leaf = LEAF7, .reg = Registers::EBX, .bit = 31};
-    static constexpr Feature PREFETCHWT1 = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 0};
-    static constexpr Feature AVX512VBMI = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 1};
-    static constexpr Feature UMIP = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 2};
-    static constexpr Feature PKU = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 3};
-    static constexpr Feature OSPKE = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 4};
-    static constexpr Feature AVX512VBMI2 = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 6};
-    static constexpr Feature GFNI = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 8};
-    static constexpr Feature VAES = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 9};
-    static constexpr Feature VPCLMULQDQ = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 10};
-    static constexpr Feature AVX512VNNI = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 11};
-    static constexpr Feature AVX512BITALG = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 12};
-    static constexpr Feature AVX512VPOPCNTDQ = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 14};
-    static constexpr Feature RDPID = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 22};
-    static constexpr Feature SGX_LC = {.leaf = LEAF7, .reg = Registers::ECX, .bit = 30};
-    static constexpr Feature AVX512_4VNNIW = {.leaf = LEAF7, .reg = Registers::EDX, .bit = 2};
-    static constexpr Feature AVX512_4FMAPS = {.leaf = LEAF7, .reg = Registers::EDX, .bit = 3};
-    static constexpr Feature PCONFIG = {.leaf = LEAF7, .reg = Registers::EDX, .bit = 18};
-    static constexpr Feature CLFLUSH = {.leaf = LEAF7, .reg = Registers::EDX, .bit = 19};
-    static constexpr Feature SPEC_CTRL = {.leaf = LEAF7, .reg = Registers::EDX, .bit = 26};
-    static constexpr Feature STIBP = {.leaf = LEAF7, .reg = Registers::EDX, .bit = 27};
-
-    static constexpr Feature LAHF = {.leaf = LEAF8_01, .reg = Registers::ECX, .bit = 0};
-    static constexpr Feature IA64 = {.leaf = LEAF8_01, .reg = Registers::EDX, .bit = 29};
-    static constexpr Feature RDTSCP = {.leaf = LEAF8_01, .reg = Registers::EDX, .bit = 27};
-    static constexpr Feature PDPE1GB = {.leaf = LEAF8_01, .reg = Registers::EDX, .bit = 26};
-    static constexpr Feature XD = {.leaf = LEAF8_01, .reg = Registers::EDX, .bit = 20};
-    static constexpr Feature SYSCALL = {.leaf = LEAF8_01, .reg = Registers::EDX, .bit = 11};
-
-    Features(Registers leaf1, Registers leaf7, Registers leaf8_01);
-
-    inline bool HasFeature(Feature feature) const {
-        DEBUG_ASSERT_MSG(feature.leaf < kLeafCount &&
-                             feature.reg <= Registers::EDX &&
-                             feature.bit <= 32,
-                         "set: %u reg:%u %d bit: %u",
-                         feature.leaf, feature.reg, Registers::EDX, feature.bit);
-        return leaves_[feature.leaf].reg[feature.reg] & (1 << feature.bit);
-    }
-
-    // Returns the maximum supported logical processors in a physical package.
-    // This is NOT that same as the number of logical processors present.
-    uint8_t max_logical_processors_in_package() const;
-
-private:
-    static constexpr size_t kLeafCount = 3;
-
-    const Registers leaves_[kLeafCount];
-};
-
-// Parses topology data from the CPUID instruction.
-class Topology {
-public:
-    static constexpr size_t kMaxLevels = 3;
-    static constexpr uint8_t kInvalidCount = 255;
-    enum class LevelType {
-        INVALID,
-        SMT,
-        CORE,
-        PACKAGE
-    };
-    struct Level {
-        LevelType type = LevelType::INVALID;
-
-        // node_count is set best-effort, only some systems provide it.
-        uint8_t node_count = kInvalidCount;
-
-        uint8_t shift_width = 0;
-    };
-    struct Levels {
-        Level levels[kMaxLevels];
-        uint8_t level_count = 0;
-    };
-
-    Topology(ManufacturerInfo info, Features features,
-             Registers leaf4, Registers* leafB);
-
-    // Provides details for each level of this system's topology.
-    // Returns nullopt if unable to parse topology from cpuid data.
-    std::optional<Levels> levels() const;
-
-private:
-    std::optional<Levels> IntelLevels() const;
-
-    static constexpr size_t kEaxBLevels = 3;
-
-    ManufacturerInfo info_;
-    Features features_;
-
-    Registers leaf4_;
-    Registers leafB_[kEaxBLevels];
-};
-
-// Wraps the CPUID instruction on x86, provides helpers to parse the output and
-// allows unit testing of libraries reading it.
-class CpuId {
-public:
-    virtual ~CpuId() = default;
-    virtual ManufacturerInfo ReadManufacturerInfo() const;
-    virtual ProcessorId ReadProcessorId() const;
-    virtual Features ReadFeatures() const;
-    virtual Topology ReadTopology() const;
-
-private:
-};
-
-} // namespace cpu_id
-
-#endif // KERNEL_ARCH_X86_CPUID_H_
diff --git a/kernel/arch/x86/cpuid/rules.mk b/kernel/arch/x86/cpuid/rules.mk
deleted file mode 100644
index e4f0f04..0000000
--- a/kernel/arch/x86/cpuid/rules.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-# Common Code
-
-LOCAL_SRCS := \
-    $(LOCAL_DIR)/cpuid.cpp \
-    $(LOCAL_DIR)/cpuid_test.cpp \
-
-# system-topology
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_GROUP := core
-
-MODULE_SRCS := $(LOCAL_SRCS)
-
-MODULE_DEPS := \
-    kernel/lib/fbl \
-    kernel/lib/unittest \
-
-MODULE_NAME := cpuid
-
-include make/module.mk
diff --git a/kernel/arch/x86/debugger.cpp b/kernel/arch/x86/debugger.cpp
deleted file mode 100644
index 3ba5231..0000000
--- a/kernel/arch/x86/debugger.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/debugger.h>
-#include <arch/x86.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/registers.h>
-#include <err.h>
-#include <kernel/lockdep.h>
-#include <kernel/thread.h>
-#include <kernel/thread_lock.h>
-#include <string.h>
-#include <sys/types.h>
-#include <zircon/syscalls/debug.h>
-#include <zircon/types.h>
-
-// Note on locking: The below functions need to read and write the register state and make sure that
-// nothing happens with respect to scheduling that thread while this is happening. As a result they
-// use ThreadLock. In most cases this will not be necessary but there are relatively few
-// guarantees so we lock the scheduler. Since these functions are used mostly for debugging, this
-// shouldn't be too significant a performance penalty.
-
-namespace {
-
-#define SYSCALL_OFFSETS_EQUAL(reg)                      \
-    (__offsetof(zx_thread_state_general_regs_t, reg) == \
-     __offsetof(x86_syscall_general_regs_t, reg))
-
-static_assert(SYSCALL_OFFSETS_EQUAL(rax), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(rbx), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(rcx), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(rdx), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(rsi), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(rdi), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(rbp), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(rsp), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(r8), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(r9), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(r10), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(r11), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(r12), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(r13), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(r14), "");
-static_assert(SYSCALL_OFFSETS_EQUAL(r15), "");
-static_assert(sizeof(zx_thread_state_general_regs_t) == sizeof(x86_syscall_general_regs_t), "");
-
-void x86_fill_in_gregs_from_syscall(zx_thread_state_general_regs_t* out,
-                                    const x86_syscall_general_regs_t* in) {
-    memcpy(out, in, sizeof(*in));
-}
-
-void x86_fill_in_syscall_from_gregs(x86_syscall_general_regs_t* out,
-                                    const zx_thread_state_general_regs_t* in) {
-    // Don't allow overriding privileged fields of rflags, and ignore writes
-    // to reserved fields.
-    const uint64_t orig_rflags = out->rflags;
-    memcpy(out, in, sizeof(*in));
-    out->rflags = orig_rflags & ~X86_FLAGS_USER;
-    out->rflags |= in->rflags & X86_FLAGS_USER;
-}
-
-#define COPY_REG(out, in, reg) (out)->reg = (in)->reg
-#define COPY_COMMON_IFRAME_REGS(out, in) \
-    do {                                 \
-        COPY_REG(out, in, rax);          \
-        COPY_REG(out, in, rbx);          \
-        COPY_REG(out, in, rcx);          \
-        COPY_REG(out, in, rdx);          \
-        COPY_REG(out, in, rsi);          \
-        COPY_REG(out, in, rdi);          \
-        COPY_REG(out, in, rbp);          \
-        COPY_REG(out, in, r8);           \
-        COPY_REG(out, in, r9);           \
-        COPY_REG(out, in, r10);          \
-        COPY_REG(out, in, r11);          \
-        COPY_REG(out, in, r12);          \
-        COPY_REG(out, in, r13);          \
-        COPY_REG(out, in, r14);          \
-        COPY_REG(out, in, r15);          \
-    } while (0)
-
-void x86_fill_in_gregs_from_iframe(zx_thread_state_general_regs_t* out,
-                                   const x86_iframe_t* in) {
-    COPY_COMMON_IFRAME_REGS(out, in);
-    out->rsp = in->user_sp;
-    out->rip = in->ip;
-    out->rflags = in->flags;
-}
-
-void x86_fill_in_iframe_from_gregs(x86_iframe_t* out,
-                                   const zx_thread_state_general_regs_t* in) {
-    COPY_COMMON_IFRAME_REGS(out, in);
-    out->user_sp = in->rsp;
-    out->ip = in->rip;
-    // Don't allow overriding privileged fields of rflags, and ignore writes
-    // to reserved fields.
-    out->flags &= ~X86_FLAGS_USER;
-    out->flags |= in->rflags & X86_FLAGS_USER;
-}
-
-// Whether an operation gets thread state or sets it.
-enum class RegAccess { kGet,
-                       kSet };
-
-// Backend for arch_get_vector_regs and arch_set_vector_regs. This does a read or write of the
-// thread to or from the regs structure.
-zx_status_t x86_get_set_vector_regs(struct thread* thread, zx_thread_state_vector_regs* regs,
-                                    RegAccess access) {
-    // Function to copy memory in the correct direction. Write the code using this function as if it
-    // was "memcpy" in "get" mode, and it will be reversed in "set" mode.
-    auto get_set_memcpy = (access == RegAccess::kGet) ? [](void* regs, void* thread, size_t size) { memcpy(regs, thread, size); } : // Get mode.
-                              [](void* regs, void* thread, size_t size) { memcpy(thread, regs, size); };                            // Set mode.
-
-    if (access == RegAccess::kGet) {
-        // Not all parts will be filled in in all cases so zero out first.
-        memset(regs, 0, sizeof(zx_thread_state_vector_regs));
-    }
-
-    // Whether to force the components to be marked present in the xsave area.
-    bool mark_present = access == RegAccess::kSet;
-
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    constexpr int kNumSSERegs = 16;
-
-    // The low 128 bits of registers 0-15 come from the legacy area and are always present.
-    constexpr int kXmmRegSize = 16; // Each XMM register is 128 bits / 16 bytes.
-    uint32_t comp_size = 0;
-    x86_xsave_legacy_area* save = static_cast<x86_xsave_legacy_area*>(
-        x86_get_extended_register_state_component(thread->arch.extended_register_state,
-                                                  X86_XSAVE_STATE_INDEX_SSE, mark_present,
-                                                  &comp_size));
-    DEBUG_ASSERT(save); // Legacy getter should always succeed.
-    for (int i = 0; i < kNumSSERegs; i++) {
-        get_set_memcpy(&regs->zmm[i].v[0], &save->xmm[i], kXmmRegSize);
-    }
-
-    // MXCSR (always present): 32-bit status word.
-    get_set_memcpy(&regs->mxcsr, &save->mxcsr, 4);
-
-    // AVX grows the registers to 256 bits each. Optional.
-    constexpr int kYmmHighSize = 16; // Additional bytes in each register.
-    uint8_t* ymm_highbits = static_cast<uint8_t*>(
-        x86_get_extended_register_state_component(thread->arch.extended_register_state,
-                                                  X86_XSAVE_STATE_INDEX_AVX, mark_present,
-                                                  &comp_size));
-    if (ymm_highbits) {
-        DEBUG_ASSERT(comp_size == kYmmHighSize * kNumSSERegs);
-        for (int i = 0; i < kNumSSERegs; i++) {
-            get_set_memcpy(&regs->zmm[i].v[2], &ymm_highbits[i * kYmmHighSize], kYmmHighSize);
-        }
-    }
-
-    // AVX-512 opmask registers (8 64-bit registers). Optional.
-    constexpr int kNumOpmaskRegs = 8;
-    uint64_t* opmask = static_cast<uint64_t*>(
-        x86_get_extended_register_state_component(thread->arch.extended_register_state,
-                                                  X86_XSAVE_STATE_INDEX_AVX512_OPMASK, mark_present,
-                                                  &comp_size));
-    if (opmask) {
-        DEBUG_ASSERT(comp_size == kNumOpmaskRegs * sizeof(uint64_t));
-        for (int i = 0; i < kNumOpmaskRegs; i++) {
-            get_set_memcpy(&regs->opmask[i], &opmask[i], sizeof(uint64_t));
-        }
-    }
-
-    // AVX-512 high bits (256 bits extra each) for ZMM0-15.
-    constexpr int kZmmHighSize = 32; // Additional bytes in each register.
-    uint8_t* zmm_highbits = static_cast<uint8_t*>(
-        x86_get_extended_register_state_component(thread->arch.extended_register_state,
-                                                  X86_XSAVE_STATE_INDEX_AVX512_LOWERZMM_HIGH,
-                                                  mark_present, &comp_size));
-    if (zmm_highbits) {
-        DEBUG_ASSERT(comp_size == kZmmHighSize * kNumSSERegs);
-        for (int i = 0; i < kNumSSERegs; i++) {
-            get_set_memcpy(&regs->zmm[i].v[4], &zmm_highbits[i * kZmmHighSize], kZmmHighSize);
-        }
-    }
-
-    // AVX-512 registers 16-31 (512 bits each) are in component 7.
-    constexpr int kNumZmmHighRegs = 16; // Extra registers added over xmm/ymm.
-    constexpr int kZmmRegSize = 64;     // Total register size.
-    uint8_t* zmm_highregs = static_cast<uint8_t*>(
-        x86_get_extended_register_state_component(thread->arch.extended_register_state,
-                                                  X86_XSAVE_STATE_INDEX_AVX512_HIGHERZMM,
-                                                  mark_present, &comp_size));
-    if (zmm_highregs) {
-        DEBUG_ASSERT(comp_size == kNumZmmHighRegs * kZmmRegSize);
-        for (int i = 0; i < kNumZmmHighRegs; i++) {
-            get_set_memcpy(&regs->zmm[i + kNumSSERegs], &zmm_highregs[i * kZmmRegSize],
-                           kZmmRegSize);
-        }
-    }
-
-    return ZX_OK;
-}
-
-} // namespace
-
-zx_status_t arch_get_general_regs(struct thread* thread, zx_thread_state_general_regs_t* out) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Punt if registers aren't available. E.g.,
-    // ZX-563 (registers aren't available in synthetic exceptions)
-    if (thread->arch.suspended_general_regs.gregs == nullptr)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    DEBUG_ASSERT(thread->arch.suspended_general_regs.gregs);
-    switch (thread->arch.general_regs_source) {
-    case X86_GENERAL_REGS_SYSCALL:
-        x86_fill_in_gregs_from_syscall(out, thread->arch.suspended_general_regs.syscall);
-        break;
-    case X86_GENERAL_REGS_IFRAME:
-        x86_fill_in_gregs_from_iframe(out, thread->arch.suspended_general_regs.iframe);
-        break;
-    default:
-        DEBUG_ASSERT(false);
-        return ZX_ERR_BAD_STATE;
-    }
-
-    return ZX_OK;
-}
-
-zx_status_t arch_set_general_regs(struct thread* thread, const zx_thread_state_general_regs_t* in) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Punt if registers aren't available. E.g.,
-    // ZX-563 (registers aren't available in synthetic exceptions)
-    if (thread->arch.suspended_general_regs.gregs == nullptr)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    DEBUG_ASSERT(thread->arch.suspended_general_regs.gregs);
-    switch (thread->arch.general_regs_source) {
-    case X86_GENERAL_REGS_SYSCALL: {
-        // Disallow setting RIP to a non-canonical address, to prevent
-        // returning to such addresses using the SYSRET instruction.
-        // See docs/sysret_problem.md.  Note that this check also
-        // disallows canonical top-bit-set addresses, but allowing such
-        // addresses is not useful and it is simpler to disallow them.
-        uint8_t addr_width = x86_linear_address_width();
-        uint64_t noncanonical_addr = ((uint64_t)1) << (addr_width - 1);
-        if (in->rip >= noncanonical_addr)
-            return ZX_ERR_INVALID_ARGS;
-        x86_fill_in_syscall_from_gregs(thread->arch.suspended_general_regs.syscall, in);
-        break;
-    }
-    case X86_GENERAL_REGS_IFRAME:
-        x86_fill_in_iframe_from_gregs(thread->arch.suspended_general_regs.iframe, in);
-        break;
-    default:
-        DEBUG_ASSERT(false);
-        return ZX_ERR_BAD_STATE;
-    }
-
-    return ZX_OK;
-}
-
-zx_status_t arch_get_single_step(struct thread* thread, bool* single_step) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Punt if registers aren't available. E.g.,
-    // ZX-563 (registers aren't available in synthetic exceptions)
-    if (thread->arch.suspended_general_regs.gregs == nullptr)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    uint64_t* flags = nullptr;
-    switch (thread->arch.general_regs_source) {
-    case X86_GENERAL_REGS_SYSCALL:
-        flags = &thread->arch.suspended_general_regs.syscall->rflags;
-        break;
-    case X86_GENERAL_REGS_IFRAME:
-        flags = &thread->arch.suspended_general_regs.iframe->flags;
-        break;
-    default:
-        DEBUG_ASSERT(false);
-        return ZX_ERR_BAD_STATE;
-    }
-
-    *single_step = !!(*flags & X86_FLAGS_TF);
-    return ZX_OK;
-}
-
-zx_status_t arch_set_single_step(struct thread* thread, bool single_step) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Punt if registers aren't available. E.g.,
-    // ZX-563 (registers aren't available in synthetic exceptions)
-    if (thread->arch.suspended_general_regs.gregs == nullptr)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    uint64_t* flags = nullptr;
-    switch (thread->arch.general_regs_source) {
-    case X86_GENERAL_REGS_SYSCALL:
-        flags = &thread->arch.suspended_general_regs.syscall->rflags;
-        break;
-    case X86_GENERAL_REGS_IFRAME:
-        flags = &thread->arch.suspended_general_regs.iframe->flags;
-        break;
-    default:
-        DEBUG_ASSERT(false);
-        return ZX_ERR_BAD_STATE;
-    }
-
-    if (single_step) {
-        *flags |= X86_FLAGS_TF;
-    } else {
-        *flags &= ~X86_FLAGS_TF;
-    }
-    return ZX_OK;
-}
-
-zx_status_t arch_get_fp_regs(struct thread* thread, zx_thread_state_fp_regs* out) {
-    // Don't leak any reserved fields.
-    memset(out, 0, sizeof(zx_thread_state_fp_regs));
-
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    uint32_t comp_size = 0;
-    x86_xsave_legacy_area* save = static_cast<x86_xsave_legacy_area*>(
-        x86_get_extended_register_state_component(thread->arch.extended_register_state,
-                                                  X86_XSAVE_STATE_INDEX_X87, false, &comp_size));
-    DEBUG_ASSERT(save); // Legacy getter should always succeed.
-
-    out->fcw = save->fcw;
-    out->fsw = save->fsw;
-    out->ftw = save->ftw;
-    out->fop = save->fop;
-    out->fip = save->fip;
-    out->fdp = save->fdp;
-    memcpy(&out->st[0], &save->st[0], sizeof(out->st));
-
-    return ZX_OK;
-}
-
-zx_status_t arch_set_fp_regs(struct thread* thread, const zx_thread_state_fp_regs* in) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    uint32_t comp_size = 0;
-    x86_xsave_legacy_area* save = static_cast<x86_xsave_legacy_area*>(
-        x86_get_extended_register_state_component(thread->arch.extended_register_state,
-                                                  X86_XSAVE_STATE_INDEX_X87, true, &comp_size));
-    DEBUG_ASSERT(save); // Legacy getter should always succeed.
-
-    save->fcw = in->fcw;
-    save->fsw = in->fsw;
-    save->ftw = in->ftw;
-    save->fop = in->fop;
-    save->fip = in->fip;
-    save->fdp = in->fdp;
-    memcpy(&save->st[0], &in->st[0], sizeof(in->st));
-
-    return ZX_OK;
-}
-
-zx_status_t arch_get_vector_regs(struct thread* thread, zx_thread_state_vector_regs* out) {
-    return x86_get_set_vector_regs(thread, out, RegAccess::kGet);
-}
-
-zx_status_t arch_set_vector_regs(struct thread* thread, const zx_thread_state_vector_regs* in) {
-    // The get_set function won't write in "kSet" mode so the const_cast is safe.
-    return x86_get_set_vector_regs(thread, const_cast<zx_thread_state_vector_regs*>(in),
-                                   RegAccess::kSet);
-}
-
-static void print_debug_state(const x86_debug_state_t* debug_state) {
-  printf("DR0=0x%lx, DR1=0x%lx, DR2=0x%lx, DR3=0x%lx, DR6=0x%lx, DR7=0x%lx\n",
-      debug_state->dr[0],
-      debug_state->dr[1],
-      debug_state->dr[2],
-      debug_state->dr[3],
-      debug_state->dr6,
-      debug_state->dr7);
-}
-
-zx_status_t arch_get_debug_regs(struct thread* thread, zx_thread_state_debug_regs* out) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // The kernel updates this per-thread data everytime a hw debug event occurs, meaning that
-    // these values will be always up to date. If the thread is not using hw debug capabilities,
-    // these will have the default zero values.
-    out->dr[0] = thread->arch.debug_state.dr[0];
-    out->dr[1] = thread->arch.debug_state.dr[1];
-    out->dr[2] = thread->arch.debug_state.dr[2];
-    out->dr[3] = thread->arch.debug_state.dr[3];
-    out->dr6 = thread->arch.debug_state.dr6;
-    out->dr7 = thread->arch.debug_state.dr7;
-
-    return ZX_OK;
-}
-
-zx_status_t arch_set_debug_regs(struct thread* thread, const zx_thread_state_debug_regs* in) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    // Replace the state of the thread with the given one. We now need to keep track of the debug
-    // state of this register across context switches.
-    x86_debug_state_t new_debug_state;
-    new_debug_state.dr[0] = in->dr[0];
-    new_debug_state.dr[1] = in->dr[1];
-    new_debug_state.dr[2] = in->dr[2];
-    new_debug_state.dr[3] = in->dr[3];
-    new_debug_state.dr6 = in->dr6;
-    new_debug_state.dr7 = in->dr7;
-
-    // Validate the new input. This will mask reserved bits to their stated values.
-    if (!x86_validate_debug_state(&new_debug_state))
-        return ZX_ERR_INVALID_ARGS;
-
-    // NOTE: This currently does a write-read round-trip to the CPU in order to ensure that
-    //       |thread->arch.debug_state| tracks the exact value as it is stored in the registers.
-    // TODO(ZX-3038): Ideally, we could do some querying at boot time about the format that the CPU
-    //                is storing reserved bits and we can create a mask we can apply to the input
-    //                values and avoid changing the state.
-
-    // Save the current debug state temporarily.
-    x86_debug_state_t current_debug_state;
-    x86_read_hw_debug_regs(&current_debug_state);
-
-    // Write and then read from the CPU to have real values tracked by the thread data.
-    // Mark the thread as now tracking the debug state.
-    x86_write_hw_debug_regs(&new_debug_state);
-    x86_read_hw_debug_regs(&thread->arch.debug_state);
-
-    thread->arch.track_debug_state = true;
-
-    // Restore the original debug state. Should always work as the input was already validated.
-    x86_write_hw_debug_regs(&current_debug_state);
-
-    return ZX_OK;
-}
-
-zx_status_t arch_get_x86_register_fs(struct thread* thread, uint64_t* out) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    *out = thread->arch.fs_base;
-    return ZX_OK;
-}
-
-zx_status_t arch_set_x86_register_fs(struct thread* thread, const uint64_t* in) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    thread->arch.fs_base = *in;
-    return ZX_OK;
-}
-
-zx_status_t arch_get_x86_register_gs(struct thread* thread, uint64_t* out) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    *out = thread->arch.gs_base;
-    return ZX_OK;
-}
-
-zx_status_t arch_set_x86_register_gs(struct thread* thread, const uint64_t* in) {
-    Guard<spin_lock_t, IrqSave> thread_lock_guard{ThreadLock::Get()};
-
-    thread->arch.gs_base = *in;
-    return ZX_OK;
-}
-
-// NOTE: While x86 supports up to 4 hw breakpoints/watchpoints, there is a catch:
-//       They are shared, so (breakpoints + watchpoints) <= HW_DEBUG_REGISTERS_COUNT.
-uint8_t arch_get_hw_breakpoint_count() {
-    return HW_DEBUG_REGISTERS_COUNT;
-}
-
-uint8_t arch_get_hw_watchpoint_count() {
-    return HW_DEBUG_REGISTERS_COUNT;
-}
diff --git a/kernel/arch/x86/descriptor.cpp b/kernel/arch/x86/descriptor.cpp
deleted file mode 100644
index f2b2bed..0000000
--- a/kernel/arch/x86/descriptor.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arch_ops.h>
-#include <arch/x86.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/idt.h>
-#include <arch/x86/interrupts.h>
-#include <arch/x86/mp.h>
-#include <assert.h>
-#include <bits.h>
-#include <err.h>
-#include <kernel/mp.h>
-#include <ktl/move.h>
-#include <string.h>
-#include <trace.h>
-#include <vm/fault.h>
-#include <vm/pmm.h>
-#include <vm/vm_aspace.h>
-#include <vm/vm_object_paged.h>
-#include <vm/vm_object_physical.h>
-#include <zircon/compiler.h>
-
-#define TSS_DESC_BUSY_BIT (1ull << 41)
-
-/* Temporary GDT defined in assembly is used during AP/BP setup process */
-extern uint8_t _temp_gdt[];
-extern uint8_t _temp_gdt_end[];
-
-/* We create a new GDT after initialization is done and switch everyone to it */
-static uintptr_t gdt = (uintptr_t)_temp_gdt;
-
-static void x86_tss_assign_ists(struct x86_percpu* percpu, tss_t* tss);
-
-struct task_desc {
-    uint64_t low;
-    uint64_t high;
-} __PACKED;
-
-void x86_initialize_percpu_tss(void) {
-    struct x86_percpu* percpu = x86_get_percpu();
-    uint cpu_num = percpu->cpu_num;
-    tss_t* tss = &percpu->default_tss;
-    memset(tss, 0, sizeof(*tss));
-
-    /* zeroed out TSS is okay for now */
-    set_global_desc_64(TSS_SELECTOR(cpu_num), (uintptr_t)tss, sizeof(*tss) - 1, 1, 0, 0, SEG_TYPE_TSS, 0, 0);
-
-    x86_tss_assign_ists(percpu, tss);
-
-    tss->iomap_base = offsetof(tss_64_t, tss_bitmap);
-    // Need to have an extra byte at the end of the bitmap because it will always potentially read two bytes
-    tss->tss_bitmap[IO_BITMAP_BYTES] = 0xff;
-
-    x86_ltr(TSS_SELECTOR(cpu_num));
-}
-
-static void x86_tss_assign_ists(struct x86_percpu* percpu, tss_t* tss) {
-    tss->ist1 = (uintptr_t)&percpu->interrupt_stacks[0] + PAGE_SIZE;
-    tss->ist2 = (uintptr_t)&percpu->interrupt_stacks[1] + PAGE_SIZE;
-    tss->ist3 = (uintptr_t)&percpu->interrupt_stacks[2] + PAGE_SIZE;
-}
-
-void x86_set_tss_sp(vaddr_t sp) {
-    tss_t* tss = &x86_get_percpu()->default_tss;
-    tss->rsp0 = sp;
-}
-
-void x86_clear_tss_busy(seg_sel_t sel) {
-    uint index = sel >> 3;
-    struct task_desc* desc = (struct task_desc*)(gdt + index * 8);
-    desc->low &= ~TSS_DESC_BUSY_BIT;
-}
-
-void set_global_desc_64(seg_sel_t sel, uint64_t base, uint32_t limit,
-                        uint8_t present, uint8_t ring, uint8_t sys,
-                        uint8_t type, uint8_t gran, uint8_t bits) {
-    // 64 bit descriptor structure
-    struct seg_desc_64 {
-        uint16_t limit_15_0;
-        uint16_t base_15_0;
-        uint8_t base_23_16;
-
-        uint8_t type : 4;
-        uint8_t s : 1;
-        uint8_t dpl : 2;
-        uint8_t p : 1;
-
-        uint8_t limit_19_16 : 4;
-        uint8_t avl : 1;
-        uint8_t reserved_0 : 1;
-        uint8_t d_b : 1;
-        uint8_t g : 1;
-
-        uint8_t base_31_24;
-
-        uint32_t base_63_32;
-        uint32_t reserved_sbz;
-    } __PACKED;
-
-    struct seg_desc_64 entry = {};
-
-    entry.limit_15_0 = limit & 0x0000ffff;
-    entry.limit_19_16 = (limit & 0x000f0000) >> 16;
-
-    entry.base_15_0 = base & 0x0000ffff;
-    entry.base_23_16 = (base & 0x00ff0000) >> 16;
-    entry.base_31_24 = (base & 0xff000000) >> 24;
-    entry.base_63_32 = (uint32_t)(base >> 32);
-
-    entry.type = type & 0x0f; // segment type
-    entry.p = present != 0;   // present
-    entry.dpl = ring & 0x03;  // descriptor privilege level
-    entry.g = gran != 0;      // granularity
-    entry.s = sys != 0;       // system / non-system
-    entry.d_b = bits != 0;    // 16 / 32 bit
-
-    // copy it into the appropriate entry
-    uint index = sel >> 3;
-
-    // for x86_64 index is still in units of 8 bytes into the gdt table
-    struct seg_desc_64* g = (struct seg_desc_64*)(gdt + index * 8);
-    *g = entry;
-}
-
-void gdt_setup() {
-    DEBUG_ASSERT(arch_curr_cpu_num() == 0);
-    DEBUG_ASSERT(mp_get_online_mask() == 1);
-    // Max GDT size is limited to 64K and we reserve the whole 64K area, but we map
-    // just enough pages to store GDT and leave the rest unmapped so all accesses
-    // beyond GDT last page are going to cause page fault.
-    // Why don't we just set a a proper limit value? That's because during VM exit
-    // on x86 architecture GDT limit is always set to 0xFFFF (see Intel SDM, Volume
-    // 3, 27.5.2 Loading Host Segment and Descriptor-Table Registers) and therefore
-    // requiring the hypervisor to restore GDT limit after VM exit using LGDT
-    // instruction which is a serializing instruction (see Intel SDM, Volume 3, 8.3
-    // Serializing Instructions).
-    uint32_t vmar_flags = VMAR_FLAG_CAN_MAP_SPECIFIC | VMAR_FLAG_CAN_MAP_READ | VMAR_FLAG_CAN_MAP_WRITE;
-    uint32_t mmu_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;
-
-    size_t gdt_real_size = _temp_gdt_end - _temp_gdt;
-    size_t gdt_size = 0x10000;
-
-    fbl::RefPtr<VmObject> vmo;
-    zx_status_t status = VmObjectPaged::Create(PMM_ALLOC_FLAG_ANY, /*options*/0u, gdt_real_size, &vmo);
-    ASSERT(status == ZX_OK);
-
-    fbl::RefPtr<VmAddressRegion> vmar;
-    status = VmAspace::kernel_aspace()->RootVmar()->CreateSubVmar(
-        0, gdt_size, PAGE_SIZE_SHIFT, vmar_flags, "gdt_vmar", &vmar);
-    ASSERT(status == ZX_OK);
-
-    fbl::RefPtr<VmMapping> mapping;
-    status = vmar->CreateVmMapping(
-        /*mapping_offset*/0u, gdt_real_size, PAGE_SIZE_SHIFT, VMAR_FLAG_SPECIFIC, ktl::move(vmo),
-        /*vmo_offset*/0u, mmu_flags, "gdt", &mapping);
-    ASSERT(status == ZX_OK);
-
-    status = mapping->MapRange(0, gdt_real_size, /*commit*/true);
-    ASSERT(status == ZX_OK);
-
-    memcpy((void*)mapping->base(), _temp_gdt, gdt_real_size);
-    gdt = mapping->base();
-    gdt_load(gdt_get());
-}
-
-uintptr_t gdt_get(void) {
-    return gdt;
-}
diff --git a/kernel/arch/x86/exceptions.S b/kernel/arch/x86/exceptions.S
deleted file mode 100644
index 2bb302a..0000000
--- a/kernel/arch/x86/exceptions.S
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2015 Intel Corporation
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/x86/descriptor.h>
-
-#define NUM_INT 256
-
-/*
- * Please note that the macro for generating interrupt routine stubs relies
- * on the macro execution counter \@ which is shared by all invocations across
- * this compilation unit. Be careful when adding additional macros to this
- * file. In particular:
- * 1) No macros can be executed before def_isr (so \@ starts at zero).
- * 2) def_isr cannot have any macros (so \@ increments by one for each
- *    def_isr invocation).
- */
-
-.text
-
-/* interrupt service routine stubs */
-_isr:
-.macro def_isr
-.pushsection .text
-FUNCTION_LABEL(_isr_\@)
-    .cfi_startproc simple
-    .cfi_signal_frame
-    /* Set CFA for an interrupt frame. */
-.if \@ == 8 || (\@ >= 10 && \@ <= 14) || \@ == 17
-    .cfi_def_cfa %rsp, (8 * 6)
-.else
-    .cfi_def_cfa %rsp, (8 * 5)
-.endif
-    .cfi_offset %rip, -(5 * 8)
-    /* Mark each reg as having the same value as from the "calling" frame.
-       This is the default state for callee-saved registers, but for completeness
-       sake we do this for all of them. */
-    ALL_CFI_SAME_VALUE
-    /* Clear the AC flag to prevent ring 0 from performing data accesses to
-     * ring 3 if SMAP is available.  If it was set, it will get restored by
-     * iretd.  DO NOT REMOVE THIS CLAC, code in idt.c assumes it is here.
-     * It MUST be the first instruction of this function. */
-    clac
-    /* We can't use push_value here: it is a macro invocation and using it
-     * will screw up tracking of \@ == isr number. Instead we inline the .cfi
-     * directives. */
-.if \@ == 8 || (\@ >= 10 && \@ <= 14) || \@ == 17
-    /* error code pushed by exception */
-    pushq $\@              /* interrupt number */
-    .cfi_adjust_cfa_offset 8
-    jmp interrupt_common
-.else
-    pushq $0               /* fill in error code in iframe */
-    .cfi_adjust_cfa_offset 8
-    pushq $\@              /* interrupt number */
-    .cfi_adjust_cfa_offset 8
-    jmp interrupt_common
-.endif
-END_FUNCTION(_isr_\@)
-.popsection
-.pushsection .rodata.isr
-.quad _isr_\@
-.popsection
-.endm
-
-.pushsection .rodata.isr
-/* build a table of isr entry points */
-.balign 8
-DATA(_isr_table)
-.popsection
-.rept NUM_INT
-def_isr
-.endr
-
-FUNCTION_LABEL(interrupt_common)
-    .cfi_startproc simple
-    .cfi_signal_frame
-    /* Set CFA for an interrupt frame. */
-    .cfi_def_cfa %rsp, 7 * 8 /* hw + _isr_* push this many values */
-    .cfi_offset %rip, -(5 * 8)
-    /* Mark each reg as having the same value as from the "calling" frame.
-       This is the default state for callee-saved registers, but for completeness
-       sake we do this for all of them. */
-    ALL_CFI_SAME_VALUE
-
-    /* Clear the direction flag.  Without this, uses of string
-       instructions, e.g. REP MOVS in memcpy() or inlined by the compiler,
-       can go wrong and copy in the wrong direction, since this code may
-       assume that the direction flag is unset. */
-    cld
-
-    /* Check to see if we came from user space by testing the PL of the
-     * CS register that was saved on the stack automatically. Check for != 0.
-     */
-    testb $3, 0x18(%rsp)
-    jz    1f
-
-    /* swap gs to kernel space */
-    swapgs
-
-1:
-    /* save general purpose registers */
-    push_reg %r15
-    push_reg %r14
-    push_reg %r13
-    push_reg %r12
-    push_reg %r11
-    push_reg %r10
-    push_reg %r9
-    push_reg %r8
-    push_reg %rax
-    push_reg %rcx
-    push_reg %rdx
-    push_reg %rbx
-    push_reg %rbp
-    push_reg %rsi
-    push_reg %rdi
-
-    movq %rsp, %rdi     /* pass the  iframe using rdi */
-
-    call x86_exception_handler
-
-/* A label to assist gdb's backtracing through kernel exceptions.
-   When gdb sees this as the return address it knows it can fetch
-   x86_iframe_t from $rsp. See scripts/zircon.elf-gdb.py. */
-interrupt_common_iframe_set_up_for_debugger:
-
-    /* restore general purpose registers */
-    pop_reg %rdi
-    pop_reg %rsi
-    pop_reg %rbp
-    pop_reg %rbx
-    pop_reg %rdx
-    pop_reg %rcx
-    pop_reg %rax
-    pop_reg %r8
-    pop_reg %r9
-    pop_reg %r10
-    pop_reg %r11
-    pop_reg %r12
-    pop_reg %r13
-    pop_reg %r14
-    pop_reg %r15
-
-    /* check if we're returning to user space as per before */
-    testb $3, 0x18(%rsp)
-    jz    1f
-
-    /* swap gs back to user space */
-    swapgs
-
-1:
-    /* drop vector number and error code*/
-    add_to_sp 16
-
-    iretq
-END_FUNCTION(interrupt_common)
-
-/* Call external interrupt handler manually without actually issuing interrupt.
- *
- * For external interrupts CPU doesn't store error code on stack so we use 0. We
- * additionally use CODE_64_SELECTOR as CS, 0 as SS, RFLAGS value and current
- * stack.
- */
-FUNCTION(x86_call_external_interrupt_handler)
-    /* save current RFLAGS value */
-    pushfq
-    popq %r10
-
-    /* save current RSP value */
-    movq %rsp, %r11
-
-    /* calculate exit address */
-    leaq .Lexit(%rip), %rax
-
-    /* prepare interrupt stack frame in the from interrupt_common expects to see */
-    sub_from_sp 0x38
-    movq %rdi, 0x00(%rsp)              // rdi holds vector number
-    movq $0, 0x08(%rsp)                // error code
-    movq %rax, 0x10(%rsp)              // RIP (return address)
-    movq $CODE_64_SELECTOR, 0x18(%rsp) // CS
-    movq %r10, 0x20(%rsp)              // RFLAGS
-    movq %r11, 0x28(%rsp)              // RSP
-    movq $0, 0x30(%rsp)                // SS
-
-    /* we can actually avoid this jump if we put this code above
-     * interrupt_common and just fall through, but benefits of doing this are
-     * not obvious so for now for the sake of clarity keep this jump
-     */
-    jmp    interrupt_common
-
-.Lexit:
-    ret
-END_FUNCTION(x86_call_external_interrupt_handler)
diff --git a/kernel/arch/x86/faults.cpp b/kernel/arch/x86/faults.cpp
deleted file mode 100644
index dca30b9..0000000
--- a/kernel/arch/x86/faults.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2015 Intel Corporation
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/exception.h>
-#include <arch/user_copy.h>
-#include <arch/x86.h>
-#include <arch/x86/apic.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/interrupts.h>
-#include <arch/x86/perf_mon.h>
-#include <arch/x86/registers.h>
-
-#include <debug.h>
-
-#include <kernel/interrupt.h>
-#include <kernel/thread.h>
-
-#include <lib/crashlog.h>
-
-#include <platform.h>
-#include <trace.h>
-#include <vm/fault.h>
-#include <vm/vm.h>
-
-#include <fbl/auto_call.h>
-
-#include <lib/counters.h>
-#include <lib/ktrace.h>
-
-#include <zircon/syscalls/exception.h>
-#include <zircon/types.h>
-
-// Returns whether the register state indicates that the CPU was executing
-// userland code.
-static bool is_from_user(const x86_iframe_t* frame) {
-    return SELECTOR_PL(frame->cs) != 0;
-}
-
-static void dump_fault_frame(x86_iframe_t* frame) {
-    dprintf(CRITICAL, " CS:  %#18" PRIx64 " RIP: %#18" PRIx64 " EFL: %#18" PRIx64 " CR2: %#18lx\n",
-            frame->cs, frame->ip, frame->flags, x86_get_cr2());
-    dprintf(CRITICAL, " RAX: %#18" PRIx64 " RBX: %#18" PRIx64 " RCX: %#18" PRIx64 " RDX: %#18" PRIx64 "\n",
-            frame->rax, frame->rbx, frame->rcx, frame->rdx);
-    dprintf(CRITICAL, " RSI: %#18" PRIx64 " RDI: %#18" PRIx64 " RBP: %#18" PRIx64 " RSP: %#18" PRIx64 "\n",
-            frame->rsi, frame->rdi, frame->rbp, frame->user_sp);
-    dprintf(CRITICAL, "  R8: %#18" PRIx64 "  R9: %#18" PRIx64 " R10: %#18" PRIx64 " R11: %#18" PRIx64 "\n",
-            frame->r8, frame->r9, frame->r10, frame->r11);
-    dprintf(CRITICAL, " R12: %#18" PRIx64 " R13: %#18" PRIx64 " R14: %#18" PRIx64 " R15: %#18" PRIx64 "\n",
-            frame->r12, frame->r13, frame->r14, frame->r15);
-    dprintf(CRITICAL, "errc: %#18" PRIx64 "\n",
-            frame->err_code);
-
-    // dump the bottom of the current stack
-    void* stack = frame;
-
-    if (frame->cs == CODE_64_SELECTOR) {
-        dprintf(CRITICAL, "bottom of kernel stack at %p:\n", stack);
-        hexdump(stack, 128);
-    }
-}
-
-KCOUNTER(exceptions_debug, "kernel.exceptions.debug");
-KCOUNTER(exceptions_nmi, "kernel.exceptions.nmi");
-KCOUNTER(exceptions_brkpt, "kernel.exceptions.breakpoint");
-KCOUNTER(exceptions_invop, "kernel.exceptions.inv_opcode");
-KCOUNTER(exceptions_dev_na, "kernel.exceptions.dev_na");
-KCOUNTER(exceptions_dfault, "kernel.exceptions.double_fault");
-KCOUNTER(exceptions_fpu, "kernel.exceptions.fpu");
-KCOUNTER(exceptions_simd, "kernel.exceptions.simd");
-KCOUNTER(exceptions_gpf, "kernel.exceptions.gpf");
-KCOUNTER(exceptions_page, "kernel.exceptions.page_fault");
-KCOUNTER(exceptions_apic_err, "kernel.exceptions.apic_error");
-KCOUNTER(exceptions_irq, "kernel.exceptions.irq");
-KCOUNTER(exceptions_unhandled, "kernel.exceptions.unhandled");
-KCOUNTER(exceptions_user, "kernel.exceptions.user");
-
-__NO_RETURN static void exception_die(x86_iframe_t* frame, const char* msg) {
-    platform_panic_start();
-
-    printf("vector %lu\n", (ulong)frame->vector);
-    dprintf(CRITICAL, "%s", msg);
-    dump_fault_frame(frame);
-    crashlog.iframe = frame;
-
-    // try to dump the user stack
-    if (is_user_address(frame->user_sp)) {
-        uint8_t buf[256];
-        if (arch_copy_from_user(buf, (void*)frame->user_sp, sizeof(buf)) == ZX_OK) {
-            printf("bottom of user stack at 0x%lx:\n", (vaddr_t)frame->user_sp);
-            hexdump_ex(buf, sizeof(buf), frame->user_sp);
-        }
-    }
-
-    platform_halt(HALT_ACTION_HALT, HALT_REASON_SW_PANIC);
-}
-
-static zx_status_t call_dispatch_user_exception(uint kind,
-                                                struct arch_exception_context* context,
-                                                x86_iframe_t* frame) {
-    thread_t* thread = get_current_thread();
-    x86_set_suspended_general_regs(&thread->arch, X86_GENERAL_REGS_IFRAME, frame);
-    zx_status_t status = dispatch_user_exception(kind, context);
-    x86_reset_suspended_general_regs(&thread->arch);
-    return status;
-}
-
-static bool try_dispatch_user_exception(x86_iframe_t* frame, uint kind) {
-    if (is_from_user(frame)) {
-        struct arch_exception_context context = {false, frame, 0};
-        thread_preempt_reenable_no_resched();
-        arch_set_blocking_disallowed(false);
-        arch_enable_ints();
-        zx_status_t erc = call_dispatch_user_exception(kind, &context, frame);
-        arch_disable_ints();
-        arch_set_blocking_disallowed(true);
-        thread_preempt_disable();
-        if (erc == ZX_OK)
-            return true;
-    }
-
-    return false;
-}
-
-static void x86_debug_handler(x86_iframe_t* frame) {
-    // We now need to keep track of the debug registers.
-    thread_t* thread = get_current_thread();
-
-    // DR6 is the status register that explains what exception happened (single step, hardware
-    // breakpoint, etc.).
-    // We only need to keep track of DR6 because the other state doesn't change and the only way
-    // to actually change the debug registers for a thread is through the thread_write_state
-    // syscall.
-    x86_read_debug_status(&thread->arch.debug_state);
-
-    // NOTE: a HW breakpoint exception can also represent a single step.
-    // TODO(ZX-3037): Is it worth separating this into two separate exceptions?
-    if (try_dispatch_user_exception(frame, ZX_EXCP_HW_BREAKPOINT))
-        return;
-
-    exception_die(frame, "unhandled hw breakpoint, halting\n");
-}
-
-static void x86_nmi_handler(x86_iframe_t* frame) {
-}
-
-static void x86_breakpoint_handler(x86_iframe_t* frame) {
-    if (try_dispatch_user_exception(frame, ZX_EXCP_SW_BREAKPOINT))
-        return;
-
-    exception_die(frame, "unhandled sw breakpoint, halting\n");
-}
-
-static void x86_gpf_handler(x86_iframe_t* frame) {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    // Check if we were doing a GPF test, e.g. to check if an MSR exists.
-    struct x86_percpu* percpu = x86_get_percpu();
-    if (unlikely(percpu->gpf_return_target)) {
-        ASSERT(!is_from_user(frame));
-
-        // Set up return to new address
-        frame->ip = percpu->gpf_return_target;
-        percpu->gpf_return_target = 0;
-        return;
-    }
-
-    if (try_dispatch_user_exception(frame, ZX_EXCP_GENERAL))
-        return;
-
-    exception_die(frame, "unhandled gpf, halting\n");
-}
-
-static void x86_invop_handler(x86_iframe_t* frame) {
-    if (try_dispatch_user_exception(frame, ZX_EXCP_UNDEFINED_INSTRUCTION))
-        return;
-
-    exception_die(frame, "invalid opcode, halting\n");
-}
-
-static void x86_df_handler(x86_iframe_t* frame) {
-    // Do not give the user exception handler the opportunity to handle double
-    // faults, since they indicate an unexpected system state and cannot be
-    // recovered from.
-    kcounter_add(exceptions_dfault, 1);
-    exception_die(frame, "double fault, halting\n");
-}
-
-static void x86_unhandled_exception(x86_iframe_t* frame) {
-    if (try_dispatch_user_exception(frame, ZX_EXCP_GENERAL))
-        return;
-
-    exception_die(frame, "unhandled exception, halting\n");
-}
-
-static void x86_dump_pfe(x86_iframe_t* frame, ulong cr2) {
-    uint64_t error_code = frame->err_code;
-
-    addr_t v_addr = cr2;
-    addr_t ssp = frame->user_ss & X86_8BYTE_MASK;
-    addr_t sp = frame->user_sp;
-    addr_t cs = frame->cs & X86_8BYTE_MASK;
-    addr_t ip = frame->ip;
-
-    dprintf(CRITICAL, "<PAGE FAULT> Instruction Pointer   = 0x%lx:0x%lx\n",
-            (ulong)cs,
-            (ulong)ip);
-    dprintf(CRITICAL, "<PAGE FAULT> Stack Pointer         = 0x%lx:0x%lx\n",
-            (ulong)ssp,
-            (ulong)sp);
-    dprintf(CRITICAL, "<PAGE FAULT> Fault Linear Address  = 0x%lx\n",
-            (ulong)v_addr);
-    dprintf(CRITICAL, "<PAGE FAULT> Error Code Value      = 0x%lx\n",
-            (ulong)error_code);
-    dprintf(CRITICAL, "<PAGE FAULT> Error Code Type       = %s %s %s%s, %s\n",
-            error_code & PFEX_U ? "user" : "supervisor",
-            error_code & PFEX_W ? "write" : "read",
-            error_code & PFEX_I ? "instruction" : "data",
-            error_code & PFEX_RSV ? " rsv" : "",
-            error_code & PFEX_P ? "protection violation" : "page not present");
-}
-
-__NO_RETURN static void x86_fatal_pfe_handler(x86_iframe_t* frame, ulong cr2) {
-    x86_dump_pfe(frame, cr2);
-
-    uint64_t error_code = frame->err_code;
-
-    dump_thread_during_panic(get_current_thread(), true);
-
-    if (error_code & PFEX_U) {
-        // User mode page fault
-        switch (error_code) {
-        case 4:
-        case 5:
-        case 6:
-        case 7:
-            exception_die(frame, "User Page Fault exception, halting\n");
-            break;
-        }
-    } else {
-        // Supervisor mode page fault
-        switch (error_code) {
-
-        case 0:
-        case 1:
-        case 2:
-        case 3:
-            exception_die(frame, "Supervisor Page Fault exception, halting\n");
-            break;
-        }
-    }
-
-    exception_die(frame, "unhandled page fault, halting\n");
-}
-
-static zx_status_t x86_pfe_handler(x86_iframe_t* frame) {
-    /* Handle a page fault exception */
-    uint64_t error_code = frame->err_code;
-    vaddr_t va = x86_get_cr2();
-
-    /* reenable interrupts */
-    thread_preempt_reenable_no_resched();
-    arch_set_blocking_disallowed(false);
-    arch_enable_ints();
-
-    /* make sure we put interrupts back as we exit */
-    auto ac = fbl::MakeAutoCall([]() {
-        arch_disable_ints();
-        arch_set_blocking_disallowed(true);
-        thread_preempt_disable();
-    });
-
-    /* check for flags we're not prepared to handle */
-    if (unlikely(error_code & ~(PFEX_I | PFEX_U | PFEX_W | PFEX_P))) {
-        printf("x86_pfe_handler: unhandled error code bits set, error code %#" PRIx64 "\n", error_code);
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-
-    /* check for a potential SMAP failure */
-    if (unlikely(
-            !(error_code & PFEX_U) &&
-            (error_code & PFEX_P) &&
-            x86_feature_test(X86_FEATURE_SMAP) &&
-            !(frame->flags & X86_FLAGS_AC) &&
-            is_user_address(va))) {
-        /* supervisor mode page-present access failure with the AC bit clear (SMAP enabled) */
-        printf("x86_pfe_handler: potential SMAP failure, supervisor access at address %#" PRIxPTR "\n", va);
-        return ZX_ERR_ACCESS_DENIED;
-    }
-
-    /* convert the PF error codes to page fault flags */
-    uint flags = 0;
-    flags |= (error_code & PFEX_W) ? VMM_PF_FLAG_WRITE : 0;
-    flags |= (error_code & PFEX_U) ? VMM_PF_FLAG_USER : 0;
-    flags |= (error_code & PFEX_I) ? VMM_PF_FLAG_INSTRUCTION : 0;
-    flags |= (error_code & PFEX_P) ? 0 : VMM_PF_FLAG_NOT_PRESENT;
-
-    /* call the high level page fault handler */
-    zx_status_t pf_err = vmm_page_fault_handler(va, flags);
-    if (likely(pf_err == ZX_OK))
-        return ZX_OK;
-
-    /* if the high level page fault handler can't deal with it,
-     * resort to trying to recover first, before bailing */
-
-    /* Check if a resume address is specified, and just return to it if so */
-    thread_t* current_thread = get_current_thread();
-    if (unlikely(current_thread->arch.page_fault_resume)) {
-        frame->ip = (uintptr_t)current_thread->arch.page_fault_resume;
-        return ZX_OK;
-    }
-
-    /* let high level code deal with this */
-    if (is_from_user(frame)) {
-        kcounter_add(exceptions_user, 1);
-        struct arch_exception_context context = {true, frame, va};
-        return call_dispatch_user_exception(ZX_EXCP_FATAL_PAGE_FAULT,
-                                            &context, frame);
-    }
-
-    /* fall through to fatal path */
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
-static void x86_iframe_process_pending_signals(x86_iframe_t* frame) {
-    thread_t* thread = get_current_thread();
-    if (unlikely(thread_is_signaled(thread))) {
-        x86_set_suspended_general_regs(&thread->arch, X86_GENERAL_REGS_IFRAME, frame);
-        thread_process_pending_signals();
-        x86_reset_suspended_general_regs(&thread->arch);
-    }
-}
-
-static void handle_exception_types(x86_iframe_t* frame) {
-    switch (frame->vector) {
-    case X86_INT_DEBUG:
-        kcounter_add(exceptions_debug, 1);
-        x86_debug_handler(frame);
-        break;
-    case X86_INT_NMI:
-        kcounter_add(exceptions_nmi, 1);
-        x86_nmi_handler(frame);
-        break;
-    case X86_INT_BREAKPOINT:
-        kcounter_add(exceptions_brkpt, 1);
-        x86_breakpoint_handler(frame);
-        break;
-
-    case X86_INT_INVALID_OP:
-        kcounter_add(exceptions_invop, 1);
-        x86_invop_handler(frame);
-        break;
-
-    case X86_INT_DEVICE_NA:
-        kcounter_add(exceptions_dev_na, 1);
-        exception_die(frame, "device na fault\n");
-        break;
-
-    case X86_INT_DOUBLE_FAULT:
-        x86_df_handler(frame);
-        break;
-    case X86_INT_FPU_FP_ERROR:
-        kcounter_add(exceptions_fpu, 1);
-        x86_unhandled_exception(frame);
-        break;
-    case X86_INT_SIMD_FP_ERROR:
-        kcounter_add(exceptions_simd, 1);
-        x86_unhandled_exception(frame);
-        break;
-    case X86_INT_GP_FAULT:
-        kcounter_add(exceptions_gpf, 1);
-        x86_gpf_handler(frame);
-        break;
-
-    case X86_INT_PAGE_FAULT:
-        kcounter_add(exceptions_page, 1);
-        CPU_STATS_INC(page_faults);
-        if (x86_pfe_handler(frame) != ZX_OK)
-            x86_fatal_pfe_handler(frame, x86_get_cr2());
-        break;
-
-    /* ignore spurious APIC irqs */
-    case X86_INT_APIC_SPURIOUS:
-        break;
-    case X86_INT_APIC_ERROR: {
-        kcounter_add(exceptions_apic_err, 1);
-        apic_error_interrupt_handler();
-        apic_issue_eoi();
-        break;
-    }
-    case X86_INT_APIC_TIMER: {
-        apic_timer_interrupt_handler();
-        apic_issue_eoi();
-        break;
-    }
-    case X86_INT_IPI_GENERIC: {
-        mp_mbx_generic_irq(nullptr);
-        apic_issue_eoi();
-        break;
-    }
-    case X86_INT_IPI_RESCHEDULE: {
-        mp_mbx_reschedule_irq(nullptr);
-        apic_issue_eoi();
-        break;
-    }
-    case X86_INT_IPI_INTERRUPT: {
-        mp_mbx_interrupt_irq(nullptr);
-        apic_issue_eoi();
-        break;
-    }
-    case X86_INT_IPI_HALT: {
-        x86_ipi_halt_handler(nullptr);
-        /* no return */
-        break;
-    }
-    case X86_INT_APIC_PMI: {
-        apic_pmi_interrupt_handler(frame);
-        // Note: apic_pmi_interrupt_handler calls apic_issue_eoi().
-        break;
-    }
-    /* pass all other non-Intel defined irq vectors to the platform */
-    case X86_INT_PLATFORM_BASE ... X86_INT_PLATFORM_MAX: {
-        kcounter_add(exceptions_irq, 1);
-        platform_irq(frame);
-        break;
-    }
-
-    /* Integer division-by-zero */
-    case X86_INT_DIVIDE_0:
-    /* Overflow for INTO instruction (should be x86-32-only) */
-    case X86_INT_OVERFLOW:
-    /* Bound range exceeded for BOUND instruction (should be x86-32-only) */
-    case X86_INT_BOUND_RANGE:
-    /* Loading segment with "not present" bit set */
-    case X86_INT_SEGMENT_NOT_PRESENT:
-    /* Stack segment fault (should be x86-32-only) */
-    case X86_INT_STACK_FAULT:
-    /* Misaligned memory access when AC=1 in flags */
-    case X86_INT_ALIGNMENT_CHECK:
-        kcounter_add(exceptions_unhandled, 1);
-        x86_unhandled_exception(frame);
-        break;
-
-    default:
-        exception_die(frame, "unhandled exception type, halting\n");
-        break;
-    }
-}
-
-/* top level x86 exception handler for most exceptions and irqs */
-void x86_exception_handler(x86_iframe_t* frame) {
-    // are we recursing?
-    if (unlikely(arch_blocking_disallowed()) && frame->vector != X86_INT_NMI) {
-        exception_die(frame, "recursion in interrupt handler\n");
-    }
-
-    int_handler_saved_state_t state;
-    int_handler_start(&state);
-
-    // did we come from user or kernel space?
-    bool from_user = is_from_user(frame);
-
-    // deliver the interrupt
-    ktrace_tiny(TAG_IRQ_ENTER, ((uint32_t)frame->vector << 8) | arch_curr_cpu_num());
-
-    handle_exception_types(frame);
-
-    bool do_preempt = int_handler_finish(&state);
-
-    /* if we came from user space, check to see if we have any signals to handle */
-    if (unlikely(from_user)) {
-        /* in the case of receiving a kill signal, this function may not return,
-         * but the scheduler would have been invoked so it's fine.
-         */
-        x86_iframe_process_pending_signals(frame);
-    }
-
-    if (do_preempt)
-        thread_preempt();
-
-    ktrace_tiny(TAG_IRQ_EXIT, ((uint)frame->vector << 8) | arch_curr_cpu_num());
-
-    DEBUG_ASSERT_MSG(arch_ints_disabled(),
-                     "ints disabled on way out of exception, vector %" PRIu64 " IP %#" PRIx64 "\n",
-                     frame->vector, frame->ip);
-}
-
-void x86_syscall_process_pending_signals(x86_syscall_general_regs_t* gregs) {
-    thread_t* thread = get_current_thread();
-    x86_set_suspended_general_regs(&thread->arch, X86_GENERAL_REGS_SYSCALL, gregs);
-    thread_process_pending_signals();
-    x86_reset_suspended_general_regs(&thread->arch);
-}
-
-void arch_dump_exception_context(const arch_exception_context_t* context) {
-    if (context->is_page_fault) {
-        x86_dump_pfe(context->frame, context->cr2);
-    }
-
-    dump_fault_frame(context->frame);
-
-    // try to dump the user stack
-    if (context->frame->cs != CODE_64_SELECTOR && is_user_address(context->frame->user_sp)) {
-        uint8_t buf[256];
-        if (arch_copy_from_user(buf, (void*)context->frame->user_sp, sizeof(buf)) == ZX_OK) {
-            printf("bottom of user stack at 0x%lx:\n", (vaddr_t)context->frame->user_sp);
-            hexdump_ex(buf, sizeof(buf), context->frame->user_sp);
-        }
-    }
-}
-
-void arch_fill_in_exception_context(const arch_exception_context_t* arch_context,
-                                    zx_exception_report_t* report) {
-    zx_exception_context_t* zx_context = &report->context;
-
-    zx_context->arch.u.x86_64.vector = arch_context->frame->vector;
-    zx_context->arch.u.x86_64.err_code = arch_context->frame->err_code;
-    zx_context->arch.u.x86_64.cr2 = arch_context->cr2;
-}
-
-zx_status_t arch_dispatch_user_policy_exception(void) {
-    x86_iframe_t frame = {};
-    arch_exception_context_t context = {};
-    context.frame = &frame;
-    return dispatch_user_exception(ZX_EXCP_POLICY_ERROR, &context);
-}
diff --git a/kernel/arch/x86/feature.cpp b/kernel/arch/x86/feature.cpp
deleted file mode 100644
index 71eec8a..0000000
--- a/kernel/arch/x86/feature.cpp
+++ /dev/null
@@ -1,635 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86/feature.h>
-
-#include <assert.h>
-#include <bits.h>
-#include <stdint.h>
-#include <string.h>
-#include <trace.h>
-
-#include <arch/ops.h>
-
-#include <fbl/algorithm.h>
-
-#define LOCAL_TRACE 0
-
-struct cpuid_leaf _cpuid[MAX_SUPPORTED_CPUID + 1];
-struct cpuid_leaf _cpuid_hyp[MAX_SUPPORTED_CPUID_HYP - X86_CPUID_HYP_BASE + 1];
-struct cpuid_leaf _cpuid_ext[MAX_SUPPORTED_CPUID_EXT - X86_CPUID_EXT_BASE + 1];
-uint32_t max_cpuid = 0;
-uint32_t max_hyp_cpuid = 0;
-uint32_t max_ext_cpuid = 0;
-
-enum x86_vendor_list x86_vendor;
-enum x86_microarch_list x86_microarch;
-const x86_microarch_config_t* x86_microarch_config;
-
-static struct x86_model_info model_info;
-
-bool g_x86_feature_fsgsbase;
-
-enum x86_hypervisor_list x86_hypervisor;
-
-static int initialized = 0;
-
-static enum x86_microarch_list get_microarch(struct x86_model_info* info);
-static void select_microarch_config(void);
-
-static enum x86_hypervisor_list get_hypervisor();
-
-void x86_feature_init(void) {
-    if (atomic_swap(&initialized, 1)) {
-        return;
-    }
-    /* test for cpuid count */
-    cpuid(0, &_cpuid[0].a, &_cpuid[0].b, &_cpuid[0].c, &_cpuid[0].d);
-
-    max_cpuid = _cpuid[0].a;
-    if (max_cpuid > MAX_SUPPORTED_CPUID)
-        max_cpuid = MAX_SUPPORTED_CPUID;
-
-    LTRACEF("max cpuid 0x%x\n", max_cpuid);
-
-    /* figure out the vendor */
-    union {
-        uint32_t vendor_id[3];
-        char vendor_string[12];
-    } vu;
-    vu.vendor_id[0] = _cpuid[0].b;
-    vu.vendor_id[1] = _cpuid[0].d;
-    vu.vendor_id[2] = _cpuid[0].c;
-    if (!memcmp(vu.vendor_string, "GenuineIntel", sizeof(vu.vendor_string))) {
-        x86_vendor = X86_VENDOR_INTEL;
-    } else if (!memcmp(vu.vendor_string, "AuthenticAMD", sizeof(vu.vendor_string))) {
-        x86_vendor = X86_VENDOR_AMD;
-    } else {
-        x86_vendor = X86_VENDOR_UNKNOWN;
-    }
-
-    /* read in the base cpuids */
-    for (uint32_t i = 1; i <= max_cpuid; i++) {
-        cpuid_c(i, 0, &_cpuid[i].a, &_cpuid[i].b, &_cpuid[i].c, &_cpuid[i].d);
-    }
-
-    /* test for extended cpuid count */
-    cpuid(X86_CPUID_EXT_BASE, &_cpuid_ext[0].a, &_cpuid_ext[0].b, &_cpuid_ext[0].c,
-          &_cpuid_ext[0].d);
-
-    max_ext_cpuid = _cpuid_ext[0].a;
-    LTRACEF("max extended cpuid 0x%x\n", max_ext_cpuid);
-    if (max_ext_cpuid > MAX_SUPPORTED_CPUID_EXT)
-        max_ext_cpuid = MAX_SUPPORTED_CPUID_EXT;
-
-    /* read in the extended cpuids */
-    for (uint32_t i = X86_CPUID_EXT_BASE + 1; i - 1 < max_ext_cpuid; i++) {
-        uint32_t index = i - X86_CPUID_EXT_BASE;
-        cpuid_c(i, 0, &_cpuid_ext[index].a, &_cpuid_ext[index].b, &_cpuid_ext[index].c,
-                &_cpuid_ext[index].d);
-    }
-
-    /* read in the hypervisor cpuids. the maximum leaf is reported at X86_CPUID_HYP_BASE. */
-    cpuid(X86_CPUID_HYP_VENDOR, &_cpuid_ext[0].a, &_cpuid_ext[0].b, &_cpuid_ext[0].c,
-          &_cpuid_ext[0].d);
-    max_hyp_cpuid = _cpuid_ext[0].a;
-    if (max_hyp_cpuid > MAX_SUPPORTED_CPUID_HYP)
-      max_hyp_cpuid = MAX_SUPPORTED_CPUID_HYP;
-    for (uint32_t i = X86_CPUID_HYP_BASE; i <= max_hyp_cpuid; i++) {
-        uint32_t index = i - X86_CPUID_HYP_BASE;
-        cpuid(i, &_cpuid_hyp[index].a, &_cpuid_hyp[index].b, &_cpuid_hyp[index].c,
-              &_cpuid_hyp[index].d);
-    }
-
-    /* populate the model info */
-    const struct cpuid_leaf* leaf = x86_get_cpuid_leaf(X86_CPUID_MODEL_FEATURES);
-    if (leaf) {
-        model_info.processor_type = (uint8_t)BITS_SHIFT(leaf->a, 13, 12);
-        model_info.family = (uint8_t)BITS_SHIFT(leaf->a, 11, 8);
-        model_info.model = (uint8_t)BITS_SHIFT(leaf->a, 7, 4);
-        model_info.stepping = (uint8_t)BITS_SHIFT(leaf->a, 3, 0);
-        model_info.display_family = model_info.family;
-        model_info.display_model = model_info.model;
-
-        if (model_info.family == 0xf) {
-            model_info.display_family += BITS_SHIFT(leaf->a, 27, 20);
-        }
-
-        if (model_info.family == 0xf || model_info.family == 0x6) {
-            model_info.display_model += BITS_SHIFT(leaf->a, 19, 16) << 4;
-        }
-
-        x86_microarch = get_microarch(&model_info);
-    }
-    select_microarch_config();
-
-    g_x86_feature_fsgsbase = x86_feature_test(X86_FEATURE_FSGSBASE);
-
-    x86_hypervisor = get_hypervisor();
-}
-
-static enum x86_microarch_list get_microarch(struct x86_model_info* info) {
-    if (x86_vendor == X86_VENDOR_INTEL && info->family == 0x6) {
-        switch (info->display_model) {
-        case 0x1a: /* Nehalem */
-        case 0x1e: /* Nehalem */
-        case 0x1f: /* Nehalem */
-        case 0x2e: /* Nehalem */
-            return X86_MICROARCH_INTEL_NEHALEM;
-        case 0x25: /* Westmere */
-        case 0x2c: /* Westmere */
-        case 0x2f: /* Westmere */
-            return X86_MICROARCH_INTEL_WESTMERE;
-        case 0x2a: /* Sandy Bridge */
-        case 0x2d: /* Sandy Bridge EP */
-            return X86_MICROARCH_INTEL_SANDY_BRIDGE;
-        case 0x3a: /* Ivy Bridge */
-        case 0x3e: /* Ivy Bridge EP */
-            return X86_MICROARCH_INTEL_IVY_BRIDGE;
-        case 0x3c: /* Haswell DT */
-        case 0x3f: /* Haswell MB */
-        case 0x45: /* Haswell ULT */
-        case 0x46: /* Haswell ULX */
-            return X86_MICROARCH_INTEL_HASWELL;
-        case 0x3d: /* Broadwell */
-        case 0x47: /* Broadwell H */
-        case 0x56: /* Broadwell EP */
-        case 0x4f: /* Broadwell EX */
-            return X86_MICROARCH_INTEL_BROADWELL;
-        case 0x4e: /* Skylake Y/U */
-        case 0x5e: /* Skylake H/S */
-        case 0x55: /* Skylake E */
-            return X86_MICROARCH_INTEL_SKYLAKE;
-        case 0x8e: /* Kabylake Y/U */
-        case 0x9e: /* Kabylake H/S */
-            return X86_MICROARCH_INTEL_KABYLAKE;
-        case 0x4d: /* Silvermont */
-            return X86_MICROARCH_INTEL_SILVERMONT;
-        }
-    } else if (x86_vendor == X86_VENDOR_AMD && info->family == 0xf) {
-        switch (info->display_family) { // zen
-        case 0x15:                      /* Bulldozer */
-            return X86_MICROARCH_AMD_BULLDOZER;
-        case 0x16: /* Jaguar */
-            return X86_MICROARCH_AMD_JAGUAR;
-        case 0x17: /* Zen */
-            return X86_MICROARCH_AMD_ZEN;
-        }
-    }
-    return X86_MICROARCH_UNKNOWN;
-}
-
-static enum x86_hypervisor_list get_hypervisor() {
-    if (!x86_feature_test(X86_FEATURE_HYPERVISOR)) {
-        return X86_HYPERVISOR_UNKNOWN;
-    }
-    uint32_t a, b, c, d;
-    cpuid(X86_CPUID_HYP_VENDOR, &a, &b, &c, &d);
-    union {
-        uint32_t vendor_id[3];
-        char vendor_string[12];
-    } vu;
-    vu.vendor_id[0] = b;
-    vu.vendor_id[1] = c;
-    vu.vendor_id[2] = d;
-    if (a >= X86_CPUID_KVM_FEATURES &&
-        !memcmp(vu.vendor_string, "KVMKVMKVM\0\0\0", sizeof(vu.vendor_string))) {
-        return X86_HYPERVISOR_KVM;
-    } else {
-        return X86_HYPERVISOR_UNKNOWN;
-    }
-}
-
-bool x86_get_cpuid_subleaf(
-    enum x86_cpuid_leaf_num num, uint32_t subleaf, struct cpuid_leaf* leaf) {
-    if (num < X86_CPUID_EXT_BASE) {
-        if (num > max_cpuid)
-            return false;
-    } else if (num > max_ext_cpuid) {
-        return false;
-    }
-
-    cpuid_c((uint32_t)num, subleaf, &leaf->a, &leaf->b, &leaf->c, &leaf->d);
-    return true;
-}
-
-bool x86_topology_enumerate(uint8_t level, struct x86_topology_level* info) {
-    DEBUG_ASSERT(info);
-
-    uint32_t eax, ebx, ecx, edx;
-    cpuid_c(X86_CPUID_TOPOLOGY, level, &eax, &ebx, &ecx, &edx);
-
-    uint8_t type = (ecx >> 8) & 0xff;
-    if (type == X86_TOPOLOGY_INVALID) {
-        return false;
-    }
-
-    info->right_shift = eax & 0x1f;
-    info->type = type;
-    return true;
-}
-
-const struct x86_model_info* x86_get_model(void) {
-    return &model_info;
-}
-
-void x86_feature_debug(void) {
-    const struct {
-        struct x86_cpuid_bit bit;
-        const char* name;
-    } features[] = {
-        {X86_FEATURE_FPU, "fpu"},
-        {X86_FEATURE_SSE, "sse"},
-        {X86_FEATURE_SSE2, "sse2"},
-        {X86_FEATURE_SSE3, "sse3"},
-        {X86_FEATURE_SSSE3, "ssse3"},
-        {X86_FEATURE_SSE4_1, "sse4.1"},
-        {X86_FEATURE_SSE4_2, "sse4.2"},
-        {X86_FEATURE_MMX, "mmx"},
-        {X86_FEATURE_AVX, "avx"},
-        {X86_FEATURE_AVX2, "avx2"},
-        {X86_FEATURE_FXSR, "fxsr"},
-        {X86_FEATURE_PCID, "pcid"},
-        {X86_FEATURE_XSAVE, "xsave"},
-        {X86_FEATURE_MON, "mon"},
-        {X86_FEATURE_AESNI, "aesni"},
-        {X86_FEATURE_CLFLUSH, "clflush"},
-        {X86_FEATURE_CLFLUSHOPT, "clflushopt"},
-        {X86_FEATURE_CLWB, "clwb"},
-        {X86_FEATURE_FSGSBASE, "fsgsbase"},
-        {X86_FEATURE_TSC_ADJUST, "tsc_adj"},
-        {X86_FEATURE_SMEP, "smep"},
-        {X86_FEATURE_SMAP, "smap"},
-        {X86_FEATURE_ERMS, "erms"},
-        {X86_FEATURE_RDRAND, "rdrand"},
-        {X86_FEATURE_RDSEED, "rdseed"},
-        {X86_FEATURE_UMIP, "umip"},
-        {X86_FEATURE_PKU, "pku"},
-        {X86_FEATURE_SYSCALL, "syscall"},
-        {X86_FEATURE_NX, "nx"},
-        {X86_FEATURE_HUGE_PAGE, "huge"},
-        {X86_FEATURE_RDTSCP, "rdtscp"},
-        {X86_FEATURE_INVAR_TSC, "invar_tsc"},
-        {X86_FEATURE_TSC_DEADLINE, "tsc_deadline"},
-        {X86_FEATURE_X2APIC, "x2apic"},
-        {X86_FEATURE_VMX, "vmx"},
-        {X86_FEATURE_HYPERVISOR, "hypervisor"},
-        {X86_FEATURE_PT, "pt"},
-        {X86_FEATURE_HWP, "hwp"},
-    };
-
-    const char* vendor_string = nullptr;
-    switch (x86_vendor) {
-    case X86_VENDOR_UNKNOWN:
-        vendor_string = "unknown";
-        break;
-    case X86_VENDOR_INTEL:
-        vendor_string = "Intel";
-        break;
-    case X86_VENDOR_AMD:
-        vendor_string = "AMD";
-        break;
-    }
-    printf("Vendor: %s\n", vendor_string);
-
-    const char* microarch_string = nullptr;
-    switch (x86_microarch) {
-    case X86_MICROARCH_UNKNOWN:
-        microarch_string = "unknown";
-        break;
-    case X86_MICROARCH_INTEL_NEHALEM:
-        microarch_string = "Nehalem";
-        break;
-    case X86_MICROARCH_INTEL_WESTMERE:
-        microarch_string = "Westmere";
-        break;
-    case X86_MICROARCH_INTEL_SANDY_BRIDGE:
-        microarch_string = "Sandy Bridge";
-        break;
-    case X86_MICROARCH_INTEL_IVY_BRIDGE:
-        microarch_string = "Ivy Bridge";
-        break;
-    case X86_MICROARCH_INTEL_BROADWELL:
-        microarch_string = "Broadwell";
-        break;
-    case X86_MICROARCH_INTEL_HASWELL:
-        microarch_string = "Haswell";
-        break;
-    case X86_MICROARCH_INTEL_SKYLAKE:
-        microarch_string = "Skylake";
-        break;
-    case X86_MICROARCH_INTEL_KABYLAKE:
-        microarch_string = "Kaby Lake";
-        break;
-    case X86_MICROARCH_INTEL_SILVERMONT:
-        microarch_string = "Silvermont";
-        break;
-    case X86_MICROARCH_AMD_BULLDOZER:
-        microarch_string = "Bulldozer";
-        break;
-    case X86_MICROARCH_AMD_JAGUAR:
-        microarch_string = "Jaguar";
-        break;
-    case X86_MICROARCH_AMD_ZEN:
-        microarch_string = "Zen";
-        break;
-    }
-    printf("Microarch: %s\n", microarch_string);
-    printf("F/M/S: %x/%x/%x\n", model_info.display_family, model_info.display_model,
-           model_info.stepping);
-
-    char brand_string[50];
-    memset(brand_string, 0, sizeof(brand_string));
-    const struct cpuid_leaf* leaf;
-    uint32_t leaf_num = X86_CPUID_BRAND;
-    for (int i = 0; i < 3; i++) {
-        leaf = x86_get_cpuid_leaf((enum x86_cpuid_leaf_num)(leaf_num + i));
-        if (!leaf) {
-            break;
-        }
-        memcpy(brand_string + (i * 16), &leaf->a, sizeof(uint32_t));
-        memcpy(brand_string + (i * 16) + 4, &leaf->b, sizeof(uint32_t));
-        memcpy(brand_string + (i * 16) + 8, &leaf->c, sizeof(uint32_t));
-        memcpy(brand_string + (i * 16) + 12, &leaf->d, sizeof(uint32_t));
-    }
-    printf("Brand: %s\n", brand_string);
-
-    printf("Features: ");
-    uint col = 0;
-    for (uint i = 0; i < fbl::count_of(features); ++i) {
-        if (x86_feature_test(features[i].bit))
-            col += printf("%s ", features[i].name);
-        if (col >= 80) {
-            printf("\n");
-            col = 0;
-        }
-    }
-    if (col > 0)
-        printf("\n");
-}
-
-static uint64_t default_apic_freq() {
-    // The APIC frequency is the core crystal clock frequency if it is
-    // enumerated in the CPUID leaf 0x15, or the processor's bus clock
-    // frequency.
-
-    const struct cpuid_leaf* tsc_leaf = x86_get_cpuid_leaf(X86_CPUID_TSC);
-    if (tsc_leaf && tsc_leaf->c != 0) {
-        return tsc_leaf->c;
-    }
-    return 0;
-}
-
-static uint64_t kbl_apic_freq() {
-    uint64_t v = default_apic_freq();
-    if (v != 0) {
-        return v;
-    }
-    return 24ul * 1000 * 1000;
-}
-
-static uint64_t bdw_apic_freq() {
-    uint64_t v = default_apic_freq();
-    if (v != 0) {
-        return v;
-    }
-    uint64_t platform_info;
-    const uint32_t msr_platform_info = 0xce;
-    if (read_msr_safe(msr_platform_info, &platform_info) == ZX_OK) {
-        uint64_t bus_freq_mult = (platform_info >> 8) & 0xf;
-        return bus_freq_mult * 100 * 1000 * 1000;
-    }
-    return 0;
-}
-
-static uint64_t bulldozer_apic_freq() {
-    uint64_t v = default_apic_freq();
-    if (v != 0) {
-        return v;
-    }
-
-    // 15h-17h BKDGs mention the APIC timer rate is 2xCLKIN,
-    // which experimentally appears to be 100Mhz always
-    return 100ul * 1000 * 1000;
-}
-
-static uint64_t unknown_freq() {
-    return 0;
-}
-
-static uint64_t intel_tsc_freq() {
-    const uint64_t core_crystal_clock_freq = x86_get_microarch_config()->get_apic_freq();
-
-    // If this leaf is present, then 18.18.3 (Determining the Processor Base
-    // Frequency) documents this as the nominal TSC frequency.
-    const struct cpuid_leaf* tsc_leaf = x86_get_cpuid_leaf(X86_CPUID_TSC);
-    if (tsc_leaf && tsc_leaf->a) {
-        return (core_crystal_clock_freq * tsc_leaf->b) / tsc_leaf->a;
-    }
-    return 0;
-}
-
-static uint64_t amd_compute_p_state_clock(uint64_t p_state_msr) {
-    // is it valid?
-    if (!BIT(p_state_msr, 63))
-        return 0;
-
-    // different AMD microarchitectures use slightly different formulas to compute
-    // the effective clock rate of a P state
-    uint64_t clock = 0;
-    switch (x86_microarch) {
-    case X86_MICROARCH_AMD_BULLDOZER:
-    case X86_MICROARCH_AMD_JAGUAR: {
-        uint64_t did = BITS_SHIFT(p_state_msr, 8, 6);
-        uint64_t fid = BITS(p_state_msr, 5, 0);
-
-        clock = (100 * (fid + 0x10) / (1 << did)) * 1000 * 1000;
-        break;
-    }
-    case X86_MICROARCH_AMD_ZEN: {
-        uint64_t fid = BITS(p_state_msr, 7, 0);
-
-        clock = (fid * 25) * 1000 * 1000;
-        break;
-    }
-    default:
-        break;
-    }
-
-    return clock;
-}
-
-static uint64_t zen_tsc_freq() {
-    const uint32_t p0_state_msr = 0xc0010064; // base P-state MSR
-    // According to the Family 17h PPR, the first P-state MSR is indeed
-    // P0 state and appears to be experimentally so
-    uint64_t p0_state;
-    if (read_msr_safe(p0_state_msr, &p0_state) != ZX_OK)
-        return 0;
-
-    return amd_compute_p_state_clock(p0_state);
-}
-
-static void unknown_reboot_system(void) {
-    return;
-}
-
-static void hsw_reboot_system(void) {
-    // 100-Series Chipset Reset Control Register: CPU + SYS Reset
-    outp(0xcf9, 0x06);
-}
-
-// Intel microarches
-static const x86_microarch_config_t kbl_config{
-    .get_apic_freq = kbl_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = hsw_reboot_system,
-    .disable_c1e = true,
-};
-static const x86_microarch_config_t skl_config{
-    .get_apic_freq = kbl_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = hsw_reboot_system,
-    .disable_c1e = true,
-};
-static const x86_microarch_config_t bdw_config{
-    .get_apic_freq = bdw_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = hsw_reboot_system,
-    .disable_c1e = true,
-};
-static const x86_microarch_config_t hsw_config{
-    .get_apic_freq = bdw_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = hsw_reboot_system,
-    .disable_c1e = true,
-};
-static const x86_microarch_config_t ivb_config{
-    .get_apic_freq = bdw_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = true,
-};
-static const x86_microarch_config_t snb_config{
-    .get_apic_freq = bdw_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = true,
-};
-static const x86_microarch_config_t westmere_config{
-    .get_apic_freq = default_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = true,
-};
-static const x86_microarch_config_t nehalem_config{
-    .get_apic_freq = default_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = true,
-};
-static const x86_microarch_config_t smt_config{
-    .get_apic_freq = default_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = false,
-};
-static const x86_microarch_config_t intel_default_config{
-    .get_apic_freq = default_apic_freq,
-    .get_tsc_freq = intel_tsc_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = false,
-};
-
-// AMD microarches
-static const x86_microarch_config_t zen_config{
-    .get_apic_freq = bulldozer_apic_freq,
-    .get_tsc_freq = zen_tsc_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = false,
-};
-static const x86_microarch_config_t jaguar_config{
-    .get_apic_freq = bulldozer_apic_freq,
-    .get_tsc_freq = unknown_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = false,
-};
-static const x86_microarch_config_t bulldozer_config{
-    .get_apic_freq = bulldozer_apic_freq,
-    .get_tsc_freq = unknown_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = false,
-};
-static const x86_microarch_config_t amd_default_config{
-    .get_apic_freq = default_apic_freq,
-    .get_tsc_freq = unknown_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = false,
-};
-
-// Unknown vendor config
-static const x86_microarch_config_t unknown_vendor_config{
-    .get_apic_freq = unknown_freq,
-    .get_tsc_freq = unknown_freq,
-    .reboot_system = unknown_reboot_system,
-    .disable_c1e = false,
-};
-
-void select_microarch_config(void) {
-    switch (x86_microarch) {
-    case X86_MICROARCH_INTEL_NEHALEM:
-        x86_microarch_config = &nehalem_config;
-        break;
-    case X86_MICROARCH_INTEL_WESTMERE:
-        x86_microarch_config = &westmere_config;
-        break;
-    case X86_MICROARCH_INTEL_SANDY_BRIDGE:
-        x86_microarch_config = &snb_config;
-        break;
-    case X86_MICROARCH_INTEL_IVY_BRIDGE:
-        x86_microarch_config = &ivb_config;
-        break;
-    case X86_MICROARCH_INTEL_BROADWELL:
-        x86_microarch_config = &bdw_config;
-        break;
-    case X86_MICROARCH_INTEL_HASWELL:
-        x86_microarch_config = &hsw_config;
-        break;
-    case X86_MICROARCH_INTEL_SKYLAKE:
-        x86_microarch_config = &skl_config;
-        break;
-    case X86_MICROARCH_INTEL_KABYLAKE:
-        x86_microarch_config = &kbl_config;
-        break;
-    case X86_MICROARCH_INTEL_SILVERMONT:
-        x86_microarch_config = &smt_config;
-        break;
-    case X86_MICROARCH_AMD_BULLDOZER:
-        x86_microarch_config = &bulldozer_config;
-        break;
-    case X86_MICROARCH_AMD_JAGUAR:
-        x86_microarch_config = &jaguar_config;
-        break;
-    case X86_MICROARCH_AMD_ZEN:
-        x86_microarch_config = &zen_config;
-        break;
-    case X86_MICROARCH_UNKNOWN: {
-        printf("WARNING: Could not identify microarch.\n");
-        printf("Please file a bug with your boot log and description of hardware.\n");
-        switch (x86_vendor) {
-        case X86_VENDOR_INTEL:
-            x86_microarch_config = &intel_default_config;
-            break;
-        case X86_VENDOR_AMD:
-            x86_microarch_config = &amd_default_config;
-            break;
-        case X86_VENDOR_UNKNOWN:
-            x86_microarch_config = &unknown_vendor_config;
-            break;
-        }
-    }
-    }
-}
diff --git a/kernel/arch/x86/gdt.S b/kernel/arch/x86/gdt.S
deleted file mode 100644
index a404730..0000000
--- a/kernel/arch/x86/gdt.S
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2015 Intel Corporation
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86/asm.h>
-#include <arch/x86/descriptor.h>
-
-.section .rodata.gdt,"a",%progbits
-// Intentionlly misalign this by 6 so that the address word holding _temp_gdt
-// is naturally aligned.  This address gets fixed up by apply_fixups (image.S).
-.balign 8
-.skip 6
-DATA(_temp_gdtr)
-    .short _temp_gdt_end - _temp_gdt - 1
-    .quad _temp_gdt
-END_DATA(_temp_gdtr)
-
-.data
-.align 8
-DATA(_temp_gdt)
-    /* null entry */
-    .int 0
-    .int 0
-
-    /* CODE_SELECTOR */
-    .short 0xffff           /* limit 15:00 */
-    .short 0x0000           /* base 15:00 */
-    .byte  0x00             /* base 23:16 */
-    .byte  0b10011010       /* P(1) DPL(00) S(1) 1 C(0) R(1) A(0) */
-    .byte  0b11001111       /* G(1) D(1) 0 0 limit 19:16 */
-    .byte  0x0              /* base 31:24 */
-
-    /* CODE_64_SELECTOR */
-    .short 0xffff           /* limit 15:00 */
-    .short 0x0000           /* base 15:00 */
-    .byte  0x00             /* base 23:16 */
-    .byte  0b10011010       /* P(1) DPL(00) S(1) 1 C(0) R(1) A(0) */
-    .byte  0b10101111       /* G(1) D(0) L(1) AVL(0) limit 19:16 */
-    .byte  0x0              /* base 31:24 */
-
-    /* DATA_SELECTOR */
-    .short 0xffff           /* limit 15:00 */
-    .short 0x0000           /* base 15:00 */
-    .byte  0x00             /* base 23:16 */
-    .byte  0b10010010       /* P(1) DPL(00) S(1) 0 E(0) W(1) A(0) */
-    .byte  0b11001111       /* G(1) B(1) 0 0 limit 19:16 */
-    .byte  0x0              /* base 31:24 */
-
-    /* disable 32bit ring3 code descriptor on 64bit kernel */
-    .int  0x0
-    .int  0x0
-
-    /* USER_DATA_SELECTOR */
-    .short 0xffff           /* limit 15:00 */
-    .short 0x0000           /* base 15:00 */
-    .byte  0x00             /* base 23:16 */
-    .byte  0b11110010       /* P(1) DPL(11) S(1) 0 E(0) W(1) A(0) */
-    .byte  0b11001111       /* G(1) B(1) 0 0 limit 19:16 */
-    .byte  0x0              /* base 31:24 */
-
-    /* USER_CODE_64_SELECTOR */
-    .short 0xffff           /* limit 15:00 */
-    .short 0x0000           /* base 15:00 */
-    .byte  0x00             /* base 23:16 */
-    .byte  0b11111010       /* P(1) DPL(11) S(1) 1 C(0) R(1) A(0) */
-    .byte  0b10101111       /* G(1) D(0) L(1) AVL(0) limit 19:16 */
-    .byte  0x0              /* base 31:24 */
-
-.rept SMP_MAX_CPUS
-    /* TSS_SELECTORs */
-    .short 0                /* limit 15:00 */
-    .short 0                /* base 15:00 */
-    .byte  0                /* base 23:16 */
-    .byte  0b10001001       /* P(1) DPL(00) 0 10 B(0) 1 */
-    .byte  0b10000000       /* G(1) 0 0 AVL(0) limit 19:16 */
-    .byte  0                /* base 31:24 */
-    /* second half of 64bit desciptor */
-    .int   0x00000000       /* base 63:32 */
-    .int   0x00000000       /* reserved/sbz */
-.endr
-
-END_DATA(_temp_gdt)
-
-DATA(_temp_gdt_end)
diff --git a/kernel/arch/x86/hwp.cpp b/kernel/arch/x86/hwp.cpp
deleted file mode 100644
index d1a8e2a..0000000
--- a/kernel/arch/x86/hwp.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86/feature.h>
-#include <err.h>
-#include <inttypes.h>
-#include <kernel/auto_lock.h>
-#include <kernel/mp.h>
-#include <kernel/spinlock.h>
-#include <lib/console.h>
-#include <string.h>
-#include <zircon/compiler.h>
-
-static bool hwp_enabled = false;
-
-static SpinLock lock;
-
-static void hwp_enable_sync_task(void* ctx) {
-    // Enable HWP
-    write_msr(X86_MSR_IA32_PM_ENABLE, 1);
-
-    // 14.4.7 set minimum/maximum to values from capabilities for
-    // common case. hint=0x80 by default
-    uint64_t hwp_caps = read_msr(X86_MSR_IA32_HWP_CAPABILITIES);
-    uint64_t hwp_req = (0x80ull << 24) | ((hwp_caps & 0xff) << 8) | ((hwp_caps >> 24) & 0xff);
-    write_msr(X86_MSR_IA32_HWP_REQUEST, hwp_req);
-}
-
-static void hwp_enable(void) {
-    AutoSpinLockNoIrqSave guard(&lock);
-
-    if (hwp_enabled) {
-        return;
-    }
-
-    if (!x86_feature_test(X86_FEATURE_HWP)) {
-        printf("HWP not supported\n");
-        return;
-    }
-
-    mp_sync_exec(MP_IPI_TARGET_ALL, 0, hwp_enable_sync_task, nullptr);
-
-    hwp_enabled = true;
-}
-
-static void hwp_set_hint_sync_task(void* ctx) {
-    uint8_t hint = (unsigned long)ctx & 0xff;
-    uint64_t hwp_req = read_msr(X86_MSR_IA32_HWP_REQUEST) & ~(0xff << 24);
-    hwp_req |= (hint << 24);
-    hwp_req &= ~(0xffffffffull << 32);
-    write_msr(X86_MSR_IA32_HWP_REQUEST, hwp_req);
-}
-
-static void hwp_set_hint(unsigned long hint) {
-    AutoSpinLockNoIrqSave guard(&lock);
-
-    if (!hwp_enabled) {
-        printf("Enable HWP first\n");
-        return;
-    }
-    if (!x86_feature_test(X86_FEATURE_HWP_PREF)) {
-        printf("HWP hint not supported\n");
-        return;
-    }
-    mp_sync_exec(MP_IPI_TARGET_ALL, 0, hwp_set_hint_sync_task, (void*)hint);
-}
-
-static int cmd_hwp(int argc, const cmd_args* argv, uint32_t flags) {
-    if (argc < 2) {
-    notenoughargs:
-        printf("not enough arguments\n");
-    usage:
-        printf("usage:\n");
-        printf("%s enable\n", argv[0].str);
-        printf("%s hint <0-255>\n", argv[0].str);
-        return ZX_ERR_INTERNAL;
-    }
-
-    if (!strcmp(argv[1].str, "enable")) {
-        hwp_enable();
-    } else if (!strcmp(argv[1].str, "hint")) {
-        if (argc < 3) {
-            goto notenoughargs;
-        }
-        if (argv[2].u > 0xff) {
-            printf("hint must be between 0 (performance) and 255 (energy efficiency)!");
-            goto usage;
-        }
-        hwp_set_hint(argv[2].u);
-    } else {
-        printf("unknown command\n");
-        goto usage;
-    }
-
-    return ZX_OK;
-}
-
-STATIC_COMMAND_START
-STATIC_COMMAND("hwp", "hardware controlled performance states\n", &cmd_hwp)
-STATIC_COMMAND_END(hwp);
diff --git a/kernel/arch/x86/hypervisor/MAINTAINERS b/kernel/arch/x86/hypervisor/MAINTAINERS
deleted file mode 100644
index 3d9d155..0000000
--- a/kernel/arch/x86/hypervisor/MAINTAINERS
+++ /dev/null
@@ -1,2 +0,0 @@
-abdulla@google.com
-alexlegg@google.com
diff --git a/kernel/arch/x86/hypervisor/guest.cpp b/kernel/arch/x86/hypervisor/guest.cpp
deleted file mode 100644
index 00a5ea0..0000000
--- a/kernel/arch/x86/hypervisor/guest.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86/apic.h>
-#include <arch/x86/feature.h>
-#include <zircon/syscalls/hypervisor.h>
-
-#include "vmx_cpu_state_priv.h"
-
-static void ignore_msr(VmxPage* msr_bitmaps_page, bool ignore_writes, uint32_t msr) {
-    // From Volume 3, Section 24.6.9.
-    uint8_t* msr_bitmaps = msr_bitmaps_page->VirtualAddress<uint8_t>();
-    if (msr >= 0xc0000000) {
-        msr_bitmaps += 1 << 10;
-    }
-
-    uint16_t msr_low = msr & 0x1fff;
-    uint16_t msr_byte = msr_low / 8;
-    uint8_t msr_bit = msr_low % 8;
-
-    // Ignore reads to the MSR.
-    msr_bitmaps[msr_byte] &= (uint8_t) ~(1 << msr_bit);
-
-    if (ignore_writes) {
-        // Ignore writes to the MSR.
-        msr_bitmaps += 2 << 10;
-        msr_bitmaps[msr_byte] &= (uint8_t) ~(1 << msr_bit);
-    }
-}
-
-// static
-zx_status_t Guest::Create(ktl::unique_ptr<Guest>* out) {
-    // Check that the CPU supports VMX.
-    if (!x86_feature_test(X86_FEATURE_VMX)) {
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-
-    zx_status_t status = alloc_vmx_state();
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    fbl::AllocChecker ac;
-    ktl::unique_ptr<Guest> guest(new (&ac) Guest);
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    status = hypervisor::GuestPhysicalAddressSpace::Create(&guest->gpas_);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // Setup common MSR bitmaps.
-    VmxInfo vmx_info;
-    status = guest->msr_bitmaps_page_.Alloc(vmx_info, UINT8_MAX);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_PAT);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_EFER);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_FS_BASE);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_GS_BASE);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_KERNEL_GS_BASE);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_STAR);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_LSTAR);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_FMASK);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_TSC_ADJUST);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_TSC_AUX);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_SYSENTER_CS);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_SYSENTER_ESP);
-    ignore_msr(&guest->msr_bitmaps_page_, true, X86_MSR_IA32_SYSENTER_EIP);
-
-    // Setup VPID allocator
-    fbl::AutoLock lock(&guest->vcpu_mutex_);
-    status = guest->vpid_allocator_.Init();
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    *out = ktl::move(guest);
-    return ZX_OK;
-}
-
-Guest::~Guest() {
-    free_vmx_state();
-}
-
-zx_status_t Guest::SetTrap(uint32_t kind, zx_vaddr_t addr, size_t len,
-                           fbl::RefPtr<PortDispatcher> port, uint64_t key) {
-    if (len == 0) {
-        return ZX_ERR_INVALID_ARGS;
-    } else if (SIZE_MAX - len < addr) {
-        return ZX_ERR_OUT_OF_RANGE;
-    }
-
-    switch (kind) {
-    case ZX_GUEST_TRAP_MEM:
-        if (port) {
-            return ZX_ERR_INVALID_ARGS;
-        }
-        break;
-    case ZX_GUEST_TRAP_BELL:
-        if (!port) {
-            return ZX_ERR_INVALID_ARGS;
-        }
-        break;
-    case ZX_GUEST_TRAP_IO:
-        if (port) {
-            return ZX_ERR_INVALID_ARGS;
-        } else if (addr + len > UINT16_MAX) {
-            return ZX_ERR_OUT_OF_RANGE;
-        }
-        return traps_.InsertTrap(kind, addr, len, ktl::move(port), key);
-    default:
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    // Common logic for memory-based traps.
-    if (!IS_PAGE_ALIGNED(addr) || !IS_PAGE_ALIGNED(len)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    zx_status_t status = gpas_->UnmapRange(addr, len);
-    if (status != ZX_OK) {
-        return status;
-    }
-    return traps_.InsertTrap(kind, addr, len, ktl::move(port), key);
-}
-
-zx_status_t Guest::AllocVpid(uint16_t* vpid) {
-    fbl::AutoLock lock(&vcpu_mutex_);
-    return vpid_allocator_.AllocId(vpid);
-}
-
-zx_status_t Guest::FreeVpid(uint16_t vpid) {
-    fbl::AutoLock lock(&vcpu_mutex_);
-    return vpid_allocator_.FreeId(vpid);
-}
diff --git a/kernel/arch/x86/hypervisor/pvclock.cpp b/kernel/arch/x86/hypervisor/pvclock.cpp
deleted file mode 100644
index 229dd03..0000000
--- a/kernel/arch/x86/hypervisor/pvclock.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include "pvclock_priv.h"
-#include <arch/hypervisor.h>
-#include <arch/x86/pvclock.h>
-#include <bits.h>
-#include <hypervisor/guest_physical_address_space.h>
-#include <platform.h>
-#include <vm/physmap.h>
-#include <zircon/types.h>
-
-namespace {
-
-void calculate_scale_factor(uint64_t tsc_freq, uint32_t* mul, int8_t* shift) {
-    // Guests converts TSC ticks to nanoseconds using this formula:
-    //   ns = #TSCticks * mul * 2^(shift - 32).
-    // mul * 2^(shift - 32) is a fractional number used as a scale factor in conversion.
-    // It's very similar to how floating point numbers are usually represented in memory.
-    static const uint64_t target_freq = 1000000000ul;
-
-    DEBUG_ASSERT(tsc_freq != 0);
-
-    // We maintain the folowing invariant: 2^(exponent - 32) * x/y ~ target_freq / tsc_freq,
-    int8_t exponent = 32;
-    uint64_t x = target_freq;
-    uint64_t y = tsc_freq;
-
-    // First make y small enough so that (y << 31) doesn't overflow in the next step. Adjust
-    // exponent along the way to maintain invariant.
-    while (y >= (1ull << 31)) {
-        y >>= 1;
-        exponent--;
-    }
-
-    // We scale x/y multiplying x by 2 until it gets big enough or we run out of bits.
-    while (x < (y << 31) && BIT(x, 63) == 0) {
-        x <<= 1;
-        exponent--;
-    }
-
-    // Though it's very unlikely lets also consider a situation when x/y is still too small.
-    while (x < y) {
-        y >>= 1;
-        exponent++;
-    }
-
-    // Finally make sure that x/y fits within 32 bits.
-    while (x >= (y << 32)) {
-        x >>= 1;
-        exponent++;
-    }
-
-    *shift = static_cast<int8_t>(exponent);
-    *mul = static_cast<uint32_t>(x / y);
-}
-
-} // namespace
-
-extern fbl::atomic<int64_t> utc_offset;
-
-zx_status_t pvclock_update_boot_time(hypervisor::GuestPhysicalAddressSpace* gpas,
-                                     zx_vaddr_t guest_paddr) {
-    // KVM doesn't provide any protection against concurrent wall time requests from different
-    // VCPUs, but documentation doesn't mention that it cannot happen and moreover it properly
-    // protects per VCPU system time. Therefore to be on the safer side we use one global mutex
-    // for protection.
-    static fbl::Mutex mutex;
-    static uint32_t version __TA_GUARDED(mutex);
-
-    hypervisor::GuestPtr guest_ptr;
-    zx_status_t status = gpas->CreateGuestPtr(guest_paddr, sizeof(pvclock_boot_time),
-                                              "pvclock-boot-time-guest-mapping", &guest_ptr);
-    if (status != ZX_OK) {
-        return status;
-    }
-    auto boot_time = guest_ptr.as<pvclock_boot_time>();
-    ZX_DEBUG_ASSERT(boot_time != nullptr);
-    memset(boot_time, 0, sizeof(*boot_time));
-
-    fbl::AutoLock lock(&mutex);
-    zx_time_t time = utc_offset.load();
-    // See the comment for pvclock_boot_time structure in arch/x86/pvclock.h
-    atomic_store_relaxed_u32(&boot_time->version, version + 1);
-    atomic_fence();
-    boot_time->seconds = static_cast<uint32_t>(time / ZX_SEC(1));
-    boot_time->nseconds = static_cast<uint32_t>(time % ZX_SEC(1));
-    atomic_fence();
-    atomic_store_relaxed_u32(&boot_time->version, version + 2);
-    version += 2;
-    return ZX_OK;
-}
-
-zx_status_t pvclock_reset_clock(PvClockState* pvclock, hypervisor::GuestPhysicalAddressSpace* gpas,
-                                zx_vaddr_t guest_paddr) {
-    zx_status_t status =
-        gpas->CreateGuestPtr(guest_paddr, sizeof(pvclock_system_time),
-                             "pvclock-system-time-guest-mapping", &pvclock->guest_ptr);
-    if (status != ZX_OK) {
-        return status;
-    }
-    pvclock->system_time = pvclock->guest_ptr.as<pvclock_system_time>();
-    ZX_DEBUG_ASSERT(pvclock->system_time != nullptr);
-    memset(pvclock->system_time, 0, sizeof(*pvclock->system_time));
-    return ZX_OK;
-}
-
-void pvclock_update_system_time(PvClockState* pvclock,
-                                hypervisor::GuestPhysicalAddressSpace* gpas) {
-    if (!pvclock->system_time) {
-        return;
-    }
-
-    uint32_t tsc_mul;
-    int8_t tsc_shift;
-    calculate_scale_factor(ticks_per_second(), &tsc_mul, &tsc_shift);
-
-    // See the comment for pvclock_boot_time structure in arch/x86/pvclock.h
-    pvclock_system_time* system_time = pvclock->system_time;
-    atomic_store_relaxed_u32(&system_time->version, pvclock->version + 1);
-    atomic_fence();
-    system_time->tsc_mul = tsc_mul;
-    system_time->tsc_shift = tsc_shift;
-    system_time->system_time = current_time();
-    system_time->tsc_timestamp = rdtsc();
-    system_time->flags = pvclock->is_stable ? kKvmSystemTimeStable : 0;
-    atomic_fence();
-    atomic_store_relaxed_u32(&system_time->version, pvclock->version + 2);
-    pvclock->version += 2;
-}
-
-void pvclock_stop_clock(PvClockState* pvclock) {
-    pvclock->system_time = nullptr;
-    pvclock->guest_ptr.reset();
-}
-
-zx_status_t pvclock_populate_offset(hypervisor::GuestPhysicalAddressSpace* gpas,
-                                    zx_vaddr_t guest_paddr) {
-    hypervisor::GuestPtr guest_ptr;
-    zx_status_t status =
-        gpas->CreateGuestPtr(guest_paddr, sizeof(PvClockOffset),
-                             "pvclock-offset-guest-mapping", &guest_ptr);
-    if (status != ZX_OK) {
-        return status;
-    }
-    auto offset = guest_ptr.as<PvClockOffset>();
-    ZX_DEBUG_ASSERT(offset != nullptr);
-    memset(offset, 0, sizeof(*offset));
-    zx_time_t time = utc_offset.load() + current_time();
-    uint64_t tsc = rdtsc();
-    offset->sec = time / ZX_SEC(1);
-    offset->nsec = time % ZX_SEC(1);
-    offset->tsc = tsc;
-    return ZX_OK;
-}
diff --git a/kernel/arch/x86/hypervisor/pvclock_priv.h b/kernel/arch/x86/hypervisor/pvclock_priv.h
deleted file mode 100644
index 3552a06..0000000
--- a/kernel/arch/x86/hypervisor/pvclock_priv.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <hypervisor/guest_physical_address_space.h>
-#include <zircon/types.h>
-
-struct PvClockState;
-
-// This structure contains mapping between TSC and host wall time at some point
-// in time. KVM has a hypercall that asks the VMM to populate this structure and
-// it's actually used, which is rather puzzling considering that PV clock
-// provides an API to get wall time at the time of boot and offset from that time
-// which seem to be enough.
-//
-// More detailed description of KVM API is available here:
-//  https://www.kernel.org/doc/Documentation/virtual/kvm/hypercalls.txt
-struct PvClockOffset {
-    uint64_t sec;
-    uint64_t nsec;
-    uint64_t tsc;
-    uint32_t flags;
-    uint32_t unused[9];
-} __PACKED;
-
-// Updates guest boot time.
-zx_status_t pvclock_update_boot_time(hypervisor::GuestPhysicalAddressSpace* gpas,
-                                     zx_vaddr_t guest_paddr);
-
-// Remembers guest physical address for KVM clock system time structure and enables updates
-// to guest system time.
-zx_status_t pvclock_reset_clock(PvClockState* pvclock, hypervisor::GuestPhysicalAddressSpace* gpas,
-                                zx_vaddr_t guest_paddr);
-
-// Disables updates to guest system time.
-void pvclock_stop_clock(PvClockState* pvclock);
-
-// Updates guest system time. If updates disabled does nothing.
-void pvclock_update_system_time(PvClockState* pvclock, hypervisor::GuestPhysicalAddressSpace* gpas);
-
-// Populates mapping between TSC and wall time per guest request. guest_padds contains
-// physical address of PvClockOffset structure where the result should be stored.
-zx_status_t pvclock_populate_offset(hypervisor::GuestPhysicalAddressSpace* gpas,
-                                    zx_vaddr_t guest_paddr);
diff --git a/kernel/arch/x86/hypervisor/rules.mk b/kernel/arch/x86/hypervisor/rules.mk
deleted file mode 100644
index d57e53c..0000000
--- a/kernel/arch/x86/hypervisor/rules.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2017 The Fuchsia Authors
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS := \
-	$(LOCAL_DIR)/guest.cpp \
-	$(LOCAL_DIR)/vcpu.cpp \
-	$(LOCAL_DIR)/vmexit.cpp \
-	$(LOCAL_DIR)/vmx.S \
-	$(LOCAL_DIR)/vmx_cpu_state.cpp \
-	$(LOCAL_DIR)/pvclock.cpp \
-
-include make/module.mk
diff --git a/kernel/arch/x86/hypervisor/vcpu.cpp b/kernel/arch/x86/hypervisor/vcpu.cpp
deleted file mode 100644
index dc35ace..0000000
--- a/kernel/arch/x86/hypervisor/vcpu.cpp
+++ /dev/null
@@ -1,915 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <bits.h>
-
-#include <arch/x86/descriptor.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/pvclock.h>
-#include <fbl/auto_call.h>
-#include <hypervisor/cpu.h>
-#include <hypervisor/ktrace.h>
-#include <kernel/mp.h>
-#include <lib/ktrace.h>
-#include <vm/fault.h>
-#include <vm/pmm.h>
-#include <vm/vm_object.h>
-#include <zircon/syscalls/hypervisor.h>
-
-#include "pvclock_priv.h"
-#include "vcpu_priv.h"
-#include "vmexit_priv.h"
-#include "vmx_cpu_state_priv.h"
-
-static constexpr uint32_t kInterruptInfoValid = 1u << 31;
-static constexpr uint32_t kInterruptInfoDeliverErrorCode = 1u << 11;
-static constexpr uint32_t kInterruptTypeNmi = 2u << 8;
-static constexpr uint32_t kInterruptTypeHardwareException = 3u << 8;
-static constexpr uint32_t kInterruptTypeSoftwareException = 6u << 8;
-static constexpr uint16_t kBaseProcessorVpid = 1;
-
-static zx_status_t invept(InvEpt invalidation, uint64_t eptp) {
-    uint8_t err;
-    uint64_t descriptor[] = {eptp, 0};
-
-    __asm__ volatile(
-        "invept %[descriptor], %[invalidation];" VMX_ERR_CHECK(err)
-        : [err] "=r"(err)
-        : [descriptor] "m"(descriptor), [invalidation] "r"(invalidation)
-        : "cc");
-
-    return err ? ZX_ERR_INTERNAL : ZX_OK;
-}
-
-static zx_status_t vmptrld(paddr_t pa) {
-    uint8_t err;
-
-    __asm__ volatile(
-        "vmptrld %[pa];" VMX_ERR_CHECK(err)
-        : [err] "=r"(err)
-        : [pa] "m"(pa)
-        : "cc", "memory");
-
-    return err ? ZX_ERR_INTERNAL : ZX_OK;
-}
-
-static zx_status_t vmclear(paddr_t pa) {
-    uint8_t err;
-
-    __asm__ volatile(
-        "vmclear %[pa];" VMX_ERR_CHECK(err)
-        : [err] "=r"(err)
-        : [pa] "m"(pa)
-        : "cc", "memory");
-
-    return err ? ZX_ERR_INTERNAL : ZX_OK;
-}
-
-static uint64_t vmread(uint64_t field) {
-    uint8_t err;
-    uint64_t val;
-
-    __asm__ volatile(
-        "vmread %[field], %[val];" VMX_ERR_CHECK(err)
-        : [err] "=r"(err), [val] "=m"(val)
-        : [field] "r"(field)
-        : "cc");
-
-    DEBUG_ASSERT(err == ZX_OK);
-    return val;
-}
-
-static void vmwrite(uint64_t field, uint64_t val) {
-    uint8_t err;
-
-    __asm__ volatile(
-        "vmwrite %[val], %[field];" VMX_ERR_CHECK(err)
-        : [err] "=r"(err)
-        : [val] "r"(val), [field] "r"(field)
-        : "cc");
-
-    DEBUG_ASSERT(err == ZX_OK);
-}
-
-AutoVmcs::AutoVmcs(paddr_t vmcs_address)
-    : vmcs_address_(vmcs_address) {
-    DEBUG_ASSERT(!arch_ints_disabled());
-    arch_disable_ints();
-    __UNUSED zx_status_t status = vmptrld(vmcs_address_);
-    arch_set_blocking_disallowed(true);
-    DEBUG_ASSERT(status == ZX_OK);
-}
-
-AutoVmcs::~AutoVmcs() {
-    DEBUG_ASSERT(arch_ints_disabled());
-    if (vmcs_address_) {
-        arch_set_blocking_disallowed(false);
-    }
-    arch_enable_ints();
-}
-
-void AutoVmcs::Invalidate() {
-    if (vmcs_address_) {
-        vmcs_address_ = 0;
-        arch_set_blocking_disallowed(false);
-    }
-}
-
-void AutoVmcs::InterruptWindowExiting(bool enable) {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    uint32_t controls = Read(VmcsField32::PROCBASED_CTLS);
-    if (enable) {
-        controls |= kProcbasedCtlsIntWindowExiting;
-    } else {
-        controls &= ~kProcbasedCtlsIntWindowExiting;
-    }
-    Write(VmcsField32::PROCBASED_CTLS, controls);
-}
-
-static bool has_error_code(uint32_t vector) {
-    switch (vector) {
-    case X86_INT_DOUBLE_FAULT:
-    case X86_INT_INVALID_TSS:
-    case X86_INT_SEGMENT_NOT_PRESENT:
-    case X86_INT_STACK_FAULT:
-    case X86_INT_GP_FAULT:
-    case X86_INT_PAGE_FAULT:
-    case X86_INT_ALIGNMENT_CHECK:
-        return true;
-    default:
-        return false;
-    }
-}
-
-void AutoVmcs::IssueInterrupt(uint32_t vector) {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    uint32_t interrupt_info = kInterruptInfoValid | (vector & UINT8_MAX);
-    if (vector == X86_INT_BREAKPOINT || vector == X86_INT_OVERFLOW) {
-        // From Volume 3, Section 24.8.3. A VMM should use type hardware exception for all
-        // exceptions other than breakpoints and overflows, which should be software exceptions.
-        interrupt_info |= kInterruptTypeSoftwareException;
-    } else if (vector == X86_INT_NMI) {
-        interrupt_info |= kInterruptTypeNmi;
-    } else if (vector <= X86_INT_VIRT) {
-        // From Volume 3, Section 6.15. All other vectors from 0 to X86_INT_VIRT are exceptions.
-        interrupt_info |= kInterruptTypeHardwareException;
-    }
-    if (has_error_code(vector)) {
-        interrupt_info |= kInterruptInfoDeliverErrorCode;
-        Write(VmcsField32::ENTRY_EXCEPTION_ERROR_CODE, 0);
-    }
-
-    DEBUG_ASSERT((Read(VmcsField32::ENTRY_INTERRUPTION_INFORMATION) & kInterruptInfoValid) == 0);
-    Write(VmcsField32::ENTRY_INTERRUPTION_INFORMATION, interrupt_info);
-}
-
-uint16_t AutoVmcs::Read(VmcsField16 field) const {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    return static_cast<uint16_t>(vmread(static_cast<uint64_t>(field)));
-}
-
-uint32_t AutoVmcs::Read(VmcsField32 field) const {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    return static_cast<uint32_t>(vmread(static_cast<uint64_t>(field)));
-}
-
-uint64_t AutoVmcs::Read(VmcsField64 field) const {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    return vmread(static_cast<uint64_t>(field));
-}
-
-uint64_t AutoVmcs::Read(VmcsFieldXX field) const {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    return vmread(static_cast<uint64_t>(field));
-}
-
-void AutoVmcs::Write(VmcsField16 field, uint16_t val) {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    vmwrite(static_cast<uint64_t>(field), val);
-}
-
-void AutoVmcs::Write(VmcsField32 field, uint32_t val) {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    vmwrite(static_cast<uint64_t>(field), val);
-}
-
-void AutoVmcs::Write(VmcsField64 field, uint64_t val) {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    vmwrite(static_cast<uint64_t>(field), val);
-}
-
-void AutoVmcs::Write(VmcsFieldXX field, uint64_t val) {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    vmwrite(static_cast<uint64_t>(field), val);
-}
-
-zx_status_t AutoVmcs::SetControl(VmcsField32 controls, uint64_t true_msr, uint64_t old_msr,
-                                 uint32_t set, uint32_t clear) {
-    DEBUG_ASSERT(vmcs_address_ != 0);
-    uint32_t allowed_0 = static_cast<uint32_t>(BITS(true_msr, 31, 0));
-    uint32_t allowed_1 = static_cast<uint32_t>(BITS_SHIFT(true_msr, 63, 32));
-    if ((allowed_1 & set) != set) {
-        dprintf(INFO, "can not set vmcs controls %#x\n", static_cast<uint>(controls));
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-    if ((~allowed_0 & clear) != clear) {
-        dprintf(INFO, "can not clear vmcs controls %#x\n", static_cast<uint>(controls));
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-    if ((set & clear) != 0) {
-        dprintf(INFO, "can not set and clear the same vmcs controls %#x\n",
-                static_cast<uint>(controls));
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    // See Volume 3, Section 31.5.1, Algorithm 3, Part C. If the control can be
-    // either 0 or 1 (flexible), and the control is unknown, then refer to the
-    // old MSR to find the default value.
-    uint32_t flexible = allowed_0 ^ allowed_1;
-    uint32_t unknown = flexible & ~(set | clear);
-    uint32_t defaults = unknown & BITS(old_msr, 31, 0);
-    Write(controls, allowed_0 | defaults | set);
-    return ZX_OK;
-}
-
-AutoPin::AutoPin(uint16_t vpid)
-    : prev_cpu_mask_(get_current_thread()->cpu_affinity), thread_(hypervisor::pin_thread(vpid)) {}
-
-AutoPin::~AutoPin() {
-    thread_set_cpu_affinity(thread_, prev_cpu_mask_);
-}
-
-static uint64_t ept_pointer(paddr_t pml4_address) {
-    return
-        // Physical address of the PML4 page, page aligned.
-        pml4_address |
-        // Use write-back memory type for paging structures.
-        VMX_MEMORY_TYPE_WRITE_BACK << 0 |
-        // Page walk length of 4 (defined as N minus 1).
-        3u << 3;
-}
-
-struct MsrListEntry {
-    uint32_t msr;
-    uint32_t reserved;
-    uint64_t value;
-} __PACKED;
-
-static void edit_msr_list(VmxPage* msr_list_page, size_t index, uint32_t msr, uint64_t value) {
-    // From Volume 3, Section 24.7.2.
-
-    // From Volume 3, Appendix A.6: Specifically, if the value bits 27:25 of
-    // IA32_VMX_MISC is N, then 512 * (N + 1) is the recommended maximum number
-    // of MSRs to be included in each list.
-    //
-    // From Volume 3, Section 24.7.2: This field specifies the number of MSRs to
-    // be stored on VM exit. It is recommended that this count not exceed 512
-    // bytes.
-    //
-    // Since these two statements conflict, we are taking the conservative
-    // minimum and asserting that: index < (512 bytes / size of MsrListEntry).
-    ASSERT(index < (512 / sizeof(MsrListEntry)));
-
-    MsrListEntry* entry = msr_list_page->VirtualAddress<MsrListEntry>() + index;
-    entry->msr = msr;
-    entry->value = value;
-}
-
-static zx_status_t vmcs_init(paddr_t vmcs_address, uint16_t vpid, uintptr_t entry,
-                             paddr_t msr_bitmaps_address, paddr_t pml4_address, VmxState* vmx_state,
-                             VmxPage* host_msr_page, VmxPage* guest_msr_page) {
-    zx_status_t status = vmclear(vmcs_address);
-    if (status != ZX_OK)
-        return status;
-
-    AutoVmcs vmcs(vmcs_address);
-    // Setup secondary processor-based VMCS controls.
-    status = vmcs.SetControl(VmcsField32::PROCBASED_CTLS2,
-                             read_msr(X86_MSR_IA32_VMX_PROCBASED_CTLS2),
-                             0,
-                             // Enable use of extended page tables.
-                             kProcbasedCtls2Ept |
-                                 // Enable use of RDTSCP instruction.
-                                 kProcbasedCtls2Rdtscp |
-                                 // Enable X2APIC.
-                                 kProcbasedCtls2x2Apic |
-                                 // Associate cached translations of linear
-                                 // addresses with a virtual processor ID.
-                                 kProcbasedCtls2Vpid |
-                                 // Enable unrestricted guest.
-                                 kProcbasedCtls2UnrestrictedGuest,
-                             0);
-    if (status != ZX_OK)
-        return status;
-
-    // Enable use of INVPCID instruction if available.
-    vmcs.SetControl(VmcsField32::PROCBASED_CTLS2,
-                    read_msr(X86_MSR_IA32_VMX_PROCBASED_CTLS2),
-                    vmcs.Read(VmcsField32::PROCBASED_CTLS2),
-                    kProcbasedCtls2Invpcid,
-                    0);
-
-    // Setup pin-based VMCS controls.
-    status = vmcs.SetControl(VmcsField32::PINBASED_CTLS,
-                             read_msr(X86_MSR_IA32_VMX_TRUE_PINBASED_CTLS),
-                             read_msr(X86_MSR_IA32_VMX_PINBASED_CTLS),
-                             // External interrupts cause a VM exit.
-                             kPinbasedCtlsExtIntExiting |
-                                 // Non-maskable interrupts cause a VM exit.
-                                 kPinbasedCtlsNmiExiting,
-                             0);
-    if (status != ZX_OK)
-        return status;
-
-    // Setup primary processor-based VMCS controls.
-    status = vmcs.SetControl(VmcsField32::PROCBASED_CTLS,
-                             read_msr(X86_MSR_IA32_VMX_TRUE_PROCBASED_CTLS),
-                             read_msr(X86_MSR_IA32_VMX_PROCBASED_CTLS),
-                             // Enable VM exit when interrupts are enabled.
-                             kProcbasedCtlsIntWindowExiting |
-                                 // Enable VM exit on HLT instruction.
-                                 kProcbasedCtlsHltExiting |
-                                 // Enable TPR virtualization.
-                                 kProcbasedCtlsTprShadow |
-                                 // Enable VM exit on IO instructions.
-                                 kProcbasedCtlsIoExiting |
-                                 // Enable use of MSR bitmaps.
-                                 kProcbasedCtlsMsrBitmaps |
-                                 // Enable VM exit on pause instruction.
-                                 kProcbasedCtlsPauseExiting |
-                                 // Enable secondary processor-based controls.
-                                 kProcbasedCtlsProcbasedCtls2,
-                             // Disable VM exit on CR3 load.
-                             kProcbasedCtlsCr3LoadExiting |
-                                 // Disable VM exit on CR3 store.
-                                 kProcbasedCtlsCr3StoreExiting |
-                                 // Disable VM exit on CR8 load.
-                                 kProcbasedCtlsCr8LoadExiting |
-                                 // Disable VM exit on CR8 store.
-                                 kProcbasedCtlsCr8StoreExiting);
-    if (status != ZX_OK)
-        return status;
-
-    // We only enable interrupt-window exiting above to ensure that the
-    // processor supports it for later use. So disable it for now.
-    vmcs.InterruptWindowExiting(false);
-
-    // Setup VM-exit VMCS controls.
-    status = vmcs.SetControl(VmcsField32::EXIT_CTLS,
-                             read_msr(X86_MSR_IA32_VMX_TRUE_EXIT_CTLS),
-                             read_msr(X86_MSR_IA32_VMX_EXIT_CTLS),
-                             // Logical processor is in 64-bit mode after VM
-                             // exit. On VM exit CS.L, IA32_EFER.LME, and
-                             // IA32_EFER.LMA is set to true.
-                             kExitCtls64bitMode |
-                                 // Save the guest IA32_PAT MSR on exit.
-                                 kExitCtlsSaveIa32Pat |
-                                 // Load the host IA32_PAT MSR on exit.
-                                 kExitCtlsLoadIa32Pat |
-                                 // Save the guest IA32_EFER MSR on exit.
-                                 kExitCtlsSaveIa32Efer |
-                                 // Load the host IA32_EFER MSR on exit.
-                                 kExitCtlsLoadIa32Efer |
-                                 // Acknowledge external interrupt on exit.
-                                 kExitCtlsAckIntOnExit,
-                             0);
-    if (status != ZX_OK)
-        return status;
-
-    // Setup VM-entry VMCS controls.
-    // Load the guest IA32_PAT MSR and IA32_EFER MSR on entry.
-    uint32_t entry_ctls = kEntryCtlsLoadIa32Pat | kEntryCtlsLoadIa32Efer;
-    if (vpid == kBaseProcessorVpid) {
-        // On the BSP, go straight to IA32E mode on entry.
-        entry_ctls |= kEntryCtlsIa32eMode;
-    }
-    status = vmcs.SetControl(VmcsField32::ENTRY_CTLS,
-                             read_msr(X86_MSR_IA32_VMX_TRUE_ENTRY_CTLS),
-                             read_msr(X86_MSR_IA32_VMX_ENTRY_CTLS),
-                             entry_ctls, 0);
-    if (status != ZX_OK)
-        return status;
-
-    // From Volume 3, Section 24.6.3: The exception bitmap is a 32-bit field
-    // that contains one bit for each exception. When an exception occurs,
-    // its vector is used to select a bit in this field. If the bit is 1,
-    // the exception causes a VM exit. If the bit is 0, the exception is
-    // delivered normally through the IDT, using the descriptor
-    // corresponding to the exception’s vector.
-    //
-    // From Volume 3, Section 25.2: If software desires VM exits on all page
-    // faults, it can set bit 14 in the exception bitmap to 1 and set the
-    // page-fault error-code mask and match fields each to 00000000H.
-    vmcs.Write(VmcsField32::EXCEPTION_BITMAP, 0);
-    vmcs.Write(VmcsField32::PAGEFAULT_ERRORCODE_MASK, 0);
-    vmcs.Write(VmcsField32::PAGEFAULT_ERRORCODE_MATCH, 0);
-
-    // From Volume 3, Section 28.1: Virtual-processor identifiers (VPIDs)
-    // introduce to VMX operation a facility by which a logical processor may
-    // cache information for multiple linear-address spaces. When VPIDs are
-    // used, VMX transitions may retain cached information and the logical
-    // processor switches to a different linear-address space.
-    //
-    // From Volume 3, Section 26.2.1.1: If the “enable VPID” VM-execution
-    // control is 1, the value of the VPID VM-execution control field must not
-    // be 0000H.
-    //
-    // From Volume 3, Section 28.3.3.3: If EPT is in use, the logical processor
-    // associates all mappings it creates with the value of bits 51:12 of
-    // current EPTP. If a VMM uses different EPTP values for different guests,
-    // it may use the same VPID for those guests.
-    //
-    // From Volume 3, Section 28.3.3.1: Operations that architecturally
-    // invalidate entries in the TLBs or paging-structure caches independent of
-    // VMX operation (e.g., the INVLPG and INVPCID instructions) invalidate
-    // linear mappings and combined mappings. They are required to do so only
-    // for the current VPID (but, for combined mappings, all EP4TAs). Linear
-    // mappings for the current VPID are invalidated even if EPT is in use.
-    // Combined mappings for the current VPID are invalidated even if EPT is
-    // not in use.
-    vmcs.Write(VmcsField16::VPID, vpid);
-
-    // From Volume 3, Section 28.2: The extended page-table mechanism (EPT) is a
-    // feature that can be used to support the virtualization of physical
-    // memory. When EPT is in use, certain addresses that would normally be
-    // treated as physical addresses (and used to access memory) are instead
-    // treated as guest-physical addresses. Guest-physical addresses are
-    // translated by traversing a set of EPT paging structures to produce
-    // physical addresses that are used to access memory.
-    const auto eptp = ept_pointer(pml4_address);
-    vmcs.Write(VmcsField64::EPT_POINTER, eptp);
-
-    // From Volume 3, Section 28.3.3.4: Software can use an INVEPT with type all
-    // ALL_CONTEXT to prevent undesired retention of cached EPT information. Here,
-    // we only care about invalidating information associated with this EPTP.
-    invept(InvEpt::SINGLE_CONTEXT, eptp);
-
-    // Setup MSR handling.
-    vmcs.Write(VmcsField64::MSR_BITMAPS_ADDRESS, msr_bitmaps_address);
-
-    edit_msr_list(host_msr_page, 0, X86_MSR_IA32_KERNEL_GS_BASE,
-                  read_msr(X86_MSR_IA32_KERNEL_GS_BASE));
-    edit_msr_list(host_msr_page, 1, X86_MSR_IA32_STAR, read_msr(X86_MSR_IA32_STAR));
-    edit_msr_list(host_msr_page, 2, X86_MSR_IA32_LSTAR, read_msr(X86_MSR_IA32_LSTAR));
-    edit_msr_list(host_msr_page, 3, X86_MSR_IA32_FMASK, read_msr(X86_MSR_IA32_FMASK));
-    edit_msr_list(host_msr_page, 4, X86_MSR_IA32_TSC_ADJUST, read_msr(X86_MSR_IA32_TSC_ADJUST));
-    edit_msr_list(host_msr_page, 5, X86_MSR_IA32_TSC_AUX, read_msr(X86_MSR_IA32_TSC_AUX));
-
-    vmcs.Write(VmcsField64::EXIT_MSR_LOAD_ADDRESS, host_msr_page->PhysicalAddress());
-    vmcs.Write(VmcsField32::EXIT_MSR_LOAD_COUNT, 6);
-
-    edit_msr_list(guest_msr_page, 0, X86_MSR_IA32_KERNEL_GS_BASE, 0);
-    edit_msr_list(guest_msr_page, 1, X86_MSR_IA32_STAR, 0);
-    edit_msr_list(guest_msr_page, 2, X86_MSR_IA32_LSTAR, 0);
-    edit_msr_list(guest_msr_page, 3, X86_MSR_IA32_FMASK, 0);
-    edit_msr_list(guest_msr_page, 4, X86_MSR_IA32_TSC_ADJUST, 0);
-    edit_msr_list(guest_msr_page, 5, X86_MSR_IA32_TSC_AUX, 0);
-    vmcs.Write(VmcsField64::EXIT_MSR_STORE_ADDRESS, guest_msr_page->PhysicalAddress());
-    vmcs.Write(VmcsField32::EXIT_MSR_STORE_COUNT, 6);
-    vmcs.Write(VmcsField64::ENTRY_MSR_LOAD_ADDRESS, guest_msr_page->PhysicalAddress());
-    vmcs.Write(VmcsField32::ENTRY_MSR_LOAD_COUNT, 6);
-
-    // Setup VMCS host state.
-    //
-    // NOTE: We are pinned to a thread when executing this function, therefore
-    // it is acceptable to use per-CPU state.
-    x86_percpu* percpu = x86_get_percpu();
-    vmcs.Write(VmcsField64::HOST_IA32_PAT, read_msr(X86_MSR_IA32_PAT));
-    vmcs.Write(VmcsField64::HOST_IA32_EFER, read_msr(X86_MSR_IA32_EFER));
-    vmcs.Write(VmcsFieldXX::HOST_CR0, x86_get_cr0());
-    vmcs.Write(VmcsFieldXX::HOST_CR3, x86_get_cr3());
-    vmcs.Write(VmcsFieldXX::HOST_CR4, x86_get_cr4());
-    vmcs.Write(VmcsField16::HOST_ES_SELECTOR, 0);
-    vmcs.Write(VmcsField16::HOST_CS_SELECTOR, CODE_64_SELECTOR);
-    vmcs.Write(VmcsField16::HOST_SS_SELECTOR, DATA_SELECTOR);
-    vmcs.Write(VmcsField16::HOST_DS_SELECTOR, 0);
-    vmcs.Write(VmcsField16::HOST_FS_SELECTOR, 0);
-    vmcs.Write(VmcsField16::HOST_GS_SELECTOR, 0);
-    vmcs.Write(VmcsField16::HOST_TR_SELECTOR, TSS_SELECTOR(percpu->cpu_num));
-    vmcs.Write(VmcsFieldXX::HOST_FS_BASE, read_msr(X86_MSR_IA32_FS_BASE));
-    vmcs.Write(VmcsFieldXX::HOST_GS_BASE, read_msr(X86_MSR_IA32_GS_BASE));
-    vmcs.Write(VmcsFieldXX::HOST_TR_BASE, reinterpret_cast<uint64_t>(&percpu->default_tss));
-    vmcs.Write(VmcsFieldXX::HOST_GDTR_BASE, reinterpret_cast<uint64_t>(gdt_get()));
-    vmcs.Write(VmcsFieldXX::HOST_IDTR_BASE, reinterpret_cast<uint64_t>(idt_get_readonly()));
-    vmcs.Write(VmcsFieldXX::HOST_IA32_SYSENTER_ESP, 0);
-    vmcs.Write(VmcsFieldXX::HOST_IA32_SYSENTER_EIP, 0);
-    vmcs.Write(VmcsField32::HOST_IA32_SYSENTER_CS, 0);
-    vmcs.Write(VmcsFieldXX::HOST_RSP, reinterpret_cast<uint64_t>(vmx_state));
-    vmcs.Write(VmcsFieldXX::HOST_RIP, reinterpret_cast<uint64_t>(vmx_exit_entry));
-
-    // Setup VMCS guest state.
-    uint64_t cr0 = X86_CR0_PE | // Enable protected mode
-                   X86_CR0_PG | // Enable paging
-                   X86_CR0_NE;  // Enable internal x87 exception handling
-    if (vpid != kBaseProcessorVpid) {
-        // Disable protected mode and paging on secondary VCPUs.
-        cr0 &= ~(X86_CR0_PE | X86_CR0_PG);
-    }
-    if (cr0_is_invalid(&vmcs, cr0)) {
-        return ZX_ERR_BAD_STATE;
-    }
-    vmcs.Write(VmcsFieldXX::GUEST_CR0, cr0);
-
-    // Ensure that CR0.NE remains set by masking and manually handling writes to CR0 that unset it.
-    vmcs.Write(VmcsFieldXX::CR0_GUEST_HOST_MASK, X86_CR0_NE);
-    vmcs.Write(VmcsFieldXX::CR0_READ_SHADOW, X86_CR0_NE);
-
-    uint64_t cr4 = X86_CR4_VMXE; // Enable VMX
-    if (vpid == kBaseProcessorVpid) {
-        // Enable the PAE bit on the BSP for 64-bit paging.
-        cr4 |= X86_CR4_PAE;
-    }
-    if (cr_is_invalid(cr4, X86_MSR_IA32_VMX_CR4_FIXED0, X86_MSR_IA32_VMX_CR4_FIXED1)) {
-        return ZX_ERR_BAD_STATE;
-    }
-    vmcs.Write(VmcsFieldXX::GUEST_CR4, cr4);
-
-    // For now, the guest can own all of the CR4 bits except VMXE, which it shouldn't touch.
-    // TODO(andymutton): Implement proper CR4 handling.
-    vmcs.Write(VmcsFieldXX::CR4_GUEST_HOST_MASK, X86_CR4_VMXE);
-    vmcs.Write(VmcsFieldXX::CR4_READ_SHADOW, 0);
-
-    vmcs.Write(VmcsField64::GUEST_IA32_PAT, read_msr(X86_MSR_IA32_PAT));
-
-    uint64_t guest_efer = read_msr(X86_MSR_IA32_EFER);
-    if (vpid != kBaseProcessorVpid) {
-        // Disable LME and LMA on all but the BSP.
-        guest_efer &= ~(X86_EFER_LME | X86_EFER_LMA);
-    }
-    vmcs.Write(VmcsField64::GUEST_IA32_EFER, guest_efer);
-
-    uint32_t cs_access_rights = kGuestXxAccessRightsDefault |
-                                kGuestXxAccessRightsTypeE |
-                                kGuestXxAccessRightsTypeCode;
-    if (vpid == kBaseProcessorVpid) {
-        // Ensure that the BSP starts with a 64-bit code segment.
-        cs_access_rights |= kGuestXxAccessRightsL;
-    }
-    vmcs.Write(VmcsField32::GUEST_CS_ACCESS_RIGHTS, cs_access_rights);
-
-    vmcs.Write(VmcsField32::GUEST_TR_ACCESS_RIGHTS,
-               kGuestTrAccessRightsTssBusy | kGuestXxAccessRightsP);
-
-    vmcs.Write(VmcsField32::GUEST_SS_ACCESS_RIGHTS, kGuestXxAccessRightsDefault);
-    vmcs.Write(VmcsField32::GUEST_DS_ACCESS_RIGHTS, kGuestXxAccessRightsDefault);
-    vmcs.Write(VmcsField32::GUEST_ES_ACCESS_RIGHTS, kGuestXxAccessRightsDefault);
-    vmcs.Write(VmcsField32::GUEST_FS_ACCESS_RIGHTS, kGuestXxAccessRightsDefault);
-    vmcs.Write(VmcsField32::GUEST_GS_ACCESS_RIGHTS, kGuestXxAccessRightsDefault);
-
-    vmcs.Write(VmcsField32::GUEST_LDTR_ACCESS_RIGHTS,
-               kGuestXxAccessRightsTypeW | kGuestXxAccessRightsP);
-
-    if (vpid == kBaseProcessorVpid) {
-        // Use GUEST_RIP to set the entry point on the BSP.
-        vmcs.Write(VmcsFieldXX::GUEST_CS_BASE, 0);
-        vmcs.Write(VmcsField16::GUEST_CS_SELECTOR, 0);
-        vmcs.Write(VmcsFieldXX::GUEST_RIP, entry);
-    } else {
-        // Use CS to set the entry point on APs.
-        vmcs.Write(VmcsFieldXX::GUEST_CS_BASE, entry);
-        vmcs.Write(VmcsField16::GUEST_CS_SELECTOR, static_cast<uint16_t>(entry >> 4));
-        vmcs.Write(VmcsFieldXX::GUEST_RIP, 0);
-    }
-    vmcs.Write(VmcsField32::GUEST_CS_LIMIT, 0xffff);
-    vmcs.Write(VmcsFieldXX::GUEST_TR_BASE, 0);
-    vmcs.Write(VmcsField16::GUEST_TR_SELECTOR, 0);
-    vmcs.Write(VmcsField32::GUEST_TR_LIMIT, 0xffff);
-    vmcs.Write(VmcsFieldXX::GUEST_DS_BASE, 0);
-    vmcs.Write(VmcsField32::GUEST_DS_LIMIT, 0xffff);
-    vmcs.Write(VmcsFieldXX::GUEST_SS_BASE, 0);
-    vmcs.Write(VmcsField32::GUEST_SS_LIMIT, 0xffff);
-    vmcs.Write(VmcsFieldXX::GUEST_ES_BASE, 0);
-    vmcs.Write(VmcsField32::GUEST_ES_LIMIT, 0xffff);
-    vmcs.Write(VmcsFieldXX::GUEST_FS_BASE, 0);
-    vmcs.Write(VmcsField32::GUEST_FS_LIMIT, 0xffff);
-    vmcs.Write(VmcsFieldXX::GUEST_GS_BASE, 0);
-    vmcs.Write(VmcsField32::GUEST_GS_LIMIT, 0xffff);
-    vmcs.Write(VmcsField32::GUEST_LDTR_LIMIT, 0xffff);
-    vmcs.Write(VmcsFieldXX::GUEST_GDTR_BASE, 0);
-    vmcs.Write(VmcsField32::GUEST_GDTR_LIMIT, 0xffff);
-    vmcs.Write(VmcsFieldXX::GUEST_IDTR_BASE, 0);
-    vmcs.Write(VmcsField32::GUEST_IDTR_LIMIT, 0xffff);
-
-    // Set all reserved RFLAGS bits to their correct values
-    vmcs.Write(VmcsFieldXX::GUEST_RFLAGS, X86_FLAGS_RESERVED_ONES);
-
-    vmcs.Write(VmcsField32::GUEST_ACTIVITY_STATE, 0);
-    vmcs.Write(VmcsField32::GUEST_INTERRUPTIBILITY_STATE, 0);
-    vmcs.Write(VmcsFieldXX::GUEST_PENDING_DEBUG_EXCEPTIONS, 0);
-
-    // From Volume 3, Section 26.3.1.1: The IA32_SYSENTER_ESP field and the
-    // IA32_SYSENTER_EIP field must each contain a canonical address.
-    vmcs.Write(VmcsFieldXX::GUEST_IA32_SYSENTER_ESP, 0);
-    vmcs.Write(VmcsFieldXX::GUEST_IA32_SYSENTER_EIP, 0);
-    vmcs.Write(VmcsField32::GUEST_IA32_SYSENTER_CS, 0);
-
-    vmcs.Write(VmcsFieldXX::GUEST_RSP, 0);
-    vmcs.Write(VmcsFieldXX::GUEST_CR3, 0);
-
-    // From Volume 3, Section 24.4.2: If the “VMCS shadowing” VM-execution
-    // control is 1, the VMREAD and VMWRITE instructions access the VMCS
-    // referenced by this pointer (see Section 24.10). Otherwise, software
-    // should set this field to FFFFFFFF_FFFFFFFFH to avoid VM-entry
-    // failures (see Section 26.3.1.5).
-    vmcs.Write(VmcsField64::LINK_POINTER, kLinkPointerInvalidate);
-
-    if (x86_feature_test(X86_FEATURE_XSAVE)) {
-        // Enable x87 state in guest XCR0.
-        vmx_state->guest_state.xcr0 = X86_XSAVE_STATE_BIT_X87;
-    }
-
-    return ZX_OK;
-}
-
-// static
-zx_status_t Vcpu::Create(Guest* guest, zx_vaddr_t entry, ktl::unique_ptr<Vcpu>* out) {
-    hypervisor::GuestPhysicalAddressSpace* gpas = guest->AddressSpace();
-    if (entry >= gpas->size())
-        return ZX_ERR_INVALID_ARGS;
-
-    uint16_t vpid;
-    zx_status_t status = guest->AllocVpid(&vpid);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    auto auto_call = fbl::MakeAutoCall([guest, vpid]() {
-        guest->FreeVpid(vpid);
-    });
-
-    // When we create a VCPU, we bind it to the current thread and a CPU based
-    // on the VPID. The VCPU must always be run on the current thread and the
-    // given CPU, unless an explicit migration is performed.
-    //
-    // The reason we do this is that:
-    // 1. The state of the current thread is stored within the VMCS, to be
-    //    restored upon a guest-to-host transition.
-    // 2. The state of the VMCS associated with the VCPU is cached within the
-    //    CPU. To move to a different CPU, we must perform an explicit migration
-    //    which will cost us performance.
-    thread_t* thread = hypervisor::pin_thread(vpid);
-
-    fbl::AllocChecker ac;
-    ktl::unique_ptr<Vcpu> vcpu(new (&ac) Vcpu(guest, vpid, thread));
-    if (!ac.check())
-        return ZX_ERR_NO_MEMORY;
-
-    timer_init(&vcpu->local_apic_state_.timer);
-    status = vcpu->local_apic_state_.interrupt_tracker.Init();
-    if (status != ZX_OK)
-        return status;
-
-    vcpu->pvclock_state_.is_stable =
-        pvclock_is_present() ? pvclock_is_stable() : x86_feature_test(X86_FEATURE_INVAR_TSC);
-
-    VmxInfo vmx_info;
-    status = vcpu->host_msr_page_.Alloc(vmx_info, 0);
-    if (status != ZX_OK)
-        return status;
-
-    status = vcpu->guest_msr_page_.Alloc(vmx_info, 0);
-    if (status != ZX_OK)
-        return status;
-
-    status = vcpu->vmcs_page_.Alloc(vmx_info, 0);
-    if (status != ZX_OK)
-        return status;
-    auto_call.cancel();
-
-    VmxRegion* region = vcpu->vmcs_page_.VirtualAddress<VmxRegion>();
-    region->revision_id = vmx_info.revision_id;
-    zx_paddr_t table = gpas->arch_aspace()->arch_table_phys();
-    status = vmcs_init(vcpu->vmcs_page_.PhysicalAddress(), vpid, entry, guest->MsrBitmapsAddress(),
-                       table, &vcpu->vmx_state_, &vcpu->host_msr_page_, &vcpu->guest_msr_page_);
-    if (status != ZX_OK)
-        return status;
-
-    *out = ktl::move(vcpu);
-    return ZX_OK;
-}
-
-Vcpu::Vcpu(Guest* guest, uint16_t vpid, const thread_t* thread)
-    : guest_(guest), vpid_(vpid), thread_(thread), running_(false), vmx_state_(/* zero-init */) {}
-
-Vcpu::~Vcpu() {
-    if (!vmcs_page_.IsAllocated()) {
-        return;
-    }
-    timer_cancel(&local_apic_state_.timer);
-    // The destructor may be called from a different thread, therefore we must
-    // pin the current thread to the same CPU as the VCPU.
-    AutoPin pin(vpid_);
-    vmclear(vmcs_page_.PhysicalAddress());
-    __UNUSED zx_status_t status = guest_->FreeVpid(vpid_);
-    DEBUG_ASSERT(status == ZX_OK);
-}
-
-// Injects an interrupt into the guest, if there is one pending.
-static zx_status_t local_apic_maybe_interrupt(AutoVmcs* vmcs, LocalApicState* local_apic_state) {
-    // Since hardware generated exceptions are delivered to the guest directly, the only exceptions
-    // we see here are those we generate in the VMM, e.g. GP faults in vmexit handlers. Therefore
-    // we simplify interrupt priority to 1) NMIs, 2) interrupts, and 3) generated exceptions. See
-    // Volume 3, Section 6.9, Table 6-2.
-    uint32_t vector = X86_INT_COUNT;
-    hypervisor::InterruptType type = local_apic_state->interrupt_tracker.TryPop(X86_INT_NMI);
-    if (type != hypervisor::InterruptType::INACTIVE) {
-        vector = X86_INT_NMI;
-    } else {
-        // Pop scans vectors from highest to lowest, which will correctly pop interrupts before
-        // exceptions. All vectors <= X86_INT_VIRT except the NMI vector are exceptions.
-        type = local_apic_state->interrupt_tracker.Pop(&vector);
-        if (type == hypervisor::InterruptType::INACTIVE) {
-            return ZX_OK;
-        }
-        // If type isn't inactive, then Pop should have initialized vector to a valid value.
-        DEBUG_ASSERT(vector != X86_INT_COUNT);
-    }
-
-    // NMI injection is blocked if an NMI is already being serviced (Volume 3, Section 24.4.2,
-    // Table 24-3), and mov ss blocks *all* interrupts (Volume 2 Section 4.3 MOV-Move instruction).
-    // Note that the IF flag does not affect NMIs (Volume 3, Section 6.8.1).
-    auto can_inject_nmi = [vmcs] {
-        return (vmcs->Read(VmcsField32::GUEST_INTERRUPTIBILITY_STATE) &
-                (kInterruptibilityNmiBlocking | kInterruptibilityMovSsBlocking)) == 0;
-    };
-    // External interrupts can be blocked due to STI, move SS or the IF flag.
-    auto can_inject_external_int = [vmcs] {
-        return (vmcs->Read(VmcsFieldXX::GUEST_RFLAGS) & X86_FLAGS_IF) &&
-               (vmcs->Read(VmcsField32::GUEST_INTERRUPTIBILITY_STATE) &
-                (kInterruptibilityStiBlocking | kInterruptibilityMovSsBlocking)) == 0;
-    };
-
-    if (vector > X86_INT_VIRT && vector < X86_INT_PLATFORM_BASE) {
-        dprintf(INFO, "Invalid interrupt vector: %u\n", vector);
-        return ZX_ERR_NOT_SUPPORTED;
-    } else if ((vector >= X86_INT_PLATFORM_BASE && !can_inject_external_int()) ||
-               (vector == X86_INT_NMI && !can_inject_nmi())
-
-    ) {
-        local_apic_state->interrupt_tracker.Track(vector, type);
-        // If interrupts are disabled, we set VM exit on interrupt enable.
-        vmcs->InterruptWindowExiting(true);
-        return ZX_OK;
-    }
-
-    // If the vector is non-maskable or interrupts are enabled, we inject an interrupt.
-    vmcs->IssueInterrupt(vector);
-
-    // Volume 3, Section 6.9: Lower priority exceptions are discarded; lower priority interrupts are
-    // held pending. Discarded exceptions are re-generated when the interrupt handler returns
-    // execution to the point in the program or task where the exceptions and/or interrupts
-    // occurred.
-    local_apic_state->interrupt_tracker.Clear(0, X86_INT_NMI);
-    local_apic_state->interrupt_tracker.Clear(X86_INT_NMI + 1, X86_INT_VIRT + 1);
-
-    return ZX_OK;
-}
-
-zx_status_t Vcpu::Resume(zx_port_packet_t* packet) {
-    if (!hypervisor::check_pinned_cpu_invariant(vpid_, thread_))
-        return ZX_ERR_BAD_STATE;
-    zx_status_t status;
-    do {
-        AutoVmcs vmcs(vmcs_page_.PhysicalAddress());
-        status = local_apic_maybe_interrupt(&vmcs, &local_apic_state_);
-        if (status != ZX_OK) {
-            return status;
-        }
-        if (x86_feature_test(X86_FEATURE_XSAVE)) {
-            // Save the host XCR0, and load the guest XCR0.
-            vmx_state_.host_state.xcr0 = x86_xgetbv(0);
-            x86_xsetbv(0, vmx_state_.guest_state.xcr0);
-        }
-
-        // Updates guest system time if the guest subscribed to updates.
-        pvclock_update_system_time(&pvclock_state_, guest_->AddressSpace());
-
-        ktrace(TAG_VCPU_ENTER, 0, 0, 0, 0);
-        running_.store(true);
-        status = vmx_enter(&vmx_state_);
-        running_.store(false);
-        if (x86_feature_test(X86_FEATURE_XSAVE)) {
-            // Save the guest XCR0, and load the host XCR0.
-            vmx_state_.guest_state.xcr0 = x86_xgetbv(0);
-            x86_xsetbv(0, vmx_state_.host_state.xcr0);
-        }
-
-        if (status != ZX_OK) {
-            ktrace_vcpu_exit(VCPU_FAILURE, vmcs.Read(VmcsFieldXX::GUEST_RIP));
-            uint64_t error = vmcs.Read(VmcsField32::INSTRUCTION_ERROR);
-            dprintf(INFO, "VCPU resume failed: %#lx\n", error);
-        } else {
-            vmx_state_.resume = true;
-            status = vmexit_handler(&vmcs, &vmx_state_.guest_state, &local_apic_state_,
-                                    &pvclock_state_, guest_->AddressSpace(), guest_->Traps(),
-                                    packet);
-        }
-    } while (status == ZX_OK);
-    return status == ZX_ERR_NEXT ? ZX_OK : status;
-}
-
-void vmx_exit(VmxState* vmx_state) {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    // Reload the task segment in order to restore its limit. VMX always
-    // restores it with a limit of 0x67, which excludes the IO bitmap.
-    seg_sel_t selector = TSS_SELECTOR(arch_curr_cpu_num());
-    x86_clear_tss_busy(selector);
-    x86_ltr(selector);
-}
-
-cpu_mask_t Vcpu::Interrupt(uint32_t vector, hypervisor::InterruptType type) {
-    bool signaled = false;
-    local_apic_state_.interrupt_tracker.Interrupt(vector, type, &signaled);
-    if (signaled || !running_.load()) {
-        return 0;
-    }
-    return cpu_num_to_mask(hypervisor::cpu_of(vpid_));
-}
-
-void Vcpu::VirtualInterrupt(uint32_t vector) {
-    cpu_mask_t mask = Interrupt(vector, hypervisor::InterruptType::VIRTUAL);
-    if (mask != 0) {
-        mp_interrupt(MP_IPI_TARGET_MASK, mask);
-    }
-}
-
-template <typename Out, typename In>
-static void register_copy(Out* out, const In& in) {
-    out->rax = in.rax;
-    out->rcx = in.rcx;
-    out->rdx = in.rdx;
-    out->rbx = in.rbx;
-    out->rbp = in.rbp;
-    out->rsi = in.rsi;
-    out->rdi = in.rdi;
-    out->r8 = in.r8;
-    out->r9 = in.r9;
-    out->r10 = in.r10;
-    out->r11 = in.r11;
-    out->r12 = in.r12;
-    out->r13 = in.r13;
-    out->r14 = in.r14;
-    out->r15 = in.r15;
-}
-
-zx_status_t Vcpu::ReadState(uint32_t kind, void* buf, size_t len) const {
-    if (!hypervisor::check_pinned_cpu_invariant(vpid_, thread_))
-        return ZX_ERR_BAD_STATE;
-    switch (kind) {
-    case ZX_VCPU_STATE: {
-        if (len != sizeof(zx_vcpu_state_t))
-            break;
-        auto state = static_cast<zx_vcpu_state_t*>(buf);
-        register_copy(state, vmx_state_.guest_state);
-        AutoVmcs vmcs(vmcs_page_.PhysicalAddress());
-        state->rsp = vmcs.Read(VmcsFieldXX::GUEST_RSP);
-        state->rflags = vmcs.Read(VmcsFieldXX::GUEST_RFLAGS) & X86_FLAGS_USER;
-        return ZX_OK;
-    }
-    }
-    return ZX_ERR_INVALID_ARGS;
-}
-
-zx_status_t Vcpu::WriteState(uint32_t kind, const void* buf, size_t len) {
-    if (!hypervisor::check_pinned_cpu_invariant(vpid_, thread_))
-        return ZX_ERR_BAD_STATE;
-    switch (kind) {
-    case ZX_VCPU_STATE: {
-        if (len != sizeof(zx_vcpu_state_t))
-            break;
-        auto state = static_cast<const zx_vcpu_state_t*>(buf);
-        register_copy(&vmx_state_.guest_state, *state);
-        AutoVmcs vmcs(vmcs_page_.PhysicalAddress());
-        vmcs.Write(VmcsFieldXX::GUEST_RSP, state->rsp);
-        if (state->rflags & X86_FLAGS_RESERVED_ONES) {
-            const uint64_t rflags = vmcs.Read(VmcsFieldXX::GUEST_RFLAGS);
-            const uint64_t user_flags = (rflags & ~X86_FLAGS_USER) |
-                                        (state->rflags & X86_FLAGS_USER);
-            vmcs.Write(VmcsFieldXX::GUEST_RFLAGS, user_flags);
-        }
-        return ZX_OK;
-    }
-    case ZX_VCPU_IO: {
-        if (len != sizeof(zx_vcpu_io_t))
-            break;
-        auto io = static_cast<const zx_vcpu_io_t*>(buf);
-        memcpy(&vmx_state_.guest_state.rax, io->data, io->access_size);
-        return ZX_OK;
-    }
-    }
-    return ZX_ERR_INVALID_ARGS;
-}
-
-bool cr0_is_invalid(AutoVmcs* vmcs, uint64_t cr0_value) {
-    uint64_t check_value = cr0_value;
-    // From Volume 3, Section 26.3.1.1: PE and PG bits of CR0 are not checked when unrestricted
-    // guest is enabled. Set both here to avoid clashing with X86_MSR_IA32_VMX_CR0_FIXED1.
-    if (vmcs->Read(VmcsField32::PROCBASED_CTLS2) & kProcbasedCtls2UnrestrictedGuest) {
-        check_value |= X86_CR0_PE | X86_CR0_PG;
-    }
-    return cr_is_invalid(check_value, X86_MSR_IA32_VMX_CR0_FIXED0, X86_MSR_IA32_VMX_CR0_FIXED1);
-}
diff --git a/kernel/arch/x86/hypervisor/vcpu_priv.h b/kernel/arch/x86/hypervisor/vcpu_priv.h
deleted file mode 100644
index 968c4ea..0000000
--- a/kernel/arch/x86/hypervisor/vcpu_priv.h
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <hypervisor/state_invalidator.h>
-
-// clang-format off
-
-#define X86_MSR_IA32_VMX_PINBASED_CTLS                  0x0481
-#define X86_MSR_IA32_VMX_PROCBASED_CTLS                 0x0482
-#define X86_MSR_IA32_VMX_EXIT_CTLS                      0x0483
-#define X86_MSR_IA32_VMX_ENTRY_CTLS                     0x0484
-#define X86_MSR_IA32_VMX_PROCBASED_CTLS2                0x048b
-#define X86_MSR_IA32_VMX_TRUE_PINBASED_CTLS             0x048d
-#define X86_MSR_IA32_VMX_TRUE_PROCBASED_CTLS            0x048e
-#define X86_MSR_IA32_VMX_TRUE_EXIT_CTLS                 0x048f
-#define X86_MSR_IA32_VMX_TRUE_ENTRY_CTLS                0x0490
-
-// PROCBASED_CTLS2 flags.
-static const uint32_t kProcbasedCtls2Ept                = 1u << 1;
-static const uint32_t kProcbasedCtls2Rdtscp             = 1u << 3;
-static const uint32_t kProcbasedCtls2x2Apic             = 1u << 4;
-static const uint32_t kProcbasedCtls2Vpid               = 1u << 5;
-static const uint32_t kProcbasedCtls2UnrestrictedGuest  = 1u << 7;
-static const uint32_t kProcbasedCtls2Invpcid            = 1u << 12;
-
-// PROCBASED_CTLS flags.
-static const uint32_t kProcbasedCtlsIntWindowExiting    = 1u << 2;
-static const uint32_t kProcbasedCtlsHltExiting          = 1u << 7;
-static const uint32_t kProcbasedCtlsCr3LoadExiting      = 1u << 15;
-static const uint32_t kProcbasedCtlsCr3StoreExiting     = 1u << 16;
-static const uint32_t kProcbasedCtlsCr8LoadExiting      = 1u << 19;
-static const uint32_t kProcbasedCtlsCr8StoreExiting     = 1u << 20;
-static const uint32_t kProcbasedCtlsTprShadow           = 1u << 21;
-static const uint32_t kProcbasedCtlsIoExiting           = 1u << 24;
-static const uint32_t kProcbasedCtlsMsrBitmaps          = 1u << 28;
-static const uint32_t kProcbasedCtlsPauseExiting        = 1u << 30;
-static const uint32_t kProcbasedCtlsProcbasedCtls2      = 1u << 31;
-
-// PINBASED_CTLS flags.
-static const uint32_t kPinbasedCtlsExtIntExiting        = 1u << 0;
-static const uint32_t kPinbasedCtlsNmiExiting           = 1u << 3;
-
-// EXIT_CTLS flags.
-static const uint32_t kExitCtls64bitMode                = 1u << 9;
-static const uint32_t kExitCtlsAckIntOnExit             = 1u << 15;
-static const uint32_t kExitCtlsSaveIa32Pat              = 1u << 18;
-static const uint32_t kExitCtlsLoadIa32Pat              = 1u << 19;
-static const uint32_t kExitCtlsSaveIa32Efer             = 1u << 20;
-static const uint32_t kExitCtlsLoadIa32Efer             = 1u << 21;
-
-// ENTRY_CTLS flags.
-static const uint32_t kEntryCtlsIa32eMode               = 1u << 9;
-static const uint32_t kEntryCtlsLoadIa32Pat             = 1u << 14;
-static const uint32_t kEntryCtlsLoadIa32Efer            = 1u << 15;
-
-// LINK_POINTER values.
-static const uint64_t kLinkPointerInvalidate            = UINT64_MAX;
-
-// GUEST_XX_ACCESS_RIGHTS flags.
-static const uint32_t kGuestXxAccessRightsUnusable      = 1u << 16;
-// See Volume 3, Section 24.4.1 for access rights format.
-static const uint32_t kGuestXxAccessRightsTypeA         = 1u << 0;
-static const uint32_t kGuestXxAccessRightsTypeW         = 1u << 1;
-static const uint32_t kGuestXxAccessRightsTypeE         = 1u << 2;
-static const uint32_t kGuestXxAccessRightsTypeCode      = 1u << 3;
-// See Volume 3, Section 3.4.5.1 for valid non-system selector types.
-static const uint32_t kGuestXxAccessRightsS             = 1u << 4;
-static const uint32_t kGuestXxAccessRightsP             = 1u << 7;
-static const uint32_t kGuestXxAccessRightsL             = 1u << 13;
-static const uint32_t kGuestXxAccessRightsD             = 1u << 14;
-// See Volume 3, Section 3.5 for valid system selectors types.
-static const uint32_t kGuestTrAccessRightsTssBusy16Bit  = 3u << 0;
-static const uint32_t kGuestTrAccessRightsTssBusy       = 11u << 0;
-
-static const uint32_t kGuestXxAccessRightsDefault       = kGuestXxAccessRightsTypeA |
-                                                          kGuestXxAccessRightsTypeW |
-                                                          kGuestXxAccessRightsS |
-                                                          kGuestXxAccessRightsP;
-
-// GUEST_INTERRUPTIBILITY_STATE flags.
-static const uint32_t kInterruptibilityStiBlocking      = 1u << 0;
-static const uint32_t kInterruptibilityMovSsBlocking    = 1u << 1;
-static const uint32_t kInterruptibilityNmiBlocking      = 1u << 3;
-
-// VMCS fields.
-enum class VmcsField16 : uint64_t {
-    VPID                                                = 0x0000,
-    GUEST_CS_SELECTOR                                   = 0x0802,
-    GUEST_TR_SELECTOR                                   = 0x080e,
-    HOST_ES_SELECTOR                                    = 0x0c00,
-    HOST_CS_SELECTOR                                    = 0x0c02,
-    HOST_SS_SELECTOR                                    = 0x0c04,
-    HOST_DS_SELECTOR                                    = 0x0c06,
-    HOST_FS_SELECTOR                                    = 0x0c08,
-    HOST_GS_SELECTOR                                    = 0x0c0a,
-    HOST_TR_SELECTOR                                    = 0x0c0c,
-};
-
-enum class VmcsField64 : uint64_t {
-    MSR_BITMAPS_ADDRESS                                 = 0x2004,
-    EXIT_MSR_STORE_ADDRESS                              = 0x2006,
-    EXIT_MSR_LOAD_ADDRESS                               = 0x2008,
-    ENTRY_MSR_LOAD_ADDRESS                              = 0x200a,
-    EPT_POINTER                                         = 0x201a,
-    GUEST_PHYSICAL_ADDRESS                              = 0x2400,
-    LINK_POINTER                                        = 0x2800,
-    GUEST_IA32_PAT                                      = 0x2804,
-    GUEST_IA32_EFER                                     = 0x2806,
-    HOST_IA32_PAT                                       = 0x2c00,
-    HOST_IA32_EFER                                      = 0x2c02,
-};
-
-enum class VmcsField32 : uint64_t {
-    PINBASED_CTLS                                       = 0x4000,
-    PROCBASED_CTLS                                      = 0x4002,
-    EXCEPTION_BITMAP                                    = 0x4004,
-    PAGEFAULT_ERRORCODE_MASK                            = 0x4006,
-    PAGEFAULT_ERRORCODE_MATCH                           = 0x4008,
-    EXIT_CTLS                                           = 0x400c,
-    EXIT_MSR_STORE_COUNT                                = 0x400e,
-    EXIT_MSR_LOAD_COUNT                                 = 0x4010,
-    ENTRY_CTLS                                          = 0x4012,
-    ENTRY_MSR_LOAD_COUNT                                = 0x4014,
-    ENTRY_INTERRUPTION_INFORMATION                      = 0x4016,
-    ENTRY_EXCEPTION_ERROR_CODE                          = 0x4018,
-    PROCBASED_CTLS2                                     = 0x401e,
-    INSTRUCTION_ERROR                                   = 0x4400,
-    EXIT_REASON                                         = 0x4402,
-    EXIT_INTERRUPTION_INFORMATION                       = 0x4404,
-    EXIT_INTERRUPTION_ERROR_CODE                        = 0x4406,
-    EXIT_INSTRUCTION_LENGTH                             = 0x440c,
-    EXIT_INSTRUCTION_INFORMATION                        = 0x440e,
-    HOST_IA32_SYSENTER_CS                               = 0x4c00,
-
-    GUEST_ES_LIMIT                                      = 0x4800,
-    GUEST_CS_LIMIT                                      = 0x4802,
-    GUEST_SS_LIMIT                                      = 0x4804,
-    GUEST_DS_LIMIT                                      = 0x4806,
-    GUEST_FS_LIMIT                                      = 0x4808,
-    GUEST_GS_LIMIT                                      = 0x480a,
-    GUEST_LDTR_LIMIT                                    = 0x480c,
-    GUEST_TR_LIMIT                                      = 0x480e,
-
-    GUEST_GDTR_LIMIT                                    = 0x4810,
-    GUEST_IDTR_LIMIT                                    = 0x4812,
-    GUEST_CS_ACCESS_RIGHTS                              = 0x4816,
-    GUEST_ES_ACCESS_RIGHTS                              = 0x4814,
-    GUEST_SS_ACCESS_RIGHTS                              = 0x4818,
-    GUEST_DS_ACCESS_RIGHTS                              = 0x481a,
-    GUEST_FS_ACCESS_RIGHTS                              = 0x481c,
-    GUEST_GS_ACCESS_RIGHTS                              = 0x481e,
-    GUEST_LDTR_ACCESS_RIGHTS                            = 0x4820,
-    GUEST_TR_ACCESS_RIGHTS                              = 0x4822,
-    GUEST_INTERRUPTIBILITY_STATE                        = 0x4824,
-    GUEST_ACTIVITY_STATE                                = 0x4826,
-    GUEST_IA32_SYSENTER_CS                              = 0x482a,
-};
-
-enum class VmcsFieldXX : uint64_t {
-    CR0_GUEST_HOST_MASK                                 = 0x6000,
-    CR4_GUEST_HOST_MASK                                 = 0x6002,
-    CR0_READ_SHADOW                                     = 0x6004,
-    CR4_READ_SHADOW                                     = 0x6006,
-    EXIT_QUALIFICATION                                  = 0x6400,
-    GUEST_LINEAR_ADDRESS                                = 0x640a,
-    GUEST_CR0                                           = 0x6800,
-    GUEST_CR3                                           = 0x6802,
-    GUEST_CR4                                           = 0x6804,
-
-    GUEST_ES_BASE                                       = 0x6806,
-    GUEST_CS_BASE                                       = 0x6808,
-    GUEST_SS_BASE                                       = 0x680A,
-    GUEST_DS_BASE                                       = 0x680C,
-    GUEST_FS_BASE                                       = 0x680E,
-    GUEST_GS_BASE                                       = 0x6810,
-    GUEST_TR_BASE                                       = 0x6814,
-
-    GUEST_GDTR_BASE                                     = 0x6816,
-    GUEST_IDTR_BASE                                     = 0x6818,
-    GUEST_RSP                                           = 0x681c,
-    GUEST_RIP                                           = 0x681e,
-    GUEST_RFLAGS                                        = 0x6820,
-    GUEST_PENDING_DEBUG_EXCEPTIONS                      = 0x6822,
-    GUEST_IA32_SYSENTER_ESP                             = 0x6824,
-    GUEST_IA32_SYSENTER_EIP                             = 0x6826,
-    HOST_CR0                                            = 0x6c00,
-    HOST_CR3                                            = 0x6c02,
-    HOST_CR4                                            = 0x6c04,
-    HOST_FS_BASE                                        = 0x6c06,
-    HOST_GS_BASE                                        = 0x6c08,
-    HOST_TR_BASE                                        = 0x6c0a,
-    HOST_GDTR_BASE                                      = 0x6c0c,
-    HOST_IDTR_BASE                                      = 0x6c0e,
-    HOST_IA32_SYSENTER_ESP                              = 0x6c10,
-    HOST_IA32_SYSENTER_EIP                              = 0x6c12,
-    HOST_RSP                                            = 0x6c14,
-    HOST_RIP                                            = 0x6c16,
-};
-
-// INVEPT invalidation types.
-enum class InvEpt : uint64_t {
-    SINGLE_CONTEXT                                      = 1,
-    ALL_CONTEXT                                         = 2,
-};
-
-// clang-format on
-
-// Loads a VMCS within a given scope.
-class AutoVmcs : public hypervisor::StateInvalidator {
-public:
-    AutoVmcs(paddr_t vmcs_address_);
-    ~AutoVmcs();
-
-    void Invalidate() override;
-    void InterruptWindowExiting(bool enable);
-    void IssueInterrupt(uint32_t vector);
-
-    uint16_t Read(VmcsField16 field) const;
-    uint32_t Read(VmcsField32 field) const;
-    uint64_t Read(VmcsField64 field) const;
-    uint64_t Read(VmcsFieldXX field) const;
-    void Write(VmcsField16 field, uint16_t val);
-    void Write(VmcsField32 field, uint32_t val);
-    void Write(VmcsField64 field, uint64_t val);
-    void Write(VmcsFieldXX field, uint64_t val);
-
-    zx_status_t SetControl(VmcsField32 controls, uint64_t true_msr, uint64_t old_msr, uint32_t set,
-                           uint32_t clear);
-
-private:
-    paddr_t vmcs_address_;
-};
-
-// Pins execution to a CPU within a given scope.
-class AutoPin {
-public:
-    AutoPin(uint16_t vpid);
-    ~AutoPin();
-
-private:
-    cpu_mask_t prev_cpu_mask_;
-    thread_t* thread_;
-};
-
-bool cr0_is_invalid(AutoVmcs* vmcs, uint64_t cr0_value);
diff --git a/kernel/arch/x86/hypervisor/vmexit.cpp b/kernel/arch/x86/hypervisor/vmexit.cpp
deleted file mode 100644
index 7c4ceec..0000000
--- a/kernel/arch/x86/hypervisor/vmexit.cpp
+++ /dev/null
@@ -1,1140 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include "vmexit_priv.h"
-
-#include <bits.h>
-#include <inttypes.h>
-#include <string.h>
-#include <trace.h>
-
-#include <arch/hypervisor.h>
-#include <arch/x86/apic.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/pvclock.h>
-#include <explicit-memory/bytes.h>
-#include <fbl/canary.h>
-#include <hypervisor/interrupt_tracker.h>
-#include <hypervisor/ktrace.h>
-#include <kernel/auto_lock.h>
-#include <lib/ktrace.h>
-#include <platform.h>
-#include <platform/pc/timer.h>
-#include <vm/fault.h>
-#include <vm/physmap.h>
-#include <vm/pmm.h>
-#include <zircon/syscalls/hypervisor.h>
-#include <zircon/time.h>
-#include <zircon/types.h>
-
-#include "pvclock_priv.h"
-#include "vcpu_priv.h"
-
-#define LOCAL_TRACE 0
-
-static constexpr uint64_t kLocalApicPhysBase =
-    APIC_PHYS_BASE | IA32_APIC_BASE_XAPIC_ENABLE | IA32_APIC_BASE_X2APIC_ENABLE;
-
-static constexpr uint64_t kX2ApicMsrBase = 0x800;
-static constexpr uint64_t kX2ApicMsrMax = 0x83f;
-
-static constexpr uint64_t kMiscEnableFastStrings = 1u << 0;
-
-static constexpr uint32_t kFirstExtendedStateComponent = 2;
-static constexpr uint32_t kLastExtendedStateComponent = 9;
-// From Volume 1, Section 13.4.
-static constexpr uint32_t kXsaveLegacyRegionSize = 512;
-static constexpr uint32_t kXsaveHeaderSize = 64;
-
-static constexpr char kHypVendorId[] = "KVMKVMKVM\0\0\0";
-static constexpr size_t kHypVendorIdLength = 12;
-static_assert(sizeof(kHypVendorId) - 1 == kHypVendorIdLength, "");
-
-static constexpr uint64_t kKvmFeatureNoIoDelay = 1u << 1;
-
-extern "C" void x86_call_external_interrupt_handler(uint64_t vector);
-
-ExitInfo::ExitInfo(const AutoVmcs& vmcs) {
-    // From Volume 3, Section 26.7.
-    uint32_t full_exit_reason = vmcs.Read(VmcsField32::EXIT_REASON);
-    entry_failure = BIT(full_exit_reason, 31);
-    exit_reason = static_cast<ExitReason>(BITS(full_exit_reason, 15, 0));
-
-    exit_qualification = vmcs.Read(VmcsFieldXX::EXIT_QUALIFICATION);
-    exit_instruction_length = vmcs.Read(VmcsField32::EXIT_INSTRUCTION_LENGTH);
-    guest_physical_address = vmcs.Read(VmcsField64::GUEST_PHYSICAL_ADDRESS);
-    guest_rip = vmcs.Read(VmcsFieldXX::GUEST_RIP);
-
-    if (exit_reason == ExitReason::EXTERNAL_INTERRUPT ||
-        exit_reason == ExitReason::IO_INSTRUCTION)
-        return;
-
-    LTRACEF("entry failure: %d\n", entry_failure);
-    LTRACEF("exit reason: %#x (%s)\n", static_cast<uint32_t>(exit_reason), exit_reason_name(exit_reason));
-    LTRACEF("exit qualification: %#lx\n", exit_qualification);
-    LTRACEF("exit instruction length: %#x\n", exit_instruction_length);
-    LTRACEF("guest activity state: %#x\n", vmcs.Read(VmcsField32::GUEST_ACTIVITY_STATE));
-    LTRACEF("guest interruptibility state: %#x\n",
-            vmcs.Read(VmcsField32::GUEST_INTERRUPTIBILITY_STATE));
-    LTRACEF("guest physical address: %#lx\n", guest_physical_address);
-    LTRACEF("guest linear address: %#lx\n", vmcs.Read(VmcsFieldXX::GUEST_LINEAR_ADDRESS));
-    LTRACEF("guest rip: %#lx\n", guest_rip);
-}
-
-ExitInterruptionInformation::ExitInterruptionInformation(const AutoVmcs& vmcs) {
-    uint32_t int_info = vmcs.Read(VmcsField32::EXIT_INTERRUPTION_INFORMATION);
-    vector = static_cast<uint8_t>(BITS(int_info, 7, 0));
-    interruption_type = static_cast<InterruptionType>(BITS_SHIFT(int_info, 10, 8));
-    valid = BIT(int_info, 31);
-};
-
-CrAccessInfo::CrAccessInfo(uint64_t qualification) {
-    // From Volume 3, Table 27-3.
-    cr_number = static_cast<uint8_t>(BITS(qualification, 3, 0));
-    access_type = static_cast<CrAccessType>(BITS_SHIFT(qualification, 5, 4));
-    reg = static_cast<uint8_t>(BITS_SHIFT(qualification, 11, 8));
-}
-
-IoInfo::IoInfo(uint64_t qualification) {
-    access_size = static_cast<uint8_t>(BITS(qualification, 2, 0) + 1);
-    input = BIT_SHIFT(qualification, 3);
-    string = BIT_SHIFT(qualification, 4);
-    repeat = BIT_SHIFT(qualification, 5);
-    port = static_cast<uint16_t>(BITS_SHIFT(qualification, 31, 16));
-}
-
-EptViolationInfo::EptViolationInfo(uint64_t qualification) {
-    // From Volume 3C, Table 27-7.
-    read = BIT(qualification, 0);
-    write = BIT(qualification, 1);
-    instruction = BIT(qualification, 2);
-}
-
-InterruptCommandRegister::InterruptCommandRegister(uint32_t hi, uint32_t lo) {
-    destination = hi;
-    destination_mode = static_cast<InterruptDestinationMode>(BIT_SHIFT(lo, 11));
-    delivery_mode = static_cast<InterruptDeliveryMode>(BITS_SHIFT(lo, 10, 8));
-    destination_shorthand = static_cast<InterruptDestinationShorthand>(BITS_SHIFT(lo, 19, 18));
-    vector = static_cast<uint8_t>(BITS(lo, 7, 0));
-}
-
-VmCallInfo::VmCallInfo(const GuestState* guest_state) {
-    // ABI is documented in Linux kernel documentation, see
-    // Documents/virtual/kvm/hypercalls.txt
-    type = static_cast<VmCallType>(guest_state->rax);
-    arg[0] = guest_state->rbx;
-    arg[1] = guest_state->rcx;
-    arg[2] = guest_state->rdx;
-    arg[3] = guest_state->rsi;
-}
-
-static void next_rip(const ExitInfo& exit_info, AutoVmcs* vmcs) {
-    vmcs->Write(VmcsFieldXX::GUEST_RIP, exit_info.guest_rip + exit_info.exit_instruction_length);
-
-    // Clear any flags blocking interrupt injection for a single instruction.
-    uint32_t guest_interruptibility = vmcs->Read(VmcsField32::GUEST_INTERRUPTIBILITY_STATE);
-    uint32_t new_interruptibility = guest_interruptibility &
-                                    ~(kInterruptibilityStiBlocking | kInterruptibilityMovSsBlocking);
-    if (new_interruptibility != guest_interruptibility) {
-        vmcs->Write(VmcsField32::GUEST_INTERRUPTIBILITY_STATE, new_interruptibility);
-    }
-}
-
-static zx_status_t handle_external_interrupt(AutoVmcs* vmcs) {
-    ExitInterruptionInformation int_info(*vmcs);
-    DEBUG_ASSERT(int_info.valid);
-    DEBUG_ASSERT(int_info.interruption_type == InterruptionType::EXTERNAL_INTERRUPT);
-    vmcs->Invalidate();
-    x86_call_external_interrupt_handler(int_info.vector);
-
-    // If we are receiving an external interrupt because the thread is being
-    // killed, we should exit with an error.
-    return get_current_thread()->signals & THREAD_SIGNAL_KILL ? ZX_ERR_CANCELED : ZX_OK;
-}
-
-static zx_status_t handle_interrupt_window(AutoVmcs* vmcs, LocalApicState* local_apic_state) {
-    vmcs->InterruptWindowExiting(false);
-    return ZX_OK;
-}
-
-// From Volume 2, Section 3.2, Table 3-8  "Processor Extended State Enumeration
-// Main Leaf (EAX = 0DH, ECX = 0)".
-//
-// Bits 31-00: Maximum size (bytes, from the beginning of the XSAVE/XRSTOR save
-// area) required by enabled features in XCR0. May be different than ECX if some
-// features at the end of the XSAVE save area are not enabled.
-static zx_status_t compute_xsave_size(uint64_t guest_xcr0, uint32_t* xsave_size) {
-    *xsave_size = kXsaveLegacyRegionSize + kXsaveHeaderSize;
-    for (uint32_t i = kFirstExtendedStateComponent; i <= kLastExtendedStateComponent; ++i) {
-        cpuid_leaf leaf;
-        if (!(guest_xcr0 & (1 << i)))
-            continue;
-        if (!x86_get_cpuid_subleaf(X86_CPUID_XSAVE, i, &leaf))
-            return ZX_ERR_INTERNAL;
-        if (leaf.a == 0 && leaf.b == 0 && leaf.c == 0 && leaf.d == 0)
-            continue;
-        const uint32_t component_offset = leaf.b;
-        const uint32_t component_size = leaf.a;
-        *xsave_size = component_offset + component_size;
-    }
-    return ZX_OK;
-}
-
-static zx_status_t handle_cpuid(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                GuestState* guest_state) {
-    const uint32_t leaf = static_cast<uint32_t>(guest_state->rax);
-    const uint32_t subleaf = static_cast<uint32_t>(guest_state->rcx);
-
-    next_rip(exit_info, vmcs);
-    switch (leaf) {
-    case X86_CPUID_BASE:
-    case X86_CPUID_EXT_BASE:
-        cpuid(leaf,
-              reinterpret_cast<uint32_t*>(&guest_state->rax),
-              reinterpret_cast<uint32_t*>(&guest_state->rbx),
-              reinterpret_cast<uint32_t*>(&guest_state->rcx),
-              reinterpret_cast<uint32_t*>(&guest_state->rdx));
-        return ZX_OK;
-    case X86_CPUID_BASE + 1 ... MAX_SUPPORTED_CPUID:
-    case X86_CPUID_EXT_BASE + 1 ... MAX_SUPPORTED_CPUID_EXT:
-        cpuid_c(leaf, subleaf,
-                reinterpret_cast<uint32_t*>(&guest_state->rax),
-                reinterpret_cast<uint32_t*>(&guest_state->rbx),
-                reinterpret_cast<uint32_t*>(&guest_state->rcx),
-                reinterpret_cast<uint32_t*>(&guest_state->rdx));
-        switch (leaf) {
-        case X86_CPUID_MODEL_FEATURES:
-            // Override the initial local APIC ID. From Vol 2, Table 3-8.
-            guest_state->rbx &= ~(0xff << 24);
-            guest_state->rbx |= (vmcs->Read(VmcsField16::VPID) - 1) << 24;
-            // Enable the hypervisor bit.
-            guest_state->rcx |= 1u << X86_FEATURE_HYPERVISOR.bit;
-            // Enable the x2APIC bit.
-            guest_state->rcx |= 1u << X86_FEATURE_X2APIC.bit;
-            // Disable the VMX bit.
-            guest_state->rcx &= ~(1u << X86_FEATURE_VMX.bit);
-            // Disable the PDCM bit.
-            guest_state->rcx &= ~(1u << X86_FEATURE_PDCM.bit);
-            // Disable MONITOR/MWAIT.
-            guest_state->rcx &= ~(1u << X86_FEATURE_MON.bit);
-            // Disable THERM_INTERRUPT and THERM_STATUS MSRs
-            guest_state->rcx &= ~(1u << X86_FEATURE_TM2.bit);
-            // Enable the SEP (SYSENTER support).
-            guest_state->rdx |= 1u << X86_FEATURE_SEP.bit;
-            // Disable the Thermal Monitor bit.
-            guest_state->rdx &= ~(1u << X86_FEATURE_TM.bit);
-            // Disable the THERM_CONTROL_MSR bit.
-            guest_state->rdx &= ~(1u << X86_FEATURE_ACPI.bit);
-            break;
-        case X86_CPUID_TOPOLOGY:
-            guest_state->rdx = vmcs->Read(VmcsField16::VPID) - 1;
-            break;
-        case X86_CPUID_XSAVE:
-            if (subleaf == 0) {
-                uint32_t xsave_size = 0;
-                zx_status_t status = compute_xsave_size(guest_state->xcr0, &xsave_size);
-                if (status != ZX_OK)
-                    return status;
-                guest_state->rbx = xsave_size;
-            } else if (subleaf == 1) {
-                guest_state->rax &= ~(1u << 3);
-            }
-            break;
-        case X86_CPUID_THERMAL_AND_POWER:
-            // Disable the performance energy bias bit.
-            guest_state->rcx &= ~(1u << X86_FEATURE_PERF_BIAS.bit);
-            // Disable the hardware coordination feedback bit.
-            guest_state->rcx &= ~(1u << X86_FEATURE_HW_FEEDBACK.bit);
-            guest_state->rax &= ~(
-                // Disable Digital Thermal Sensor
-                1u << X86_FEATURE_DTS.bit |
-                // Disable Package Thermal Status MSR.
-                1u << X86_FEATURE_PTM.bit |
-                // Disable THERM_STATUS MSR bits 10/11 & THERM_INTERRUPT MSR bit 24
-                1u << X86_FEATURE_PTM.bit |
-                // Disable HWP MSRs.
-                1u << X86_FEATURE_HWP.bit |
-                1u << X86_FEATURE_HWP_NOT.bit |
-                1u << X86_FEATURE_HWP_ACT.bit |
-                1u << X86_FEATURE_HWP_PREF.bit);
-            break;
-        case X86_CPUID_PERFORMANCE_MONITORING: {
-            // Disable all performance monitoring.
-            // 31-07 = Reserved 0, 06-00 = 1 if event is not available.
-            const uint32_t performance_monitoring_no_events = 0b1111111;
-            guest_state->rax = 0;
-            guest_state->rbx = performance_monitoring_no_events;
-            guest_state->rcx = 0;
-            guest_state->rdx = 0;
-            break;
-        }
-        case X86_CPUID_MON:
-            // MONITOR/MWAIT are not implemented.
-            guest_state->rax = 0;
-            guest_state->rbx = 0;
-            guest_state->rcx = 0;
-            guest_state->rdx = 0;
-            break;
-        case X86_CPUID_EXTENDED_FEATURE_FLAGS:
-            // It's possible when running under KVM in nVMX mode, that host
-            // CPUID indicates that invpcid is supported but VMX doesn't allow
-            // to enable INVPCID bit in secondary processor based controls.
-            // Therefore explicitly clear INVPCID bit in CPUID if the VMX flag
-            // wasn't set.
-            if ((vmcs->Read(VmcsField32::PROCBASED_CTLS2) & kProcbasedCtls2Invpcid) == 0)
-                guest_state->rbx &= ~(1u << X86_FEATURE_INVPCID.bit);
-            // Disable the Processor Trace bit.
-            guest_state->rbx &= ~(1u << X86_FEATURE_PT.bit);
-            // Disable:
-            //  * Indirect Branch Prediction Barrier bit
-            //  * Single Thread Indirect Branch Predictors bit
-            //  * Speculative Store Bypass Disable bit
-            // These imply support for the IA32_SPEC_CTRL and IA32_PRED_CMD
-            // MSRs, which are not implemented.
-            guest_state->rdx &= ~(
-                1u << X86_FEATURE_IBRS_IBPB.bit |
-                1u << X86_FEATURE_STIBP.bit |
-                1u << X86_FEATURE_SSBD.bit);
-            break;
-        }
-        return ZX_OK;
-    case X86_CPUID_HYP_VENDOR: {
-        // This leaf is commonly used to identify a hypervisor via ebx:ecx:edx.
-        static const uint32_t* regs = reinterpret_cast<const uint32_t*>(kHypVendorId);
-        // Since Zircon hypervisor disguises itself as KVM, it needs to return
-        // in EAX max CPUID function supported by hypervisor. Zero in EAX
-        // should be interpreted as 0x40000001. Details are available in the
-        // Linux kernel documentation (Documentation/virtual/kvm/cpuid.txt).
-        guest_state->rax = X86_CPUID_KVM_FEATURES;
-        guest_state->rbx = regs[0];
-        guest_state->rcx = regs[1];
-        guest_state->rdx = regs[2];
-        return ZX_OK;
-    }
-    case X86_CPUID_KVM_FEATURES:
-        // We support KVM clock.
-        guest_state->rax =
-            kKvmFeatureClockSourceOld | kKvmFeatureClockSource | kKvmFeatureNoIoDelay;
-        guest_state->rbx = 0;
-        guest_state->rcx = 0;
-        guest_state->rdx = 0;
-        return ZX_OK;
-    // From Volume 2A, CPUID instruction reference. If the EAX value is outside
-    // the range recognized by CPUID then the information for the highest
-    // supported base information leaf is returned. Any value in ECX is
-    // honored.
-    default:
-        cpuid_c(MAX_SUPPORTED_CPUID, subleaf,
-                reinterpret_cast<uint32_t*>(&guest_state->rax),
-                reinterpret_cast<uint32_t*>(&guest_state->rbx),
-                reinterpret_cast<uint32_t*>(&guest_state->rcx),
-                reinterpret_cast<uint32_t*>(&guest_state->rdx));
-        return ZX_OK;
-    }
-}
-
-static zx_status_t handle_hlt(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                              LocalApicState* local_apic_state) {
-    next_rip(exit_info, vmcs);
-    return local_apic_state->interrupt_tracker.Wait(ZX_TIME_INFINITE, vmcs);
-}
-
-static zx_status_t handle_cr0_write(AutoVmcs* vmcs, GuestState* guest_state, uint64_t val) {
-    // Ensure that CR0.NE is set since it is set in X86_MSR_IA32_VMX_CR0_FIXED1.
-    uint64_t cr0 = val | X86_CR0_NE;
-    if (cr0_is_invalid(vmcs, cr0)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    vmcs->Write(VmcsFieldXX::GUEST_CR0, cr0);
-    // From Volume 3, Section 26.3.1.1: If CR0.PG and EFER.LME are set then EFER.LMA and the IA-32e
-    // mode guest entry control must also be set.
-    uint64_t efer = vmcs->Read(VmcsField64::GUEST_IA32_EFER);
-    if (!(efer & X86_EFER_LME && cr0 & X86_CR0_PG)) {
-        return ZX_OK;
-    }
-    vmcs->Write(VmcsField64::GUEST_IA32_EFER, efer | X86_EFER_LMA);
-    return vmcs->SetControl(VmcsField32::ENTRY_CTLS,
-                            read_msr(X86_MSR_IA32_VMX_TRUE_ENTRY_CTLS),
-                            read_msr(X86_MSR_IA32_VMX_ENTRY_CTLS),
-                            kEntryCtlsIa32eMode, 0);
-}
-
-static zx_status_t register_value(AutoVmcs* vmcs, GuestState* guest_state, uint8_t register_id,
-                                  uint64_t* out) {
-    switch (register_id) {
-    // From Intel Volume 3, Table 27-3.
-    case 0:
-        *out = guest_state->rax;
-        return ZX_OK;
-    case 1:
-        *out = guest_state->rcx;
-        return ZX_OK;
-    case 2:
-        *out = guest_state->rdx;
-        return ZX_OK;
-    case 3:
-        *out = guest_state->rbx;
-        return ZX_OK;
-    case 4:
-        *out = vmcs->Read(VmcsFieldXX::GUEST_RSP);
-        return ZX_OK;
-    case 5:
-        *out = guest_state->rbp;
-        return ZX_OK;
-    case 6:
-        *out = guest_state->rsi;
-        return ZX_OK;
-    case 7:
-        *out = guest_state->rdi;
-        return ZX_OK;
-    case 8:
-        *out = guest_state->r8;
-        return ZX_OK;
-    case 9:
-        *out = guest_state->r9;
-        return ZX_OK;
-    case 10:
-        *out = guest_state->r10;
-        return ZX_OK;
-    case 11:
-        *out = guest_state->r11;
-        return ZX_OK;
-    case 12:
-        *out = guest_state->r12;
-        return ZX_OK;
-    case 13:
-        *out = guest_state->r13;
-        return ZX_OK;
-    case 14:
-        *out = guest_state->r14;
-        return ZX_OK;
-    case 15:
-        *out = guest_state->r15;
-        return ZX_OK;
-    default:
-        return ZX_ERR_INVALID_ARGS;
-    }
-}
-
-static zx_status_t handle_control_register_access(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                                  GuestState* guest_state) {
-    CrAccessInfo cr_access_info(exit_info.exit_qualification);
-    switch (cr_access_info.access_type) {
-    case CrAccessType::MOV_TO_CR: {
-        // Handle CR0 only.
-        if (cr_access_info.cr_number != 0) {
-            return ZX_ERR_NOT_SUPPORTED;
-        }
-        uint64_t val;
-        zx_status_t status = register_value(vmcs, guest_state, cr_access_info.reg, &val);
-        if (status != ZX_OK) {
-            return status;
-        }
-        status = handle_cr0_write(vmcs, guest_state, val);
-        if (status != ZX_OK) {
-            return status;
-        }
-        next_rip(exit_info, vmcs);
-        return ZX_OK;
-    }
-    default:
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-}
-
-static zx_status_t handle_io_instruction(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                         GuestState* guest_state, hypervisor::TrapMap* traps,
-                                         zx_port_packet_t* packet) {
-    IoInfo io_info(exit_info.exit_qualification);
-    if (io_info.string || io_info.repeat) {
-        dprintf(CRITICAL, "Unsupported IO instruction\n");
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-
-    hypervisor::Trap* trap;
-    zx_status_t status = traps->FindTrap(ZX_GUEST_TRAP_IO, io_info.port, &trap);
-    if (status != ZX_OK) {
-        dprintf(CRITICAL, "Unhandled IO port %s %#x\n",
-                io_info.input ? "in" : "out", io_info.port);
-        return status;
-    }
-    next_rip(exit_info, vmcs);
-
-    memset(packet, 0, sizeof(*packet));
-    packet->key = trap->key();
-    packet->type = ZX_PKT_TYPE_GUEST_IO;
-    packet->guest_io.port = io_info.port;
-    packet->guest_io.access_size = io_info.access_size;
-    packet->guest_io.input = io_info.input;
-    if (io_info.input) {
-        // From Volume 1, Section 3.4.1.1: 32-bit operands generate a 32-bit
-        // result, zero-extended to a 64-bit result in the destination general-
-        // purpose register.
-        if (io_info.access_size == 4)
-            guest_state->rax = 0;
-    } else {
-        memcpy(packet->guest_io.data, &guest_state->rax, io_info.access_size);
-        if (trap->HasPort())
-            return trap->Queue(*packet, vmcs);
-        // If there was no port for the range, then return to user-space.
-    }
-
-    return ZX_ERR_NEXT;
-}
-
-static zx_status_t handle_apic_rdmsr(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                     GuestState* guest_state, LocalApicState* local_apic_state) {
-    switch (static_cast<X2ApicMsr>(guest_state->rcx)) {
-    case X2ApicMsr::ID:
-        next_rip(exit_info, vmcs);
-        guest_state->rax = vmcs->Read(VmcsField16::VPID) - 1;
-        return ZX_OK;
-    case X2ApicMsr::VERSION: {
-        next_rip(exit_info, vmcs);
-        // We choose 15H as it causes us to be seen as a modern APIC by Linux,
-        // and is the highest non-reserved value. See Volume 3 Section 10.4.8.
-        const uint32_t version = 0x15;
-        const uint32_t max_lvt_entry = 0x6; // LVT entries minus 1.
-        const uint32_t eoi_suppression = 0; // Disable support for EOI-broadcast suppression.
-        guest_state->rax = version | (max_lvt_entry << 16) | (eoi_suppression << 24);
-        return ZX_OK;
-    }
-    case X2ApicMsr::SVR:
-        // Spurious interrupt vector resets to 0xff. See Volume 3 Section 10.12.5.1.
-        next_rip(exit_info, vmcs);
-        guest_state->rax = 0xff;
-        return ZX_OK;
-    case X2ApicMsr::TPR:
-    case X2ApicMsr::LDR:
-    case X2ApicMsr::ISR_31_0... X2ApicMsr::ISR_255_224:
-    case X2ApicMsr::TMR_31_0... X2ApicMsr::TMR_255_224:
-    case X2ApicMsr::IRR_31_0... X2ApicMsr::IRR_255_224:
-    case X2ApicMsr::ESR:
-    case X2ApicMsr::LVT_MONITOR:
-        // These registers reset to 0. See Volume 3 Section 10.12.5.1.
-        next_rip(exit_info, vmcs);
-        guest_state->rax = 0;
-        return ZX_OK;
-    case X2ApicMsr::LVT_LINT0:
-    case X2ApicMsr::LVT_LINT1:
-    case X2ApicMsr::LVT_THERMAL_SENSOR:
-    case X2ApicMsr::LVT_CMCI:
-        // LVT registers reset with the mask bit set. See Volume 3 Section 10.12.5.1.
-        next_rip(exit_info, vmcs);
-        guest_state->rax = LVT_MASKED;
-        return ZX_OK;
-    case X2ApicMsr::LVT_TIMER:
-        next_rip(exit_info, vmcs);
-        guest_state->rax = local_apic_state->lvt_timer;
-        return ZX_OK;
-    default:
-        // Issue a general protection fault for write only and unimplemented
-        // registers.
-        dprintf(INFO, "Unhandled x2APIC rdmsr %#lx\n", guest_state->rcx);
-        local_apic_state->interrupt_tracker.VirtualInterrupt(X86_INT_GP_FAULT);
-        return ZX_OK;
-    }
-}
-
-static zx_status_t handle_rdmsr(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                GuestState* guest_state, LocalApicState* local_apic_state) {
-    // On execution of rdmsr, rcx specifies the MSR and the value is loaded into edx:eax.
-    switch (static_cast<uint32_t>(guest_state->rcx)) {
-    case X86_MSR_IA32_APIC_BASE:
-        next_rip(exit_info, vmcs);
-        guest_state->rax = kLocalApicPhysBase;
-        if (vmcs->Read(VmcsField16::VPID) == 1)
-            guest_state->rax |= IA32_APIC_BASE_BSP;
-        guest_state->rdx = 0;
-        return ZX_OK;
-    // From Volume 4, Section 2.1, Table 2-2: For now, only enable fast strings.
-    case X86_MSR_IA32_MISC_ENABLE:
-        next_rip(exit_info, vmcs);
-        guest_state->rax = read_msr(X86_MSR_IA32_MISC_ENABLE) & kMiscEnableFastStrings;
-        guest_state->rdx = 0;
-        return ZX_OK;
-    case X86_MSR_DRAM_ENERGY_STATUS:
-    case X86_MSR_DRAM_POWER_LIMIT:
-    // From Volume 3, Section 28.2.6.2: The MTRRs have no effect on the memory
-    // type used for an access to a guest-physical address.
-    case X86_MSR_IA32_MTRRCAP:
-    case X86_MSR_IA32_MTRR_DEF_TYPE:
-    case X86_MSR_IA32_MTRR_FIX64K_00000:
-    case X86_MSR_IA32_MTRR_FIX16K_80000... X86_MSR_IA32_MTRR_FIX16K_A0000:
-    case X86_MSR_IA32_MTRR_FIX4K_C0000... X86_MSR_IA32_MTRR_FIX4K_F8000:
-    case X86_MSR_IA32_MTRR_PHYSBASE0... X86_MSR_IA32_MTRR_PHYSMASK9:
-    // From Volume 3, Section 9.11.4: For now, 0.
-    case X86_MSR_IA32_PLATFORM_ID:
-    // From Volume 3, Section 9.11.7: 0 indicates no microcode update is loaded.
-    case X86_MSR_IA32_BIOS_SIGN_ID:
-    // From Volume 3, Section 15.3.1: 0 indicates that our machine has no
-    // checking capabilities.
-    case X86_MSR_IA32_MCG_CAP:
-    case X86_MSR_IA32_MCG_STATUS:
-    case X86_MSR_IA32_TEMPERATURE_TARGET:
-    case X86_MSR_PKG_ENERGY_STATUS:
-    case X86_MSR_PLATFORM_ENERGY_COUNTER:
-    case X86_MSR_PLATFORM_POWER_LIMIT:
-    case X86_MSR_PP0_ENERGY_STATUS:
-    case X86_MSR_PP0_POWER_LIMIT:
-    case X86_MSR_PP1_ENERGY_STATUS:
-    case X86_MSR_PP1_POWER_LIMIT:
-    case X86_MSR_RAPL_POWER_UNIT:
-        next_rip(exit_info, vmcs);
-        guest_state->rax = 0;
-        guest_state->rdx = 0;
-        return ZX_OK;
-    case kX2ApicMsrBase... kX2ApicMsrMax:
-        return handle_apic_rdmsr(exit_info, vmcs, guest_state, local_apic_state);
-    default:
-        dprintf(INFO, "Unhandled rdmsr %#lx\n", guest_state->rcx);
-        local_apic_state->interrupt_tracker.VirtualInterrupt(X86_INT_GP_FAULT);
-        return ZX_OK;
-    }
-}
-
-zx_time_t lvt_deadline(LocalApicState* local_apic_state) {
-    if ((local_apic_state->lvt_timer & LVT_TIMER_MODE_MASK) != LVT_TIMER_MODE_ONESHOT &&
-        (local_apic_state->lvt_timer & LVT_TIMER_MODE_MASK) != LVT_TIMER_MODE_PERIODIC) {
-        return 0;
-    }
-    uint32_t shift = BITS_SHIFT(local_apic_state->lvt_divide_config, 1, 0) |
-                     (BIT_SHIFT(local_apic_state->lvt_divide_config, 3) << 2);
-    uint32_t divisor_shift = (shift + 1) & 7;
-    zx_duration_t duration = ticks_to_nanos(local_apic_state->lvt_initial_count << divisor_shift);
-    return zx_time_add_duration(current_time(), duration);
-}
-
-static void update_timer(LocalApicState* local_apic_state, zx_time_t deadline);
-
-static void deadline_callback(timer_t* timer, zx_time_t now, void* arg) {
-    LocalApicState* local_apic_state = static_cast<LocalApicState*>(arg);
-    if (local_apic_state->lvt_timer & LVT_MASKED) {
-        return;
-    }
-    if ((local_apic_state->lvt_timer & LVT_TIMER_MODE_MASK) == LVT_TIMER_MODE_PERIODIC) {
-        update_timer(local_apic_state, lvt_deadline(local_apic_state));
-    }
-    uint8_t vector = local_apic_state->lvt_timer & LVT_TIMER_VECTOR_MASK;
-    local_apic_state->interrupt_tracker.VirtualInterrupt(vector);
-}
-
-static void update_timer(LocalApicState* local_apic_state, zx_time_t deadline) {
-    timer_cancel(&local_apic_state->timer);
-    if (deadline > 0) {
-        timer_set_oneshot(&local_apic_state->timer, deadline, deadline_callback, local_apic_state);
-    }
-}
-
-static uint64_t ipi_target_mask(const InterruptCommandRegister& icr, uint16_t self) {
-    switch (icr.destination_shorthand) {
-    case InterruptDestinationShorthand::NO_SHORTHAND:
-        return 1u << icr.destination;
-    case InterruptDestinationShorthand::SELF:
-        return 1u << (self - 1);
-    case InterruptDestinationShorthand::ALL_INCLUDING_SELF:
-        return UINT64_MAX;
-    case InterruptDestinationShorthand::ALL_EXCLUDING_SELF:
-        return ~(1u << (self - 1));
-    }
-    return 0;
-}
-
-static zx_status_t handle_ipi(const ExitInfo& exit_info, AutoVmcs* vmcs, GuestState* guest_state,
-                              zx_port_packet* packet) {
-    if (guest_state->rax > UINT32_MAX || guest_state->rdx > UINT32_MAX)
-        return ZX_ERR_INVALID_ARGS;
-    InterruptCommandRegister icr(static_cast<uint32_t>(guest_state->rdx),
-                                 static_cast<uint32_t>(guest_state->rax));
-    if (icr.destination_mode == InterruptDestinationMode::LOGICAL) {
-        dprintf(CRITICAL, "Logical IPI destination mode is not supported\n");
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-    switch (icr.delivery_mode) {
-    case InterruptDeliveryMode::FIXED: {
-        uint16_t self = static_cast<uint16_t>(vmcs->Read(VmcsField16::VPID) - 1);
-        memset(packet, 0, sizeof(*packet));
-        packet->type = ZX_PKT_TYPE_GUEST_VCPU;
-        packet->guest_vcpu.type = ZX_PKT_GUEST_VCPU_INTERRUPT;
-        packet->guest_vcpu.interrupt.mask = ipi_target_mask(icr, self);
-        packet->guest_vcpu.interrupt.vector = icr.vector;
-        next_rip(exit_info, vmcs);
-        return ZX_ERR_NEXT;
-    }
-    case InterruptDeliveryMode::INIT:
-        // Ignore INIT IPIs, we only need STARTUP to bring up a VCPU.
-        next_rip(exit_info, vmcs);
-        return ZX_OK;
-    case InterruptDeliveryMode::STARTUP:
-        memset(packet, 0, sizeof(*packet));
-        packet->type = ZX_PKT_TYPE_GUEST_VCPU;
-        packet->guest_vcpu.type = ZX_PKT_GUEST_VCPU_STARTUP;
-        packet->guest_vcpu.startup.id = icr.destination;
-        packet->guest_vcpu.startup.entry = icr.vector << 12;
-        next_rip(exit_info, vmcs);
-        return ZX_ERR_NEXT;
-    default:
-        dprintf(CRITICAL, "Unsupported IPI delivery mode %#x\n",
-                static_cast<uint8_t>(icr.delivery_mode));
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-}
-
-static zx_status_t handle_apic_wrmsr(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                     GuestState* guest_state, LocalApicState* local_apic_state,
-                                     zx_port_packet* packet) {
-    switch (static_cast<X2ApicMsr>(guest_state->rcx)) {
-    case X2ApicMsr::EOI:
-    case X2ApicMsr::ESR:
-        if (guest_state->rax != 0) {
-            // Non-zero writes to EOI and ESR cause GP fault. See Volume 3 Section 10.12.1.2.
-            local_apic_state->interrupt_tracker.VirtualInterrupt(X86_INT_GP_FAULT);
-            return ZX_OK;
-        }
-        __FALLTHROUGH;
-    case X2ApicMsr::TPR:
-    case X2ApicMsr::SVR:
-    case X2ApicMsr::LVT_MONITOR:
-    case X2ApicMsr::LVT_ERROR:
-    case X2ApicMsr::LVT_LINT0:
-    case X2ApicMsr::LVT_LINT1:
-    case X2ApicMsr::LVT_THERMAL_SENSOR:
-    case X2ApicMsr::LVT_CMCI:
-        if (guest_state->rdx != 0 || guest_state->rax > UINT32_MAX)
-            return ZX_ERR_INVALID_ARGS;
-        next_rip(exit_info, vmcs);
-        return ZX_OK;
-    case X2ApicMsr::LVT_TIMER:
-        if (guest_state->rax > UINT32_MAX)
-            return ZX_ERR_INVALID_ARGS;
-        if ((guest_state->rax & LVT_TIMER_MODE_MASK) == LVT_TIMER_MODE_RESERVED)
-            return ZX_ERR_INVALID_ARGS;
-        next_rip(exit_info, vmcs);
-        local_apic_state->lvt_timer = static_cast<uint32_t>(guest_state->rax);
-        update_timer(local_apic_state, lvt_deadline(local_apic_state));
-        return ZX_OK;
-    case X2ApicMsr::INITIAL_COUNT:
-        if (guest_state->rax > UINT32_MAX)
-            return ZX_ERR_INVALID_ARGS;
-        next_rip(exit_info, vmcs);
-        local_apic_state->lvt_initial_count = static_cast<uint32_t>(guest_state->rax);
-        update_timer(local_apic_state, lvt_deadline(local_apic_state));
-        return ZX_OK;
-    case X2ApicMsr::DCR:
-        if (guest_state->rax > UINT32_MAX)
-            return ZX_ERR_INVALID_ARGS;
-        next_rip(exit_info, vmcs);
-        local_apic_state->lvt_divide_config = static_cast<uint32_t>(guest_state->rax);
-        update_timer(local_apic_state, lvt_deadline(local_apic_state));
-        return ZX_OK;
-    case X2ApicMsr::SELF_IPI: {
-        next_rip(exit_info, vmcs);
-        uint32_t vector = static_cast<uint32_t>(guest_state->rax) & UINT8_MAX;
-        local_apic_state->interrupt_tracker.VirtualInterrupt(vector);
-        return ZX_OK;
-    }
-    case X2ApicMsr::ICR:
-        return handle_ipi(exit_info, vmcs, guest_state, packet);
-    default:
-        // Issue a general protection fault for read only and unimplemented
-        // registers.
-        dprintf(INFO, "Unhandled x2APIC wrmsr %#lx\n", guest_state->rcx);
-        local_apic_state->interrupt_tracker.VirtualInterrupt(X86_INT_GP_FAULT);
-        return ZX_OK;
-    }
-}
-
-static zx_status_t handle_kvm_wrmsr(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                    GuestState* guest_state, LocalApicState* local_apic_state,
-                                    PvClockState* pvclock,
-                                    hypervisor::GuestPhysicalAddressSpace* gpas) {
-    zx_paddr_t guest_paddr = BITS(guest_state->rax, 31, 0) | (BITS(guest_state->rdx, 31, 0) << 32);
-
-    next_rip(exit_info, vmcs);
-    switch (static_cast<uint32_t>(guest_state->rcx)) {
-    case kKvmSystemTimeMsrOld:
-    case kKvmSystemTimeMsr:
-        vmcs->Invalidate();
-        if ((guest_paddr & 1) != 0)
-            return pvclock_reset_clock(pvclock, gpas, guest_paddr & ~static_cast<zx_paddr_t>(1));
-        else
-            pvclock_stop_clock(pvclock);
-        return ZX_OK;
-    case kKvmBootTimeOld:
-    case kKvmBootTime:
-        vmcs->Invalidate();
-        return pvclock_update_boot_time(gpas, guest_paddr);
-    default:
-        local_apic_state->interrupt_tracker.VirtualInterrupt(X86_INT_GP_FAULT);
-        return ZX_OK;
-    }
-}
-
-static zx_status_t handle_wrmsr(const ExitInfo& exit_info, AutoVmcs* vmcs, GuestState* guest_state,
-                                LocalApicState* local_apic_state, PvClockState* pvclock,
-                                hypervisor::GuestPhysicalAddressSpace* gpas,
-                                zx_port_packet* packet) {
-    // On execution of wrmsr, rcx specifies the MSR and edx:eax contains the value to be written.
-    switch (static_cast<uint32_t>(guest_state->rcx)) {
-    case X86_MSR_IA32_APIC_BASE:
-        if (guest_state->rdx != 0)
-            return ZX_ERR_INVALID_ARGS;
-        if ((guest_state->rax & ~IA32_APIC_BASE_BSP) != kLocalApicPhysBase)
-            return ZX_ERR_INVALID_ARGS;
-        next_rip(exit_info, vmcs);
-        return ZX_OK;
-    // See note in handle_rdmsr.
-    case X86_MSR_IA32_MTRRCAP:
-    case X86_MSR_IA32_MTRR_DEF_TYPE:
-    case X86_MSR_IA32_MTRR_FIX64K_00000:
-    case X86_MSR_IA32_MTRR_FIX16K_80000... X86_MSR_IA32_MTRR_FIX16K_A0000:
-    case X86_MSR_IA32_MTRR_FIX4K_C0000... X86_MSR_IA32_MTRR_FIX4K_F8000:
-    case X86_MSR_IA32_MTRR_PHYSBASE0... X86_MSR_IA32_MTRR_PHYSMASK9:
-    case X86_MSR_IA32_BIOS_SIGN_ID:
-    case X86_MSR_DRAM_POWER_LIMIT:
-    case X86_MSR_PP0_POWER_LIMIT:
-    case X86_MSR_PP1_POWER_LIMIT:
-    case X86_MSR_PLATFORM_POWER_LIMIT:
-    // From AMD64 Volume 2, Section 6.1.1: CSTAR is unused, but Linux likes to
-    // set a null handler, even when not in compatibility mode. Just ignore it.
-    case X86_MSR_IA32_CSTAR:
-        next_rip(exit_info, vmcs);
-        return ZX_OK;
-    case X86_MSR_IA32_TSC_DEADLINE: {
-        if ((local_apic_state->lvt_timer & LVT_TIMER_MODE_MASK) != LVT_TIMER_MODE_TSC_DEADLINE)
-            return ZX_ERR_INVALID_ARGS;
-        next_rip(exit_info, vmcs);
-        uint64_t tsc_deadline = (guest_state->rdx << 32) | (guest_state->rax & UINT32_MAX);
-        update_timer(local_apic_state, ticks_to_nanos(tsc_deadline));
-        return ZX_OK;
-    }
-    case kX2ApicMsrBase... kX2ApicMsrMax:
-        return handle_apic_wrmsr(exit_info, vmcs, guest_state, local_apic_state, packet);
-    case kKvmSystemTimeMsrOld:
-    case kKvmSystemTimeMsr:
-    case kKvmBootTimeOld:
-    case kKvmBootTime:
-        return handle_kvm_wrmsr(exit_info, vmcs, guest_state, local_apic_state, pvclock, gpas);
-    default:
-        dprintf(INFO, "Unhandled wrmsr %#lx\n", guest_state->rcx);
-        local_apic_state->interrupt_tracker.VirtualInterrupt(X86_INT_GP_FAULT);
-        return ZX_OK;
-    }
-}
-
-/* Returns the page address for a given page table entry.
- *
- * If the page address is for a large page, we additionally calculate the offset
- * to the correct guest physical page that backs the large page.
- */
-static zx_paddr_t page_addr(zx_paddr_t pt_addr, size_t level, zx_vaddr_t guest_vaddr) {
-    zx_paddr_t off = 0;
-    if (IS_LARGE_PAGE(pt_addr)) {
-        if (level == 1) {
-            off = guest_vaddr & PAGE_OFFSET_MASK_HUGE;
-        } else if (level == 2) {
-            off = guest_vaddr & PAGE_OFFSET_MASK_LARGE;
-        }
-    }
-    return (pt_addr & X86_PG_FRAME) + (off & X86_PG_FRAME);
-}
-
-static zx_status_t get_page(hypervisor::GuestPhysicalAddressSpace* gpas, zx_vaddr_t guest_vaddr,
-                            zx_paddr_t pt_addr, zx_paddr_t* host_paddr) {
-    size_t indices[X86_PAGING_LEVELS] = {
-        VADDR_TO_PML4_INDEX(guest_vaddr),
-        VADDR_TO_PDP_INDEX(guest_vaddr),
-        VADDR_TO_PD_INDEX(guest_vaddr),
-        VADDR_TO_PT_INDEX(guest_vaddr),
-    };
-    zx_paddr_t pa;
-    for (size_t level = 0; level <= X86_PAGING_LEVELS; level++) {
-        zx_status_t status = gpas->GetPage(page_addr(pt_addr, level - 1, guest_vaddr), &pa);
-        if (status != ZX_OK)
-            return status;
-        if (level == X86_PAGING_LEVELS || IS_LARGE_PAGE(pt_addr))
-            break;
-        pt_entry_t* pt = static_cast<pt_entry_t*>(paddr_to_physmap(pa));
-        pt_addr = pt[indices[level]];
-        if (!IS_PAGE_PRESENT(pt_addr))
-            return ZX_ERR_NOT_FOUND;
-    }
-    *host_paddr = pa;
-    return ZX_OK;
-}
-
-static zx_status_t fetch_data(hypervisor::GuestPhysicalAddressSpace* gpas, zx_vaddr_t guest_vaddr,
-                              uint8_t* data, size_t size, zx_paddr_t pt_addr) {
-    // TODO(abdulla): Make this handle a fetch that crosses more than two pages.
-    if (size > PAGE_SIZE)
-        return ZX_ERR_OUT_OF_RANGE;
-
-    zx_paddr_t pa;
-    zx_status_t status = get_page(gpas, guest_vaddr, pt_addr, &pa);
-    if (status != ZX_OK)
-        return status;
-
-    size_t page_offset = guest_vaddr & PAGE_OFFSET_MASK_4KB;
-    uint8_t* page = static_cast<uint8_t*>(paddr_to_physmap(pa));
-    size_t from_page = fbl::min(size, PAGE_SIZE - page_offset);
-    mandatory_memcpy(data, page + page_offset, from_page);
-
-    // If the fetch is not split across pages, return.
-    if (from_page == size)
-        return ZX_OK;
-
-    status = get_page(gpas, guest_vaddr + size, pt_addr, &pa);
-    if (status != ZX_OK)
-        return status;
-
-    page = static_cast<uint8_t*>(paddr_to_physmap(pa));
-    mandatory_memcpy(data + from_page, page, size - from_page);
-    return ZX_OK;
-}
-
-static zx_status_t handle_trap(const ExitInfo& exit_info, AutoVmcs* vmcs, bool read,
-                               zx_vaddr_t guest_paddr, hypervisor::GuestPhysicalAddressSpace* gpas,
-                               hypervisor::TrapMap* traps, zx_port_packet_t* packet) {
-    if (exit_info.exit_instruction_length > X86_MAX_INST_LEN)
-        return ZX_ERR_INTERNAL;
-
-    hypervisor::Trap* trap;
-    zx_status_t status = traps->FindTrap(ZX_GUEST_TRAP_BELL, guest_paddr, &trap);
-    if (status != ZX_OK)
-        return status;
-    next_rip(exit_info, vmcs);
-
-    switch (trap->kind()) {
-    case ZX_GUEST_TRAP_BELL:
-        if (read)
-            return ZX_ERR_NOT_SUPPORTED;
-        *packet = {};
-        packet->key = trap->key();
-        packet->type = ZX_PKT_TYPE_GUEST_BELL;
-        packet->guest_bell.addr = guest_paddr;
-        if (!trap->HasPort())
-            return ZX_ERR_BAD_STATE;
-        return trap->Queue(*packet, vmcs);
-    case ZX_GUEST_TRAP_MEM: {
-        *packet = {};
-        packet->key = trap->key();
-        packet->type = ZX_PKT_TYPE_GUEST_MEM;
-        packet->guest_mem.addr = guest_paddr;
-        packet->guest_mem.inst_len = exit_info.exit_instruction_length & UINT8_MAX;
-        // See Volume 3, Section 5.2.1.
-        uint64_t efer = vmcs->Read(VmcsField64::GUEST_IA32_EFER);
-        uint32_t cs_access_rights = vmcs->Read(VmcsField32::GUEST_CS_ACCESS_RIGHTS);
-        if ((efer & X86_EFER_LMA) && (cs_access_rights & kGuestXxAccessRightsL)) {
-            // IA32-e 64 bit mode.
-            packet->guest_mem.default_operand_size = 4;
-        } else if (cs_access_rights & kGuestXxAccessRightsD) {
-            // CS.D set (and not 64 bit mode).
-            packet->guest_mem.default_operand_size = 4;
-        } else {
-            // CS.D clear (and not 64 bit mode).
-            packet->guest_mem.default_operand_size = 2;
-        }
-        zx_paddr_t pt_addr = vmcs->Read(VmcsFieldXX::GUEST_CR3);
-        // Done with the vmcs, can now invalidate in case we block.
-        vmcs->Invalidate();
-        status = fetch_data(gpas, exit_info.guest_rip, packet->guest_mem.inst_buf,
-                            packet->guest_mem.inst_len, pt_addr);
-        return status == ZX_OK ? ZX_ERR_NEXT : status;
-    }
-    default:
-        return ZX_ERR_BAD_STATE;
-    }
-}
-
-static zx_status_t handle_ept_violation(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                        hypervisor::GuestPhysicalAddressSpace* gpas,
-                                        hypervisor::TrapMap* traps, zx_port_packet_t* packet) {
-    EptViolationInfo ept_violation_info(exit_info.exit_qualification);
-    zx_vaddr_t guest_paddr = exit_info.guest_physical_address;
-    zx_status_t status =
-        handle_trap(exit_info, vmcs, ept_violation_info.read, guest_paddr, gpas, traps, packet);
-    switch (status) {
-    case ZX_ERR_NOT_FOUND:
-        break;
-    case ZX_OK:
-    default:
-        return status;
-    }
-    // We may have to block when handling the page fault.
-    vmcs->Invalidate();
-
-    // If there was no trap associated with this address and it is outside of
-    // guest physical address space, return failure.
-    if (guest_paddr >= gpas->size())
-        return ZX_ERR_OUT_OF_RANGE;
-
-    status = gpas->PageFault(guest_paddr);
-    if (status != ZX_OK) {
-        dprintf(CRITICAL, "Unhandled EPT violation %#lx\n", exit_info.guest_physical_address);
-    }
-    return status;
-}
-
-static zx_status_t handle_xsetbv(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                 GuestState* guest_state) {
-    uint64_t guest_cr4 = vmcs->Read(VmcsFieldXX::GUEST_CR4);
-    if (!(guest_cr4 & X86_CR4_OSXSAVE))
-        return ZX_ERR_INVALID_ARGS;
-
-    // We only support XCR0.
-    if (guest_state->rcx != 0)
-        return ZX_ERR_INVALID_ARGS;
-
-    cpuid_leaf leaf;
-    if (!x86_get_cpuid_subleaf(X86_CPUID_XSAVE, 0, &leaf))
-        return ZX_ERR_INTERNAL;
-
-    // Check that XCR0 is valid.
-    uint64_t xcr0_bitmap = ((uint64_t)leaf.d << 32) | leaf.a;
-    uint64_t xcr0 = (guest_state->rdx << 32) | (guest_state->rax & UINT32_MAX);
-    if (~xcr0_bitmap & xcr0 ||
-        // x87 state must be enabled.
-        (xcr0 & X86_XSAVE_STATE_BIT_X87) != X86_XSAVE_STATE_BIT_X87 ||
-        // If AVX state is enabled, SSE state must be enabled.
-        (xcr0 & (X86_XSAVE_STATE_BIT_AVX | X86_XSAVE_STATE_BIT_SSE)) == X86_XSAVE_STATE_BIT_AVX)
-        return ZX_ERR_INVALID_ARGS;
-
-    guest_state->xcr0 = xcr0;
-    next_rip(exit_info, vmcs);
-    return ZX_OK;
-}
-
-static zx_status_t handle_pause(const ExitInfo& exit_info, AutoVmcs* vmcs) {
-    next_rip(exit_info, vmcs);
-    vmcs->Invalidate();
-    thread_reschedule();
-    return ZX_OK;
-}
-
-static zx_status_t handle_vmcall(const ExitInfo& exit_info, AutoVmcs* vmcs,
-                                 hypervisor::GuestPhysicalAddressSpace* gpas,
-                                 GuestState* guest_state) {
-    next_rip(exit_info, vmcs);
-    vmcs->Invalidate();
-
-    VmCallInfo info(guest_state);
-    switch (info.type) {
-    case VmCallType::CLOCK_PAIRING: {
-        if (info.arg[1] != 0) {
-            dprintf(INFO, "CLOCK_PAIRING hypercall doesn't support clock type %lu\n",
-                    info.arg[1]);
-            guest_state->rax = VmCallStatus::OP_NOT_SUPPORTED;
-            break;
-        }
-        zx_status_t status = pvclock_populate_offset(gpas, info.arg[0]);
-        if (status != ZX_OK) {
-            dprintf(INFO, "Populating lock offset failed with %d\n", status);
-            guest_state->rax = VmCallStatus::FAULT;
-            break;
-        }
-        guest_state->rax = VmCallStatus::OK;
-        break;
-    }
-    default:
-        dprintf(INFO, "Unknown VMCALL(%lu) (arg0=%#lx, arg1=%#lx, arg2=%#lx, arg3=%#lx)\n",
-                static_cast<unsigned long>(info.type),
-                info.arg[0], info.arg[1], info.arg[2], info.arg[3]);
-        guest_state->rax = VmCallStatus::NO_SYS;
-        break;
-    }
-    // We never fail in case of hypercalls, we just return/propagate errors to the caller.
-    return ZX_OK;
-}
-
-zx_status_t vmexit_handler(AutoVmcs* vmcs, GuestState* guest_state,
-                           LocalApicState* local_apic_state, PvClockState* pvclock,
-                           hypervisor::GuestPhysicalAddressSpace* gpas, hypervisor::TrapMap* traps,
-                           zx_port_packet_t* packet) {
-    zx_status_t status;
-    ExitInfo exit_info(*vmcs);
-    switch (exit_info.exit_reason) {
-    case ExitReason::EXTERNAL_INTERRUPT:
-        ktrace_vcpu_exit(VCPU_EXTERNAL_INTERRUPT, exit_info.guest_rip);
-        status = handle_external_interrupt(vmcs);
-        break;
-    case ExitReason::INTERRUPT_WINDOW:
-        LTRACEF("handling interrupt window\n\n");
-        ktrace_vcpu_exit(VCPU_INTERRUPT_WINDOW, exit_info.guest_rip);
-        status = handle_interrupt_window(vmcs, local_apic_state);
-        break;
-    case ExitReason::CPUID:
-        LTRACEF("handling CPUID\n\n");
-        ktrace_vcpu_exit(VCPU_CPUID, exit_info.guest_rip);
-        status = handle_cpuid(exit_info, vmcs, guest_state);
-        break;
-    case ExitReason::HLT:
-        LTRACEF("handling HLT\n\n");
-        ktrace_vcpu_exit(VCPU_HLT, exit_info.guest_rip);
-        status = handle_hlt(exit_info, vmcs, local_apic_state);
-        break;
-    case ExitReason::CONTROL_REGISTER_ACCESS:
-        LTRACEF("handling control-register access\n\n");
-        ktrace_vcpu_exit(VCPU_CONTROL_REGISTER_ACCESS, exit_info.guest_rip);
-        status = handle_control_register_access(exit_info, vmcs, guest_state);
-        break;
-    case ExitReason::IO_INSTRUCTION:
-        ktrace_vcpu_exit(VCPU_IO_INSTRUCTION, exit_info.guest_rip);
-        status = handle_io_instruction(exit_info, vmcs, guest_state, traps, packet);
-        break;
-    case ExitReason::RDMSR:
-        LTRACEF("handling RDMSR %#lx\n\n", guest_state->rcx);
-        ktrace_vcpu_exit(VCPU_RDMSR, exit_info.guest_rip);
-        status = handle_rdmsr(exit_info, vmcs, guest_state, local_apic_state);
-        break;
-    case ExitReason::WRMSR:
-        LTRACEF("handling WRMSR %#lx\n\n", guest_state->rcx);
-        ktrace_vcpu_exit(VCPU_WRMSR, exit_info.guest_rip);
-        status = handle_wrmsr(exit_info, vmcs, guest_state, local_apic_state, pvclock, gpas, packet);
-        break;
-    case ExitReason::ENTRY_FAILURE_GUEST_STATE:
-    case ExitReason::ENTRY_FAILURE_MSR_LOADING:
-        LTRACEF("handling VM entry failure\n\n");
-        ktrace_vcpu_exit(VCPU_VM_ENTRY_FAILURE, exit_info.guest_rip);
-        status = ZX_ERR_BAD_STATE;
-        break;
-    case ExitReason::EPT_VIOLATION:
-        LTRACEF("handling EPT violation\n\n");
-        ktrace_vcpu_exit(VCPU_EPT_VIOLATION, exit_info.guest_rip);
-        status = handle_ept_violation(exit_info, vmcs, gpas, traps, packet);
-        break;
-    case ExitReason::XSETBV:
-        LTRACEF("handling XSETBV\n\n");
-        ktrace_vcpu_exit(VCPU_XSETBV, exit_info.guest_rip);
-        status = handle_xsetbv(exit_info, vmcs, guest_state);
-        break;
-    case ExitReason::PAUSE:
-        LTRACEF("handling PAUSE\n\n");
-        ktrace_vcpu_exit(VCPU_PAUSE, exit_info.guest_rip);
-        status = handle_pause(exit_info, vmcs);
-        break;
-    case ExitReason::VMCALL:
-        LTRACEF("handling VMCALL\n\n");
-        ktrace_vcpu_exit(VCPU_VMCALL, exit_info.guest_rip);
-        status = handle_vmcall(exit_info, vmcs, gpas, guest_state);
-        break;
-    // Currently all exceptions except NMI delivered to guest directly. NMI causes vmexit
-    // and handled by host via IDT as any other interrupt/exception.
-    case ExitReason::EXCEPTION:
-    default:
-        ktrace_vcpu_exit(VCPU_UNKNOWN, exit_info.guest_rip);
-        status = ZX_ERR_NOT_SUPPORTED;
-        break;
-    }
-    if (status != ZX_OK && status != ZX_ERR_NEXT && status != ZX_ERR_CANCELED) {
-        dprintf(CRITICAL, "VM exit handler for %u (%s) at RIP %#lx returned %d\n",
-                static_cast<uint32_t>(exit_info.exit_reason),
-                exit_reason_name(exit_info.exit_reason),
-                exit_info.guest_rip,
-                status);
-    }
-    return status;
-}
diff --git a/kernel/arch/x86/hypervisor/vmexit_priv.h b/kernel/arch/x86/hypervisor/vmexit_priv.h
deleted file mode 100644
index 4824688..0000000
--- a/kernel/arch/x86/hypervisor/vmexit_priv.h
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <hypervisor/guest_physical_address_space.h>
-#include <hypervisor/trap_map.h>
-#include <zircon/types.h>
-
-// clang-format off
-
-// VM exit reasons.
-enum class ExitReason : uint32_t {
-    EXCEPTION                   = 0u,  // NMI is an exception too
-    EXTERNAL_INTERRUPT          = 1u,
-    TRIPLE_FAULT                = 2u,
-    INIT_SIGNAL                 = 3u,
-    STARTUP_IPI                 = 4u,
-    IO_SMI                      = 5u,
-    OTHER_SMI                   = 6u,
-    INTERRUPT_WINDOW            = 7u,
-    NMI_WINDOW                  = 8u,
-    TASK_SWITCH                 = 9u,
-    CPUID                       = 10u,
-    GETSEC                      = 11u,
-    HLT                         = 12u,
-    INVD                        = 13u,
-    INVLPG                      = 14u,
-    RDPMC                       = 15u,
-    RDTSC                       = 16u,
-    RSM                         = 17u,
-    VMCALL                      = 18u,
-    VMCLEAR                     = 19u,
-    VMLAUNCH                    = 20u,
-    VMPTRLD                     = 21u,
-    VMPTRST                     = 22u,
-    VMREAD                      = 23u,
-    VMRESUME                    = 24u,
-    VMWRITE                     = 25u,
-    VMXOFF                      = 26u,
-    VMXON                       = 27u,
-    CONTROL_REGISTER_ACCESS     = 28u,
-    MOV_DR                      = 29u,
-    IO_INSTRUCTION              = 30u,
-    RDMSR                       = 31u,
-    WRMSR                       = 32u,
-    ENTRY_FAILURE_GUEST_STATE   = 33u,
-    ENTRY_FAILURE_MSR_LOADING   = 34u,
-    MWAIT                       = 36u,
-    MONITOR_TRAP_FLAG           = 37u,
-    MONITOR                     = 39u,
-    PAUSE                       = 40u,
-    ENTRY_FAILURE_MACHINE_CHECK = 41u,
-    TPR_BELOW_THRESHOLD         = 43u,
-    APIC_ACCESS                 = 44u,
-    VIRTUALIZED_EOI             = 45u,
-    ACCESS_GDTR_OR_IDTR         = 46u,
-    ACCESS_LDTR_OR_TR           = 47u,
-    EPT_VIOLATION               = 48u,
-    EPT_MISCONFIGURATION        = 49u,
-    INVEPT                      = 50u,
-    RDTSCP                      = 51u,
-    VMX_PREEMPT_TIMER_EXPIRED   = 52u,
-    INVVPID                     = 53u,
-    WBINVD                      = 54u,
-    XSETBV                      = 55u,
-    APIC_WRITE                  = 56u,
-    RDRAND                      = 57u,
-    INVPCID                     = 58u,
-    VMFUNC                      = 59u,
-    ENCLS                       = 60u,
-    RDSEED                      = 61u,
-    PAGE_MODIFICATION_LOG_FULL  = 62u,
-    XSAVES                      = 63u,
-    XRSTORS                     = 64u,
-};
-
-static inline const char* exit_reason_name(ExitReason exit_reason) {
-#define EXIT_REASON_NAME(name) case ExitReason::name: return #name
-    switch (exit_reason) {
-    EXIT_REASON_NAME(EXCEPTION);
-    EXIT_REASON_NAME(EXTERNAL_INTERRUPT);
-    EXIT_REASON_NAME(TRIPLE_FAULT);
-    EXIT_REASON_NAME(INIT_SIGNAL);
-    EXIT_REASON_NAME(STARTUP_IPI);
-    EXIT_REASON_NAME(IO_SMI);
-    EXIT_REASON_NAME(OTHER_SMI);
-    EXIT_REASON_NAME(INTERRUPT_WINDOW);
-    EXIT_REASON_NAME(NMI_WINDOW);
-    EXIT_REASON_NAME(TASK_SWITCH);
-    EXIT_REASON_NAME(CPUID);
-    EXIT_REASON_NAME(GETSEC);
-    EXIT_REASON_NAME(HLT);
-    EXIT_REASON_NAME(INVD);
-    EXIT_REASON_NAME(INVLPG);
-    EXIT_REASON_NAME(RDPMC);
-    EXIT_REASON_NAME(RDTSC);
-    EXIT_REASON_NAME(RSM);
-    EXIT_REASON_NAME(VMCALL);
-    EXIT_REASON_NAME(VMCLEAR);
-    EXIT_REASON_NAME(VMLAUNCH);
-    EXIT_REASON_NAME(VMPTRLD);
-    EXIT_REASON_NAME(VMPTRST);
-    EXIT_REASON_NAME(VMREAD);
-    EXIT_REASON_NAME(VMRESUME);
-    EXIT_REASON_NAME(VMWRITE);
-    EXIT_REASON_NAME(VMXOFF);
-    EXIT_REASON_NAME(VMXON);
-    EXIT_REASON_NAME(CONTROL_REGISTER_ACCESS);
-    EXIT_REASON_NAME(MOV_DR);
-    EXIT_REASON_NAME(IO_INSTRUCTION);
-    EXIT_REASON_NAME(RDMSR);
-    EXIT_REASON_NAME(WRMSR);
-    EXIT_REASON_NAME(ENTRY_FAILURE_GUEST_STATE);
-    EXIT_REASON_NAME(ENTRY_FAILURE_MSR_LOADING);
-    EXIT_REASON_NAME(MWAIT);
-    EXIT_REASON_NAME(MONITOR_TRAP_FLAG);
-    EXIT_REASON_NAME(MONITOR);
-    EXIT_REASON_NAME(PAUSE);
-    EXIT_REASON_NAME(ENTRY_FAILURE_MACHINE_CHECK);
-    EXIT_REASON_NAME(TPR_BELOW_THRESHOLD);
-    EXIT_REASON_NAME(APIC_ACCESS);
-    EXIT_REASON_NAME(VIRTUALIZED_EOI);
-    EXIT_REASON_NAME(ACCESS_GDTR_OR_IDTR);
-    EXIT_REASON_NAME(ACCESS_LDTR_OR_TR);
-    EXIT_REASON_NAME(EPT_VIOLATION);
-    EXIT_REASON_NAME(EPT_MISCONFIGURATION);
-    EXIT_REASON_NAME(INVEPT);
-    EXIT_REASON_NAME(RDTSCP);
-    EXIT_REASON_NAME(VMX_PREEMPT_TIMER_EXPIRED);
-    EXIT_REASON_NAME(INVVPID);
-    EXIT_REASON_NAME(WBINVD);
-    EXIT_REASON_NAME(XSETBV);
-    EXIT_REASON_NAME(APIC_WRITE);
-    EXIT_REASON_NAME(RDRAND);
-    EXIT_REASON_NAME(INVPCID);
-    EXIT_REASON_NAME(VMFUNC);
-    EXIT_REASON_NAME(ENCLS);
-    EXIT_REASON_NAME(RDSEED);
-    EXIT_REASON_NAME(PAGE_MODIFICATION_LOG_FULL);
-    EXIT_REASON_NAME(XSAVES);
-    EXIT_REASON_NAME(XRSTORS);
-#undef EXIT_REASON_NAME
-    default: return "UNKNOWN";
-    }
-}
-
-// VM exit interruption type.
-enum class InterruptionType : uint8_t {
-    EXTERNAL_INTERRUPT          = 0u,
-    NON_MASKABLE_INTERRUPT      = 2u,
-    HARDWARE_EXCEPTION          = 3u,
-    SOFTWARE_EXCEPTION          = 6u,
-};
-
-// X2APIC MSR addresses from Volume 3, Section 10.12.1.2.
-enum class X2ApicMsr : uint32_t {
-    ID                  = 0x802,
-    VERSION             = 0x803,
-    EOI                 = 0x80b,
-    TPR                 = 0x808,
-    LDR                 = 0x80d,
-    SVR                 = 0x80f,
-    ISR_31_0            = 0x810,
-    ISR_63_32           = 0x811,
-    ISR_95_64           = 0x812,
-    ISR_127_96          = 0x813,
-    ISR_159_128         = 0x814,
-    ISR_191_160         = 0x815,
-    ISR_223_192         = 0x816,
-    ISR_255_224         = 0x817,
-    TMR_31_0            = 0x818,
-    TMR_63_32           = 0x819,
-    TMR_95_64           = 0x81a,
-    TMR_127_96          = 0x81b,
-    TMR_159_128         = 0x81c,
-    TMR_191_160         = 0x81d,
-    TMR_223_192         = 0x81e,
-    TMR_255_224         = 0x81f,
-    IRR_31_0            = 0x820,
-    IRR_63_32           = 0x821,
-    IRR_95_64           = 0x822,
-    IRR_127_96          = 0x823,
-    IRR_159_128         = 0x824,
-    IRR_191_160         = 0x825,
-    IRR_223_192         = 0x826,
-    IRR_255_224         = 0x827,
-    ESR                 = 0x828,
-    LVT_CMCI            = 0x82f,
-    ICR                 = 0x830,
-    LVT_TIMER           = 0x832,
-    LVT_THERMAL_SENSOR  = 0x833,
-    LVT_MONITOR         = 0x834,
-    LVT_LINT0           = 0x835,
-    LVT_LINT1           = 0x836,
-    LVT_ERROR           = 0x837,
-    INITIAL_COUNT       = 0x838,
-    DCR                 = 0x83e,
-    SELF_IPI            = 0x83f,
-};
-
-enum class InterruptDeliveryMode : uint8_t {
-    FIXED               = 0u,
-    SMI                 = 2u,
-    NMI                 = 4u,
-    INIT                = 5u,
-    STARTUP             = 6u,
-};
-
-enum class InterruptDestinationMode : bool {
-    PHYSICAL            = false,
-    LOGICAL             = true,
-};
-
-enum class InterruptDestinationShorthand : uint8_t {
-    NO_SHORTHAND        = 0u,
-    SELF                = 1u,
-    ALL_INCLUDING_SELF  = 2u,
-    ALL_EXCLUDING_SELF  = 3u,
-};
-
-enum class CrAccessType : uint8_t {
-    MOV_TO_CR           = 0u,
-    MOV_FROM_CR         = 1u,
-    CLTS                = 2u,
-    LMSW                = 3u,
-};
-
-enum VmCallStatus : int64_t {
-    OK                  = 0,
-    FAULT               = -14,
-    OP_NOT_SUPPORTED    = -95,
-    NO_SYS              = -1000,
-};
-
-enum class VmCallType : uint64_t {
-    CLOCK_PAIRING       = 9u,
-};
-
-// clang-format on
-
-typedef struct zx_port_packet zx_port_packet_t;
-
-class AutoVmcs;
-struct GuestState;
-struct LocalApicState;
-struct PvClockState;
-
-// Stores VM exit info from VMCS fields.
-struct ExitInfo {
-    bool entry_failure;
-    ExitReason exit_reason;
-    uint64_t exit_qualification;
-    uint32_t exit_instruction_length;
-    uint64_t guest_physical_address;
-    uint64_t guest_rip;
-
-    ExitInfo(const AutoVmcs& vmcs);
-};
-
-// Stores VM exit interruption information. See Volume 3, Section 24.9.2.
-struct ExitInterruptionInformation {
-    uint8_t vector;
-    InterruptionType interruption_type;
-    bool valid;
-
-    ExitInterruptionInformation(const AutoVmcs& vmcs);
-};
-
-// Stores EPT violation info from the VMCS exit qualification field.
-struct EptViolationInfo {
-    bool read;
-    bool write;
-    bool instruction;
-
-    EptViolationInfo(uint64_t qualification);
-};
-
-// Stores control register access info from the VMCS exit qualification field.
-struct CrAccessInfo {
-    uint8_t cr_number;
-    CrAccessType access_type;
-    uint8_t reg;
-
-    CrAccessInfo(uint64_t qualification);
-};
-
-// Stores IO instruction info from the VMCS exit qualification field.
-struct IoInfo {
-    uint8_t access_size;
-    bool input;
-    bool string;
-    bool repeat;
-    uint16_t port;
-
-    IoInfo(uint64_t qualification);
-};
-
-// Stores VMCALL type and arguments.
-struct VmCallInfo {
-    VmCallType type;
-    uint64_t arg[4];
-
-    VmCallInfo(const GuestState* guest_state);
-};
-
-// Interrupt command register.
-struct InterruptCommandRegister {
-    uint32_t destination;
-    enum InterruptDestinationMode destination_mode;
-    enum InterruptDeliveryMode delivery_mode;
-    enum InterruptDestinationShorthand destination_shorthand;
-    uint8_t vector;
-
-    InterruptCommandRegister(uint32_t hi, uint32_t lo);
-};
-
-zx_status_t vmexit_handler(AutoVmcs* vmcs, GuestState* guest_state,
-                           LocalApicState* local_apic_state, PvClockState* pvclock,
-                           hypervisor::GuestPhysicalAddressSpace* gpas, hypervisor::TrapMap* traps,
-                           zx_port_packet_t* packet);
diff --git a/kernel/arch/x86/hypervisor/vmx.S b/kernel/arch/x86/hypervisor/vmx.S
deleted file mode 100644
index 5459847..0000000
--- a/kernel/arch/x86/hypervisor/vmx.S
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-
-#include <arch/x86/vmx_state.h>
-#include <zircon/errors.h>
-
-.text
-
-/* zx_status_t vmx_enter(VmxState* vmx_state) */
-FUNCTION(vmx_enter)
-    // Store the return address.
-    // We do this first to adjust the RSP we store.
-    popq HS_RIP(%rdi)
-
-    // Store the callee save registers.
-    mov %rbx, HS_RBX(%rdi)
-    mov %rsp, HS_RSP(%rdi)
-    mov %rbp, HS_RBP(%rdi)
-    mov %r12, HS_R12(%rdi)
-    mov %r13, HS_R13(%rdi)
-    mov %r14, HS_R14(%rdi)
-    mov %r15, HS_R15(%rdi)
-
-    // Store the processor flags.
-    pushfq
-    popq HS_RFLAGS(%rdi)
-
-    // We are going to trample RDI, so move it to RSP. This also conveniently
-    // mirrors the exit code.
-    mov %rdi, %rsp
-
-    // Load the guest CR2.
-    mov GS_CR2(%rsp), %rax
-    mov %rax, %cr2
-
-    // Load the guest registers not covered by the VMCS.
-    mov GS_RAX(%rsp), %rax
-    mov GS_RCX(%rsp), %rcx
-    mov GS_RDX(%rsp), %rdx
-    mov GS_RBX(%rsp), %rbx
-    mov GS_RBP(%rsp), %rbp
-    mov GS_RSI(%rsp), %rsi
-    mov GS_RDI(%rsp), %rdi
-    mov GS_R8(%rsp), %r8
-    mov GS_R9(%rsp), %r9
-    mov GS_R10(%rsp), %r10
-    mov GS_R11(%rsp), %r11
-    mov GS_R12(%rsp), %r12
-    mov GS_R13(%rsp), %r13
-    mov GS_R14(%rsp), %r14
-    mov GS_R15(%rsp), %r15
-
-    // If we are resuming, jump to resume.
-    testb $1, VS_RESUME(%rsp)
-    jnz resume
-
-    // Launch the guest.
-    vmlaunch
-    jmp failure
-
-resume:
-    // Resume the guest.
-    vmresume
-
-failure:
-    // We will only be here if vmlaunch or vmresume failed.
-    // Restore host RDI and RSP.
-    mov %rsp, %rdi
-    mov HS_RSP(%rdi), %rsp
-
-    // Set up the return address.
-    pushq HS_RIP(%rdi)
-
-    // Return ZX_ERR_INTERNAL.
-    mov $ZX_ERR_INTERNAL, %eax
-    ret
-END_FUNCTION(vmx_enter)
-
-/* This is effectively the second-half of vmx_enter. When we return from a
- * VM exit, vmx_state argument is stored in RSP. We use this to restore the
- * stack and registers to the state they were in when vmx_enter was called.
- */
-FUNCTION(vmx_exit_entry)
-    // Store the guest registers not covered by the VMCS. At this point,
-    // vmx_state is in RSP.
-    mov %rax, GS_RAX(%rsp)
-    mov %rcx, GS_RCX(%rsp)
-    mov %rdx, GS_RDX(%rsp)
-    mov %rbx, GS_RBX(%rsp)
-    mov %rbp, GS_RBP(%rsp)
-    mov %rsi, GS_RSI(%rsp)
-    mov %rdi, GS_RDI(%rsp)
-    mov %r8, GS_R8(%rsp)
-    mov %r9, GS_R9(%rsp)
-    mov %r10, GS_R10(%rsp)
-    mov %r11, GS_R11(%rsp)
-    mov %r12, GS_R12(%rsp)
-    mov %r13, GS_R13(%rsp)
-    mov %r14, GS_R14(%rsp)
-    mov %r15, GS_R15(%rsp)
-
-    // Store the guest CR2.
-    mov %cr2, %rax
-    mov %rax, GS_CR2(%rsp)
-
-    // Load vmx_state from RSP into RDI.
-    mov %rsp, %rdi
-
-    // Load the host callee save registers.
-    mov HS_RBX(%rdi), %rbx
-    mov HS_RSP(%rdi), %rsp
-    mov HS_RBP(%rdi), %rbp
-    mov HS_R12(%rdi), %r12
-    mov HS_R13(%rdi), %r13
-    mov HS_R14(%rdi), %r14
-    mov HS_R15(%rdi), %r15
-
-    // Load the host processor flags.
-    pushq HS_RFLAGS(%rdi)
-    popfq
-
-    // Set up the return address.
-    pushq HS_RIP(%rdi)
-
-    // Call vmx_exit(vmx_state).
-    sub $8, %rsp
-    call vmx_exit
-    add $8, %rsp
-
-    // Return ZX_OK, using the return address of vmx_enter pushed above.
-    mov $ZX_OK, %eax
-    ret
-END_FUNCTION(vmx_exit_entry)
diff --git a/kernel/arch/x86/hypervisor/vmx_cpu_state.cpp b/kernel/arch/x86/hypervisor/vmx_cpu_state.cpp
deleted file mode 100644
index a95c3b5..0000000
--- a/kernel/arch/x86/hypervisor/vmx_cpu_state.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include "vmx_cpu_state_priv.h"
-
-#include <assert.h>
-#include <bits.h>
-#include <string.h>
-
-#include <hypervisor/cpu.h>
-#include <kernel/auto_lock.h>
-#include <kernel/mp.h>
-
-#include <fbl/mutex.h>
-
-static fbl::Mutex guest_mutex;
-static size_t num_guests TA_GUARDED(guest_mutex) = 0;
-static fbl::Array<VmxPage> vmxon_pages TA_GUARDED(guest_mutex);
-
-static zx_status_t vmxon(paddr_t pa) {
-    uint8_t err;
-
-    __asm__ volatile(
-        "vmxon %[pa];" VMX_ERR_CHECK(err)
-        : [err] "=r"(err)
-        : [pa] "m"(pa)
-        : "cc", "memory");
-
-    return err ? ZX_ERR_INTERNAL : ZX_OK;
-}
-
-static zx_status_t vmxoff() {
-    uint8_t err;
-
-    __asm__ volatile(
-        "vmxoff;" VMX_ERR_CHECK(err)
-        : [err] "=r"(err)
-        :
-        : "cc");
-
-    return err ? ZX_ERR_INTERNAL : ZX_OK;
-}
-
-VmxInfo::VmxInfo() {
-    // From Volume 3, Appendix A.1.
-    uint64_t basic_info = read_msr(X86_MSR_IA32_VMX_BASIC);
-    revision_id = static_cast<uint32_t>(BITS(basic_info, 30, 0));
-    region_size = static_cast<uint16_t>(BITS_SHIFT(basic_info, 44, 32));
-    write_back = BITS_SHIFT(basic_info, 53, 50) == VMX_MEMORY_TYPE_WRITE_BACK;
-    io_exit_info = BIT_SHIFT(basic_info, 54);
-    vmx_controls = BIT_SHIFT(basic_info, 55);
-}
-
-EptInfo::EptInfo() {
-    // From Volume 3, Appendix A.10.
-    uint64_t ept_info = read_msr(X86_MSR_IA32_VMX_EPT_VPID_CAP);
-    page_walk_4 = BIT_SHIFT(ept_info, 6);
-    write_back = BIT_SHIFT(ept_info, 14);
-    invept =
-        // INVEPT instruction is supported.
-        BIT_SHIFT(ept_info, 20) &&
-        // Single-context INVEPT type is supported.
-        BIT_SHIFT(ept_info, 25) &&
-        // All-context INVEPT type is supported.
-        BIT_SHIFT(ept_info, 26);
-}
-
-zx_status_t VmxPage::Alloc(const VmxInfo& vmx_info, uint8_t fill) {
-    // From Volume 3, Appendix A.1: Bits 44:32 report the number of bytes that
-    // software should allocate for the VMXON region and any VMCS region. It is
-    // a value greater than 0 and at most 4096 (bit 44 is set if and only if
-    // bits 43:32 are clear).
-    if (vmx_info.region_size > PAGE_SIZE)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    // Check use of write-back memory for VMX regions is supported.
-    if (!vmx_info.write_back)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    // The maximum size for a VMXON or VMCS region is 4096, therefore
-    // unconditionally allocating a page is adequate.
-    return hypervisor::Page::Alloc(fill);
-}
-
-static zx_status_t vmxon_task(void* context, cpu_num_t cpu_num) {
-    auto pages = static_cast<fbl::Array<VmxPage>*>(context);
-    VmxPage& page = (*pages)[cpu_num];
-
-    // Check that we have instruction information when we VM exit on IO.
-    VmxInfo vmx_info;
-    if (!vmx_info.io_exit_info)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    // Check that full VMX controls are supported.
-    if (!vmx_info.vmx_controls)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    // Check that a page-walk length of 4 is supported.
-    EptInfo ept_info;
-    if (!ept_info.page_walk_4)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    // Check use write-back memory for EPT is supported.
-    if (!ept_info.write_back)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    // Check that the INVEPT instruction is supported.
-    if (!ept_info.invept)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    // Enable VMXON, if required.
-    uint64_t feature_control = read_msr(X86_MSR_IA32_FEATURE_CONTROL);
-    if (!(feature_control & X86_MSR_IA32_FEATURE_CONTROL_LOCK) ||
-        !(feature_control & X86_MSR_IA32_FEATURE_CONTROL_VMXON)) {
-        if ((feature_control & X86_MSR_IA32_FEATURE_CONTROL_LOCK) &&
-            !(feature_control & X86_MSR_IA32_FEATURE_CONTROL_VMXON)) {
-            return ZX_ERR_NOT_SUPPORTED;
-        }
-        feature_control |= X86_MSR_IA32_FEATURE_CONTROL_LOCK;
-        feature_control |= X86_MSR_IA32_FEATURE_CONTROL_VMXON;
-        write_msr(X86_MSR_IA32_FEATURE_CONTROL, feature_control);
-    }
-
-    // Check control registers are in a VMX-friendly state.
-    uint64_t cr0 = x86_get_cr0();
-    if (cr_is_invalid(cr0, X86_MSR_IA32_VMX_CR0_FIXED0, X86_MSR_IA32_VMX_CR0_FIXED1))
-        return ZX_ERR_BAD_STATE;
-    uint64_t cr4 = x86_get_cr4() | X86_CR4_VMXE;
-    if (cr_is_invalid(cr4, X86_MSR_IA32_VMX_CR4_FIXED0, X86_MSR_IA32_VMX_CR4_FIXED1))
-        return ZX_ERR_BAD_STATE;
-
-    // Enable VMX using the VMXE bit.
-    x86_set_cr4(cr4);
-
-    // Setup VMXON page.
-    VmxRegion* region = page.VirtualAddress<VmxRegion>();
-    region->revision_id = vmx_info.revision_id;
-
-    // Execute VMXON.
-    zx_status_t status = vmxon(page.PhysicalAddress());
-    if (status != ZX_OK) {
-        dprintf(CRITICAL, "Failed to turn on VMX on CPU %u\n", cpu_num);
-        return status;
-    }
-
-    return ZX_OK;
-}
-
-static void vmxoff_task(void* arg) {
-    // Execute VMXOFF.
-    zx_status_t status = vmxoff();
-    if (status != ZX_OK) {
-        dprintf(CRITICAL, "Failed to turn off VMX on CPU %u\n", arch_curr_cpu_num());
-        return;
-    }
-
-    // Disable VMX.
-    x86_set_cr4(x86_get_cr4() & ~X86_CR4_VMXE);
-}
-
-zx_status_t alloc_vmx_state() {
-    fbl::AutoLock lock(&guest_mutex);
-    if (num_guests == 0) {
-        fbl::AllocChecker ac;
-        size_t num_cpus = arch_max_num_cpus();
-        VmxPage* pages_ptr = new (&ac) VmxPage[num_cpus];
-        if (!ac.check())
-            return ZX_ERR_NO_MEMORY;
-        fbl::Array<VmxPage> pages(pages_ptr, num_cpus);
-        VmxInfo vmx_info;
-        for (auto& page : pages) {
-            zx_status_t status = page.Alloc(vmx_info, 0);
-            if (status != ZX_OK)
-                return status;
-        }
-
-        // Enable VMX for all online CPUs.
-        cpu_mask_t cpu_mask = percpu_exec(vmxon_task, &pages);
-        if (cpu_mask != mp_get_online_mask()) {
-            mp_sync_exec(MP_IPI_TARGET_MASK, cpu_mask, vmxoff_task, nullptr);
-            return ZX_ERR_NOT_SUPPORTED;
-        }
-
-        vmxon_pages = ktl::move(pages);
-    }
-    num_guests++;
-    return ZX_OK;
-}
-
-zx_status_t free_vmx_state() {
-    fbl::AutoLock lock(&guest_mutex);
-    num_guests--;
-    if (num_guests == 0) {
-        mp_sync_exec(MP_IPI_TARGET_ALL, 0, vmxoff_task, nullptr);
-        vmxon_pages.reset();
-    }
-    return ZX_OK;
-}
-
-bool cr_is_invalid(uint64_t cr_value, uint32_t fixed0_msr, uint32_t fixed1_msr) {
-    uint64_t fixed0 = read_msr(fixed0_msr);
-    uint64_t fixed1 = read_msr(fixed1_msr);
-    return ~(cr_value | ~fixed0) != 0 || ~(~cr_value | fixed1) != 0;
-}
diff --git a/kernel/arch/x86/hypervisor/vmx_cpu_state_priv.h b/kernel/arch/x86/hypervisor/vmx_cpu_state_priv.h
deleted file mode 100644
index e476ef0..0000000
--- a/kernel/arch/x86/hypervisor/vmx_cpu_state_priv.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/hypervisor.h>
-
-// clang-format off
-
-#define X86_MSR_IA32_FEATURE_CONTROL        0x003a // Feature control
-#define X86_MSR_IA32_VMX_BASIC              0x0480 // Basic info
-#define X86_MSR_IA32_VMX_CR0_FIXED0         0x0486 // CR0 bits that must be 0 to enter VMX
-#define X86_MSR_IA32_VMX_CR0_FIXED1         0x0487 // CR0 bits that must be 1 to enter VMX
-#define X86_MSR_IA32_VMX_CR4_FIXED0         0x0488 // CR4 bits that must be 0 to enter VMX
-#define X86_MSR_IA32_VMX_CR4_FIXED1         0x0489 // CR4 bits that must be 1 to enter VMX
-#define X86_MSR_IA32_VMX_EPT_VPID_CAP       0x048c // VPID and EPT Capabilities
-#define X86_MSR_IA32_VMX_MISC               0x0485 // Miscellaneous info
-
-/* X86_MSR_IA32_VMX_BASIC flags */
-#define VMX_MEMORY_TYPE_WRITE_BACK          0x06 // Write back
-
-/* X86_MSR_IA32_FEATURE_CONTROL flags */
-#define X86_MSR_IA32_FEATURE_CONTROL_LOCK   (1u << 0) // Locked
-#define X86_MSR_IA32_FEATURE_CONTROL_VMXON  (1u << 2) // Enable VMXON
-
-#define VMX_ERR_CHECK(var)                  "setna %[" #var "];" // Check CF and ZF for error.
-
-// clang-format on
-
-/* Stores VMX info from the IA32_VMX_BASIC MSR. */
-struct VmxInfo {
-    uint32_t revision_id;
-    uint16_t region_size;
-    bool write_back;
-    bool io_exit_info;
-    bool vmx_controls;
-
-    VmxInfo();
-};
-
-/* Stores EPT info from the IA32_VMX_EPT_VPID_CAP MSR. */
-struct EptInfo {
-    bool page_walk_4;
-    bool write_back;
-    bool invept;
-
-    EptInfo();
-};
-
-/* VMX region to be used with both VMXON and VMCS. */
-struct VmxRegion {
-    uint32_t revision_id;
-};
-
-zx_status_t alloc_vmx_state();
-zx_status_t free_vmx_state();
-bool cr_is_invalid(uint64_t cr_value, uint32_t fixed0_msr, uint32_t fixed1_msr);
diff --git a/kernel/arch/x86/idt.cpp b/kernel/arch/x86/idt.cpp
deleted file mode 100644
index c9e0568..0000000
--- a/kernel/arch/x86/idt.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/ops.h>
-#include <assert.h>
-#include <err.h>
-#include <fbl/algorithm.h>
-#include <kernel/mp.h>
-#include <string.h>
-#include <vm/pmm.h>
-#include <vm/vm_aspace.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-#include <arch/x86.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/idt.h>
-#include <arch/x86/interrupts.h>
-
-// The size of the `clac` instruction
-#define CLAC_SIZE 3
-
-// Early boot shared IDT structure
-struct idt _idt_startup;
-
-// IDT after early boot
-struct idt _idt __ALIGNED(PAGE_SIZE);
-// Read-only remapping of the IDT
-static struct idt* _idt_ro;
-
-static inline void idt_set_segment_sel(struct idt_entry* entry, uint16_t sel) {
-    entry->w0 = (entry->w0 & 0x0000ffff) | (sel << 16);
-}
-
-static inline void idt_set_offset(struct idt_entry* entry, uintptr_t offset) {
-    uint32_t low_16 = offset & 0xffff;
-    uint32_t mid_16 = (offset >> 16) & 0xffff;
-    entry->w0 = (entry->w0 & 0xffff0000) | low_16;
-    entry->w1 = (entry->w1 & 0x0000ffff) | (mid_16 << 16);
-    uint32_t high_32 = (uint32_t)(offset >> 32);
-    entry->w2 = high_32;
-}
-
-static inline void idt_set_present(struct idt_entry* entry, bool present) {
-    entry->w1 = (entry->w1 & ~(1 << 15)) | ((!!present) << 15);
-}
-
-static inline void idt_set_dpl(struct idt_entry* entry, enum idt_dpl dpl) {
-    ASSERT(dpl <= 3);
-    entry->w1 = (entry->w1 & ~(3 << 13)) | ((uint32_t)dpl << 13);
-}
-
-static inline void idt_set_type(
-    struct idt_entry* entry,
-    enum idt_entry_type typ) {
-    entry->w1 = (entry->w1 & ~(0xf << 8)) | ((uint32_t)typ << 8);
-}
-
-void idt_set_vector(
-    struct idt* idt,
-    uint8_t vec,
-    uint16_t code_segment_sel,
-    uintptr_t entry_point_offset,
-    enum idt_dpl dpl,
-    enum idt_entry_type typ) {
-    struct idt_entry* entry = &idt->entries[vec];
-    memset(entry, 0, sizeof(*entry));
-    idt_set_segment_sel(entry, code_segment_sel);
-    idt_set_offset(entry, entry_point_offset);
-    idt_set_type(entry, typ);
-    idt_set_dpl(entry, dpl);
-    idt_set_present(entry, true);
-}
-
-void idt_set_ist_index(struct idt* idt, uint8_t vec, uint8_t ist_idx) {
-    ASSERT(ist_idx < 8);
-    struct idt_entry* entry = &idt->entries[vec];
-    entry->w1 = (entry->w1 & ~0x7) | ist_idx;
-}
-
-void idt_setup(struct idt* idt) {
-    extern uintptr_t const _isr_table[];
-
-    // If SMAP is not available, we need to skip past the CLAC instruction
-    // at the beginning of the ISR stubs.
-    int clac_shift = 0;
-    if (!x86_feature_test(X86_FEATURE_SMAP)) {
-        clac_shift += CLAC_SIZE;
-    }
-
-    uint16_t sel;
-    enum idt_entry_type typ;
-    sel = CODE_64_SELECTOR;
-    typ = IDT_INTERRUPT_GATE64;
-    for (size_t i = 0; i < fbl::count_of(idt->entries); ++i) {
-        uintptr_t offset = _isr_table[i] + clac_shift;
-        enum idt_dpl dpl;
-        switch (i) {
-        case X86_INT_BREAKPOINT:
-            dpl = IDT_DPL3;
-            break;
-        default:
-            dpl = IDT_DPL0;
-            break;
-        }
-        idt_set_vector(idt, (uint8_t)i, sel, offset, dpl, typ);
-    }
-}
-
-// Create a read-only remapping of the global IDT.
-// This function is called on arch initialization before additional cpus
-// started. It reloads the main processor IDT to be read-only. Each
-// additional cpu will pick-up the read-only IDT by default.
-// TODO(thgarnie): Move to C++ and non-compact VMAR for KASLR support.
-void idt_setup_readonly(void) {
-    DEBUG_ASSERT(arch_curr_cpu_num() == 0);
-    DEBUG_ASSERT(mp_get_online_mask() == 1);
-    zx_status_t status = VmAspace::kernel_aspace()->AllocPhysical(
-        "idt_readonly",
-        sizeof(_idt),
-        (void**)&_idt_ro,
-        PAGE_SIZE_SHIFT,
-        vaddr_to_paddr(&_idt),
-        0 /* vmm flags */,
-        ARCH_MMU_FLAG_PERM_READ);
-    ASSERT(status == ZX_OK);
-    idt_load(_idt_ro);
-}
-
-// Get the read-only IDT
-struct idt* idt_get_readonly(void) {
-    ASSERT(_idt_ro != nullptr);
-    return _idt_ro;
-}
diff --git a/kernel/arch/x86/image.S b/kernel/arch/x86/image.S
deleted file mode 100644
index c9a199f..0000000
--- a/kernel/arch/x86/image.S
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016 Google, Inc.
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/x86/asm.h>
-#include <zircon/boot/image.h>
-
-
-// This file lays out the final kernel image seen by the boot loader.
-// It concatenates:
-//     1. the boot loader headers
-//     2. the actual kernel image (converted from the kernel ELF file)
-//     3. the fixup code to relocate the kernel image
-// The headers must tell the boot loader to load the whole combined image,
-// and leave enough space in memory after it for the bss.  The fixup code
-// in the image overlaps with the start of the kernel's bss, so start.S
-// will move it to after the bss.  Hence the headers must tell the boot
-// loader to leave enough space for that copy too.
-//
-// The label arithmetic to define the header fields only works because this
-// whole file is all in the same section (.text).  Because it's all just
-// one big section and there are no relocs to absolute locations within
-// this section, it really doesn't matter what memory layout the linker
-// thinks it's doing, but nonetheless image.ld produces an ELF segment
-// layout faithful to the physical memory picture (except that it's
-// actually position-independent).  The addresses in the ELF headers of the
-// final image.elf file are completely ignored because boot loaders don't
-// actually use that file.  It only exists to have the contents extracted
-// with objcopy -O binary.
-
-// Where the fixup code winds up in memory exactly overlaps the kernel's
-// .bss, which the kernel needs to zero before it's ready to run the fixup
-// code.  So move_fixups_and_zero_bss (in start.S) copies the fixup code to
-// scratch memory starting at IMAGE_MEMORY_END (i.e., right after the
-// kernel's .bss).  So add the fixup code size.
-//
-// The zbi_kernel_t header records this as a number of bytes after the
-// image, rather than as an address.
-#define boot_bss_end (IMAGE_MEMORY_END + IMAGE_RESERVE_SIZE)
-
-.globl IMAGE_RESERVE_SIZE
-IMAGE_RESERVE_SIZE = apply_fixups_end - apply_fixups
-
-.text
-
-// ZBI file header (zbi_header_t)
-ZBI_CONTAINER_HEADER(_zbi_file_header, boot_load_end - _zbi_kernel_header)
-
-// ZBI kernel header (zbi_header_t)
-DATA(_zbi_kernel_header)
-    .int ZBI_TYPE_KERNEL_X64
-    .int boot_load_end - _zbi_kernel_payload
-    .int 0
-    .int ZBI_FLAG_VERSION
-    .int 0
-    .int 0
-    .int ZBI_ITEM_MAGIC
-    .int ZBI_ITEM_NO_CRC32
-END_DATA(_zbi_kernel_header)
-
-// ZBI_TYPE_KERNEL payload (zbi_kernel_t)
-DATA(_zbi_kernel_payload)
-    .quad PHYS(IMAGE_ELF_ENTRY)
-    .quad boot_bss_end - boot_load_end
-END_DATA(_zbi_kernel_payload)
-
-// Pad out to the header size that was allocated in the kernel image layout.
-// This ensures that the kernel image is aligned correctly in memory.
-.org BOOT_HEADER_SIZE
-
-// Include the kernel image itself, skipping the padding left for the headers.
-DATA(kernel_image)
-.incbin KERNEL_IMAGE, BOOT_HEADER_SIZE
-DATA(kernel_image_end)
-END_DATA(kernel_image)
-
-// Immediately after the kernel image comes the fixup code.
-// The start.S code sees this address as _end.
-
-// The first word encodes the size of the fixup code so it can be moved around.
-DATA(fixup_code_size)
-    .int apply_fixups_end - apply_fixups
-END_DATA(fixup_code_size)
-
-#define FIXUP_LOCATION(addr) (addr - KERNEL_BASE)(%rdi)
-
-// This code must be purely position-independent and have no relocs.
-// This is called with the runtime address of __code_start in %rdi.
-FUNCTION(apply_fixups)
-    mov %rdi, %rax
-    sub $KERNEL_BASE, %rax
-
-// The generated kernel-fixups.inc invokes this macro for each run of fixups.
-.macro fixup addr, n, stride
-.if \n == 1
-    // This instruction is 7 bytes.
-    add %rax, FIXUP_LOCATION(\addr)
-.elseif \n == 2
-    // So this pair is 14 bytes.
-    add %rax, FIXUP_LOCATION(\addr)
-    add %rax, FIXUP_LOCATION(\addr + \stride)
-.else
-    // This sequence is 21 bytes, so it's smaller for n > 3.
-    mov $\n, %ecx
-    lea FIXUP_LOCATION(\addr), %rdx
-0:
-    add %rax, (%rdx)
-    add $\stride, %rdx
-    loop 0b
-.endif
-.endm
-
-#include "kernel-fixups.inc"
-
-    ret
-
-DATA(apply_fixups_end)
-END_FUNCTION(apply_fixups)
-
-.balign 8
-DATA(boot_load_end)
diff --git a/kernel/arch/x86/include/arch/arch_ops.h b/kernel/arch/x86/include/arch/arch_ops.h
deleted file mode 100644
index 1f8fa22..0000000
--- a/kernel/arch/x86/include/arch/arch_ops.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2014 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/compiler.h>
-
-#ifndef __ASSEMBLER__
-
-#include <arch/x86.h>
-#include <arch/x86/mp.h>
-#include <kernel/atomic.h>
-
-__BEGIN_CDECLS
-
-/* override of some routines */
-static inline void arch_enable_ints(void)
-{
-    atomic_signal_fence();
-    __asm__ volatile("sti");
-}
-
-static inline void arch_disable_ints(void)
-{
-    __asm__ volatile("cli");
-    atomic_signal_fence();
-}
-
-static inline bool arch_ints_disabled(void)
-{
-    x86_flags_t state;
-
-    __asm__ volatile(
-        "pushfq;"
-        "popq %%rax"
-        : "=a" (state)
-        :: "memory");
-
-    return !(state & (1<<9));
-}
-
-static inline uint64_t arch_cycle_count(void)
-{
-    return rdtsc();
-}
-
-static inline void arch_spinloop_pause(void)
-{
-    __asm__ volatile("pause" ::: "memory");
-}
-
-#define mb()        __asm__ volatile ("mfence" ::: "memory")
-#define smp_mb()    mb()
-
-static inline uint32_t arch_cpu_features(void)
-{
-    return 0; // Use cpuid instead.
-}
-
-uint32_t arch_dcache_line_size(void);
-uint32_t arch_icache_line_size(void);
-
-// Log architecture-specific data for process creation.
-// This can only be called after the process has been created and before
-// it is running. Alas we can't use zx_koid_t here as the arch layer is at a
-// lower level than zircon.
-void arch_trace_process_create(uint64_t pid, paddr_t pt_phys);
-
-__END_CDECLS
-
-#endif // !__ASSEMBLER__
diff --git a/kernel/arch/x86/include/arch/arch_thread.h b/kernel/arch/x86/include/arch/arch_thread.h
deleted file mode 100644
index 874d615..0000000
--- a/kernel/arch/x86/include/arch/arch_thread.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2015 Intel Corporation
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <assert.h>
-#include <zircon/compiler.h>
-#include <arch/x86/registers.h>
-#include <sys/types.h>
-
-__BEGIN_CDECLS
-
-struct arch_thread {
-    vaddr_t sp;
-#if __has_feature(safe_stack)
-    vaddr_t unsafe_sp;
-#endif
-    vaddr_t fs_base;
-    vaddr_t gs_base;
-
-    // Which entry of |suspended_general_regs| to use.
-    // One of X86_GENERAL_REGS_*.
-    uint32_t general_regs_source;
-
-    // Debugger access to userspace general regs while suspended or stopped
-    // in an exception.
-    // The regs are saved on the stack and then a pointer is stored here.
-    // NULL if not suspended or stopped in an exception.
-    union {
-        void *gregs;
-        x86_syscall_general_regs_t *syscall;
-        x86_iframe_t *iframe;
-    } suspended_general_regs;
-
-    /* Buffer to save fpu and extended register (e.g., PT) state */
-    void* extended_register_state;
-    uint8_t extended_register_buffer[X86_MAX_EXTENDED_REGISTER_SIZE + 64];
-
-    /* if non-NULL, address to return to on page fault */
-    void *page_fault_resume;
-
-    /* |track_debug_state| tells whether the kernel should keep track of the whole debug state for
-     * this thread. Normally this is set explicitly by an user that wants to make use of HW
-     * breakpoints or watchpoints.
-     * |debug_state| will still keep track of the status of the exceptions (DR6), as there are HW
-     * exceptions that are triggered without explicit debug state setting (eg. single step).
-     *
-     * Userspace can still read the complete |debug_state| even if |track_debug_state| is false.
-     * As normally the CPU only changes DR6, the |debug_state| will be up to date anyway. */
-    bool track_debug_state;
-    x86_debug_state_t debug_state;
-};
-
-static inline void x86_set_suspended_general_regs(struct arch_thread *thread, uint32_t source, void *gregs)
-{
-    DEBUG_ASSERT(thread->suspended_general_regs.gregs == NULL);
-    DEBUG_ASSERT(gregs != NULL);
-    DEBUG_ASSERT(source != X86_GENERAL_REGS_NONE);
-    thread->general_regs_source = source;
-    thread->suspended_general_regs.gregs = gregs;
-}
-
-static inline void x86_reset_suspended_general_regs(struct arch_thread *thread)
-{
-    thread->general_regs_source = X86_GENERAL_REGS_NONE;
-    thread->suspended_general_regs.gregs = NULL;
-}
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/asm_macros.h b/kernel/arch/x86/include/arch/asm_macros.h
deleted file mode 100644
index 0b62c13..0000000
--- a/kernel/arch/x86/include/arch/asm_macros.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// Use these when pushing a register from the calling frame.
-// Here we can easily describe where to find the value of the register.
-
-.macro push_reg reg
-pushq \reg
-.cfi_adjust_cfa_offset 8
-.cfi_rel_offset \reg, 0
-.endm
-
-.macro pop_reg reg
-popq \reg
-.cfi_adjust_cfa_offset -8
-.cfi_same_value \reg
-.endm
-
-// Use these when pushing a value other than the above, or when pushing
-// a register that is not from the calling frame.
-// Here we just punt on trying to describe the value pushed, the caller
-// can do so if desired.
-
-.macro push_value value
-pushq \value
-.cfi_adjust_cfa_offset 8
-.endm
-
-.macro pop_value value
-popq \value
-.cfi_adjust_cfa_offset -8
-.endm
-
-// Use these when adding/subtracting values from the stack pointer.
-// The value must be positive.
-
-.macro sub_from_sp value
-sub $\value, %rsp
-.cfi_adjust_cfa_offset \value
-.endm
-
-.macro add_to_sp value
-add $\value, %rsp
-.cfi_adjust_cfa_offset -\value
-.endm
-
-// For "functions" that are not normal functions in the ABI sense.
-// Treat all previous frame registers as having the same value.
-
-#define ALL_CFI_SAME_VALUE \
-    .cfi_same_value %rax ; \
-    .cfi_same_value %rbx ; \
-    .cfi_same_value %rcx ; \
-    .cfi_same_value %rdx ; \
-    .cfi_same_value %rsi ; \
-    .cfi_same_value %rdi ; \
-    .cfi_same_value %rbp ; \
-    .cfi_same_value %r8  ; \
-    .cfi_same_value %r9  ; \
-    .cfi_same_value %r10 ; \
-    .cfi_same_value %r11 ; \
-    .cfi_same_value %r12 ; \
-    .cfi_same_value %r13 ; \
-    .cfi_same_value %r14 ; \
-    .cfi_same_value %r15
-
-// Treat all previous frame registers as not being restorable.
-
-#define ALL_CFI_UNDEFINED \
-    .cfi_undefined %rax ; \
-    .cfi_undefined %rbx ; \
-    .cfi_undefined %rcx ; \
-    .cfi_undefined %rdx ; \
-    .cfi_undefined %rsi ; \
-    .cfi_undefined %rdi ; \
-    .cfi_undefined %rbp ; \
-    .cfi_undefined %r8  ; \
-    .cfi_undefined %r9  ; \
-    .cfi_undefined %r10 ; \
-    .cfi_undefined %r11 ; \
-    .cfi_undefined %r12 ; \
-    .cfi_undefined %r13 ; \
-    .cfi_undefined %r14 ; \
-    .cfi_undefined %r15
diff --git a/kernel/arch/x86/include/arch/aspace.h b/kernel/arch/x86/include/arch/aspace.h
deleted file mode 100644
index fd43587..0000000
--- a/kernel/arch/x86/include/arch/aspace.h
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/x86/ioport.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/page_tables/page_tables.h>
-#include <fbl/algorithm.h>
-#include <fbl/atomic.h>
-#include <fbl/canary.h>
-#include <vm/arch_vm_aspace.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-// Implementation of page tables used by x86-64 CPUs.
-class X86PageTableMmu final : public X86PageTableBase {
-public:
-    using X86PageTableBase::Init;
-    using X86PageTableBase::Destroy;
-
-    // Initialize the kernel page table, assigning the given context to it.
-    // This X86PageTable will be special in that its mappings will all have
-    // the G (global) bit set, and are expected to be aliased across all page
-    // tables used in the normal MMU.  See |AliasKernelMappings|.
-    zx_status_t InitKernel(void* ctx);
-
-    // Used for normal MMU page tables so they can share the high kernel mapping
-    zx_status_t AliasKernelMappings();
-
-private:
-    PageTableLevel top_level() final { return PML4_L; }
-    bool allowed_flags(uint flags) final { return (flags & ARCH_MMU_FLAG_PERM_READ); }
-    bool check_paddr(paddr_t paddr) final;
-    bool check_vaddr(vaddr_t vaddr) final;
-    bool supports_page_size(PageTableLevel level) final;
-    IntermediatePtFlags intermediate_flags() final;
-    PtFlags terminal_flags(PageTableLevel level, uint flags) final;
-    PtFlags split_flags(PageTableLevel level, PtFlags flags) final;
-    void TlbInvalidate(PendingTlbInvalidation* pending) final;
-    uint pt_flags_to_mmu_flags(PtFlags flags, PageTableLevel level) final;
-    bool needs_cache_flushes() final { return false; }
-
-    // If true, all mappings will have the global bit set.
-    bool use_global_mappings_ = false;
-};
-
-// Implementation of Intel's Extended Page Tables, for use in virtualization.
-class X86PageTableEpt final : public X86PageTableBase {
-public:
-    using X86PageTableBase::Init;
-    using X86PageTableBase::Destroy;
-private:
-    PageTableLevel top_level() final { return PML4_L; }
-    bool allowed_flags(uint flags) final;
-    bool check_paddr(paddr_t paddr) final;
-    bool check_vaddr(vaddr_t vaddr) final;
-    bool supports_page_size(PageTableLevel level) final;
-    IntermediatePtFlags intermediate_flags() final;
-    PtFlags terminal_flags(PageTableLevel level, uint flags) final;
-    PtFlags split_flags(PageTableLevel level, PtFlags flags) final;
-    void TlbInvalidate(PendingTlbInvalidation* pending) final;
-    uint pt_flags_to_mmu_flags(PtFlags flags, PageTableLevel level) final;
-    bool needs_cache_flushes() final { return false; }
-};
-
-class X86ArchVmAspace final : public ArchVmAspaceInterface {
-public:
-    X86ArchVmAspace();
-    virtual ~X86ArchVmAspace();
-
-    zx_status_t Init(vaddr_t base, size_t size, uint mmu_flags) override;
-
-    zx_status_t Destroy() override;
-
-    // main methods
-    zx_status_t MapContiguous(vaddr_t vaddr, paddr_t paddr, size_t count,
-                              uint mmu_flags, size_t* mapped) override;
-    zx_status_t Map(vaddr_t vaddr, paddr_t* phys, size_t count, uint mmu_flags,
-                    size_t* mapped) override;
-    zx_status_t Unmap(vaddr_t vaddr, size_t count, size_t* unmapped) override;
-    zx_status_t Protect(vaddr_t vaddr, size_t count, uint mmu_flags) override;
-    zx_status_t Query(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags) override;
-
-    vaddr_t PickSpot(vaddr_t base, uint prev_region_mmu_flags,
-                     vaddr_t end, uint next_region_mmu_flags,
-                     vaddr_t align, size_t size, uint mmu_flags) override;
-
-    paddr_t arch_table_phys() const override { return pt_->phys(); }
-    paddr_t pt_phys() const { return pt_->phys(); }
-    size_t pt_pages() const { return pt_->pages(); }
-
-    int active_cpus() { return active_cpus_.load(); }
-
-    IoBitmap& io_bitmap() { return io_bitmap_; }
-
-    static void ContextSwitch(X86ArchVmAspace* from, X86ArchVmAspace* to);
-
-private:
-    // Test the vaddr against the address space's range.
-    bool IsValidVaddr(vaddr_t vaddr) {
-        return (vaddr >= base_ && vaddr <= base_ + size_ - 1);
-    }
-
-    fbl::Canary<fbl::magic("VAAS")> canary_;
-    IoBitmap io_bitmap_;
-
-    static constexpr size_t kPageTableAlign = fbl::max(alignof(X86PageTableMmu),
-                                                       alignof(X86PageTableEpt));
-    static constexpr size_t kPageTableSize = fbl::max(sizeof(X86PageTableMmu),
-                                                      sizeof(X86PageTableEpt));
-    // Embedded storage for the object pointed to by |pt_|.
-    alignas(kPageTableAlign) char page_table_storage_[kPageTableSize];
-
-    // This will be either a normal page table or an EPT, depending on whether
-    // flags_ includes ARCH_ASPACE_FLAG_GUEST.
-    X86PageTableBase* pt_;
-
-    uint flags_ = 0;
-
-    // Range of address space.
-    vaddr_t base_ = 0;
-    size_t size_ = 0;
-
-    // CPUs that are currently executing in this aspace.
-    // Actually an mp_cpu_mask_t, but header dependencies.
-    fbl::atomic_int active_cpus_{0};
-};
-
-using ArchVmAspace = X86ArchVmAspace;
diff --git a/kernel/arch/x86/include/arch/current_thread.h b/kernel/arch/x86/include/arch/current_thread.h
deleted file mode 100644
index ee431b5..0000000
--- a/kernel/arch/x86/include/arch/current_thread.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86/mp.h>
-
-#pragma once
-
-__BEGIN_CDECLS
-
-static inline struct thread *get_current_thread(void)
-{
-    /* Read directly from gs, rather than via x86_get_percpu()->current_thread,
-     * so that this is atomic.  Otherwise, we could context switch between the
-     * read of percpu from gs and the read of the current_thread pointer, and
-     * discover the current thread on a different CPU */
-    return (struct thread *)x86_read_gs_offset64(PERCPU_CURRENT_THREAD_OFFSET);
-}
-
-static inline void set_current_thread(struct thread *t)
-{
-    /* See above for why this is a direct gs write */
-    x86_write_gs_offset64(PERCPU_CURRENT_THREAD_OFFSET, (uint64_t)t);
-}
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/defines.h b/kernel/arch/x86/include/arch/defines.h
deleted file mode 100644
index c88ef40..0000000
--- a/kernel/arch/x86/include/arch/defines.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2015 Intel Corporation
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#define PAGE_SIZE 4096
-#define PAGE_SIZE_SHIFT 12
-#define PAGE_MASK (PAGE_SIZE - 1)
-
-#define MAX_CACHE_LINE 64
-
-#define ARCH_DEFAULT_STACK_SIZE 8192
-
-#define ARCH_PHYSMAP_SIZE (0x1000000000) // 64GB
-
diff --git a/kernel/arch/x86/include/arch/hypervisor.h b/kernel/arch/x86/include/arch/hypervisor.h
deleted file mode 100644
index 8c1881f..0000000
--- a/kernel/arch/x86/include/arch/hypervisor.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/x86/apic.h>
-#include <arch/x86/interrupts.h>
-#include <arch/x86/vmx_state.h>
-#include <fbl/ref_ptr.h>
-#include <ktl/unique_ptr.h>
-#include <hypervisor/guest_physical_address_space.h>
-#include <hypervisor/id_allocator.h>
-#include <hypervisor/interrupt_tracker.h>
-#include <hypervisor/page.h>
-#include <hypervisor/trap_map.h>
-#include <kernel/event.h>
-#include <kernel/spinlock.h>
-#include <kernel/timer.h>
-#include <zircon/types.h>
-
-struct VmxInfo;
-
-class VmxPage : public hypervisor::Page {
-public:
-    zx_status_t Alloc(const VmxInfo& info, uint8_t fill);
-
-private:
-    using hypervisor::Page::Alloc;
-};
-
-// Represents a guest within the hypervisor.
-class Guest {
-public:
-    static zx_status_t Create(ktl::unique_ptr<Guest>* out);
-    ~Guest();
-    DISALLOW_COPY_ASSIGN_AND_MOVE(Guest);
-
-    zx_status_t SetTrap(uint32_t kind, zx_vaddr_t addr, size_t len,
-                        fbl::RefPtr<PortDispatcher> port, uint64_t key);
-
-    hypervisor::GuestPhysicalAddressSpace* AddressSpace() const { return gpas_.get(); }
-    hypervisor::TrapMap* Traps() { return &traps_; }
-    zx_paddr_t MsrBitmapsAddress() const { return msr_bitmaps_page_.PhysicalAddress(); }
-
-    zx_status_t AllocVpid(uint16_t* vpid);
-    zx_status_t FreeVpid(uint16_t vpid);
-
-private:
-    ktl::unique_ptr<hypervisor::GuestPhysicalAddressSpace> gpas_;
-    hypervisor::TrapMap traps_;
-    VmxPage msr_bitmaps_page_;
-
-    fbl::Mutex vcpu_mutex_;
-    // TODO(alexlegg): Find a good place for this constant to live (max VCPUs).
-    hypervisor::IdAllocator<uint16_t, 64> TA_GUARDED(vcpu_mutex_) vpid_allocator_;
-
-    Guest() = default;
-};
-
-// Stores the local APIC state across VM exits.
-struct LocalApicState {
-    // Timer for APIC timer.
-    timer_t timer;
-    // Tracks pending interrupts.
-    hypervisor::InterruptTracker<X86_INT_COUNT> interrupt_tracker;
-    // LVT timer configuration
-    uint32_t lvt_timer = LVT_MASKED; // Initial state is masked (Vol 3 Section 10.12.5.1).
-    uint32_t lvt_initial_count;
-    uint32_t lvt_divide_config;
-};
-
-// System time is time since boot time and boot time is some fixed point in the past. This
-// structure keeps track of the state required to update system time in guest.
-struct pvclock_system_time;
-struct PvClockState {
-    bool is_stable = false;
-    uint32_t version = 0;
-    pvclock_system_time* system_time = nullptr;
-    hypervisor::GuestPtr guest_ptr;
-};
-
-// Represents a virtual CPU within a guest.
-class Vcpu {
-public:
-    static zx_status_t Create(Guest* guest, zx_vaddr_t entry, ktl::unique_ptr<Vcpu>* out);
-    ~Vcpu();
-    DISALLOW_COPY_ASSIGN_AND_MOVE(Vcpu);
-
-    zx_status_t Resume(zx_port_packet_t* packet);
-    cpu_mask_t Interrupt(uint32_t vector, hypervisor::InterruptType type);
-    void VirtualInterrupt(uint32_t vector);
-    zx_status_t ReadState(uint32_t kind, void* buf, size_t len) const;
-    zx_status_t WriteState(uint32_t kind, const void* buf, size_t len);
-
-private:
-    Guest* guest_;
-    const uint16_t vpid_;
-    const thread_t* thread_;
-    fbl::atomic_bool running_;
-    LocalApicState local_apic_state_;
-    PvClockState pvclock_state_;
-    VmxState vmx_state_;
-    VmxPage host_msr_page_;
-    VmxPage guest_msr_page_;
-    VmxPage vmcs_page_;
-
-    Vcpu(Guest* guest, uint16_t vpid, const thread_t* thread);
-};
diff --git a/kernel/arch/x86/include/arch/spinlock.h b/kernel/arch/x86/include/arch/spinlock.h
deleted file mode 100644
index 12fb2d8..0000000
--- a/kernel/arch/x86/include/arch/spinlock.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2015 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/x86.h>
-#include <arch/x86/mp.h>
-#include <kernel/atomic.h>
-#include <stdbool.h>
-#include <zircon/compiler.h>
-#include <zircon/thread_annotations.h>
-
-__BEGIN_CDECLS
-
-#define SPIN_LOCK_INITIAL_VALUE (spin_lock_t){0}
-
-typedef struct TA_CAP("mutex") spin_lock {
-    unsigned long value;
-} spin_lock_t;
-
-typedef x86_flags_t spin_lock_saved_state_t;
-typedef uint spin_lock_save_flags_t;
-
-void arch_spin_lock(spin_lock_t *lock) TA_ACQ(lock);
-int arch_spin_trylock(spin_lock_t *lock) TA_TRY_ACQ(false, lock);
-void arch_spin_unlock(spin_lock_t *lock) TA_REL(lock);
-
-static inline uint arch_spin_lock_holder_cpu(spin_lock_t *lock)
-{
-    return (uint)__atomic_load_n(&lock->value, __ATOMIC_RELAXED) - 1;
-}
-
-static inline bool arch_spin_lock_held(spin_lock_t *lock)
-{
-    return arch_spin_lock_holder_cpu(lock) == arch_curr_cpu_num();
-}
-
-/* flags are unused on x86 */
-#define ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS  0
-
-static inline void
-arch_interrupt_save(spin_lock_saved_state_t *statep, spin_lock_save_flags_t flags)
-{
-    *statep = x86_save_flags();
-    __asm__ volatile("cli");
-    atomic_signal_fence();
-}
-
-static inline void
-arch_interrupt_restore(spin_lock_saved_state_t old_state, spin_lock_save_flags_t flags)
-{
-    x86_restore_flags(old_state);
-}
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86.h b/kernel/arch/x86/include/arch/x86.h
deleted file mode 100644
index fba467e..0000000
--- a/kernel/arch/x86/include/arch/x86.h
+++ /dev/null
@@ -1,494 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2015 Intel Corporation
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <cpuid.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-#include <arch/x86/general_regs.h>
-#include <arch/x86/registers.h>
-#include <arch/x86/x86intrin.h>
-#include <syscalls/syscalls.h>
-
-__BEGIN_CDECLS
-
-#define X86_8BYTE_MASK 0xFFFFFFFF
-
-struct x86_64_iframe {
-    uint64_t rdi, rsi, rbp, rbx, rdx, rcx, rax;    // pushed by common handler
-    uint64_t r8, r9, r10, r11, r12, r13, r14, r15; // pushed by common handler
-    uint64_t vector;                               // pushed by stub
-    uint64_t err_code;                             // pushed by interrupt or stub
-    uint64_t ip, cs, flags;                        // pushed by interrupt
-    uint64_t user_sp, user_ss;                     // pushed by interrupt
-};
-
-typedef struct x86_64_iframe x86_iframe_t;
-typedef struct x86_64_iframe iframe_t;
-
-void x86_exception_handler(x86_iframe_t* frame);
-void platform_irq(x86_iframe_t* frame);
-
-struct arch_exception_context {
-    bool is_page_fault;
-    x86_iframe_t* frame;
-    uint64_t cr2;
-};
-
-// Register state layout used by x86_64_context_switch().
-struct x86_64_context_switch_frame {
-    uint64_t r15, r14, r13, r12;
-    uint64_t rbp;
-    uint64_t rbx;
-    uint64_t rip;
-};
-
-void x86_64_context_switch(vaddr_t* oldsp, vaddr_t newsp);
-void x86_uspace_entry(uintptr_t arg1, uintptr_t arg2, uintptr_t sp,
-                      uintptr_t pc, uint64_t rflags) __NO_RETURN;
-
-void x86_syscall(void);
-
-void x86_syscall_process_pending_signals(x86_syscall_general_regs_t* gregs);
-
-/* @brief Register all of the CPUs in the system
- *
- * Must be called only once.
- *
- * @param apic_ids A list of all APIC IDs in the system.  The BP should be in
- *        the list.
- * @param num_cpus The number of entries in the apic_ids list.
- */
-void x86_init_smp(uint32_t* apic_ids, uint32_t num_cpus);
-
-/* @brief Bring all of the specified APs up and hand them over to the kernel
- *
- * This function must not be called before x86_init_smp.
- *
- * May be called by any running CPU.  Due to requiring use of the very limited
- * low 1MB of memory, this function is not re-entrant.  Itshould not be executed
- * more than once concurrently.
- *
- * @param apic_ids A list of all APIC IDs to launch.
- * @param count The number of entries in the apic_ids list.
- *
- * @return ZX_ERR_INVALID_ARGS if an unknown APIC ID was provided.
- * @return ZX_ERR_BAD_STATE if one of the targets is currently online
- * @return ZX_ERR_TIMED_OUT if one of the targets failed to launch
- */
-zx_status_t x86_bringup_aps(uint32_t* apic_ids, uint32_t count);
-
-#define IO_BITMAP_BITS 65536
-#define IO_BITMAP_BYTES (IO_BITMAP_BITS / 8)
-#define IO_BITMAP_LONGS (IO_BITMAP_BITS / sizeof(long))
-
-/*
- * Assignment of Interrupt Stack Table entries
- */
-#define NUM_ASSIGNED_IST_ENTRIES 3
-#define NMI_IST_INDEX 1
-#define MCE_IST_INDEX 2
-#define DBF_IST_INDEX 3
-
-/*
- * x86-64 TSS structure
- */
-typedef struct {
-    uint32_t rsvd0;
-    uint64_t rsp0;
-    uint64_t rsp1;
-    uint64_t rsp2;
-    uint32_t rsvd1;
-    uint32_t rsvd2;
-    uint64_t ist1;
-    uint64_t ist2;
-    uint64_t ist3;
-    uint64_t ist4;
-    uint64_t ist5;
-    uint64_t ist6;
-    uint64_t ist7;
-    uint32_t rsvd3;
-    uint32_t rsvd4;
-    uint16_t rsvd5;
-    uint16_t iomap_base;
-
-    uint8_t tss_bitmap[IO_BITMAP_BYTES + 1];
-} __PACKED tss_64_t;
-
-typedef tss_64_t tss_t;
-
-static inline void x86_clts(void) {
-    __asm__ __volatile__("clts");
-}
-static inline void x86_hlt(void) {
-    __asm__ __volatile__("hlt");
-}
-static inline void x86_sti(void) {
-    __asm__ __volatile__("sti");
-}
-static inline void x86_cli(void) {
-    __asm__ __volatile__("cli");
-}
-static inline void x86_ltr(uint16_t sel) {
-    __asm__ __volatile__("ltr %%ax" ::"a"(sel));
-}
-static inline void x86_lidt(uintptr_t base) {
-    __asm volatile("lidt (%0)" ::"r"(base)
-                   : "memory");
-}
-static inline void x86_lgdt(uintptr_t base)
-{
-    __asm volatile("lgdt (%0)" :: "r"(base) : "memory");
-}
-
-static inline uint8_t inp(uint16_t _port) {
-    uint8_t rv;
-    __asm__ __volatile__("inb %1, %0"
-                         : "=a"(rv)
-                         : "dN"(_port));
-    return (rv);
-}
-
-static inline uint16_t inpw(uint16_t _port) {
-    uint16_t rv;
-    __asm__ __volatile__("inw %1, %0"
-                         : "=a"(rv)
-                         : "dN"(_port));
-    return (rv);
-}
-
-static inline uint32_t inpd(uint16_t _port) {
-    uint32_t rv;
-    __asm__ __volatile__("inl %1, %0"
-                         : "=a"(rv)
-                         : "dN"(_port));
-    return (rv);
-}
-
-static inline void outp(uint16_t _port, uint8_t _data) {
-    __asm__ __volatile__("outb %1, %0"
-                         :
-                         : "dN"(_port),
-                           "a"(_data));
-}
-
-static inline void outpw(uint16_t _port, uint16_t _data) {
-    __asm__ __volatile__("outw %1, %0"
-                         :
-                         : "dN"(_port),
-                           "a"(_data));
-}
-
-static inline void outpd(uint16_t _port, uint32_t _data) {
-    __asm__ __volatile__("outl %1, %0"
-                         :
-                         : "dN"(_port),
-                           "a"(_data));
-}
-
-static inline uint64_t rdtsc(void) {
-    return __rdtsc();
-}
-
-static inline void cpuid(uint32_t sel, uint32_t* a, uint32_t* b, uint32_t* c, uint32_t* d) {
-    __cpuid(sel, *a, *b, *c, *d);
-}
-
-/* cpuid wrapper with ecx set to a second argument */
-static inline void cpuid_c(uint32_t sel, uint32_t sel_c, uint32_t* a, uint32_t* b, uint32_t* c, uint32_t* d) {
-    __cpuid_count(sel, sel_c, *a, *b, *c, *d);
-}
-
-static inline void set_in_cr0(ulong mask) {
-    ulong temp;
-
-    __asm__ __volatile__(
-        "mov %%cr0, %0  \n\t"
-        "or %1, %0      \n\t"
-        "mov %0, %%cr0   \n\t"
-        : "=r"(temp)
-        : "irg"(mask)
-        :);
-}
-
-static inline void clear_in_cr0(ulong mask) {
-    ulong temp;
-
-    __asm__ __volatile__(
-        "mov %%cr0, %0  \n\t"
-        "and %1, %0     \n\t"
-        "mov %0, %%cr0  \n\t"
-        : "=r"(temp)
-        : "irg"(~mask)
-        :);
-}
-
-static inline ulong x86_get_cr2(void) {
-    ulong rv;
-
-    __asm__ __volatile__(
-        "mov %%cr2, %0"
-        : "=r"(rv));
-
-    return rv;
-}
-
-static inline ulong x86_get_cr3(void) {
-    ulong rv;
-
-    __asm__ __volatile__(
-        "mov %%cr3, %0"
-        : "=r"(rv));
-    return rv;
-}
-
-static inline void x86_set_cr3(ulong in_val) {
-    __asm__ __volatile__(
-        "mov %0,%%cr3 \n\t"
-        :
-        : "r"(in_val));
-}
-
-static inline ulong x86_get_cr0(void) {
-    ulong rv;
-
-    __asm__ __volatile__(
-        "mov %%cr0, %0 \n\t"
-        : "=r"(rv));
-    return rv;
-}
-
-static inline ulong x86_get_cr4(void) {
-    ulong rv;
-
-    __asm__ __volatile__(
-        "mov %%cr4, %0 \n\t"
-        : "=r"(rv));
-    return rv;
-}
-
-static inline void x86_set_cr0(ulong in_val) {
-    __asm__ __volatile__(
-        "mov %0,%%cr0 \n\t"
-        :
-        : "r"(in_val));
-}
-
-static inline void x86_set_cr4(ulong in_val) {
-    __asm__ __volatile__(
-        "mov %0,%%cr4 \n\t"
-        :
-        : "r"(in_val));
-}
-
-#define DEFINE_REGISTER_ACCESSOR(REG)              \
-    static inline void set_##REG(uint16_t value) { \
-        __asm__ volatile("mov %0, %%" #REG         \
-                         :                         \
-                         : "r"(value));            \
-    }                                              \
-    static inline uint16_t get_##REG(void) {       \
-        uint16_t value;                            \
-        __asm__ volatile("mov %%" #REG ", %0"      \
-                         : "=r"(value));           \
-        return value;                              \
-    }
-
-DEFINE_REGISTER_ACCESSOR(ds)
-DEFINE_REGISTER_ACCESSOR(es)
-DEFINE_REGISTER_ACCESSOR(fs)
-DEFINE_REGISTER_ACCESSOR(gs)
-
-#undef DEFINE_REGISTER_ACCESSOR
-
-static inline uint64_t read_msr(uint32_t msr_id) {
-    uint32_t msr_read_val_lo;
-    uint32_t msr_read_val_hi;
-
-    __asm__ __volatile__(
-        "rdmsr \n\t"
-        : "=a"(msr_read_val_lo), "=d"(msr_read_val_hi)
-        : "c"(msr_id));
-
-    return ((uint64_t)msr_read_val_hi << 32) | msr_read_val_lo;
-}
-
-static inline uint32_t read_msr32(uint32_t msr_id) {
-    uint32_t msr_read_val;
-
-    __asm__ __volatile__(
-        "rdmsr \n\t"
-        : "=a"(msr_read_val)
-        : "c"(msr_id)
-        : "rdx");
-
-    return msr_read_val;
-}
-
-zx_status_t read_msr_safe(uint32_t msr_id, uint64_t* val);
-
-static inline void write_msr(uint32_t msr_id, uint64_t msr_write_val) {
-    __asm__ __volatile__(
-        "wrmsr \n\t"
-        :
-        : "c"(msr_id), "a"(msr_write_val & 0xffffffff), "d"(msr_write_val >> 32));
-}
-
-static inline bool x86_is_paging_enabled(void) {
-    if (x86_get_cr0() & X86_CR0_PG)
-        return true;
-
-    return false;
-}
-
-static inline bool x86_is_PAE_enabled(void) {
-    if (x86_is_paging_enabled() == false)
-        return false;
-
-    if (!(x86_get_cr4() & X86_CR4_PAE))
-        return false;
-
-    return true;
-}
-
-static inline uint64_t x86_read_gs_offset64(uintptr_t offset) {
-    uint64_t ret;
-    __asm__("movq  %%gs:%1, %0"
-            : "=r"(ret)
-            : "m"(*(uint64_t*)(offset)));
-    return ret;
-}
-
-static inline void x86_write_gs_offset64(uintptr_t offset, uint64_t val) {
-    __asm__("movq  %0, %%gs:%1"
-            :
-            : "ir"(val), "m"(*(uint64_t*)(offset))
-            : "memory");
-}
-
-static inline uint32_t x86_read_gs_offset32(uintptr_t offset) {
-    uint32_t ret;
-    __asm__("movl  %%gs:%1, %0"
-            : "=r"(ret)
-            : "m"(*(uint32_t*)(offset)));
-    return ret;
-}
-
-static inline void x86_write_gs_offset32(uintptr_t offset, uint32_t val) {
-    __asm__("movl   %0, %%gs:%1"
-            :
-            : "ir"(val), "m"(*(uint32_t*)(offset))
-            : "memory");
-}
-
-typedef uint64_t x86_flags_t;
-
-static inline uint64_t x86_save_flags(void) {
-    uint64_t state;
-
-    __asm__ volatile(
-        "pushfq;"
-        "popq %0"
-        : "=rm"(state)::"memory");
-
-    return state;
-}
-
-static inline void x86_restore_flags(uint64_t flags) {
-    __asm__ volatile(
-        "pushq %0;"
-        "popfq" ::"g"(flags)
-        : "memory", "cc");
-}
-
-static inline void inprep(uint16_t _port, uint8_t* _buffer, uint32_t _reads) {
-    __asm__ __volatile__("pushfq \n\t"
-                         "cli \n\t"
-                         "cld \n\t"
-                         "rep insb \n\t"
-                         "popfq \n\t"
-                         :
-                         : "d"(_port),
-                           "D"(_buffer),
-                           "c"(_reads));
-}
-
-static inline void outprep(uint16_t _port, uint8_t* _buffer, uint32_t _writes) {
-    __asm__ __volatile__("pushfq \n\t"
-                         "cli \n\t"
-                         "cld \n\t"
-                         "rep outsb \n\t"
-                         "popfq \n\t"
-                         :
-                         : "d"(_port),
-                           "S"(_buffer),
-                           "c"(_writes));
-}
-
-static inline void inpwrep(uint16_t _port, uint16_t* _buffer, uint32_t _reads) {
-    __asm__ __volatile__("pushfq \n\t"
-                         "cli \n\t"
-                         "cld \n\t"
-                         "rep insw \n\t"
-                         "popfq \n\t"
-                         :
-                         : "d"(_port),
-                           "D"(_buffer),
-                           "c"(_reads));
-}
-
-static inline void outpwrep(uint16_t _port, uint16_t* _buffer,
-                            uint32_t _writes) {
-    __asm__ __volatile__("pushfq \n\t"
-                         "cli \n\t"
-                         "cld \n\t"
-                         "rep outsw \n\t"
-                         "popfq \n\t"
-                         :
-                         : "d"(_port),
-                           "S"(_buffer),
-                           "c"(_writes));
-}
-
-static inline void inpdrep(uint16_t _port, uint32_t* _buffer,
-                           uint32_t _reads) {
-    __asm__ __volatile__("pushfq \n\t"
-                         "cli \n\t"
-                         "cld \n\t"
-                         "rep insl \n\t"
-                         "popfq \n\t"
-                         :
-                         : "d"(_port),
-                           "D"(_buffer),
-                           "c"(_reads));
-}
-
-static inline void outpdrep(uint16_t _port, uint32_t* _buffer,
-                            uint32_t _writes) {
-    __asm__ __volatile__("pushfq \n\t"
-                         "cli \n\t"
-                         "cld \n\t"
-                         "rep outsl \n\t"
-                         "popfq \n\t"
-                         :
-                         : "d"(_port),
-                           "S"(_buffer),
-                           "c"(_writes));
-}
-
-void x86_monitor(volatile void* addr);
-void x86_mwait(void);
-void x86_idle(void);
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86/acpi.h b/kernel/arch/x86/include/arch/x86/acpi.h
deleted file mode 100644
index 7e32978..0000000
--- a/kernel/arch/x86/include/arch/x86/acpi.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <acpica/acpi.h>
-#include <arch/x86/bootstrap16.h>
-#include <stdint.h>
-
-__BEGIN_CDECLS
-
-// Initiates a transition to the requested ACPI S-state.
-//
-// This must not be called before bootstrap16 is configured to handle the resume.
-//
-// This must be called from a kernel thread, unless it is a transition to
-// S5 (poweroff).  Failure to do so may result in loss of usermode register state.
-ACPI_STATUS x86_acpi_transition_s_state(struct x86_realmode_entry_data_registers* regs,
-                                        uint8_t target_s_state,
-                                        uint8_t sleep_type_a, uint8_t sleep_type_b);
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86/apic.h b/kernel/arch/x86/include/arch/x86/apic.h
deleted file mode 100644
index c519cdf..0000000
--- a/kernel/arch/x86/include/arch/x86/apic.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-#include <dev/interrupt.h>
-
-__BEGIN_CDECLS
-
-// clang-format off
-#define INVALID_APIC_ID              0xffffffff
-#define APIC_PHYS_BASE               0xfee00000
-#define IA32_APIC_BASE_BSP           (1u << 8)
-#define IA32_APIC_BASE_X2APIC_ENABLE (1u << 10)
-#define IA32_APIC_BASE_XAPIC_ENABLE  (1u << 11)
-#define NUM_ISA_IRQS                 16
-
-// LVT Timer bitmasks
-#define LVT_TIMER_VECTOR_MASK       0x000000ff
-#define LVT_TIMER_MODE_MASK         0x00060000
-#define LVT_TIMER_MODE_ONESHOT      (0u << 17)
-#define LVT_TIMER_MODE_PERIODIC     (1u << 17)
-#define LVT_TIMER_MODE_TSC_DEADLINE (2u << 17)
-#define LVT_TIMER_MODE_RESERVED     (3u << 17)
-#define LVT_MASKED                  (1u << 16)
-// clang-format on
-
-enum apic_interrupt_delivery_mode {
-    // Unless you know what you're doing, you want FIXED.
-    DELIVERY_MODE_FIXED = 0,
-    DELIVERY_MODE_LOWEST_PRI = 1,
-    DELIVERY_MODE_SMI = 2,
-    DELIVERY_MODE_NMI = 4,
-    DELIVERY_MODE_INIT = 5,
-    DELIVERY_MODE_STARTUP = 6,
-    DELIVERY_MODE_EXT_INT = 7,
-};
-
-enum apic_interrupt_dst_mode {
-    DST_MODE_PHYSICAL = 0,
-    DST_MODE_LOGICAL = 1,
-};
-
-// Functionality provided by the local APIC
-void apic_vm_init(void);
-void apic_local_init(void);
-uint8_t apic_local_id(void);
-uint8_t apic_bsp_id(void); // The APIC ID of the bootstrap processor
-void apic_irq_set(unsigned int vector, bool enable);
-void apic_send_ipi(
-    uint8_t vector,
-    uint32_t dst_apic_id,
-    enum apic_interrupt_delivery_mode dm);
-void apic_send_self_ipi(uint8_t vector, enum apic_interrupt_delivery_mode dm);
-void apic_send_broadcast_ipi(
-    uint8_t vector,
-    enum apic_interrupt_delivery_mode dm);
-void apic_send_broadcast_self_ipi(
-    uint8_t vector,
-    enum apic_interrupt_delivery_mode dm);
-void apic_issue_eoi(void);
-
-zx_status_t apic_timer_set_oneshot(uint32_t count, uint8_t divisor, bool masked);
-void apic_timer_set_tsc_deadline(uint64_t deadline, bool masked);
-zx_status_t apic_timer_set_periodic(uint32_t count, uint8_t divisor);
-uint32_t apic_timer_current_count(void);
-void apic_timer_mask(void);
-void apic_timer_unmask(void);
-void apic_timer_stop(void);
-
-void apic_pmi_mask(void);
-void apic_pmi_unmask(void);
-
-void apic_error_interrupt_handler(void);
-void apic_timer_interrupt_handler(void);
-
-// platform code needs to implement this
-void platform_handle_apic_timer_tick(void);
-
-// Information about the system IO APICs
-struct io_apic_descriptor {
-    uint8_t apic_id;
-    // virtual IRQ base for ACPI
-    uint32_t global_irq_base;
-    // Physical address of the base of this IOAPIC's MMIO
-    paddr_t paddr;
-};
-
-// Information describing an ISA override.  An override can change the
-// global IRQ number and/or change bus signaling characteristics
-// for the specified ISA IRQ.
-struct io_apic_isa_override {
-    uint8_t isa_irq;
-    bool remapped;
-    enum interrupt_trigger_mode tm;
-    enum interrupt_polarity pol;
-    uint32_t global_irq;
-};
-
-// Functionality provided by the IO APICs
-// clang-format off
-#define IO_APIC_IOREGSEL    0x00
-#define IO_APIC_IOWIN       0x10
-
-#define IO_APIC_REG_ID      0x00
-#define IO_APIC_REG_VER     0x01
-#define IO_APIC_IRQ_MASK    true
-#define IO_APIC_IRQ_UNMASK  false
-// clang-format on
-
-void apic_io_init(
-    struct io_apic_descriptor* io_apics_descs,
-    unsigned int num_io_apics,
-    struct io_apic_isa_override* overrides,
-    unsigned int num_overrides);
-bool apic_io_is_valid_irq(uint32_t global_irq);
-void apic_io_mask_irq(uint32_t global_irq, bool mask);
-void apic_io_configure_irq(
-    uint32_t global_irq,
-    enum interrupt_trigger_mode trig_mode,
-    enum interrupt_polarity polarity,
-    enum apic_interrupt_delivery_mode del_mode,
-    bool mask,
-    enum apic_interrupt_dst_mode dst_mode,
-    uint8_t dst,
-    uint8_t vector);
-zx_status_t apic_io_fetch_irq_config(
-    uint32_t global_irq,
-    enum interrupt_trigger_mode* trig_mode,
-    enum interrupt_polarity* polarity);
-void apic_io_configure_irq_vector(
-    uint32_t global_irq,
-    uint8_t vector);
-uint8_t apic_io_fetch_irq_vector(uint32_t global_irq);
-
-void apic_io_mask_isa_irq(uint8_t isa_irq, bool mask);
-// For ISA configuration, we don't need to specify the trigger mode
-// and polarity since we initialize these to match the ISA bus or
-// any overrides we've been told about.
-void apic_io_configure_isa_irq(
-    uint8_t isa_irq,
-    enum apic_interrupt_delivery_mode del_mode,
-    bool mask,
-    enum apic_interrupt_dst_mode dst_mode,
-    uint8_t dst,
-    uint8_t vector);
-void apic_io_issue_eoi(uint32_t global_irq, uint8_t vec);
-uint32_t apic_io_isa_to_global(uint8_t isa_irq);
-
-// These functions must be invoked with interrupts disabled.  They save/restore the
-// current redirection table entries to/from memory.  They are intended for use
-// with suspend-to-RAM.
-void apic_io_save(void);
-void apic_io_restore(void);
-
-void apic_local_debug(void);
-void apic_io_debug(void);
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86/asm.h b/kernel/arch/x86/include/arch/x86/asm.h
deleted file mode 100644
index 6f1f05d..0000000
--- a/kernel/arch/x86/include/arch/x86/asm.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <asm.h>
-
-/* x86 assembly macros used in a few files */
-
-#define PHYS_LOAD_ADDRESS (KERNEL_LOAD_OFFSET)
-#define PHYS_ADDR_DELTA (KERNEL_BASE - PHYS_LOAD_ADDRESS)
-#define PHYS(x) ((x) - PHYS_ADDR_DELTA)
diff --git a/kernel/arch/x86/include/arch/x86/bootstrap16.h b/kernel/arch/x86/include/arch/x86/bootstrap16.h
deleted file mode 100644
index 5c6f284..0000000
--- a/kernel/arch/x86/include/arch/x86/bootstrap16.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/x86/mmu.h>
-
-#define BCD_PHYS_BOOTSTRAP_PML4_OFFSET 0
-#define BCD_PHYS_KERNEL_PML4_OFFSET 4
-#define BCD_PHYS_GDTR_OFFSET 8
-#define BCD_PHYS_LM_ENTRY_OFFSET 20
-#define BCD_LM_CS_OFFSET 24
-#define BCD_CPU_COUNTER_OFFSET 28
-#define BCD_CPU_WAITING_OFFSET 32
-#define BCD_PER_CPU_BASE_OFFSET 40
-
-#define RED_REGISTERS_OFFSET 28
-
-#ifndef __ASSEMBLER__
-#include <assert.h>
-#include <vm/vm_aspace.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-// Markers for the application processor bootstrap code region
-extern void x86_bootstrap16_start(void);
-extern void x86_bootstrap16_end(void);
-
-// 64-bit entry points that bootstrap might transition to
-
-// Entry point used for secondary CPU initialization
-extern void _x86_secondary_cpu_long_mode_entry(void);
-
-// Entry point used for suspend-to-RAM resume vector.
-// Note that this does not restore %rdi, and it touches below the saved %rsp.
-extern void _x86_suspend_wakeup(void);
-
-__END_CDECLS
-
-struct __PACKED x86_bootstrap16_data {
-    // Physical address of identity PML4
-    uint32_t phys_bootstrap_pml4;
-    // Physical address of the kernel PML4
-    uint32_t phys_kernel_pml4;
-    // Physical address of GDTR
-    uint16_t phys_gdtr_limit;
-    uint64_t phys_gdtr_base;
-    uint16_t __pad;
-
-    // Ordering of these two matter; they should be usable by retfl
-    // Physical address of long mode entry point
-    uint32_t phys_long_mode_entry;
-    // 64-bit code segment to use
-    uint32_t long_mode_cs;
-};
-
-struct __PACKED x86_realmode_entry_data {
-    struct x86_bootstrap16_data hdr;
-
-    // Virtual address of the register dump (expected to be in
-    // the form of x86_realmode_entry_data_registers)
-    uint64_t registers_ptr;
-};
-
-struct x86_realmode_entry_data_registers {
-    uint64_t rdi, rsi, rbp, rbx, rdx, rcx, rax;
-    uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
-    uint64_t rsp, rip;
-};
-
-
-struct __PACKED x86_ap_bootstrap_data {
-    struct x86_bootstrap16_data hdr;
-
-    // Counter for APs to use to determine which stack to take
-    uint32_t cpu_id_counter;
-    // Pointer to value to use to determine when APs are done with boot
-    volatile int *cpu_waiting_mask;
-
-    // Per-cpu data
-    struct __PACKED {
-        // Virtual address of base of initial kstack
-        vaddr_t kstack_base;
-        // Virtual address of initial thread_t
-        thread_t* thread;
-    } per_cpu[SMP_MAX_CPUS - 1];
-};
-
-// Initialize the bootstrap16 subsystem by giving it pages to work with.
-// |bootstrap_base| must refer to two consecutive pages of RAM with addresses
-// less than 1M that are available for the OS to use.
-void x86_bootstrap16_init(paddr_t bootstrap_base);
-
-// Upon success, returns a pointer to the bootstrap aspace, a pointer to the
-// virtual address of the bootstrap data, and the physical address of the
-// first instruction that should be executed in 16-bit mode.  It is the caller's
-// responsibility to free the aspace once it is no longer needed.
-//
-// If this function returns success, x86_bootstrap16_release() must be called
-// later, to allow the bootstrap16 module to be reused.
-zx_status_t x86_bootstrap16_acquire(uintptr_t entry64, fbl::RefPtr<VmAspace> *temp_aspace,
-                                    void **bootstrap_aperature, paddr_t* instr_ptr);
-
-// To be called once the caller is done using the bootstrap16 module
-void x86_bootstrap16_release(void* bootstrap_aperature);
-
-static_assert(sizeof(struct x86_ap_bootstrap_data) <= PAGE_SIZE, "");
-static_assert(sizeof(struct x86_realmode_entry_data) <= PAGE_SIZE, "");
-
-static_assert(__offsetof(struct x86_bootstrap16_data, phys_bootstrap_pml4) == BCD_PHYS_BOOTSTRAP_PML4_OFFSET, "");
-static_assert(__offsetof(struct x86_bootstrap16_data, phys_kernel_pml4) == BCD_PHYS_KERNEL_PML4_OFFSET, "");
-static_assert(__offsetof(struct x86_bootstrap16_data, phys_gdtr_limit) == BCD_PHYS_GDTR_OFFSET, "");
-static_assert(__offsetof(struct x86_bootstrap16_data, phys_gdtr_base) == BCD_PHYS_GDTR_OFFSET+2, "");
-static_assert(__offsetof(struct x86_bootstrap16_data, phys_long_mode_entry) == BCD_PHYS_LM_ENTRY_OFFSET, "");
-static_assert(__offsetof(struct x86_bootstrap16_data, long_mode_cs) == BCD_LM_CS_OFFSET, "");
-
-static_assert(__offsetof(struct x86_ap_bootstrap_data, hdr) == 0, "");
-static_assert(__offsetof(struct x86_ap_bootstrap_data, cpu_id_counter) == BCD_CPU_COUNTER_OFFSET, "");
-static_assert(__offsetof(struct x86_ap_bootstrap_data, cpu_waiting_mask) == BCD_CPU_WAITING_OFFSET, "");
-static_assert(__offsetof(struct x86_ap_bootstrap_data, per_cpu) == BCD_PER_CPU_BASE_OFFSET, "");
-
-static_assert(__offsetof(struct x86_realmode_entry_data, hdr) == 0, "");
-static_assert(__offsetof(struct x86_realmode_entry_data, registers_ptr) == RED_REGISTERS_OFFSET, "");
-
-#endif // __ASSEMBLER__
diff --git a/kernel/arch/x86/include/arch/x86/cpu_topology.h b/kernel/arch/x86/include/arch/x86/cpu_topology.h
deleted file mode 100644
index c31e408..0000000
--- a/kernel/arch/x86/include/arch/x86/cpu_topology.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/x86/feature.h>
-#include <zircon/compiler.h>
-#include <stdint.h>
-
-__BEGIN_CDECLS
-
-typedef struct {
-    uint32_t package_id;
-    uint32_t node_id;
-    uint32_t core_id;
-    uint32_t smt_id;
-} x86_cpu_topology_t;
-
-void x86_cpu_topology_init(void);
-void x86_cpu_topology_decode(uint32_t apic_id, x86_cpu_topology_t *topo);
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86/descriptor.h b/kernel/arch/x86/include/arch/x86/descriptor.h
deleted file mode 100644
index 25817b7..0000000
--- a/kernel/arch/x86/include/arch/x86/descriptor.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2014 Intel Corporation
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-/*
- * System Selectors
- */
-#define NULL_SELECTOR           0x00
-
-/********* kernel selectors *********/
-#define CODE_SELECTOR           0x08
-#define CODE_64_SELECTOR        0x10
-#define DATA_SELECTOR           0x18
-
-/********* user selectors *********/
-#define USER_CODE_SELECTOR      (0x20 | 3)
-#define USER_DATA_SELECTOR      (0x28 | 3)
-#define USER_CODE_64_SELECTOR   (0x30 | 3)
-
-#define TSS_SELECTOR(i)            ((uint16_t)(0x38 + 16 * (i)))
-/* 0x40 is used by the second half of the first TSS descriptor */
-
-/* selector priviledge level */
-#define SELECTOR_PL(s) ((s) & 0x3)
-
-/*
- * Descriptor Types
- */
-#define SEG_TYPE_TSS        0x9
-#define SEG_TYPE_TSS_BUSY   0xb
-#define SEG_TYPE_TASK_GATE  0x5
-#define SEG_TYPE_INT_GATE   0xe     /* 32 bit */
-#define SEG_TYPE_DATA_RW    0x2
-#define SEG_TYPE_CODE_RW    0xa
-
-#ifndef __ASSEMBLER__
-
-#include <arch/aspace.h>
-#include <zircon/compiler.h>
-#include <reg.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-#include <arch/x86/ioport.h>
-
-void x86_set_tss_io_bitmap(IoBitmap& bitmap);
-void x86_clear_tss_io_bitmap(IoBitmap& bitmap);
-void x86_reset_tss_io_bitmap(void);
-#endif // __cplusplus
-
-__BEGIN_CDECLS
-
-typedef uint16_t seg_sel_t;
-
-/* fill in a descriptor in the GDT */
-void set_global_desc_64(seg_sel_t sel, uint64_t base, uint32_t limit,
-                        uint8_t present, uint8_t ring, uint8_t sys,
-                        uint8_t type, uint8_t gran, uint8_t bits);
-
-/* tss stuff */
-void x86_initialize_percpu_tss(void);
-
-void x86_set_tss_sp(vaddr_t sp);
-void x86_clear_tss_busy(seg_sel_t sel);
-
-static inline void gdt_load(uintptr_t base) {
-    struct gdtr {
-        uint16_t limit;
-        uintptr_t address;
-    } __PACKED;
-    // During VM exit GDTR limit is always set to 0xffff and instead of
-    // trying to maintain the limit aligned with the actual GDT size we
-    // decided to just keep it 0xffff all the time and instead of relying
-    // on the limit just map GDT in the way that accesses beyond GDT cause
-    // page faults. This allows us to avoid calling LGDT on every VM exit.
-    struct gdtr gdtr = { .limit = 0xffff, .address = base };
-    x86_lgdt((uintptr_t)&gdtr);
-}
-
-void gdt_setup(void);
-uintptr_t gdt_get(void);
-
-__END_CDECLS
-
-#endif
diff --git a/kernel/arch/x86/include/arch/x86/feature.h b/kernel/arch/x86/include/arch/x86/feature.h
deleted file mode 100644
index 7dde735..0000000
--- a/kernel/arch/x86/include/arch/x86/feature.h
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <assert.h>
-#include <zircon/compiler.h>
-#include <stdint.h>
-#include <arch/x86.h>
-
-__BEGIN_CDECLS
-
-#define MAX_SUPPORTED_CPUID     (0x17)
-#define MAX_SUPPORTED_CPUID_HYP (0x40000001)
-#define MAX_SUPPORTED_CPUID_EXT (0x8000001e)
-
-struct cpuid_leaf {
-    uint32_t a;
-    uint32_t b;
-    uint32_t c;
-    uint32_t d;
-};
-
-enum x86_cpuid_leaf_num {
-    X86_CPUID_BASE = 0,
-    X86_CPUID_MODEL_FEATURES = 0x1,
-    X86_CPUID_CACHE_V1 = 0x2,
-    X86_CPUID_CACHE_V2 = 0x4,
-    X86_CPUID_MON = 0x5,
-    X86_CPUID_THERMAL_AND_POWER = 0x6,
-    X86_CPUID_EXTENDED_FEATURE_FLAGS = 0x7,
-    X86_CPUID_PERFORMANCE_MONITORING = 0xa,
-    X86_CPUID_TOPOLOGY = 0xb,
-    X86_CPUID_XSAVE = 0xd,
-    X86_CPUID_PT = 0x14,
-    X86_CPUID_TSC = 0x15,
-
-    X86_CPUID_HYP_BASE = 0x40000000,
-    X86_CPUID_HYP_VENDOR = 0x40000000,
-    X86_CPUID_KVM_FEATURES = 0x40000001,
-
-    X86_CPUID_EXT_BASE = 0x80000000,
-    X86_CPUID_BRAND = 0x80000002,
-    X86_CPUID_ADDR_WIDTH = 0x80000008,
-    X86_CPUID_AMD_TOPOLOGY = 0x8000001e,
-};
-
-struct x86_cpuid_bit {
-    enum x86_cpuid_leaf_num leaf_num;
-    uint8_t word;
-    uint8_t bit;
-};
-
-#define X86_CPUID_BIT(leaf, word, bit) \
-        (struct x86_cpuid_bit){(enum x86_cpuid_leaf_num)(leaf), (word), (bit)}
-
-void x86_feature_init(void);
-
-static inline const struct cpuid_leaf *x86_get_cpuid_leaf(enum x86_cpuid_leaf_num leaf)
-{
-    extern struct cpuid_leaf _cpuid[MAX_SUPPORTED_CPUID + 1];
-    extern struct cpuid_leaf _cpuid_hyp[MAX_SUPPORTED_CPUID_HYP - X86_CPUID_HYP_BASE + 1];
-    extern struct cpuid_leaf _cpuid_ext[MAX_SUPPORTED_CPUID_EXT - X86_CPUID_EXT_BASE + 1];
-    extern uint32_t max_cpuid;
-    extern uint32_t max_ext_cpuid;
-    extern uint32_t max_hyp_cpuid;
-
-    if (leaf < X86_CPUID_HYP_BASE) {
-        if (unlikely(leaf > max_cpuid))
-            return NULL;
-
-        return &_cpuid[leaf];
-    } else if (leaf < X86_CPUID_EXT_BASE) {
-        if (unlikely(leaf > max_hyp_cpuid))
-            return NULL;
-
-        return &_cpuid_hyp[(uint32_t)leaf - (uint32_t)X86_CPUID_HYP_BASE];
-    } else {
-        if (unlikely(leaf > max_ext_cpuid))
-            return NULL;
-
-        return &_cpuid_ext[(uint32_t)leaf - (uint32_t)X86_CPUID_EXT_BASE];
-    }
-}
-/* Retrieve the specified subleaf.  This function is not cached.
- * Returns false if leaf num is invalid */
-bool x86_get_cpuid_subleaf(
-        enum x86_cpuid_leaf_num, uint32_t, struct cpuid_leaf *);
-
-static inline bool x86_feature_test(struct x86_cpuid_bit bit)
-{
-    DEBUG_ASSERT (bit.word <= 3 && bit.bit <= 31);
-
-    if (bit.word > 3 || bit.bit > 31)
-        return false;
-
-    const struct cpuid_leaf *leaf = x86_get_cpuid_leaf(bit.leaf_num);
-    if (!leaf)
-        return false;
-
-    switch (bit.word) {
-        case 0: return !!((1u << bit.bit) & leaf->a);
-        case 1: return !!((1u << bit.bit) & leaf->b);
-        case 2: return !!((1u << bit.bit) & leaf->c);
-        case 3: return !!((1u << bit.bit) & leaf->d);
-        default: return false;
-    }
-}
-
-void x86_feature_debug(void);
-
-/* add feature bits to test here */
-/* format: X86_CPUID_BIT(cpuid leaf, register (eax-edx:0-3), bit) */
-#define X86_FEATURE_SSE3                X86_CPUID_BIT(0x1, 2, 0)
-#define X86_FEATURE_MON                 X86_CPUID_BIT(0x1, 2, 3)
-#define X86_FEATURE_VMX                 X86_CPUID_BIT(0x1, 2, 5)
-#define X86_FEATURE_TM2                 X86_CPUID_BIT(0x1, 2, 8)
-#define X86_FEATURE_SSSE3               X86_CPUID_BIT(0x1, 2, 9)
-#define X86_FEATURE_PDCM                X86_CPUID_BIT(0x1, 2, 15)
-#define X86_FEATURE_PCID                X86_CPUID_BIT(0x1, 2, 17)
-#define X86_FEATURE_SSE4_1              X86_CPUID_BIT(0x1, 2, 19)
-#define X86_FEATURE_SSE4_2              X86_CPUID_BIT(0x1, 2, 20)
-#define X86_FEATURE_X2APIC              X86_CPUID_BIT(0x1, 2, 21)
-#define X86_FEATURE_TSC_DEADLINE        X86_CPUID_BIT(0x1, 2, 24)
-#define X86_FEATURE_AESNI               X86_CPUID_BIT(0x1, 2, 25)
-#define X86_FEATURE_XSAVE               X86_CPUID_BIT(0x1, 2, 26)
-#define X86_FEATURE_AVX                 X86_CPUID_BIT(0x1, 2, 28)
-#define X86_FEATURE_RDRAND              X86_CPUID_BIT(0x1, 2, 30)
-#define X86_FEATURE_HYPERVISOR          X86_CPUID_BIT(0x1, 2, 31)
-#define X86_FEATURE_FPU                 X86_CPUID_BIT(0x1, 3, 0)
-#define X86_FEATURE_SEP                 X86_CPUID_BIT(0x1, 3, 11)
-#define X86_FEATURE_CLFLUSH             X86_CPUID_BIT(0x1, 3, 19)
-#define X86_FEATURE_ACPI                X86_CPUID_BIT(0x1, 3, 22)
-#define X86_FEATURE_MMX                 X86_CPUID_BIT(0x1, 3, 23)
-#define X86_FEATURE_FXSR                X86_CPUID_BIT(0x1, 3, 24)
-#define X86_FEATURE_SSE                 X86_CPUID_BIT(0x1, 3, 25)
-#define X86_FEATURE_SSE2                X86_CPUID_BIT(0x1, 3, 26)
-#define X86_FEATURE_TM                  X86_CPUID_BIT(0x1, 3, 29)
-#define X86_FEATURE_DTS                 X86_CPUID_BIT(0x6, 0, 0)
-#define X86_FEATURE_PLN                 X86_CPUID_BIT(0x6, 0, 4)
-#define X86_FEATURE_PTM                 X86_CPUID_BIT(0x6, 0, 6)
-#define X86_FEATURE_HWP                 X86_CPUID_BIT(0x6, 0, 7)
-#define X86_FEATURE_HWP_NOT             X86_CPUID_BIT(0x6, 0, 8)
-#define X86_FEATURE_HWP_ACT             X86_CPUID_BIT(0x6, 0, 9)
-#define X86_FEATURE_HWP_PREF            X86_CPUID_BIT(0x6, 0, 10)
-#define X86_FEATURE_HW_FEEDBACK         X86_CPUID_BIT(0x6, 2, 0)
-#define X86_FEATURE_PERF_BIAS           X86_CPUID_BIT(0x6, 2, 3)
-#define X86_FEATURE_FSGSBASE            X86_CPUID_BIT(0x7, 1, 0)
-#define X86_FEATURE_TSC_ADJUST          X86_CPUID_BIT(0x7, 1, 1)
-#define X86_FEATURE_AVX2                X86_CPUID_BIT(0x7, 1, 5)
-#define X86_FEATURE_SMEP                X86_CPUID_BIT(0x7, 1, 7)
-#define X86_FEATURE_ERMS                X86_CPUID_BIT(0x7, 1, 9)
-#define X86_FEATURE_INVPCID             X86_CPUID_BIT(0x7, 1, 10)
-#define X86_FEATURE_RDSEED              X86_CPUID_BIT(0x7, 1, 18)
-#define X86_FEATURE_SMAP                X86_CPUID_BIT(0x7, 1, 20)
-#define X86_FEATURE_CLFLUSHOPT          X86_CPUID_BIT(0x7, 1, 23)
-#define X86_FEATURE_CLWB                X86_CPUID_BIT(0x7, 1, 24)
-#define X86_FEATURE_PT                  X86_CPUID_BIT(0x7, 1, 25)
-#define X86_FEATURE_UMIP                X86_CPUID_BIT(0x7, 2, 2)
-#define X86_FEATURE_PKU                 X86_CPUID_BIT(0x7, 2, 3)
-#define X86_FEATURE_IBRS_IBPB           X86_CPUID_BIT(0x7, 3, 26)
-#define X86_FEATURE_STIBP               X86_CPUID_BIT(0x7, 3, 27)
-#define X86_FEATURE_SSBD                X86_CPUID_BIT(0x7, 3, 31)
-
-#define X86_FEATURE_KVM_PVCLOCK_STABLE  X86_CPUID_BIT(0x40000001, 0, 24)
-#define X86_FEATURE_AMD_TOPO            X86_CPUID_BIT(0x80000001, 2, 22)
-#define X86_FEATURE_SYSCALL             X86_CPUID_BIT(0x80000001, 3, 11)
-#define X86_FEATURE_NX                  X86_CPUID_BIT(0x80000001, 3, 20)
-#define X86_FEATURE_HUGE_PAGE           X86_CPUID_BIT(0x80000001, 3, 26)
-#define X86_FEATURE_RDTSCP              X86_CPUID_BIT(0x80000001, 3, 27)
-#define X86_FEATURE_INVAR_TSC           X86_CPUID_BIT(0x80000007, 3, 8)
-
-/* legacy accessors */
-static inline uint8_t x86_linear_address_width(void)
-{
-    const struct cpuid_leaf *leaf = x86_get_cpuid_leaf(X86_CPUID_ADDR_WIDTH);
-    if (!leaf)
-        return 0;
-
-    /*
-     Extracting bit 15:8 from eax register
-     Bits 15-08: #Linear Address Bits
-    */
-    return (leaf->a >> 8) & 0xff;
-}
-
-static inline uint8_t x86_physical_address_width(void)
-{
-    const struct cpuid_leaf *leaf = x86_get_cpuid_leaf(X86_CPUID_ADDR_WIDTH);
-    if (!leaf)
-        return 0;
-
-    /*
-     Extracting bit 7:0 from eax register
-     Bits 07-00: #Physical Address Bits
-    */
-    return leaf->a & 0xff;
-}
-
-static inline uint32_t x86_get_clflush_line_size(void)
-{
-    const struct cpuid_leaf *leaf = x86_get_cpuid_leaf(X86_CPUID_MODEL_FEATURES);
-    if (!leaf)
-        return 0;
-
-    /*
-     Extracting bit 15:8 from ebx register
-     Bits 15-08: #CLFLUSH line size in quadwords
-    */
-    return ((leaf->b >> 8) & 0xff) * 8u;
-}
-
-/* cpu vendors */
-enum x86_vendor_list {
-    X86_VENDOR_UNKNOWN,
-    X86_VENDOR_INTEL,
-    X86_VENDOR_AMD
-};
-
-extern enum x86_vendor_list x86_vendor;
-
-/* topology */
-
-#define X86_TOPOLOGY_INVALID 0
-#define X86_TOPOLOGY_SMT 1
-#define X86_TOPOLOGY_CORE 2
-
-struct x86_topology_level {
-    /* The number of bits to right shift to identify the next-higher topological
-     * level */
-    uint8_t right_shift;
-    /* The type of relationship this level describes (hyperthread/core/etc) */
-    uint8_t type;
-};
-
-/**
- * @brief Fetch the topology information for the given level.
- *
- * This interface is uncached.
- *
- * @param level The level to retrieve info for.  Should initially be 0 and
- * incremented with each call.
- * @param info The structure to populate with the discovered information
- *
- * @return true if the requested level existed (and there may be higher levels).
- * @return false if the requested level does not exist (and no higher ones do).
- */
-bool x86_topology_enumerate(uint8_t level, struct x86_topology_level *info);
-
-struct x86_model_info {
-    uint8_t processor_type;
-    uint8_t family;
-    uint8_t model;
-    uint8_t stepping;
-
-    uint32_t display_family;
-    uint32_t display_model;
-};
-
-const struct x86_model_info * x86_get_model(void);
-
-enum x86_microarch_list {
-    X86_MICROARCH_UNKNOWN,
-    X86_MICROARCH_INTEL_NEHALEM,
-    X86_MICROARCH_INTEL_WESTMERE,
-    X86_MICROARCH_INTEL_SANDY_BRIDGE,
-    X86_MICROARCH_INTEL_IVY_BRIDGE,
-    X86_MICROARCH_INTEL_BROADWELL,
-    X86_MICROARCH_INTEL_HASWELL,
-    X86_MICROARCH_INTEL_SKYLAKE,
-    X86_MICROARCH_INTEL_KABYLAKE,
-    X86_MICROARCH_INTEL_SILVERMONT,
-    X86_MICROARCH_AMD_BULLDOZER,
-    X86_MICROARCH_AMD_JAGUAR,
-    X86_MICROARCH_AMD_ZEN,
-};
-extern enum x86_microarch_list x86_microarch;
-
-extern bool g_x86_feature_fsgsbase;
-
-enum x86_hypervisor_list {
-    X86_HYPERVISOR_UNKNOWN,
-    X86_HYPERVISOR_KVM,
-};
-
-extern enum x86_hypervisor_list x86_hypervisor;
-
-/* returns 0 if unknown, otherwise value in Hz */
-typedef uint64_t (*x86_get_timer_freq_func_t)(void);
-
-/* attempt to reboot the system; may fail and simply return */
-typedef void (*x86_reboot_system_func_t)(void);
-
-/* Structure for supporting per-microarchitecture kernel configuration */
-typedef struct {
-    x86_get_timer_freq_func_t get_apic_freq;
-    x86_get_timer_freq_func_t get_tsc_freq;
-    x86_reboot_system_func_t reboot_system;
-
-    bool disable_c1e;
-} x86_microarch_config_t;
-
-static inline const x86_microarch_config_t* x86_get_microarch_config(void) {
-    extern const x86_microarch_config_t* x86_microarch_config;
-    return x86_microarch_config;
-}
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86/general_regs.h b/kernel/arch/x86/include/arch/x86/general_regs.h
deleted file mode 100644
index 6f54e7d..0000000
--- a/kernel/arch/x86/include/arch/x86/general_regs.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// Userspace general regs are stored in two different structs:
-// - syscalls = x86_syscall_general_regs_t
-// - interrupts/exceptions = x86_iframe_t
-// A tagged pointer is stored in struct arch_thread to specify which one.
-#define X86_GENERAL_REGS_NONE    0
-#define X86_GENERAL_REGS_SYSCALL 1
-#define X86_GENERAL_REGS_IFRAME  2
-
-#ifndef __ASSEMBLER__
-
-#include <assert.h>
-#include <zircon/compiler.h>
-#include <stdint.h>
-
-__BEGIN_CDECLS
-
-// the structure used to hold the general purpose integer registers
-// when a syscall is suspended
-
-typedef struct {
-    uint64_t rax;
-    uint64_t rbx;
-    uint64_t rcx;
-    uint64_t rdx;
-    uint64_t rsi;
-    uint64_t rdi;
-    uint64_t rbp;
-    uint64_t rsp;
-    uint64_t r8;
-    uint64_t r9;
-    uint64_t r10;
-    uint64_t r11;
-    uint64_t r12;
-    uint64_t r13;
-    uint64_t r14;
-    uint64_t r15;
-    uint64_t rip;
-    uint64_t rflags;
-} x86_syscall_general_regs_t;
-
-__END_CDECLS
-
-#endif // !__ASSEMBLER__
diff --git a/kernel/arch/x86/include/arch/x86/idt.h b/kernel/arch/x86/include/arch/x86/idt.h
deleted file mode 100644
index 153b515..0000000
--- a/kernel/arch/x86/include/arch/x86/idt.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <assert.h>
-#include <zircon/compiler.h>
-
-__BEGIN_CDECLS
-
-struct idt_entry {
-    uint32_t w0, w1;
-    uint32_t w2, w3;
-};
-
-struct idt {
-    struct idt_entry entries[256];
-};
-
-static_assert(sizeof(struct idt_entry) == 16, "");
-static_assert(sizeof(struct idt) == 16 * 256, "");
-
-struct idtr {
-    uint16_t limit;
-    uintptr_t address;
-} __PACKED;
-
-enum idt_entry_type {
-    IDT_INTERRUPT_GATE64 = 0xe,
-    IDT_TRAP_GATE64 = 0xf,
-};
-
-enum idt_dpl {
-    IDT_DPL0 = 0,
-    IDT_DPL1 = 1,
-    IDT_DPL2 = 2,
-    IDT_DPL3 = 3,
-};
-
-/*
- * @brief Change an IDT entry
- *
- * Caution: Interrupts should probably be disabled when this is called
- *
- * @param idt Pointer to the IDT to change.
- * @param vec The vector to replace.
- * @param code_segment_sel The code segment selector to use on taking this
- *        interrupt.
- * @param entry_point_offset The offset of the code to begin executing (relative
- *        to the segment).
- * @param dpl The desired privilege level of the handler.
- * @param typ The type of interrupt handler
- */
-void idt_set_vector(
-        struct idt *idt,
-        uint8_t vec,
-        uint16_t code_segment_sel,
-        uintptr_t entry_point_offset,
-        enum idt_dpl dpl,
-        enum idt_entry_type typ);
-
-/*
- * @brief Set the Interrupt Stack Table index to use
- *
- * @param idt Pointer to the IDT to change.
- * @param vec The vector to change.
- * @param ist_idx A value in the range [0, 8) indicating which stack to use.
- *        If ist_idx == 0, use the normal stack for the target privilege level.
- */
-void idt_set_ist_index(struct idt *idt, uint8_t vec, uint8_t ist_idx);
-
-/*
- * @brief Initialize this IDT with our default values
- *
- * @param idt Pointer to the IDT to initialize
- */
-void idt_setup(struct idt *idt);
-
-/*
- * @brief Setup the read-only remapping of the IDT.
- */
-void idt_setup_readonly(void);
-
-/*
- * @brief Switch to thie given IDT
- *
- * @param idt Pointer to the IDT
- */
-static void idt_load(struct idt *idt) {
-    // After VM exit IDT limit is always set to 0xffff, so in order to avoid
-    // calling LIDT in hypervisor to restore the proper IDT limit after every
-    // VM exit in hypervisor we decided to use 0xffff all the time. There is
-    // no harm in doing that because IDT limit is only relevant if it's smaller
-    // than sizeof(struct idt) - 1 and doesn't affect anything otherwise.
-    struct idtr idtr = { .limit = 0xffff, .address = (uintptr_t)idt };
-    x86_lidt((uintptr_t)&idtr);
-}
-
-/*
- * @brief Get the read-only IDT.
- */
-struct idt * idt_get_readonly(void);
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86/interrupts.h b/kernel/arch/x86/include/arch/x86/interrupts.h
deleted file mode 100644
index 8562ce0..0000000
--- a/kernel/arch/x86/include/arch/x86/interrupts.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-enum x86_interrupt_vector {
-    X86_INT_DIVIDE_0 = 0,
-    X86_INT_DEBUG,
-    X86_INT_NMI,
-    X86_INT_BREAKPOINT,
-    X86_INT_OVERFLOW,
-    X86_INT_BOUND_RANGE,
-    X86_INT_INVALID_OP,
-    X86_INT_DEVICE_NA,
-    X86_INT_DOUBLE_FAULT,
-    X86_INT_INVALID_TSS = 0xa,
-    X86_INT_SEGMENT_NOT_PRESENT,
-    X86_INT_STACK_FAULT,
-    X86_INT_GP_FAULT,
-    X86_INT_PAGE_FAULT,
-    X86_INT_RESERVED,
-    X86_INT_FPU_FP_ERROR,
-    X86_INT_ALIGNMENT_CHECK,
-    X86_INT_MACHINE_CHECK,
-    X86_INT_SIMD_FP_ERROR,
-    X86_INT_VIRT,
-    X86_INT_MAX_INTEL_DEFINED = 0x1f,
-
-    X86_INT_PLATFORM_BASE = 0x20,
-    X86_INT_PLATFORM_MAX = 0xef,
-
-    X86_INT_LOCAL_APIC_BASE = 0xf0,
-    X86_INT_APIC_SPURIOUS = 0xf0,
-    X86_INT_APIC_TIMER,
-    X86_INT_APIC_ERROR,
-    X86_INT_APIC_PMI,
-    X86_INT_IPI_GENERIC,
-    X86_INT_IPI_RESCHEDULE,
-    X86_INT_IPI_INTERRUPT,
-    X86_INT_IPI_HALT,
-
-    X86_INT_MAX = 0xff,
-    X86_INT_COUNT,
-};
diff --git a/kernel/arch/x86/include/arch/x86/ioport.h b/kernel/arch/x86/include/arch/x86/ioport.h
deleted file mode 100644
index 28e00fa..0000000
--- a/kernel/arch/x86/include/arch/x86/ioport.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <kernel/spinlock.h>
-#include <ktl/unique_ptr.h>
-#include <sys/types.h>
-
-#include <bitmap/rle-bitmap.h>
-
-class IoBitmap {
-public:
-    // Return the IoBitmap associated with the current thread.
-    static IoBitmap& GetCurrent();
-
-    ~IoBitmap();
-
-    int SetIoBitmap(uint32_t port, uint32_t len, bool enable);
-
-private:
-    // Task used for updating IO permissions on each CPU.
-    static void UpdateTask(void* context);
-
-    friend void x86_set_tss_io_bitmap(IoBitmap& bitmap);
-    friend void x86_clear_tss_io_bitmap(IoBitmap& bitmap);
-
-    ktl::unique_ptr<bitmap::RleBitmap> bitmap_;
-    SpinLock lock_;
-};
diff --git a/kernel/arch/x86/include/arch/x86/mmu.h b/kernel/arch/x86/include/arch/x86/mmu.h
deleted file mode 100644
index 4fed4eb..0000000
--- a/kernel/arch/x86/include/arch/x86/mmu.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2008 Travis Geiselbrecht
-// Copyright (c) 2015 Intel Corporation
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/x86/page_tables/constants.h>
-
-/* top level defines for the x86 mmu */
-/* NOTE: the top part can be included from assembly */
-
-#define X86_EPT_R                 (1u << 0) /* R    Read     */
-#define X86_EPT_W                 (1u << 1) /* W    Write    */
-#define X86_EPT_X                 (1u << 2) /* X    Execute  */
-#define X86_EPT_A                 (1u << 8) /* A    Accessed */
-#define X86_EPT_D                 (1u << 9) /* D    Dirty    */
-
-/* From Volume 3, Section 28.2.6: EPT and Memory Typing */
-#define X86_EPT_MEMORY_TYPE_MASK  (7u << 3)
-#define X86_EPT_UC                (0u << 3) /* UC   Uncached memory type        */
-#define X86_EPT_WC                (1u << 3) /* WC   Write-combining memory type */
-#define X86_EPT_WT                (4u << 3) /* WT   Write-through memory type   */
-#define X86_EPT_WP                (5u << 3) /* WP   Write-protected memory type */
-#define X86_EPT_WB                (6u << 3) /* WB   Write-back memory type      */
-
-/* Page Attribute Table memory types, defined in Table 11-10 of Intel 3A */
-#define X86_PAT_UC                0x00 /* Uncached */
-#define X86_PAT_WC                0x01 /* Write-combining */
-#define X86_PAT_WT                0x04 /* Write-through */
-#define X86_PAT_WP                0x05 /* Write protected */
-#define X86_PAT_WB                0X06 /* Write-back */
-#define X86_PAT_UC_               0x07 /* Weakly Uncached (can be overridden by a WC MTRR setting) */
-
-/* Our configuration for the PAT indexes.  This must be kept in sync with the
- * selector definitions below it.  For safety, it is important to ensure that
- * the default mode is less cached than our substitution.  This ensures that
- * any mappings defined before we switch all CPUs to this new map will still
- * function correctly. */
-#define X86_PAT_INDEX0  X86_PAT_WB  /* default */
-#define X86_PAT_INDEX1  X86_PAT_WT  /* default */
-#define X86_PAT_INDEX2  X86_PAT_UC_ /* default */
-#define X86_PAT_INDEX3  X86_PAT_UC  /* default */
-#define X86_PAT_INDEX4  X86_PAT_WB  /* default */
-#define X86_PAT_INDEX5  X86_PAT_WT  /* default */
-#define X86_PAT_INDEX6  X86_PAT_UC_ /* default */
-#define X86_PAT_INDEX7  X86_PAT_WC  /* UC by default */
-
-/* These assume our defined PAT entries.  We need to update these if we decide
- * to change them PAT entries */
-#define X86_MMU_PTE_PAT_WRITEBACK               X86_PAT_PTE_SELECTOR(0)
-#define X86_MMU_PTE_PAT_WRITETHROUGH            X86_PAT_PTE_SELECTOR(1)
-#define X86_MMU_PTE_PAT_UNCACHABLE              X86_PAT_PTE_SELECTOR(3)
-#define X86_MMU_PTE_PAT_WRITE_COMBINING         X86_PAT_PTE_SELECTOR(7)
-#define X86_MMU_LARGE_PAT_WRITEBACK             X86_PAT_LARGE_SELECTOR(0)
-#define X86_MMU_LARGE_PAT_WRITETHROUGH          X86_PAT_LARGE_SELECTOR(1)
-#define X86_MMU_LARGE_PAT_UNCACHABLE            X86_PAT_LARGE_SELECTOR(3)
-#define X86_MMU_LARGE_PAT_WRITE_COMBINING       X86_PAT_LARGE_SELECTOR(7)
-
-/* default flags for inner page directory entries */
-#define X86_KERNEL_PD_FLAGS (X86_MMU_PG_RW | X86_MMU_PG_P)
-
-/* default flags for 2MB/4MB/1GB page directory entries */
-#define X86_KERNEL_PD_LP_FLAGS (X86_MMU_PG_G | X86_MMU_PG_PS | X86_MMU_PG_RW | X86_MMU_PG_P)
-
-#define X86_MMU_PG_NX           (1UL << 63)
-
-#define X86_PAGING_LEVELS       4
-
-#define MMU_GUEST_SIZE_SHIFT    48
-
-/* page fault error code flags */
-#define PFEX_P      (1<<0)
-#define PFEX_W      (1<<1)
-#define PFEX_U      (1<<2)
-#define PFEX_RSV    (1<<3)
-#define PFEX_I      (1<<4)
-#define PFEX_PK     (1<<5)
-#define PFEX_SGX    (1<<15)
-
-/* C defines below */
-#ifndef __ASSEMBLER__
-
-#include <sys/types.h>
-#include <zircon/compiler.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-__BEGIN_CDECLS
-
-struct map_range {
-    vaddr_t start_vaddr;
-    paddr_t start_paddr; /* Physical address in the PAE mode is 32 bits wide */
-    size_t size;
-};
-
-bool x86_is_vaddr_canonical(vaddr_t vaddr);
-bool x86_mmu_check_paddr(paddr_t paddr);
-
-void x86_mmu_percpu_init(void);
-void x86_mmu_early_init(void);
-void x86_mmu_init(void);
-
-paddr_t x86_kernel_cr3(void);
-
-__END_CDECLS
-
-#endif // !__ASSEMBLER__
diff --git a/kernel/arch/x86/include/arch/x86/mmu_mem_types.h b/kernel/arch/x86/include/arch/x86/mmu_mem_types.h
deleted file mode 100644
index 33f17f0..0000000
--- a/kernel/arch/x86/include/arch/x86/mmu_mem_types.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-#pragma once
-
-#include <kernel/cpu.h>
-#include <zircon/compiler.h>
-
-__BEGIN_CDECLS
-
-void x86_mmu_mem_type_init(void);
-void x86_pat_sync(cpu_mask_t targets);
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86/mp.h b/kernel/arch/x86/include/arch/x86/mp.h
deleted file mode 100644
index 377e958..0000000
--- a/kernel/arch/x86/include/arch/x86/mp.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-/* describes the per cpu structure pointed to by gs: in the kernel */
-
-/* offsets into this structure, used by assembly */
-#define PERCPU_DIRECT_OFFSET           0x0
-#define PERCPU_CURRENT_THREAD_OFFSET   0x8
-//      ZX_TLS_STACK_GUARD_OFFSET      0x10
-//      ZX_TLS_UNSAFE_SP_OFFSET        0x18
-#define PERCPU_SAVED_USER_SP_OFFSET    0x20
-#define PERCPU_GPF_RETURN_OFFSET       0x40
-#define PERCPU_CPU_NUM_OFFSET          0x48
-#define PERCPU_DEFAULT_TSS_OFFSET      0x50
-
-/* offset of default_tss.rsp0 */
-#define PERCPU_KERNEL_SP_OFFSET        (PERCPU_DEFAULT_TSS_OFFSET + 4)
-
-#ifndef __ASSEMBLER__
-
-#include <arch/x86.h>
-#include <arch/x86/idt.h>
-#include <assert.h>
-#include <kernel/align.h>
-#include <kernel/cpu.h>
-#include <stdint.h>
-#include <zircon/compiler.h>
-#include <zircon/tls.h>
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-struct thread;
-
-struct x86_percpu {
-    /* a direct pointer to ourselves */
-    struct x86_percpu *direct;
-
-    /* the current thread */
-    struct thread *current_thread;
-
-    // The offsets of these two slots are published in
-    // system/public/zircon/tls.h and known to the compiler.
-    uintptr_t stack_guard;
-    uintptr_t kernel_unsafe_sp;
-
-    /* temporarily saved during a syscall */
-    uintptr_t saved_user_sp;
-
-    /* Whether blocking is disallowed.  See arch_blocking_disallowed(). */
-    uint32_t blocking_disallowed;
-
-    /* Memory for IPI-free rescheduling of idle CPUs with monitor/mwait. */
-    volatile uint8_t* monitor;
-
-    /* local APIC id */
-    uint32_t apic_id;
-
-    /* If nonzero and we receive a GPF, change the return IP to this value. */
-    uintptr_t gpf_return_target;
-
-    /* CPU number */
-    cpu_num_t cpu_num;
-
-    /* This CPU's default TSS */
-    tss_t default_tss __ALIGNED(16);
-
-    /* Reserved space for interrupt stacks */
-    uint8_t interrupt_stacks[NUM_ASSIGNED_IST_ENTRIES][PAGE_SIZE] __ALIGNED(16);
-} __CPU_ALIGN;
-
-static_assert(__offsetof(struct x86_percpu, direct) == PERCPU_DIRECT_OFFSET, "");
-static_assert(__offsetof(struct x86_percpu, current_thread) == PERCPU_CURRENT_THREAD_OFFSET, "");
-static_assert(__offsetof(struct x86_percpu, stack_guard) == ZX_TLS_STACK_GUARD_OFFSET, "");
-static_assert(__offsetof(struct x86_percpu, kernel_unsafe_sp) == ZX_TLS_UNSAFE_SP_OFFSET, "");
-static_assert(__offsetof(struct x86_percpu, saved_user_sp) == PERCPU_SAVED_USER_SP_OFFSET, "");
-static_assert(__offsetof(struct x86_percpu, gpf_return_target) == PERCPU_GPF_RETURN_OFFSET, "");
-static_assert(__offsetof(struct x86_percpu, cpu_num) == PERCPU_CPU_NUM_OFFSET, "");
-static_assert(__offsetof(struct x86_percpu, default_tss) == PERCPU_DEFAULT_TSS_OFFSET, "");
-static_assert(__offsetof(struct x86_percpu, default_tss.rsp0) == PERCPU_KERNEL_SP_OFFSET, "");
-
-extern struct x86_percpu bp_percpu;
-extern struct x86_percpu *ap_percpus;
-
-// This needs to be run very early in the boot process from start.S and as
-// each CPU is brought up.
-void x86_init_percpu(uint cpu_num);
-
-/* used to set the bootstrap processor's apic_id once the APIC is initialized */
-void x86_set_local_apic_id(uint32_t apic_id);
-
-int x86_apic_id_to_cpu_num(uint32_t apic_id);
-
-// Allocate all of the necessary structures for all of the APs to run.
-zx_status_t x86_allocate_ap_structures(uint32_t *apic_ids, uint8_t cpu_count);
-
-static inline struct x86_percpu *x86_get_percpu(void)
-{
-    return (struct x86_percpu *)x86_read_gs_offset64(PERCPU_DIRECT_OFFSET);
-}
-
-static inline cpu_num_t arch_curr_cpu_num(void)
-{
-    return x86_read_gs_offset32(PERCPU_CPU_NUM_OFFSET);
-}
-
-extern uint8_t x86_num_cpus;
-static uint arch_max_num_cpus(void)
-{
-    return x86_num_cpus;
-}
-
-#define READ_PERCPU_FIELD32(field) \
-    x86_read_gs_offset32(offsetof(struct x86_percpu, field))
-
-#define WRITE_PERCPU_FIELD32(field, value) \
-    x86_write_gs_offset32(offsetof(struct x86_percpu, field), (value))
-
-void x86_ipi_halt_handler(void*) __NO_RETURN;
-void x86_secondary_entry(volatile int *aps_still_booting, thread_t *thread);
-void x86_force_halt_all_but_local_and_bsp(void);
-
-__END_CDECLS
-
-#endif // !__ASSEMBLER__
diff --git a/kernel/arch/x86/include/arch/x86/perf_mon.h b/kernel/arch/x86/include/arch/x86/perf_mon.h
deleted file mode 100644
index f12728d..0000000
--- a/kernel/arch/x86/include/arch/x86/perf_mon.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <err.h>
-#include <stdint.h>
-
-#include <fbl/ref_ptr.h>
-#include <vm/vm_object.h>
-
-#include <arch/x86.h>
-
-#include <lib/zircon-internal/device/cpu-trace/intel-pm.h>
-
-zx_status_t arch_perfmon_get_properties(zx_x86_pmu_properties_t* state);
-
-zx_status_t arch_perfmon_init();
-
-zx_status_t arch_perfmon_assign_buffer(uint32_t cpu, fbl::RefPtr<VmObject> vmo);
-
-zx_status_t arch_perfmon_stage_config(zx_x86_pmu_config_t* config);
-
-zx_status_t arch_perfmon_start();
-
-zx_status_t arch_perfmon_stop();
-
-zx_status_t arch_perfmon_fini();
-
-void apic_pmi_interrupt_handler(x86_iframe_t *frame);
diff --git a/kernel/arch/x86/include/arch/x86/proc_trace.h b/kernel/arch/x86/include/arch/x86/proc_trace.h
deleted file mode 100644
index 8366721..0000000
--- a/kernel/arch/x86/include/arch/x86/proc_trace.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <err.h>
-#include <stdint.h>
-
-#include <lib/zircon-internal/device/cpu-trace/intel-pt.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-void x86_processor_trace_init(void);
-
-__END_CDECLS
-
-#ifdef __cplusplus
-
-typedef enum {
-    IPT_TRACE_CPUS,
-    IPT_TRACE_THREADS
-} ipt_trace_mode_t;
-
-zx_status_t x86_ipt_alloc_trace(ipt_trace_mode_t mode, uint32_t num_traces);
-
-zx_status_t x86_ipt_free_trace();
-
-zx_status_t x86_ipt_start();
-
-zx_status_t x86_ipt_stop();
-
-zx_status_t x86_ipt_stage_trace_data(zx_itrace_buffer_descriptor_t descriptor,
-                                     const zx_x86_pt_regs_t* regs);
-
-zx_status_t x86_ipt_get_trace_data(zx_itrace_buffer_descriptor_t descriptor,
-                                   zx_x86_pt_regs_t* regs);
-
-#endif // __cplusplus
diff --git a/kernel/arch/x86/include/arch/x86/pvclock.h b/kernel/arch/x86/include/arch/x86/pvclock.h
deleted file mode 100644
index 0c6b70e..0000000
--- a/kernel/arch/x86/include/arch/x86/pvclock.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-static constexpr uint32_t kKvmSystemTimeMsrOld = 0x12;
-static constexpr uint32_t kKvmSystemTimeMsr = 0x4b564d01;
-
-static constexpr uint32_t kKvmBootTimeOld = 0x11;
-static constexpr uint32_t kKvmBootTime = 0x4b564d00;
-
-static constexpr uint32_t kKvmFeatureClockSourceOld = 1u << 0;
-static constexpr uint32_t kKvmFeatureClockSource = 1u << 3;
-
-static constexpr uint8_t kKvmSystemTimeStable = 1u << 0;
-
-// Both structures below are part of the ABI used by Xen and KVM, this ABI is not
-// defined by use we just follow it. For more detail please refer to the
-// documentation (https://www.kernel.org/doc/Documentation/virtual/kvm/msr.txt).
-struct pvclock_boot_time {
-    // With multiple VCPUs it is possible that one VCPU can try to read boot time
-    // while we are updating it because another VCPU asked for the update. In this
-    // case odd version value serves as an indicator for the guest that update is
-    // in progress. Therefore we need to update version before we write anything
-    // else and after, also we need to user proper memory barriers. The same logic
-    // applies to system time version below, even though system time is per VCPU
-    // others VCPUs still can access system times of other VCPUs (Linux however
-    // never does that).
-    uint32_t version;
-    uint32_t seconds;
-    uint32_t nseconds;
-} __PACKED;
-static_assert(sizeof(struct pvclock_boot_time) == 12, "sizeof(pvclock_boot_time) should be 12");
-
-struct pvclock_system_time {
-    uint32_t version;
-    uint32_t pad0;
-    uint64_t tsc_timestamp;
-    uint64_t system_time;
-    uint32_t tsc_mul;
-    int8_t tsc_shift;
-    uint8_t flags;
-    uint8_t pad1[2];
-} __PACKED;
-static_assert(sizeof(struct pvclock_system_time) == 32, "sizeof(pvclock_system_time) should be 32");
-
-zx_status_t pvclock_init();
-bool pvclock_is_present();
-bool pvclock_is_stable();
-uint64_t pvclock_get_tsc_freq();
diff --git a/kernel/arch/x86/include/arch/x86/registers.h b/kernel/arch/x86/include/arch/x86/registers.h
deleted file mode 100644
index 9f231e7..0000000
--- a/kernel/arch/x86/include/arch/x86/registers.h
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// This header is intended to be included in both C and ASM
-#define X86_CR0_PE                      0x00000001 /* protected mode enable */
-#define X86_CR0_MP                      0x00000002 /* monitor coprocessor */
-#define X86_CR0_EM                      0x00000004 /* emulation */
-#define X86_CR0_TS                      0x00000008 /* task switched */
-#define X86_CR0_NE                      0x00000020 /* enable x87 exception */
-#define X86_CR0_WP                      0x00010000 /* supervisor write protect */
-#define X86_CR0_NW                      0x20000000 /* not write-through */
-#define X86_CR0_CD                      0x40000000 /* cache disable */
-#define X86_CR0_PG                      0x80000000 /* enable paging */
-#define X86_CR4_PAE                     0x00000020 /* PAE paging */
-#define X86_CR4_PGE                     0x00000080 /* page global enable */
-#define X86_CR4_OSFXSR                  0x00000200 /* os supports fxsave */
-#define X86_CR4_OSXMMEXPT               0x00000400 /* os supports xmm exception */
-#define X86_CR4_UMIP                    0x00000800 /* User-mode instruction prevention */
-#define X86_CR4_VMXE                    0x00002000 /* enable vmx */
-#define X86_CR4_FSGSBASE                0x00010000 /* enable {rd,wr}{fs,gs}base */
-#define X86_CR4_PCIDE                   0x00020000 /* Process-context ID enable  */
-#define X86_CR4_OSXSAVE                 0x00040000 /* os supports xsave */
-#define X86_CR4_SMEP                    0x00100000 /* SMEP protection enabling */
-#define X86_CR4_SMAP                    0x00200000 /* SMAP protection enabling */
-#define X86_EFER_SCE                    0x00000001 /* enable SYSCALL */
-#define X86_EFER_LME                    0x00000100 /* long mode enable */
-#define X86_EFER_LMA                    0x00000400 /* long mode active */
-#define X86_EFER_NXE                    0x00000800 /* to enable execute disable bit */
-#define X86_MSR_IA32_PLATFORM_ID        0x00000017 /* platform id */
-#define X86_MSR_IA32_APIC_BASE          0x0000001b /* APIC base physical address */
-#define X86_MSR_IA32_TSC_ADJUST         0x0000003b /* TSC adjust */
-#define X86_MSR_IA32_BIOS_SIGN_ID       0x0000008b /* BIOS update signature */
-#define X86_MSR_IA32_MTRRCAP            0x000000fe /* MTRR capability */
-#define X86_MSR_IA32_SYSENTER_CS        0x00000174 /* SYSENTER CS */
-#define X86_MSR_IA32_SYSENTER_ESP       0x00000175 /* SYSENTER ESP */
-#define X86_MSR_IA32_SYSENTER_EIP       0x00000176 /* SYSENTER EIP */
-#define X86_MSR_IA32_MCG_CAP            0x00000179 /* global machine check capability */
-#define X86_MSR_IA32_MCG_STATUS         0x0000017a /* global machine check status */
-#define X86_MSR_IA32_MISC_ENABLE        0x000001a0 /* enable/disable misc processor features */
-#define X86_MSR_IA32_TEMPERATURE_TARGET 0x000001a2 /* Temperature target */
-#define X86_MSR_IA32_MTRR_PHYSBASE0     0x00000200 /* MTRR PhysBase0 */
-#define X86_MSR_IA32_MTRR_PHYSMASK0     0x00000201 /* MTRR PhysMask0 */
-#define X86_MSR_IA32_MTRR_PHYSMASK9     0x00000213 /* MTRR PhysMask9 */
-#define X86_MSR_IA32_MTRR_DEF_TYPE      0x000002ff /* MTRR default type */
-#define X86_MSR_IA32_MTRR_FIX64K_00000  0x00000250 /* MTRR FIX64K_00000 */
-#define X86_MSR_IA32_MTRR_FIX16K_80000  0x00000258 /* MTRR FIX16K_80000 */
-#define X86_MSR_IA32_MTRR_FIX16K_A0000  0x00000259 /* MTRR FIX16K_A0000 */
-#define X86_MSR_IA32_MTRR_FIX4K_C0000   0x00000268 /* MTRR FIX4K_C0000 */
-#define X86_MSR_IA32_MTRR_FIX4K_F8000   0x0000026f /* MTRR FIX4K_F8000 */
-#define X86_MSR_IA32_PAT                0x00000277 /* PAT */
-#define X86_MSR_IA32_TSC_DEADLINE       0x000006e0 /* TSC deadline */
-#define X86_MSR_IA32_EFER               0xc0000080 /* EFER */
-#define X86_MSR_IA32_STAR               0xc0000081 /* system call address */
-#define X86_MSR_IA32_LSTAR              0xc0000082 /* long mode call address */
-#define X86_MSR_IA32_CSTAR              0xc0000083 /* ia32-e compat call address */
-#define X86_MSR_IA32_FMASK              0xc0000084 /* system call flag mask */
-#define X86_MSR_IA32_FS_BASE            0xc0000100 /* fs base address */
-#define X86_MSR_IA32_GS_BASE            0xc0000101 /* gs base address */
-#define X86_MSR_IA32_KERNEL_GS_BASE     0xc0000102 /* kernel gs base */
-#define X86_MSR_IA32_TSC_AUX            0xc0000103 /* TSC aux */
-#define X86_MSR_IA32_PM_ENABLE          0x00000770 /* enable/disable HWP */
-#define X86_MSR_IA32_HWP_CAPABILITIES   0x00000771 /* HWP performance range enumeration */
-#define X86_MSR_IA32_HWP_REQUEST        0x00000774 /* power manage control hints */
-#define X86_CR4_PSE                     0xffffffef /* Disabling PSE bit in the CR4 */
-
-// Non-architectural MSRs
-#define X86_MSR_RAPL_POWER_UNIT         0x00000606 /* RAPL unit multipliers */
-#define X86_MSR_PKG_POWER_LIMIT         0x00000610 /* Package power limits */
-#define X86_MSR_PKG_POWER_LIMIT_PL1_CLAMP   (1 << 16)
-#define X86_MSR_PKG_POWER_LIMIT_PL1_ENABLE  (1 << 15)
-#define X86_MSR_PKG_ENERGY_STATUS       0x00000611 /* Package energy status */
-#define X86_MSR_PKG_POWER_INFO          0x00000614 /* Package power range info */
-#define X86_MSR_DRAM_POWER_LIMIT        0x00000618 /* DRAM RAPL power limit control */
-#define X86_MSR_DRAM_ENERGY_STATUS      0x00000619 /* DRAM energy status */
-#define X86_MSR_PP0_POWER_LIMIT         0x00000638 /* PP0 RAPL power limit control */
-#define X86_MSR_PP0_ENERGY_STATUS       0x00000639 /* PP0 energy status */
-#define X86_MSR_PP1_POWER_LIMIT         0x00000640 /* PP1 RAPL power limit control */
-#define X86_MSR_PP1_ENERGY_STATUS       0x00000641 /* PP1 energy status */
-#define X86_MSR_PLATFORM_ENERGY_COUNTER 0x0000064d /* Platform energy counter */
-#define X86_MSR_PLATFORM_POWER_LIMIT    0x0000065c /* Platform power limit control */
-
-/* EFLAGS/RFLAGS */
-#define X86_FLAGS_CF                    (1<<0)
-#define X86_FLAGS_PF                    (1<<2)
-#define X86_FLAGS_AF                    (1<<4)
-#define X86_FLAGS_ZF                    (1<<6)
-#define X86_FLAGS_SF                    (1<<7)
-#define X86_FLAGS_TF                    (1<<8)
-#define X86_FLAGS_IF                    (1<<9)
-#define X86_FLAGS_DF                    (1<<10)
-#define X86_FLAGS_OF                    (1<<11)
-#define X86_FLAGS_STATUS_MASK           (0xfff)
-#define X86_FLAGS_IOPL_MASK             (3<<12)
-#define X86_FLAGS_IOPL_SHIFT            (12)
-#define X86_FLAGS_NT                    (1<<14)
-#define X86_FLAGS_RF                    (1<<16)
-#define X86_FLAGS_VM                    (1<<17)
-#define X86_FLAGS_AC                    (1<<18)
-#define X86_FLAGS_VIF                   (1<<19)
-#define X86_FLAGS_VIP                   (1<<20)
-#define X86_FLAGS_ID                    (1<<21)
-#define X86_FLAGS_RESERVED_ONES         0x2
-#define X86_FLAGS_RESERVED              0xffc0802a
-#define X86_FLAGS_USER                  (X86_FLAGS_CF | \
-                                         X86_FLAGS_PF | \
-                                         X86_FLAGS_AF | \
-                                         X86_FLAGS_ZF | \
-                                         X86_FLAGS_SF | \
-                                         X86_FLAGS_TF | \
-                                         X86_FLAGS_DF | \
-                                         X86_FLAGS_OF | \
-                                         X86_FLAGS_NT | \
-                                         X86_FLAGS_AC | \
-                                         X86_FLAGS_ID)
-
-/* DR6 */
-#define X86_DR6_B0 (1ul << 0)
-#define X86_DR6_B1 (1ul << 1)
-#define X86_DR6_B2 (1ul << 2)
-#define X86_DR6_B3 (1ul << 3)
-#define X86_DR6_BD (1ul << 13)
-#define X86_DR6_BS (1ul << 14)
-#define X86_DR6_BT (1ul << 15)
-
-// NOTE: DR6 is used as a read-only status registers, and it is not writeable through userspace.
-//       Any bits attempted to be written will be ignored.
-#define X86_DR6_USER_MASK (X86_DR6_B0 | \
-                           X86_DR6_B1 | \
-                           X86_DR6_B2 | \
-                           X86_DR6_B3 | \
-                           X86_DR6_BD | \
-                           X86_DR6_BS | \
-                           X86_DR6_BT)
-/* Only bits in X86_DR6_USER_MASK are writeable.
- * Bits 12 and 32:63 must be written with 0, the rest as 1s */
-#define X86_DR6_MASK (0xffff0ff0ul)
-
-/* DR7 */
-#define X86_DR7_L0    (1ul << 0)
-#define X86_DR7_G0    (1ul << 1)
-#define X86_DR7_L1    (1ul << 2)
-#define X86_DR7_G1    (1ul << 3)
-#define X86_DR7_L2    (1ul << 4)
-#define X86_DR7_G2    (1ul << 5)
-#define X86_DR7_L3    (1ul << 6)
-#define X86_DR7_G3    (1ul << 7)
-#define X86_DR7_LE    (1ul << 8)
-#define X86_DR7_GE    (1ul << 9)
-#define X86_DR7_GD    (1ul << 13)
-#define X86_DR7_RW0   (3ul << 16)
-#define X86_DR7_LEN0  (3ul << 18)
-#define X86_DR7_RW1   (3ul << 20)
-#define X86_DR7_LEN1  (3ul << 22)
-#define X86_DR7_RW2   (3ul << 24)
-#define X86_DR7_LEN2  (3ul << 26)
-#define X86_DR7_RW3   (3ul << 28)
-#define X86_DR7_LEN3  (3ul << 30)
-
-// NOTE1: Even though the GD bit is writable, we disable it for the write_state syscall because it
-//        complicates a lot the reasoning about how to access the registers. This is because
-//        enabling this bit would make any other access to debug registers to issue an exception.
-//        New syscalls should be define to lock/unlock debug registers.
-// NOTE2: LE/GE bits are normally ignored, but the manual recommends always setting it to 1 in
-//        order to be backwards compatible. Hence they are not writable from userspace.
-#define X86_DR7_USER_MASK (X86_DR7_L0 |   \
-                           X86_DR7_G0 |   \
-                           X86_DR7_L1 |   \
-                           X86_DR7_G1 |   \
-                           X86_DR7_L2 |   \
-                           X86_DR7_G2 |   \
-                           X86_DR7_L3 |   \
-                           X86_DR7_G3 |   \
-                           X86_DR7_RW0 |  \
-                           X86_DR7_LEN0 | \
-                           X86_DR7_RW1 |  \
-                           X86_DR7_LEN1 | \
-                           X86_DR7_RW2 |  \
-                           X86_DR7_LEN2 | \
-                           X86_DR7_RW3 |  \
-                           X86_DR7_LEN3)
-
-/* Bits 11:12, 14:15 and 32:63 must be cleared to 0. Bit 10 must be set to 1. */
-#define X86_DR7_MASK ((1ul << 10) | X86_DR7_LE | X86_DR7_GE)
-
-#define HW_DEBUG_REGISTERS_COUNT 4
-
-#ifndef __ASSEMBLER__
-
-#include <zircon/compiler.h>
-#include <sys/types.h>
-
-__BEGIN_CDECLS
-
-/* Indices of xsave feature states; state components are
- * enumerated in Intel Vol 1 section 13.1 */
-#define X86_XSAVE_STATE_INDEX_X87                  0
-#define X86_XSAVE_STATE_INDEX_SSE                  1
-#define X86_XSAVE_STATE_INDEX_AVX                  2
-#define X86_XSAVE_STATE_INDEX_MPX_BNDREG           3
-#define X86_XSAVE_STATE_INDEX_MPX_BNDCSR           4
-#define X86_XSAVE_STATE_INDEX_AVX512_OPMASK        5
-#define X86_XSAVE_STATE_INDEX_AVX512_LOWERZMM_HIGH 6
-#define X86_XSAVE_STATE_INDEX_AVX512_HIGHERZMM     7
-#define X86_XSAVE_STATE_INDEX_PT                   8
-#define X86_XSAVE_STATE_INDEX_PKRU                 9
-
-/* Bit masks for xsave feature states. */
-#define X86_XSAVE_STATE_BIT_X87                  (1 << X86_XSAVE_STATE_INDEX_X87)
-#define X86_XSAVE_STATE_BIT_SSE                  (1 << X86_XSAVE_STATE_INDEX_SSE)
-#define X86_XSAVE_STATE_BIT_AVX                  (1 << X86_XSAVE_STATE_INDEX_AVX)
-#define X86_XSAVE_STATE_BIT_MPX_BNDREG           (1 << X86_XSAVE_STATE_INDEX_MPX_BNDREG)
-#define X86_XSAVE_STATE_BIT_MPX_BNDCSR           (1 << X86_XSAVE_STATE_INDEX_MPX_BNDCSR)
-#define X86_XSAVE_STATE_BIT_AVX512_OPMASK        (1 << X86_XSAVE_STATE_INDEX_AVX512_OPMASK)
-#define X86_XSAVE_STATE_BIT_AVX512_LOWERZMM_HIGH (1 << X86_XSAVE_STATE_INDEX_AVX512_LOWERZMM_HIGH)
-#define X86_XSAVE_STATE_BIT_AVX512_HIGHERZMM     (1 << X86_XSAVE_STATE_INDEX_AVX512_HIGHERZMM)
-#define X86_XSAVE_STATE_BIT_PT                   (1 << X86_XSAVE_STATE_INDEX_PT)
-#define X86_XSAVE_STATE_BIT_PKRU                 (1 << X86_XSAVE_STATE_INDEX_PKRU)
-
-// Maximum buffer size needed for xsave and variants. To allocate, see ...BUFFER_SIZE below.
-#define X86_MAX_EXTENDED_REGISTER_SIZE 1024
-
-enum x86_extended_register_feature {
-    X86_EXTENDED_REGISTER_X87,
-    X86_EXTENDED_REGISTER_SSE,
-    X86_EXTENDED_REGISTER_AVX,
-    X86_EXTENDED_REGISTER_MPX,
-    X86_EXTENDED_REGISTER_AVX512,
-    X86_EXTENDED_REGISTER_PT,
-    X86_EXTENDED_REGISTER_PKRU,
-};
-
-/* Identify which extended registers are supported.  Also initialize
- * the FPU if present */
-void x86_extended_register_init(void);
-
-/* Enable the requested feature on this CPU, return true on success.
- * It is currently assumed that if a feature is enabled on one CPU, the caller
- * will ensure it is enabled on all CPUs */
-bool x86_extended_register_enable_feature(enum x86_extended_register_feature);
-
-size_t x86_extended_register_size(void);
-
-/* Initialize a state vector. The passed in buffer must be X86_EXTENDED_REGISTER_SIZE big and it
- * must be 64-byte aligned. This function will initialize it for use in save and restore. */
-void x86_extended_register_init_state(void* buffer);
-
-/* Save current state to state vector */
-void x86_extended_register_save_state(void *register_state);
-
-/* Restore a state created by x86_extended_register_init_state or
- * x86_extended_register_save_state */
-void x86_extended_register_restore_state(void *register_state);
-
-typedef struct thread thread_t;
-void x86_extended_register_context_switch(
-        thread_t *old_thread, thread_t *new_thread);
-
-void x86_set_extended_register_pt_state(bool threads);
-
-uint64_t x86_xgetbv(uint32_t reg);
-void x86_xsetbv(uint32_t reg, uint64_t val);
-
-struct x86_xsave_legacy_area {
-    uint16_t fcw;  /* FPU control word. */
-    uint16_t fsw;  /* FPU status word. */
-    uint8_t ftw;   /* Abridged FPU tag word (not the same as the FTW register, see
-                    * Intel manual sec 10.5.1.1: "x87 State". */
-    uint8_t reserved;
-    uint16_t fop;  /* FPU opcode. */
-    uint64_t fip;  /* FPU instruction pointer. */
-    uint64_t fdp;  /* FPU data pointer. */
-    uint32_t mxcsr;  /* SSE control status register. */
-    uint32_t mxcsr_mask;
-
-    /* The x87/MMX state. For x87 the each "st" entry has the low 80 bits used for the register
-     * contents. For MMX, the low 64 bits are used. The higher bits are unused. */
-    struct {
-        uint64_t low;
-        uint64_t high;
-    } st[8];
-
-    /* SSE registers. */
-    struct {
-        uint64_t low;
-        uint64_t high;
-    } xmm[16];
-} __PACKED;
-
-/* Returns the address within the given xsave area of the requested state component. The state
- * component indexes formats are described in section 13.4 of the Intel Software Developer's manual.
- * Use the X86_XSAVE_STATE_INDEX_* macros above for the component indices.
- *
- * The given register state must have previously been filled with the variant of XSAVE that the
- * system is using. Since the save area can be compressed, the offset of each component can vary
- * depending on the contents.
- *
- * The components 0 and 1 are special and refer to the legacy area. In both cases a pointer to the
- * x86_xsave_legacy_area will be returned. Note that "mark_present=true" will only affect the
- * requested component, so if you're writing to both x87 and SSE states, make two separate calls
- * even though the returned pointer will be the same.
- *
- * Some parts of the xsave area are can be marked as unused to optimize. If you plan on
- * writing to the area, set mark_present = true which will ensure that the corresponding area is
- * marked used. Without this, the registers might not be restored when the thread is resumed. This
- * is not currently supported for components >= 2. This means that to set AVX registers, for
- * example, AVX needed to have been previously used by the thread in question. This capability can
- * be added in the future if required.
- *
- * The size of the component will be placed in *size.
- *
- * This function will return null and fill 0 into *size if the component is not present. */
-void* x86_get_extended_register_state_component(void* register_state, uint32_t component,
-                                                bool mark_present, uint32_t* size);
-
-/* Kernel tracking of the current state of the x86 debug registers for a particular thread */
-typedef struct x86_debug_state {
-    uint64_t dr[4];
-    uint64_t dr6;
-    uint64_t dr7;
-} x86_debug_state_t;
-
-
-/* Disables the HW debug functionalities for the current thread.
- * There is no "enable" call. To do this, use the x86_write_debug_state call. */
-void x86_disable_debug_state(void);
-
-/* Checks whether the given state is valid to install on a running thread.
- * Will mask out reserved values on DR6 and DR7. This is for the caller convenience, considering
- * that we don't have a good mechanism to communicate back to the user what went wrong with the
- * call. */
-bool x86_validate_debug_state(x86_debug_state_t* debug_state);
-
-/* Only update the status section of |debug_state| (DR6). All other state will not be modified */
-void x86_read_debug_status(x86_debug_state_t* debug_state);
-
-/* Read from the CPU registers into |debug_state|. */
-void x86_read_hw_debug_regs(x86_debug_state_t* debug_state);
-
-/* Write from the |debug_state| into the CPU registers.
- *
- * IMPORTANT: This function is used in the context switch, so no validation is done, just writing.
- *            In any other context (eg. setting debug values from a syscall), you *MUST* call
- *            x86_validate_debug_state first. */
-void x86_write_hw_debug_regs(const x86_debug_state_t* debug_state);
-
-/* Handles the context switch for debug HW functionality (drN registers).
- * Will only copy over state if it's enabled (non-zero) for |new_thread|. */
-void x86_debug_state_context_switch(thread_t* old_thread, thread_t* new_thread);
-
-__END_CDECLS
-
-#endif
diff --git a/kernel/arch/x86/include/arch/x86/timer_freq.h b/kernel/arch/x86/include/arch/x86/timer_freq.h
deleted file mode 100644
index 886a58d..0000000
--- a/kernel/arch/x86/include/arch/x86/timer_freq.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <stdint.h>
-
-__BEGIN_CDECLS
-
-// Returns the core crystal clock frequency if it can be found from the CPU
-// alone (i.e. without calibration), or returns 0 if not.
-uint64_t x86_lookup_core_crystal_freq(void);
-
-// Returns the TSC frequency if it can be found from the CPU alone (i.e. without
-// calibration), or returns 0 if not.
-uint64_t x86_lookup_tsc_freq(void);
-
-__END_CDECLS
-
-
diff --git a/kernel/arch/x86/include/arch/x86/tsc.h b/kernel/arch/x86/include/arch/x86/tsc.h
deleted file mode 100644
index dfc6611..0000000
--- a/kernel/arch/x86/include/arch/x86/tsc.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-#pragma once
-
-void x86_tsc_adjust(void);
-void x86_tsc_store_adjustment(void);
diff --git a/kernel/arch/x86/include/arch/x86/user_copy.h b/kernel/arch/x86/include/arch/x86/user_copy.h
deleted file mode 100644
index 4649803..0000000
--- a/kernel/arch/x86/include/arch/x86/user_copy.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-/* This function is used by arch_copy_from_user() and arch_copy_to_user().
- * It should not be called anywhere except in the x86 usercopy
- * implementation. */
-
-zx_status_t _x86_copy_to_or_from_user(
-        void *dst,
-        const void *src,
-        size_t len,
-        void **fault_return);
-
-__END_CDECLS
diff --git a/kernel/arch/x86/include/arch/x86/vmx_state.h b/kernel/arch/x86/include/arch/x86/vmx_state.h
deleted file mode 100644
index eae6887..0000000
--- a/kernel/arch/x86/include/arch/x86/vmx_state.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/compiler.h>
-
-#define VS_RESUME   0
-
-#define HS_RIP      (VS_RESUME + 8)
-#define HS_RBX      (HS_RIP + 8)
-#define HS_RSP      (HS_RBX + 8)
-#define HS_RBP      (HS_RSP + 8)
-#define HS_R12      (HS_RBP + 8)
-#define HS_R13      (HS_R12 + 8)
-#define HS_R14      (HS_R13 + 8)
-#define HS_R15      (HS_R14 + 8)
-#define HS_RFLAGS   (HS_R15 + 8)
-
-#define GS_RAX      (HS_RFLAGS + 16)
-#define GS_RCX      (GS_RAX + 8)
-#define GS_RDX      (GS_RCX + 8)
-#define GS_RBX      (GS_RDX + 8)
-#define GS_RBP      (GS_RBX + 8)
-#define GS_RSI      (GS_RBP + 8)
-#define GS_RDI      (GS_RSI + 8)
-#define GS_R8       (GS_RDI + 8)
-#define GS_R9       (GS_R8 + 8)
-#define GS_R10      (GS_R9 + 8)
-#define GS_R11      (GS_R10 + 8)
-#define GS_R12      (GS_R11 + 8)
-#define GS_R13      (GS_R12 + 8)
-#define GS_R14      (GS_R13 + 8)
-#define GS_R15      (GS_R14 + 8)
-#define GS_CR2      (GS_R15 + 8)
-
-#ifndef __ASSEMBLER__
-
-#include <zircon/types.h>
-
-/* Holds the register state used to restore a host. */
-struct HostState {
-    // Return address.
-    uint64_t rip;
-
-    // Callee-save registers.
-    uint64_t rbx;
-    uint64_t rsp;
-    uint64_t rbp;
-    uint64_t r12;
-    uint64_t r13;
-    uint64_t r14;
-    uint64_t r15;
-
-    // Processor flags.
-    uint64_t rflags;
-
-    // Extended control registers.
-    uint64_t xcr0;
-};
-
-struct GuestState {
-    //  RIP, RSP, and RFLAGS are automatically saved by VMX in the VMCS.
-    uint64_t rax;
-    uint64_t rcx;
-    uint64_t rdx;
-    uint64_t rbx;
-    uint64_t rbp;
-    uint64_t rsi;
-    uint64_t rdi;
-    uint64_t r8;
-    uint64_t r9;
-    uint64_t r10;
-    uint64_t r11;
-    uint64_t r12;
-    uint64_t r13;
-    uint64_t r14;
-    uint64_t r15;
-
-    // Control registers.
-    uint64_t cr2;
-
-    // Extended control registers.
-    uint64_t xcr0;
-};
-
-struct VmxState {
-    bool resume;
-    HostState host_state;
-    GuestState guest_state;
-};
-
-static_assert(__offsetof(VmxState, resume) == VS_RESUME, "");
-
-static_assert(__offsetof(VmxState, host_state.rip) == HS_RIP, "");
-static_assert(__offsetof(VmxState, host_state.rsp) == HS_RSP, "");
-static_assert(__offsetof(VmxState, host_state.rbp) == HS_RBP, "");
-static_assert(__offsetof(VmxState, host_state.rbx) == HS_RBX, "");
-static_assert(__offsetof(VmxState, host_state.r12) == HS_R12, "");
-static_assert(__offsetof(VmxState, host_state.r13) == HS_R13, "");
-static_assert(__offsetof(VmxState, host_state.r14) == HS_R14, "");
-static_assert(__offsetof(VmxState, host_state.r15) == HS_R15, "");
-static_assert(__offsetof(VmxState, host_state.rflags) == HS_RFLAGS, "");
-
-static_assert(__offsetof(VmxState, guest_state.rax) == GS_RAX, "");
-static_assert(__offsetof(VmxState, guest_state.rbx) == GS_RBX, "");
-static_assert(__offsetof(VmxState, guest_state.rcx) == GS_RCX, "");
-static_assert(__offsetof(VmxState, guest_state.rdx) == GS_RDX, "");
-static_assert(__offsetof(VmxState, guest_state.rdi) == GS_RDI, "");
-static_assert(__offsetof(VmxState, guest_state.rsi) == GS_RSI, "");
-static_assert(__offsetof(VmxState, guest_state.rbp) == GS_RBP, "");
-static_assert(__offsetof(VmxState, guest_state.r8) == GS_R8, "");
-static_assert(__offsetof(VmxState, guest_state.r9) == GS_R9, "");
-static_assert(__offsetof(VmxState, guest_state.r10) == GS_R10, "");
-static_assert(__offsetof(VmxState, guest_state.r11) == GS_R11, "");
-static_assert(__offsetof(VmxState, guest_state.r12) == GS_R12, "");
-static_assert(__offsetof(VmxState, guest_state.r13) == GS_R13, "");
-static_assert(__offsetof(VmxState, guest_state.r14) == GS_R14, "");
-static_assert(__offsetof(VmxState, guest_state.r15) == GS_R15, "");
-static_assert(__offsetof(VmxState, guest_state.cr2) == GS_CR2, "");
-
-__BEGIN_CDECLS
-
-/* Launch the guest and save the host state.
- * If we return 0, we have exited from the guest, otherwise we have failed to
- * launch the guest.
- */
-zx_status_t vmx_enter(VmxState* vmx_state);
-
-/* Exit from the guest, and load the saved host state.
- * This function is never called directly, but is executed on exit from a guest.
- * It calls vmx_exit before returning through vmx_enter.
- */
-void vmx_exit_entry();
-void vmx_exit(VmxState* vmx_state);
-
-__END_CDECLS
-
-#endif // __ASSEMBLER__
diff --git a/kernel/arch/x86/include/arch/x86/x86intrin.h b/kernel/arch/x86/include/arch/x86/x86intrin.h
deleted file mode 100644
index c67f50c..0000000
--- a/kernel/arch/x86/include/arch/x86/x86intrin.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-// TODO(mcgrathr): As of GCC 6.3.0, these other files included by
-// <x86intrin.h> are incompatible with -mno-sse.
-// When https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80298 is fixed,
-// these #define hacks can be removed.
-#if !defined(__clang__) && __GNUC__ < 7
-#define _AVX512VLINTRIN_H_INCLUDED
-#define _AVX512BWINTRIN_H_INCLUDED
-#define _AVX512DQINTRIN_H_INCLUDED
-#define _AVX512VLBWINTRIN_H_INCLUDED
-#define _AVX512VLDQINTRIN_H_INCLUDED
-#define _AVX512VBMIINTRIN_H_INCLUDED
-#define _AVX512VBMIVLINTRIN_H_INCLUDED
-#define _MM3DNOW_H_INCLUDED
-#define _FMA4INTRIN_H_INCLUDED
-#define _XOPMMINTRIN_H_INCLUDED
-#endif
-#include <x86intrin.h>
diff --git a/kernel/arch/x86/ioapic.cpp b/kernel/arch/x86/ioapic.cpp
deleted file mode 100644
index 6e97763..0000000
--- a/kernel/arch/x86/ioapic.cpp
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-
-#include <arch/x86/apic.h>
-#include <arch/x86/interrupts.h>
-#include <err.h>
-#include <fbl/array.h>
-#include <kernel/auto_lock.h>
-#include <kernel/spinlock.h>
-#include <new>
-#include <trace.h>
-#include <vm/physmap.h>
-#include <vm/pmm.h>
-#include <vm/vm_aspace.h>
-#include <zircon/types.h>
-
-#define IO_APIC_IND(base) ((volatile uint32_t*)(((uint8_t*)(base)) + IO_APIC_IOREGSEL))
-#define IO_APIC_DAT(base) ((volatile uint32_t*)(((uint8_t*)(base)) + IO_APIC_IOWIN))
-#define IO_APIC_EOIR(base) ((volatile uint32_t*)(((uint8_t*)(base)) + 0x40))
-// The minimum address space required past the base address
-#define IO_APIC_WINDOW_SIZE 0x44
-// The minimum version that supported the EOIR
-#define IO_APIC_EOIR_MIN_VERSION 0x20
-
-// IO APIC register offsets
-#define IO_APIC_REG_RTE(idx) (0x10 + 2 * (idx))
-
-// Macros for extracting data from REG_ID
-#define IO_APIC_ID_ID(v) (((v) >> 24) & 0xf)
-// Macros for extracting data from REG_VER
-#define IO_APIC_VER_MAX_REDIR_ENTRY(v) (((v) >> 16) & 0xff)
-#define IO_APIC_VER_VERSION(v) ((v)&0xff)
-// Macros for writing REG_RTE entries
-#define IO_APIC_RTE_DST(v) (((uint64_t)(v)) << 56)
-#define IO_APIC_RTE_EXTENDED_DST_ID(v) (((uint64_t)((v)&0xf)) << 48)
-#define IO_APIC_RTE_MASKED (1ULL << 16)
-#define IO_APIC_RTE_TRIGGER_MODE(tm) (((uint64_t)(tm)) << 15)
-#define IO_APIC_RTE_POLARITY(p) (((uint64_t)(p)) << 13)
-#define IO_APIC_RTE_DST_MODE(dm) (((uint64_t)(dm)) << 11)
-#define IO_APIC_RTE_DELIVERY_MODE(dm) ((((uint64_t)(dm)) & 0x7) << 8)
-#define IO_APIC_RTE_VECTOR(x) (((uint64_t)(x)) & 0xff)
-#define IO_APIC_RTE_MASK IO_APIC_RTE_VECTOR(0xff)
-// Macros for reading REG_RTE entries
-#define IO_APIC_RTE_REMOTE_IRR (1ULL << 14)
-#define IO_APIC_RTE_DELIVERY_STATUS (1ULL << 12)
-#define IO_APIC_RTE_GET_POLARITY(r) \
-    ((enum interrupt_polarity)(((r) >> 13) & 0x1))
-#define IO_APIC_RTE_GET_TRIGGER_MODE(r) \
-    ((enum interrupt_trigger_mode)(((r) >> 15) & 0x1))
-#define IO_APIC_RTE_GET_VECTOR(r) \
-    ((uint8_t)((r)&0xFF))
-
-// Technically this can be larger, but the spec as of the 100-Series doesn't
-// guarantee where the additional redirections will be.
-#define IO_APIC_NUM_REDIRECTIONS 120
-
-#define LOCAL_TRACE 0
-
-// Struct for tracking all we need to know about each IO APIC
-struct io_apic {
-    struct io_apic_descriptor desc;
-
-    // Virtual address of the base of this IOAPIC's MMIO
-    void* vaddr;
-
-    uint8_t version;
-    // The index of the last redirection entry
-    uint8_t max_redirection_entry;
-
-    // Pre-allocated space for suspend/resume bookkeeping
-    uint64_t saved_rtes[IO_APIC_NUM_REDIRECTIONS];
-};
-
-// This lock guards all access to IO APIC registers
-static SpinLock lock;
-
-// General register accessors
-static inline uint32_t apic_io_read_reg(struct io_apic* io_apic, uint8_t reg) TA_REQ(lock);
-static inline void apic_io_write_reg(struct io_apic* io_apic, uint8_t reg,
-                                     uint32_t val) TA_REQ(lock);
-
-// Register-specific accessors
-static uint64_t apic_io_read_redirection_entry(struct io_apic* io_apic,
-                                               uint32_t global_irq) TA_REQ(lock);
-static void apic_io_write_redirection_entry(struct io_apic* io_apic, uint32_t global_irq,
-                                            uint64_t value) TA_REQ(lock);
-
-// Utility for finding the right IO APIC for a specific global IRQ, cannot fail
-static struct io_apic* apic_io_resolve_global_irq(uint32_t irq);
-// Utility for finding the right IO APIC for a specific global IRQ, can fail
-static struct io_apic* apic_io_resolve_global_irq_no_panic(uint32_t irq);
-
-// Track all IO APICs in the system
-static fbl::Array<io_apic> io_apics;
-static uint32_t num_io_apics;
-
-// The first 16 global IRQs are identity mapped to the legacy ISA IRQs unless
-// we are told otherwise.  This tracks the actual mapping.
-// Read-only after initialization in apic_io_init()
-static struct io_apic_isa_override isa_overrides[NUM_ISA_IRQS];
-
-void apic_io_init(
-    struct io_apic_descriptor* io_apic_descs,
-    unsigned int num_io_apic_descs,
-    struct io_apic_isa_override* overrides,
-    unsigned int num_overrides) {
-    ASSERT(!io_apics);
-
-    num_io_apics = num_io_apic_descs;
-    {
-        fbl::AllocChecker ac;
-        io_apics.reset(new (&ac) io_apic[num_io_apics], num_io_apics);
-        ASSERT(ac.check());
-    }
-    for (unsigned int i = 0; i < num_io_apics; ++i) {
-        io_apics[i].desc = io_apic_descs[i];
-    }
-
-    // Allocate windows to their control pages
-    for (uint32_t i = 0; i < num_io_apics; ++i) {
-        struct io_apic* apic = &io_apics[i];
-        paddr_t paddr = apic->desc.paddr;
-        void* vaddr = paddr_to_physmap(paddr);
-        // If the window isn't mapped yet (multiple IO APICs can be in the
-        // same page), map it in.
-        if (vaddr == nullptr) {
-            paddr_t paddr_page_base = ROUNDDOWN(paddr, PAGE_SIZE);
-            ASSERT(paddr + IO_APIC_WINDOW_SIZE <= paddr_page_base + PAGE_SIZE);
-            zx_status_t res = VmAspace::kernel_aspace()->AllocPhysical(
-                "ioapic",
-                PAGE_SIZE,       // size
-                &vaddr,          // requested virtual vaddress
-                PAGE_SIZE_SHIFT, // alignment log2
-                paddr_page_base, // physical vaddress
-                0,               // vmm flags
-                ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE |
-                    ARCH_MMU_FLAG_UNCACHED_DEVICE); // arch mmu flags
-            ASSERT(res == ZX_OK);
-            vaddr = (void*)((uintptr_t)vaddr + paddr - paddr_page_base);
-        }
-
-        // Populate the rest of the descriptor
-        apic->vaddr = vaddr;
-
-        AutoSpinLock guard(&lock);
-
-        uint32_t ver = apic_io_read_reg(apic, IO_APIC_REG_VER);
-        apic->version = IO_APIC_VER_VERSION(ver);
-        apic->max_redirection_entry = IO_APIC_VER_MAX_REDIR_ENTRY(ver);
-        LTRACEF("Found an IO APIC at phys %p, virt %p: ver %08x\n", (void*)paddr, vaddr, ver);
-        if (apic->max_redirection_entry > IO_APIC_NUM_REDIRECTIONS - 1) {
-            TRACEF("IO APIC supports more redirections than kernel: %08x\n",
-                   ver);
-            apic->max_redirection_entry = IO_APIC_NUM_REDIRECTIONS - 1;
-        }
-
-        // Cleanout the redirection entries
-        for (unsigned int j = 0; j <= apic->max_redirection_entry; ++j) {
-            apic_io_write_redirection_entry(
-                apic, j + apic->desc.global_irq_base, IO_APIC_RTE_MASKED);
-        }
-    }
-
-    // Process ISA IRQ overrides
-    for (unsigned int i = 0; i < num_overrides; ++i) {
-        uint8_t isa_irq = overrides[i].isa_irq;
-        ASSERT(isa_irq < NUM_ISA_IRQS);
-        isa_overrides[isa_irq] = overrides[i];
-        LTRACEF("ISA IRQ override for ISA IRQ %u, mapping to %u\n",
-                isa_irq, overrides[i].global_irq);
-    }
-}
-
-static struct io_apic* apic_io_resolve_global_irq_no_panic(uint32_t irq) {
-    for (uint32_t i = 0; i < num_io_apics; ++i) {
-        uint32_t start = io_apics[i].desc.global_irq_base;
-        uint32_t end = start + io_apics[i].max_redirection_entry;
-        if (start <= irq && irq <= end) {
-            return &io_apics[i];
-        }
-    }
-    return nullptr;
-}
-
-static struct io_apic* apic_io_resolve_global_irq(uint32_t irq) {
-    struct io_apic* res = apic_io_resolve_global_irq_no_panic(irq);
-    if (res) {
-        return res;
-    }
-    // Treat this as fatal, since dealing with an unmapped IRQ is a bug.
-    panic("Could not resolve global IRQ: %u\n", irq);
-}
-
-static inline uint32_t apic_io_read_reg(
-    struct io_apic* io_apic,
-    uint8_t reg) {
-    ASSERT(io_apic != nullptr);
-    DEBUG_ASSERT(lock.IsHeld());
-    *IO_APIC_IND(io_apic->vaddr) = reg;
-    uint32_t val = *IO_APIC_DAT(io_apic->vaddr);
-    return val;
-}
-
-static inline void apic_io_write_reg(
-    struct io_apic* io_apic,
-    uint8_t reg,
-    uint32_t val) {
-    ASSERT(io_apic != nullptr);
-    DEBUG_ASSERT(lock.IsHeld());
-    *IO_APIC_IND(io_apic->vaddr) = reg;
-    *IO_APIC_DAT(io_apic->vaddr) = val;
-}
-
-static uint64_t apic_io_read_redirection_entry(
-    struct io_apic* io_apic,
-    uint32_t global_irq) {
-    DEBUG_ASSERT(lock.IsHeld());
-
-    ASSERT(global_irq >= io_apic->desc.global_irq_base);
-    uint32_t offset = global_irq - io_apic->desc.global_irq_base;
-    ASSERT(offset <= io_apic->max_redirection_entry);
-
-    uint8_t reg_id = (uint8_t)IO_APIC_REG_RTE(offset);
-    uint64_t result = 0;
-    result |= apic_io_read_reg(io_apic, reg_id);
-    result |= ((uint64_t)apic_io_read_reg(io_apic, (uint8_t)(reg_id + 1))) << 32;
-    return result;
-}
-
-static void apic_io_write_redirection_entry(
-    struct io_apic* io_apic,
-    uint32_t global_irq,
-    uint64_t value) {
-    DEBUG_ASSERT(lock.IsHeld());
-
-    ASSERT(global_irq >= io_apic->desc.global_irq_base);
-    uint32_t offset = global_irq - io_apic->desc.global_irq_base;
-    ASSERT(offset <= io_apic->max_redirection_entry);
-
-    uint8_t reg_id = (uint8_t)IO_APIC_REG_RTE(offset);
-    apic_io_write_reg(io_apic, reg_id, (uint32_t)value);
-    apic_io_write_reg(io_apic, (uint8_t)(reg_id + 1), (uint32_t)(value >> 32));
-}
-
-bool apic_io_is_valid_irq(uint32_t global_irq) {
-    return apic_io_resolve_global_irq_no_panic(global_irq) != nullptr;
-}
-
-/*
- * To correctly use this function, we need to do some work first.
- * 1) We need to check for EOI-broadcast suppression support in the local APIC
- *    version register.
- * 2) We need to check that the IOAPIC is new enough to support the EOI
- * 3) We need to enable suppression in the spurious interrupt register.
- * 4) Call this function after calling apic_issue_eoi() (or maybe modify
- *    apic_issue_eoi() to call this automatically).
- *
- * In the mean time, IO APIC EOIs are automatically issued via broadcast to
- * all IO APICs whenever the local APIC receives an EOI for a level-triggered
- * interrupt.
- */
-void apic_io_issue_eoi(uint32_t global_irq, uint8_t vec) {
-    struct io_apic* io_apic = apic_io_resolve_global_irq(global_irq);
-
-    AutoSpinLock guard(&lock);
-
-    ASSERT(io_apic->version >= IO_APIC_EOIR_MIN_VERSION);
-    *IO_APIC_EOIR(io_apic->vaddr) = vec;
-}
-
-void apic_io_mask_irq(uint32_t global_irq, bool mask) {
-    struct io_apic* io_apic = apic_io_resolve_global_irq(global_irq);
-
-    AutoSpinLock guard(&lock);
-
-    uint64_t reg = apic_io_read_redirection_entry(io_apic, global_irq);
-    if (mask) {
-        reg |= IO_APIC_RTE_MASKED;
-    } else {
-        /* If we are unmasking, we had better have been assigned a valid vector */
-        DEBUG_ASSERT((IO_APIC_RTE_GET_VECTOR(reg) >= X86_INT_PLATFORM_BASE) &&
-                     (IO_APIC_RTE_GET_VECTOR(reg) <= X86_INT_PLATFORM_MAX));
-        reg &= ~IO_APIC_RTE_MASKED;
-    }
-    apic_io_write_redirection_entry(io_apic, global_irq, reg);
-}
-
-void apic_io_configure_irq(
-    uint32_t global_irq,
-    enum interrupt_trigger_mode trig_mode,
-    enum interrupt_polarity polarity,
-    enum apic_interrupt_delivery_mode del_mode,
-    bool mask,
-    enum apic_interrupt_dst_mode dst_mode,
-    uint8_t dst,
-    uint8_t vector) {
-    struct io_apic* io_apic = apic_io_resolve_global_irq(global_irq);
-
-    AutoSpinLock guard(&lock);
-
-    /* If we are configuring an invalid vector, for the IRQ to be masked. */
-    if ((del_mode == DELIVERY_MODE_FIXED || del_mode == DELIVERY_MODE_LOWEST_PRI) &&
-        ((vector < X86_INT_PLATFORM_BASE) || (vector > X86_INT_PLATFORM_MAX))) {
-
-        mask = true;
-    }
-
-    uint64_t reg = 0;
-    reg |= IO_APIC_RTE_TRIGGER_MODE(trig_mode);
-    reg |= IO_APIC_RTE_POLARITY(polarity);
-    reg |= IO_APIC_RTE_DELIVERY_MODE(del_mode);
-    reg |= IO_APIC_RTE_DST_MODE(dst_mode);
-    reg |= IO_APIC_RTE_DST(dst);
-    reg |= IO_APIC_RTE_VECTOR(vector);
-    if (mask) {
-        reg |= IO_APIC_RTE_MASKED;
-    }
-    apic_io_write_redirection_entry(io_apic, global_irq, reg);
-}
-
-zx_status_t apic_io_fetch_irq_config(
-    uint32_t global_irq,
-    enum interrupt_trigger_mode* trig_mode,
-    enum interrupt_polarity* polarity) {
-    struct io_apic* io_apic = apic_io_resolve_global_irq(global_irq);
-
-    if (!io_apic)
-        return ZX_ERR_INVALID_ARGS;
-
-    AutoSpinLock guard(&lock);
-
-    uint64_t reg = apic_io_read_redirection_entry(io_apic, global_irq);
-    if (trig_mode)
-        *trig_mode = IO_APIC_RTE_GET_TRIGGER_MODE(reg);
-    if (polarity)
-        *polarity = IO_APIC_RTE_GET_POLARITY(reg);
-
-    return ZX_OK;
-}
-
-void apic_io_configure_irq_vector(
-    uint32_t global_irq,
-    uint8_t vector) {
-    struct io_apic* io_apic = apic_io_resolve_global_irq(global_irq);
-
-    AutoSpinLock guard(&lock);
-
-    uint64_t reg = apic_io_read_redirection_entry(io_apic, global_irq);
-
-    /* If we are configuring an invalid vector, automatically mask the IRQ. */
-    if ((IO_APIC_RTE_GET_VECTOR(reg) < X86_INT_PLATFORM_BASE) ||
-        (IO_APIC_RTE_GET_VECTOR(reg) > X86_INT_PLATFORM_MAX)) {
-        reg |= IO_APIC_RTE_MASKED;
-    }
-
-    reg &= ~IO_APIC_RTE_MASK;
-    reg |= IO_APIC_RTE_VECTOR(vector);
-    apic_io_write_redirection_entry(io_apic, global_irq, reg);
-}
-
-uint8_t apic_io_fetch_irq_vector(uint32_t global_irq) {
-    struct io_apic* io_apic = apic_io_resolve_global_irq(global_irq);
-
-    AutoSpinLock guard(&lock);
-
-    uint64_t reg = apic_io_read_redirection_entry(io_apic, global_irq);
-    uint8_t vector = IO_APIC_RTE_GET_VECTOR(reg);
-
-    return vector;
-}
-
-void apic_io_mask_isa_irq(uint8_t isa_irq, bool mask) {
-    ASSERT(isa_irq < NUM_ISA_IRQS);
-    uint32_t global_irq = isa_irq;
-    if (isa_overrides[isa_irq].remapped) {
-        global_irq = isa_overrides[isa_irq].global_irq;
-    }
-    apic_io_mask_irq(global_irq, mask);
-}
-
-void apic_io_configure_isa_irq(
-    uint8_t isa_irq,
-    enum apic_interrupt_delivery_mode del_mode,
-    bool mask,
-    enum apic_interrupt_dst_mode dst_mode,
-    uint8_t dst,
-    uint8_t vector) {
-    ASSERT(isa_irq < NUM_ISA_IRQS);
-    uint32_t global_irq = isa_irq;
-    enum interrupt_trigger_mode trig_mode = IRQ_TRIGGER_MODE_EDGE;
-    enum interrupt_polarity polarity = IRQ_POLARITY_ACTIVE_HIGH;
-    if (isa_overrides[isa_irq].remapped) {
-        global_irq = isa_overrides[isa_irq].global_irq;
-        trig_mode = isa_overrides[isa_irq].tm;
-        polarity = isa_overrides[isa_irq].pol;
-    }
-
-    apic_io_configure_irq(
-        global_irq,
-        trig_mode,
-        polarity,
-        del_mode,
-        mask,
-        dst_mode,
-        dst,
-        vector);
-}
-
-// Convert a legacy ISA IRQ number into a global IRQ number
-uint32_t apic_io_isa_to_global(uint8_t isa_irq) {
-    // It is a programming bug for this to be invoked with an invalid value.
-    ASSERT(isa_irq < NUM_ISA_IRQS);
-    if (isa_overrides[isa_irq].remapped) {
-        return isa_overrides[isa_irq].global_irq;
-    }
-    return isa_irq;
-}
-
-void apic_io_save(void) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    AutoSpinLockNoIrqSave guard(&lock);
-    for (uint32_t i = 0; i < num_io_apics; ++i) {
-        struct io_apic* apic = &io_apics[i];
-        for (uint8_t j = 0; j <= apic->max_redirection_entry; ++j) {
-            uint32_t global_irq = apic->desc.global_irq_base + j;
-            uint64_t reg = apic_io_read_redirection_entry(apic, global_irq);
-            apic->saved_rtes[j] = reg;
-        }
-    }
-}
-
-void apic_io_restore(void) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    AutoSpinLockNoIrqSave guard(&lock);
-    for (uint32_t i = 0; i < num_io_apics; ++i) {
-        struct io_apic* apic = &io_apics[i];
-        for (uint8_t j = 0; j <= apic->max_redirection_entry; ++j) {
-            uint32_t global_irq = apic->desc.global_irq_base + j;
-            apic_io_write_redirection_entry(apic, global_irq, apic->saved_rtes[j]);
-        }
-    }
-}
-
-void apic_io_debug(void) {
-    AutoSpinLock guard(&lock);
-    for (uint32_t i = 0; i < num_io_apics; ++i) {
-        struct io_apic* apic = &io_apics[i];
-        printf("IO APIC idx %u:\n", i);
-        printf("  id: %08x\n", apic->desc.apic_id);
-        printf("  version: %08hhx\n", apic->version);
-        printf("  entries: %08x\n", apic->max_redirection_entry + 1U);
-        for (uint8_t j = 0; j <= apic->max_redirection_entry; ++j) {
-            uint32_t global_irq = apic->desc.global_irq_base + j;
-            uint64_t reg = apic_io_read_redirection_entry(apic, global_irq);
-            printf("    %4u: dst: %s %02hhx, %s, %s, %s, dm %hhx, vec %2hhx, %s %s\n",
-                   global_irq,
-                   (reg & (1 << 11)) ? "l" : "p",
-                   (uint8_t)(reg >> 56),
-                   (reg & IO_APIC_RTE_MASKED) ? "masked" : "unmasked",
-                   IO_APIC_RTE_GET_TRIGGER_MODE(reg) ? "level" : "edge",
-                   IO_APIC_RTE_GET_POLARITY(reg) ? "low" : "high",
-                   (uint8_t)((reg >> 8) & 0x7),
-                   (uint8_t)reg,
-                   (reg & (1 << 12)) ? "pending" : "",
-                   (reg & (1 << 14)) ? "RIRR" : "");
-        }
-    }
-}
diff --git a/kernel/arch/x86/ioport.cpp b/kernel/arch/x86/ioport.cpp
deleted file mode 100644
index ac545f0..0000000
--- a/kernel/arch/x86/ioport.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/ioport.h>
-#include <arch/x86/mp.h>
-#include <assert.h>
-#include <bits.h>
-#include <err.h>
-#include <kernel/auto_lock.h>
-#include <kernel/mp.h>
-#include <kernel/thread.h>
-#include <string.h>
-#include <vm/vm.h>
-#include <vm/vm_aspace.h>
-#include <zircon/types.h>
-
-#include <fbl/alloc_checker.h>
-#include <ktl/unique_ptr.h>
-#include <ktl/move.h>
-
-void x86_reset_tss_io_bitmap(void) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    tss_t* tss = &x86_get_percpu()->default_tss;
-    auto tss_bitmap = reinterpret_cast<unsigned long*>(tss->tss_bitmap);
-
-    bitmap_set(tss_bitmap, 0, IO_BITMAP_BITS);
-}
-
-static void x86_clear_tss_io_bitmap(const bitmap::RleBitmap& bitmap) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    tss_t* tss = &x86_get_percpu()->default_tss;
-
-    auto tss_bitmap = reinterpret_cast<unsigned long*>(tss->tss_bitmap);
-    for (const auto& extent : bitmap) {
-        DEBUG_ASSERT(extent.bitoff + extent.bitlen <= IO_BITMAP_BITS);
-        bitmap_set(tss_bitmap, static_cast<int>(extent.bitoff), static_cast<int>(extent.bitlen));
-    }
-}
-
-void x86_clear_tss_io_bitmap(IoBitmap& io_bitmap) {
-    AutoSpinLockNoIrqSave guard(&io_bitmap.lock_);
-    if (!io_bitmap.bitmap_)
-        return;
-
-    x86_clear_tss_io_bitmap(*io_bitmap.bitmap_);
-}
-
-static void x86_set_tss_io_bitmap(const bitmap::RleBitmap& bitmap) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    tss_t* tss = &x86_get_percpu()->default_tss;
-
-    auto tss_bitmap = reinterpret_cast<unsigned long*>(tss->tss_bitmap);
-    for (const auto& extent : bitmap) {
-        DEBUG_ASSERT(extent.bitoff + extent.bitlen <= IO_BITMAP_BITS);
-        bitmap_clear(tss_bitmap, static_cast<int>(extent.bitoff), static_cast<int>(extent.bitlen));
-    }
-}
-
-void x86_set_tss_io_bitmap(IoBitmap& io_bitmap) {
-    AutoSpinLockNoIrqSave guard(&io_bitmap.lock_);
-    if (!io_bitmap.bitmap_)
-        return;
-
-    x86_set_tss_io_bitmap(*io_bitmap.bitmap_);
-}
-
-IoBitmap& IoBitmap::GetCurrent() {
-    VmAspace* aspace = vmm_aspace_to_obj(get_current_thread()->aspace);
-    return aspace->arch_aspace().io_bitmap();
-}
-
-IoBitmap::~IoBitmap() {}
-
-struct ioport_update_context {
-    // IoBitmap that we're trying to update
-    IoBitmap* io_bitmap;
-};
-
-void IoBitmap::UpdateTask(void* raw_context) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    struct ioport_update_context* context =
-        (struct ioport_update_context*)raw_context;
-
-    IoBitmap& io_bitmap = GetCurrent();
-    if (&io_bitmap != context->io_bitmap) {
-        return;
-    }
-
-    {
-        AutoSpinLockNoIrqSave guard(&io_bitmap.lock_);
-        // This is overkill, but it's much simpler to reason about
-        x86_reset_tss_io_bitmap();
-        x86_set_tss_io_bitmap(*io_bitmap.bitmap_);
-    }
-}
-
-int IoBitmap::SetIoBitmap(uint32_t port, uint32_t len, bool enable) {
-    DEBUG_ASSERT(!arch_ints_disabled());
-
-    if ((port + len < port) || (port + len > IO_BITMAP_BITS))
-        return ZX_ERR_INVALID_ARGS;
-
-    ktl::unique_ptr<bitmap::RleBitmap> optimistic_bitmap;
-    if (!bitmap_) {
-        // Optimistically allocate a bitmap structure if we don't have one, and
-        // we'll see if we actually need this allocation later.  In the common
-        // case, when we make the allocation we will use it.
-        fbl::AllocChecker ac;
-        optimistic_bitmap.reset(new (&ac) bitmap::RleBitmap());
-        if (!ac.check()) {
-            return ZX_ERR_NO_MEMORY;
-        }
-    }
-
-    // Create a free-list in case any of our bitmap operations need to free any
-    // nodes.
-    bitmap::RleBitmap::FreeList bitmap_freelist;
-
-    // Optimistically allocate an element for the bitmap, in case we need one.
-    {
-        fbl::AllocChecker ac;
-        bitmap_freelist.push_back(ktl::unique_ptr<bitmap::RleBitmapElement>(new (&ac) bitmap::RleBitmapElement()));
-        if (!ac.check()) {
-            return ZX_ERR_NO_MEMORY;
-        }
-    }
-
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-
-    zx_status_t status = ZX_OK;
-    do {
-        AutoSpinLockNoIrqSave guard(&lock_);
-
-        if (!bitmap_) {
-            bitmap_ = ktl::move(optimistic_bitmap);
-        }
-        DEBUG_ASSERT(bitmap_);
-
-        status = enable ? bitmap_->SetNoAlloc(port, port + len, &bitmap_freelist) : bitmap_->ClearNoAlloc(port, port + len, &bitmap_freelist);
-        if (status != ZX_OK) {
-            break;
-        }
-
-        IoBitmap& current = GetCurrent();
-        if (this == &current) {
-            // Set the io bitmap in the tss (the tss IO bitmap has reversed polarity)
-            tss_t* tss = &x86_get_percpu()->default_tss;
-            if (enable) {
-                bitmap_clear(reinterpret_cast<unsigned long*>(tss->tss_bitmap), port, len);
-            } else {
-                bitmap_set(reinterpret_cast<unsigned long*>(tss->tss_bitmap), port, len);
-            }
-        }
-    } while (0);
-
-    // Let all other CPUs know about the update
-    if (status == ZX_OK) {
-        struct ioport_update_context task_context = {.io_bitmap = this};
-        mp_sync_exec(MP_IPI_TARGET_ALL_BUT_LOCAL, 0, IoBitmap::UpdateTask, &task_context);
-    }
-
-    arch_interrupt_restore(state, 0);
-    return status;
-}
diff --git a/kernel/arch/x86/lapic.cpp b/kernel/arch/x86/lapic.cpp
deleted file mode 100644
index e9a9742..0000000
--- a/kernel/arch/x86/lapic.cpp
+++ /dev/null
@@ -1,522 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <arch/ops.h>
-#include <arch/spinlock.h>
-#include <arch/x86.h>
-#include <arch/x86/apic.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/interrupts.h>
-#include <arch/x86/mp.h>
-#include <debug.h>
-#include <dev/interrupt.h>
-#include <err.h>
-#include <vm/vm_aspace.h>
-#include <zircon/types.h>
-
-#include <lib/console.h>
-
-// We currently only implement support for the xAPIC
-
-// Virtual address of the local APIC's MMIO registers
-static void* apic_virt_base;
-static bool x2apic_enabled = false;
-
-static uint8_t bsp_apic_id;
-static bool bsp_apic_id_valid;
-
-// local apic registers
-// set as an offset into the mmio region here
-// x2APIC msr offsets are these >> 4
-#define LAPIC_REG_ID (0x020)
-#define LAPIC_REG_VERSION (0x030)
-#define LAPIC_REG_TASK_PRIORITY (0x080)
-#define LAPIC_REG_PROCESSOR_PRIORITY (0x0A0)
-#define LAPIC_REG_EOI (0x0B0)
-#define LAPIC_REG_LOGICAL_DST (0x0D0)
-#define LAPIC_REG_SPURIOUS_IRQ (0x0F0)
-#define LAPIC_REG_IN_SERVICE(x) (0x100 + ((x) << 4))
-#define LAPIC_REG_TRIGGER_MODE(x) (0x180 + ((x) << 4))
-#define LAPIC_REG_IRQ_REQUEST(x) (0x200 + ((x) << 4))
-#define LAPIC_REG_ERROR_STATUS (0x280)
-#define LAPIC_REG_LVT_CMCI (0x2F0)
-#define LAPIC_REG_IRQ_CMD_LOW (0x300)
-#define LAPIC_REG_IRQ_CMD_HIGH (0x310)
-#define LAPIC_REG_LVT_TIMER (0x320)
-#define LAPIC_REG_LVT_THERMAL (0x330)
-#define LAPIC_REG_LVT_PERF (0x340)
-#define LAPIC_REG_LVT_LINT0 (0x350)
-#define LAPIC_REG_LVT_LINT1 (0x360)
-#define LAPIC_REG_LVT_ERROR (0x370)
-#define LAPIC_REG_INIT_COUNT (0x380)
-#define LAPIC_REG_CURRENT_COUNT (0x390)
-#define LAPIC_REG_DIVIDE_CONF (0x3E0)
-
-#define LAPIC_X2APIC_MSR_BASE (0x800)
-#define LAPIC_X2APIC_MSR_ICR (0x830)
-#define LAPIC_X2APIC_MSR_SELF_IPI (0x83f)
-
-// Spurious IRQ bitmasks
-#define SVR_APIC_ENABLE (1 << 8)
-#define SVR_SPURIOUS_VECTOR(x) (x)
-
-// Interrupt Command bitmasks
-#define ICR_VECTOR(x) (x)
-#define ICR_DELIVERY_PENDING (1 << 12)
-#define ICR_LEVEL_ASSERT (1 << 14)
-#define ICR_DST(x) (((uint32_t)(x)) << 24)
-#define ICR_DST_BROADCAST ICR_DST(0xff)
-#define ICR_DELIVERY_MODE(x) (((uint32_t)(x)) << 8)
-#define ICR_DST_SHORTHAND(x) (((uint32_t)(x)) << 18)
-#define ICR_DST_SELF ICR_DST_SHORTHAND(1)
-#define ICR_DST_ALL ICR_DST_SHORTHAND(2)
-#define ICR_DST_ALL_MINUS_SELF ICR_DST_SHORTHAND(3)
-
-#define X2_ICR_DST(x) ((uint64_t)(x) << 32)
-#define X2_ICR_BROADCAST ((uint64_t)(0xffffffff) << 32)
-
-// Common LVT bitmasks
-#define LVT_VECTOR(x) (x)
-#define LVT_DELIVERY_MODE(x) (((uint32_t)(x)) << 8)
-#define LVT_DELIVERY_PENDING (1 << 12)
-
-static void apic_error_init(void);
-static void apic_timer_init(void);
-static void apic_pmi_init(void);
-
-static uint32_t lapic_reg_read(size_t offset) {
-    if (x2apic_enabled) {
-        return read_msr32(LAPIC_X2APIC_MSR_BASE + (uint32_t)(offset >> 4));
-    } else {
-        return *((volatile uint32_t*)((uintptr_t)apic_virt_base + offset));
-    }
-}
-
-static void lapic_reg_write(size_t offset, uint32_t val) {
-    if (x2apic_enabled) {
-        write_msr(LAPIC_X2APIC_MSR_BASE + (uint32_t)(offset >> 4), val);
-    } else {
-        *((volatile uint32_t*)((uintptr_t)apic_virt_base + offset)) = val;
-    }
-}
-
-static void lapic_reg_or(size_t offset, uint32_t bits) {
-    lapic_reg_write(offset, lapic_reg_read(offset) | bits);
-}
-
-static void lapic_reg_and(size_t offset, uint32_t bits) {
-    lapic_reg_write(offset, lapic_reg_read(offset) & bits);
-}
-
-// This function must be called once on the kernel address space
-void apic_vm_init(void) {
-    // only memory map the aperture if we're using the legacy mmio interface
-    if (!x2apic_enabled) {
-        ASSERT(apic_virt_base == nullptr);
-        // Create a mapping for the page of MMIO registers
-        zx_status_t res = VmAspace::kernel_aspace()->AllocPhysical(
-            "lapic",
-            PAGE_SIZE,       // size
-            &apic_virt_base, // returned virtual address
-            PAGE_SIZE_SHIFT, // alignment log2
-            APIC_PHYS_BASE,  // physical address
-            0,               // vmm flags
-            ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE |
-                ARCH_MMU_FLAG_UNCACHED_DEVICE); // arch mmu flags
-        if (res != ZX_OK) {
-            panic("Could not allocate APIC management page: %d\n", res);
-        }
-        ASSERT(apic_virt_base != nullptr);
-    }
-}
-
-// Initializes the current processor's local APIC.  Should be called after
-// apic_vm_init has been called.
-void apic_local_init(void) {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    uint64_t v = read_msr(X86_MSR_IA32_APIC_BASE);
-
-    // if were the boot processor, test and cache x2apic ability
-    if (v & IA32_APIC_BASE_BSP) {
-        if (x86_feature_test(X86_FEATURE_X2APIC)) {
-            dprintf(SPEW, "x2APIC enabled\n");
-            x2apic_enabled = true;
-        }
-    }
-
-    // Enter xAPIC or x2APIC mode and set the base address
-    v |= IA32_APIC_BASE_XAPIC_ENABLE;
-    v |= x2apic_enabled ? IA32_APIC_BASE_X2APIC_ENABLE : 0;
-    write_msr(X86_MSR_IA32_APIC_BASE, v);
-
-    // If this is the bootstrap processor, we should record our APIC ID now
-    // that we know it.
-    if (v & IA32_APIC_BASE_BSP) {
-        uint8_t id = apic_local_id();
-
-        bsp_apic_id = id;
-        bsp_apic_id_valid = true;
-        x86_set_local_apic_id(id);
-    }
-
-    // Specify the spurious interrupt vector and enable the local APIC
-    uint32_t svr = SVR_SPURIOUS_VECTOR(X86_INT_APIC_SPURIOUS) | SVR_APIC_ENABLE;
-    lapic_reg_write(LAPIC_REG_SPURIOUS_IRQ, svr);
-
-    apic_error_init();
-    apic_timer_init();
-    apic_pmi_init();
-}
-
-uint8_t apic_local_id(void) {
-    uint32_t id = lapic_reg_read(LAPIC_REG_ID);
-
-    // legacy apic stores the id in the top 8 bits of the register
-    if (!x2apic_enabled)
-        id >>= 24;
-
-    // we can only deal with 8 bit apic ids right now
-    DEBUG_ASSERT(id < 256);
-
-    return (uint8_t)id;
-}
-
-uint8_t apic_bsp_id(void) {
-    DEBUG_ASSERT(bsp_apic_id_valid);
-    return bsp_apic_id;
-}
-
-static inline void apic_wait_for_ipi_send(void) {
-    while (lapic_reg_read(LAPIC_REG_IRQ_CMD_LOW) & ICR_DELIVERY_PENDING)
-        ;
-}
-
-// We only support physical destination modes for now
-
-void apic_send_ipi(
-    uint8_t vector,
-    uint32_t dst_apic_id,
-    enum apic_interrupt_delivery_mode dm) {
-    // we only support 8 bit apic ids
-    DEBUG_ASSERT(dst_apic_id < UINT8_MAX);
-
-    uint32_t request = ICR_VECTOR(vector) | ICR_LEVEL_ASSERT;
-    request |= ICR_DELIVERY_MODE(dm);
-
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    if (x2apic_enabled) {
-        write_msr(LAPIC_X2APIC_MSR_ICR, X2_ICR_DST(dst_apic_id) | request);
-    } else {
-        lapic_reg_write(LAPIC_REG_IRQ_CMD_HIGH, ICR_DST(dst_apic_id));
-        lapic_reg_write(LAPIC_REG_IRQ_CMD_LOW, request);
-        apic_wait_for_ipi_send();
-    }
-    arch_interrupt_restore(state, 0);
-}
-
-void apic_send_self_ipi(uint8_t vector, enum apic_interrupt_delivery_mode dm) {
-    uint32_t request = ICR_VECTOR(vector) | ICR_LEVEL_ASSERT;
-    request |= ICR_DELIVERY_MODE(dm) | ICR_DST_SELF;
-
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    if (x2apic_enabled) {
-        // special register for triggering self ipis
-        write_msr(LAPIC_X2APIC_MSR_SELF_IPI, vector);
-    } else {
-        lapic_reg_write(LAPIC_REG_IRQ_CMD_LOW, request);
-        apic_wait_for_ipi_send();
-    }
-    arch_interrupt_restore(state, 0);
-}
-
-// Broadcast to everyone including self
-void apic_send_broadcast_self_ipi(
-    uint8_t vector,
-    enum apic_interrupt_delivery_mode dm) {
-    uint32_t request = ICR_VECTOR(vector) | ICR_LEVEL_ASSERT;
-    request |= ICR_DELIVERY_MODE(dm) | ICR_DST_ALL;
-
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    if (x2apic_enabled) {
-        write_msr(LAPIC_X2APIC_MSR_ICR, X2_ICR_BROADCAST | request);
-    } else {
-        lapic_reg_write(LAPIC_REG_IRQ_CMD_HIGH, ICR_DST_BROADCAST);
-        lapic_reg_write(LAPIC_REG_IRQ_CMD_LOW, request);
-        apic_wait_for_ipi_send();
-    }
-    arch_interrupt_restore(state, 0);
-}
-
-// Broadcast to everyone excluding self
-void apic_send_broadcast_ipi(
-    uint8_t vector,
-    enum apic_interrupt_delivery_mode dm) {
-    uint32_t request = ICR_VECTOR(vector) | ICR_LEVEL_ASSERT;
-    request |= ICR_DELIVERY_MODE(dm) | ICR_DST_ALL_MINUS_SELF;
-
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    if (x2apic_enabled) {
-        write_msr(LAPIC_X2APIC_MSR_ICR, X2_ICR_BROADCAST | request);
-    } else {
-        lapic_reg_write(LAPIC_REG_IRQ_CMD_HIGH, ICR_DST_BROADCAST);
-        lapic_reg_write(LAPIC_REG_IRQ_CMD_LOW, request);
-        apic_wait_for_ipi_send();
-    }
-    arch_interrupt_restore(state, 0);
-}
-
-void apic_issue_eoi(void) {
-    // Write 0 to the EOI address to issue an EOI
-    lapic_reg_write(LAPIC_REG_EOI, 0);
-}
-
-// If this function returns an error, timer state will not have
-// been changed.
-static zx_status_t apic_timer_set_divide_value(uint8_t v) {
-    uint32_t new_value = 0;
-    switch (v) {
-    case 1:
-        new_value = 0xb;
-        break;
-    case 2:
-        new_value = 0x0;
-        break;
-    case 4:
-        new_value = 0x1;
-        break;
-    case 8:
-        new_value = 0x2;
-        break;
-    case 16:
-        new_value = 0x3;
-        break;
-    case 32:
-        new_value = 0x8;
-        break;
-    case 64:
-        new_value = 0x9;
-        break;
-    case 128:
-        new_value = 0xa;
-        break;
-    default:
-        return ZX_ERR_INVALID_ARGS;
-    }
-    lapic_reg_write(LAPIC_REG_DIVIDE_CONF, new_value);
-    return ZX_OK;
-}
-
-static void apic_timer_init(void) {
-    lapic_reg_write(LAPIC_REG_LVT_TIMER, LVT_VECTOR(X86_INT_APIC_TIMER) | LVT_MASKED);
-}
-
-// Racy; primarily useful for calibrating the timer.
-uint32_t apic_timer_current_count(void) {
-    return lapic_reg_read(LAPIC_REG_CURRENT_COUNT);
-}
-
-void apic_timer_mask(void) {
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    lapic_reg_or(LAPIC_REG_LVT_TIMER, LVT_MASKED);
-    arch_interrupt_restore(state, 0);
-}
-
-void apic_timer_unmask(void) {
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    lapic_reg_and(LAPIC_REG_LVT_TIMER, ~LVT_MASKED);
-    arch_interrupt_restore(state, 0);
-}
-
-void apic_timer_stop(void) {
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    lapic_reg_write(LAPIC_REG_INIT_COUNT, 0);
-    if (x86_feature_test(X86_FEATURE_TSC_DEADLINE)) {
-        write_msr(X86_MSR_IA32_TSC_DEADLINE, 0);
-    }
-    arch_interrupt_restore(state, 0);
-}
-
-zx_status_t apic_timer_set_oneshot(uint32_t count, uint8_t divisor, bool masked) {
-    zx_status_t status = ZX_OK;
-    uint32_t timer_config = LVT_VECTOR(X86_INT_APIC_TIMER) |
-                            LVT_TIMER_MODE_ONESHOT;
-    if (masked) {
-        timer_config |= LVT_MASKED;
-    }
-
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-
-    status = apic_timer_set_divide_value(divisor);
-    if (status != ZX_OK) {
-        goto cleanup;
-    }
-    lapic_reg_write(LAPIC_REG_LVT_TIMER, timer_config);
-    lapic_reg_write(LAPIC_REG_INIT_COUNT, count);
-cleanup:
-    arch_interrupt_restore(state, 0);
-    return status;
-}
-
-void apic_timer_set_tsc_deadline(uint64_t deadline, bool masked) {
-    DEBUG_ASSERT(x86_feature_test(X86_FEATURE_TSC_DEADLINE));
-
-    uint32_t timer_config = LVT_VECTOR(X86_INT_APIC_TIMER) |
-                            LVT_TIMER_MODE_TSC_DEADLINE;
-    if (masked) {
-        timer_config |= LVT_MASKED;
-    }
-
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-
-    lapic_reg_write(LAPIC_REG_LVT_TIMER, timer_config);
-    // Intel recommends using an MFENCE to ensure the LVT_TIMER_ADDR write
-    // takes before the write_msr(), since writes to this MSR are ignored if the
-    // time mode is not DEADLINE.
-    mb();
-    write_msr(X86_MSR_IA32_TSC_DEADLINE, deadline);
-
-    arch_interrupt_restore(state, 0);
-}
-
-zx_status_t apic_timer_set_periodic(uint32_t count, uint8_t divisor) {
-    zx_status_t status = ZX_OK;
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-
-    status = apic_timer_set_divide_value(divisor);
-    if (status != ZX_OK) {
-        goto cleanup;
-    }
-    lapic_reg_write(LAPIC_REG_LVT_TIMER, LVT_VECTOR(X86_INT_APIC_TIMER) | LVT_TIMER_MODE_PERIODIC);
-    lapic_reg_write(LAPIC_REG_INIT_COUNT, count);
-cleanup:
-    arch_interrupt_restore(state, 0);
-    return status;
-}
-
-void apic_timer_interrupt_handler(void) {
-    platform_handle_apic_timer_tick();
-}
-
-static void apic_error_init(void) {
-    lapic_reg_write(LAPIC_REG_LVT_ERROR, LVT_VECTOR(X86_INT_APIC_ERROR));
-    // Re-arm the error interrupt triggering mechanism
-    lapic_reg_write(LAPIC_REG_ERROR_STATUS, 0);
-}
-
-void apic_error_interrupt_handler(void) {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    // This write doesn't effect the subsequent read, but is required prior to
-    // reading.
-    lapic_reg_write(LAPIC_REG_ERROR_STATUS, 0);
-    panic("APIC error detected: %u\n", lapic_reg_read(LAPIC_REG_ERROR_STATUS));
-}
-
-static void apic_pmi_init(void) {
-    lapic_reg_write(LAPIC_REG_LVT_PERF, LVT_VECTOR(X86_INT_APIC_PMI) | LVT_MASKED);
-}
-
-void apic_pmi_mask(void) {
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    lapic_reg_or(LAPIC_REG_LVT_PERF, LVT_MASKED);
-    arch_interrupt_restore(state, 0);
-}
-
-void apic_pmi_unmask(void) {
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-    lapic_reg_and(LAPIC_REG_LVT_PERF, ~LVT_MASKED);
-    arch_interrupt_restore(state, 0);
-}
-
-static int cmd_apic(int argc, const cmd_args* argv, uint32_t flags) {
-    if (argc < 2) {
-    notenoughargs:
-        printf("not enough arguments\n");
-    usage:
-        printf("usage:\n");
-        printf("%s dump io\n", argv[0].str);
-        printf("%s dump local\n", argv[0].str);
-        printf("%s broadcast <vec>\n", argv[0].str);
-        printf("%s self <vec>\n", argv[0].str);
-        return ZX_ERR_INTERNAL;
-    }
-
-    if (!strcmp(argv[1].str, "broadcast")) {
-        if (argc < 3)
-            goto notenoughargs;
-        uint8_t vec = (uint8_t)argv[2].u;
-        apic_send_broadcast_ipi(vec, DELIVERY_MODE_FIXED);
-        printf("irr: %x\n", lapic_reg_read(LAPIC_REG_IRQ_REQUEST(vec / 32)));
-        printf("isr: %x\n", lapic_reg_read(LAPIC_REG_IN_SERVICE(vec / 32)));
-        printf("icr: %x\n", lapic_reg_read(LAPIC_REG_IRQ_CMD_LOW));
-    } else if (!strcmp(argv[1].str, "self")) {
-        if (argc < 3)
-            goto notenoughargs;
-        uint8_t vec = (uint8_t)argv[2].u;
-        apic_send_self_ipi(vec, DELIVERY_MODE_FIXED);
-        printf("irr: %x\n", lapic_reg_read(LAPIC_REG_IRQ_REQUEST(vec / 32)));
-        printf("isr: %x\n", lapic_reg_read(LAPIC_REG_IN_SERVICE(vec / 32)));
-        printf("icr: %x\n", lapic_reg_read(LAPIC_REG_IRQ_CMD_LOW));
-    } else if (!strcmp(argv[1].str, "dump")) {
-        if (argc < 3)
-            goto notenoughargs;
-        if (!strcmp(argv[2].str, "local")) {
-            printf("Caution: this is only for one CPU\n");
-            apic_local_debug();
-        } else if (!strcmp(argv[2].str, "io")) {
-            apic_io_debug();
-        } else {
-            printf("unknown subcommand\n");
-            goto usage;
-        }
-    } else {
-        printf("unknown command\n");
-        goto usage;
-    }
-
-    return ZX_OK;
-}
-
-void apic_local_debug(void) {
-    spin_lock_saved_state_t state;
-    arch_interrupt_save(&state, 0);
-
-    printf("apic %02x:\n", apic_local_id());
-    printf("  version: %08x:\n", lapic_reg_read(LAPIC_REG_VERSION));
-    printf("  logical_dst: %08x\n", lapic_reg_read(LAPIC_REG_LOGICAL_DST));
-    printf("  spurious_irq: %08x\n", lapic_reg_read(LAPIC_REG_SPURIOUS_IRQ));
-    printf("  tpr: %02x\n", (uint8_t)lapic_reg_read(LAPIC_REG_TASK_PRIORITY));
-    printf("  ppr: %02x\n", (uint8_t)lapic_reg_read(LAPIC_REG_PROCESSOR_PRIORITY));
-    for (int i = 0; i < 8; ++i)
-        printf("  irr %d: %08x\n", i, lapic_reg_read(LAPIC_REG_IRQ_REQUEST(i)));
-    for (int i = 0; i < 8; ++i)
-        printf("  isr %d: %08x\n", i, lapic_reg_read(LAPIC_REG_IN_SERVICE(i)));
-
-    arch_interrupt_restore(state, 0);
-}
-
-STATIC_COMMAND_START
-#if LK_DEBUGLEVEL > 0
-STATIC_COMMAND("apic", "apic commands", &cmd_apic)
-#endif
-STATIC_COMMAND_END(apic);
diff --git a/kernel/arch/x86/mexec.S b/kernel/arch/x86/mexec.S
deleted file mode 100644
index dd492be..0000000
--- a/kernel/arch/x86/mexec.S
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/defines.h>
-#include <arch/x86/asm.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/registers.h>
-#include <asm.h>
-#include <zircon/tls.h>
-#include <mexec.h>
-
-#define CODE_SEGMENT_SELECTOR (1 << 3)
-#define DATA_SEGMENT_SELECTOR (2 << 3)
-
-.text
-FUNCTION_LABEL(mexec_asm)
-    // Make sure interrupts are disabled.
-    cli
-
-    /* Stash all the arguments passed in registers R8 - R13 */
-    mov %r9,  %r13   /* Unused Arg */
-    mov %r8,  %r12   /* Memmove Ops */
-    mov %rcx, %r11   /* Unused Arg */
-    mov %rdx, %r10   /* ENTRY64_ADDR */
-    mov %rsi, %r9    /* CR3 for Safe page tables */
-    mov %rdi, %r8    /* Bootimage Address */
-
-    // The old SP is in the old kernel virtual address space, so don't use it.
-    xor %esp, %esp
-
-    // Make sure old PGE mappings from the kernel address space are not
-    // still in the TLB.  Having them there masked the previous bug wherein
-    // this code relied on using the incoming stack pointer.
-    mov %cr4, %rax
-    and $~X86_CR4_PGE, %rax
-    mov %rax, %cr4
-
-    // Switch to the safe identity mapped page tables.
-    mov  %r9, %cr3
-
-    // Load our little GDT defined below.  The current GDT is somewhere
-    // that might be overwritten when we copy in the new kernel below.
-    lea mexec_gdt(%rip), %rax
-    mov %rax, mexec_gdt_pointer(%rip)
-    lgdt mexec_gdt_descriptor(%rip)
-
-    // Switch to the new data segment.
-    mov $DATA_SEGMENT_SELECTOR, %ax
-    mov %ax, %ds
-    mov %ax, %es
-    mov %ax, %ss
-
-    // Switch to the new code segment.
-    // Note that ljmp accepts only a 32-bit address (aka "offset").
-    // That's fine here, since we know we're running in the low 4G here.
-    leal .Lnew_cs(%rip), %eax
-    movl %eax, mexec_ljmp_descriptor(%rip)
-    ljmp *mexec_ljmp_descriptor(%rip)
-.Lnew_cs:
-
-    /* Load the kernel relocation op into ram */
-    mov MEMMOV_OPS_DST_OFFSET (%r12), %rdi
-    mov MEMMOV_OPS_SRC_OFFSET (%r12), %rsi
-    mov MEMMOV_OPS_LEN_OFFSET (%r12), %rcx
-
-    /* Move RCX bytes from RSI to RDI */
-    cld               /* Clear the direction flag so that we're copying forward */
-                      /* by default when we start */
-
-    cmp %rsi, %rdi    /* Compare the src and dst registers to see if we need to */
-                      /* copy forwards or backwards */
-
-    jbe .Ldo_copy      /* if dst is greater than src, go ahead and do the copy */
-                      /* forwards */
-
-    mov %rcx, %rax    /* rcx and rax contain the number of bytes to be copied */
-    sub $1,   %rax    /* Move rsi and rdi to the end of their respective buffers */
-    add %rax, %rdi
-    add %rax, %rsi
-
-    std               /* Set the direction flag to 1. This will ensure that the */
-                      /* copy happens from the back of the buffers to the front */
-
-.Ldo_copy:
-
-    rep movsb         /* copy RCX bytes from RSI to RDI */
-
-    cld               /* Clear the direction flag since we may have polluted it */
-                      /* if we did a copy backwards */
-
-    /* Move the address of the bootdata into the appropriate register */
-    mov %r8, %rsi
-
-    /* Zero out some registers */
-    xor %ebx, %ebx
-    xor %edi, %edi
-    xor %ebp, %ebp
-
-    /* Grab 64bit entrypoint from provided location */
-    mov (%r10), %rax
-
-    /* See you on the other side! */
-    jmp *%rax
-
-    /* Crash, we should never reach here */
-    ud2
-
-END_DATA(mexec_asm)
-
-.balign 8
-LOCAL_DATA(mexec_gdt)
-    // Null entry.
-    .int 0
-    .int 0
-
-    // 64-bit code segment.
-    .short 0xffff           // limit 15:00
-    .short 0x0000           // base 15:00
-    .byte  0x00             // base 23:16
-    .byte  0b10011010       // P(1) DPL(00) S(1) 1 C(0) R(1) A(0)
-    .byte  0b10101111       // G(1) D(0) L(1) AVL(0) limit 19:16
-    .byte  0x0              // base 31:24
-
-    // Data segment.
-    .short 0xffff           // limit 15:00
-    .short 0x0000           // base 15:00
-    .byte  0x00             // base 23:16
-    .byte  0b10010010       // P(1) DPL(00) S(1) 0 E(0) W(1) A(0)
-    .byte  0b11001111       // G(1) B(1) 0 0 limit 19:16
-    .byte  0x0              // base 31:24
-END_DATA(mexec_gdt)
-DATA(mexec_gdt_end)
-
-.balign 8
-LOCAL_DATA(mexec_gdt_descriptor)
-    .short mexec_gdt_end - mexec_gdt - 1
-LOCAL_DATA(mexec_gdt_pointer)
-    .quad 0 // Filled in at runtime.
-END_DATA(mexec_gdt_descriptor)
-
-.balign 8
-LOCAL_DATA(mexec_ljmp_descriptor)
-    .long 0 // Filled in at runtime.
-    .short CODE_SEGMENT_SELECTOR
-END_DATA(mexec_ljmp_descriptor)
-
-DATA(mexec_asm_end)
diff --git a/kernel/arch/x86/mmu.cpp b/kernel/arch/x86/mmu.cpp
deleted file mode 100644
index 3626a0a..0000000
--- a/kernel/arch/x86/mmu.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-#include <err.h>
-#include <string.h>
-#include <trace.h>
-
-#include <arch/arch_ops.h>
-#include <arch/mmu.h>
-#include <arch/x86.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/mmu_mem_types.h>
-#include <kernel/mp.h>
-#include <new>
-#include <vm/arch_vm_aspace.h>
-#include <vm/physmap.h>
-#include <vm/pmm.h>
-#include <vm/vm.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-/* Default address width including virtual/physical address.
- * newer versions fetched below */
-uint8_t g_vaddr_width = 48;
-uint8_t g_paddr_width = 32;
-
-/* True if the system supports 1GB pages */
-static bool supports_huge_pages = false;
-
-/* top level kernel page tables, initialized in start.S */
-volatile pt_entry_t pml4[NO_OF_PT_ENTRIES] __ALIGNED(PAGE_SIZE);
-volatile pt_entry_t pdp[NO_OF_PT_ENTRIES] __ALIGNED(PAGE_SIZE); /* temporary */
-volatile pt_entry_t pte[NO_OF_PT_ENTRIES] __ALIGNED(PAGE_SIZE);
-
-/* top level pdp needed to map the -512GB..0 space */
-volatile pt_entry_t pdp_high[NO_OF_PT_ENTRIES] __ALIGNED(PAGE_SIZE);
-
-/* a big pile of page tables needed to map 64GB of memory into kernel space using 2MB pages */
-volatile pt_entry_t linear_map_pdp[(64ULL * GB) / (2 * MB)] __ALIGNED(PAGE_SIZE);
-
-/* which of the above variables is the top level page table */
-#define KERNEL_PT pml4
-
-// Static relocated base to prepare for KASLR. Used at early boot and by gdb
-// script to know the target relocated address.
-// TODO(thgarnie): Move to a dynamicly generated base address
-#if DISABLE_KASLR
-uint64_t kernel_relocated_base = KERNEL_BASE - KERNEL_LOAD_OFFSET;
-#else
-uint64_t kernel_relocated_base = 0xffffffff00000000;
-#endif
-
-/* kernel base top level page table in physical space */
-static const paddr_t kernel_pt_phys =
-    (vaddr_t)KERNEL_PT - (vaddr_t)__code_start + KERNEL_LOAD_OFFSET;
-
-// Valid EPT MMU flags.
-static const uint kValidEptFlags =
-    ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE | ARCH_MMU_FLAG_PERM_EXECUTE;
-
-paddr_t x86_kernel_cr3(void) {
-    return kernel_pt_phys;
-}
-
-/**
- * @brief  check if the virtual address is canonical
- */
-bool x86_is_vaddr_canonical(vaddr_t vaddr) {
-    uint64_t max_vaddr_lohalf, min_vaddr_hihalf;
-
-    /* get max address in lower-half canonical addr space */
-    /* e.g. if width is 48, then 0x00007FFF_FFFFFFFF */
-    max_vaddr_lohalf = ((uint64_t)1ull << (g_vaddr_width - 1)) - 1;
-
-    /* get min address in higher-half canonical addr space */
-    /* e.g. if width is 48, then 0xFFFF8000_00000000*/
-    min_vaddr_hihalf = ~max_vaddr_lohalf;
-
-    /* Check to see if the address in a canonical address */
-    if ((vaddr > max_vaddr_lohalf) && (vaddr < min_vaddr_hihalf))
-        return false;
-
-    return true;
-}
-
-/**
- * @brief  check if the virtual address is aligned and canonical
- */
-static bool x86_mmu_check_vaddr(vaddr_t vaddr) {
-    /* Check to see if the address is PAGE aligned */
-    if (!IS_ALIGNED(vaddr, PAGE_SIZE))
-        return false;
-
-    return x86_is_vaddr_canonical(vaddr);
-}
-
-/**
- * @brief  check if the physical address is valid and aligned
- */
-bool x86_mmu_check_paddr(paddr_t paddr) {
-    uint64_t max_paddr;
-
-    /* Check to see if the address is PAGE aligned */
-    if (!IS_ALIGNED(paddr, PAGE_SIZE))
-        return false;
-
-    max_paddr = ((uint64_t)1ull << g_paddr_width) - 1;
-
-    return paddr <= max_paddr;
-}
-
-/**
- * @brief  invalidate all TLB entries, including global entries
- */
-static void x86_tlb_global_invalidate() {
-    /* See Intel 3A section 4.10.4.1 */
-    ulong cr4 = x86_get_cr4();
-    if (likely(cr4 & X86_CR4_PGE)) {
-        x86_set_cr4(cr4 & ~X86_CR4_PGE);
-        x86_set_cr4(cr4);
-    } else {
-        x86_set_cr3(x86_get_cr3());
-    }
-}
-
-/**
- * @brief  invalidate all TLB entries, excluding global entries
- */
-static void x86_tlb_nonglobal_invalidate() {
-    x86_set_cr3(x86_get_cr3());
-}
-
-/* Task used for invalidating a TLB entry on each CPU */
-struct TlbInvalidatePage_context {
-    ulong target_cr3;
-    const PendingTlbInvalidation* pending;
-};
-static void TlbInvalidatePage_task(void* raw_context) {
-    DEBUG_ASSERT(arch_ints_disabled());
-    TlbInvalidatePage_context* context = (TlbInvalidatePage_context*)raw_context;
-
-    ulong cr3 = x86_get_cr3();
-    if (context->target_cr3 != cr3 && !context->pending->contains_global) {
-        /* This invalidation doesn't apply to this CPU, ignore it */
-        return;
-    }
-
-    if (context->pending->full_shootdown) {
-        if (context->pending->contains_global) {
-            x86_tlb_global_invalidate();
-        } else {
-            x86_tlb_nonglobal_invalidate();
-        }
-        return;
-    }
-
-    for (uint i = 0; i < context->pending->count; ++i) {
-        const auto& item = context->pending->item[i];
-        switch (item.page_level()) {
-            case PML4_L:
-                panic("PML4_L invld found; should not be here\n");
-            case PDP_L:
-            case PD_L:
-            case PT_L:
-                __asm__ volatile("invlpg %0" ::"m"(*(uint8_t*)item.addr()));
-                break;
-        }
-    }
-}
-
-/**
- * @brief Execute a queued TLB invalidation
- *
- * @param pt The page table we're invalidating for (if nullptr, assume for current one)
- * @param pending The planned invalidation
- */
-static void x86_tlb_invalidate_page(const X86PageTableBase* pt, PendingTlbInvalidation* pending) {
-    if (pending->count == 0) {
-        return;
-    }
-
-    ulong cr3 = pt ? pt->phys() : x86_get_cr3();
-    struct TlbInvalidatePage_context task_context = {
-        .target_cr3 = cr3, .pending = pending,
-    };
-
-    /* Target only CPUs this aspace is active on.  It may be the case that some
-     * other CPU will become active in it after this load, or will have left it
-     * just before this load.  In the former case, it is becoming active after
-     * the write to the page table, so it will see the change.  In the latter
-     * case, it will get a spurious request to flush. */
-    mp_ipi_target_t target;
-    cpu_mask_t target_mask = 0;
-    if (pending->contains_global || pt == nullptr) {
-        target = MP_IPI_TARGET_ALL;
-    } else {
-        target = MP_IPI_TARGET_MASK;
-        target_mask = static_cast<X86ArchVmAspace*>(pt->ctx())->active_cpus();
-    }
-
-    mp_sync_exec(target, target_mask, TlbInvalidatePage_task, &task_context);
-    pending->clear();
-}
-
-bool X86PageTableMmu::check_paddr(paddr_t paddr) {
-    return x86_mmu_check_paddr(paddr);
-}
-
-bool X86PageTableMmu::check_vaddr(vaddr_t vaddr) {
-    return x86_mmu_check_vaddr(vaddr);
-}
-
-bool X86PageTableMmu::supports_page_size(PageTableLevel level) {
-    DEBUG_ASSERT(level != PT_L);
-    switch (level) {
-    case PD_L:
-        return true;
-    case PDP_L:
-        return supports_huge_pages;
-    case PML4_L:
-        return false;
-    default:
-        panic("Unreachable case in supports_page_size\n");
-    }
-}
-
-X86PageTableBase::IntermediatePtFlags X86PageTableMmu::intermediate_flags() {
-    return X86_MMU_PG_RW | X86_MMU_PG_U;
-}
-
-X86PageTableBase::PtFlags X86PageTableMmu::terminal_flags(PageTableLevel level,
-                                                          uint flags) {
-    X86PageTableBase::PtFlags terminal_flags = 0;
-
-    if (flags & ARCH_MMU_FLAG_PERM_WRITE) {
-        terminal_flags |= X86_MMU_PG_RW;
-    }
-    if (flags & ARCH_MMU_FLAG_PERM_USER) {
-        terminal_flags |= X86_MMU_PG_U;
-    }
-    if (use_global_mappings_) {
-        terminal_flags |= X86_MMU_PG_G;
-    }
-    if (!(flags & ARCH_MMU_FLAG_PERM_EXECUTE)) {
-        terminal_flags |= X86_MMU_PG_NX;
-    }
-
-    if (level > 0) {
-        switch (flags & ARCH_MMU_FLAG_CACHE_MASK) {
-        case ARCH_MMU_FLAG_CACHED:
-            terminal_flags |= X86_MMU_LARGE_PAT_WRITEBACK;
-            break;
-        case ARCH_MMU_FLAG_UNCACHED_DEVICE:
-        case ARCH_MMU_FLAG_UNCACHED:
-            terminal_flags |= X86_MMU_LARGE_PAT_UNCACHABLE;
-            break;
-        case ARCH_MMU_FLAG_WRITE_COMBINING:
-            terminal_flags |= X86_MMU_LARGE_PAT_WRITE_COMBINING;
-            break;
-        default:
-            PANIC_UNIMPLEMENTED;
-        }
-    } else {
-        switch (flags & ARCH_MMU_FLAG_CACHE_MASK) {
-        case ARCH_MMU_FLAG_CACHED:
-            terminal_flags |= X86_MMU_PTE_PAT_WRITEBACK;
-            break;
-        case ARCH_MMU_FLAG_UNCACHED_DEVICE:
-        case ARCH_MMU_FLAG_UNCACHED:
-            terminal_flags |= X86_MMU_PTE_PAT_UNCACHABLE;
-            break;
-        case ARCH_MMU_FLAG_WRITE_COMBINING:
-            terminal_flags |= X86_MMU_PTE_PAT_WRITE_COMBINING;
-            break;
-        default:
-            PANIC_UNIMPLEMENTED;
-        }
-    }
-
-    return terminal_flags;
-}
-
-X86PageTableBase::PtFlags X86PageTableMmu::split_flags(PageTableLevel level,
-                                                       X86PageTableBase::PtFlags flags) {
-    DEBUG_ASSERT(level != PML4_L && level != PT_L);
-    DEBUG_ASSERT(flags & X86_MMU_PG_PS);
-    if (level == PD_L) {
-        // Note: Clear PS before the check below; the PAT bit for a PTE is the
-        // the same as the PS bit for a higher table entry.
-        flags &= ~X86_MMU_PG_PS;
-
-        /* If the larger page had the PAT flag set, make sure it's
-         * transferred to the different index for a PTE */
-        if (flags & X86_MMU_PG_LARGE_PAT) {
-            flags &= ~X86_MMU_PG_LARGE_PAT;
-            flags |= X86_MMU_PG_PTE_PAT;
-        }
-    }
-    return flags;
-}
-
-void X86PageTableMmu::TlbInvalidate(PendingTlbInvalidation* pending) {
-    x86_tlb_invalidate_page(this, pending);
-}
-
-uint X86PageTableMmu::pt_flags_to_mmu_flags(PtFlags flags, PageTableLevel level) {
-    uint mmu_flags = ARCH_MMU_FLAG_PERM_READ;
-
-    if (flags & X86_MMU_PG_RW) {
-        mmu_flags |= ARCH_MMU_FLAG_PERM_WRITE;
-    }
-    if (flags & X86_MMU_PG_U) {
-        mmu_flags |= ARCH_MMU_FLAG_PERM_USER;
-    }
-    if (!(flags & X86_MMU_PG_NX)) {
-        mmu_flags |= ARCH_MMU_FLAG_PERM_EXECUTE;
-    }
-
-    if (level > 0) {
-        switch (flags & X86_MMU_LARGE_PAT_MASK) {
-        case X86_MMU_LARGE_PAT_WRITEBACK:
-            mmu_flags |= ARCH_MMU_FLAG_CACHED;
-            break;
-        case X86_MMU_LARGE_PAT_UNCACHABLE:
-            mmu_flags |= ARCH_MMU_FLAG_UNCACHED;
-            break;
-        case X86_MMU_LARGE_PAT_WRITE_COMBINING:
-            mmu_flags |= ARCH_MMU_FLAG_WRITE_COMBINING;
-            break;
-        default:
-            PANIC_UNIMPLEMENTED;
-        }
-    } else {
-        switch (flags & X86_MMU_PTE_PAT_MASK) {
-        case X86_MMU_PTE_PAT_WRITEBACK:
-            mmu_flags |= ARCH_MMU_FLAG_CACHED;
-            break;
-        case X86_MMU_PTE_PAT_UNCACHABLE:
-            mmu_flags |= ARCH_MMU_FLAG_UNCACHED;
-            break;
-        case X86_MMU_PTE_PAT_WRITE_COMBINING:
-            mmu_flags |= ARCH_MMU_FLAG_WRITE_COMBINING;
-            break;
-        default:
-            PANIC_UNIMPLEMENTED;
-        }
-    }
-    return mmu_flags;
-}
-
-bool X86PageTableEpt::allowed_flags(uint flags) {
-    if (!(flags & ARCH_MMU_FLAG_PERM_READ)) {
-        return false;
-    }
-    if (flags & ~kValidEptFlags) {
-        return false;
-    }
-    return true;
-}
-
-bool X86PageTableEpt::check_paddr(paddr_t paddr) {
-    return x86_mmu_check_paddr(paddr);
-}
-
-bool X86PageTableEpt::check_vaddr(vaddr_t vaddr) {
-    return x86_mmu_check_vaddr(vaddr);
-}
-
-bool X86PageTableEpt::supports_page_size(PageTableLevel level) {
-    DEBUG_ASSERT(level != PT_L);
-    switch (level) {
-    case PD_L:
-        return true;
-    case PDP_L:
-        return supports_huge_pages;
-    case PML4_L:
-        return false;
-    default:
-        panic("Unreachable case in supports_page_size\n");
-    }
-}
-
-X86PageTableBase::PtFlags X86PageTableEpt::intermediate_flags() {
-    return X86_EPT_R | X86_EPT_W | X86_EPT_X;
-}
-
-X86PageTableBase::PtFlags X86PageTableEpt::terminal_flags(PageTableLevel level,
-                                                          uint flags) {
-    X86PageTableBase::PtFlags terminal_flags = 0;
-
-    if (flags & ARCH_MMU_FLAG_PERM_READ) {
-        terminal_flags |= X86_EPT_R;
-    }
-    if (flags & ARCH_MMU_FLAG_PERM_WRITE) {
-        terminal_flags |= X86_EPT_W;
-    }
-    if (flags & ARCH_MMU_FLAG_PERM_EXECUTE) {
-        terminal_flags |= X86_EPT_X;
-    }
-
-    switch (flags & ARCH_MMU_FLAG_CACHE_MASK) {
-    case ARCH_MMU_FLAG_CACHED:
-        terminal_flags |= X86_EPT_WB;
-        break;
-    case ARCH_MMU_FLAG_UNCACHED_DEVICE:
-    case ARCH_MMU_FLAG_UNCACHED:
-        terminal_flags |= X86_EPT_UC;
-        break;
-    case ARCH_MMU_FLAG_WRITE_COMBINING:
-        terminal_flags |= X86_EPT_WC;
-        break;
-    default:
-        PANIC_UNIMPLEMENTED;
-    }
-
-    return terminal_flags;
-}
-
-X86PageTableBase::PtFlags X86PageTableEpt::split_flags(PageTableLevel level,
-                                                       X86PageTableBase::PtFlags flags) {
-    DEBUG_ASSERT(level != PML4_L && level != PT_L);
-    // We don't need to relocate any flags on split for EPT.
-    return flags;
-}
-
-
-void X86PageTableEpt::TlbInvalidate(PendingTlbInvalidation* pending) {
-    // TODO(ZX-981): Implement this.
-    pending->clear();
-}
-
-uint X86PageTableEpt::pt_flags_to_mmu_flags(PtFlags flags, PageTableLevel level) {
-    uint mmu_flags = 0;
-
-    if (flags & X86_EPT_R) {
-        mmu_flags |= ARCH_MMU_FLAG_PERM_READ;
-    }
-    if (flags & X86_EPT_W) {
-        mmu_flags |= ARCH_MMU_FLAG_PERM_WRITE;
-    }
-    if (flags & X86_EPT_X) {
-        mmu_flags |= ARCH_MMU_FLAG_PERM_EXECUTE;
-    }
-
-    switch (flags & X86_EPT_MEMORY_TYPE_MASK) {
-    case X86_EPT_WB:
-        mmu_flags |= ARCH_MMU_FLAG_CACHED;
-        break;
-    case X86_EPT_UC:
-        mmu_flags |= ARCH_MMU_FLAG_UNCACHED;
-        break;
-    case X86_EPT_WC:
-        mmu_flags |= ARCH_MMU_FLAG_WRITE_COMBINING;
-        break;
-    default:
-        PANIC_UNIMPLEMENTED;
-    }
-
-    return mmu_flags;
-}
-
-void x86_mmu_early_init() {
-    x86_mmu_percpu_init();
-
-    x86_mmu_mem_type_init();
-
-    // Unmap the lower identity mapping.
-    pml4[0] = 0;
-    PendingTlbInvalidation tlb;
-    tlb.enqueue(0, PML4_L, /* global */ false, /* terminal */ false);
-    x86_tlb_invalidate_page(nullptr, &tlb);
-
-    /* get the address width from the CPU */
-    uint8_t vaddr_width = x86_linear_address_width();
-    uint8_t paddr_width = x86_physical_address_width();
-
-    supports_huge_pages = x86_feature_test(X86_FEATURE_HUGE_PAGE);
-
-    /* if we got something meaningful, override the defaults.
-     * some combinations of cpu on certain emulators seems to return
-     * nonsense paddr widths (1), so trim it. */
-    if (paddr_width > g_paddr_width)
-        g_paddr_width = paddr_width;
-    if (vaddr_width > g_vaddr_width)
-        g_vaddr_width = vaddr_width;
-
-    LTRACEF("paddr_width %u vaddr_width %u\n", g_paddr_width, g_vaddr_width);
-}
-
-void x86_mmu_init(void) {}
-
-X86PageTableBase::X86PageTableBase() {
-}
-
-X86PageTableBase::~X86PageTableBase() {
-    DEBUG_ASSERT_MSG(!phys_, "page table dtor called before Destroy()");
-}
-
-// We disable analysis due to the write to |pages_| tripping it up.  It is safe
-// to write to |pages_| since this is part of object construction.
-zx_status_t X86PageTableBase::Init(void* ctx) TA_NO_THREAD_SAFETY_ANALYSIS {
-    /* allocate a top level page table for the new address space */
-    vm_page* p;
-    paddr_t pa;
-    zx_status_t status = pmm_alloc_page(0, &p, &pa);
-    if (status != ZX_OK) {
-        TRACEF("error allocating top level page directory\n");
-        return ZX_ERR_NO_MEMORY;
-    }
-    virt_ = reinterpret_cast<pt_entry_t*>(paddr_to_physmap(pa));
-    phys_ = pa;
-    p->state = VM_PAGE_STATE_MMU;
-
-    // TODO(abdulla): Remove when PMM returns pre-zeroed pages.
-    arch_zero_page(virt_);
-
-    ctx_ = ctx;
-    pages_ = 1;
-    return ZX_OK;
-}
-
-// We disable analysis due to the write to |pages_| tripping it up.  It is safe
-// to write to |pages_| since this is part of object construction.
-zx_status_t X86PageTableMmu::InitKernel(void* ctx) TA_NO_THREAD_SAFETY_ANALYSIS {
-    phys_ = kernel_pt_phys;
-    virt_ = (pt_entry_t*)X86_PHYS_TO_VIRT(phys_);
-    ctx_ = ctx;
-    pages_ = 1;
-    use_global_mappings_ = true;
-    return ZX_OK;
-}
-
-zx_status_t X86PageTableMmu::AliasKernelMappings() {
-    // Copy the kernel portion of it from the master kernel pt.
-    memcpy(virt_ + NO_OF_PT_ENTRIES / 2,
-           const_cast<pt_entry_t*>(&KERNEL_PT[NO_OF_PT_ENTRIES / 2]),
-           sizeof(pt_entry_t) * NO_OF_PT_ENTRIES / 2);
-    return ZX_OK;
-}
-
-X86ArchVmAspace::X86ArchVmAspace() {}
-
-/*
- * Fill in the high level x86 arch aspace structure and allocating a top level page table.
- */
-zx_status_t X86ArchVmAspace::Init(vaddr_t base, size_t size, uint mmu_flags) {
-    static_assert(sizeof(cpu_mask_t) == sizeof(active_cpus_), "err");
-    canary_.Assert();
-
-    LTRACEF("aspace %p, base %#" PRIxPTR ", size 0x%zx, mmu_flags 0x%x\n", this, base, size,
-            mmu_flags);
-
-    flags_ = mmu_flags;
-    base_ = base;
-    size_ = size;
-    if (mmu_flags & ARCH_ASPACE_FLAG_KERNEL) {
-        X86PageTableMmu* mmu = new (page_table_storage_) X86PageTableMmu();
-        pt_ = mmu;
-
-        zx_status_t status = mmu->InitKernel(this);
-        if (status != ZX_OK) {
-            return status;
-        }
-        LTRACEF("kernel aspace: pt phys %#" PRIxPTR ", virt %p\n", pt_->phys(), pt_->virt());
-    } else if (mmu_flags & ARCH_ASPACE_FLAG_GUEST) {
-        X86PageTableEpt* ept = new (page_table_storage_) X86PageTableEpt();
-        pt_ = ept;
-
-        zx_status_t status = ept->Init(this);
-        if (status != ZX_OK) {
-            return status;
-        }
-        LTRACEF("guest paspace: pt phys %#" PRIxPTR ", virt %p\n", pt_->phys(), pt_->virt());
-    } else {
-        X86PageTableMmu* mmu = new (page_table_storage_) X86PageTableMmu;
-        pt_ = mmu;
-
-        zx_status_t status = mmu->Init(this);
-        if (status != ZX_OK) {
-            return status;
-        }
-
-        status = mmu->AliasKernelMappings();
-        if (status != ZX_OK) {
-            return status;
-        }
-
-        LTRACEF("user aspace: pt phys %#" PRIxPTR ", virt %p\n", pt_->phys(), pt_->virt());
-    }
-    fbl::atomic_init(&active_cpus_, 0);
-
-    return ZX_OK;
-}
-
-zx_status_t X86ArchVmAspace::Destroy() {
-    canary_.Assert();
-    DEBUG_ASSERT(active_cpus_.load() == 0);
-
-    if (flags_ & ARCH_ASPACE_FLAG_GUEST) {
-        static_cast<X86PageTableEpt*>(pt_)->Destroy(base_, size_);
-    } else {
-        static_cast<X86PageTableMmu*>(pt_)->Destroy(base_, size_);
-    }
-    return ZX_OK;
-}
-
-zx_status_t X86ArchVmAspace::Unmap(vaddr_t vaddr, size_t count, size_t* unmapped) {
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    return pt_->UnmapPages(vaddr, count, unmapped);
-}
-
-zx_status_t X86ArchVmAspace::MapContiguous(vaddr_t vaddr, paddr_t paddr, size_t count,
-                                           uint mmu_flags, size_t* mapped) {
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    return pt_->MapPagesContiguous(vaddr, paddr, count, mmu_flags, mapped);
-}
-
-zx_status_t X86ArchVmAspace::Map(vaddr_t vaddr, paddr_t* phys, size_t count,
-                                 uint mmu_flags, size_t* mapped) {
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    return pt_->MapPages(vaddr, phys, count, mmu_flags, mapped);
-}
-
-zx_status_t X86ArchVmAspace::Protect(vaddr_t vaddr, size_t count, uint mmu_flags) {
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    return pt_->ProtectPages(vaddr, count, mmu_flags);
-}
-
-void X86ArchVmAspace::ContextSwitch(X86ArchVmAspace* old_aspace, X86ArchVmAspace* aspace) {
-    cpu_mask_t cpu_bit = cpu_num_to_mask(arch_curr_cpu_num());
-    if (aspace != nullptr) {
-        aspace->canary_.Assert();
-        paddr_t phys = aspace->pt_phys();
-        LTRACEF_LEVEL(3, "switching to aspace %p, pt %#" PRIXPTR "\n", aspace, phys);
-        x86_set_cr3(phys);
-
-        if (old_aspace != nullptr) {
-            old_aspace->active_cpus_.fetch_and(~cpu_bit);
-        }
-        aspace->active_cpus_.fetch_or(cpu_bit);
-    } else {
-        LTRACEF_LEVEL(3, "switching to kernel aspace, pt %#" PRIxPTR "\n", kernel_pt_phys);
-        x86_set_cr3(kernel_pt_phys);
-        if (old_aspace != nullptr) {
-            old_aspace->active_cpus_.fetch_and(~cpu_bit);
-        }
-    }
-
-    // Cleanup io bitmap entries from previous thread.
-    if (old_aspace)
-        x86_clear_tss_io_bitmap(old_aspace->io_bitmap());
-
-    // Set the io bitmap for this thread.
-    if (aspace)
-        x86_set_tss_io_bitmap(aspace->io_bitmap());
-}
-
-zx_status_t X86ArchVmAspace::Query(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags) {
-    if (!IsValidVaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-
-    return pt_->QueryVaddr(vaddr, paddr, mmu_flags);
-}
-
-void x86_mmu_percpu_init(void) {
-    ulong cr0 = x86_get_cr0();
-    /* Set write protect bit in CR0*/
-    cr0 |= X86_CR0_WP;
-    // Clear Cache disable/not write-through bits
-    cr0 &= ~(X86_CR0_NW | X86_CR0_CD);
-    x86_set_cr0(cr0);
-
-    /* Setting the SMEP & SMAP bit in CR4 */
-    ulong cr4 = x86_get_cr4();
-    if (x86_feature_test(X86_FEATURE_SMEP))
-        cr4 |= X86_CR4_SMEP;
-    if (x86_feature_test(X86_FEATURE_SMAP))
-        cr4 |= X86_CR4_SMAP;
-    x86_set_cr4(cr4);
-
-    // Set NXE bit in X86_MSR_IA32_EFER.
-    uint64_t efer_msr = read_msr(X86_MSR_IA32_EFER);
-    efer_msr |= X86_EFER_NXE;
-    write_msr(X86_MSR_IA32_EFER, efer_msr);
-}
-
-X86ArchVmAspace::~X86ArchVmAspace() {
-    if (pt_) {
-        pt_->~X86PageTableBase();
-    }
-    // TODO(ZX-980): check that we've destroyed the aspace.
-}
-
-vaddr_t X86ArchVmAspace::PickSpot(vaddr_t base, uint prev_region_mmu_flags,
-                                  vaddr_t end, uint next_region_mmu_flags,
-                                  vaddr_t align, size_t size, uint mmu_flags) {
-    canary_.Assert();
-    return PAGE_ALIGN(base);
-}
diff --git a/kernel/arch/x86/mmu_mem_types.cpp b/kernel/arch/x86/mmu_mem_types.cpp
deleted file mode 100644
index b968029..0000000
--- a/kernel/arch/x86/mmu_mem_types.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/mmu_mem_types.h>
-#include <arch/x86/registers.h>
-#include <assert.h>
-#include <debug.h>
-#include <err.h>
-#include <kernel/mp.h>
-#include <lib/console.h>
-#include <stdio.h>
-#include <string.h>
-
-/* address widths from mmu.c */
-extern uint8_t g_paddr_width;
-
-/* MTRR MSRs */
-#define IA32_MTRR_NUM_FIX16K 2
-#define IA32_MTRR_FIX16K_80000(x) (X86_MSR_IA32_MTRR_FIX16K_80000 + (x))
-#define IA32_MTRR_NUM_FIX4K 8
-#define IA32_MTRR_FIX4K_C0000(x) (X86_MSR_IA32_MTRR_FIX4K_C0000 + (x))
-#define IA32_MTRR_PHYSBASE(x) (X86_MSR_IA32_MTRR_PHYSBASE0 + 2 * (x))
-#define IA32_MTRR_PHYSMASK(x) (X86_MSR_IA32_MTRR_PHYSMASK0 + 2 * (x))
-
-/* IA32_MTRRCAP read functions */
-#define MTRRCAP_VCNT(x) ((x)&0xff)
-#define MTRRCAP_VCNT_MAX 255
-#define MTRRCAP_FIX(x) !!((x) & (1 << 8))
-#define MTRRCAP_WC(x) !!((x) & (1 << 10))
-
-/* IA32_MTRR_DEF_TYPE read functions */
-/* global enable flag for MTRRs */
-#define MTRR_DEF_TYPE_ENABLE(x) ((x) & (1 << 11))
-/* enable flag for fixed-range MTRRs */
-#define MTRR_DEF_TYPE_FIXED_ENABLE(x) ((x) & (1 << 10))
-#define MTRR_DEF_TYPE_TYPE(x) ((uint8_t)(x))
-
-/* IA32_MTRR_DEF_TYPE masks */
-#define MTRR_DEF_TYPE_ENABLE_FLAG (1 << 11)
-#define MTRR_DEF_TYPE_FIXED_ENABLE_FLAG (1 << 10)
-#define MTRR_DEF_TYPE_TYPE_MASK 0xff
-
-/* IA32_MTRR_PHYSBASE read functions */
-#define MTRR_PHYSBASE_BASE(x) ((x) & ~((1ULL << 12) - 1) & ((1ULL << g_paddr_width) - 1))
-#define MTRR_PHYSBASE_TYPE(x) ((uint8_t)(x))
-
-/* IA32_MTRR_PHYSMASK read functions */
-#define MTRR_PHYSMASK_MASK(x) ((x) & ~((1ULL << 12) - 1) & ((1ULL << g_paddr_width) - 1))
-#define MTRR_PHYSMASK_VALID(x) !!((x) & (1 << 11))
-
-/* Number of variable length MTRRs */
-static uint8_t num_variable = 0;
-/* Whether or not fixed range MTRRs are supported */
-static bool supports_fixed_range = false;
-/* Whether write-combining memory type is supported */
-static bool supports_wc = false;
-
-struct variable_mtrr {
-    uint64_t physbase;
-    uint64_t physmask;
-};
-
-struct mtrrs {
-    uint64_t mtrr_def;
-    uint64_t mtrr_fix64k;
-    uint64_t mtrr_fix16k[IA32_MTRR_NUM_FIX16K];
-    uint64_t mtrr_fix4k[IA32_MTRR_NUM_FIX4K];
-    struct variable_mtrr mtrr_var[MTRRCAP_VCNT_MAX];
-};
-
-static struct mtrrs THE_MTRRS;
-static struct mtrrs* target_mtrrs = &THE_MTRRS;
-
-/* Function called by all CPUs to setup their PAT */
-static void x86_pat_sync_task(void* context);
-struct pat_sync_task_context {
-    /* Barrier counters for the two barriers described in Intel's algorithm */
-    volatile int barrier1;
-    volatile int barrier2;
-};
-
-void x86_mmu_mem_type_init(void) {
-    uint64_t caps = read_msr(X86_MSR_IA32_MTRRCAP);
-    num_variable = MTRRCAP_VCNT(caps);
-    supports_fixed_range = MTRRCAP_FIX(caps);
-    supports_wc = MTRRCAP_WC(caps);
-
-    target_mtrrs->mtrr_def = read_msr(X86_MSR_IA32_MTRR_DEF_TYPE);
-    target_mtrrs->mtrr_fix64k = read_msr(X86_MSR_IA32_MTRR_FIX64K_00000);
-    for (uint i = 0; i < IA32_MTRR_NUM_FIX16K; ++i) {
-        target_mtrrs->mtrr_fix16k[i] = read_msr(IA32_MTRR_FIX16K_80000(i));
-    }
-    for (uint i = 0; i < IA32_MTRR_NUM_FIX4K; ++i) {
-        target_mtrrs->mtrr_fix4k[i] = read_msr(IA32_MTRR_FIX4K_C0000(i));
-    }
-    for (uint i = 0; i < num_variable; ++i) {
-        target_mtrrs->mtrr_var[i].physbase = read_msr(IA32_MTRR_PHYSBASE(i));
-        target_mtrrs->mtrr_var[i].physmask = read_msr(IA32_MTRR_PHYSMASK(i));
-    }
-
-    /* Update the PAT on the bootstrap processor (and sync any changes to the
-     * MTRR that may have been made above). */
-    x86_pat_sync(1 << 0);
-}
-
-/* @brief Give the specificed CPUs our Page Attribute Tables and
- * Memory Type Range Registers.
- *
- * This operation is not safe to perform while a CPU may be
- * hotplugged.  This should be called with mp_get_online_mask() as
- * the targets if we ever want to update the PAT or MTRRs after
- * boot.
- *
- * This algorithm is based on section 11.11.8 of Intel 3A
- */
-void x86_pat_sync(cpu_mask_t targets) {
-    targets &= mp_get_online_mask();
-
-    struct pat_sync_task_context context = {
-        .barrier1 = (int)targets,
-        .barrier2 = (int)targets,
-    };
-    /* Step 1: Broadcast to all processors to execute the sequence */
-    mp_sync_exec(MP_IPI_TARGET_MASK, targets, x86_pat_sync_task, &context);
-}
-
-static void x86_pat_sync_task(void* raw_context) {
-    /* Step 2: Disable interrupts */
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    struct pat_sync_task_context* context = (struct pat_sync_task_context*)raw_context;
-
-    uint cpu = arch_curr_cpu_num();
-
-    /* Step 3: Wait for all processors to reach this point. */
-    atomic_and(&context->barrier1, ~(1 << cpu));
-    while (context->barrier1 != 0) {
-        arch_spinloop_pause();
-    }
-
-    /* Step 4: Enter the no-fill cache mode (cache-disable and writethrough) */
-    ulong cr0 = x86_get_cr0();
-    DEBUG_ASSERT(!(cr0 & X86_CR0_CD) && !(cr0 & X86_CR0_NW));
-    cr0 |= X86_CR0_CD;
-    cr0 &= ~X86_CR0_NW;
-    x86_set_cr0(cr0);
-
-    /* Step 5: Flush all caches */
-    __asm volatile("wbinvd" ::
-                       : "memory");
-
-    /* Step 6: If the PGE flag is set, clear it to flush the TLB */
-    ulong cr4 = x86_get_cr4();
-    bool pge_was_set = !!(cr4 & X86_CR4_PGE);
-    cr4 &= ~X86_CR4_PGE;
-    x86_set_cr4(cr4);
-
-    /* Step 7: If the PGE flag wasn't set, flush the TLB via CR3 */
-    if (!pge_was_set) {
-        x86_set_cr3(x86_get_cr3());
-    }
-
-    /* Step 8: Disable MTRRs */
-    write_msr(X86_MSR_IA32_MTRR_DEF_TYPE, 0);
-
-    /* Step 9: Sync up the MTRR entries */
-    write_msr(X86_MSR_IA32_MTRR_FIX64K_00000, target_mtrrs->mtrr_fix64k);
-    for (uint i = 0; i < IA32_MTRR_NUM_FIX16K; ++i) {
-        write_msr(IA32_MTRR_FIX16K_80000(i), target_mtrrs->mtrr_fix16k[i]);
-    }
-    for (uint i = 0; i < IA32_MTRR_NUM_FIX4K; ++i) {
-        write_msr(IA32_MTRR_FIX4K_C0000(i), target_mtrrs->mtrr_fix4k[i]);
-    }
-    for (uint i = 0; i < num_variable; ++i) {
-        write_msr(IA32_MTRR_PHYSBASE(i), target_mtrrs->mtrr_var[i].physbase);
-        write_msr(IA32_MTRR_PHYSMASK(i), target_mtrrs->mtrr_var[i].physmask);
-    }
-
-    /* For now, we leave the MTRRs as the firmware gave them to us, except for
-     * setting the default memory type to uncached */
-
-    /* Starting from here, we diverge from the algorithm in 11.11.8.  That
-     * algorithm is for MTRR changes, and 11.12.4 suggests using a variant of
-     * it.
-     */
-
-    /* Perform PAT changes now that caches aren't being filled and the
-     * TLB is flushed. */
-    uint64_t pat_val = 0;
-    pat_val |= (uint64_t)X86_PAT_INDEX0 << 0;
-    pat_val |= (uint64_t)X86_PAT_INDEX1 << 8;
-    pat_val |= (uint64_t)X86_PAT_INDEX2 << 16;
-    pat_val |= (uint64_t)X86_PAT_INDEX3 << 24;
-    pat_val |= (uint64_t)X86_PAT_INDEX4 << 32;
-    pat_val |= (uint64_t)X86_PAT_INDEX5 << 40;
-    pat_val |= (uint64_t)X86_PAT_INDEX6 << 48;
-    pat_val |= (uint64_t)X86_PAT_INDEX7 << 56;
-    write_msr(X86_MSR_IA32_PAT, pat_val);
-
-    /* Step 10: Re-enable MTRRs (and set the default type) */
-    write_msr(X86_MSR_IA32_MTRR_DEF_TYPE, target_mtrrs->mtrr_def);
-
-    /* Step 11: Flush all cache and the TLB again */
-    __asm volatile("wbinvd" ::
-                       : "memory");
-    x86_set_cr3(x86_get_cr3());
-
-    /* Step 12: Enter the normal cache mode */
-    cr0 = x86_get_cr0();
-    cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
-    x86_set_cr0(cr0);
-
-    /* Step 13: Re-enable PGE if it was previously set */
-    if (pge_was_set) {
-        cr4 = x86_get_cr4();
-        cr4 |= X86_CR4_PGE;
-        x86_set_cr4(cr4);
-    }
-
-    /* Step 14: Wait for all processors to reach this point. */
-    atomic_and(&context->barrier2, ~(1 << cpu));
-    while (context->barrier2 != 0) {
-        arch_spinloop_pause();
-    }
-}
-
-/* Helper for decoding and printing MTRRs */
-static void print_fixed_range_mtrr(uint32_t msr, uint32_t base, uint32_t record_size) {
-    uint64_t val = read_msr(msr);
-    for (int i = 0; i < 8; ++i) {
-        printf("  f %#05x-%#05x: %#02x\n", base, base + record_size - 1, (uint8_t)val);
-        base += record_size;
-        val >>= 8;
-    }
-}
-
-static void print_pat_entries(void* _ignored) {
-    uint64_t pat = read_msr(X86_MSR_IA32_PAT);
-    for (int i = 0; i < 8; ++i) {
-        printf("  Index %d: %#02x\n", i, (uint8_t)pat);
-        pat >>= 8;
-    }
-}
-
-static int cmd_memtype(int argc, const cmd_args* argv, uint32_t flags) {
-    if (argc < 2) {
-        printf("not enough arguments\n");
-    usage:
-        printf("usage:\n");
-        printf("%s mtrr\n", argv[0].str);
-        printf("%s pat\n", argv[0].str);
-        return ZX_ERR_INTERNAL;
-    }
-
-    if (!strcmp(argv[1].str, "mtrr")) {
-        bool print_fixed = false;
-        if (argc > 2) {
-            if (!strcmp(argv[2].str, "-f")) {
-                print_fixed = true;
-            } else {
-                printf("usage: %s mtrr [-f]\n", argv[0].str);
-                printf("  -f    Display fixed registers\n");
-                return ZX_ERR_INTERNAL;
-            }
-        }
-        uint64_t default_type = read_msr(X86_MSR_IA32_MTRR_DEF_TYPE);
-        printf("MTRR state: master %s, fixed %s\n",
-               MTRR_DEF_TYPE_ENABLE(default_type) ? "enable" : "disable",
-               MTRR_DEF_TYPE_FIXED_ENABLE(default_type) ? "enable" : "disable");
-        printf("  default: %#02x\n", MTRR_DEF_TYPE_TYPE(default_type));
-        if (supports_fixed_range && print_fixed) {
-            print_fixed_range_mtrr(X86_MSR_IA32_MTRR_FIX64K_00000, 0x00000, (1 << 16));
-            for (int i = 0; i < IA32_MTRR_NUM_FIX16K; ++i) {
-                print_fixed_range_mtrr(IA32_MTRR_FIX16K_80000(i), 0x80000 + i * (1 << 17), (1 << 14));
-            }
-            for (int i = 0; i < IA32_MTRR_NUM_FIX4K; ++i) {
-                print_fixed_range_mtrr(IA32_MTRR_FIX4K_C0000(i), 0xC0000 + i * (1 << 15), (1 << 12));
-            }
-        }
-
-        for (uint i = 0; i < num_variable; ++i) {
-            uint64_t base = read_msr(IA32_MTRR_PHYSBASE(i));
-            uint64_t mask = read_msr(IA32_MTRR_PHYSMASK(i));
-            printf("  v (%s) base %#016llx, mask %#016llx: %#02x\n",
-                   MTRR_PHYSMASK_VALID(mask) ? "valid" : "invalid",
-                   MTRR_PHYSBASE_BASE(base),
-                   MTRR_PHYSMASK_MASK(mask),
-                   MTRR_PHYSBASE_TYPE(base));
-        }
-    } else if (!strcmp(argv[1].str, "pat")) {
-        uint num_cpus = arch_max_num_cpus();
-        for (uint i = 0; i < num_cpus; ++i) {
-            printf("CPU %u Page Attribute Table types:\n", i);
-            mp_sync_exec(MP_IPI_TARGET_MASK, 1u << i, print_pat_entries, nullptr);
-        }
-    } else {
-        printf("unknown command\n");
-        goto usage;
-    }
-
-    return ZX_OK;
-}
-
-STATIC_COMMAND_START
-#if LK_DEBUGLEVEL > 0
-STATIC_COMMAND("memtype", "memory type commands", &cmd_memtype)
-#endif
-STATIC_COMMAND_END(memtype);
diff --git a/kernel/arch/x86/mmu_tests.cpp b/kernel/arch/x86/mmu_tests.cpp
deleted file mode 100644
index 6b58337..0000000
--- a/kernel/arch/x86/mmu_tests.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/aspace.h>
-#include <arch/mmu.h>
-#include <arch/x86/mmu.h>
-#include <err.h>
-#include <lib/unittest/unittest.h>
-#include <vm/arch_vm_aspace.h>
-#include <zircon/types.h>
-
-static bool mmu_tests() {
-    BEGIN_TEST;
-    unittest_printf("creating large un-aligned vm region, and unmap it without mapping, make sure no leak (ZX-315)\n");
-    {
-        ArchVmAspace aspace;
-        vaddr_t base = 1UL << 20;
-        size_t size = (1UL << 47) - base - (1UL << 20);
-        zx_status_t err = aspace.Init(1UL << 20, size, 0);
-        EXPECT_EQ(err, ZX_OK, "init aspace");
-        EXPECT_EQ(aspace.pt_pages(), 1u, "single page for PML4 table");
-
-        const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;
-
-        // We want our region to be misaligned by at least a page, and for
-        // it to straddle the PDP.
-        vaddr_t va = (1UL << PDP_SHIFT) - (1UL << PD_SHIFT) + 2 * PAGE_SIZE;
-        // Make sure alloc_size is less than 1 PD page, to exercise the
-        // non-terminal code path.
-        static const size_t alloc_size = (1UL << PD_SHIFT) - PAGE_SIZE;
-
-        // Map a single page to force the lower PDP of the target region
-        // to be created
-        size_t mapped;
-        err = aspace.MapContiguous(va - 3 * PAGE_SIZE, 0, 1, arch_rw_flags, &mapped);
-        EXPECT_EQ(err, ZX_OK, "map single page");
-        EXPECT_EQ(mapped, 1u, "map single page");
-        EXPECT_EQ(aspace.pt_pages(), 4u,
-                  "map single page, PDP, PD and PT tables allocated");
-
-        // Map the last page of the region
-        err = aspace.MapContiguous(va + alloc_size - PAGE_SIZE, 0, 1, arch_rw_flags, &mapped);
-        EXPECT_EQ(err, ZX_OK, "map last page");
-        EXPECT_EQ(mapped, 1u, "map single page");
-        EXPECT_EQ(aspace.pt_pages(), 6u,
-                  "map single page, PD and PT tables allocated");
-
-        paddr_t pa;
-        uint flags;
-        err = aspace.Query(va + alloc_size - PAGE_SIZE, &pa, &flags);
-        EXPECT_EQ(err, ZX_OK, "last entry is mapped");
-
-        // Attempt to unmap the target region (analogous to unmapping a demand
-        // paged region that has only had its last page touched)
-        size_t unmapped;
-        err = aspace.Unmap(va, alloc_size / PAGE_SIZE, &unmapped);
-        EXPECT_EQ(err, ZX_OK, "unmap unallocated region");
-        EXPECT_EQ(unmapped, alloc_size / PAGE_SIZE, "unmap unallocated region");
-        EXPECT_EQ(aspace.pt_pages(), 4u, "unmap allocated region");
-
-        err = aspace.Query(va + alloc_size - PAGE_SIZE, &pa, &flags);
-        EXPECT_EQ(err, ZX_ERR_NOT_FOUND, "last entry is not mapped anymore");
-
-        // Unmap the single page from earlier
-        err = aspace.Unmap(va - 3 * PAGE_SIZE, 1, &unmapped);
-        EXPECT_EQ(err, ZX_OK, "unmap single page");
-        EXPECT_EQ(unmapped, 1u, "unmap unallocated region");
-        EXPECT_EQ(aspace.pt_pages(), 1u, "unmap single page");
-
-        err = aspace.Destroy();
-        EXPECT_EQ(err, ZX_OK, "destroy aspace");
-    }
-
-    unittest_printf("creating large un-aligned vm region, and unmap it without mapping (ZX-315)\n");
-    {
-        ArchVmAspace aspace;
-        vaddr_t base = 1UL << 20;
-        size_t size = (1UL << 47) - base - (1UL << 20);
-        zx_status_t err = aspace.Init(1UL << 20, size, 0);
-        EXPECT_EQ(err, ZX_OK, "init aspace");
-        EXPECT_EQ(aspace.pt_pages(), 1u, "single page for PML4 table");
-
-        const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;
-
-        // We want our region to be misaligned by a page, and for it to
-        // straddle the PDP
-        vaddr_t va = (1UL << PDP_SHIFT) - (1UL << PD_SHIFT) + PAGE_SIZE;
-        // Make sure alloc_size is bigger than 1 PD page, to exercise the
-        // non-terminal code path.
-        static const size_t alloc_size = 3UL << PD_SHIFT;
-
-        // Map a single page to force the lower PDP of the target region
-        // to be created
-        size_t mapped;
-        err = aspace.MapContiguous(va - 2 * PAGE_SIZE, 0, 1, arch_rw_flags, &mapped);
-        EXPECT_EQ(err, ZX_OK, "map single page");
-        EXPECT_EQ(mapped, 1u, "map single page");
-        EXPECT_EQ(aspace.pt_pages(), 4u,
-                  "map single page, PDP, PD and PT tables allocated");
-
-        // Attempt to unmap the target region (analogous to unmapping a demand
-        // paged region that has not been touched)
-        size_t unmapped;
-        err = aspace.Unmap(va, alloc_size / PAGE_SIZE, &unmapped);
-        EXPECT_EQ(err, ZX_OK, "unmap unallocated region");
-        EXPECT_EQ(unmapped, alloc_size / PAGE_SIZE, "unmap unallocated region");
-        EXPECT_EQ(aspace.pt_pages(), 4u, "unmap unallocated region");
-
-        // Unmap the single page from earlier
-        err = aspace.Unmap(va - 2 * PAGE_SIZE, 1, &unmapped);
-        EXPECT_EQ(err, ZX_OK, "unmap single page");
-        EXPECT_EQ(unmapped, 1u, "unmap single page");
-        EXPECT_EQ(aspace.pt_pages(), 1u, "unmap single page");
-
-        err = aspace.Destroy();
-        EXPECT_EQ(err, ZX_OK, "destroy aspace");
-    }
-
-    unittest_printf("creating large vm region, and change permissions\n");
-    {
-        ArchVmAspace aspace;
-        vaddr_t base = 1UL << 20;
-        size_t size = (1UL << 47) - base - (1UL << 20);
-        zx_status_t err = aspace.Init(1UL << 20, size, 0);
-        EXPECT_EQ(err, ZX_OK, "init aspace");
-        EXPECT_EQ(aspace.pt_pages(), 1u, "single page for PML4 table");
-
-        const uint arch_rw_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;
-
-        vaddr_t va = 1UL << PDP_SHIFT;
-        // Force a large page.
-        static const size_t alloc_size = 1UL << PD_SHIFT;
-
-        size_t mapped;
-        err = aspace.MapContiguous(va, 0, alloc_size / PAGE_SIZE, arch_rw_flags, &mapped);
-        EXPECT_EQ(err, ZX_OK, "map large page");
-        EXPECT_EQ(mapped, 512u, "map large page");
-        EXPECT_EQ(aspace.pt_pages(), 3u, "map large page");
-
-        err = aspace.Protect(va + PAGE_SIZE, 1, ARCH_MMU_FLAG_PERM_READ);
-        EXPECT_EQ(err, ZX_OK, "protect single page");
-        EXPECT_EQ(aspace.pt_pages(), 4u,
-                  "protect single page, split large page");
-
-        err = aspace.Destroy();
-        EXPECT_EQ(err, ZX_OK, "destroy aspace");
-    }
-
-    unittest_printf("done with mmu tests\n");
-    END_TEST;
-}
-
-UNITTEST_START_TESTCASE(x86_mmu_tests)
-UNITTEST("mmu tests", mmu_tests)
-UNITTEST_END_TESTCASE(x86_mmu_tests, "x86_mmu", "x86 mmu tests");
diff --git a/kernel/arch/x86/mp.cpp b/kernel/arch/x86/mp.cpp
deleted file mode 100644
index 4c7b0f85..0000000
--- a/kernel/arch/x86/mp.cpp
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-#include <debug.h>
-#include <err.h>
-#include <stdio.h>
-#include <string.h>
-#include <trace.h>
-#include <zircon/compiler.h>
-
-#include <arch/mp.h>
-#include <arch/ops.h>
-#include <arch/x86.h>
-#include <arch/x86/apic.h>
-#include <arch/x86/cpu_topology.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/interrupts.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/mp.h>
-#include <arch/x86/tsc.h>
-#include <dev/hw_rng.h>
-#include <dev/interrupt.h>
-#include <kernel/event.h>
-#include <kernel/timer.h>
-#include <platform.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-struct x86_percpu* ap_percpus;
-uint8_t x86_num_cpus = 1;
-static bool use_monitor = false;
-
-extern struct idt _idt;
-
-#if __has_feature(safe_stack)
-static uint8_t unsafe_kstack[PAGE_SIZE] __ALIGNED(16);
-#define unsafe_kstack_end (&unsafe_kstack[sizeof(unsafe_kstack)])
-#else
-#define unsafe_kstack_end nullptr
-#endif
-
-// Fake monitor to use until smp is initialized. The size of
-// the memory range doesn't matter, since it won't actually get
-// used in a non-smp environment.
-volatile uint8_t fake_monitor;
-
-// Pre-initialize the per cpu structure for the boot cpu. Referenced by
-// early boot code prior to being able to initialize via code.
-struct x86_percpu bp_percpu = {
-    .direct = &bp_percpu,
-    .current_thread = {},
-
-    .stack_guard = {},
-    .kernel_unsafe_sp = (uintptr_t)unsafe_kstack_end,
-    .saved_user_sp = {},
-
-    .blocking_disallowed = {},
-    .monitor = &fake_monitor,
-
-    // Start with an invalid ID until we know the local APIC is set up.
-    .apic_id = INVALID_APIC_ID,
-
-    .gpf_return_target = {},
-
-    .cpu_num = 0,
-
-    .default_tss = {},
-    .interrupt_stacks = {},
-};
-
-zx_status_t x86_allocate_ap_structures(uint32_t* apic_ids, uint8_t cpu_count) {
-    ASSERT(ap_percpus == nullptr);
-
-    DEBUG_ASSERT(cpu_count >= 1);
-    if (cpu_count == 0) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (cpu_count > 1) {
-        size_t len = sizeof(*ap_percpus) * (cpu_count - 1);
-        ap_percpus = (x86_percpu*)memalign(MAX_CACHE_LINE, len);
-        if (ap_percpus == nullptr) {
-            return ZX_ERR_NO_MEMORY;
-        }
-        memset(ap_percpus, 0, len);
-
-        if ((use_monitor = x86_feature_test(X86_FEATURE_MON))) {
-            uint16_t monitor_size = x86_get_cpuid_leaf(X86_CPUID_MON)->b & 0xffff;
-            if (monitor_size < MAX_CACHE_LINE) {
-                monitor_size = MAX_CACHE_LINE;
-            }
-            uint8_t* monitors = (uint8_t*)memalign(monitor_size, monitor_size * cpu_count);
-            if (monitors == nullptr) {
-                return ZX_ERR_NO_MEMORY;
-            }
-            bp_percpu.monitor = monitors;
-            for (uint i = 1; i < cpu_count; ++i) {
-                ap_percpus[i - 1].monitor = monitors + (i * monitor_size);
-            }
-        }
-    }
-
-    uint32_t bootstrap_ap = apic_local_id();
-    DEBUG_ASSERT(bootstrap_ap == apic_bsp_id());
-
-    uint apic_idx = 0;
-    for (uint i = 0; i < cpu_count; ++i) {
-        if (apic_ids[i] == bootstrap_ap) {
-            continue;
-        }
-        DEBUG_ASSERT(apic_idx != (uint)(cpu_count - 1));
-        if (apic_idx == (uint)cpu_count - 1) {
-            /* Never found bootstrap CPU in apic id list */
-            return ZX_ERR_BAD_STATE;
-        }
-        ap_percpus[apic_idx].cpu_num = apic_idx + 1;
-        ap_percpus[apic_idx].apic_id = apic_ids[i];
-        ap_percpus[apic_idx].direct = &ap_percpus[apic_idx];
-        apic_idx++;
-    }
-
-    x86_num_cpus = cpu_count;
-    return ZX_OK;
-}
-
-void x86_init_percpu(cpu_num_t cpu_num) {
-    struct x86_percpu* const percpu =
-        cpu_num == 0 ? &bp_percpu : &ap_percpus[cpu_num - 1];
-    DEBUG_ASSERT(percpu->cpu_num == cpu_num);
-    DEBUG_ASSERT(percpu->direct == percpu);
-
-    // Assembly code has already set up %gs.base so that this function's
-    // own code can use it implicitly for stack-protector or safe-stack.
-    DEBUG_ASSERT(read_msr(X86_MSR_IA32_GS_BASE) == (uintptr_t)percpu);
-
-    /* set the KERNEL_GS_BASE MSR to 0 */
-    /* when we enter user space, this will be populated via a swapgs */
-    write_msr(X86_MSR_IA32_KERNEL_GS_BASE, 0);
-
-    x86_feature_init();
-
-    x86_cpu_topology_init();
-    x86_extended_register_init();
-    x86_extended_register_enable_feature(X86_EXTENDED_REGISTER_SSE);
-    x86_extended_register_enable_feature(X86_EXTENDED_REGISTER_AVX);
-
-    // This can be turned on/off later by the user. Turn it on here so that
-    // the buffer size assumes it's on.
-    x86_extended_register_enable_feature(X86_EXTENDED_REGISTER_PT);
-    // But then set the default mode to off.
-    x86_set_extended_register_pt_state(false);
-
-    gdt_load(gdt_get());
-
-    x86_initialize_percpu_tss();
-
-    // Setup the post early boot IDT
-    if (cpu_num == 0) {
-        idt_setup(&_idt);
-        // Setup alternate stacks to guarantee stack sanity when handling these
-        // interrupts
-        idt_set_ist_index(&_idt, X86_INT_NMI, NMI_IST_INDEX);
-        idt_set_ist_index(&_idt, X86_INT_MACHINE_CHECK, MCE_IST_INDEX);
-        idt_set_ist_index(&_idt, X86_INT_DOUBLE_FAULT, DBF_IST_INDEX);
-        idt_load(&_idt);
-    } else {
-        // Load the read-only IDT setup on arch initialization.
-        idt_load(idt_get_readonly());
-    }
-
-    // Apply any timestamp counter adjustment to keep a continuous clock across
-    // suspend/resume.
-    x86_tsc_adjust();
-
-    /* load the syscall entry point */
-    write_msr(X86_MSR_IA32_LSTAR, (uint64_t)&x86_syscall);
-
-    /* set the STAR MSR to load the appropriate kernel code selector on syscall
-     * and the appropriate user code selector on return.
-     * on syscall entry the following are loaded into segment registers:
-     *   CS = CODE_64_SELECTOR      (STAR[47:32])
-     *   SS = DATA_SELECTOR         (STAR[47:32] + 0x8)
-     * on syscall exit:
-     *   CS = USER_CODE_64_SELECTOR (STAR[63:48] + 0x16)
-     *   SS = USER_DATA_SELECTOR    (STAR[63:48] + 0x8)
-     */
-    write_msr(X86_MSR_IA32_STAR, (uint64_t)USER_CODE_SELECTOR << 48 | (uint64_t)CODE_64_SELECTOR << 32);
-
-    // Set the FMASK register to mask off certain bits in RFLAGS on syscall
-    // entry.  See docs/kernel_invariants.md.
-    uint64_t mask =
-        X86_FLAGS_AC |         /* disable alignment check/access control (this
-                                * prevents ring 0 from performing data access
-                                * to ring 3 if SMAP is available) */
-        X86_FLAGS_NT |         /* clear nested task */
-        X86_FLAGS_IOPL_MASK |  /* set iopl to 0 */
-        X86_FLAGS_STATUS_MASK; /* clear all status flags, interrupt disabled, trap flag */
-    write_msr(X86_MSR_IA32_FMASK, mask);
-
-    // Apply the same mask to our current flags, to ensure that flags are
-    // set to known-good values, because some flags may be inherited by
-    // later kernel threads.  We do this just in case any bad values were
-    // left behind by firmware or the bootloader.
-    x86_restore_flags(x86_save_flags() & ~mask);
-
-    /* enable syscall instruction */
-    uint64_t efer_msr = read_msr(X86_MSR_IA32_EFER);
-    efer_msr |= X86_EFER_SCE;
-    write_msr(X86_MSR_IA32_EFER, efer_msr);
-
-    uint64_t cr4 = x86_get_cr4();
-    // Enable {rd,wr}{fs,gs}base instructions.
-    if (x86_feature_test(X86_FEATURE_FSGSBASE)) {
-        cr4 |= X86_CR4_FSGSBASE;
-    }
-    if (x86_feature_test(X86_FEATURE_UMIP)) {
-        cr4 |= X86_CR4_UMIP;
-    }
-    x86_set_cr4(cr4);
-
-    // Some intel cpus support auto-entering C1E state when all cores are at C1. In
-    // C1E state the voltage is reduced on all cores as well as clock gated. There is
-    // a latency associated with ramping the voltage on wake. Disable this feature here
-    // to save time on the irq path from idle. (5-10us on skylake nuc from kernel irq
-    // handler to user space handler).
-    if (!x86_feature_test(X86_FEATURE_HYPERVISOR) &&
-        x86_get_microarch_config()->disable_c1e) {
-        uint64_t power_ctl_msr = read_msr(0x1fc);
-        write_msr(0x1fc, power_ctl_msr & ~0x2);
-    }
-
-    mp_set_curr_cpu_online(true);
-}
-
-void x86_set_local_apic_id(uint32_t apic_id) {
-    struct x86_percpu* percpu = x86_get_percpu();
-    DEBUG_ASSERT(percpu->cpu_num == 0);
-    percpu->apic_id = apic_id;
-}
-
-int x86_apic_id_to_cpu_num(uint32_t apic_id) {
-    if (bp_percpu.apic_id == apic_id) {
-        return (int)bp_percpu.cpu_num;
-    }
-
-    for (uint i = 0; i < (uint)x86_num_cpus - 1; ++i) {
-        if (ap_percpus[i].apic_id == apic_id) {
-            return (int)ap_percpus[i].cpu_num;
-        }
-    }
-    return -1;
-}
-
-zx_status_t arch_mp_reschedule(cpu_mask_t mask) {
-    DEBUG_ASSERT(thread_lock_held());
-
-    cpu_mask_t needs_ipi = 0;
-    if (use_monitor) {
-        while (mask) {
-            cpu_num_t cpu_id = lowest_cpu_set(mask);
-            cpu_mask_t cpu_mask = cpu_num_to_mask(cpu_id);
-            struct x86_percpu* percpu = cpu_id ? &ap_percpus[cpu_id - 1] : &bp_percpu;
-
-            // When a cpu see that it is about to start the idle thread, it sets its own
-            // monitor flag. When a cpu is rescheduling another cpu, if it sees the monitor flag
-            // set, it can clear the flag to wake up the other cpu w/o an IPI. When the other
-            // cpu wakes up, the idle thread sees the cleared flag and preempts itself. Both of
-            // these operations are under the scheduler lock, so there are no races where the
-            // wrong signal can be sent.
-            uint8_t old_val = *percpu->monitor;
-            *percpu->monitor = 0;
-            if (!old_val) {
-                needs_ipi |= cpu_mask;
-            }
-            mask &= ~cpu_mask;
-        }
-    } else {
-        needs_ipi = mask;
-    }
-
-    return needs_ipi ? arch_mp_send_ipi(MP_IPI_TARGET_MASK, needs_ipi, MP_IPI_RESCHEDULE) : ZX_OK;
-}
-
-void arch_prepare_current_cpu_idle_state(bool idle) {
-    DEBUG_ASSERT(thread_lock_held());
-
-    if (use_monitor) {
-        *x86_get_percpu()->monitor = idle;
-    }
-}
-
-__NO_RETURN int arch_idle_thread_routine(void*) {
-    if (use_monitor) {
-        struct x86_percpu* percpu = x86_get_percpu();
-        for (;;) {
-            while (*percpu->monitor) {
-                x86_monitor(percpu->monitor);
-                // Check percpu->monitor in case it was cleared between the first check and
-                // the monitor being armed. Any writes after arming the monitor will trigger
-                // it and cause mwait to return, so there aren't races after this check.
-                if (*percpu->monitor) {
-                    x86_mwait();
-                }
-            }
-            thread_preempt();
-        }
-    } else {
-        for (;;) {
-            x86_idle();
-        }
-    }
-}
-
-zx_status_t arch_mp_send_ipi(mp_ipi_target_t target, cpu_mask_t mask, mp_ipi_t ipi) {
-    uint8_t vector = 0;
-    switch (ipi) {
-    case MP_IPI_GENERIC:
-        vector = X86_INT_IPI_GENERIC;
-        break;
-    case MP_IPI_RESCHEDULE:
-        vector = X86_INT_IPI_RESCHEDULE;
-        break;
-    case MP_IPI_INTERRUPT:
-        vector = X86_INT_IPI_INTERRUPT;
-        break;
-    case MP_IPI_HALT:
-        vector = X86_INT_IPI_HALT;
-        break;
-    default:
-        panic("Unexpected MP IPI value: %u", (uint)ipi);
-    }
-
-    if (target == MP_IPI_TARGET_ALL_BUT_LOCAL) {
-        apic_send_broadcast_ipi(vector, DELIVERY_MODE_FIXED);
-        return ZX_OK;
-    } else if (target == MP_IPI_TARGET_ALL) {
-        apic_send_broadcast_self_ipi(vector, DELIVERY_MODE_FIXED);
-        return ZX_OK;
-    }
-
-    ASSERT(x86_num_cpus <= sizeof(mask) * CHAR_BIT);
-
-    cpu_mask_t remaining = mask;
-    uint cpu_id = 0;
-    while (remaining && cpu_id < x86_num_cpus) {
-        if (remaining & 1) {
-            struct x86_percpu* percpu;
-            if (cpu_id == 0) {
-                percpu = &bp_percpu;
-            } else {
-                percpu = &ap_percpus[cpu_id - 1];
-            }
-            /* Reschedule IPIs may occur before all CPUs are fully up.  Just
-             * ignore attempts to send them to down CPUs. */
-            if (ipi != MP_IPI_RESCHEDULE) {
-                DEBUG_ASSERT(percpu->apic_id != INVALID_APIC_ID);
-            }
-            /* Make sure the CPU is actually up before sending the IPI */
-            if (percpu->apic_id != INVALID_APIC_ID) {
-                apic_send_ipi(vector, (uint8_t)percpu->apic_id, DELIVERY_MODE_FIXED);
-            }
-        }
-        remaining >>= 1;
-        cpu_id++;
-    }
-
-    return ZX_OK;
-}
-
-void x86_ipi_halt_handler(void*) {
-    printf("halting cpu %u\n", arch_curr_cpu_num());
-
-    platform_halt_cpu();
-
-    for (;;) {
-        x86_cli();
-        x86_hlt();
-    }
-}
-
-// Forcibly stops all other CPUs except the current one and the BSP (which is
-// cpu 0)
-void x86_force_halt_all_but_local_and_bsp(void) {
-    cpu_num_t self = arch_curr_cpu_num();
-    for (cpu_num_t i = 1; i < x86_num_cpus; ++i) {
-        if (i == self) {
-            continue;
-        }
-        uint32_t dst_apic_id = ap_percpus[i - 1].apic_id;
-        apic_send_ipi(0, static_cast<uint8_t>(dst_apic_id),
-                      DELIVERY_MODE_INIT);
-    }
-}
-
-zx_status_t arch_mp_prep_cpu_unplug(uint cpu_id) {
-    if (cpu_id == 0 || cpu_id >= x86_num_cpus) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    return ZX_OK;
-}
-
-zx_status_t arch_mp_cpu_unplug(uint cpu_id) {
-    /* we do not allow unplugging the bootstrap processor */
-    if (cpu_id == 0 || cpu_id >= x86_num_cpus) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    uint32_t dst_apic_id = ap_percpus[cpu_id - 1].apic_id;
-    if (dst_apic_id == INVALID_APIC_ID) {
-        /* This is a transient state that can occur during CPU onlining */
-        return ZX_ERR_UNAVAILABLE;
-    }
-
-    DEBUG_ASSERT(dst_apic_id < UINT8_MAX);
-    apic_send_ipi(0, (uint8_t)dst_apic_id, DELIVERY_MODE_INIT);
-    return ZX_OK;
-}
-
-zx_status_t arch_mp_cpu_hotplug(uint cpu_id) {
-    if (cpu_id >= x86_num_cpus) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    if (mp_is_cpu_online(cpu_id)) {
-        return ZX_ERR_BAD_STATE;
-    }
-    DEBUG_ASSERT(cpu_id != 0);
-    if (cpu_id == 0) {
-        /* We shouldn't be able to shutoff the bootstrap CPU, so
-         * no reason to be able to bring it back via this route. */
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    struct x86_percpu* percpu = &ap_percpus[cpu_id - 1];
-    DEBUG_ASSERT(percpu->apic_id != INVALID_APIC_ID);
-    return x86_bringup_aps(&percpu->apic_id, 1);
-}
-
-/* Used to suspend work on a CPU until it is further shutdown */
-void arch_flush_state_and_halt(event_t* flush_done) {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    __asm__ volatile("wbinvd"
-                     :
-                     :
-                     : "memory");
-
-    event_signal(flush_done, false);
-    while (1) {
-        __asm__ volatile("cli; hlt"
-                         :
-                         :
-                         : "memory");
-    }
-}
diff --git a/kernel/arch/x86/ops.S b/kernel/arch/x86/ops.S
deleted file mode 100644
index 89fff7d..0000000
--- a/kernel/arch/x86/ops.S
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/x86/mp.h>
-#include <err.h>
-
-.text
-
-/* This follows the x86-64 ABI, the parameters are stored in registers in the following order*/
-/*
-%rdi used to pass 1st argument
-%rsi used to pass 2nd argument
-%rdx used to pass 3rd argument and 2nd return register
-%rcx used to pass 4th argument
-%r8 used to pass 5th argument
-%r9 used to pass 6th argument
-%rax 1st return register
-*/
-
-/* void x86_idle(); */
-FUNCTION(x86_idle)
-    pushf
-    popq %rax
-    andq $0x200, %rax
-    test %rax, %rax
-    je 1f                   /* don't halt if local interrupts are disabled */
-    hlt
-1:
-    ret
-END_FUNCTION(x86_idle)
-
-
-/* zx_status_t read_msr_safe(uint32_t msr_id, uint64_t *val); */
-FUNCTION(read_msr_safe)
-    // Set up MSR index
-    mov %rdi, %rcx
-
-    // Disable interrupts before touching percpu state
-    pushfq
-    cli
-
-    // Set up the GPF handler, in case the MSR doesn't exist
-    leaq .Lgpf_handler(%rip), %rax
-    movq %rax, %gs:PERCPU_GPF_RETURN_OFFSET
-    rdmsr
-
-    // Cleanup the GPF handler
-    movq $0, %gs:PERCPU_GPF_RETURN_OFFSET
-    // Restore interrupts if they were on before
-    popfq
-
-    // rdmsr returns value via edx:eax
-    shl $32, %rdx
-    or %rax, %rdx
-    mov %rdx, (%rsi)
-
-    mov $ZX_OK, %rax
-    ret
-.Lgpf_handler:
-    // Cleanup GPF handler
-    movq $0, %gs:PERCPU_GPF_RETURN_OFFSET
-    // Restore interrupts if they were on before
-    popfq
-
-    mov $ZX_ERR_NOT_SUPPORTED, %rax
-    ret
-END_FUNCTION(read_msr_safe)
-
-/* void x86_mwait(); */
-FUNCTION(x86_mwait)
-    pushf
-    popq %rax
-    andq $0x200, %rax
-    test %rax, %rax
-    je 1f                   /* don't halt if local interrupts are disabled */
-    // Clear the mwait hints and extension registers
-    xor %eax, %eax
-    xor %ecx, %ecx
-    mwait
-1:
-    ret
-END_FUNCTION(x86_mwait)
-
-/* void x86_monitor(void* addr); */
-FUNCTION(x86_monitor)
-    // Set the address to monitor
-    movq %rdi, %rax
-    // Clear the monitor extension and hints registers
-    xor %ecx, %ecx
-    xor %edx, %edx
-    monitor
-    ret
-END_FUNCTION(x86_monitor)
diff --git a/kernel/arch/x86/page_tables/include/arch/x86/page_tables/constants.h b/kernel/arch/x86/page_tables/include/arch/x86/page_tables/constants.h
deleted file mode 100644
index df4baa2..0000000
--- a/kernel/arch/x86/page_tables/include/arch/x86/page_tables/constants.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2008 Travis Geiselbrecht
-// Copyright (c) 2015 Intel Corporation
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#define X86_MMU_PG_P            0x0001          /* P    Valid                   */
-#define X86_MMU_PG_RW           0x0002          /* R/W  Read/Write              */
-#define X86_MMU_PG_U            0x0004          /* U/S  User/Supervisor         */
-#define X86_MMU_PG_WT           0x0008          /* WT   Write-through           */
-#define X86_MMU_PG_CD           0x0010          /* CD   Cache disable           */
-#define X86_MMU_PG_A            0x0020          /* A    Accessed                */
-#define X86_MMU_PG_D            0x0040          /* D    Dirty                   */
-#define X86_MMU_PG_PS           0x0080          /* PS   Page size (0=4k,1=4M)   */
-#define X86_MMU_PG_PTE_PAT      0x0080          /* PAT  PAT index for 4k pages  */
-#define X86_MMU_PG_LARGE_PAT    0x1000          /* PAT  PAT index otherwise     */
-#define X86_MMU_PG_G            0x0100          /* G    Global                  */
-#define X86_DIRTY_ACCESS_MASK   0xf9f
-
-/* Macros for converting from PAT index to appropriate page table flags.  Note
- * that the smallest level has one of the flags at a different bit index, so we
- * need two versions of each macro. */
-#define _X86_PAT_COMMON_SELECTOR(x) ((((x) & 0x2) ? X86_MMU_PG_CD : 0) | \
-                                     (((x) & 0x1) ? X86_MMU_PG_WT : 0))
-#define X86_PAT_PTE_SELECTOR(x) ((((x) & 0x4) ? X86_MMU_PG_PTE_PAT : 0) | \
-                                 _X86_PAT_COMMON_SELECTOR(x))
-#define X86_PAT_LARGE_SELECTOR(x) ((((x) & 0x4) ? X86_MMU_PG_LARGE_PAT : 0) | \
-                                   _X86_PAT_COMMON_SELECTOR(x))
-
-#define X86_MMU_PTE_PAT_MASK X86_PAT_PTE_SELECTOR(0x7)
-#define X86_MMU_LARGE_PAT_MASK X86_PAT_LARGE_SELECTOR(0x7)
-
-/* on x86-64 physical memory is mapped at the base of the kernel address space */
-#define X86_PHYS_TO_VIRT(x)     ((uintptr_t)(x) + KERNEL_ASPACE_BASE)
-#define X86_VIRT_TO_PHYS(x)     ((uintptr_t)(x) - KERNEL_ASPACE_BASE)
-
-#define IS_PAGE_PRESENT(pte)    ((pte) & X86_MMU_PG_P)
-#define IS_LARGE_PAGE(pte)      ((pte) & X86_MMU_PG_PS)
-
-// NOTE(abdulla): We assume that PT and EPT paging levels match, specifically:
-// - PML4 entries refer to 512GB pages
-// - PDP entries refer to 1GB pages
-// - PD entries refer to 2MB pages
-// - PT entries refer to 4KB pages
-#define PML4_SHIFT              39
-#define PDP_SHIFT               30
-#define PD_SHIFT                21
-#define PT_SHIFT                12
-#define ADDR_OFFSET             9
-#define PDPT_ADDR_OFFSET        2
-#define NO_OF_PT_ENTRIES        512
-
-#define X86_FLAGS_MASK          (0x8000000000000ffful)
-#define X86_LARGE_FLAGS_MASK    (0x8000000000001ffful)
-#define X86_PDPT_ADDR_MASK      (0x00000000ffffffe0ul)
-#define X86_HUGE_PAGE_FRAME     (0x000fffffc0000000ul)
-#define X86_LARGE_PAGE_FRAME    (0x000fffffffe00000ul)
-#define X86_PG_FRAME            (0x000ffffffffff000ul)
-#define PAGE_OFFSET_MASK_4KB    ((1ul << PT_SHIFT) - 1)
-#define PAGE_OFFSET_MASK_LARGE  ((1ul << PD_SHIFT) - 1)
-#define PAGE_OFFSET_MASK_HUGE   ((1ul << PDP_SHIFT) - 1)
-
-#define VADDR_TO_PML4_INDEX(vaddr) ((vaddr) >> PML4_SHIFT) & ((1ul << ADDR_OFFSET) - 1)
-#define VADDR_TO_PDP_INDEX(vaddr)  ((vaddr) >> PDP_SHIFT) & ((1ul << ADDR_OFFSET) - 1)
-
-#define VADDR_TO_PD_INDEX(vaddr)  ((vaddr) >> PD_SHIFT) & ((1ul << ADDR_OFFSET) - 1)
-#define VADDR_TO_PT_INDEX(vaddr)  ((vaddr) >> PT_SHIFT) & ((1ul << ADDR_OFFSET) - 1)
diff --git a/kernel/arch/x86/page_tables/include/arch/x86/page_tables/page_tables.h b/kernel/arch/x86/page_tables/include/arch/x86/page_tables/page_tables.h
deleted file mode 100644
index 3c38ac9..0000000
--- a/kernel/arch/x86/page_tables/include/arch/x86/page_tables/page_tables.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <fbl/auto_lock.h>
-#include <fbl/canary.h>
-#include <fbl/mutex.h>
-#include <hwreg/bitfields.h>
-// Needed for ARCH_MMU_FLAG_*
-#include <vm/arch_vm_aspace.h>
-
-typedef uint64_t pt_entry_t;
-#define PRIxPTE PRIx64
-
-// Different page table levels in the page table mgmt hirerachy
-enum PageTableLevel {
-    PT_L,
-    PD_L,
-    PDP_L,
-    PML4_L,
-};
-
-// Structure for tracking an upcoming TLB invalidation
-struct PendingTlbInvalidation {
-    struct Item {
-        uint64_t raw;
-        DEF_SUBFIELD(raw, 2, 0, page_level);
-        DEF_SUBBIT(raw, 3, is_global);
-        DEF_SUBBIT(raw, 4, is_terminal);
-        DEF_SUBFIELD(raw, 63, 12, encoded_addr);
-
-        vaddr_t addr() const { return encoded_addr() << PAGE_SIZE_SHIFT; }
-    };
-    static_assert(sizeof(Item) == 8, "");
-
-    // If true, ignore |vaddr| and perform a full invalidation for this context.
-    bool full_shootdown = false;
-    // If true, at least one enqueued entry was for a global page.
-    bool contains_global = false;
-    // Number of valid elements in |item|
-    uint count = 0;
-    // List of addresses queued for invalidation
-    Item item[32];
-
-    // Add address |v|, translated at depth |level|, to the set of addresses to be invalidated.
-    // |is_terminal| should be true iff this invalidation is targeting the final step of the translation
-    // rather than a higher page table entry.
-    // |is_global_page| should be true iff this page was mapped with the global
-    // bit set.
-    void enqueue(vaddr_t v, PageTableLevel level, bool is_global_page, bool is_terminal);
-
-    // Clear the list of pending invalidations
-    void clear();
-
-    ~PendingTlbInvalidation();
-};
-
-class X86PageTableBase {
-public:
-    X86PageTableBase();
-    virtual ~X86PageTableBase();
-
-    // Type for flags used in the hardware page tables, for terminal entries.
-    // Note that some flags here may have meanings that depend on the level
-    // at which they occur (e.g. page size and PAT).
-    using PtFlags = uint64_t;
-
-    // Type for flags used in the hardware page tables, for non-terminal
-    // entries.
-    using IntermediatePtFlags = uint64_t;
-
-    paddr_t phys() const { return phys_; }
-    void* virt() const { return virt_; }
-
-    size_t pages() {
-        fbl::AutoLock al(&lock_);
-        return pages_;
-    }
-    void* ctx() const { return ctx_; }
-
-    zx_status_t MapPages(vaddr_t vaddr, paddr_t* phys, size_t count,
-                         uint flags, size_t* mapped);
-    zx_status_t MapPagesContiguous(vaddr_t vaddr, paddr_t paddr, const size_t count,
-                                   uint flags, size_t* mapped);
-    zx_status_t UnmapPages(vaddr_t vaddr, const size_t count, size_t* unmapped);
-    zx_status_t ProtectPages(vaddr_t vaddr, size_t count, uint flags);
-
-    zx_status_t QueryVaddr(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags);
-
-protected:
-    // Initialize an empty page table, assigning this given context to it.
-    zx_status_t Init(void* ctx);
-
-    // Release the resources associated with this page table.  |base| and |size|
-    // are only used for debug checks that the page tables have no more mappings.
-    void Destroy(vaddr_t base, size_t size);
-
-    // Returns the highest level of the page tables
-    virtual PageTableLevel top_level() = 0;
-    // Returns true if the given ARCH_MMU_FLAG_* flag combination is valid.
-    virtual bool allowed_flags(uint flags) = 0;
-    // Returns true if the given paddr is valid
-    virtual bool check_paddr(paddr_t paddr) = 0;
-    // Returns true if the given vaddr is valid
-    virtual bool check_vaddr(vaddr_t vaddr) = 0;
-    // Whether the processor supports the page size of this level
-    virtual bool supports_page_size(PageTableLevel level) = 0;
-    // Return the hardware flags to use on intermediate page tables entries
-    virtual IntermediatePtFlags intermediate_flags() = 0;
-    // Return the hardware flags to use on terminal page table entries
-    virtual PtFlags terminal_flags(PageTableLevel level, uint flags) = 0;
-    // Return the hardware flags to use on smaller pages after a splitting a
-    // large page with flags |flags|.
-    virtual PtFlags split_flags(PageTableLevel level, PtFlags flags) = 0;
-    // Execute the given pending invalidation
-    virtual void TlbInvalidate(PendingTlbInvalidation* pending) = 0;
-
-    // Convert PtFlags to ARCH_MMU_* flags.
-    virtual uint pt_flags_to_mmu_flags(PtFlags flags, PageTableLevel level) = 0;
-    // Returns true if a cache flush is necessary for pagetable changes to be
-    // visible.
-    virtual bool needs_cache_flushes() = 0;
-
-    // Pointer to the translation table.
-    paddr_t phys_ = 0;
-    pt_entry_t* virt_ = nullptr;
-
-    // Counter of pages allocated to back the translation table.
-    size_t pages_ TA_GUARDED(lock_) = 0;
-
-    // A context structure that may used by a PageTable type above as part of
-    // invalidation.
-    void* ctx_ = nullptr;
-
-private:
-    DISALLOW_COPY_ASSIGN_AND_MOVE(X86PageTableBase);
-
-    class CacheLineFlusher;
-    class ConsistencyManager;
-    struct MappingCursor;
-
-    zx_status_t AddMapping(volatile pt_entry_t* table, uint mmu_flags,
-                           PageTableLevel level, const MappingCursor& start_cursor,
-                           MappingCursor* new_cursor, ConsistencyManager* cm) TA_REQ(lock_);
-    zx_status_t AddMappingL0(volatile pt_entry_t* table, uint mmu_flags,
-                             const MappingCursor& start_cursor,
-                             MappingCursor* new_cursor, ConsistencyManager* cm) TA_REQ(lock_);
-
-    bool RemoveMapping(volatile pt_entry_t* table,
-                       PageTableLevel level, const MappingCursor& start_cursor,
-                       MappingCursor* new_cursor, ConsistencyManager* cm) TA_REQ(lock_);
-    bool RemoveMappingL0(volatile pt_entry_t* table,
-                         const MappingCursor& start_cursor,
-                         MappingCursor* new_cursor, ConsistencyManager* cm) TA_REQ(lock_);
-
-    zx_status_t UpdateMapping(volatile pt_entry_t* table, uint mmu_flags,
-                              PageTableLevel level, const MappingCursor& start_cursor,
-                              MappingCursor* new_cursor, ConsistencyManager* cm) TA_REQ(lock_);
-    zx_status_t UpdateMappingL0(volatile pt_entry_t* table, uint mmu_flags,
-                                const MappingCursor& start_cursor, MappingCursor* new_cursor,
-                                ConsistencyManager* cm) TA_REQ(lock_);
-
-    zx_status_t GetMapping(volatile pt_entry_t* table, vaddr_t vaddr,
-                           PageTableLevel level,
-                           PageTableLevel* ret_level,
-                           volatile pt_entry_t** mapping) TA_REQ(lock_);
-    zx_status_t GetMappingL0(volatile pt_entry_t* table, vaddr_t vaddr,
-                             enum PageTableLevel* ret_level,
-                             volatile pt_entry_t** mapping) TA_REQ(lock_);
-
-    zx_status_t SplitLargePage(PageTableLevel level, vaddr_t vaddr,
-                               volatile pt_entry_t* pte, ConsistencyManager* cm) TA_REQ(lock_);
-
-    void UpdateEntry(ConsistencyManager* cm, PageTableLevel level, vaddr_t vaddr,
-                     volatile pt_entry_t* pte, paddr_t paddr, PtFlags flags,
-                     bool was_terminal) TA_REQ(lock_);
-    void UnmapEntry(ConsistencyManager* cm, PageTableLevel level, vaddr_t vaddr,
-                    volatile pt_entry_t* pte, bool was_terminal) TA_REQ(lock_);
-
-    fbl::Canary<fbl::magic("X86P")> canary_;
-
-    // low lock to protect the mmu code
-    fbl::Mutex lock_;
-};
diff --git a/kernel/arch/x86/page_tables/page_tables.cpp b/kernel/arch/x86/page_tables/page_tables.cpp
deleted file mode 100644
index dc56228..0000000
--- a/kernel/arch/x86/page_tables/page_tables.cpp
+++ /dev/null
@@ -1,1053 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86/page_tables/page_tables.h>
-
-#include <arch/x86/feature.h>
-#include <arch/x86/page_tables/constants.h>
-#include <assert.h>
-#include <fbl/algorithm.h>
-#include <fbl/auto_call.h>
-#include <fbl/auto_lock.h>
-#include <trace.h>
-#include <vm/physmap.h>
-#include <vm/pmm.h>
-
-#define LOCAL_TRACE 0
-
-namespace {
-
-// Return the page size for this level
-size_t page_size(PageTableLevel level) {
-    switch (level) {
-        case PT_L:
-            return 1ULL << PT_SHIFT;
-        case PD_L:
-            return 1ULL << PD_SHIFT;
-        case PDP_L:
-            return 1ULL << PDP_SHIFT;
-        case PML4_L:
-            return 1ULL << PML4_SHIFT;
-        default:
-            panic("page_size: invalid level\n");
-    }
-}
-
-// Whether an address is aligned to the page size of this level
-bool page_aligned(PageTableLevel level, vaddr_t vaddr) {
-    return (vaddr & (page_size(level) - 1)) == 0;
-}
-
-// Extract the index needed for finding |vaddr| for the given level
-uint vaddr_to_index(PageTableLevel level, vaddr_t vaddr) {
-    switch (level) {
-    case PML4_L:
-        return VADDR_TO_PML4_INDEX(vaddr);
-    case PDP_L:
-        return VADDR_TO_PDP_INDEX(vaddr);
-    case PD_L:
-        return VADDR_TO_PD_INDEX(vaddr);
-    case PT_L:
-        return VADDR_TO_PT_INDEX(vaddr);
-    default:
-        panic("vaddr_to_index: invalid level\n");
-    }
-}
-
-// Convert a PTE to a physical address
-paddr_t paddr_from_pte(PageTableLevel level, pt_entry_t pte) {
-    DEBUG_ASSERT(IS_PAGE_PRESENT(pte));
-
-    paddr_t pa;
-    switch (level) {
-    case PDP_L:
-        pa = (pte & X86_HUGE_PAGE_FRAME);
-        break;
-    case PD_L:
-        pa = (pte & X86_LARGE_PAGE_FRAME);
-        break;
-    case PT_L:
-        pa = (pte & X86_PG_FRAME);
-        break;
-    default:
-        panic("paddr_from_pte at unhandled level %d\n", level);
-    }
-
-    return pa;
-}
-
-PageTableLevel lower_level(PageTableLevel level) {
-    DEBUG_ASSERT(level != 0);
-    return (PageTableLevel)(level - 1);
-}
-
-} // namespace
-
-void PendingTlbInvalidation::enqueue(vaddr_t v, PageTableLevel level, bool is_global_page,
-                                     bool is_terminal) {
-    if (is_global_page) {
-        contains_global = true;
-    }
-
-    // We mark PML4_L entries as full shootdowns, since it's going to be
-    // expensive one way or another.
-    if (count >= fbl::count_of(item) || level == PML4_L) {
-        full_shootdown = true;
-        return;
-    }
-    item[count].set_page_level(static_cast<uint64_t>(level));
-    item[count].set_is_global(is_global_page);
-    item[count].set_is_terminal(is_terminal);
-    item[count].set_encoded_addr(v >> PAGE_SIZE_SHIFT);
-    count++;
-}
-
-void PendingTlbInvalidation::clear() {
-    count = 0;
-    full_shootdown = false;
-    contains_global = false;
-}
-
-PendingTlbInvalidation::~PendingTlbInvalidation() {
-    DEBUG_ASSERT(count == 0);
-}
-
-// Utility for coalescing cache line flushes when modifying page tables.  This
-// allows us to mutate adjacent page table entries without having to flush for
-// each cache line multiple times.
-class X86PageTableBase::CacheLineFlusher {
-public:
-    // If |perform_invalidations| is false, this class acts as a no-op.
-    explicit CacheLineFlusher(bool perform_invalidations);
-    ~CacheLineFlusher();
-    void FlushPtEntry(const volatile pt_entry_t* entry);
-
-    void ForceFlush();
-private:
-    DISALLOW_COPY_ASSIGN_AND_MOVE(CacheLineFlusher);
-
-    // The cache-aligned address that currently dirty.  If 0, no dirty line.
-    uintptr_t dirty_line_;
-
-    const uintptr_t cl_mask_;
-    const bool perform_invalidations_;
-};
-
-X86PageTableBase::CacheLineFlusher::CacheLineFlusher(bool perform_invalidations)
-    : dirty_line_(0), cl_mask_(~(x86_get_clflush_line_size() - 1ull)),
-      perform_invalidations_(perform_invalidations) {
-}
-
-X86PageTableBase::CacheLineFlusher::~CacheLineFlusher() {
-    ForceFlush();
-}
-
-void X86PageTableBase::CacheLineFlusher::ForceFlush() {
-    if (dirty_line_ && perform_invalidations_) {
-        __asm__ volatile("clflush %0\n"
-                         :
-                         : "m"(*reinterpret_cast<char*>(dirty_line_))
-                         : "memory");
-        dirty_line_ = 0;
-    }
-}
-
-void X86PageTableBase::CacheLineFlusher::FlushPtEntry(const volatile pt_entry_t* entry) {
-    uintptr_t entry_line = reinterpret_cast<uintptr_t>(entry) & cl_mask_;
-    if (entry_line != dirty_line_) {
-        ForceFlush();
-        dirty_line_ = entry_line;
-    }
-}
-
-// Utility for managing consistency of the page tables from a cache and TLB
-// point-of-view.  It ensures that memory is not freed while a TLB entry may
-// refer to it, and that changes to the page tables have appropriate visiblity
-// to the hardware interpreting them.  Finish MUST be called on this
-// class, even if the page table change failed.
-class X86PageTableBase::ConsistencyManager {
-public:
-    explicit ConsistencyManager(X86PageTableBase* pt);
-    ~ConsistencyManager();
-
-    // Disable thread safety analysis here because it has trouble identifying
-    // that |pt_->lock_| is held here.
-    void queue_free(vm_page_t* page) TA_NO_THREAD_SAFETY_ANALYSIS {
-        DEBUG_ASSERT(pt_->lock_.IsHeld());
-
-        list_add_tail(&to_free_, &page->queue_node);
-        pt_->pages_--;
-    }
-
-    CacheLineFlusher* cache_line_flusher() { return &clf_; }
-    PendingTlbInvalidation* pending_tlb() { return &tlb_; }
-
-    // This function must be called while holding pt_->lock_.
-    void Finish();
-private:
-    X86PageTableBase* pt_;
-
-    // Cache line to flush prior to TLB invalidations
-    X86PageTableBase::CacheLineFlusher clf_;
-
-    // TLB invalidations that need to occur
-    PendingTlbInvalidation tlb_;
-
-    // vm_page_t's to relese to the PMM after the TLB invalidation occurs
-    list_node to_free_;
-};
-
-X86PageTableBase::ConsistencyManager::ConsistencyManager(X86PageTableBase* pt)
-    : pt_(pt), clf_(pt->needs_cache_flushes()) {
-
-    to_free_ = LIST_INITIAL_VALUE(to_free_);
-}
-
-X86PageTableBase::ConsistencyManager::~ConsistencyManager() {
-    DEBUG_ASSERT(pt_ == nullptr);
-
-    // We free the paging structures here rather than in Finish(), to allow
-    // support deferring invoking pmm_free() until after we've left the page
-    // table lock.
-    if (!list_is_empty(&to_free_)) {
-        pmm_free(&to_free_);
-    }
-}
-
-void X86PageTableBase::ConsistencyManager::Finish() {
-    DEBUG_ASSERT(pt_->lock_.IsHeld());
-
-    clf_.ForceFlush();
-    if (pt_->needs_cache_flushes()) {
-        // If the hardware needs cache flushes for the tables to be visible,
-        // make sure we serialize the flushes before issuing the TLB
-        // invalidations.
-        mb();
-    }
-    pt_->TlbInvalidate(&tlb_);
-    pt_ = nullptr;
-}
-
-struct X86PageTableBase::MappingCursor {
-public:
-    /**
-   * @brief Update the cursor to skip over a not-present page table entry.
-   */
-    void SkipEntry(PageTableLevel level) {
-        const size_t ps = page_size(level);
-        // Calculate the amount the cursor should skip to get to the next entry at
-        // this page table level.
-        const size_t skipped_size = ps - (vaddr & (ps - 1));
-        // If our endpoint was in the middle of this range, clamp the
-        // amount we remove from the cursor
-        const size_t _size = (size > skipped_size) ? skipped_size : size;
-
-        size -= _size;
-        vaddr += _size;
-    }
-
-    paddr_t paddr;
-    vaddr_t vaddr;
-    size_t size;
-};
-
-void X86PageTableBase::UpdateEntry(ConsistencyManager* cm, PageTableLevel level, vaddr_t vaddr,
-                                   volatile pt_entry_t* pte, paddr_t paddr, PtFlags flags,
-                                   bool was_terminal) {
-    DEBUG_ASSERT(pte);
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(paddr));
-
-    pt_entry_t olde = *pte;
-
-    /* set the new entry */
-    *pte = paddr | flags | X86_MMU_PG_P;
-    cm->cache_line_flusher()->FlushPtEntry(pte);
-
-    /* attempt to invalidate the page */
-    if (IS_PAGE_PRESENT(olde)) {
-        // TODO(teisenbe): the is_kernel_address should be a check for the
-        // global bit
-        cm->pending_tlb()->enqueue(vaddr, level, is_kernel_address(vaddr), was_terminal);
-    }
-}
-
-void X86PageTableBase::UnmapEntry(ConsistencyManager* cm, PageTableLevel level, vaddr_t vaddr,
-                                  volatile pt_entry_t* pte, bool was_terminal) {
-    DEBUG_ASSERT(pte);
-
-    pt_entry_t olde = *pte;
-
-    *pte = 0;
-    cm->cache_line_flusher()->FlushPtEntry(pte);
-
-    /* attempt to invalidate the page */
-    if (IS_PAGE_PRESENT(olde)) {
-        // TODO(teisenbe): the is_kernel_address should be a check for the
-        // global bit
-        cm->pending_tlb()->enqueue(vaddr, level, is_kernel_address(vaddr), was_terminal);
-    }
-}
-
-/**
- * @brief Allocating a new page table
- */
-static volatile pt_entry_t* _map_alloc_page(void) {
-    paddr_t pa;
-    vm_page* p;
-    zx_status_t status = pmm_alloc_page(0, &p, &pa);
-    if (status != ZX_OK) {
-        return nullptr;
-    }
-    p->state = VM_PAGE_STATE_MMU;
-
-    pt_entry_t* page_ptr = static_cast<pt_entry_t*>(paddr_to_physmap(pa));
-    DEBUG_ASSERT(page_ptr);
-
-    arch_zero_page(page_ptr);
-
-    return page_ptr;
-}
-
-/*
- * @brief Split the given large page into smaller pages
- */
-zx_status_t X86PageTableBase::SplitLargePage(PageTableLevel level, vaddr_t vaddr,
-                                             volatile pt_entry_t* pte, ConsistencyManager* cm) {
-    DEBUG_ASSERT_MSG(level != PT_L, "tried splitting PT_L");
-    LTRACEF_LEVEL(2, "splitting table %p at level %d\n", pte, level);
-
-    DEBUG_ASSERT(IS_PAGE_PRESENT(*pte) && IS_LARGE_PAGE(*pte));
-    volatile pt_entry_t* m = _map_alloc_page();
-    if (m == nullptr) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    paddr_t paddr_base = paddr_from_pte(level, *pte);
-    PtFlags flags = split_flags(level, *pte & X86_LARGE_FLAGS_MASK);
-
-    DEBUG_ASSERT(page_aligned(level, vaddr));
-    vaddr_t new_vaddr = vaddr;
-    paddr_t new_paddr = paddr_base;
-    size_t ps = page_size(lower_level(level));
-    for (int i = 0; i < NO_OF_PT_ENTRIES; i++) {
-        volatile pt_entry_t* e = m + i;
-        // If this is a PDP_L (i.e. huge page), flags will include the
-        // PS bit still, so the new PD entries will be large pages.
-        UpdateEntry(cm, lower_level(level), new_vaddr, e, new_paddr, flags,
-                    false /* was_terminal */);
-        new_vaddr += ps;
-        new_paddr += ps;
-    }
-    DEBUG_ASSERT(new_vaddr == vaddr + page_size(level));
-
-    flags = intermediate_flags();
-    UpdateEntry(cm, level, vaddr, pte, X86_VIRT_TO_PHYS(m), flags, true /* was_terminal */);
-    pages_++;
-    return ZX_OK;
-}
-
-/*
- * @brief given a page table entry, return a pointer to the next page table one level down
- */
-static inline volatile pt_entry_t* get_next_table_from_entry(pt_entry_t entry) {
-    if (!IS_PAGE_PRESENT(entry) || IS_LARGE_PAGE(entry))
-        return nullptr;
-
-    return reinterpret_cast<volatile pt_entry_t*>(X86_PHYS_TO_VIRT(entry & X86_PG_FRAME));
-}
-
-/**
- * @brief  Walk the page table structures returning the entry and level that maps the address.
- *
- * @param table The top-level paging structure's virtual address
- * @param vaddr The virtual address to retrieve the mapping for
- * @param ret_level The level of the table that defines the found mapping
- * @param mapping The mapping that was found
- *
- * @return ZX_OK if mapping is found
- * @return ZX_ERR_NOT_FOUND if mapping is not found
- */
-zx_status_t X86PageTableBase::GetMapping(volatile pt_entry_t* table, vaddr_t vaddr,
-                                         PageTableLevel level,
-                                         PageTableLevel* ret_level,
-                                         volatile pt_entry_t** mapping) {
-    DEBUG_ASSERT(table);
-    DEBUG_ASSERT(ret_level);
-    DEBUG_ASSERT(mapping);
-
-    if (level == PT_L) {
-        return GetMappingL0(table, vaddr, ret_level, mapping);
-    }
-
-    LTRACEF_LEVEL(2, "table %p\n", table);
-
-    uint index = vaddr_to_index(level, vaddr);
-    volatile pt_entry_t* e = table + index;
-    pt_entry_t pt_val = *e;
-    if (!IS_PAGE_PRESENT(pt_val))
-        return ZX_ERR_NOT_FOUND;
-
-    /* if this is a large page, stop here */
-    if (IS_LARGE_PAGE(pt_val)) {
-        *mapping = e;
-        *ret_level = level;
-        return ZX_OK;
-    }
-
-    volatile pt_entry_t* next_table = get_next_table_from_entry(pt_val);
-    return GetMapping(next_table, vaddr, lower_level(level), ret_level, mapping);
-}
-
-zx_status_t X86PageTableBase::GetMappingL0(volatile pt_entry_t* table, vaddr_t vaddr,
-                                           PageTableLevel* ret_level,
-                                           volatile pt_entry_t** mapping) {
-    /* do the final page table lookup */
-    uint index = vaddr_to_index(PT_L, vaddr);
-    volatile pt_entry_t* e = table + index;
-    if (!IS_PAGE_PRESENT(*e))
-        return ZX_ERR_NOT_FOUND;
-
-    *mapping = e;
-    *ret_level = PT_L;
-    return ZX_OK;
-}
-
-/**
- * @brief Unmaps the range specified by start_cursor.
- *
- * Level must be top_level() when invoked.  The caller must, even on failure,
- * free all pages in the |to_free| list and adjust the |pages_| count.
- *
- * @param table The top-level paging structure's virtual address.
- * @param start_cursor A cursor describing the range of address space to
- * unmap within table
- * @param new_cursor A returned cursor describing how much work was not
- * completed.  Must be non-null.
- *
- * @return true if at least one page was unmapped at this level
- */
-bool X86PageTableBase::RemoveMapping(volatile pt_entry_t* table, PageTableLevel level,
-                                     const MappingCursor& start_cursor, MappingCursor* new_cursor,
-                                     ConsistencyManager* cm) {
-    DEBUG_ASSERT(table);
-    LTRACEF("L: %d, %016" PRIxPTR " %016zx\n", level, start_cursor.vaddr,
-            start_cursor.size);
-    DEBUG_ASSERT(check_vaddr(start_cursor.vaddr));
-
-    if (level == PT_L) {
-        return RemoveMappingL0(table, start_cursor, new_cursor, cm);
-    }
-
-    *new_cursor = start_cursor;
-
-    bool unmapped = false;
-    size_t ps = page_size(level);
-    uint index = vaddr_to_index(level, new_cursor->vaddr);
-    for (; index != NO_OF_PT_ENTRIES && new_cursor->size != 0; ++index) {
-        volatile pt_entry_t* e = table + index;
-        pt_entry_t pt_val = *e;
-        // If the page isn't even mapped, just skip it
-        if (!IS_PAGE_PRESENT(pt_val)) {
-            new_cursor->SkipEntry(level);
-            DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-            continue;
-        }
-
-        if (IS_LARGE_PAGE(pt_val)) {
-            bool vaddr_level_aligned = page_aligned(level, new_cursor->vaddr);
-            // If the request covers the entire large page, just unmap it
-            if (vaddr_level_aligned && new_cursor->size >= ps) {
-                UnmapEntry(cm, level, new_cursor->vaddr, e, true /* was_terminal */);
-                unmapped = true;
-
-                new_cursor->vaddr += ps;
-                new_cursor->size -= ps;
-                DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-                continue;
-            }
-            // Otherwise, we need to split it
-            vaddr_t page_vaddr = new_cursor->vaddr & ~(ps - 1);
-            zx_status_t status = SplitLargePage(level, page_vaddr, e, cm);
-            if (status != ZX_OK) {
-                // If split fails, just unmap the whole thing, and let a
-                // subsequent page fault clean it up.
-                UnmapEntry(cm, level, new_cursor->vaddr, e, true /* was_terminal */);
-                unmapped = true;
-
-                new_cursor->SkipEntry(level);
-                DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-            }
-            pt_val = *e;
-        }
-
-        MappingCursor cursor;
-        volatile pt_entry_t* next_table = get_next_table_from_entry(pt_val);
-        bool lower_unmapped = RemoveMapping(next_table, lower_level(level),
-                                            *new_cursor, &cursor, cm);
-
-        // If we were requesting to unmap everything in the lower page table,
-        // we know we can unmap the lower level page table.  Otherwise, if
-        // we unmapped anything in the lower level, check to see if that
-        // level is now empty.
-        bool unmap_page_table =
-            page_aligned(level, new_cursor->vaddr) && new_cursor->size >= ps;
-        if (!unmap_page_table && lower_unmapped) {
-            uint lower_idx;
-            for (lower_idx = 0; lower_idx < NO_OF_PT_ENTRIES; ++lower_idx) {
-                if (IS_PAGE_PRESENT(next_table[lower_idx])) {
-                    break;
-                }
-            }
-            if (lower_idx == NO_OF_PT_ENTRIES) {
-                unmap_page_table = true;
-            }
-        }
-        if (unmap_page_table) {
-            paddr_t ptable_phys = X86_VIRT_TO_PHYS(next_table);
-            LTRACEF("L: %d free pt v %#" PRIxPTR " phys %#" PRIxPTR "\n",
-                    level, (uintptr_t)next_table, ptable_phys);
-
-            UnmapEntry(cm, level, new_cursor->vaddr, e, false /* was_terminal */);
-            vm_page_t* page = paddr_to_vm_page(ptable_phys);
-
-            DEBUG_ASSERT(page);
-            DEBUG_ASSERT_MSG(page->state == VM_PAGE_STATE_MMU,
-                             "page %p state %u, paddr %#" PRIxPTR "\n", page, page->state,
-                             X86_VIRT_TO_PHYS(next_table));
-            DEBUG_ASSERT(!list_in_list(&page->queue_node));
-
-            cm->queue_free(page);
-            unmapped = true;
-        }
-        *new_cursor = cursor;
-        DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-
-        DEBUG_ASSERT(new_cursor->size == 0 || page_aligned(level, new_cursor->vaddr));
-    }
-
-    return unmapped;
-}
-
-// Base case of RemoveMapping for smallest page size.
-bool X86PageTableBase::RemoveMappingL0(volatile pt_entry_t* table,
-                                       const MappingCursor& start_cursor, MappingCursor* new_cursor,
-                                       ConsistencyManager* cm) {
-    LTRACEF("%016" PRIxPTR " %016zx\n", start_cursor.vaddr, start_cursor.size);
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(start_cursor.size));
-
-    *new_cursor = start_cursor;
-
-    bool unmapped = false;
-    uint index = vaddr_to_index(PT_L, new_cursor->vaddr);
-    for (; index != NO_OF_PT_ENTRIES && new_cursor->size != 0; ++index) {
-        volatile pt_entry_t* e = table + index;
-        if (IS_PAGE_PRESENT(*e)) {
-            UnmapEntry(cm, PT_L, new_cursor->vaddr, e, true /* was_terminal */);
-            unmapped = true;
-        }
-
-        new_cursor->vaddr += PAGE_SIZE;
-        new_cursor->size -= PAGE_SIZE;
-        DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-    }
-    return unmapped;
-}
-
-/**
- * @brief Creates mappings for the range specified by start_cursor
- *
- * Level must be top_level() when invoked.
- *
- * @param table The top-level paging structure's virtual address.
- * @param start_cursor A cursor describing the range of address space to
- * act on within table
- * @param new_cursor A returned cursor describing how much work was not
- * completed.  Must be non-null.
- *
- * @return ZX_OK if successful
- * @return ZX_ERR_ALREADY_EXISTS if the range overlaps an existing mapping
- * @return ZX_ERR_NO_MEMORY if intermediate page tables could not be allocated
- */
-zx_status_t X86PageTableBase::AddMapping(volatile pt_entry_t* table, uint mmu_flags,
-                                         PageTableLevel level, const MappingCursor& start_cursor,
-                                         MappingCursor* new_cursor,
-                                         ConsistencyManager* cm) {
-    DEBUG_ASSERT(table);
-    DEBUG_ASSERT(check_vaddr(start_cursor.vaddr));
-    DEBUG_ASSERT(check_paddr(start_cursor.paddr));
-
-    zx_status_t ret = ZX_OK;
-    *new_cursor = start_cursor;
-
-    if (level == PT_L) {
-        return AddMappingL0(table, mmu_flags, start_cursor, new_cursor, cm);
-    }
-
-    // Disable thread safety analysis, since Clang has trouble noticing that
-    // lock_ is held when RemoveMapping is called.
-    auto abort = fbl::MakeAutoCall([&]() TA_NO_THREAD_SAFETY_ANALYSIS {
-        if (level == top_level()) {
-            MappingCursor cursor = start_cursor;
-            MappingCursor result;
-            // new_cursor->size should be how much is left to be mapped still
-            cursor.size -= new_cursor->size;
-            if (cursor.size > 0) {
-                RemoveMapping(table, level, cursor, &result, cm);
-                DEBUG_ASSERT(result.size == 0);
-            }
-        }
-    });
-
-    X86PageTableBase::IntermediatePtFlags interm_flags = intermediate_flags();
-    X86PageTableBase::PtFlags term_flags = terminal_flags(level, mmu_flags);
-
-    size_t ps = page_size(level);
-    bool level_supports_large_pages = supports_page_size(level);
-    uint index = vaddr_to_index(level, new_cursor->vaddr);
-    for (; index != NO_OF_PT_ENTRIES && new_cursor->size != 0; ++index) {
-        volatile pt_entry_t* e = table + index;
-        pt_entry_t pt_val = *e;
-        // See if there's a large page in our way
-        if (IS_PAGE_PRESENT(pt_val) && IS_LARGE_PAGE(pt_val)) {
-            return ZX_ERR_ALREADY_EXISTS;
-        }
-
-        // Check if this is a candidate for a new large page
-        bool level_valigned = page_aligned(level, new_cursor->vaddr);
-        bool level_paligned = page_aligned(level, new_cursor->paddr);
-        if (level_supports_large_pages && !IS_PAGE_PRESENT(pt_val) && level_valigned &&
-            level_paligned && new_cursor->size >= ps) {
-
-            UpdateEntry(cm, level, new_cursor->vaddr, table + index,
-                        new_cursor->paddr, term_flags | X86_MMU_PG_PS, false /* was_terminal */);
-            new_cursor->paddr += ps;
-            new_cursor->vaddr += ps;
-            new_cursor->size -= ps;
-            DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-        } else {
-            // See if we need to create a new table
-            if (!IS_PAGE_PRESENT(pt_val)) {
-                volatile pt_entry_t* m = _map_alloc_page();
-                if (m == nullptr) {
-                    return ZX_ERR_NO_MEMORY;
-                }
-
-                LTRACEF_LEVEL(2, "new table %p at level %d\n", m, level);
-
-                UpdateEntry(cm, level, new_cursor->vaddr, e,
-                            X86_VIRT_TO_PHYS(m), interm_flags, false /* was_terminal */);
-                pt_val = *e;
-                pages_++;
-            }
-
-            MappingCursor cursor;
-            ret = AddMapping(get_next_table_from_entry(pt_val), mmu_flags,
-                             lower_level(level), *new_cursor, &cursor, cm);
-            *new_cursor = cursor;
-            DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-            if (ret != ZX_OK) {
-                return ret;
-            }
-        }
-    }
-    abort.cancel();
-    return ZX_OK;
-}
-
-// Base case of AddMapping for smallest page size.
-zx_status_t X86PageTableBase::AddMappingL0(volatile pt_entry_t* table, uint mmu_flags,
-                                           const MappingCursor& start_cursor,
-                                           MappingCursor* new_cursor, ConsistencyManager* cm) {
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(start_cursor.size));
-
-    *new_cursor = start_cursor;
-
-    X86PageTableBase::PtFlags term_flags = terminal_flags(PT_L, mmu_flags);
-
-    uint index = vaddr_to_index(PT_L, new_cursor->vaddr);
-    for (; index != NO_OF_PT_ENTRIES && new_cursor->size != 0; ++index) {
-        volatile pt_entry_t* e = table + index;
-        if (IS_PAGE_PRESENT(*e)) {
-            return ZX_ERR_ALREADY_EXISTS;
-        }
-
-        UpdateEntry(cm, PT_L, new_cursor->vaddr, e, new_cursor->paddr, term_flags,
-                    false /* was_terminal */);
-
-        new_cursor->paddr += PAGE_SIZE;
-        new_cursor->vaddr += PAGE_SIZE;
-        new_cursor->size -= PAGE_SIZE;
-        DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-    }
-
-    return ZX_OK;
-}
-
-/**
- * @brief Changes the permissions/caching of the range specified by start_cursor
- *
- * Level must be top_level() when invoked.  The caller must, even on failure,
- * free all pages in the |to_free| list and adjust the |pages_| count.
- *
- * @param table The top-level paging structure's virtual address.
- * @param start_cursor A cursor describing the range of address space to
- * act on within table
- * @param new_cursor A returned cursor describing how much work was not
- * completed.  Must be non-null.
- */
-zx_status_t X86PageTableBase::UpdateMapping(volatile pt_entry_t* table, uint mmu_flags,
-                                            PageTableLevel level, const MappingCursor& start_cursor,
-                                            MappingCursor* new_cursor, ConsistencyManager* cm) {
-    DEBUG_ASSERT(table);
-    LTRACEF("L: %d, %016" PRIxPTR " %016zx\n", level, start_cursor.vaddr,
-            start_cursor.size);
-    DEBUG_ASSERT(check_vaddr(start_cursor.vaddr));
-
-    if (level == PT_L) {
-        return UpdateMappingL0(table, mmu_flags, start_cursor, new_cursor, cm);
-    }
-
-    zx_status_t ret = ZX_OK;
-    *new_cursor = start_cursor;
-
-    X86PageTableBase::PtFlags term_flags = terminal_flags(level, mmu_flags);
-
-    size_t ps = page_size(level);
-    uint index = vaddr_to_index(level, new_cursor->vaddr);
-    for (; index != NO_OF_PT_ENTRIES && new_cursor->size != 0; ++index) {
-        volatile pt_entry_t* e = table + index;
-        pt_entry_t pt_val = *e;
-        // Skip unmapped pages (we may encounter these due to demand paging)
-        if (!IS_PAGE_PRESENT(pt_val)) {
-            new_cursor->SkipEntry(level);
-            continue;
-        }
-
-        if (IS_LARGE_PAGE(pt_val)) {
-            bool vaddr_level_aligned = page_aligned(level, new_cursor->vaddr);
-            // If the request covers the entire large page, just change the
-            // permissions
-            if (vaddr_level_aligned && new_cursor->size >= ps) {
-                UpdateEntry(cm, level, new_cursor->vaddr, e,
-                            paddr_from_pte(level, pt_val),
-                            term_flags | X86_MMU_PG_PS, true /* was_terminal */);
-                new_cursor->vaddr += ps;
-                new_cursor->size -= ps;
-                DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-                continue;
-            }
-            // Otherwise, we need to split it
-            vaddr_t page_vaddr = new_cursor->vaddr & ~(ps - 1);
-            ret = SplitLargePage(level, page_vaddr, e, cm);
-            if (ret != ZX_OK) {
-                // If we failed to split the table, just unmap it.  Subsequent
-                // page faults will bring it back in.
-                MappingCursor cursor;
-                cursor.vaddr = new_cursor->vaddr;
-                cursor.size = ps;
-
-                MappingCursor tmp_cursor;
-                RemoveMapping(table, level, cursor, &tmp_cursor, cm);
-
-                new_cursor->SkipEntry(level);
-            }
-            pt_val = *e;
-        }
-
-        MappingCursor cursor;
-        volatile pt_entry_t* next_table = get_next_table_from_entry(pt_val);
-        ret = UpdateMapping(next_table, mmu_flags, lower_level(level),
-                            *new_cursor, &cursor, cm);
-        *new_cursor = cursor;
-        if (ret != ZX_OK) {
-            // Currently this can't happen
-            ASSERT(false);
-        }
-        DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-        DEBUG_ASSERT(new_cursor->size == 0 || page_aligned(level, new_cursor->vaddr));
-    }
-    return ZX_OK;
-}
-
-// Base case of UpdateMapping for smallest page size.
-zx_status_t X86PageTableBase::UpdateMappingL0(volatile pt_entry_t* table, uint mmu_flags,
-                                              const MappingCursor& start_cursor,
-                                              MappingCursor* new_cursor,
-                                              ConsistencyManager* cm) {
-    LTRACEF("%016" PRIxPTR " %016zx\n", start_cursor.vaddr, start_cursor.size);
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(start_cursor.size));
-
-    *new_cursor = start_cursor;
-
-    X86PageTableBase::PtFlags term_flags = terminal_flags(PT_L, mmu_flags);
-
-    uint index = vaddr_to_index(PT_L, new_cursor->vaddr);
-    for (; index != NO_OF_PT_ENTRIES && new_cursor->size != 0; ++index) {
-        volatile pt_entry_t* e = table + index;
-        pt_entry_t pt_val = *e;
-        // Skip unmapped pages (we may encounter these due to demand paging)
-        if (IS_PAGE_PRESENT(pt_val)) {
-            UpdateEntry(cm, PT_L, new_cursor->vaddr, e, paddr_from_pte(PT_L, pt_val),
-                        term_flags, true /* was_terminal */);
-        }
-
-        new_cursor->vaddr += PAGE_SIZE;
-        new_cursor->size -= PAGE_SIZE;
-        DEBUG_ASSERT(new_cursor->size <= start_cursor.size);
-    }
-    DEBUG_ASSERT(new_cursor->size == 0 || page_aligned(PT_L, new_cursor->vaddr));
-    return ZX_OK;
-}
-
-zx_status_t X86PageTableBase::UnmapPages(vaddr_t vaddr, const size_t count,
-                                         size_t* unmapped) {
-    LTRACEF("aspace %p, vaddr %#" PRIxPTR ", count %#zx\n", this, vaddr, count);
-
-    canary_.Assert();
-
-    if (!check_vaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-    if (count == 0)
-        return ZX_OK;
-
-    MappingCursor start = {
-        .paddr = 0, .vaddr = vaddr, .size = count * PAGE_SIZE,
-    };
-    MappingCursor result;
-
-    ConsistencyManager cm(this);
-    {
-        fbl::AutoLock a(&lock_);
-        DEBUG_ASSERT(virt_);
-        RemoveMapping(virt_, top_level(), start, &result, &cm);
-        cm.Finish();
-    }
-    DEBUG_ASSERT(result.size == 0);
-
-    if (unmapped)
-        *unmapped = count;
-
-    return ZX_OK;
-}
-
-zx_status_t X86PageTableBase::MapPages(vaddr_t vaddr, paddr_t* phys, size_t count,
-                                       uint mmu_flags, size_t* mapped) {
-    canary_.Assert();
-
-    LTRACEF("aspace %p, vaddr %#" PRIxPTR " count %#zx mmu_flags 0x%x\n",
-            this, vaddr, count, mmu_flags);
-
-    if (!check_vaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-    for (size_t i = 0; i < count; ++i) {
-        if (!check_paddr(phys[i]))
-            return ZX_ERR_INVALID_ARGS;
-    }
-    if (count == 0)
-        return ZX_OK;
-
-    if (!allowed_flags(mmu_flags))
-        return ZX_ERR_INVALID_ARGS;
-
-    PageTableLevel top = top_level();
-    ConsistencyManager cm(this);
-    {
-        fbl::AutoLock a(&lock_);
-        DEBUG_ASSERT(virt_);
-
-        // TODO(teisenbe): Improve performance of this function by integrating deeper into
-        // the algorithm (e.g. make the cursors aware of the page array).
-        size_t idx = 0;
-        auto undo = fbl::MakeAutoCall([&]() TA_NO_THREAD_SAFETY_ANALYSIS {
-            if (idx > 0) {
-                MappingCursor start = {
-                    .paddr = 0, .vaddr = vaddr, .size = idx * PAGE_SIZE,
-                };
-
-                MappingCursor result;
-                RemoveMapping(virt_, top, start, &result, &cm);
-                DEBUG_ASSERT(result.size == 0);
-            }
-            cm.Finish();
-        });
-
-        vaddr_t v = vaddr;
-        for (; idx < count; ++idx) {
-            MappingCursor start = {
-                .paddr = phys[idx], .vaddr = v, .size = PAGE_SIZE,
-            };
-            MappingCursor result;
-            zx_status_t status = AddMapping(virt_, mmu_flags, top, start, &result, &cm);
-            if (status != ZX_OK) {
-                dprintf(SPEW, "Add mapping failed with err=%d\n", status);
-                return status;
-            }
-            DEBUG_ASSERT(result.size == 0);
-
-            v += PAGE_SIZE;
-        }
-
-        undo.cancel();
-        cm.Finish();
-    }
-
-    if (mapped) {
-        *mapped = count;
-    }
-    return ZX_OK;
-}
-
-zx_status_t X86PageTableBase::MapPagesContiguous(vaddr_t vaddr, paddr_t paddr,
-                                                 const size_t count, uint mmu_flags,
-                                                 size_t* mapped) {
-    canary_.Assert();
-
-    LTRACEF("aspace %p, vaddr %#" PRIxPTR " paddr %#" PRIxPTR " count %#zx mmu_flags 0x%x\n",
-            this, vaddr, paddr, count, mmu_flags);
-
-    if (!check_paddr(paddr))
-        return ZX_ERR_INVALID_ARGS;
-    if (!check_vaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-    if (count == 0)
-        return ZX_OK;
-
-    if (!allowed_flags(mmu_flags))
-        return ZX_ERR_INVALID_ARGS;
-
-    MappingCursor start = {
-        .paddr = paddr, .vaddr = vaddr, .size = count * PAGE_SIZE,
-    };
-    MappingCursor result;
-    ConsistencyManager cm(this);
-    {
-        fbl::AutoLock a(&lock_);
-        DEBUG_ASSERT(virt_);
-        zx_status_t status = AddMapping(virt_, mmu_flags, top_level(), start, &result, &cm);
-        cm.Finish();
-        if (status != ZX_OK) {
-            dprintf(SPEW, "Add mapping failed with err=%d\n", status);
-            return status;
-        }
-    }
-    DEBUG_ASSERT(result.size == 0);
-
-    if (mapped)
-        *mapped = count;
-
-    return ZX_OK;
-}
-
-zx_status_t X86PageTableBase::ProtectPages(vaddr_t vaddr, size_t count, uint mmu_flags) {
-    canary_.Assert();
-
-    LTRACEF("aspace %p, vaddr %#" PRIxPTR " count %#zx mmu_flags 0x%x\n",
-            this, vaddr, count, mmu_flags);
-
-    if (!check_vaddr(vaddr))
-        return ZX_ERR_INVALID_ARGS;
-    if (count == 0)
-        return ZX_OK;
-
-    if (!allowed_flags(mmu_flags))
-        return ZX_ERR_INVALID_ARGS;
-
-    MappingCursor start = {
-        .paddr = 0, .vaddr = vaddr, .size = count * PAGE_SIZE,
-    };
-    MappingCursor result;
-    ConsistencyManager cm(this);
-    {
-        fbl::AutoLock a(&lock_);
-        zx_status_t status = UpdateMapping(virt_, mmu_flags, top_level(), start, &result, &cm);
-        cm.Finish();
-        if (status != ZX_OK) {
-            return status;
-        }
-    }
-    DEBUG_ASSERT(result.size == 0);
-    return ZX_OK;
-}
-
-zx_status_t X86PageTableBase::QueryVaddr(vaddr_t vaddr, paddr_t* paddr, uint* mmu_flags) {
-    canary_.Assert();
-
-    PageTableLevel ret_level;
-
-    LTRACEF("aspace %p, vaddr %#" PRIxPTR ", paddr %p, mmu_flags %p\n", this, vaddr, paddr,
-            mmu_flags);
-
-    fbl::AutoLock a(&lock_);
-
-    volatile pt_entry_t* last_valid_entry;
-    zx_status_t status = GetMapping(virt_, vaddr, top_level(), &ret_level, &last_valid_entry);
-    if (status != ZX_OK)
-        return status;
-
-    DEBUG_ASSERT(last_valid_entry);
-    LTRACEF("last_valid_entry (%p) 0x%" PRIxPTE ", level %d\n", last_valid_entry, *last_valid_entry,
-            ret_level);
-
-    /* based on the return level, parse the page table entry */
-    if (paddr) {
-        switch (ret_level) {
-        case PDP_L: /* 1GB page */
-            *paddr = paddr_from_pte(PDP_L, *last_valid_entry);
-            *paddr |= vaddr & PAGE_OFFSET_MASK_HUGE;
-            break;
-        case PD_L: /* 2MB page */
-            *paddr = paddr_from_pte(PD_L, *last_valid_entry);
-            *paddr |= vaddr & PAGE_OFFSET_MASK_LARGE;
-            break;
-        case PT_L: /* 4K page */
-            *paddr = paddr_from_pte(PT_L, *last_valid_entry);
-            *paddr |= vaddr & PAGE_OFFSET_MASK_4KB;
-            break;
-        default:
-            panic("arch_mmu_query: unhandled frame level\n");
-        }
-
-        LTRACEF("paddr %#" PRIxPTR "\n", *paddr);
-    }
-
-    /* converting arch-specific flags to mmu flags */
-    if (mmu_flags) {
-        *mmu_flags = pt_flags_to_mmu_flags(*last_valid_entry, ret_level);
-    }
-
-    return ZX_OK;
-}
-
-void X86PageTableBase::Destroy(vaddr_t base, size_t size) {
-    canary_.Assert();
-
-#if LK_DEBUGLEVEL > 1
-    PageTableLevel top = top_level();
-    if (virt_) {
-        pt_entry_t* table = static_cast<pt_entry_t*>(virt_);
-        uint start = vaddr_to_index(top, base);
-        uint end = vaddr_to_index(top, base + size - 1);
-
-        // Don't check start if that table is shared with another aspace.
-        if (!page_aligned(top, base)) {
-            start += 1;
-        }
-        // Do check the end if it fills out the table entry.
-        if (page_aligned(top, base + size)) {
-            end += 1;
-        }
-
-        for (uint i = start; i < end; ++i) {
-            DEBUG_ASSERT(!IS_PAGE_PRESENT(table[i]));
-        }
-    }
-#endif
-
-    if (phys_) {
-        pmm_free_page(paddr_to_vm_page(phys_));
-        phys_ = 0;
-    }
-}
diff --git a/kernel/arch/x86/page_tables/rules.mk b/kernel/arch/x86/page_tables/rules.mk
deleted file mode 100644
index eb6232a..0000000
--- a/kernel/arch/x86/page_tables/rules.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2017 The Fuchsia Authors
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-KERNEL_INCLUDES += $(LOCAL_DIR)/include
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/page_tables.cpp
-
-MODULE_DEPS += \
-	kernel/lib/fbl \
-	kernel/lib/hwreg \
-
-include make/module.mk
diff --git a/kernel/arch/x86/perf_mon.cpp b/kernel/arch/x86/perf_mon.cpp
deleted file mode 100644
index abd239a..0000000
--- a/kernel/arch/x86/perf_mon.cpp
+++ /dev/null
@@ -1,2145 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-// A note on the distribution of code between us and the userspace driver:
-// The default location for code is the userspace driver. Reasons for
-// putting code here are: implementation requirement (need ring zero to write
-// MSRs), stability, and performance. The device driver should do as much
-// error checking as possible before calling us.
-// Note that we do a lot of verification of the input configuration:
-// We don't want to be compromised if the userspace driver gets compromised.
-
-// A note on terminology: "events" vs "counters": A "counter" is an
-// "event", but some events are not counters. Internally, we use the
-// term "counter" when we know the event is a counter.
-
-// This file contains the lower part of Intel Performance Monitor support that
-// must be done in the kernel (so that we can read/write msrs).
-// The userspace driver is in system/dev/misc/cpu-trace/intel-pm.c.
-
-// TODO(dje): See Intel Vol 3 18.2.3.1 for hypervisor recommendations.
-// TODO(dje): LBR, BTS, et.al. See Intel Vol 3 Chapter 17.
-// TODO(dje): PMI mitigations
-// TODO(dje): Eventually may wish to virtualize some/all of the MSRs,
-//            some have multiple disparate uses.
-// TODO(dje): vmo management
-// TODO(dje): check hyperthread handling
-// TODO(dje): See about reducing two loops (programmable+fixed) into one.
-// TODO(dje): If we're using one counter as the trigger, we could skip
-// resetting the other counters and instead record the last value (so that we
-// can continue to emit the delta into the trace buffer) - assuming the write
-// to memory is faster than the wrmsr which is apparently true.
-// TODO(dje): rdpmc
-
-#include <arch/arch_ops.h>
-#include <arch/mmu.h>
-#include <arch/x86.h>
-#include <arch/x86/apic.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/perf_mon.h>
-#include <assert.h>
-#include <err.h>
-#include <fbl/algorithm.h>
-#include <fbl/alloc_checker.h>
-#include <fbl/macros.h>
-#include <fbl/ref_ptr.h>
-#include <ktl/unique_ptr.h>
-#include <kernel/align.h>
-#include <kernel/mp.h>
-#include <kernel/mutex.h>
-#include <kernel/stats.h>
-#include <kernel/thread.h>
-#include <ktl/move.h>
-#include <lib/ktrace.h>
-#include <lib/pci/pio.h>
-#include <lib/zircon-internal/device/cpu-trace/cpu-perf.h>
-#include <lib/zircon-internal/device/cpu-trace/intel-pm.h>
-#include <lib/zircon-internal/ktrace.h>
-#include <lib/zircon-internal/mtrace.h>
-#include <lk/init.h>
-#include <new>
-#include <platform.h>
-#include <pow2.h>
-#include <string.h>
-#include <trace.h>
-#include <vm/vm.h>
-#include <vm/vm_address_region.h>
-#include <vm/vm_aspace.h>
-#include <vm/vm_object_physical.h>
-#include <zircon/thread_annotations.h>
-
-#define LOCAL_TRACE 0
-
-// TODO(cja): Sort out headers so the kernel can include these sorts of definitions
-// without needing DDK access
-#define PCI_CONFIG_VENDOR_ID        0x00
-#define PCI_CONFIG_DEVICE_ID        0x02
-
-// There's only a few misc events, and they're non-homogenous,
-// so handle them directly.
-typedef enum {
-#define DEF_MISC_SKL_EVENT(symbol, event_name, id, offset, size, flags, readable_name, description) \
-    symbol ## _ID = CPUPERF_MAKE_EVENT_ID(CPUPERF_GROUP_MISC, id),
-#include <lib/zircon-internal/device/cpu-trace/skylake-misc-events.inc>
-} misc_event_id_t;
-
-// h/w address of misc events.
-typedef enum {
-#define DEF_MISC_SKL_EVENT(symbol, event_name, id, offset, size, flags, readable_name, description) \
-    symbol ## _OFFSET = offset,
-#include <lib/zircon-internal/device/cpu-trace/skylake-misc-events.inc>
-} misc_event_offset_t;
-
-// TODO(dje): Freeze-on-PMI doesn't work in skylake.
-// This is here for experimentation purposes.
-#define TRY_FREEZE_ON_PMI 0
-
-// At a minimum we require Performance Monitoring version 4.
-// KISS: Skylake supports version 4.
-#define MINIMUM_PERFMON_VERSION 4
-
-// MSRs
-
-#define IA32_PLATFORM_INFO 0xce
-
-#define IA32_PERF_CAPABILITIES 0x345
-
-// The counter MSR addresses are contiguous from here.
-#define IA32_PMC_FIRST 0x0c1
-// The event selection MSR addresses are contiguous from here.
-#define IA32_PERFEVTSEL_FIRST 0x186
-
-#define IA32_FIXED_CTR_CTRL 0x38d
-
-// The fixed counter MSR addresses are contiguous from here.
-#define IA32_FIXED_CTR0 0x309
-
-#define IA32_PERF_GLOBAL_CTRL 0x38f
-#define IA32_PERF_GLOBAL_STATUS 0x38e
-#define IA32_PERF_GLOBAL_OVF_CTRL 0x390
-#define IA32_PERF_GLOBAL_STATUS_RESET 0x390 // Yes, same as OVF_CTRL.
-#define IA32_PERF_GLOBAL_STATUS_SET 0x391
-#define IA32_PERF_GLOBAL_INUSE 0x392
-
-#define IA32_DEBUGCTL 0x1d9
-
-#define SKL_LAST_BRANCH_SELECT  0x1c8
-#define SKL_LAST_BRANCH_TOS     0x1c9
-
-// N.B. These values have changed across models.
-#define SKL_LAST_BRANCH_FROM_0  0x680
-#define SKL_LAST_BRANCH_FROM_16 0x690
-#define SKL_LAST_BRANCH_TO_0    0x6c0
-#define SKL_LAST_BRANCH_TO_16   0x6d0
-#define SKL_LAST_BRANCH_INFO_0  0xdc0
-#define SKL_LAST_BRANCH_INFO_16 0xdd0
-
-// Vendor,device ids of the device with MCHBAR stats registers.
-#define INTEL_MCHBAR_PCI_VENDOR_ID 0x8086
-const uint16_t supported_mem_device_ids[] = {
-    0x1900,  // docs use this value
-    0x1904,  // seen on NUC6
-    0x5904,  // seen on NUC7
-};
-
-// Offset in PCI config space of the BAR (base address register) of the
-// MCHBAR stats registers.
-#define INTEL_MCHBAR_PCI_CONFIG_OFFSET 0x48
-
-// Offsets from the BAR in the memory controller hub mmio space of counters
-// we're interested in. See the specs for MCHBAR in, e.g.,
-// "6th Generation Intel Core Processor Family Datasheet, Vol. 2".
-// TODO(dje): These values are model specific. The current values work for
-// currently supported platforms. Need to detect when we're on a supported
-// platform.
-// The BEGIN/END values are for computing the page(s) we need to map.
-// Offset from BAR of the first byte we need to map.
-#define UNC_IMC_STATS_BEGIN 0x5040 // MISC_MEM_GT_REQUESTS
-// Offset from BAR of the last byte we need to map.
-#define UNC_IMC_STATS_END   0x5983 // MISC_PKG_GT_TEMP
-
-// Verify all values are within [BEGIN,END].
-#define DEF_MISC_SKL_EVENT(symbol, event_name, id, offset, size, flags, readable_name, description) \
-    && (offset >= UNC_IMC_STATS_BEGIN && (offset + size/8) <= UNC_IMC_STATS_END + 1)
-static_assert(1
-#include <lib/zircon-internal/device/cpu-trace/skylake-misc-events.inc>
-    , "");
-
-// These aren't constexpr as we iterate to fill in values for each counter.
-static uint64_t kGlobalCtrlWritableBits;
-static uint64_t kFixedCounterCtrlWritableBits;
-
-// While the last-branch record is far larger, it is not emitted for each
-// event.
-static constexpr size_t kMaxEventRecordSize = sizeof(cpuperf_pc_record_t);
-
-// Commented out values represent currently unsupported features.
-// They remain present for documentation purposes.
-// Note: Making this const assumes at least PM version >= 2 (e.g.,
-// IA32_DEBUGCTL_FREEZE_LBRS_ON_PMI_MASK).
-// Note: At least FREEZE_WHILE_SMM needs to be set based on a runtime
-// determination (need to check PERF_CAPABILITIES).
-static constexpr uint64_t kDebugCtrlWritableBits =
-    (IA32_DEBUGCTL_LBR_MASK |
-     /*IA32_DEBUGCTL_BTF_MASK |*/
-     /*IA32_DEBUGCTL_TR_MASK |*/
-     /*IA32_DEBUGCTL_BTS_MASK |*/
-     /*IA32_DEBUGCTL_BTINT_MASK |*/
-     /*IA32_DEBUGCTL_BTS_OFF_OS_MASK |*/
-     /*IA32_DEBUGCTL_BTS_OFF_USR_MASK |*/
-     IA32_DEBUGCTL_FREEZE_LBRS_ON_PMI_MASK |
-#if TRY_FREEZE_ON_PMI
-     IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI_MASK |
-#endif
-     /*IA32_DEBUGCTL_FREEZE_WHILE_SMM_MASK |*/
-     /*IA32_DEBUGCTL_RTM_MASK |*/
-     0);
-static constexpr uint64_t kEventSelectWritableBits =
-    (IA32_PERFEVTSEL_EVENT_SELECT_MASK |
-     IA32_PERFEVTSEL_UMASK_MASK |
-     IA32_PERFEVTSEL_USR_MASK |
-     IA32_PERFEVTSEL_OS_MASK |
-     IA32_PERFEVTSEL_E_MASK |
-     IA32_PERFEVTSEL_PC_MASK |
-     IA32_PERFEVTSEL_INT_MASK |
-     IA32_PERFEVTSEL_ANY_MASK |
-     IA32_PERFEVTSEL_EN_MASK |
-     IA32_PERFEVTSEL_INV_MASK |
-     IA32_PERFEVTSEL_CMASK_MASK);
-
-enum LbrFormat {
-    LBR_FORMAT_32 = 0,
-    // The format contains LBR_INFO in addition to LBR_FROM/LBR_TO.
-    LBR_FORMAT_INFO = 0b101,
-};
-
-static bool supports_perfmon = false;
-
-static uint16_t perfmon_version = 0;
-static uint16_t perfmon_num_programmable_counters = 0;
-static uint16_t perfmon_programmable_counter_width = 0;
-static uint16_t perfmon_num_fixed_counters = 0;
-static uint16_t perfmon_fixed_counter_width = 0;
-static uint32_t perfmon_unsupported_events = 0;
-static uint32_t perfmon_capabilities = 0;
-
-// Maximum counter values, derived from their width.
-static uint64_t perfmon_max_fixed_counter_value = 0;
-static uint64_t perfmon_max_programmable_counter_value = 0;
-
-// Number of entries we can write in an LBR record.
-static uint32_t perfmon_lbr_stack_size = 0;
-
-// Counter bits in GLOBAL_STATUS to check on each interrupt.
-static uint64_t perfmon_counter_status_bits = 0;
-
-// BAR (base address register) of Intel MCHBAR performance
-// registers. These registers are accessible via mmio.
-static uint32_t perfmon_mchbar_bar = 0;
-
-// The number of "miscellaneous" events we can handle at once.
-static uint16_t perfmon_num_misc_events = 0;
-
-struct PerfmonCpuData {
-    // The trace buffer, passed in from userspace.
-    fbl::RefPtr<VmObject> buffer_vmo;
-    size_t buffer_size = 0;
-
-    // The trace buffer when mapped into kernel space.
-    // This is only done while the trace is running.
-    fbl::RefPtr<VmMapping> buffer_mapping;
-    cpuperf_buffer_header_t* buffer_start = 0;
-    void* buffer_end = 0;
-
-    // The next record to fill.
-    cpuperf_record_header_t* buffer_next = nullptr;
-} __CPU_ALIGN;
-
-struct MemoryControllerHubData {
-    // Where the regs are mapped.
-    fbl::RefPtr<VmMapping> mapping;
-
-    // The address where UNC_IMC_STATS_BEGIN is mapped, or zero if not mapped.
-    volatile void* stats_addr = 0;
-
-    // We can't reset the events, and even if we could it's preferable to
-    // avoid making the device writable (lots of critical stuff in there),
-    // so record the previous values so that we can emit into the trace buffer
-    // the delta since the last interrupt.
-    struct {
-        uint32_t bytes_read = 0;
-        uint32_t bytes_written = 0;
-        uint32_t gt_requests = 0;
-        uint32_t ia_requests = 0;
-        uint32_t io_requests = 0;
-        uint64_t all_active_core_cycles = 0;
-        uint64_t any_active_core_cycles = 0;
-        uint64_t active_gt_cycles = 0;
-        uint64_t active_ia_gt_cycles = 0;
-        uint64_t active_gt_slice_cycles = 0;
-        uint64_t active_gt_engine_cycles = 0;
-        // The remaining registers don't count anything.
-    } last_mem;
-};
-
-struct PerfmonState {
-    static zx_status_t Create(unsigned n_cpus, ktl::unique_ptr<PerfmonState>* out_state);
-    explicit PerfmonState(unsigned n_cpus);
-    ~PerfmonState();
-
-    // IA32_PERF_GLOBAL_CTRL
-    uint64_t global_ctrl = 0;
-
-    // IA32_FIXED_CTR_CTRL
-    uint64_t fixed_ctrl = 0;
-
-    // IA32_DEBUGCTL
-    uint64_t debug_ctrl = 0;
-
-    // True if MCHBAR perf regs need to be mapped in.
-    bool need_mchbar = false;
-
-    // See intel-pm.h:zx_x86_pmu_config_t.
-    cpuperf_event_id_t timebase_id = CPUPERF_EVENT_ID_NONE;
-
-    // The number of each kind of event in use, so we don't have to iterate
-    // over the entire arrays.
-    unsigned num_used_fixed = 0;
-    unsigned num_used_programmable = 0;
-    unsigned num_used_misc = 0;
-
-    // True if last branch records have been requested.
-    bool request_lbr_record = false;
-
-    // Number of entries in |cpu_data|.
-    const unsigned num_cpus;
-
-    // An array with one entry for each cpu.
-    // TODO(dje): Ideally this would be something like
-    // ktl::unique_ptr<PerfmonCpuData[]> cpu_data;
-    // but that will need to wait for a "new" that handles aligned allocs.
-    PerfmonCpuData* cpu_data = nullptr;
-
-    MemoryControllerHubData mchbar_data;
-
-    // |fixed_hw_map[i]| is the h/w fixed counter number.
-    // This is used to only look at fixed counters that are used.
-    unsigned fixed_hw_map[IPM_MAX_FIXED_COUNTERS] = {};
-
-    // The counters are reset to this at the start.
-    // And again for those that are reset on overflow.
-    uint64_t fixed_initial_value[IPM_MAX_FIXED_COUNTERS] = {};
-    uint64_t programmable_initial_value[IPM_MAX_PROGRAMMABLE_COUNTERS] = {};
-
-    // Flags for each event/counter, IPM_CONFIG_FLAG_*.
-    uint32_t fixed_flags[IPM_MAX_FIXED_COUNTERS] = {};
-    uint32_t programmable_flags[IPM_MAX_PROGRAMMABLE_COUNTERS] = {};
-    uint32_t misc_flags[IPM_MAX_MISC_EVENTS] = {};
-
-    // The ids for each of the in-use events, or zero if not used.
-    // These are passed in from the driver and then written to the buffer,
-    // but otherwise have no meaning to us.
-    // All in-use entries appear consecutively.
-    cpuperf_event_id_t fixed_ids[IPM_MAX_FIXED_COUNTERS] = {};
-    cpuperf_event_id_t programmable_ids[IPM_MAX_PROGRAMMABLE_COUNTERS] = {};
-    cpuperf_event_id_t misc_ids[IPM_MAX_MISC_EVENTS] = {};
-
-    // IA32_PERFEVTSEL_*
-    uint64_t events[IPM_MAX_PROGRAMMABLE_COUNTERS] = {};
-};
-
-static fbl::Mutex perfmon_lock;
-
-static ktl::unique_ptr<PerfmonState> perfmon_state TA_GUARDED(perfmon_lock);
-
-// This is accessed atomically as it is also accessed by the PMI handler.
-static int perfmon_active = false;
-
-static inline bool x86_perfmon_lbr_is_supported() {
-    return perfmon_lbr_stack_size > 0;
-}
-
-zx_status_t PerfmonState::Create(unsigned n_cpus, ktl::unique_ptr<PerfmonState>* out_state) {
-    fbl::AllocChecker ac;
-    auto state = ktl::unique_ptr<PerfmonState>(new (&ac) PerfmonState(n_cpus));
-    if (!ac.check())
-        return ZX_ERR_NO_MEMORY;
-
-    size_t space_needed = sizeof(PerfmonCpuData) * n_cpus;
-    auto cpu_data = reinterpret_cast<PerfmonCpuData*>(
-        memalign(alignof(PerfmonCpuData), space_needed));
-    if (!cpu_data)
-        return ZX_ERR_NO_MEMORY;
-
-    for (unsigned cpu = 0; cpu < n_cpus; ++cpu) {
-        new (&cpu_data[cpu]) PerfmonCpuData();
-    }
-
-    state->cpu_data = cpu_data;
-    *out_state = ktl::move(state);
-    return ZX_OK;
-}
-
-PerfmonState::PerfmonState(unsigned n_cpus)
-        : num_cpus(n_cpus) { }
-
-PerfmonState::~PerfmonState() {
-    DEBUG_ASSERT(!atomic_load(&perfmon_active));
-    if (cpu_data) {
-        for (unsigned cpu = 0; cpu < num_cpus; ++cpu) {
-            auto data = &cpu_data[cpu];
-            data->~PerfmonCpuData();
-        }
-        free(cpu_data);
-    }
-}
-
-static bool x86_perfmon_have_mchbar_data() {
-    uint32_t vendor_id, device_id;
-
-    auto status = Pci::PioCfgRead(0, 0, 0,
-                                  PCI_CONFIG_VENDOR_ID,
-                                  &vendor_id, 16);
-    if (status != ZX_OK)
-        return false;
-    if (vendor_id != INTEL_MCHBAR_PCI_VENDOR_ID)
-        return false;
-    status = Pci::PioCfgRead(0, 0, 0,
-                             PCI_CONFIG_DEVICE_ID,
-                             &device_id, 16);
-    if (status != ZX_OK)
-        return false;
-    for (auto supported_device_id : supported_mem_device_ids) {
-        if (supported_device_id == device_id)
-            return true;
-    }
-
-    TRACEF("perfmon: unsupported pci device: 0x%x.0x%x\n",
-           vendor_id, device_id);
-    return false;
-}
-
-static void x86_perfmon_init_mchbar() {
-    uint32_t bar;
-    auto status = Pci::PioCfgRead(0, 0, 0,
-                                  INTEL_MCHBAR_PCI_CONFIG_OFFSET,
-                                  &bar, 32);
-    if (status == ZX_OK) {
-        LTRACEF("perfmon: mchbar: 0x%x\n", bar);
-        // TODO(dje): The lower four bits contain useful data, but punt for now.
-        // See PCI spec 6.2.5.1.
-        perfmon_mchbar_bar = bar & ~15u;
-        perfmon_num_misc_events =
-            static_cast<uint32_t>(fbl::count_of(static_cast<zx_x86_pmu_config_t*>(nullptr)->misc_ids));
-    } else {
-        TRACEF("perfmon: error %d reading mchbar\n", status);
-    }
-}
-
-// Return the size of the LBR stack, or zero if not supported.
-static unsigned x86_perfmon_lbr_stack_size() {
-    static const struct {
-        x86_microarch_list microarch;
-        uint8_t stack_size;
-    } supported_chips[] = {
-        { X86_MICROARCH_INTEL_SKYLAKE, 32 },
-        { X86_MICROARCH_INTEL_KABYLAKE, 32 },
-    };
-
-    unsigned lbr_format =
-        perfmon_capabilities & ((1u << IA32_PERF_CAPABILITIES_LBR_FORMAT_LEN) - 1);
-    // TODO(dje): KISS and only support these formats for now.
-    switch (lbr_format) {
-    case LBR_FORMAT_INFO:
-        break;
-    default:
-        return 0;
-    }
-
-    for (const auto& chip : supported_chips) {
-        if (chip.microarch == x86_microarch)
-            return chip.stack_size;
-    }
-
-    return 0;
-}
-
-static void x86_perfmon_init_lbr(uint32_t lbr_stack_size) {
-    perfmon_lbr_stack_size = lbr_stack_size;
-}
-
-static void x86_perfmon_init_once(uint level)
-{
-    struct cpuid_leaf leaf;
-    if (!x86_get_cpuid_subleaf(X86_CPUID_PERFORMANCE_MONITORING, 0, &leaf)) {
-        return;
-    }
-
-    perfmon_version = leaf.a & 0xff;
-
-    perfmon_num_programmable_counters = (leaf.a >> 8) & 0xff;
-    if (perfmon_num_programmable_counters > IPM_MAX_PROGRAMMABLE_COUNTERS) {
-        TRACEF("perfmon: unexpected num programmable counters %u in cpuid.0AH\n",
-               perfmon_num_programmable_counters);
-        return;
-    }
-    perfmon_programmable_counter_width = (leaf.a >> 16) & 0xff;
-    // The <16 test is just something simple to ensure it's usable.
-    if (perfmon_programmable_counter_width < 16 ||
-        perfmon_programmable_counter_width > 64) {
-        TRACEF("perfmon: unexpected programmable counter width %u in cpuid.0AH\n",
-               perfmon_programmable_counter_width);
-        return;
-    }
-    perfmon_max_programmable_counter_value = ~0ul;
-    if (perfmon_programmable_counter_width < 64) {
-        perfmon_max_programmable_counter_value =
-            (1ul << perfmon_programmable_counter_width) - 1;
-    }
-
-    unsigned ebx_length = (leaf.a >> 24) & 0xff;
-    if (ebx_length > 7) {
-        TRACEF("perfmon: unexpected value %u in cpuid.0AH.EAH[31..24]\n",
-               ebx_length);
-        return;
-    }
-    perfmon_unsupported_events = leaf.b & ((1u << ebx_length) - 1);
-
-    perfmon_num_fixed_counters = leaf.d & 0x1f;
-    if (perfmon_num_fixed_counters > IPM_MAX_FIXED_COUNTERS) {
-        TRACEF("perfmon: unexpected num fixed counters %u in cpuid.0AH\n",
-               perfmon_num_fixed_counters);
-        return;
-    }
-    perfmon_fixed_counter_width = (leaf.d >> 5) & 0xff;
-    // The <16 test is just something simple to ensure it's usable.
-    if (perfmon_fixed_counter_width < 16 ||
-        perfmon_fixed_counter_width > 64) {
-        TRACEF("perfmon: unexpected fixed counter width %u in cpuid.0AH\n",
-               perfmon_fixed_counter_width);
-        return;
-    }
-    perfmon_max_fixed_counter_value = ~0ul;
-    if (perfmon_fixed_counter_width < 64) {
-        perfmon_max_fixed_counter_value =
-            (1ul << perfmon_fixed_counter_width) - 1;
-    }
-
-    supports_perfmon = perfmon_version >= MINIMUM_PERFMON_VERSION;
-
-    if (x86_feature_test(X86_FEATURE_PDCM)) {
-        perfmon_capabilities = static_cast<uint32_t>(read_msr(IA32_PERF_CAPABILITIES));
-    }
-
-    perfmon_counter_status_bits = 0;
-    for (unsigned i = 0; i < perfmon_num_programmable_counters; ++i)
-        perfmon_counter_status_bits |= IA32_PERF_GLOBAL_STATUS_PMC_OVF_MASK(i);
-    for (unsigned i = 0; i < perfmon_num_fixed_counters; ++i)
-        perfmon_counter_status_bits |= IA32_PERF_GLOBAL_STATUS_FIXED_OVF_MASK(i);
-
-    kGlobalCtrlWritableBits = 0;
-    for (unsigned i = 0; i < perfmon_num_programmable_counters; ++i)
-        kGlobalCtrlWritableBits |= IA32_PERF_GLOBAL_CTRL_PMC_EN_MASK(i);
-    for (unsigned i = 0; i < perfmon_num_fixed_counters; ++i)
-        kGlobalCtrlWritableBits |= IA32_PERF_GLOBAL_CTRL_FIXED_EN_MASK(i);
-    kFixedCounterCtrlWritableBits = 0;
-    for (unsigned i = 0; i < perfmon_num_fixed_counters; ++i) {
-        kFixedCounterCtrlWritableBits |= IA32_FIXED_CTR_CTRL_EN_MASK(i);
-        kFixedCounterCtrlWritableBits |= IA32_FIXED_CTR_CTRL_ANY_MASK(i);
-        kFixedCounterCtrlWritableBits |= IA32_FIXED_CTR_CTRL_PMI_MASK(i);
-    }
-
-    if (x86_perfmon_have_mchbar_data()) {
-        x86_perfmon_init_mchbar();
-    }
-
-    unsigned lbr_stack_size = x86_perfmon_lbr_stack_size();
-    if (lbr_stack_size != 0) {
-        // Don't crash if the h/w supports more than we do, just clip it.
-        if (lbr_stack_size > CPUPERF_MAX_NUM_LAST_BRANCH) {
-            TRACEF("WARNING: H/W LBR stack size is %u, clipping to %u\n",
-                   lbr_stack_size, CPUPERF_MAX_NUM_LAST_BRANCH);
-            lbr_stack_size = CPUPERF_MAX_NUM_LAST_BRANCH;
-        }
-        x86_perfmon_init_lbr(lbr_stack_size);
-    }
-
-    printf("PMU: version %u\n", perfmon_version);
-}
-
-LK_INIT_HOOK(x86_perfmon, x86_perfmon_init_once, LK_INIT_LEVEL_ARCH);
-
-static void x86_perfmon_clear_overflow_indicators() {
-    uint64_t value = (IA32_PERF_GLOBAL_OVF_CTRL_CLR_COND_CHGD_MASK |
-                      IA32_PERF_GLOBAL_OVF_CTRL_DS_BUFFER_CLR_OVF_MASK |
-                      IA32_PERF_GLOBAL_OVF_CTRL_UNCORE_CLR_OVF_MASK);
-
-    // This function isn't performance critical enough to precompute this.
-    for (unsigned i = 0; i < perfmon_num_programmable_counters; ++i) {
-        value |= IA32_PERF_GLOBAL_OVF_CTRL_PMC_CLR_OVF_MASK(i);
-    }
-
-    for (unsigned i = 0; i < perfmon_num_fixed_counters; ++i) {
-        value |= IA32_PERF_GLOBAL_OVF_CTRL_FIXED_CTR_CLR_OVF_MASK(i);
-    }
-
-    write_msr(IA32_PERF_GLOBAL_OVF_CTRL, value);
-}
-
-// Return the h/w register number for fixed event id |id|
-// or IPM_MAX_FIXED_COUNTERS if not found.
-static unsigned x86_perfmon_lookup_fixed_counter(cpuperf_event_id_t id) {
-    if (CPUPERF_EVENT_ID_GROUP(id) != CPUPERF_GROUP_FIXED)
-        return IPM_MAX_FIXED_COUNTERS;
-    switch (CPUPERF_EVENT_ID_EVENT(id)) {
-#define DEF_FIXED_EVENT(symbol, event_name, id, regnum, flags, readable_name, description) \
-    case id: return regnum;
-#include <lib/zircon-internal/device/cpu-trace/intel-pm-events.inc>
-    default: return IPM_MAX_FIXED_COUNTERS;
-    }
-}
-
-size_t get_max_space_needed_for_all_records(PerfmonState* state) {
-    size_t num_events = (state->num_used_programmable +
-                         state->num_used_fixed +
-                         state->num_used_misc);
-    size_t space_needed = (sizeof(cpuperf_time_record_t) +
-                           num_events * kMaxEventRecordSize);
-    if (state->request_lbr_record)
-        space_needed += sizeof(cpuperf_last_branch_record_t);
-    return space_needed;
-}
-
-static void x86_perfmon_write_header(cpuperf_record_header_t* hdr,
-                                     cpuperf_record_type_t type,
-                                     cpuperf_event_id_t event) {
-    hdr->type = type;
-    hdr->reserved_flags = 0;
-    hdr->event = event;
-}
-
-static cpuperf_record_header_t* x86_perfmon_write_time_record(
-        cpuperf_record_header_t* hdr,
-        cpuperf_event_id_t event, zx_time_t time) {
-    auto rec = reinterpret_cast<cpuperf_time_record_t*>(hdr);
-    x86_perfmon_write_header(&rec->header, CPUPERF_RECORD_TIME, event);
-    rec->time = time;
-    ++rec;
-    return reinterpret_cast<cpuperf_record_header_t*>(rec);
-}
-
-static cpuperf_record_header_t* x86_perfmon_write_tick_record(
-        cpuperf_record_header_t* hdr,
-        cpuperf_event_id_t event) {
-    auto rec = reinterpret_cast<cpuperf_tick_record_t*>(hdr);
-    x86_perfmon_write_header(&rec->header, CPUPERF_RECORD_TICK, event);
-    ++rec;
-    return reinterpret_cast<cpuperf_record_header_t*>(rec);
-}
-
-static cpuperf_record_header_t* x86_perfmon_write_count_record(
-        cpuperf_record_header_t* hdr,
-        cpuperf_event_id_t event, uint64_t count) {
-    auto rec = reinterpret_cast<cpuperf_count_record_t*>(hdr);
-    x86_perfmon_write_header(&rec->header, CPUPERF_RECORD_COUNT, event);
-    rec->count = count;
-    ++rec;
-    return reinterpret_cast<cpuperf_record_header_t*>(rec);
-}
-
-static cpuperf_record_header_t* x86_perfmon_write_value_record(
-        cpuperf_record_header_t* hdr,
-        cpuperf_event_id_t event, uint64_t value) {
-    auto rec = reinterpret_cast<cpuperf_value_record_t*>(hdr);
-    x86_perfmon_write_header(&rec->header, CPUPERF_RECORD_VALUE, event);
-    rec->value = value;
-    ++rec;
-    return reinterpret_cast<cpuperf_record_header_t*>(rec);
-}
-
-static cpuperf_record_header_t* x86_perfmon_write_pc_record(
-        cpuperf_record_header_t* hdr,
-        cpuperf_event_id_t event, uint64_t cr3, uint64_t pc) {
-    auto rec = reinterpret_cast<cpuperf_pc_record_t*>(hdr);
-    x86_perfmon_write_header(&rec->header, CPUPERF_RECORD_PC, event);
-    rec->aspace = cr3;
-    rec->pc = pc;
-    ++rec;
-    return reinterpret_cast<cpuperf_record_header_t*>(rec);
-}
-
-zx_status_t arch_perfmon_get_properties(zx_x86_pmu_properties_t* props) {
-    fbl::AutoLock al(&perfmon_lock);
-
-    if (!supports_perfmon)
-        return ZX_ERR_NOT_SUPPORTED;
-    memset(props, 0, sizeof(*props));
-    props->pm_version = perfmon_version;
-    props->num_fixed_events = perfmon_num_fixed_counters;
-    props->num_programmable_events = perfmon_num_programmable_counters;
-    props->num_misc_events = perfmon_num_misc_events;
-    props->fixed_counter_width = perfmon_fixed_counter_width;
-    props->programmable_counter_width = perfmon_programmable_counter_width;
-    props->perf_capabilities = perfmon_capabilities;
-    props->lbr_stack_size = perfmon_lbr_stack_size;
-    return ZX_OK;
-}
-
-zx_status_t arch_perfmon_init() {
-    fbl::AutoLock al(&perfmon_lock);
-
-    if (!supports_perfmon)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (atomic_load(&perfmon_active))
-        return ZX_ERR_BAD_STATE;
-    if (perfmon_state)
-        return ZX_ERR_BAD_STATE;
-
-    ktl::unique_ptr<PerfmonState> state;
-    auto status = PerfmonState::Create(arch_max_num_cpus(), &state);
-    if (status != ZX_OK)
-        return status;
-
-    perfmon_state = ktl::move(state);
-    return ZX_OK;
-}
-
-zx_status_t arch_perfmon_assign_buffer(uint32_t cpu, fbl::RefPtr<VmObject> vmo) {
-    fbl::AutoLock al(&perfmon_lock);
-
-    if (!supports_perfmon)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (atomic_load(&perfmon_active))
-        return ZX_ERR_BAD_STATE;
-    if (!perfmon_state)
-        return ZX_ERR_BAD_STATE;
-    if (cpu >= perfmon_state->num_cpus)
-        return ZX_ERR_INVALID_ARGS;
-
-    // A simple safe approximation of the minimum size needed.
-    size_t min_size_needed = sizeof(cpuperf_buffer_header_t);
-    min_size_needed += sizeof(cpuperf_time_record_t);
-    min_size_needed += CPUPERF_MAX_EVENTS * kMaxEventRecordSize;
-    if (vmo->size() < min_size_needed)
-        return ZX_ERR_INVALID_ARGS;
-
-    auto data = &perfmon_state->cpu_data[cpu];
-    data->buffer_vmo = vmo;
-    data->buffer_size = vmo->size();
-    // The buffer is mapped into kernelspace later.
-
-    return ZX_OK;
-}
-
-static zx_status_t x86_perfmon_verify_control_config(
-        const zx_x86_pmu_config_t* config) {
-#if TRY_FREEZE_ON_PMI
-    if (!(config->debug_ctrl & IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI_MASK)) {
-        // IWBN to pass back a hint, instead of either nothing or
-        // a log message.
-        TRACEF("IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI not set\n");
-        return ZX_ERR_INVALID_ARGS;
-    }
-#else
-    if (config->debug_ctrl & IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI_MASK) {
-        TRACEF("IA32_DEBUGCTL_FREEZE_PERFMON_ON_PMI is set\n");
-        return ZX_ERR_INVALID_ARGS;
-    }
-#endif
-
-    if (config->global_ctrl & ~kGlobalCtrlWritableBits) {
-        TRACEF("Non writable bits set in |global_ctrl|\n");
-        return ZX_ERR_INVALID_ARGS;
-    }
-    if (config->fixed_ctrl & ~kFixedCounterCtrlWritableBits) {
-        TRACEF("Non writable bits set in |fixed_ctrl|\n");
-        return ZX_ERR_INVALID_ARGS;
-    }
-    if (config->debug_ctrl & ~kDebugCtrlWritableBits) {
-        TRACEF("Non writable bits set in |debug_ctrl|\n");
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    return ZX_OK;
-}
-
-static zx_status_t x86_perfmon_verify_fixed_config(
-        const zx_x86_pmu_config_t* config, unsigned* out_num_used) {
-    bool seen_last = false;
-    unsigned num_used = perfmon_num_fixed_counters;
-    for (unsigned i = 0; i < perfmon_num_fixed_counters; ++i) {
-        cpuperf_event_id_t id = config->fixed_ids[i];
-        if (id != 0 && seen_last) {
-            TRACEF("Active fixed events not front-filled\n");
-            return ZX_ERR_INVALID_ARGS;
-        }
-        // As a rule this file is agnostic to event ids, it's the device
-        // driver's job to map them to values we use. Thus we don't
-        // validate the ID here. We are given it so that we can include
-        // this ID in the trace output.
-        if (id == 0) {
-            if (!seen_last)
-                num_used = i;
-            seen_last = true;
-        }
-        if (seen_last) {
-            if (config->fixed_initial_value[i] != 0) {
-                TRACEF("Unused |fixed_initial_value[%u]| not zero\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if (config->fixed_flags[i] != 0) {
-                TRACEF("Unused |fixed_flags[%u]| not zero\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-        } else {
-            if (config->fixed_initial_value[i] > perfmon_max_fixed_counter_value) {
-                TRACEF("Initial value too large for |fixed_initial_value[%u]|\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if (config->fixed_flags[i] & ~IPM_CONFIG_FLAG_MASK) {
-                TRACEF("Unused bits set in |fixed_flags[%u]|\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if (!x86_perfmon_lbr_is_supported() &&
-                (config->fixed_flags[i] & IPM_CONFIG_FLAG_LBR) != 0) {
-                TRACEF("Last branch records requested for |fixed_flags[%u]|,"
-                       " but not supported\n", i);
-                return ZX_ERR_NOT_SUPPORTED;
-            }
-            if ((config->fixed_flags[i] & IPM_CONFIG_FLAG_TIMEBASE) &&
-                    config->timebase_id == CPUPERF_EVENT_ID_NONE) {
-                TRACEF("Timebase requested for |fixed_flags[%u]|, but not provided\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            unsigned hw_regnum = x86_perfmon_lookup_fixed_counter(id);
-            if (hw_regnum == IPM_MAX_FIXED_COUNTERS) {
-                TRACEF("Invalid fixed counter id |fixed_ids[%u]|\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-        }
-    }
-
-    *out_num_used = num_used;
-    return ZX_OK;
-}
-
-static zx_status_t x86_perfmon_verify_programmable_config(
-        const zx_x86_pmu_config_t* config, unsigned* out_num_used) {
-    bool seen_last = false;
-    unsigned num_used = perfmon_num_programmable_counters;
-    for (unsigned i = 0; i < perfmon_num_programmable_counters; ++i) {
-        cpuperf_event_id_t id = config->programmable_ids[i];
-        if (id != 0 && seen_last) {
-            TRACEF("Active programmable events not front-filled\n");
-            return ZX_ERR_INVALID_ARGS;
-        }
-        // As a rule this file is agnostic to event ids, it's the device
-        // driver's job to map them to the hw values we use. Thus we don't
-        // validate the ID here. We are given it so that we can include
-        // this ID in the trace output.
-        if (id == 0) {
-            if (!seen_last)
-                num_used = i;
-            seen_last = true;
-        }
-        if (seen_last) {
-            if (config->programmable_events[i] != 0) {
-                TRACEF("Unused |programmable_events[%u]| not zero\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if (config->programmable_initial_value[i] != 0) {
-                TRACEF("Unused |programmable_initial_value[%u]| not zero\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if (config->programmable_flags[i] != 0) {
-                TRACEF("Unused |programmable_flags[%u]| not zero\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-        } else {
-            if (config->programmable_events[i] & ~kEventSelectWritableBits) {
-                TRACEF("Non writable bits set in |programmable_events[%u]|\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if (config->programmable_initial_value[i] > perfmon_max_programmable_counter_value) {
-                TRACEF("Initial value too large for |programmable_initial_value[%u]|\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if (config->programmable_flags[i] & ~IPM_CONFIG_FLAG_MASK) {
-                TRACEF("Unused bits set in |programmable_flags[%u]|\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if (!x86_perfmon_lbr_is_supported() &&
-                (config->programmable_flags[i] & IPM_CONFIG_FLAG_LBR) != 0) {
-                TRACEF("Last branch records requested for |programmable_flags[%u]|,"
-                       " but not supported\n", i);
-                return ZX_ERR_NOT_SUPPORTED;
-            }
-            if ((config->programmable_flags[i] & IPM_CONFIG_FLAG_TIMEBASE) &&
-                    config->timebase_id == CPUPERF_EVENT_ID_NONE) {
-                TRACEF("Timebase requested for |programmable_flags[%u]|, but not provided\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-        }
-    }
-
-    *out_num_used = num_used;
-    return ZX_OK;
-}
-
-static zx_status_t x86_perfmon_verify_misc_config(
-        const zx_x86_pmu_config_t* config,
-        unsigned* out_num_used) {
-    bool seen_last = false;
-    size_t max_num_used = fbl::count_of(config->misc_ids);
-    size_t num_used = max_num_used;
-    for (size_t i = 0; i < max_num_used; ++i) {
-        cpuperf_event_id_t id = config->misc_ids[i];
-        if (id != 0 && seen_last) {
-            TRACEF("Active misc events not front-filled\n");
-            return ZX_ERR_INVALID_ARGS;
-        }
-        if (id == 0) {
-            if (!seen_last)
-                num_used = i;
-            seen_last = true;
-        }
-        if (seen_last) {
-            if (config->misc_flags[i] != 0) {
-                TRACEF("Unused |misc_flags[%zu]| not zero\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-        } else {
-            if (config->misc_flags[i] & ~IPM_CONFIG_FLAG_MASK) {
-                TRACEF("Unused bits set in |misc_flags[%zu]|\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            // Currently we only support the MCHBAR events.
-            // They cannot provide pc. We ignore the OS/USER bits.
-            if (config->misc_flags[i] & (IPM_CONFIG_FLAG_PC | IPM_CONFIG_FLAG_LBR)) {
-                TRACEF("Invalid bits (0x%x) in |misc_flags[%zu]|\n",
-                       config->misc_flags[i], i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            if ((config->misc_flags[i] & IPM_CONFIG_FLAG_TIMEBASE) &&
-                    config->timebase_id == CPUPERF_EVENT_ID_NONE) {
-                TRACEF("Timebase requested for |misc_flags[%zu]|, but not provided\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-            switch (CPUPERF_EVENT_ID_EVENT(id)) {
-#define DEF_MISC_SKL_EVENT(symbol, event_name, id, offset, size, flags, readable_name, description) \
-            case id: break;
-#include <lib/zircon-internal/device/cpu-trace/skylake-misc-events.inc>
-            default:
-                TRACEF("Invalid misc event id |misc_ids[%zu]|\n", i);
-                return ZX_ERR_INVALID_ARGS;
-            }
-        }
-    }
-
-    *out_num_used = static_cast<unsigned>(num_used);
-    return ZX_OK;
-}
-
-static zx_status_t x86_perfmon_verify_timebase_config(
-        zx_x86_pmu_config_t* config,
-        unsigned num_fixed, unsigned num_programmable) {
-    if (config->timebase_id == CPUPERF_EVENT_ID_NONE) {
-        return ZX_OK;
-    }
-
-    for (unsigned i = 0; i < num_fixed; ++i) {
-        if (config->fixed_ids[i] == config->timebase_id) {
-            // The PMI code is simpler if this is the case.
-            config->fixed_flags[i] &= ~IPM_CONFIG_FLAG_TIMEBASE;
-            return ZX_OK;
-        }
-    }
-
-    for (unsigned i = 0; i < num_programmable; ++i) {
-        if (config->programmable_ids[i] == config->timebase_id) {
-            // The PMI code is simpler if this is the case.
-            config->programmable_flags[i] &= ~IPM_CONFIG_FLAG_TIMEBASE;
-            return ZX_OK;
-        }
-    }
-
-    TRACEF("Timebase 0x%x requested but not present\n", config->timebase_id);
-    return ZX_ERR_INVALID_ARGS;
-}
-
-static zx_status_t x86_perfmon_verify_config(zx_x86_pmu_config_t* config,
-                                             PerfmonState* state) {
-    auto status = x86_perfmon_verify_control_config(config);
-    if (status != ZX_OK)
-        return status;
-
-    unsigned num_used_fixed;
-    status = x86_perfmon_verify_fixed_config(config, &num_used_fixed);
-    if (status != ZX_OK)
-        return status;
-    state->num_used_fixed = num_used_fixed;
-
-    unsigned num_used_programmable;
-    status = x86_perfmon_verify_programmable_config(config, &num_used_programmable);
-    if (status != ZX_OK)
-        return status;
-    state->num_used_programmable = num_used_programmable;
-
-    unsigned num_used_misc;
-    status = x86_perfmon_verify_misc_config(config, &num_used_misc);
-    if (status != ZX_OK)
-        return status;
-    state->num_used_misc = num_used_misc;
-
-    status = x86_perfmon_verify_timebase_config(config,
-                                                state->num_used_fixed,
-                                                state->num_used_programmable);
-    if (status != ZX_OK)
-        return status;
-
-    return ZX_OK;
-}
-
-static void x86_perfmon_stage_fixed_config(const zx_x86_pmu_config_t* config,
-                                           PerfmonState* state) {
-    static_assert(sizeof(state->fixed_ids) ==
-                  sizeof(config->fixed_ids), "");
-    memcpy(state->fixed_ids, config->fixed_ids,
-           sizeof(state->fixed_ids));
-
-    static_assert(sizeof(state->fixed_initial_value) ==
-                  sizeof(config->fixed_initial_value), "");
-    memcpy(state->fixed_initial_value, config->fixed_initial_value,
-           sizeof(state->fixed_initial_value));
-
-    static_assert(sizeof(state->fixed_flags) ==
-                  sizeof(config->fixed_flags), "");
-    memcpy(state->fixed_flags, config->fixed_flags,
-           sizeof(state->fixed_flags));
-
-    for (unsigned i = 0; i < fbl::count_of(state->fixed_hw_map); ++i) {
-        state->fixed_hw_map[i] = x86_perfmon_lookup_fixed_counter(config->fixed_ids[i]);
-    }
-}
-
-static void x86_perfmon_stage_programmable_config(
-        const zx_x86_pmu_config_t* config, PerfmonState* state) {
-    static_assert(sizeof(state->programmable_ids) ==
-                  sizeof(config->programmable_ids), "");
-    memcpy(state->programmable_ids, config->programmable_ids,
-           sizeof(state->programmable_ids));
-
-    static_assert(sizeof(state->programmable_initial_value) ==
-                  sizeof(config->programmable_initial_value), "");
-    memcpy(state->programmable_initial_value, config->programmable_initial_value,
-           sizeof(state->programmable_initial_value));
-
-    static_assert(sizeof(state->programmable_flags) ==
-                  sizeof(config->programmable_flags), "");
-    memcpy(state->programmable_flags, config->programmable_flags,
-           sizeof(state->programmable_flags));
-
-    static_assert(sizeof(state->events) ==
-                  sizeof(config->programmable_events), "");
-    memcpy(state->events, config->programmable_events, sizeof(state->events));
-}
-
-static void x86_perfmon_stage_misc_config(const zx_x86_pmu_config_t* config,
-                                          PerfmonState* state) {
-    static_assert(sizeof(state->misc_ids) ==
-                  sizeof(config->misc_ids), "");
-    memcpy(state->misc_ids, config->misc_ids,
-           sizeof(state->misc_ids));
-
-    static_assert(sizeof(state->misc_flags) ==
-                  sizeof(config->misc_flags), "");
-    memcpy(state->misc_flags, config->misc_flags,
-           sizeof(state->misc_flags));
-
-    state->need_mchbar = false;
-    for (unsigned i = 0; i < state->num_used_misc; ++i) {
-        // All misc events currently come from MCHBAR.
-        // When needed we can add a flag to the event to denote origin.
-        switch (CPUPERF_EVENT_ID_EVENT(state->misc_ids[i])) {
-#define DEF_MISC_SKL_EVENT(symbol, event_name, id, offset, size, flags, readable_name, description) \
-        case id:
-#include <lib/zircon-internal/device/cpu-trace/skylake-misc-events.inc>
-            state->need_mchbar = true;
-            break;
-        default:
-            break;
-        }
-    }
-
-    // What we'd like to do here is record the current values of these
-    // events, but they're not mapped in yet.
-    memset(&state->mchbar_data.last_mem, 0,
-           sizeof(state->mchbar_data.last_mem));
-}
-
-// Stage the configuration for later activation by START.
-// One of the main goals of this function is to verify the provided config
-// is ok, e.g., it won't cause us to crash.
-zx_status_t arch_perfmon_stage_config(zx_x86_pmu_config_t* config) {
-    fbl::AutoLock al(&perfmon_lock);
-
-    if (!supports_perfmon)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (atomic_load(&perfmon_active))
-        return ZX_ERR_BAD_STATE;
-    if (!perfmon_state)
-        return ZX_ERR_BAD_STATE;
-
-    auto state = perfmon_state.get();
-
-    LTRACEF("global_ctrl 0x%" PRIx64 "\n", config->global_ctrl);
-
-    // Note: The verification pass may also alter |config| to make things
-    // simpler for the implementation.
-    auto status = x86_perfmon_verify_config(config, state);
-    if (status != ZX_OK)
-        return status;
-
-    state->global_ctrl = config->global_ctrl;
-    state->fixed_ctrl = config->fixed_ctrl;
-    state->debug_ctrl = config->debug_ctrl;
-    state->timebase_id = config->timebase_id;
-
-    if (state->debug_ctrl & IA32_DEBUGCTL_LBR_MASK) {
-        if (!x86_perfmon_lbr_is_supported()) {
-            TRACEF("Last branch records requested in |debug_ctrl|, but not supported\n");
-            return ZX_ERR_NOT_SUPPORTED;
-        }
-        state->request_lbr_record = true;
-    }
-
-    x86_perfmon_stage_fixed_config(config, state);
-    x86_perfmon_stage_programmable_config(config, state);
-    x86_perfmon_stage_misc_config(config, state);
-
-    return ZX_OK;
-}
-
-// System statistics that come from MCHBAR.
-// See, e.g., desktop-6th-gen-core-family-datasheet-vol-2.
-// TODO(dje): Consider moving misc event support to a separate file
-// when the amount of code to support them gets large enough.
-
-// Take advantage of the ABI's support for returning two values so that
-// we can return both in registers.
-struct ReadMiscResult {
-    // The value of the register.
-    uint64_t value;
-    // The record type to use, either CPUPERF_RECORD_COUNT or
-    // CPUPERF_RECORD_VALUE.
-    uint8_t type;
-};
-
-// Read the 32-bit counter from MCHBAR and return the delta
-// since the last read. We do this in part because it's easier for clients
-// to process and in part to catch the cases of the counter wrapping that
-// we can (they're only 32 bits in h/w and are read-only).
-// WARNING: This function has the side-effect of updating |*last_value|.
-static uint32_t read_mc_counter32(volatile uint32_t* addr,
-                                  uint32_t* last_value_addr) {
-    uint32_t value = *addr;
-    uint32_t last_value = *last_value_addr;
-    *last_value_addr = value;
-    // Check for overflow. The code is the same in both branches, the if()
-    // exists to document the issue.
-    if (value < last_value) {
-        // Overflow, counter wrapped.
-        // We don't know how many times it wrapped, assume once.
-        // We rely on unsigned twos-complement arithmetic here.
-        return value - last_value;
-    } else {
-        // The counter may still have wrapped, but we can't detect this case.
-        return value - last_value;
-    }
-}
-
-// Read the 64-bit counter from MCHBAR and return the delta
-// since the last read. We do this because it's easier for clients to process.
-// Overflow is highly unlikely with a 64-bit counter.
-// WARNING: This function has the side-effect of updating |*last_value|.
-static uint64_t read_mc_counter64(volatile uint64_t* addr,
-                                  uint64_t* last_value_addr) {
-    uint64_t value = *addr;
-    uint64_t last_value = *last_value_addr;
-    *last_value_addr = value;
-    return value - last_value;
-}
-
-// Read the 32-bit non-counter value from MCHBAR.
-static uint32_t read_mc_value32(volatile uint32_t* addr) {
-    return *addr;
-}
-
-static ReadMiscResult read_mc_typed_counter32(volatile uint32_t* addr,
-                                              uint32_t* last_value_addr) {
-    return ReadMiscResult{
-        read_mc_counter32(addr, last_value_addr), CPUPERF_RECORD_COUNT};
-}
-
-static ReadMiscResult read_mc_typed_counter64(volatile uint64_t* addr,
-                                              uint64_t* last_value_addr) {
-    return ReadMiscResult{
-        read_mc_counter64(addr, last_value_addr), CPUPERF_RECORD_COUNT};
-}
-
-static ReadMiscResult read_mc_typed_value32(volatile uint32_t* addr) {
-    return ReadMiscResult{
-        read_mc_value32(addr), CPUPERF_RECORD_VALUE};
-}
-
-static volatile uint32_t* get_mc_addr32(PerfmonState* state,
-                                        uint32_t hw_addr) {
-    return reinterpret_cast<volatile uint32_t*>(
-        reinterpret_cast<volatile char*>(state->mchbar_data.stats_addr)
-        + hw_addr - UNC_IMC_STATS_BEGIN);
-}
-
-static volatile uint64_t* get_mc_addr64(PerfmonState* state,
-                                        uint32_t hw_addr) {
-    return reinterpret_cast<volatile uint64_t*>(
-        reinterpret_cast<volatile char*>(state->mchbar_data.stats_addr)
-        + hw_addr - UNC_IMC_STATS_BEGIN);
-}
-
-static ReadMiscResult read_mc_bytes_read(PerfmonState* state) {
-    uint32_t value = read_mc_counter32(
-        get_mc_addr32(state, MISC_MEM_BYTES_READ_OFFSET),
-        &state->mchbar_data.last_mem.bytes_read);
-    // Return the value in bytes, easier for human readers of the
-    // resulting report.
-    return ReadMiscResult{value * 64ul, CPUPERF_RECORD_COUNT};
-}
-
-static ReadMiscResult read_mc_bytes_written(PerfmonState* state) {
-    uint32_t value = read_mc_counter32(
-        get_mc_addr32(state, MISC_MEM_BYTES_WRITTEN_OFFSET),
-        &state->mchbar_data.last_mem.bytes_written);
-    // Return the value in bytes, easier for human readers of the
-    // resulting report.
-    return ReadMiscResult{value * 64ul, CPUPERF_RECORD_COUNT};
-}
-
-static ReadMiscResult read_mc_gt_requests(PerfmonState* state) {
-    return read_mc_typed_counter32(
-        get_mc_addr32(state, MISC_MEM_GT_REQUESTS_OFFSET),
-        &state->mchbar_data.last_mem.gt_requests);
-}
-
-static ReadMiscResult read_mc_ia_requests(PerfmonState* state) {
-    return read_mc_typed_counter32(
-        get_mc_addr32(state, MISC_MEM_IA_REQUESTS_OFFSET),
-        &state->mchbar_data.last_mem.ia_requests);
-}
-
-static ReadMiscResult read_mc_io_requests(PerfmonState* state) {
-    return read_mc_typed_counter32(
-        get_mc_addr32(state, MISC_MEM_IO_REQUESTS_OFFSET),
-        &state->mchbar_data.last_mem.io_requests);
-}
-
-static ReadMiscResult read_mc_all_active_core_cycles(PerfmonState* state) {
-    return read_mc_typed_counter64(
-        get_mc_addr64(state, MISC_PKG_ALL_ACTIVE_CORE_CYCLES_OFFSET),
-        &state->mchbar_data.last_mem.all_active_core_cycles);
-}
-
-static ReadMiscResult read_mc_any_active_core_cycles(PerfmonState* state) {
-    return read_mc_typed_counter64(
-        get_mc_addr64(state, MISC_PKG_ANY_ACTIVE_CORE_CYCLES_OFFSET),
-        &state->mchbar_data.last_mem.any_active_core_cycles);
-}
-
-static ReadMiscResult read_mc_active_gt_cycles(PerfmonState* state) {
-    return read_mc_typed_counter64(
-        get_mc_addr64(state, MISC_PKG_ACTIVE_GT_CYCLES_OFFSET),
-        &state->mchbar_data.last_mem.active_gt_cycles);
-}
-
-static ReadMiscResult read_mc_active_ia_gt_cycles(PerfmonState* state) {
-    return read_mc_typed_counter64(
-        get_mc_addr64(state, MISC_PKG_ACTIVE_IA_GT_CYCLES_OFFSET),
-        &state->mchbar_data.last_mem.active_ia_gt_cycles);
-}
-
-static ReadMiscResult read_mc_active_gt_slice_cycles(PerfmonState* state) {
-    return read_mc_typed_counter64(
-        get_mc_addr64(state, MISC_PKG_ACTIVE_GT_SLICE_CYCLES_OFFSET),
-        &state->mchbar_data.last_mem.active_gt_slice_cycles);
-}
-
-static ReadMiscResult read_mc_active_gt_engine_cycles(PerfmonState* state) {
-    return read_mc_typed_counter64(
-        get_mc_addr64(state, MISC_PKG_ACTIVE_GT_ENGINE_CYCLES_OFFSET),
-        &state->mchbar_data.last_mem.active_gt_engine_cycles);
-}
-
-static ReadMiscResult read_mc_peci_therm_margin(PerfmonState* state) {
-    uint32_t value = read_mc_value32(
-                get_mc_addr32(state, MISC_PKG_PECI_THERM_MARGIN_OFFSET));
-    return ReadMiscResult{value & 0xffff, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_rapl_perf_status(PerfmonState* state) {
-    return read_mc_typed_value32(
-        get_mc_addr32(state, MISC_PKG_RAPL_PERF_STATUS_OFFSET));
-}
-
-static ReadMiscResult read_mc_ia_freq_clamping_reasons(PerfmonState* state) {
-    // Some of the reserved bits have read as ones. Remove them to make the
-    // reported value easier to read.
-    const uint32_t kReserved =
-        (1u << 31) | (1u << 30) | (1u << 25) | (1u << 19) | (1u << 18) |
-        (1u << 15) | (1u << 14) | (1u << 9)  | (1u << 3)  | (1u << 2);
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_IA_FREQ_CLAMPING_REASONS_OFFSET));
-    return ReadMiscResult{value & ~kReserved, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_gt_freq_clamping_reasons(PerfmonState* state) {
-    // Some of the reserved bits have read as ones. Remove them to make the
-    // reported value easier to read.
-    const uint32_t kReserved =
-        (1u << 31) | (1u << 30) | (1u << 29) | (1u << 25) | (1u << 20) |
-        (1u << 19) | (1u << 18) | (1u << 15) | (1u << 14) | (1u << 13) |
-        (1u << 9)  | (1u << 4)  | (1u << 3)  | (1u << 2);
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_GT_FREQ_CLAMPING_REASONS_OFFSET));
-    return ReadMiscResult{value & ~kReserved, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_rp_slice_freq(PerfmonState* state) {
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_RP_GT_SLICE_FREQ_OFFSET));
-    value = (value >> 17) & 0x1ff;
-    // Convert the value to Mhz.
-    // We can't do floating point, and this doesn't have to be perfect.
-    uint64_t scaled_value = value * 16667ul / 1000 /*16.667*/;
-    return ReadMiscResult{scaled_value, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_rp_unslice_freq(PerfmonState* state) {
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_RP_GT_UNSLICE_FREQ_OFFSET));
-    value = (value >> 8) & 0x1ff;
-    // Convert the value to Mhz.
-    // We can't do floating point, and this doesn't have to be perfect.
-    uint64_t scaled_value = value * 16667ul / 1000 /*16.667*/;
-    return ReadMiscResult{scaled_value, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_rp_gt_volt(PerfmonState* state) {
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_RP_GT_VOLT_OFFSET));
-    return ReadMiscResult{value & 0xff, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_edram_temp(PerfmonState* state) {
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_EDRAM_TEMP_OFFSET));
-    return ReadMiscResult{value & 0xff, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_pkg_temp(PerfmonState* state) {
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_PKG_TEMP_OFFSET));
-    return ReadMiscResult{value & 0xff, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_ia_temp(PerfmonState* state) {
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_IA_TEMP_OFFSET));
-    return ReadMiscResult{value & 0xff, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_mc_gt_temp(PerfmonState* state) {
-    uint32_t value = read_mc_value32(
-        get_mc_addr32(state, MISC_PKG_GT_TEMP_OFFSET));
-    return ReadMiscResult{value & 0xff, CPUPERF_RECORD_VALUE};
-}
-
-static ReadMiscResult read_misc_event(PerfmonState* state,
-                                      cpuperf_event_id_t id) {
-    switch (id) {
-    case MISC_MEM_BYTES_READ_ID:
-        return read_mc_bytes_read(state);
-    case MISC_MEM_BYTES_WRITTEN_ID:
-        return read_mc_bytes_written(state);
-    case MISC_MEM_GT_REQUESTS_ID:
-        return read_mc_gt_requests(state);
-    case MISC_MEM_IA_REQUESTS_ID:
-        return read_mc_ia_requests(state);
-    case MISC_MEM_IO_REQUESTS_ID:
-        return read_mc_io_requests(state);
-    case MISC_PKG_ALL_ACTIVE_CORE_CYCLES_ID:
-        return read_mc_all_active_core_cycles(state);
-    case MISC_PKG_ANY_ACTIVE_CORE_CYCLES_ID:
-        return read_mc_any_active_core_cycles(state);
-    case MISC_PKG_ACTIVE_GT_CYCLES_ID:
-        return read_mc_active_gt_cycles(state);
-    case MISC_PKG_ACTIVE_IA_GT_CYCLES_ID:
-        return read_mc_active_ia_gt_cycles(state);
-    case MISC_PKG_ACTIVE_GT_SLICE_CYCLES_ID:
-        return read_mc_active_gt_slice_cycles(state);
-    case MISC_PKG_ACTIVE_GT_ENGINE_CYCLES_ID:
-        return read_mc_active_gt_engine_cycles(state);
-    case MISC_PKG_PECI_THERM_MARGIN_ID:
-        return read_mc_peci_therm_margin(state);
-    case MISC_PKG_RAPL_PERF_STATUS_ID:
-        return read_mc_rapl_perf_status(state);
-    case MISC_PKG_IA_FREQ_CLAMPING_REASONS_ID:
-        return read_mc_ia_freq_clamping_reasons(state);
-    case MISC_PKG_GT_FREQ_CLAMPING_REASONS_ID:
-        return read_mc_gt_freq_clamping_reasons(state);
-    case MISC_PKG_RP_GT_SLICE_FREQ_ID:
-        return read_mc_rp_slice_freq(state);
-    case MISC_PKG_RP_GT_UNSLICE_FREQ_ID:
-        return read_mc_rp_unslice_freq(state);
-    case MISC_PKG_RP_GT_VOLT_ID:
-        return read_mc_rp_gt_volt(state);
-    case MISC_PKG_EDRAM_TEMP_ID:
-        return read_mc_edram_temp(state);
-    case MISC_PKG_PKG_TEMP_ID:
-        return read_mc_pkg_temp(state);
-    case MISC_PKG_IA_TEMP_ID:
-        return read_mc_ia_temp(state);
-    case MISC_PKG_GT_TEMP_ID:
-        return read_mc_gt_temp(state);
-    default:
-        __UNREACHABLE;
-    }
-}
-
-
-static void x86_perfmon_unmap_buffers_locked(PerfmonState* state) {
-    unsigned num_cpus = state->num_cpus;
-    for (unsigned cpu = 0; cpu < num_cpus; ++cpu) {
-        auto data = &state->cpu_data[cpu];
-        if (data->buffer_start) {
-            data->buffer_mapping->Destroy();
-        }
-        data->buffer_mapping.reset();
-        data->buffer_start = nullptr;
-        data->buffer_end = nullptr;
-        data->buffer_next = nullptr;
-    }
-
-    if (state->mchbar_data.mapping) {
-        state->mchbar_data.mapping->Destroy();
-    }
-    state->mchbar_data.mapping.reset();
-    state->mchbar_data.stats_addr = nullptr;
-
-    LTRACEF("buffers unmapped");
-}
-
-static zx_status_t x86_map_mchbar_stat_registers(PerfmonState* state) {
-    DEBUG_ASSERT(perfmon_mchbar_bar != 0);
-    fbl::RefPtr<VmObject> vmo;
-    vaddr_t begin_page =
-        (perfmon_mchbar_bar + UNC_IMC_STATS_BEGIN) & ~(PAGE_SIZE - 1);
-    vaddr_t end_page =
-        (perfmon_mchbar_bar + UNC_IMC_STATS_END) & ~(PAGE_SIZE - 1);
-    size_t num_bytes_to_map = end_page + PAGE_SIZE - begin_page;
-    size_t begin_offset =
-        (perfmon_mchbar_bar + UNC_IMC_STATS_BEGIN) & (PAGE_SIZE - 1);
-
-    // We only map in the page(s) with the data we need.
-    auto status = VmObjectPhysical::Create(begin_page, num_bytes_to_map, &vmo);
-    if (status != ZX_OK)
-        return status;
-
-    const char name[] = "perfmon-mchbar";
-    vmo->set_name(name, sizeof(name));
-    status = vmo->SetMappingCachePolicy(ZX_CACHE_POLICY_UNCACHED_DEVICE);
-    if (status != ZX_OK)
-        return status;
-
-    auto vmar = VmAspace::kernel_aspace()->RootVmar();
-    uint32_t vmar_flags = 0;
-    uint32_t arch_mmu_flags = ARCH_MMU_FLAG_PERM_READ;
-    fbl::RefPtr<VmMapping> mapping;
-    status = vmar->CreateVmMapping(0, PAGE_SIZE, /*align_pow2*/0,
-                                   vmar_flags, ktl::move(vmo),
-                                   0, arch_mmu_flags, name,
-                                   &mapping);
-    if (status != ZX_OK)
-        return status;
-
-    status = mapping->MapRange(0, PAGE_SIZE, false);
-    if (status != ZX_OK)
-        return status;
-
-    state->mchbar_data.mapping = mapping;
-    state->mchbar_data.stats_addr =
-            reinterpret_cast<void*>(mapping->base() + begin_offset);
-
-    // Record the current values of these so that the trace will only include
-    // the delta since tracing started.
-#define INIT_MC_COUNT(member) \
-    do { \
-        state->mchbar_data.last_mem.member = 0; \
-        (void) read_mc_ ## member(state); \
-    } while (0)
-    INIT_MC_COUNT(bytes_read);
-    INIT_MC_COUNT(bytes_written);
-    INIT_MC_COUNT(gt_requests);
-    INIT_MC_COUNT(ia_requests);
-    INIT_MC_COUNT(io_requests);
-    INIT_MC_COUNT(all_active_core_cycles);
-    INIT_MC_COUNT(any_active_core_cycles);
-    INIT_MC_COUNT(active_gt_cycles);
-    INIT_MC_COUNT(active_ia_gt_cycles);
-    INIT_MC_COUNT(active_gt_slice_cycles);
-    INIT_MC_COUNT(active_gt_engine_cycles);
-#undef INIT_MC_COUNT
-
-    LTRACEF("memory stats mapped: begin 0x%lx, %zu bytes\n",
-            mapping->base(), num_bytes_to_map);
-
-    return ZX_OK;
-}
-
-static zx_status_t x86_perfmon_map_buffers_locked(PerfmonState* state) {
-    unsigned num_cpus = state->num_cpus;
-    zx_status_t status = ZX_OK;
-    for (unsigned cpu = 0; cpu < num_cpus; ++cpu) {
-        auto data = &state->cpu_data[cpu];
-        // Heads up: The logic is off if |vmo_offset| is non-zero.
-        const uint64_t vmo_offset = 0;
-        const size_t size = data->buffer_size;
-        const uint arch_mmu_flags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE;
-        const char* name = "ipm-buffer";
-        status = VmAspace::kernel_aspace()->RootVmar()->CreateVmMapping(
-            0 /* ignored */, size, 0 /* align pow2 */, 0 /* vmar flags */,
-            data->buffer_vmo, vmo_offset, arch_mmu_flags, name,
-            &data->buffer_mapping);
-        if (status != ZX_OK) {
-            TRACEF("error %d mapping buffer: cpu %u, size 0x%zx\n",
-                   status, cpu, size);
-            break;
-        }
-        // Pass true for |commit| so that we get our pages mapped up front.
-        // Otherwise we'll need to allow for a page fault to happen in the
-        // PMI handler.
-        status = data->buffer_mapping->MapRange(vmo_offset, size, true);
-        if (status != ZX_OK) {
-            TRACEF("error %d mapping range: cpu %u, size 0x%zx\n",
-                   status, cpu, size);
-            data->buffer_mapping->Destroy();
-            data->buffer_mapping.reset();
-            break;
-        }
-        data->buffer_start = reinterpret_cast<cpuperf_buffer_header_t*>(
-            data->buffer_mapping->base() + vmo_offset);
-        data->buffer_end = reinterpret_cast<char*>(data->buffer_start) + size;
-        LTRACEF("buffer mapped: cpu %u, start %p, end %p\n",
-                cpu, data->buffer_start, data->buffer_end);
-
-        auto hdr = data->buffer_start;
-        hdr->version = CPUPERF_BUFFER_VERSION;
-        hdr->arch = CPUPERF_BUFFER_ARCH_X86_64;
-        hdr->flags = 0;
-        hdr->ticks_per_second = ticks_per_second();
-        hdr->capture_end = sizeof(*hdr);
-        data->buffer_next = reinterpret_cast<cpuperf_record_header_t*>(
-            reinterpret_cast<char*>(data->buffer_start) + hdr->capture_end);
-    }
-
-    // Get access to MCHBAR stats if we can.
-    if (status == ZX_OK && state->need_mchbar) {
-        status = x86_map_mchbar_stat_registers(state);
-    }
-
-    if (status != ZX_OK) {
-        x86_perfmon_unmap_buffers_locked(state);
-    }
-
-    return status;
-}
-
-// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
-static void x86_perfmon_start_cpu_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
-    DEBUG_ASSERT(arch_ints_disabled());
-    DEBUG_ASSERT(!atomic_load(&perfmon_active) && raw_context);
-
-    auto state = reinterpret_cast<PerfmonState*>(raw_context);
-
-    for (unsigned i = 0; i < state->num_used_fixed; ++i) {
-        unsigned hw_num = state->fixed_hw_map[i];
-        DEBUG_ASSERT(hw_num < perfmon_num_fixed_counters);
-        write_msr(IA32_FIXED_CTR0 + hw_num, state->fixed_initial_value[i]);
-    }
-    write_msr(IA32_FIXED_CTR_CTRL, state->fixed_ctrl);
-
-    for (unsigned i = 0; i < state->num_used_programmable; ++i) {
-        // Ensure PERFEVTSEL.EN is zero before resetting the counter value,
-        // h/w requires it (apparently even if global ctrl is off).
-        write_msr(IA32_PERFEVTSEL_FIRST + i, 0);
-        // The counter must be written before PERFEVTSEL.EN is set to 1.
-        write_msr(IA32_PMC_FIRST + i, state->programmable_initial_value[i]);
-        write_msr(IA32_PERFEVTSEL_FIRST + i, state->events[i]);
-    }
-
-    write_msr(IA32_DEBUGCTL, state->debug_ctrl);
-
-    apic_pmi_unmask();
-
-    // Enable counters as late as possible so that our setup doesn't contribute
-    // to the data.
-    write_msr(IA32_PERF_GLOBAL_CTRL, state->global_ctrl);
-}
-
-// Begin collecting data.
-
-zx_status_t arch_perfmon_start() {
-    fbl::AutoLock al(&perfmon_lock);
-
-    if (!supports_perfmon)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (atomic_load(&perfmon_active))
-        return ZX_ERR_BAD_STATE;
-    if (!perfmon_state)
-        return ZX_ERR_BAD_STATE;
-
-    // Sanity check the buffers and map them in.
-    // This is deferred until now so that they are mapped in as minimally as
-    // necessary.
-    // TODO(dje): OTOH one might want to start/stop/start/stop/... and
-    // continually mapping/unmapping will be painful. Revisit when things
-    // settle down.
-    auto state = perfmon_state.get();
-    auto status = x86_perfmon_map_buffers_locked(state);
-    if (status != ZX_OK)
-        return status;
-
-    TRACEF("Enabling perfmon, %u fixed, %u programmable, %u misc\n",
-           state->num_used_fixed, state->num_used_programmable,
-           state->num_used_misc);
-    if (LOCAL_TRACE) {
-        LTRACEF("global ctrl: 0x%" PRIx64 ", fixed ctrl: 0x%" PRIx64 "\n",
-                state->global_ctrl, state->fixed_ctrl);
-        for (unsigned i = 0; i < state->num_used_fixed; ++i) {
-            LTRACEF("fixed[%u]: num %u, initial 0x%" PRIx64 "\n",
-                    i, state->fixed_hw_map[i], state->fixed_initial_value[i]);
-        }
-        for (unsigned i = 0; i < state->num_used_programmable; ++i) {
-            LTRACEF("programmable[%u]: id 0x%x, initial 0x%" PRIx64 "\n",
-                    i, state->programmable_ids[i],
-                    state->programmable_initial_value[i]);
-        }
-    }
-
-    mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_perfmon_start_cpu_task, state);
-    atomic_store(&perfmon_active, true);
-
-    return ZX_OK;
-}
-
-// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
-static void x86_perfmon_write_last_records(PerfmonState* state, uint32_t cpu) TA_NO_THREAD_SAFETY_ANALYSIS {
-    PerfmonCpuData* data = &state->cpu_data[cpu];
-    cpuperf_record_header_t* next = data->buffer_next;
-
-    zx_time_t now = rdtsc();
-    next = x86_perfmon_write_time_record(next, CPUPERF_EVENT_ID_NONE, now);
-
-    // If the counter triggers interrupts then the PMI handler will
-    // continually reset it to its initial value. To keep things simple
-    // just always subtract out the initial value from the current value
-    // and write the difference out. For non-interrupt triggering events
-    // the user should normally initialize the counter to zero to get
-    // correct results.
-    // Counters that don't trigger interrupts could overflow and we won't
-    // necessarily catch it, but there's nothing we can do about it.
-    // We can handle the overflowed-once case, which should catch the
-    // vast majority of cases.
-    // TODO(dje): Counters that trigger interrupts should never have
-    // an overflowed value here, but that's what I'm seeing.
-
-    for (unsigned i = 0; i < state->num_used_programmable; ++i) {
-        cpuperf_event_id_t id = state->programmable_ids[i];
-        DEBUG_ASSERT(id != 0);
-        uint64_t count = read_msr(IA32_PMC_FIRST + i);
-        if (count >= state->programmable_initial_value[i]) {
-            count -= state->programmable_initial_value[i];
-        } else {
-            // The max counter value is generally not 64 bits.
-            count += (perfmon_max_programmable_counter_value -
-                      state->programmable_initial_value[i] + 1);
-        }
-        next = x86_perfmon_write_count_record(next, id, count);
-    }
-    for (unsigned i = 0; i < state->num_used_fixed; ++i) {
-        cpuperf_event_id_t id = state->fixed_ids[i];
-        DEBUG_ASSERT(id != 0);
-        unsigned hw_num = state->fixed_hw_map[i];
-        DEBUG_ASSERT(hw_num < perfmon_num_fixed_counters);
-        uint64_t count = read_msr(IA32_FIXED_CTR0 + hw_num);
-        if (count >= state->fixed_initial_value[i]) {
-            count -= state->fixed_initial_value[i];
-        } else {
-            // The max counter value is generally not 64 bits.
-            count += (perfmon_max_fixed_counter_value -
-                      state->fixed_initial_value[i] + 1);
-        }
-        next = x86_perfmon_write_count_record(next, id, count);
-    }
-    // Misc events are currently all non-cpu-specific.
-    // Just report for cpu 0. See pmi_interrupt_handler.
-    if (cpu == 0) {
-        for (unsigned i = 0; i < state->num_used_misc; ++i) {
-            cpuperf_event_id_t id = state->misc_ids[i];
-            ReadMiscResult typed_value = read_misc_event(state, id);
-            switch (typed_value.type) {
-            case CPUPERF_RECORD_COUNT:
-                next = x86_perfmon_write_count_record(next, id, typed_value.value);
-                break;
-            case CPUPERF_RECORD_VALUE:
-                next = x86_perfmon_write_value_record(next, id, typed_value.value);
-                break;
-            default:
-                __UNREACHABLE;
-            }
-        }
-    }
-
-    data->buffer_next = next;
-}
-
-// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
-static void x86_perfmon_finalize_buffer(PerfmonState* state, uint32_t cpu) TA_NO_THREAD_SAFETY_ANALYSIS {
-    LTRACEF("Collecting last data for cpu %u\n", cpu);
-
-    PerfmonCpuData* data = &state->cpu_data[cpu];
-    cpuperf_buffer_header_t* hdr = data->buffer_start;
-
-    // KISS. There may be enough space to write some of what we want to write
-    // here, but don't try. Just use the same simple check that
-    // |pmi_interrupt_handler()| does.
-    size_t space_needed = get_max_space_needed_for_all_records(state);
-    if (reinterpret_cast<char*>(data->buffer_next) + space_needed > data->buffer_end) {
-        hdr->flags |= CPUPERF_BUFFER_FLAG_FULL;
-        LTRACEF("Buffer overflow on cpu %u\n", cpu);
-    } else {
-        x86_perfmon_write_last_records(state, cpu);
-    }
-
-    hdr->capture_end =
-        reinterpret_cast<char*>(data->buffer_next) -
-        reinterpret_cast<char*>(data->buffer_start);
-}
-
-// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
-static void x86_perfmon_stop_cpu_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
-    // Disable all counters ASAP.
-    write_msr(IA32_PERF_GLOBAL_CTRL, 0);
-    apic_pmi_mask();
-
-    DEBUG_ASSERT(arch_ints_disabled());
-    DEBUG_ASSERT(!atomic_load(&perfmon_active));
-    DEBUG_ASSERT(raw_context);
-
-    auto state = reinterpret_cast<PerfmonState*>(raw_context);
-    auto cpu = arch_curr_cpu_num();
-    auto data = &state->cpu_data[cpu];
-
-    // Retrieve final event values and write into the trace buffer.
-
-    if (data->buffer_start) {
-        x86_perfmon_finalize_buffer(state, cpu);
-    }
-
-    x86_perfmon_clear_overflow_indicators();
-}
-
-// Stop collecting data.
-// It's ok to call this multiple times.
-// Returns an error if called before ALLOC or after FREE.
-zx_status_t arch_perfmon_stop() {
-    fbl::AutoLock al(&perfmon_lock);
-
-    if (!supports_perfmon)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (!perfmon_state)
-        return ZX_ERR_BAD_STATE;
-
-    TRACEF("Disabling perfmon\n");
-
-    // Do this before anything else so that any PMI interrupts from this point
-    // on won't try to access potentially unmapped memory.
-    atomic_store(&perfmon_active, false);
-
-    // TODO(dje): Check clobbering of values - user should be able to do
-    // multiple stops and still read register values.
-
-    auto state = perfmon_state.get();
-    mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_perfmon_stop_cpu_task, state);
-
-    // x86_perfmon_start currently maps the buffers in, so we unmap them here.
-    // Make sure to do this after we've turned everything off so that we
-    // don't get another PMI after this.
-    x86_perfmon_unmap_buffers_locked(state);
-
-    return ZX_OK;
-}
-
-// Worker for x86_perfmon_fini to be executed on all cpus.
-// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
-static void x86_perfmon_reset_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
-    DEBUG_ASSERT(arch_ints_disabled());
-    DEBUG_ASSERT(!atomic_load(&perfmon_active));
-    DEBUG_ASSERT(!raw_context);
-
-    write_msr(IA32_PERF_GLOBAL_CTRL, 0);
-    apic_pmi_mask();
-    x86_perfmon_clear_overflow_indicators();
-
-    write_msr(IA32_DEBUGCTL, 0);
-
-    for (unsigned i = 0; i < perfmon_num_programmable_counters; ++i) {
-        write_msr(IA32_PERFEVTSEL_FIRST + i, 0);
-        write_msr(IA32_PMC_FIRST + i, 0);
-    }
-
-    write_msr(IA32_FIXED_CTR_CTRL, 0);
-    for (unsigned i = 0; i < perfmon_num_fixed_counters; ++i) {
-        write_msr(IA32_FIXED_CTR0 + i, 0);
-    }
-}
-
-// Finish data collection, reset h/w back to initial state and undo
-// everything x86_perfmon_init did.
-// Must be called while tracing is stopped.
-// It's ok to call this multiple times.
-zx_status_t arch_perfmon_fini() {
-    fbl::AutoLock al(&perfmon_lock);
-
-    if (!supports_perfmon)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (atomic_load(&perfmon_active))
-        return ZX_ERR_BAD_STATE;
-
-    mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_perfmon_reset_task, nullptr);
-
-    perfmon_state.reset();
-
-    return ZX_OK;
-}
-
-// Interrupt handling.
-
-// Write out a |cpuperf_last_branch_record_t| record.
-static cpuperf_record_header_t* x86_perfmon_write_last_branches(
-        PerfmonState* state, uint64_t cr3, cpuperf_record_header_t* hdr,
-        cpuperf_event_id_t id) {
-    auto rec = reinterpret_cast<cpuperf_last_branch_record_t*>(hdr);
-    auto num_entries = perfmon_lbr_stack_size;
-    static_assert(CPUPERF_MAX_NUM_LAST_BRANCH ==
-                  countof(cpuperf_last_branch_record_t::branches), "");
-    DEBUG_ASSERT(num_entries > 0 && num_entries <= CPUPERF_MAX_NUM_LAST_BRANCH);
-    x86_perfmon_write_header(&rec->header, CPUPERF_RECORD_LAST_BRANCH, id);
-    rec->num_branches = num_entries;
-    rec->aspace = cr3;
-
-    auto branches = &rec->branches[0];
-    unsigned tos = ((read_msr(SKL_LAST_BRANCH_TOS) & IA32_LBR_TOS_TOS_MASK) >>
-                    IA32_LBR_TOS_TOS_SHIFT);
-    for (unsigned i = 0; i < num_entries; ++i) {
-        unsigned msr_offset = (tos - i) % num_entries;
-        branches[i].from = read_msr(SKL_LAST_BRANCH_FROM_0 + msr_offset);
-        branches[i].to = read_msr(SKL_LAST_BRANCH_TO_0 + msr_offset);
-        uint64_t info = read_msr(SKL_LAST_BRANCH_INFO_0 + msr_offset);
-        // Only write these bits out.
-        info &= (IA32_LBR_INFO_CYCLE_COUNT_MASK | IA32_LBR_INFO_MISPRED_MASK);
-        branches[i].info = info;
-    }
-
-    // Get a pointer to the end of this record. Since this record is
-    // variable length it's more complicated than just "rec + 1".
-    auto next = reinterpret_cast<cpuperf_record_header_t*>(
-        reinterpret_cast<char*>(rec) + CPUPERF_LAST_BRANCH_RECORD_SIZE(rec));
-    LTRACEF("LBR record: num branches %u, @%p, next @%p\n",
-            num_entries, hdr, next);
-    return next;
-}
-
-// Helper function so that there is only one place where we enable/disable
-// interrupts (our caller).
-// Returns true if success, false if buffer is full.
-
-static bool pmi_interrupt_handler(x86_iframe_t *frame, PerfmonState* state) {
-    // This is done here instead of in the caller so that it is done *after*
-    // we disable the counters.
-    CPU_STATS_INC(perf_ints);
-
-    uint cpu = arch_curr_cpu_num();
-    auto data = &state->cpu_data[cpu];
-
-    // On x86 zx_ticks_get uses rdtsc.
-    zx_time_t now = rdtsc();
-    LTRACEF("cpu %u: now %" PRIi64 ", sp %p\n", cpu, now, __GET_FRAME());
-
-    // Rather than continually checking if we have enough space, just
-    // conservatively check for the maximum amount we'll need.
-    size_t space_needed = get_max_space_needed_for_all_records(state);
-    if (reinterpret_cast<char*>(data->buffer_next) + space_needed > data->buffer_end) {
-        TRACEF("cpu %u: @%" PRIi64 " pmi buffer full\n", cpu, now);
-        data->buffer_start->flags |= CPUPERF_BUFFER_FLAG_FULL;
-        return false;
-    }
-
-    const uint64_t status = read_msr(IA32_PERF_GLOBAL_STATUS);
-    uint64_t bits_to_clear = 0;
-    uint64_t cr3 = x86_get_cr3();
-
-    LTRACEF("cpu %u: status 0x%" PRIx64 "\n", cpu, status);
-
-    if (status & perfmon_counter_status_bits) {
-#if TRY_FREEZE_ON_PMI
-        if (!(status & IA32_PERF_GLOBAL_STATUS_CTR_FRZ_MASK))
-            LTRACEF("Eh? status.CTR_FRZ not set\n");
-#else
-        if (status & IA32_PERF_GLOBAL_STATUS_CTR_FRZ_MASK)
-            LTRACEF("Eh? status.CTR_FRZ is set\n");
-#endif
-
-        auto next = data->buffer_next;
-        bool saw_timebase = false;
-        bool request_lbr = false;
-        // We can't record every event that requested LBR data.
-        // It is unspecified which one we pick.
-        cpuperf_event_id_t lbr_id = CPUPERF_EVENT_ID_NONE;
-
-        next = x86_perfmon_write_time_record(next, CPUPERF_EVENT_ID_NONE, now);
-
-        // Note: We don't write "value" records here instead prefering the
-        // smaller "tick" record. If the user is tallying the counts the user
-        // is required to recognize this and apply the tick rate.
-        // TODO(dje): Precompute mask to detect whether the interrupt is for
-        // the timebase counter, and then combine the loops.
-
-        for (unsigned i = 0; i < state->num_used_programmable; ++i) {
-            if (!(status & IA32_PERF_GLOBAL_STATUS_PMC_OVF_MASK(i)))
-                continue;
-            cpuperf_event_id_t id = state->programmable_ids[i];
-            // Counters using a separate timebase are handled below.
-            // We shouldn't get an interrupt on a counter using a timebase.
-            // TODO(dje): The counter could still overflow. Later.
-            if (id == state->timebase_id) {
-                saw_timebase = true;
-            } else if (state->programmable_flags[i] & IPM_CONFIG_FLAG_TIMEBASE) {
-                continue;
-            }
-            if (state->programmable_flags[i] & IPM_CONFIG_FLAG_PC) {
-                next = x86_perfmon_write_pc_record(next, id, cr3, frame->ip);
-            } else {
-                next = x86_perfmon_write_tick_record(next, id);
-            }
-            if (state->programmable_flags[i] & IPM_CONFIG_FLAG_LBR) {
-                request_lbr = true;
-                lbr_id = id;
-            }
-            LTRACEF("cpu %u: resetting PMC %u to 0x%" PRIx64 "\n",
-                    cpu, i, state->programmable_initial_value[i]);
-            write_msr(IA32_PMC_FIRST + i, state->programmable_initial_value[i]);
-        }
-
-        for (unsigned i = 0; i < state->num_used_fixed; ++i) {
-            unsigned hw_num = state->fixed_hw_map[i];
-            DEBUG_ASSERT(hw_num < perfmon_num_fixed_counters);
-            if (!(status & IA32_PERF_GLOBAL_STATUS_FIXED_OVF_MASK(hw_num)))
-                continue;
-            cpuperf_event_id_t id = state->fixed_ids[i];
-            // Counters using a separate timebase are handled below.
-            // We shouldn't get an interrupt on a counter using a timebase.
-            // TODO(dje): The counter could still overflow. Later.
-            if (id == state->timebase_id) {
-                saw_timebase = true;
-            } else if (state->fixed_flags[i] & IPM_CONFIG_FLAG_TIMEBASE) {
-                continue;
-            }
-            if (state->fixed_flags[i] & IPM_CONFIG_FLAG_PC) {
-                next = x86_perfmon_write_pc_record(next, id, cr3, frame->ip);
-            } else {
-                next = x86_perfmon_write_tick_record(next, id);
-            }
-            if (state->fixed_flags[i] & IPM_CONFIG_FLAG_LBR) {
-                request_lbr = true;
-                lbr_id = id;
-            }
-            LTRACEF("cpu %u: resetting FIXED %u to 0x%" PRIx64 "\n",
-                    cpu, hw_num, state->fixed_initial_value[i]);
-            write_msr(IA32_FIXED_CTR0 + hw_num, state->fixed_initial_value[i]);
-        }
-
-        bits_to_clear |= perfmon_counter_status_bits;
-
-        // Now handle events that have IPM_CONFIG_FLAG_TIMEBASE set.
-        if (saw_timebase) {
-            for (unsigned i = 0; i < state->num_used_programmable; ++i) {
-                if (!(state->programmable_flags[i] & IPM_CONFIG_FLAG_TIMEBASE))
-                    continue;
-                cpuperf_event_id_t id = state->programmable_ids[i];
-                uint64_t count = read_msr(IA32_PMC_FIRST + i);
-                next = x86_perfmon_write_count_record(next, id, count);
-                // We could leave the counter alone, but it could overflow.
-                // Instead reduce the risk and just always reset to zero.
-                LTRACEF("cpu %u: resetting PMC %u to 0x%" PRIx64 "\n",
-                        cpu, i, state->programmable_initial_value[i]);
-                write_msr(IA32_PMC_FIRST + i, state->programmable_initial_value[i]);
-            }
-            for (unsigned i = 0; i < state->num_used_fixed; ++i) {
-                if (!(state->fixed_flags[i] & IPM_CONFIG_FLAG_TIMEBASE))
-                    continue;
-                cpuperf_event_id_t id = state->fixed_ids[i];
-                unsigned hw_num = state->fixed_hw_map[i];
-                DEBUG_ASSERT(hw_num < perfmon_num_fixed_counters);
-                uint64_t count = read_msr(IA32_FIXED_CTR0 + hw_num);
-                next = x86_perfmon_write_count_record(next, id, count);
-                // We could leave the counter alone, but it could overflow.
-                // Instead reduce the risk and just always reset to zero.
-                LTRACEF("cpu %u: resetting FIXED %u to 0x%" PRIx64 "\n",
-                        cpu, hw_num, state->fixed_initial_value[i]);
-                write_msr(IA32_FIXED_CTR0 + hw_num, state->fixed_initial_value[i]);
-            }
-            // Misc events are currently all non-cpu-specific. We have a
-            // timebase driving their collection, but useful timebases
-            // are triggered on each cpu. One thing we'd like to avoid is
-            // contention for the cache line containing these counters.
-            // For now, only collect data when we're running on cpu 0.
-            // This is not ideal, it could be mostly idle. OTOH, some
-            // interrupts are currently only serviced on cpu 0 so that
-            // ameliorates the problem somewhat.
-            if (cpu == 0) {
-                for (unsigned i = 0; i < state->num_used_misc; ++i) {
-                    if (!(state->misc_flags[i] & IPM_CONFIG_FLAG_TIMEBASE)) {
-                        // While a timebase is required for all current misc
-                        // counters, we don't assume this here.
-                        continue;
-                    }
-                    cpuperf_event_id_t id = state->misc_ids[i];
-                    ReadMiscResult typed_value = read_misc_event(state, id);
-                    switch (typed_value.type) {
-                    case CPUPERF_RECORD_COUNT:
-                        next = x86_perfmon_write_count_record(next, id, typed_value.value);
-                        break;
-                    case CPUPERF_RECORD_VALUE:
-                        next = x86_perfmon_write_value_record(next, id, typed_value.value);
-                        break;
-                    default:
-                        __UNREACHABLE;
-                    }
-                }
-            }
-        }
-
-        if (request_lbr) {
-            next = x86_perfmon_write_last_branches(state, cr3, next, lbr_id);
-        }
-
-        data->buffer_next = next;
-    }
-
-    // We shouldn't be seeing these set (at least not yet).
-    if (status & IA32_PERF_GLOBAL_STATUS_TRACE_TOPA_PMI_MASK)
-        LTRACEF("WARNING: GLOBAL_STATUS_TRACE_TOPA_PMI set\n");
-    if (status & IA32_PERF_GLOBAL_STATUS_LBR_FRZ_MASK)
-        LTRACEF("WARNING: GLOBAL_STATUS_LBR_FRZ set\n");
-    if (status & IA32_PERF_GLOBAL_STATUS_DS_BUFFER_OVF_MASK)
-        LTRACEF("WARNING: GLOBAL_STATUS_DS_BUFFER_OVF set\n");
-    // TODO(dje): IA32_PERF_GLOBAL_STATUS_ASCI_MASK ???
-
-    // Note IA32_PERF_GLOBAL_STATUS_CTR_FRZ_MASK is readonly.
-    bits_to_clear |= (IA32_PERF_GLOBAL_STATUS_UNCORE_OVF_MASK |
-                      IA32_PERF_GLOBAL_STATUS_COND_CHGD_MASK);
-
-    // TODO(dje): No need to accumulate bits to clear if we're going to clear
-    // everything that's set anyway. Kept as is during development.
-    bits_to_clear |= status;
-
-    LTRACEF("cpu %u: clearing status bits 0x%" PRIx64 "\n",
-            cpu, bits_to_clear);
-    write_msr(IA32_PERF_GLOBAL_STATUS_RESET, bits_to_clear);
-
-    // TODO(dje): Always do this test for now. Later conditionally include
-    // via some debugging macro.
-    uint64_t end_status = read_msr(IA32_PERF_GLOBAL_STATUS);
-    if (end_status != 0)
-        TRACEF("WARNING: cpu %u: end status 0x%" PRIx64 "\n", cpu, end_status);
-
-    return true;
-}
-
-void apic_pmi_interrupt_handler(x86_iframe_t *frame) TA_NO_THREAD_SAFETY_ANALYSIS {
-    if (!atomic_load(&perfmon_active)) {
-        apic_issue_eoi();
-        return;
-    }
-
-#if TRY_FREEZE_ON_PMI
-    // Note: We're using perfmon v4 "streamlined" processing here.
-    // See Intel vol3 table 17-3 "Legacy and Streamlined Operation with
-    // Freeze_Perfmon_On_PMI = 1, Counter Overflowed".
-#else
-    // Turn all counters off as soon as possible so that the counters that
-    // haven't overflowed yet stop counting while we're working.
-    // TODO(dje): Is this necessary with CTR_FRZ?
-    // Otherwise once we reset the counter that overflowed the other counters
-    // will resume counting, and if we don't reset them too then CTR_FRZ
-    // remains set and we'll get no more PMIs.
-    write_msr(IA32_PERF_GLOBAL_CTRL, 0);
-#endif
-
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    auto state = perfmon_state.get();
-
-#if 0
-    // TODO(dje): We may want this anyway. If we want to be able to handle
-    // page faults inside this handler we'll need to turn interrupts back
-    // on. At the moment we can't do this as we don't handle recursive PMIs.
-    arch_set_blocking_disallowed(false);
-    arch_enable_ints();
-#endif
-
-    bool success = pmi_interrupt_handler(frame, state);
-
-#if 0
-    arch_disable_ints();
-    arch_set_blocking_disallowed(true);
-#endif
-
-    // This is done here instead of in the caller so that we have full control
-    // of when counting is restored.
-    apic_issue_eoi();
-
-    // If buffer is full leave everything turned off.
-    if (!success) {
-#if TRY_FREEZE_ON_PMI
-        write_msr(IA32_PERF_GLOBAL_CTRL, 0);
-#else
-        // Don't restore GLOBAL_CTRL, leave everything turned off.
-#endif
-    } else {
-        // The docs suggest this is only necessary for earlier chips
-        // (e.g., not Skylake). Intel vol3 section 10.5.1 "Local Vector Table".
-        // However, this is needed for at least Skylake too (at least when
-        // Freeze-On-PMI is off).
-        apic_pmi_unmask();
-
-#if !TRY_FREEZE_ON_PMI
-        // This is the last thing we do: Once we do this the counters
-        // will start counting again.
-        write_msr(IA32_PERF_GLOBAL_CTRL, state->global_ctrl);
-#endif
-    }
-}
diff --git a/kernel/arch/x86/proc_trace.cpp b/kernel/arch/x86/proc_trace.cpp
deleted file mode 100644
index e92dc08..0000000
--- a/kernel/arch/x86/proc_trace.cpp
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-// TODO(ZX-992): Need to be able to r/w MSRs.
-// The thought is to use resources (as in ResourceDispatcher), at which point
-// this will all get rewritten. Until such time, the goal here is KISS.
-// This file contains the lower part of Intel Processor Trace support that must
-// be done in the kernel (so that we can read/write msrs).
-// The userspace driver is in system/dev/misc/cpu-trace/intel-pt.c.
-//
-// We currently only support Table of Physical Addresses mode:
-// it supports discontiguous buffers and supports stop-on-full behavior
-// in addition to wrap-around.
-//
-// IPT tracing has two "modes":
-// - per-cpu tracing
-// - thread-specific tracing
-// Tracing can only be done in one mode at a time. This is because saving/
-// restoring thread PT state via the xsaves/xrstors instructions is a global
-// flag in the XSS msr.
-// Plus once a trace has been done with IPT_TRACE_THREADS one cannot go back
-// to IPT_TRACE_CPUS: supporting this requires flushing trace state from all
-// threads which is a bit of work. For now it's easy enough to just require
-// the user to reboot. ZX-892
-
-#include <arch/arch_ops.h>
-#include <arch/mmu.h>
-#include <arch/x86.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/proc_trace.h>
-#include <err.h>
-#include <fbl/auto_lock.h>
-#include <fbl/macros.h>
-#include <fbl/mutex.h>
-#include <ktl/unique_ptr.h>
-#include <kernel/mp.h>
-#include <kernel/thread.h>
-#include <lib/ktrace.h>
-#include <pow2.h>
-#include <string.h>
-#include <trace.h>
-#include <vm/vm.h>
-#include <vm/vm_aspace.h>
-#include <lib/zircon-internal/device/cpu-trace/intel-pt.h>
-#include <lib/zircon-internal/ktrace.h>
-#include <lib/zircon-internal/mtrace.h>
-#include <zircon/thread_annotations.h>
-#include <zircon/types.h>
-
-using fbl::AutoLock;
-
-#define LOCAL_TRACE 0
-
-// Control MSRs
-#define IA32_RTIT_OUTPUT_BASE 0x560
-#define IA32_RTIT_OUTPUT_MASK_PTRS 0x561
-#define IA32_RTIT_CTL 0x570
-#define IA32_RTIT_STATUS 0x571
-#define IA32_RTIT_CR3_MATCH 0x572
-#define IA32_RTIT_ADDR0_A 0x580
-#define IA32_RTIT_ADDR0_B 0x581
-#define IA32_RTIT_ADDR1_A 0x582
-#define IA32_RTIT_ADDR1_B 0x583
-#define IA32_RTIT_ADDR2_A 0x584
-#define IA32_RTIT_ADDR2_B 0x585
-#define IA32_RTIT_ADDR3_A 0x586
-#define IA32_RTIT_ADDR3_B 0x587
-
-// We need bits[15:8] to get the "maximum non-turbo ratio".
-// See libipt:intel-pt.h:pt_config, and Intel Vol. 3 chapter 35.5.
-#define IA32_PLATFORM_INFO 0xce
-
-// Our own copy of what h/w supports, mostly for sanity checking.
-static bool supports_pt = false;
-static bool supports_cr3_filtering = false;
-static bool supports_psb = false;
-static bool supports_ip_filtering = false;
-static bool supports_mtc = false;
-static bool supports_ptwrite = false;
-static bool supports_power_events = false;
-static bool supports_output_topa = false;
-static bool supports_output_topa_multi = false;
-static bool supports_output_single = false;
-static bool supports_output_transport = false;
-
-struct ipt_trace_state_t {
-    uint64_t ctl;
-    uint64_t status;
-    uint64_t output_base;
-    uint64_t output_mask_ptrs;
-    uint64_t cr3_match;
-    struct {
-        uint64_t a, b;
-    } addr_ranges[IPT_MAX_NUM_ADDR_RANGES];
-};
-
-static fbl::Mutex ipt_lock;
-
-static ipt_trace_state_t* ipt_trace_state TA_GUARDED(ipt_lock);
-
-static bool active TA_GUARDED(ipt_lock) = false;
-
-static ipt_trace_mode_t trace_mode TA_GUARDED(ipt_lock) = IPT_TRACE_CPUS;
-
-// In cpu mode this arch_max_num_cpus.
-// In thread mode this is provided by the user.
-static uint32_t ipt_num_traces TA_GUARDED(ipt_lock);
-
-void x86_processor_trace_init(void) {
-    if (!x86_feature_test(X86_FEATURE_PT)) {
-        return;
-    }
-
-    struct cpuid_leaf leaf;
-    if (!x86_get_cpuid_subleaf(X86_CPUID_PT, 0, &leaf)) {
-        return;
-    }
-
-    supports_pt = true;
-
-    // Keep our own copy of these flags, mostly for potential sanity checks.
-    supports_cr3_filtering = !!(leaf.b & (1 << 0));
-    supports_psb = !!(leaf.b & (1 << 1));
-    supports_ip_filtering = !!(leaf.b & (1 << 2));
-    supports_mtc = !!(leaf.b & (1 << 3));
-    supports_ptwrite = !!(leaf.b & (1 << 4));
-    supports_power_events = !!(leaf.b & (1 << 5));
-
-    supports_output_topa = !!(leaf.c & (1 << 0));
-    supports_output_topa_multi = !!(leaf.c & (1 << 1));
-    supports_output_single = !!(leaf.c & (1 << 2));
-    supports_output_transport = !!(leaf.c & (1 << 3));
-}
-
-// Intel Processor Trace support needs to be able to map cr3 values that
-// appear in the trace to pids that ld.so uses to dump memory maps.
-void arch_trace_process_create(uint64_t pid, paddr_t pt_phys) {
-    // The cr3 value that appears in Intel PT h/w tracing.
-    uint64_t cr3 = pt_phys;
-    ktrace(TAG_IPT_PROCESS_CREATE, (uint32_t)pid, (uint32_t)(pid >> 32),
-           (uint32_t)cr3, (uint32_t)(cr3 >> 32));
-}
-
-// Worker for x86_ipt_alloc_trace to be executed on all cpus.
-// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
-static void x86_ipt_set_mode_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
-    DEBUG_ASSERT(arch_ints_disabled());
-    DEBUG_ASSERT(!active);
-
-    // When changing modes make sure all PT MSRs are in the init state.
-    // We don't want a value to appear in the xsave buffer and have xrstors
-    // #gp because XCOMP_BV has the PT bit set that's not set in XSS.
-    // We still need to do this, even with ZX-892, when transitioning
-    // from IPT_TRACE_CPUS to IPT_TRACE_THREADS.
-    write_msr(IA32_RTIT_CTL, 0);
-    write_msr(IA32_RTIT_STATUS, 0);
-    write_msr(IA32_RTIT_OUTPUT_BASE, 0);
-    write_msr(IA32_RTIT_OUTPUT_MASK_PTRS, 0);
-    if (supports_cr3_filtering)
-        write_msr(IA32_RTIT_CR3_MATCH, 0);
-    // TODO(dje): addr range msrs
-
-    ipt_trace_mode_t new_mode = static_cast<ipt_trace_mode_t>(reinterpret_cast<uintptr_t>(raw_context));
-
-    // PT state saving, if supported, was enabled during boot so there's no
-    // need to recalculate the xsave space needed.
-    x86_set_extended_register_pt_state(new_mode == IPT_TRACE_THREADS);
-}
-
-zx_status_t x86_ipt_alloc_trace(ipt_trace_mode_t mode, uint32_t num_traces) {
-    AutoLock al(&ipt_lock);
-
-    DEBUG_ASSERT(mode == IPT_TRACE_CPUS || mode == IPT_TRACE_THREADS);
-    if (mode == IPT_TRACE_CPUS) {
-        if (num_traces != arch_max_num_cpus())
-            return ZX_ERR_INVALID_ARGS;
-    } else {
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-
-    if (!supports_pt)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (active)
-        return ZX_ERR_BAD_STATE;
-    if (ipt_trace_state)
-        return ZX_ERR_BAD_STATE;
-
-    // ZX-892: We don't support changing the mode from IPT_TRACE_THREADS to
-    // IPT_TRACE_CPUS: We can't turn off XSS.PT until we're sure all threads
-    // have no PT state, and that's too tricky to do right now. Instead,
-    // require the developer to reboot.
-    if (trace_mode == IPT_TRACE_THREADS && mode == IPT_TRACE_CPUS)
-        return ZX_ERR_NOT_SUPPORTED;
-
-    ipt_trace_state =
-        reinterpret_cast<ipt_trace_state_t*>(calloc(num_traces,
-                                                    sizeof(*ipt_trace_state)));
-    if (!ipt_trace_state)
-        return ZX_ERR_NO_MEMORY;
-
-    mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_ipt_set_mode_task,
-                 reinterpret_cast<void*>(static_cast<uintptr_t>(mode)));
-
-    trace_mode = mode;
-    ipt_num_traces = num_traces;
-    return ZX_OK;
-}
-
-// Free resources obtained by x86_ipt_alloc_trace().
-// This doesn't care if resources have already been freed to save callers
-// from having to care during any cleanup.
-
-zx_status_t x86_ipt_free_trace() {
-    AutoLock al(&ipt_lock);
-
-    if (!supports_pt)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (trace_mode == IPT_TRACE_THREADS)
-        return ZX_ERR_BAD_STATE;
-    if (active)
-        return ZX_ERR_BAD_STATE;
-
-    free(ipt_trace_state);
-    ipt_trace_state = nullptr;
-    return ZX_OK;
-}
-
-// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
-static void x86_ipt_start_cpu_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
-    DEBUG_ASSERT(arch_ints_disabled());
-    DEBUG_ASSERT(active && raw_context);
-
-    ipt_trace_state_t* context = reinterpret_cast<ipt_trace_state_t*>(raw_context);
-    uint32_t cpu = arch_curr_cpu_num();
-    ipt_trace_state_t* state = &context[cpu];
-
-    DEBUG_ASSERT(!(read_msr(IA32_RTIT_CTL) & IPT_CTL_TRACE_EN_MASK));
-
-    // Load the ToPA configuration
-    write_msr(IA32_RTIT_OUTPUT_BASE, state->output_base);
-    write_msr(IA32_RTIT_OUTPUT_MASK_PTRS, state->output_mask_ptrs);
-
-    // Load all other msrs, prior to enabling tracing.
-    write_msr(IA32_RTIT_STATUS, state->status);
-    if (supports_cr3_filtering)
-        write_msr(IA32_RTIT_CR3_MATCH, state->cr3_match);
-
-    // Enable the trace
-    write_msr(IA32_RTIT_CTL, state->ctl);
-}
-
-// Begin the trace.
-
-zx_status_t x86_ipt_start() {
-    AutoLock al(&ipt_lock);
-
-    if (!supports_pt)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (trace_mode == IPT_TRACE_THREADS)
-        return ZX_ERR_BAD_STATE;
-    if (active)
-        return ZX_ERR_BAD_STATE;
-    if (!ipt_trace_state)
-        return ZX_ERR_BAD_STATE;
-
-    uint64_t kernel_cr3 = x86_kernel_cr3();
-    TRACEF("Starting processor trace, kernel cr3: 0x%" PRIxPTR "\n",
-           kernel_cr3);
-
-    if (LOCAL_TRACE && trace_mode == IPT_TRACE_CPUS) {
-        uint32_t num_cpus = ipt_num_traces;
-        for (uint32_t cpu = 0; cpu < num_cpus; ++cpu) {
-            TRACEF("Cpu %u: ctl 0x%" PRIx64 ", status 0x%" PRIx64 ", base 0x%" PRIx64 ", mask 0x%" PRIx64 "\n",
-                   cpu, ipt_trace_state[cpu].ctl, ipt_trace_state[cpu].status,
-                   ipt_trace_state[cpu].output_base,
-                   ipt_trace_state[cpu].output_mask_ptrs);
-        }
-    }
-
-    active = true;
-
-    // Sideband info needed by the trace reader.
-    uint64_t platform_msr = read_msr(IA32_PLATFORM_INFO);
-    unsigned nom_freq = (platform_msr >> 8) & 0xff;
-    ktrace(TAG_IPT_START, (uint32_t)nom_freq, 0,
-           (uint32_t)kernel_cr3, (uint32_t)(kernel_cr3 >> 32));
-    const struct x86_model_info* model_info = x86_get_model();
-    ktrace(TAG_IPT_CPU_INFO, model_info->processor_type,
-           model_info->display_family, model_info->display_model,
-           model_info->stepping);
-
-    if (trace_mode == IPT_TRACE_CPUS) {
-        mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_ipt_start_cpu_task, ipt_trace_state);
-    }
-
-    return ZX_OK;
-}
-
-// This is invoked via mp_sync_exec which thread safety analysis cannot follow.
-static void x86_ipt_stop_cpu_task(void* raw_context) TA_NO_THREAD_SAFETY_ANALYSIS {
-    DEBUG_ASSERT(arch_ints_disabled());
-    DEBUG_ASSERT(raw_context);
-
-    ipt_trace_state_t* context = reinterpret_cast<ipt_trace_state_t*>(raw_context);
-    uint32_t cpu = arch_curr_cpu_num();
-    ipt_trace_state_t* state = &context[cpu];
-
-    // Disable the trace
-    write_msr(IA32_RTIT_CTL, 0);
-
-    // Retrieve msr values for later providing to userspace
-    state->ctl = 0;
-    state->status = read_msr(IA32_RTIT_STATUS);
-    state->output_base = read_msr(IA32_RTIT_OUTPUT_BASE);
-    state->output_mask_ptrs = read_msr(IA32_RTIT_OUTPUT_MASK_PTRS);
-
-    // Zero all MSRs so that we are in the XSAVE initial configuration.
-    // This allows h/w to do some optimizations regarding the state.
-    write_msr(IA32_RTIT_STATUS, 0);
-    write_msr(IA32_RTIT_OUTPUT_BASE, 0);
-    write_msr(IA32_RTIT_OUTPUT_MASK_PTRS, 0);
-    if (supports_cr3_filtering)
-        write_msr(IA32_RTIT_CR3_MATCH, 0);
-
-    // TODO(dje): Make it explicit that packets have been completely written.
-    // See Intel Vol 3 chapter 36.2.4.
-
-    // TODO(teisenbe): Clear ADDR* MSRs depending on leaf 1
-}
-
-// This can be called while not active, so the caller doesn't have to care
-// during any cleanup.
-
-zx_status_t x86_ipt_stop() {
-    AutoLock al(&ipt_lock);
-
-    if (!supports_pt)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (trace_mode == IPT_TRACE_THREADS)
-        return ZX_ERR_BAD_STATE;
-    if (!ipt_trace_state)
-        return ZX_ERR_BAD_STATE;
-
-    TRACEF("Stopping processor trace\n");
-
-    if (trace_mode == IPT_TRACE_CPUS) {
-        mp_sync_exec(MP_IPI_TARGET_ALL, 0, x86_ipt_stop_cpu_task, ipt_trace_state);
-    }
-
-    ktrace(TAG_IPT_STOP, 0, 0, 0, 0);
-    active = false;
-
-    if (LOCAL_TRACE && trace_mode == IPT_TRACE_CPUS) {
-        uint32_t num_cpus = ipt_num_traces;
-        for (uint32_t cpu = 0; cpu < num_cpus; ++cpu) {
-            TRACEF("Cpu %u: ctl 0x%" PRIx64 ", status 0x%" PRIx64 ", base 0x%" PRIx64 ", mask 0x%" PRIx64 "\n",
-                   cpu, ipt_trace_state[cpu].ctl, ipt_trace_state[cpu].status,
-                   ipt_trace_state[cpu].output_base,
-                   ipt_trace_state[cpu].output_mask_ptrs);
-        }
-    }
-
-    return ZX_OK;
-}
-
-zx_status_t x86_ipt_stage_trace_data(zx_itrace_buffer_descriptor_t descriptor,
-                                     const zx_x86_pt_regs_t* regs) {
-    AutoLock al(&ipt_lock);
-
-    if (!supports_pt)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (trace_mode == IPT_TRACE_CPUS && active)
-        return ZX_ERR_BAD_STATE;
-    if (!ipt_trace_state)
-        return ZX_ERR_BAD_STATE;
-    if (descriptor >= ipt_num_traces)
-        return ZX_ERR_INVALID_ARGS;
-
-    ipt_trace_state[descriptor].ctl = regs->ctl;
-    ipt_trace_state[descriptor].status = regs->status;
-    ipt_trace_state[descriptor].output_base = regs->output_base;
-    ipt_trace_state[descriptor].output_mask_ptrs = regs->output_mask_ptrs;
-    ipt_trace_state[descriptor].cr3_match = regs->cr3_match;
-    static_assert(sizeof(ipt_trace_state[descriptor].addr_ranges) == sizeof(regs->addr_ranges), "addr_ranges size mismatch");
-    memcpy(ipt_trace_state[descriptor].addr_ranges, regs->addr_ranges, sizeof(regs->addr_ranges));
-
-    return ZX_OK;
-}
-
-zx_status_t x86_ipt_get_trace_data(zx_itrace_buffer_descriptor_t descriptor,
-                                   zx_x86_pt_regs_t* regs) {
-    AutoLock al(&ipt_lock);
-
-    if (!supports_pt)
-        return ZX_ERR_NOT_SUPPORTED;
-    if (trace_mode == IPT_TRACE_CPUS && active)
-        return ZX_ERR_BAD_STATE;
-    if (!ipt_trace_state)
-        return ZX_ERR_BAD_STATE;
-    if (descriptor >= ipt_num_traces)
-        return ZX_ERR_INVALID_ARGS;
-
-    regs->ctl = ipt_trace_state[descriptor].ctl;
-    regs->status = ipt_trace_state[descriptor].status;
-    regs->output_base = ipt_trace_state[descriptor].output_base;
-    regs->output_mask_ptrs = ipt_trace_state[descriptor].output_mask_ptrs;
-    regs->cr3_match = ipt_trace_state[descriptor].cr3_match;
-    static_assert(sizeof(regs->addr_ranges) == sizeof(ipt_trace_state[descriptor].addr_ranges), "addr_ranges size mismatch");
-    memcpy(regs->addr_ranges, ipt_trace_state[descriptor].addr_ranges, sizeof(regs->addr_ranges));
-
-    return ZX_OK;
-}
diff --git a/kernel/arch/x86/pvclock.cpp b/kernel/arch/x86/pvclock.cpp
deleted file mode 100644
index 43195b9..0000000
--- a/kernel/arch/x86/pvclock.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/ops.h>
-#include <arch/x86.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/pvclock.h>
-#include <kernel/atomic.h>
-#include <vm/physmap.h>
-#include <vm/pmm.h>
-
-static volatile struct pvclock_boot_time* boot_time = nullptr;
-static volatile struct pvclock_system_time* system_time = nullptr;
-
-static constexpr uint64_t kSystemTimeEnable = 1u;
-
-zx_status_t pvclock_init(void) {
-    if (boot_time != nullptr || system_time != nullptr) {
-        return ZX_ERR_BAD_STATE;
-    }
-
-    paddr_t pa;
-    zx_status_t status = pmm_alloc_page(0, &pa);
-    if (status != ZX_OK) {
-        return status;
-    }
-    arch_zero_page(paddr_to_physmap(pa));
-    boot_time = static_cast<struct pvclock_boot_time*>(paddr_to_physmap(pa));
-    write_msr(kKvmBootTime, pa);
-
-    status = pmm_alloc_page(0, &pa);
-    if (status != ZX_OK) {
-        return status;
-    }
-    arch_zero_page(paddr_to_physmap(pa));
-    system_time = static_cast<struct pvclock_system_time*>(paddr_to_physmap(pa));
-    write_msr(kKvmSystemTimeMsr, pa | kSystemTimeEnable);
-
-    return ZX_OK;
-}
-
-bool pvclock_is_present(void) {
-    if (x86_hypervisor != X86_HYPERVISOR_KVM) {
-        return false;
-    }
-    uint32_t a, ignored;
-    cpuid(X86_CPUID_KVM_FEATURES, &a, &ignored, &ignored, &ignored);
-    if (a & kKvmFeatureClockSource) {
-        return true;
-    }
-    return false;
-}
-
-bool pvclock_is_stable() {
-    bool is_stable = (system_time->flags & kKvmSystemTimeStable) ||
-                     x86_feature_test(X86_FEATURE_KVM_PVCLOCK_STABLE);
-    printf("pvclock: Clocksource is %sstable\n", (is_stable ? "" : "not "));
-    return is_stable;
-}
-
-uint64_t pvclock_get_tsc_freq() {
-    printf("pvclock: Fetching TSC frequency\n");
-    uint32_t tsc_mul = 0;
-    int8_t tsc_shift = 0;
-    uint32_t pre_version = 0, post_version = 0;
-    do {
-        pre_version = atomic_load_u32(&system_time->version);
-        if (pre_version % 2 != 0) {
-            arch_spinloop_pause();
-            continue;
-        }
-        tsc_mul = system_time->tsc_mul;
-        tsc_shift = system_time->tsc_shift;
-        post_version = atomic_load_u32(&system_time->version);
-    } while (pre_version != post_version);
-
-    uint64_t tsc_khz = 1000000ULL << 32;
-    tsc_khz = tsc_khz / tsc_mul;
-    if (tsc_shift > 0) {
-        tsc_khz >>= tsc_shift;
-    } else {
-        tsc_khz <<= -tsc_shift;
-    }
-    return tsc_khz * 1000;
-}
diff --git a/kernel/arch/x86/registers.cpp b/kernel/arch/x86/registers.cpp
deleted file mode 100644
index 13378dd..0000000
--- a/kernel/arch/x86/registers.cpp
+++ /dev/null
@@ -1,739 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-/****************************************************************************
- * This file handles detection of supported extended register saving
- * mechanisms.  Of the ones detected, the following is our preference for
- * mechanisms, from best to worst:
- *
- * 1) XSAVES (performs modified+init optimizations, uses compressed register
- *            form, and can save supervisor-only registers)
- * 2) XSAVEOPT (performs modified+init optimizations)
- * 3) XSAVE (no optimizations/compression, but can save all supported extended
- *           registers)
- * 4) FXSAVE (can only save FPU/SSE registers)
- * 5) none (will not save any extended registers, will not allow enabling
- *          features that use extended registers.)
- ****************************************************************************/
-
-#include <arch/ops.h>
-#include <arch/x86.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/mp.h>
-#include <arch/x86/proc_trace.h>
-#include <arch/x86/registers.h>
-#include <fbl/auto_call.h>
-#include <inttypes.h>
-#include <kernel/auto_lock.h>
-#include <kernel/spinlock.h>
-#include <kernel/thread.h>
-#include <string.h>
-#include <trace.h>
-#include <vm/vm.h>
-#include <zircon/compiler.h>
-
-#define LOCAL_TRACE 0
-
-#define IA32_XSS_MSR 0xDA0
-
-// Offset in xsave area that components >= 2 start at.
-#define XSAVE_EXTENDED_AREA_OFFSET 576
-
-// The first xsave component in the extended (non-legacy) area.
-#define XSAVE_FIRST_EXT_COMPONENT 2
-
-// Number of possible components in the state vector.
-#define XSAVE_MAX_COMPONENTS 63
-
-// Bit in XCOMP_BV field of xsave indicating compacted format.
-#define XSAVE_XCOMP_BV_COMPACT (1ULL << 63)
-
-static void fxsave(void* register_state);
-static void fxrstor(void* register_state);
-static void xrstor(void* register_state, uint64_t feature_mask);
-static void xrstors(void* register_state, uint64_t feature_mask);
-static void xsave(void* register_state, uint64_t feature_mask);
-static void xsaveopt(void* register_state, uint64_t feature_mask);
-static void xsaves(void* register_state, uint64_t feature_mask);
-
-static void read_xsave_state_info(void);
-static void recompute_state_size(void);
-
-// Indexed by component. Components 0 and 1 are the "legacy" floating point and
-// SSE ones. These do not have a size or align64 set in this structure since
-// they are inside the legacy xsave area. Use XSAVE_FIRST_EXT_COMPONENT for
-// the first valid entry.
-static struct {
-    // Total size of this component in bytes.
-    uint32_t size;
-
-    // If true, this component must be aligned to a 64-byte boundary.
-    bool align64;
-} state_components[XSAVE_MAX_COMPONENTS];
-
-/* Supported bits in XCR0 (each corresponds to a state component) */
-static uint64_t xcr0_component_bitmap = 0;
-/* Supported bits in IA32_XSS (each corresponds to a state component) */
-static uint64_t xss_component_bitmap = 0;
-/* Maximum total size for xsave, if all features are enabled */
-static size_t xsave_max_area_size = 0;
-/* Does this processor support the XSAVES instruction */
-static bool xsaves_supported = false;
-/* Does this processor support the XSAVEOPT instruction */
-static bool xsaveopt_supported = false;
-/* Does this processor support the XGETBV instruction with ecx=1 */
-static bool xgetbv_1_supported = false;
-/* Does this processor support the XSAVE instruction */
-static bool xsave_supported = false;
-/* Does this processor support FXSAVE */
-static bool fxsave_supported = false;
-/* Maximum register state size */
-static size_t register_state_size = 0;
-/* Spinlock to guard register state size changes */
-static SpinLock state_lock;
-
-/* For FXRSTOR, we need 512 bytes to save the state.  For XSAVE-based
- * mechanisms, we only need 512 + 64 bytes for the initial state, since
- * our initial state only needs to specify some SSE state (masking exceptions),
- * and XSAVE doesn't require space for any disabled register groups after
- * the last enabled one. */
-static uint8_t __ALIGNED(64)
-    extended_register_init_state[512 + 64] = {0};
-
-static_assert(sizeof(x86_xsave_legacy_area) == 416, "Size of legacy xsave area should match spec.");
-
-/* Format described in Intel 3A section 13.4 */
-struct xsave_area {
-    // Always valid, even when using the older fxsave.
-    x86_xsave_legacy_area legacy;
-
-    uint8_t reserved1[96];
-
-    // The xsave header. It and the extended regions are only valid when using xsave, not fxsave.
-    uint64_t xstate_bv;
-    uint64_t xcomp_bv;
-    uint8_t reserved2[48];
-
-    uint8_t extended_region[];
-} __PACKED;
-static_assert(offsetof(xsave_area, extended_region) == XSAVE_EXTENDED_AREA_OFFSET,
-              "xsave_area format should match CPU spec.");
-
-static void x86_extended_register_cpu_init(void) {
-    if (likely(xsave_supported)) {
-        ulong cr4 = x86_get_cr4();
-        /* Enable XSAVE feature set */
-        x86_set_cr4(cr4 | X86_CR4_OSXSAVE);
-        /* Put xcr0 into a known state (X87 must be enabled in this register) */
-        x86_xsetbv(0, X86_XSAVE_STATE_BIT_X87);
-    }
-
-    /* Enable the FPU */
-    __UNUSED bool enabled = x86_extended_register_enable_feature(
-        X86_EXTENDED_REGISTER_X87);
-    DEBUG_ASSERT(enabled);
-}
-
-// Sets the portions of the xsave legacy area such that the x87 state is considered in its "initial
-// configuration" as defined by Intel Vol 1 section 13.6.
-//
-// "The x87 state component comprises bytes 23:0 and bytes 159:32." This doesn't count the MXCSR
-// register.
-static void set_x87_initial_state(x86_xsave_legacy_area* legacy_area) {
-    legacy_area->fcw = 0x037f;
-    legacy_area->fsw = 0;
-    // The initial value of the FTW register is 0xffff. The FTW field in the xsave area is an
-    // abbreviated version (see Intel manual sec 13.5.1). In the FTW register 1 bits indicate
-    // the empty tag (two per register), while the abbreviated version uses 1 bit per register and
-    // 0 indicates empty. So set to 0 to indicate all registers are empty.
-    legacy_area->ftw = 0;
-    legacy_area->fop = 0;
-    legacy_area->fip = 0;
-    legacy_area->fdp = 0;
-
-    // Register values are all 0.
-    constexpr size_t fp_reg_size = sizeof(legacy_area->st);
-    static_assert(fp_reg_size == 128, "Struct size is wrong");
-    memset(&legacy_area->st[0], 0, fp_reg_size);
-}
-
-// SSE state is only the XMM registers which is all 0 and does not count MXCSR as defined by Intel
-// Vol 1 section 13.6.
-static void set_sse_initial_state(x86_xsave_legacy_area* legacy_area) {
-    constexpr size_t sse_reg_size = sizeof(legacy_area->xmm);
-    static_assert(sse_reg_size == 256, "Struct size is wrong");
-    memset(&legacy_area->xmm[0], 0, sse_reg_size);
-}
-
-/* Figure out what forms of register saving this machine supports and
- * select the best one */
-void x86_extended_register_init(void) {
-    /* Have we already read the cpu support info */
-    static bool info_initialized = false;
-    bool initialized_cpu_already = false;
-
-    if (!info_initialized) {
-        DEBUG_ASSERT(arch_curr_cpu_num() == 0);
-
-        read_xsave_state_info();
-        info_initialized = true;
-
-        /* We currently assume that if xsave isn't support fxsave is */
-        fxsave_supported = x86_feature_test(X86_FEATURE_FXSR);
-
-        /* Set up initial states */
-        if (likely(fxsave_supported || xsave_supported)) {
-            x86_extended_register_cpu_init();
-            initialized_cpu_already = true;
-
-            // Intel Vol 3 section 13.5.4 describes the XSAVE initialization. The only change we
-            // want to make to the init state is having SIMD exceptions masked. The "legacy" area
-            // of the xsave structure is valid for fxsave as well.
-            xsave_area* area = reinterpret_cast<xsave_area*>(extended_register_init_state);
-            set_x87_initial_state(&area->legacy);
-            set_sse_initial_state(&area->legacy);
-            area->legacy.mxcsr = 0x3f << 7;
-
-            if (xsave_supported) {
-                area->xstate_bv |= X86_XSAVE_STATE_BIT_SSE;
-
-                /* If xsaves is being used, then make the saved state be in
-                 * compact form.  xrstors will GPF if it is not. */
-                if (xsaves_supported) {
-                    area->xcomp_bv |= XSAVE_XCOMP_BV_COMPACT;
-                    area->xcomp_bv |= area->xstate_bv;
-                }
-            }
-        }
-
-        if (likely(xsave_supported)) {
-            recompute_state_size();
-        } else if (fxsave_supported) {
-            register_state_size = 512;
-        }
-    }
-    /* Ensure that xsaves_supported == true implies xsave_supported == true */
-    DEBUG_ASSERT(!xsaves_supported || xsave_supported);
-    /* Ensure that xsaveopt_supported == true implies xsave_supported == true */
-    DEBUG_ASSERT(!xsaveopt_supported || xsave_supported);
-
-    if (!initialized_cpu_already) {
-        x86_extended_register_cpu_init();
-    }
-}
-
-bool x86_extended_register_enable_feature(
-    enum x86_extended_register_feature feature) {
-    /* We currently assume this is only called during initialization.
-     * We rely on interrupts being disabled so xgetbv/xsetbv will not be
-     * racey */
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    switch (feature) {
-    case X86_EXTENDED_REGISTER_X87: {
-        if (unlikely(!x86_feature_test(X86_FEATURE_FPU) ||
-                     (!fxsave_supported && !xsave_supported))) {
-            return false;
-        }
-
-        /* No x87 emul, monitor co-processor */
-        ulong cr0 = x86_get_cr0();
-        cr0 &= ~X86_CR0_EM;
-        cr0 |= X86_CR0_NE;
-        cr0 |= X86_CR0_MP;
-        x86_set_cr0(cr0);
-
-        /* Init x87, starts with exceptions masked */
-        __asm__ __volatile__("finit"
-                             :
-                             :
-                             : "memory");
-
-        if (likely(xsave_supported)) {
-            x86_xsetbv(0, x86_xgetbv(0) | X86_XSAVE_STATE_BIT_X87);
-        }
-        break;
-    }
-    case X86_EXTENDED_REGISTER_SSE: {
-        if (unlikely(
-                !x86_feature_test(X86_FEATURE_SSE) ||
-                !x86_feature_test(X86_FEATURE_FXSR))) {
-
-            return false;
-        }
-
-        /* Init SSE */
-        ulong cr4 = x86_get_cr4();
-        cr4 |= X86_CR4_OSXMMEXPT;
-        cr4 |= X86_CR4_OSFXSR;
-        x86_set_cr4(cr4);
-
-        /* mask all exceptions */
-        uint32_t mxcsr = 0;
-        __asm__ __volatile__("stmxcsr %0"
-                             : "=m"(mxcsr));
-        mxcsr = (0x3f << 7);
-        __asm__ __volatile__("ldmxcsr %0"
-                             :
-                             : "m"(mxcsr));
-
-        if (likely(xsave_supported)) {
-            x86_xsetbv(0, x86_xgetbv(0) | X86_XSAVE_STATE_BIT_SSE);
-        }
-        break;
-    }
-    case X86_EXTENDED_REGISTER_AVX: {
-        if (!xsave_supported ||
-            !(xcr0_component_bitmap & X86_XSAVE_STATE_BIT_AVX)) {
-            return false;
-        }
-
-        /* Enable SIMD exceptions */
-        ulong cr4 = x86_get_cr4();
-        cr4 |= X86_CR4_OSXMMEXPT;
-        x86_set_cr4(cr4);
-
-        x86_xsetbv(0, x86_xgetbv(0) | X86_XSAVE_STATE_BIT_AVX);
-        break;
-    }
-    case X86_EXTENDED_REGISTER_MPX: {
-        /* Currently unsupported */
-        return false;
-    }
-    case X86_EXTENDED_REGISTER_AVX512: {
-        const uint64_t xsave_avx512 =
-            X86_XSAVE_STATE_BIT_AVX512_OPMASK |
-            X86_XSAVE_STATE_BIT_AVX512_LOWERZMM_HIGH |
-            X86_XSAVE_STATE_BIT_AVX512_HIGHERZMM;
-
-        if (!xsave_supported ||
-            (xcr0_component_bitmap & xsave_avx512) != xsave_avx512) {
-            return false;
-        }
-        x86_xsetbv(0, x86_xgetbv(0) | xsave_avx512);
-        break;
-    }
-    case X86_EXTENDED_REGISTER_PT: {
-        if (!xsaves_supported ||
-            !(xss_component_bitmap & X86_XSAVE_STATE_BIT_PT)) {
-            return false;
-        }
-        x86_set_extended_register_pt_state(true);
-        break;
-    }
-    case X86_EXTENDED_REGISTER_PKRU: {
-        /* Currently unsupported */
-        return false;
-    }
-    default:
-        return false;
-    }
-
-    recompute_state_size();
-    return true;
-}
-
-size_t x86_extended_register_size(void) {
-    return register_state_size;
-}
-
-void x86_extended_register_init_state(void* register_state) {
-    // Copy the initialization state; this overcopies on systems that fall back
-    // to fxsave, but the buffer is required to be large enough.
-    memcpy(register_state, extended_register_init_state, sizeof(extended_register_init_state));
-}
-
-void x86_extended_register_save_state(void* register_state) {
-    /* The idle threads have no extended register state */
-    if (unlikely(!register_state)) {
-        return;
-    }
-
-    if (xsaves_supported) {
-        xsaves(register_state, ~0ULL);
-    } else if (xsaveopt_supported) {
-        xsaveopt(register_state, ~0ULL);
-    } else if (xsave_supported) {
-        xsave(register_state, ~0ULL);
-    } else if (fxsave_supported) {
-        fxsave(register_state);
-    }
-}
-
-void x86_extended_register_restore_state(void* register_state) {
-    /* The idle threads have no extended register state */
-    if (unlikely(!register_state)) {
-        return;
-    }
-
-    if (xsaves_supported) {
-        xrstors(register_state, ~0ULL);
-    } else if (xsave_supported) {
-        xrstor(register_state, ~0ULL);
-    } else if (fxsave_supported) {
-        fxrstor(register_state);
-    }
-}
-
-void x86_extended_register_context_switch(
-    thread_t* old_thread, thread_t* new_thread) {
-    if (likely(old_thread)) {
-        x86_extended_register_save_state(old_thread->arch.extended_register_state);
-    }
-    x86_extended_register_restore_state(new_thread->arch.extended_register_state);
-}
-
-static void read_xsave_state_info(void) {
-    xsave_supported = x86_feature_test(X86_FEATURE_XSAVE);
-    if (!xsave_supported) {
-        LTRACEF("xsave not supported\n");
-        return;
-    }
-
-    /* if we bail, set everything to unsupported */
-    auto ac = fbl::MakeAutoCall([]() {
-        xsave_supported = false;
-        xsaves_supported = false;
-        xsaveopt_supported = false;
-    });
-
-    /* This procedure is described in Intel Vol 1 section 13.2 */
-
-    /* Read feature support from subleaves 0 and 1 */
-    struct cpuid_leaf leaf;
-    if (!x86_get_cpuid_subleaf(X86_CPUID_XSAVE, 0, &leaf)) {
-        LTRACEF("could not find xsave leaf\n");
-        return;
-    }
-    xcr0_component_bitmap = ((uint64_t)leaf.d << 32) | leaf.a;
-    size_t max_area = XSAVE_EXTENDED_AREA_OFFSET;
-
-    x86_get_cpuid_subleaf(X86_CPUID_XSAVE, 1, &leaf);
-    xgetbv_1_supported = !!(leaf.a & (1 << 2));
-    xsaves_supported = !!(leaf.a & (1 << 3));
-    xsaveopt_supported = !!(leaf.a & (1 << 0));
-    xss_component_bitmap = ((uint64_t)leaf.d << 32) | leaf.c;
-
-    LTRACEF("xcr0 bitmap: %016" PRIx64 "\n", xcr0_component_bitmap);
-    LTRACEF("xss bitmap: %016" PRIx64 "\n", xss_component_bitmap);
-
-    /* Sanity check; all CPUs that support xsave support components 0 and 1 */
-    DEBUG_ASSERT((xcr0_component_bitmap & 0x3) == 0x3);
-    if ((xcr0_component_bitmap & 0x3) != 0x3) {
-        LTRACEF("unexpected xcr0 bitmap %016" PRIx64 "\n",
-                xcr0_component_bitmap);
-        return;
-    }
-
-    /* we're okay from now on out */
-    ac.cancel();
-
-    /* Read info about the state components */
-    for (int i = XSAVE_FIRST_EXT_COMPONENT; i < XSAVE_MAX_COMPONENTS; ++i) {
-        if (!(xcr0_component_bitmap & (1ULL << i)) &&
-            !(xss_component_bitmap & (1ULL << i))) {
-            continue;
-        }
-        x86_get_cpuid_subleaf(X86_CPUID_XSAVE, i, &leaf);
-
-        bool align64 = !!(leaf.c & 0x2);
-
-        state_components[i].size = leaf.a;
-        state_components[i].align64 = align64;
-        LTRACEF("component %d size: %u (xcr0 %d)\n",
-                i, state_components[i].size,
-                !!(xcr0_component_bitmap & (1ULL << i)));
-
-        if (align64) {
-            max_area = ROUNDUP(max_area, 64);
-        }
-        max_area += leaf.a;
-    }
-    xsave_max_area_size = max_area;
-    LTRACEF("total xsave size: %zu\n", max_area);
-
-    return;
-}
-
-static void recompute_state_size(void) {
-    if (!xsave_supported) {
-        return;
-    }
-
-    size_t new_size = 0;
-    /* If we're in a compacted form, compute the total size.  The algorithm
-     * for this is defined in Intel Vol 1 section 13.4.3 */
-    if (xsaves_supported) {
-        new_size = XSAVE_EXTENDED_AREA_OFFSET;
-        uint64_t enabled_features = x86_xgetbv(0) | read_msr(IA32_XSS_MSR);
-        for (int i = XSAVE_FIRST_EXT_COMPONENT; i < XSAVE_MAX_COMPONENTS; ++i) {
-            if (!(enabled_features & (1ULL << i))) {
-                continue;
-            }
-
-            if (state_components[i].align64) {
-                new_size = ROUNDUP(new_size, 64);
-            }
-            new_size += state_components[i].size;
-        }
-    } else {
-        /* Otherwise, use CPUID.(EAX=0xD,ECX=1):EBX, which stores the computed
-         * maximum size required for saving everything specified in XCR0 */
-        struct cpuid_leaf leaf;
-        x86_get_cpuid_subleaf(X86_CPUID_XSAVE, 0, &leaf);
-        new_size = leaf.b;
-    }
-
-    AutoSpinLockNoIrqSave guard(&state_lock);
-    /* Only allow size to increase; all CPUs should converge to the same value,
-     * but for sanity let's keep it monotonically increasing */
-    if (new_size > register_state_size) {
-        register_state_size = new_size;
-        DEBUG_ASSERT(register_state_size <= X86_MAX_EXTENDED_REGISTER_SIZE);
-    }
-}
-
-static void fxsave(void* register_state) {
-    __asm__ __volatile__("fxsave %0"
-                         : "=m"(*(uint8_t*)register_state)
-                         :
-                         : "memory");
-}
-
-static void fxrstor(void* register_state) {
-    __asm__ __volatile__("fxrstor %0"
-                         :
-                         : "m"(*(uint8_t*)register_state)
-                         : "memory");
-}
-
-static void xrstor(void* register_state, uint64_t feature_mask) {
-    __asm__ volatile("xrstor %0"
-                     :
-                     : "m"(*(uint8_t*)register_state),
-                       "d"((uint32_t)(feature_mask >> 32)),
-                       "a"((uint32_t)feature_mask)
-                     : "memory");
-}
-
-static void xrstors(void* register_state, uint64_t feature_mask) {
-    __asm__ volatile("xrstors %0"
-                     :
-                     : "m"(*(uint8_t*)register_state),
-                       "d"((uint32_t)(feature_mask >> 32)),
-                       "a"((uint32_t)feature_mask)
-                     : "memory");
-}
-
-static void xsave(void* register_state, uint64_t feature_mask) {
-    __asm__ volatile("xsave %0"
-                     : "+m"(*(uint8_t*)register_state)
-                     : "d"((uint32_t)(feature_mask >> 32)),
-                       "a"((uint32_t)feature_mask)
-                     : "memory");
-}
-
-static void xsaveopt(void* register_state, uint64_t feature_mask) {
-    __asm__ volatile("xsaveopt %0"
-                     : "+m"(*(uint8_t*)register_state)
-                     : "d"((uint32_t)(feature_mask >> 32)),
-                       "a"((uint32_t)feature_mask)
-                     : "memory");
-}
-
-static void xsaves(void* register_state, uint64_t feature_mask) {
-    __asm__ volatile("xsaves %0"
-                     : "+m"(*(uint8_t*)register_state)
-                     : "d"((uint32_t)(feature_mask >> 32)),
-                       "a"((uint32_t)feature_mask)
-                     : "memory");
-}
-
-uint64_t x86_xgetbv(uint32_t reg) {
-    uint32_t hi, lo;
-    __asm__ volatile("xgetbv"
-                     : "=d"(hi), "=a"(lo)
-                     : "c"(reg)
-                     : "memory");
-    return ((uint64_t)hi << 32) + lo;
-}
-
-void x86_xsetbv(uint32_t reg, uint64_t val) {
-    __asm__ volatile("xsetbv"
-                     :
-                     : "c"(reg), "d"((uint32_t)(val >> 32)), "a"((uint32_t)val)
-                     : "memory");
-}
-
-void* x86_get_extended_register_state_component(void* register_state, uint32_t component,
-                                                bool mark_present, uint32_t* size) {
-    if (component >= XSAVE_MAX_COMPONENTS) {
-        *size = 0;
-        return nullptr;
-    }
-
-    xsave_area* area = reinterpret_cast<xsave_area*>(register_state);
-
-    uint64_t state_component_bit = (1ul << component);
-
-    // Components 0 and 1 are special and are always present in the legacy area.
-    if (component <= 1) {
-        *size = sizeof(x86_xsave_legacy_area);
-        if (!(area->xstate_bv & state_component_bit)) {
-            // Component not written because registers were in the initial configuration. Set it so
-            // the caller sees the correct initial values.
-            if (component == 0) {
-                set_x87_initial_state(&area->legacy);
-            } else {
-                set_sse_initial_state(&area->legacy);
-            }
-            if (mark_present) {
-                area->xstate_bv |= state_component_bit;
-            }
-        }
-
-        return area;
-    }
-
-    if (!(area->xcomp_bv & XSAVE_XCOMP_BV_COMPACT)) {
-        // Standard format. The offset and size are provided by a static CPUID call.
-        cpuid_leaf leaf;
-        x86_get_cpuid_subleaf(X86_CPUID_XSAVE, component, &leaf);
-        *size = leaf.a;
-        if (leaf.a == 0) {
-            return nullptr;
-        }
-        uint8_t* component_begin = static_cast<uint8_t*>(register_state) + leaf.b;
-
-        if (!(area->xstate_bv & state_component_bit)) {
-            // Component not written because it's in the initial state. Write the initial values to
-            // the structure the caller sees the correct data. The initial state of all non-x87
-            // xsave components (x87 is handled above) is all 0's.
-            memset(component_begin, 0, *size);
-            if (mark_present) {
-                area->xstate_bv |= state_component_bit;
-            }
-        }
-        return component_begin;
-    }
-
-    // Compacted format used. The corresponding bit in xcomp_bv indicates whether the component is
-    // present.
-    if (!(area->xcomp_bv & state_component_bit)) {
-        // Currently this doesn't support reading or writing compacted components that aren't
-        // currently marked present. In the future, we may want to add this which will require
-        // rewriting all the following components.
-        *size = 0;
-        return nullptr;
-    }
-
-    // Walk all present components and add up their sizes (optionally aligned up) to get the offset.
-    uint32_t offset = XSAVE_EXTENDED_AREA_OFFSET;
-    for (uint32_t i = XSAVE_FIRST_EXT_COMPONENT; i < component; i++) {
-        if (!(area->xcomp_bv & (1ul << i))) {
-            continue;
-        }
-        if (state_components[i].align64) {
-            offset = ROUNDUP(offset, 64);
-        }
-        offset += state_components[i].size;
-    }
-    if (state_components[component].align64) {
-        offset = ROUNDUP(offset, 64);
-    }
-
-    uint8_t* component_begin = static_cast<uint8_t*>(register_state) + offset;
-    *size = state_components[component].size;
-
-    if (!(area->xstate_bv & state_component_bit)) {
-        // Component not written because it's in the initial state. Write the initial values to
-        // the structure the caller sees the correct data. The initial state of all non-x87
-        // xsave components (x87 is handled above) is all 0's.
-        memset(component_begin, 0, *size);
-        if (mark_present) {
-            area->xstate_bv |= state_component_bit;
-        }
-    }
-    return component_begin;
-}
-
-// Set the extended register PT mode to trace either cpus (!threads)
-// or threads.
-// WARNING: All PT MSRs should be set to init values before changing the mode.
-// See x86_ipt_set_mode_task.
-
-void x86_set_extended_register_pt_state(bool threads) {
-    if (!xsaves_supported || !(xss_component_bitmap & X86_XSAVE_STATE_BIT_PT))
-        return;
-
-    uint64_t xss = read_msr(IA32_XSS_MSR);
-    if (threads)
-        xss |= X86_XSAVE_STATE_BIT_PT;
-    else
-        xss &= ~(0ULL + X86_XSAVE_STATE_BIT_PT);
-    write_msr(IA32_XSS_MSR, xss);
-}
-
-// Debug Registers --------------------------------------------------------------------------------
-
-/* Validates whether this is a valid address to save into a debug register.
- * Will mask out reserved bits to their expected values. */
-bool x86_validate_debug_state(x86_debug_state_t* debug_state) {
-    // Validate the addresses being written.
-    for (size_t i = 0; i < 4; i++) {
-        uint64_t addr = debug_state->dr[i];
-        if (addr != 0 && !is_user_address(addr)) {
-            return false;
-        }
-    }
-
-    // DR6 is not writable from userspace, as it is a debug status registers.
-    // Zircon takes on the job of keeping it up to date.
-
-    // DR7.
-    uint64_t dr7 = debug_state->dr7;
-    debug_state->dr7 = X86_DR7_MASK;
-    uint64_t values_to_write2 = dr7 & X86_DR7_USER_MASK;
-    debug_state->dr7 |= values_to_write2;
-
-    return true;
-}
-
-void x86_read_debug_status(x86_debug_state_t* debug_state) {
-    // NOTE: There is a difference in bit 16 between Intel64 and AMD64.
-    //       In AMD, bit 16 is reserved and always set to 0.
-    //       In Intel, it can mean that an debug or breakpoint exception ocurrred during a RTM
-    //       block. For now, we mask this bit to make both platforms uniform.
-    asm("mov %%dr6, %0" :"=r" (debug_state->dr6));
-    debug_state->dr6 |= X86_DR6_MASK;
-}
-
-void x86_disable_debug_state(void) {
-    // Disabling dr7 is enough to disable the debug functionality.
-    uint64_t zero_val = 0;
-    asm("mov %0, %%dr7" ::"r"(zero_val));
-}
-
-void x86_read_hw_debug_regs(x86_debug_state_t* debug_state) {
-    asm("mov %%dr0, %0" :"=r" (debug_state->dr[0]));
-    asm("mov %%dr1, %0" :"=r" (debug_state->dr[1]));
-    asm("mov %%dr2, %0" :"=r" (debug_state->dr[2]));
-    asm("mov %%dr3, %0" :"=r" (debug_state->dr[3]));
-
-    x86_read_debug_status(debug_state);
-
-    asm("mov %%dr7, %0" :"=r" (debug_state->dr7));
-}
-
-void x86_write_hw_debug_regs(const x86_debug_state_t* debug_state) {
-    asm("mov %0, %%dr0" ::"r"(debug_state->dr[0]));
-    asm("mov %0, %%dr1" ::"r"(debug_state->dr[1]));
-    asm("mov %0, %%dr2" ::"r"(debug_state->dr[2]));
-    asm("mov %0, %%dr3" ::"r"(debug_state->dr[3]));
-    // DR6 is not writable from userspace.
-    // IMPORTANT: DR7 should be already masked at this point by calling x86_validate_debug_state.
-    asm("mov %0, %%dr7" ::"r"(debug_state->dr7));
-}
diff --git a/kernel/arch/x86/rules.mk b/kernel/arch/x86/rules.mk
deleted file mode 100644
index b183c04..0000000
--- a/kernel/arch/x86/rules.mk
+++ /dev/null
@@ -1,154 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-BOOT_HEADER_SIZE ?= 0x50
-KERNEL_LOAD_OFFSET ?= 0x00100000 # 1MB
-KERNEL_BASE ?= 0xffffffff80100000 # has KERNEL_LOAD_OFFSET baked into it
-KERNEL_SIZE ?= 0x40000000 # 1GB
-KERNEL_ASPACE_BASE ?= 0xffffff8000000000UL # -512GB
-KERNEL_ASPACE_SIZE ?= 0x0000008000000000UL
-USER_ASPACE_BASE   ?= 0x0000000001000000UL # 16MB
-# We set the top of user address space to be (1 << 47) - 4k.  See
-# docs/sysret_problem.md for why we subtract 4k here.  Subtracting
-# USER_ASPACE_BASE from that value gives the value for USER_ASPACE_SIZE
-# below.
-USER_ASPACE_SIZE   ?= 0x00007ffffefff000UL
-
-LOCAL_BUILDDIR := $(call TOBUILDDIR,$(LOCAL_DIR))
-
-KERNEL_DEFINES += \
-	ARCH_$(ARCH)=1 \
-	KERNEL_BASE=$(KERNEL_BASE) \
-	KERNEL_SIZE=$(KERNEL_SIZE) \
-	KERNEL_LOAD_OFFSET=$(KERNEL_LOAD_OFFSET)
-
-GLOBAL_DEFINES += \
-	KERNEL_ASPACE_BASE=$(KERNEL_ASPACE_BASE) \
-	KERNEL_ASPACE_SIZE=$(KERNEL_ASPACE_SIZE) \
-	USER_ASPACE_BASE=$(USER_ASPACE_BASE) \
-	USER_ASPACE_SIZE=$(USER_ASPACE_SIZE)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/acpi.S \
-	$(LOCAL_DIR)/arch.cpp \
-	$(LOCAL_DIR)/asm.S \
-	$(LOCAL_DIR)/cache.cpp \
-	$(LOCAL_DIR)/cpu_topology.cpp \
-	$(LOCAL_DIR)/debugger.cpp \
-	$(LOCAL_DIR)/descriptor.cpp \
-	$(LOCAL_DIR)/exceptions.S \
-	$(LOCAL_DIR)/faults.cpp \
-	$(LOCAL_DIR)/feature.cpp \
-	$(LOCAL_DIR)/gdt.S \
-	$(LOCAL_DIR)/hwp.cpp \
-	$(LOCAL_DIR)/idt.cpp \
-	$(LOCAL_DIR)/ioapic.cpp \
-	$(LOCAL_DIR)/ioport.cpp \
-	$(LOCAL_DIR)/lapic.cpp \
-	$(LOCAL_DIR)/mexec.S \
-	$(LOCAL_DIR)/mmu.cpp \
-	$(LOCAL_DIR)/mmu_mem_types.cpp \
-	$(LOCAL_DIR)/mmu_tests.cpp \
-	$(LOCAL_DIR)/mp.cpp \
-	$(LOCAL_DIR)/ops.S \
-	$(LOCAL_DIR)/perf_mon.cpp \
-	$(LOCAL_DIR)/proc_trace.cpp \
-	$(LOCAL_DIR)/pvclock.cpp \
-	$(LOCAL_DIR)/registers.cpp \
-	$(LOCAL_DIR)/start.S \
-	$(LOCAL_DIR)/syscall.S \
-	$(LOCAL_DIR)/thread.cpp \
-	$(LOCAL_DIR)/timer_freq.cpp \
-	$(LOCAL_DIR)/tsc.cpp \
-	$(LOCAL_DIR)/user_copy.S \
-	$(LOCAL_DIR)/user_copy.cpp \
-	$(LOCAL_DIR)/uspace_entry.S \
-
-MODULE_DEPS += \
-	kernel/arch/x86/page_tables \
-	kernel/arch/x86/cpuid \
-	kernel/dev/iommu/dummy \
-	kernel/dev/iommu/intel \
-	kernel/lib/bitmap \
-	kernel/lib/crashlog \
-	kernel/lib/code_patching \
-	kernel/lib/fbl \
-	kernel/object
-
-include $(LOCAL_DIR)/toolchain.mk
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/bootstrap16.cpp \
-	$(LOCAL_DIR)/smp.cpp \
-	$(LOCAL_DIR)/start16.S
-
-# default to 16 cpu max support
-SMP_MAX_CPUS ?= 16
-KERNEL_DEFINES += \
-	SMP_MAX_CPUS=$(SMP_MAX_CPUS)
-
-# set the default toolchain to x86 elf and set a #define
-ifndef TOOLCHAIN_PREFIX
-TOOLCHAIN_PREFIX := $(ARCH_x86_64_TOOLCHAIN_PREFIX)
-endif
-
-#$(warning ARCH_x86_TOOLCHAIN_PREFIX = $(ARCH_x86_TOOLCHAIN_PREFIX))
-#$(warning ARCH_x86_64_TOOLCHAIN_PREFIX = $(ARCH_x86_64_TOOLCHAIN_PREFIX))
-#$(warning TOOLCHAIN_PREFIX = $(TOOLCHAIN_PREFIX))
-
-cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`"; \
-	then echo "$(2)"; else echo "$(3)"; fi ;)
-
-# disable SSP if the compiler supports it; it will break stuff
-GLOBAL_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
-
-# set the default architecture
-GLOBAL_COMPILEFLAGS += -march=x86-64 -mcx16
-
-CLANG_ARCH := x86_64
-ifeq ($(call TOBOOL,$(USE_CLANG)),true)
-GLOBAL_LDFLAGS += -m elf_x86_64
-GLOBAL_MODULE_LDFLAGS += -m elf_x86_64
-endif
-GLOBAL_LDFLAGS += -z max-page-size=4096
-ifeq ($(call TOBOOL,$(USE_CLANG)),false)
-KERNEL_COMPILEFLAGS += -falign-jumps=1 -falign-loops=1 -falign-functions=4
-# Don't over-align data by default, which GCC always did before.
-# Newer binutils complains about over-aligned SHT_NOTE sections.
-GLOBAL_COMPILEFLAGS += -malign-data=abi
-endif
-
-# hard disable floating point in the kernel
-KERNEL_COMPILEFLAGS += -msoft-float -mno-mmx -mno-sse -mno-sse2 -mno-3dnow -mno-avx -mno-avx2
-ifeq ($(call TOBOOL,$(USE_CLANG)),false)
-KERNEL_COMPILEFLAGS += -mno-80387 -mno-fp-ret-in-387
-endif
-
-KERNEL_COMPILEFLAGS += -fPIE -include kernel/include/hidden.h
-KERNEL_COMPILEFLAGS += -mno-red-zone
-
-# Clang needs -mcmodel=kernel to tell it to use the right safe-stack ABI for
-# the kernel.
-ifeq ($(call TOBOOL,$(USE_CLANG)),true)
-KERNEL_COMPILEFLAGS += -mcmodel=kernel
-endif
-
-# optimization: since fpu is disabled, do not pass flag in rax to varargs routines
-# that floating point args are in use.
-ifeq ($(call TOBOOL,$(USE_CLANG)),false)
-KERNEL_COMPILEFLAGS += -mskip-rax-setup
-endif
-
-ifeq ($(call TOBOOL,$(ENABLE_NEW_BOOTDATA)),true)
-MODULE_DEFINES += ENABLE_NEW_BOOTDATA=1
-endif
-
-include make/module.mk
diff --git a/kernel/arch/x86/smp.cpp b/kernel/arch/x86/smp.cpp
deleted file mode 100644
index cff88b4..0000000
--- a/kernel/arch/x86/smp.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <arch/mmu.h>
-#include <arch/x86.h>
-#include <arch/x86/apic.h>
-#include <arch/x86/bootstrap16.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/mmu_mem_types.h>
-#include <arch/x86/mp.h>
-#include <err.h>
-#include <kernel/mp.h>
-#include <kernel/thread.h>
-#include <lk/main.h>
-#include <trace.h>
-#include <vm/vm_aspace.h>
-#include <zircon/types.h>
-
-void x86_init_smp(uint32_t* apic_ids, uint32_t num_cpus) {
-    DEBUG_ASSERT(num_cpus <= UINT8_MAX);
-    zx_status_t status = x86_allocate_ap_structures(apic_ids, (uint8_t)num_cpus);
-    if (status != ZX_OK) {
-        TRACEF("Failed to allocate structures for APs");
-        return;
-    }
-
-    lk_init_secondary_cpus(num_cpus - 1);
-}
-
-static void free_stack_and_thread(thread_t* t) {
-    if (t) {
-        vm_free_kstack(&t->stack);
-        free(t);
-    }
-}
-
-zx_status_t x86_bringup_aps(uint32_t* apic_ids, uint32_t count) {
-    volatile int aps_still_booting = 0;
-    zx_status_t status = ZX_ERR_INTERNAL;
-
-    // if being asked to bring up 0 cpus, move on
-    if (count == 0) {
-        return ZX_OK;
-    }
-
-    // Sanity check the given ids
-    for (uint i = 0; i < count; ++i) {
-        int cpu = x86_apic_id_to_cpu_num(apic_ids[i]);
-        DEBUG_ASSERT(cpu > 0);
-        if (cpu <= 0) {
-            return ZX_ERR_INVALID_ARGS;
-        }
-        if (mp_is_cpu_online(cpu)) {
-            return ZX_ERR_BAD_STATE;
-        }
-        aps_still_booting |= 1U << cpu;
-    }
-
-    struct x86_ap_bootstrap_data* bootstrap_data = nullptr;
-    fbl::RefPtr<VmAspace> bootstrap_aspace;
-    paddr_t bootstrap_instr_ptr;
-    status = x86_bootstrap16_acquire((uintptr_t)_x86_secondary_cpu_long_mode_entry,
-                                     &bootstrap_aspace, (void**)&bootstrap_data,
-                                     &bootstrap_instr_ptr);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    bootstrap_data->cpu_id_counter = 0;
-    bootstrap_data->cpu_waiting_mask = &aps_still_booting;
-    // Zero the kstack list so if we have to bail, we can safely free the
-    // resources.
-    memset(&bootstrap_data->per_cpu, 0, sizeof(bootstrap_data->per_cpu));
-    // Allocate kstacks and threads for all processors
-    for (unsigned int i = 0; i < count; ++i) {
-        thread_t* thread = static_cast<thread_t*>(calloc(1, sizeof(thread_t)));
-        if (!thread) {
-            status = ZX_ERR_NO_MEMORY;
-            goto cleanup_all;
-        }
-
-        status = vm_allocate_kstack(&thread->stack);
-        bootstrap_data->per_cpu[i].kstack_base = thread->stack.base;
-        bootstrap_data->per_cpu[i].thread = thread;
-    }
-
-    // Memory fence to ensure all writes to the bootstrap region are
-    // visible on the APs when they come up
-    smp_mb();
-
-    dprintf(INFO, "booting apic ids: ");
-    for (unsigned int i = 0; i < count; ++i) {
-        uint32_t apic_id = apic_ids[i];
-        dprintf(INFO, "%#x ", apic_id);
-        apic_send_ipi(0, apic_id, DELIVERY_MODE_INIT);
-    }
-    dprintf(INFO, "\n");
-
-    // Wait 10 ms and then send the startup signals
-    thread_sleep_relative(ZX_MSEC(10));
-
-    // Actually send the startups
-    DEBUG_ASSERT(bootstrap_instr_ptr < 1 * MB && IS_PAGE_ALIGNED(bootstrap_instr_ptr));
-    uint8_t vec;
-    vec = static_cast<uint8_t>(bootstrap_instr_ptr >> PAGE_SIZE_SHIFT);
-    // Try up to two times per CPU, as Intel 3A recommends.
-    for (int tries = 0; tries < 2; ++tries) {
-        for (unsigned int i = 0; i < count; ++i) {
-            uint32_t apic_id = apic_ids[i];
-
-            // This will cause the APs to begin executing at
-            // |bootstrap_instr_ptr| in physical memory.
-            apic_send_ipi(vec, apic_id, DELIVERY_MODE_STARTUP);
-        }
-
-        if (aps_still_booting == 0) {
-            break;
-        }
-        // Wait 1ms for cores to boot.  The docs recommend 200us between STARTUP
-        // IPIs.
-        thread_sleep_relative(ZX_MSEC(1));
-    }
-
-    // The docs recommend waiting 200us for cores to boot.  We do a bit more
-    // work before the cores report in, so wait longer (up to 1 second).
-    for (int tries_left = 200;
-         aps_still_booting != 0 && tries_left > 0;
-         --tries_left) {
-
-        thread_sleep_relative(ZX_MSEC(5));
-    }
-
-    uint failed_aps;
-    failed_aps = (uint)atomic_swap(&aps_still_booting, 0);
-    if (failed_aps != 0) {
-        printf("Failed to boot CPUs: mask %x\n", failed_aps);
-        for (uint i = 0; i < count; ++i) {
-            int cpu = x86_apic_id_to_cpu_num(apic_ids[i]);
-            uint mask = 1U << cpu;
-            if ((failed_aps & mask) == 0) {
-                continue;
-            }
-
-            // Shut the failed AP down
-            apic_send_ipi(0, apic_ids[i], DELIVERY_MODE_INIT);
-
-            // It shouldn't have been possible for it to have been in the
-            // scheduler...
-            ASSERT(!mp_is_cpu_active(cpu));
-
-            // Make sure the CPU is not marked online
-            atomic_and((volatile int*)&mp.online_cpus, ~mask);
-
-            // Free the failed AP's thread, it was cancelled before it could use it.
-            free_stack_and_thread(bootstrap_data->per_cpu[i].thread);
-            bootstrap_data->per_cpu[i].thread = nullptr;
-
-            failed_aps &= ~mask;
-        }
-        DEBUG_ASSERT(failed_aps == 0);
-
-        status = ZX_ERR_TIMED_OUT;
-
-        goto finish;
-    }
-
-    // Now that everything is booted, cleanup temporary structures, but keep the threads and stacks.
-    goto cleanup_aspace;
-
-cleanup_all:
-    for (unsigned int i = 0; i < count; ++i) {
-        free_stack_and_thread(bootstrap_data->per_cpu[i].thread);
-        bootstrap_data->per_cpu[i].thread = nullptr;
-    }
-cleanup_aspace:
-    bootstrap_aspace->Destroy();
-    x86_bootstrap16_release(bootstrap_data);
-finish:
-    return status;
-}
diff --git a/kernel/arch/x86/start.S b/kernel/arch/x86/start.S
deleted file mode 100644
index 26ad50c..0000000
--- a/kernel/arch/x86/start.S
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2015 Intel Corporation
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/x86/asm.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/mmu.h>
-#include <arch/x86/registers.h>
-#include <zircon/tls.h>
-
-#define ADDR_OFFSET_MASK ((1 << ADDR_OFFSET)-1)
-#define SHIFT_OFFSET(_s) ((_s) >> 3)
-#define SHIFT_REMAIN(_s) ((_s) - (SHIFT_OFFSET(_s) << 3))
-
-// Set a page table entry for the kernel module relocated 64-bit virtual
-// address in 32-bit code. Clobbers the %ecx register.
-.macro set_relocated_page_table_entry table, shift, value
-    // Extract 32-bit chunk of kernel_relocated_base containing the index bits
-    // for this page level shift.
-    mov PHYS(kernel_relocated_base + SHIFT_OFFSET(\shift)), %ecx
-
-    // Get the exact portion of the 32-bit value that is the index
-    shrl $SHIFT_REMAIN(\shift), %ecx
-    andl $ADDR_OFFSET_MASK, %ecx
-
-    // Get the address on the page table of index * 8 and set the value
-    shll $3, %ecx
-    addl $PHYS(\table), %ecx
-    movl \value, (%ecx)
-.endm
-
-// This section name is known specially to kernel.ld and gen-kaslr-fixups.sh.
-// This code has relocations for absolute physical addresses, which do not get
-// adjusted by the boot-time fixups (which this code calls at the end).
-.section .text.boot, "ax", @progbits
-.align 8
-FUNCTION_LABEL(_start)
-    /* set up a temporary stack pointer */
-    mov $PHYS(_kstack_end), %rsp
-
-    // Save off the bootdata pointer in a register that won't get clobbered.
-    mov %esi, %ebx
-
-    // The fixup code in image.S runs in 64-bit mode with paging enabled,
-    // so we can't run it too early.  But it overlaps the bss, so we move
-    // it before zeroing the bss.  We can't delay zeroing the bss because
-    // the page tables we're about to set up are themselves in bss.
-
-    // The first word after the kernel image (at __data_end in our view)
-    // gives the size of the following code.  Copy it to _end.
-    mov PHYS(__data_end), %ecx
-    mov $PHYS(__data_end+4), %esi
-    mov $PHYS(_end), %edi
-    rep movsb // while (ecx-- > 0) *edi++ = *esi++;
-
-    // Now it's safe to zero the bss.
-    movl $PHYS(__bss_start), %edi
-    movl $PHYS(_end), %ecx
-    sub %edi, %ecx              // Compute the length of the bss in bytes.
-    xor %eax, %eax
-    rep stosb // while (ecx-- > 0) *edi++ = al;
-
-    // _zbi_base is in bss, so now it's safe to set it.
-    mov %ebx, PHYS(_zbi_base)
-
-    /* give the boot allocator a chance to compute the physical address of the kernel */
-    call boot_alloc_init
-
-.Lpaging_setup64:
-    /* initialize the default page tables */
-    /* Setting the First PML4E with a PDP table reference*/
-    movl $PHYS(pdp), %eax
-    orl  $X86_KERNEL_PD_FLAGS, %eax
-    movl %eax, PHYS(pml4)
-
-    /* Setting the First PDPTE with a Page table reference*/
-    movl $PHYS(pte), %eax
-    orl  $X86_KERNEL_PD_FLAGS, %eax
-    movl %eax, PHYS(pdp)
-
-    /* point the pml4e at the second high PDP (for -2GB mapping) */
-    movl $PHYS(pdp_high),   %eax
-    orl  $X86_KERNEL_PD_FLAGS, %eax
-    set_relocated_page_table_entry pml4, PML4_SHIFT, %eax
-
-    /* point the second pdp at the same low level page table */
-    movl $PHYS(pte), %eax
-    orl  $X86_KERNEL_PD_FLAGS, %eax
-    set_relocated_page_table_entry pdp_high, PDP_SHIFT, %eax
-
-    /* map the first 1GB in this table */
-    movl $PHYS(pte), %esi
-    movl $0x200, %ecx
-    xor  %eax, %eax
-
-0:
-    mov  %eax, %ebx
-    shll $21, %ebx
-    orl  $X86_KERNEL_PD_LP_FLAGS, %ebx
-    movl %ebx, (%esi)
-    addl $8,%esi
-    inc  %eax
-    loop 0b
-
-    /* set up a linear map of the first 64GB at 0xffffff8000000000 */
-    movl $PHYS(linear_map_pdp), %esi
-    movl $32768, %ecx
-    xor  %eax, %eax
-
-    /* loop across these page tables, incrementing the address by 2MB */
-0:
-    mov  %eax, %ebx
-    shll $21, %ebx
-    orl  $X86_KERNEL_PD_LP_FLAGS, %ebx    // lower word of the entry
-    movl %ebx, (%esi)
-    mov  %eax, %ebx
-    shrl $11, %ebx      // upper word of the entry
-    movl %ebx, 4(%esi)
-    addl $8,%esi
-    inc  %eax
-    loop 0b
-
-    /* point the high pdp at our linear mapping page tables */
-    movl $PHYS(pdp_high), %esi
-    movl $64, %ecx
-    movl $PHYS(linear_map_pdp), %eax
-    orl  $X86_KERNEL_PD_FLAGS, %eax
-
-0:
-    movl %eax, (%esi)
-    add  $8, %esi
-    addl $4096, %eax
-    loop 0b
-
-    /*
-     * Set PGE to enable global kernel pages
-     */
-    mov   %cr4, %rax
-    or    $(X86_CR4_PGE), %rax
-    mov   %rax, %cr4
-
-    /* load the physical pointer to the top level page table */
-    mov  $PHYS(pml4), %rax
-    mov  %rax, %cr3
-
-    // Load our new GDT by physical pointer.
-    // _temp_gdtr has it as a virtual pointer, so copy it and adjust.
-    movw PHYS(_temp_gdtr), %ax
-    movl PHYS(_temp_gdtr+2), %ecx
-    sub $PHYS_ADDR_DELTA, %ecx
-    movw %ax, -6(%esp)
-    movl %ecx, -4(%esp)
-    lgdt -6(%esp)
-
-    /* long jump to our code selector and the high address relocated */
-    push  $CODE_64_SELECTOR
-    mov  $PHYS(high_entry), %rax
-    addq PHYS(kernel_relocated_base), %rax
-    pushq %rax
-    lretq
-
-// This code runs at the final virtual address, so it should be pure PIC.
-.text
-high_entry:
-    /* zero our kernel segment data registers */
-    xor %eax, %eax
-    mov %eax, %ds
-    mov %eax, %es
-    mov %eax, %fs
-    mov %eax, %gs
-    mov %eax, %ss
-
-    /* load the high kernel stack */
-    lea _kstack_end(%rip), %rsp
-
-    // move_fixups_and_zero_bss copied the fixup code to _end.
-    // It expects %rdi to contain the actual runtime address of __code_start.
-    lea __code_start(%rip), %rdi
-    call _end
-    // The fixup code won't be used again, so the memory can be reused now.
-
-    /* reload the gdtr after relocations as it relies on relocated VAs */
-    lgdt _temp_gdtr(%rip)
-
-    // Set %gs.base to &bp_percpu.  It's statically initialized
-    // with kernel_unsafe_sp set, so after this it's safe to call
-    // into C code that might use safe-stack and/or stack-protector.
-    lea bp_percpu(%rip), %rax
-    mov %rax, %rdx
-    shr $32, %rdx
-    mov $X86_MSR_IA32_GS_BASE, %ecx
-    wrmsr
-
-    /* set up the idt */
-    lea _idt_startup(%rip), %rdi
-    call idt_setup
-    call load_startup_idt
-
-    /* assign this core CPU# 0 and initialize its per cpu state */
-    xor %edi, %edi
-    call x86_init_percpu
-
-    // Fill the stack canary with a random value as early as possible.
-    // This isn't done in x86_init_percpu because the hw_rng_get_entropy
-    // call would make it eligible for stack-guard checking itself.  But
-    // %gs is not set up yet in the prologue of the function, so it would
-    // crash if it tried to use the stack-guard.
-    call choose_stack_guard
-
-    // Move it into place.
-    mov %rcx, %gs:ZX_TLS_STACK_GUARD_OFFSET
-    // Don't leak that value to other code.
-    xor %ecx, %ecx
-
-    // configure the kernel base address
-    // TODO: dynamically figure this out once we allow the x86 kernel to be loaded anywhere
-    movl $PHYS_LOAD_ADDRESS, kernel_base_phys(%rip)
-
-    /* call the main module */
-    call lk_main
-
-0:                          /* just sit around waiting for interrupts */
-    hlt                     /* interrupts will unhalt the processor */
-    pause
-    jmp 0b                  /* so jump back to halt to conserve power */
-
-.bss
-.align 16
-DATA(_kstack)
-    .skip 4096
-DATA(_kstack_end)
-
-// These symbols are used by image.S
-.global IMAGE_ELF_ENTRY
-IMAGE_ELF_ENTRY = _start
-
-// This symbol is used by gdb python to know the base of the kernel module
-.global KERNEL_BASE_ADDRESS
-KERNEL_BASE_ADDRESS = KERNEL_BASE - KERNEL_LOAD_OFFSET
diff --git a/kernel/arch/x86/start16.S b/kernel/arch/x86/start16.S
deleted file mode 100644
index b3d2da6..0000000
--- a/kernel/arch/x86/start16.S
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-// This file provides real-mode entry points for
-// 1) secondary CPU initialization
-// 2) suspend-to-RAM wakeup
-
-#include <asm.h>
-#include <arch/x86/bootstrap16.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/registers.h>
-#include <arch/defines.h>
-
-// This code's only non-PIC instructions are movabs, which can be fixed up
-// safely (see gen-kaslr-fixups.sh).  This section name is specially known
-// by kernel.ld and gen-kaslr-fixups.sh.
-.section .text.bootstrap16,"ax",%progbits
-.balign PAGE_SIZE
-
-DATA(x86_bootstrap16_start)
-
-.code16
-FUNCTION_LABEL(x86_bootstrap16_entry)
-    // Enter no-fill cache mode (allegedly this is the initial state
-    // according to Intel 3A, but on at least one Broadwell the APs can
-    // come up with caching enabled)
-    mov %cr0, %ebx
-    or $X86_CR0_CD, %ebx
-    and $~X86_CR0_NW, %ebx
-    mov %ebx, %cr0
-0:
-
-    // We cheat a little and don't switch off of our real mode segments in
-    // protected mode.  In real mode and protected mode, all of our code
-    // and data accesses are relative to %cs and %ss, using the real mode
-    // segment calculations.
-
-    // setup %ds/%ss to refer to the data region
-    mov %cs, %si
-    add $0x100, %si
-    mov %si, %ds
-    mov %si, %ss
-
-    lgdtl BCD_PHYS_GDTR_OFFSET
-
-    // enter protected mode (but without paging)
-    mov %cr0, %ebx
-    or $X86_CR0_PE, %ebx
-    mov %ebx, %cr0
-
-    // clear instruction prefetch queue
-    jmp 0f
-0:
-    // enable PAE / PGE
-    mov %cr4, %ecx
-    or $(X86_CR4_PAE|X86_CR4_PGE), %ecx
-    mov %ecx, %cr4
-
-    // load CR3 with the bootstrap PML4
-    mov BCD_PHYS_BOOTSTRAP_PML4_OFFSET, %ecx
-    mov %ecx, %cr3
-
-    // enable IA-32e mode and indicate support for NX pages.
-    // need the latter for once we switch to the real kernel
-    // address space.
-    mov $X86_MSR_IA32_EFER, %ecx
-    rdmsr
-    or $X86_EFER_LME, %eax
-    or $X86_EFER_NXE, %eax
-    wrmsr
-
-    // enable paging
-    mov %cr0, %ebx
-    or $X86_CR0_PG, %ebx
-    mov %ebx, %cr0
-
-    // Translate data page segment into full address
-    mov %ds, %esi
-    shl $4, %esi
-
-    // Jump to 64-bit CS
-    mov $BCD_PHYS_LM_ENTRY_OFFSET, %esp
-    lretl
-
-// Get the secondary cpu into 64-bit mode with interrupts disabled and no TSS
-.code64
-FUNCTION_LABEL(_x86_secondary_cpu_long_mode_entry)
-    // When we get here, %rsi should contain the absolute address of our data
-    // page.
-    mov $1, %rdi
-    LOCK xadd %edi, BCD_CPU_COUNTER_OFFSET(%esi)
-    // %rdi is now the index this CPU should use to grab resources
-
-    // Shift index by 2, since the per_cpu member contains two 64-bit values which
-    // will be at offsets 8*(2n) and 8*(2n+1) relative to PER_CPU_BASE_OFFSET
-    shl $1, %rdi
-    // Retrieve this CPUs initial kernel stack
-    // Note: the stack is unusable until we switch cr3 below
-    mov BCD_PER_CPU_BASE_OFFSET(%rsi, %rdi, 8), %rsp
-    add $PAGE_SIZE, %rsp
-
-    // Retrieve this CPUs initial thread
-    // Note: the stack is unusable until we switch cr3 below
-    add $1, %rdi
-    mov BCD_PER_CPU_BASE_OFFSET(%rsi, %rdi, 8), %rdx
-
-    // Retrieve the new PML4 address before our data page becomes unreachable
-    mov BCD_PHYS_KERNEL_PML4_OFFSET(%esi), %ecx
-    // Similarly for the CPU waiting mask
-    mov BCD_CPU_WAITING_OFFSET(%esi), %rdi
-
-    // Switch out of the copied code page and into the kernel's
-    // version of it
-    movabs $.Lhighaddr, %rbx
-    jmp  *%rbx
-.Lhighaddr:
-    // Switch to the kernel's PML4
-    mov %rcx, %cr3
-    // As of this point, %esi is invalid
-
-    // Reload the GDT with one based off of non-identity mapping
-    lgdt _temp_gdtr(%rip)
-
-    // Zero our data segments
-    xor %eax, %eax
-    mov %eax, %ds
-    mov %eax, %es
-    mov %eax, %fs
-    mov %eax, %gs
-    mov %eax, %ss
-
-    // Load the IDT
-    call load_startup_idt
-
-    mov %rdx, %rsi
-    // Do an indirect call to keep this position independent
-    // x86_secondary_entry(CPU ready counter, thread)
-    movabs $x86_secondary_entry, %rbx
-    call *%rbx
-
-// If x86_secondary_entry returns, hang.
-0:
-    hlt
-    jmp 0b
-
-// Get the cpu into 64-bit mode with interrupts disabled and no TSS.  This must
-// only be called on the bootstrap processor.
-FUNCTION_LABEL(_x86_suspend_wakeup)
-    // Retrieve the new PML4 address before our data page becomes unreachable
-    mov BCD_PHYS_KERNEL_PML4_OFFSET(%esi), %ecx
-
-    // Stash register pointer so that we can read it after we change
-    // address spaces
-    mov RED_REGISTERS_OFFSET(%esi), %rdi
-
-    // Switch out of the copied code page and into the kernel's
-    // version of it
-    movabs $.Lwakeup_highaddr, %rbx
-    jmp  *%rbx
-.Lwakeup_highaddr:
-    // Switch to the kernel's PML4
-    mov %rcx, %cr3
-    // As of this point, %esi is invalid
-
-    // Reload the GDT with one based off of non-identity mapping
-    lgdt _temp_gdtr(%rip)
-
-    // Zero our data segments
-    xor %eax, %eax
-    mov %eax, %ds
-    mov %eax, %es
-    mov %eax, %fs
-    mov %eax, %gs
-    mov %eax, %ss
-
-    // Restore %gs.base to &bp_percpu.  We need to do this before
-    // returning to C code, since the C code might use safe-stack
-    // and/or stack-protector.
-    // TODO(teisenbe):  There is a small performance gain that could be made here
-    // by switching from wrmsr to wrgsbase, if wrgsbase is supported.  Currently
-    // this is omitted for simplicity.
-    lea bp_percpu(%rip), %rax
-    mov %rax, %rdx
-    shr $32, %rdx
-    mov $X86_MSR_IA32_GS_BASE, %ecx
-    wrmsr
-
-    // Restore the stack pointer first, so we can use the stack right now.
-    mov 120(%rdi), %rsp
-
-    // Load the IDT.  Note this uses the stack and clobbers %rax, but not %rdi.
-    call load_startup_idt
-
-    mov 8(%rdi), %rsi
-    mov 16(%rdi), %rbp
-    mov 24(%rdi), %rbx
-    mov 32(%rdi), %rdx
-    mov 40(%rdi), %rcx
-    mov 48(%rdi), %rax
-    mov 56(%rdi), %r8
-    mov 64(%rdi), %r9
-    mov 72(%rdi), %r10
-    mov 80(%rdi), %r11
-    mov 88(%rdi), %r12
-    mov 96(%rdi), %r13
-    mov 104(%rdi), %r14
-    mov 112(%rdi), %r15
-
-    // Note: %rdi is not restored, but it is a caller-save register anyway.
-    // If we want to restore %rdi, we could potentially use the stack here
-    // to do something like "push 128(%rdi); mov (%rdi), %rdi; ret".
-
-    // Restore RIP
-    jmp *128(%rdi)
-
-DATA(x86_bootstrap16_end)
-    nop
diff --git a/kernel/arch/x86/syscall.S b/kernel/arch/x86/syscall.S
deleted file mode 100644
index 75cde3d..0000000
--- a/kernel/arch/x86/syscall.S
+++ /dev/null
@@ -1,405 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/x86/mp.h>
-#include <zircon/zx-syscall-numbers.h>
-
-#define DW_REG_rsp        0x7
-#define DW_REG_rip        0x10
-
-//
-// Macros for preparing ABI conformant calls for syscall wrappers.
-//
-// syscall_8(arg_1, arg_2, arg_3, arg_4, arg_5, arg_6, arg_7, arg_8, rip)
-//
-// arg_1 from rdi to rdi
-// arg_2 from rsi to rsi
-// arg_3 from rdx to rdx
-// arg_4 from r10 to rcx
-// arg_5 from r8  to r8
-// arg_6 from r9  to r9
-// arg_7 from r12 to (%rsp)
-// arg_8 from r13 to 8(%rsp)
-// rip   from rcx to 16(%rsp)
-//
-.macro pre_8_args
-    pre_push 3
-    push_value %rcx
-    push_value %r13
-    push_value %r12
-
-    /* move arg 4 into the proper register for calling convention */
-    mov      %r10, %rcx
-.endm
-
-.macro post_8_args
-    post_pop 3
-    jmp     .Lcleanup_and_return
-.endm
-
-//
-// syscall_7(arg_1, arg_2, arg_3, arg_4, arg_5, arg_6, arg_7, rip)
-//
-// arg_1 from rdi to rdi
-// arg_2 from rsi to rsi
-// arg_3 from rdx to rdx
-// arg_4 from r10 to rcx
-// arg_5 from r8  to r8
-// arg_6 from r9  to r9
-// arg_7 from r12 to (rsp)
-// rip   from rcx to 8(rsp)
-//
-.macro pre_7_args
-    pre_push 2
-    push_value %rcx
-    push_value %r12
-    mov      %r10, %rcx
-.endm
-
-.macro post_7_args
-    post_pop 2
-    jmp     .Lcleanup_and_return
-.endm
-
-//
-// syscall_6(arg_1, arg_2, arg_3, arg_4, arg_5, arg_6, rip)
-//
-// arg_1 from rdi to rdi
-// arg_2 from rsi to rsi
-// arg_3 from rdx to rdx
-// arg_4 from r10 to rcx
-// arg_5 from r8  to r8
-// arg_6 from r9  to r9
-// rip   from rcx to (rsp)
-//
-.macro pre_6_args
-    pre_push 1
-    push_value %rcx
-    mov      %r10, %rcx
-.endm
-
-.macro post_6_args
-    post_pop 1
-    jmp     .Lcleanup_and_return
-.endm
-
-//
-// syscall_5(arg_1, arg_2, arg_3, arg_4, arg_5, rip)
-//
-// arg_1 from rdi to rdi
-// arg_2 from rsi to rsi
-// arg_3 from rdx to rdx
-// arg_4 from r10 to rcx
-// arg_5 from r8  to r8
-// rip   from rcx to r9
-//
-.macro pre_5_args
-    pre_push 0
-    mov     %rcx, %r9
-    mov     %r10, %rcx
-.endm
-
-.macro post_5_args
-    post_pop 0
-    jmp     .Lcleanup_and_return
-.endm
-
-//
-// syscall_4(arg_1, arg_2, arg_3, arg_4, rip)
-//
-// arg_1 from rdi to rdi
-// arg_2 from rsi to rsi
-// arg_3 from rdx to rdx
-// arg_4 from r10 to rcx
-// rip   from rcx to r8
-//
-.macro pre_4_args
-    pre_push 0
-    mov     %rcx, %r8
-    mov     %r10, %rcx
-.endm
-
-.macro post_4_args
-    post_pop 0
-    jmp     .Lcleanup_and_return
-.endm
-
-//
-// syscall_3(arg_1, arg_2, arg_3, rip)
-//
-// arg_1 from rdi to rdi
-// arg_2 from rsi to rsi
-// arg_3 from rdx to rdx
-// rip   from rcx to rcx
-//
-.macro pre_3_args
-    pre_push 0
-.endm
-
-.macro post_3_args
-    post_pop 0
-    jmp     .Lcleanup_and_return
-.endm
-
-//
-// syscall_2(arg_1, arg_2, rip)
-//
-// arg_1 from rdi to rdi
-// arg_2 from rsi to rsi
-// rip   from rcx to rdx
-//
-.macro pre_2_args
-    pre_push 0
-    mov     %rcx, %rdx
-.endm
-
-.macro post_2_args
-    post_pop 0
-    jmp     .Lcleanup_and_return
-.endm
-
-//
-// syscall_1(arg_1, rip)
-//
-// arg_1 from rdi to rdi
-// rip   from rcx to rsi
-//
-.macro pre_1_args
-    pre_push 0
-    mov    %rcx, %rsi
-.endm
-
-.macro post_1_args
-    post_pop 0
-    jmp     .Lcleanup_and_return
-.endm
-
-
-//
-// syscall_0(rip)
-//
-// rip   from rcx to rdi
-//
-.macro pre_0_args
-    pre_push 0
-    mov    %rcx, %rdi
-.endm
-
-.macro post_0_args
-    post_pop 0
-    jmp     .Lcleanup_and_return
-.endm
-
-// x86_syscall (below) leaves the stack misaligned by 8, so the macros
-// need to account for that.
-.macro pre_push n
-.if \n % 2 == 0
-    push_value $0
-.endif
-.endm
-
-.macro post_pop n
-.if \n % 2 == 0
-    add_to_sp ((\n + 1) * 8)
-.else
-    add_to_sp (\n * 8)
-.endif
-.endm
-
-.macro cfi_outermost_frame
-    // TODO(dje): IWBN to use .cfi_undefined here, but gdb didn't properly
-    // handle initial attempts. Need to try again (or file gdb bug).
-    cfi_register_is_zero DW_REG_rsp
-    cfi_register_is_zero DW_REG_rip
-.endm
-
-// Adds a label for making the syscall and adds it to the jump table.
-.macro syscall_dispatch nargs, syscall
-    .pushsection .text.syscall-dispatch,"ax",%progbits
-    LOCAL_FUNCTION(.Lcall_\syscall\())
-        // See x86_syscall for why this is here.
-        cfi_outermost_frame
-        pre_\nargs\()_args
-        call wrapper_\syscall
-        post_\nargs\()_args
-    END_FUNCTION(.Lcall_\syscall\())
-    .popsection
-    .pushsection .rodata.syscall-table,"a",%progbits
-        .quad .Lcall_\syscall
-    .popsection
-.endm
-
-// Adds the label for the jump table.
-.macro start_syscall_dispatch
-    .pushsection .rodata.syscall-table,"a",%progbits
-    .balign 8
-    .Lcall_wrapper_table:
-    .popsection
-.endm
-
-.text
-
-    /* kernel side of the SYSCALL instruction
-     * state on entry:
-     * RCX holds user RIP
-     * R11 holds user RFLAGS
-     * RSP still holds user stack
-     * CS loaded with kernel CS from IA32_STAR
-     * SS loaded with kernel CS + 8 from IA32_STAR
-
-     * args passed:
-     *  rax - syscall # and return
-     *  rbx - saved
-     *  rcx - modified as part of syscall instruction
-     *  rdx - arg 3
-     *  rdi - arg 1
-     *  rsi - arg 2
-     *  rbp - saved
-     *  rsp - saved
-     *  r8  - arg 5
-     *  r9  - arg 6
-     *  r10 - arg 4
-     *  r11 - modified as part of syscall instruction
-     *  r12 - arg 7
-     *  r13 - arg 8
-     *  r14 - saved
-     *  r15 - saved
-     */
-FUNCTION_LABEL(x86_syscall)
-    .cfi_startproc simple
-    // CFI tracking here doesn't (currently) try to support backtracing from
-    // kernel space to user space. This is left for later. For now just say
-    // %rsp and %rip of the previous frame are zero, mark all the other
-    // registers as undefined, and have all register push/pop just specify
-    // stack adjustments and not how to find the register's value.
-    cfi_outermost_frame
-    // The default for caller-saved regs is "undefined", but for completeness
-    // sake mark them all as undefined.
-    ALL_CFI_UNDEFINED
-
-    /* swap to the kernel GS register */
-    swapgs
-
-    /* save the user stack pointer */
-    mov     %rsp, %gs:PERCPU_SAVED_USER_SP_OFFSET
-
-    /* load the kernel stack pointer */
-    mov     %gs:PERCPU_KERNEL_SP_OFFSET, %rsp
-    .cfi_def_cfa %rsp, 0
-
-    /* save away the user stack pointer */
-    push_value %gs:PERCPU_SAVED_USER_SP_OFFSET
-
-    push_value %r11 /* user RFLAGS */
-    push_value %rcx /* user RIP */
-
-    // Any changes to the stack here need to be reflected in
-    // pre_push and post_pop macros above to maintain alignment.
-    // Verify the syscall is in range and jump to it.
-    cmp     $ZX_SYS_COUNT, %rax
-    jae     .Lunknown_syscall
-    leaq    .Lcall_wrapper_table(%rip), %r11
-    jmp     *(%r11, %rax, 8)
-.Lunknown_syscall:
-    pre_0_args
-    call    unknown_syscall
-    post_0_args
-
-.Lcleanup_and_return:
-
-    /* at this point:
-       rax = syscall result
-       rdx = non-zero if thread was signaled */
-
-    /* restore the registers from which SYSRET restores user state */
-    pop_value %rcx /* user RIP */
-    pop_value %r11 /* user RFLAGS */
-
-    /* zero out trashed arg registers */
-    xorl    %edi, %edi
-    xorl    %esi, %esi
-    /* Don't zero %rdx yet -- it contains the "is_signaled" indicator */
-    xorl    %r10d, %r10d
-    xorl    %r8d, %r8d
-    xorl    %r9d, %r9d
-
-    cmp     $0, %rdx
-    jnz     .Lthread_signaled
-
-    /*xor     %rdx, %rdx - already zero */
-
-.Lreturn_from_syscall:
-
-    /* make sure interrupts are disabled (they already are in the fall-through
-       path, but if we took the .Lthread_signaled path they aren't) */
-    cli
-
-    /* restore the user stack */
-    pop_value %rsp
-
-    /* put the user gs back */
-    swapgs
-
-    /* This will fault if the return address is non-canonical.  See
-     * docs/sysret_problem.md for how we avoid that. */
-    sysretq
-
-.Lthread_signaled:
-    /* re-enable interrupts to maintain kernel preemptiveness */
-    sti
-
-    /* fill in x86_syscall_general_regs_t
-       Because we don't save the regs unless we have to a lot of the original
-       values are gone. The user just has to deal with it. One important thing
-       to do here is not leak kernel values to userspace. */
-    movq    (%rsp), %rdi /* user rsp */
-    push_value %r11 /* rflags */
-    push_value %rcx /* rip */
-    push_value %r15
-    push_value %r14
-    push_value %r13
-    push_value %r12
-    push_value %r11
-    push_value %r10
-    push_value %r9
-    push_value %r8
-    push_value %rdi /* rsp */
-    push_value %rbp
-    push_value $0
-    push_value %rsi
-    push_value $0 /* instead of signaled flag */
-    push_value %rcx
-    push_value %rbx
-    push_value %rax
-
-    movq    %rsp, %rdi
-    call    x86_syscall_process_pending_signals
-
-    pop_value %rax
-    pop_value %rbx
-    pop_value %rcx
-    pop_value %rdx
-    pop_value %rsi
-    pop_value %rdi
-    pop_value %rbp
-    pop_value %r8 /* discard any changed %rsp value - TODO(dje): check ok */
-    pop_value %r8
-    pop_value %r9
-    pop_value %r10
-    pop_value %r11
-    pop_value %r12
-    pop_value %r13
-    pop_value %r14
-    pop_value %r15
-    pop_value %rcx
-    pop_value %r11
-    jmp     .Lreturn_from_syscall
-
-END_FUNCTION(x86_syscall)
-
-#include <zircon/syscall-kernel-branches.S>
diff --git a/kernel/arch/x86/thread.cpp b/kernel/arch/x86/thread.cpp
deleted file mode 100644
index 975974a..0000000
--- a/kernel/arch/x86/thread.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2009 Corey Tabaka
-// Copyright (c) 2014 Travis Geiselbrecht
-// Copyright (c) 2015 Intel Corporation
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86.h>
-#include <arch/x86/descriptor.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/mp.h>
-#include <arch/x86/registers.h>
-#include <arch/x86/x86intrin.h>
-#include <assert.h>
-#include <debug.h>
-#include <kernel/spinlock.h>
-#include <kernel/thread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-void arch_thread_initialize(thread_t* t, vaddr_t entry_point) {
-    // create a default stack frame on the stack
-    vaddr_t stack_top = t->stack.top;
-
-    // make sure the top of the stack is 16 byte aligned for ABI compliance
-    stack_top = ROUNDDOWN(stack_top, 16);
-    t->stack.top = stack_top;
-
-    // make sure we start the frame 8 byte unaligned (relative to the 16 byte alignment) because
-    // of the way the context switch will pop the return address off the stack. After the first
-    // context switch, this leaves the stack unaligned relative to how a called function expects it.
-    stack_top -= 8;
-    struct x86_64_context_switch_frame* frame = (struct x86_64_context_switch_frame*)(stack_top);
-
-    // Record a zero return address so that backtraces will stop here.
-    // Otherwise if heap debugging is on, and say there is 99..99 here,
-    // then the debugger could try to continue the backtrace from there.
-    memset((void*)stack_top, 0, 8);
-
-    // move down a frame size and zero it out
-    frame--;
-    memset(frame, 0, sizeof(*frame));
-
-    frame->rip = entry_point;
-
-    // initialize the saved extended register state
-    vaddr_t buf = ROUNDUP(((vaddr_t)t->arch.extended_register_buffer), 64);
-    __UNUSED size_t overhead = buf - (vaddr_t)t->arch.extended_register_buffer;
-    DEBUG_ASSERT(sizeof(t->arch.extended_register_buffer) - overhead >=
-                 x86_extended_register_size());
-    t->arch.extended_register_state = (vaddr_t*)buf;
-    x86_extended_register_init_state(t->arch.extended_register_state);
-
-    // set the stack pointer
-    t->arch.sp = (vaddr_t)frame;
-#if __has_feature(safe_stack)
-    t->arch.unsafe_sp =
-        ROUNDDOWN(t->stack.unsafe_base + t->stack.size, 16);
-#endif
-
-    // initialize the fs, gs and kernel bases to 0.
-    t->arch.fs_base = 0;
-    t->arch.gs_base = 0;
-
-    // Initialize the debug registers to a valid initial state.
-    t->arch.track_debug_state = false;
-    for (size_t i = 0; i < 4; i++) {
-      t->arch.debug_state.dr[i] = 0;
-    }
-    t->arch.debug_state.dr6 = ~X86_DR6_USER_MASK;
-    t->arch.debug_state.dr7 = ~X86_DR7_USER_MASK;
-}
-
-void arch_thread_construct_first(thread_t* t) {
-}
-
-void arch_dump_thread(thread_t* t) {
-    if (t->state != THREAD_RUNNING) {
-        dprintf(INFO, "\tarch: ");
-        dprintf(INFO, "sp %#" PRIxPTR "\n", t->arch.sp);
-    }
-}
-
-void* arch_thread_get_blocked_fp(struct thread* t) {
-    if (!WITH_FRAME_POINTERS)
-        return nullptr;
-
-    struct x86_64_context_switch_frame* frame = (struct x86_64_context_switch_frame*)t->arch.sp;
-
-    return (void*)frame->rbp;
-}
-
-__NO_SAFESTACK __attribute__((target("fsgsbase")))
-void arch_context_switch(thread_t* oldthread, thread_t* newthread) {
-    x86_extended_register_context_switch(oldthread, newthread);
-
-    x86_debug_state_context_switch(oldthread, newthread);
-
-    //printf("cs 0x%llx\n", kstack_top);
-
-    /* set the tss SP0 value to point at the top of our stack */
-    x86_set_tss_sp(newthread->stack.top);
-
-    /* Save the user fs_base register value.  The new rdfsbase instruction
-     * is much faster than reading the MSR, so use the former in
-     * preference. */
-    if (likely(g_x86_feature_fsgsbase)) {
-        oldthread->arch.fs_base = _readfsbase_u64();
-    } else {
-        oldthread->arch.fs_base = read_msr(X86_MSR_IA32_FS_BASE);
-    }
-
-    /* The segment selector registers can't be preserved across context
-     * switches in all cases, because some values get clobbered when
-     * returning from interrupts.  If an interrupt occurs when a userland
-     * process has set %fs = 1 (for example), the IRET instruction used for
-     * returning from the interrupt will reset %fs to 0.
-     *
-     * To prevent the segment selector register values from leaking between
-     * processes, we reset these registers across context switches. */
-    set_ds(0);
-    set_es(0);
-    set_fs(0);
-    if (get_gs() != 0) {
-        /* Assigning to %gs clobbers gs_base, so we must restore gs_base
-         * afterwards. */
-        DEBUG_ASSERT(arch_ints_disabled());
-        uintptr_t gs_base = (uintptr_t)x86_get_percpu();
-        set_gs(0);
-        write_msr(X86_MSR_IA32_GS_BASE, gs_base);
-    }
-
-    /* Restore fs_base and save+restore user gs_base.  Note that the user
-     * and kernel gs_base values have been swapped -- the user value is
-     * currently in KERNEL_GS_BASE. */
-    if (likely(g_x86_feature_fsgsbase)) {
-        /* There is no variant of the {rd,wr}gsbase instructions for
-         * accessing KERNEL_GS_BASE, so we wrap those in two swapgs
-         * instructions to get the same effect.  This is a little
-         * convoluted, but still faster than using the KERNEL_GS_BASE
-         * MSRs. */
-        __asm__ __volatile__(
-            "swapgs\n"
-            "rdgsbase %[old_value]\n"
-            "wrgsbase %[new_value]\n"
-            "swapgs\n"
-            : [old_value] "=&r"(oldthread->arch.gs_base)
-            : [new_value] "r"(newthread->arch.gs_base));
-
-        _writefsbase_u64(newthread->arch.fs_base);
-    } else {
-        oldthread->arch.gs_base = read_msr(X86_MSR_IA32_KERNEL_GS_BASE);
-        write_msr(X86_MSR_IA32_FS_BASE, newthread->arch.fs_base);
-        write_msr(X86_MSR_IA32_KERNEL_GS_BASE, newthread->arch.gs_base);
-    }
-
-#if __has_feature(safe_stack)
-    oldthread->arch.unsafe_sp = x86_read_gs_offset64(ZX_TLS_UNSAFE_SP_OFFSET);
-    x86_write_gs_offset64(ZX_TLS_UNSAFE_SP_OFFSET, newthread->arch.unsafe_sp);
-#endif
-
-    x86_64_context_switch(&oldthread->arch.sp, newthread->arch.sp);
-}
-
-void x86_debug_state_context_switch(thread_t *old_thread, thread_t *new_thread) {
-    // If the new thread has debug state, then install it, replacing the current contents.
-    if (unlikely(new_thread->arch.track_debug_state)) {
-        // NOTE: There is no enable debug state call, as x86 doesn't have a global enable/disable
-        //       switch, but rather enables particular registers through DR7. These registers are
-        //       selected by userspace (and filtered by zircon) in the thread_write_state state
-        //       syscall.
-        //
-        //       This means that just writing the thread debug state into the CPU is enough to
-        //       activate the debug functionality.
-        x86_write_hw_debug_regs(&new_thread->arch.debug_state);
-        return;
-    }
-
-    // If the old thread had debug state running and the new one doesn't use it, disable the
-    // debug capabilities.
-    if (unlikely(old_thread->arch.track_debug_state)) {
-        x86_disable_debug_state();
-    }
-}
diff --git a/kernel/arch/x86/timer_freq.cpp b/kernel/arch/x86/timer_freq.cpp
deleted file mode 100644
index 424c85b..0000000
--- a/kernel/arch/x86/timer_freq.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86/feature.h>
-#include <arch/x86/timer_freq.h>
-
-uint64_t x86_lookup_core_crystal_freq() {
-    return x86_get_microarch_config()->get_apic_freq();
-}
-
-uint64_t x86_lookup_tsc_freq() {
-    return x86_get_microarch_config()->get_tsc_freq();
-}
diff --git a/kernel/arch/x86/toolchain.mk b/kernel/arch/x86/toolchain.mk
deleted file mode 100644
index 808842e..0000000
--- a/kernel/arch/x86/toolchain.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-# x86-64 GCC toolchain
-ifndef ARCH_x86_64_TOOLCHAIN_INCLUDED
-ARCH_x86_64_TOOLCHAIN_INCLUDED := 1
-
-ifndef ARCH_x86_64_TOOLCHAIN_PREFIX
-ARCH_x86_64_TOOLCHAIN_PREFIX := x86_64-elf-
-endif
-FOUNDTOOL=$(shell which $(ARCH_x86_64_TOOLCHAIN_PREFIX)gcc)
-
-endif # ifndef ARCH_x86_64_TOOLCHAIN_INCLUDED
-
-# Clang
-ifeq ($(call TOBOOL,$(USE_CLANG)),true)
-FOUNDTOOL=$(shell which $(CLANG_TOOLCHAIN_PREFIX)clang)
-endif # USE_CLANG==true
-
-ifeq ($(FOUNDTOOL),)
-$(error cannot find toolchain, please set ARCH_x86_64_TOOLCHAIN_PREFIX, \
-        CLANG_TOOLCHAIN_PREFIX, or add either to your path)
-endif
diff --git a/kernel/arch/x86/tsc.cpp b/kernel/arch/x86/tsc.cpp
deleted file mode 100644
index 2ac01bb..0000000
--- a/kernel/arch/x86/tsc.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/x86.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/tsc.h>
-
-#define X86_MSR_IA32_TIME_STAMP_COUNTER 0x10
-
-uint64_t tsc_adj = 0;
-
-void x86_tsc_adjust(void) {
-    if (x86_feature_test(X86_FEATURE_TSC_ADJUST))
-        write_msr(X86_MSR_IA32_TSC_ADJUST, tsc_adj);
-}
-
-void x86_tsc_store_adjustment(void) {
-    if (x86_feature_test(X86_FEATURE_TSC_ADJUST))
-        tsc_adj = read_msr(X86_MSR_IA32_TIME_STAMP_COUNTER);
-}
diff --git a/kernel/arch/x86/user_copy.S b/kernel/arch/x86/user_copy.S
deleted file mode 100644
index e3459b0..0000000
--- a/kernel/arch/x86/user_copy.S
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <err.h>
-#include <lib/code_patching.h>
-
-#define STAC APPLY_CODE_PATCH_FUNC(fill_out_stac_instruction, 3)
-#define CLAC APPLY_CODE_PATCH_FUNC(fill_out_clac_instruction, 3)
-
-/* Register use in this code:
- * %rdi = argument 1, void* dst
- * %rsi = argument 2, const void* src
- * %rdx = argument 3, size_t len
- *   - moved to %rcx
- * %rcx = argument 4, void** fault_return
- *   - moved to %r10
- */
-
-// zx_status_t _x86_copy_to_or_from_user(void *dst, const void *src, size_t len, void **fault_return)
-FUNCTION(_x86_copy_to_or_from_user)
-    // Copy fault_return out of %rcx, because %rcx is used by "rep movsb" later.
-    movq %rcx, %r10
-
-    // Disable SMAP protection if SMAP is enabled
-    STAC
-
-    // Setup page fault return
-    leaq .Lfault_copy(%rip), %rax
-    movq %rax, (%r10)
-
-    // Between now and the reset of the fault return, we cannot make a function
-    // call or manipulate the stack.  We need to be able to restore all callee
-    // registers, without any knowledge of where between these two points we
-    // faulted.
-
-    // Perform the actual copy
-    cld
-    // %rdi and %rsi already contain the destination and source addresses.
-    movq %rdx, %rcx
-    rep movsb  // while (rcx-- > 0) *rdi++ = *rsi++;
-
-    mov $ZX_OK, %rax
-
-.Lcleanup_copy:
-    // Reset fault return
-    movq $0, (%r10)
-
-    // Re-enable SMAP protection
-    CLAC
-    ret
-
-.Lfault_copy:
-    mov $ZX_ERR_INVALID_ARGS, %rax
-    jmp .Lcleanup_copy
-END_FUNCTION(_x86_copy_to_or_from_user)
diff --git a/kernel/arch/x86/user_copy.cpp b/kernel/arch/x86/user_copy.cpp
deleted file mode 100644
index 4f4dfde..0000000
--- a/kernel/arch/x86/user_copy.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-#include <string.h>
-#include <trace.h>
-
-#include <arch/user_copy.h>
-#include <arch/x86.h>
-#include <arch/x86/feature.h>
-#include <arch/x86/user_copy.h>
-#include <kernel/thread.h>
-#include <lib/code_patching.h>
-#include <vm/vm.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-CODE_TEMPLATE(kStacInstruction, "stac");
-CODE_TEMPLATE(kClacInstruction, "clac");
-static const uint8_t kNopInstruction = 0x90;
-
-extern "C" {
-
-void fill_out_stac_instruction(const CodePatchInfo* patch) {
-    const size_t kSize = 3;
-    DEBUG_ASSERT(patch->dest_size == kSize);
-    DEBUG_ASSERT(kStacInstructionEnd - kStacInstruction == kSize);
-    if (x86_feature_test(X86_FEATURE_SMAP)) {
-        memcpy(patch->dest_addr, kStacInstruction, kSize);
-    } else {
-        memset(patch->dest_addr, kNopInstruction, kSize);
-    }
-}
-
-void fill_out_clac_instruction(const CodePatchInfo* patch) {
-    const size_t kSize = 3;
-    DEBUG_ASSERT(patch->dest_size == kSize);
-    DEBUG_ASSERT(kClacInstructionEnd - kClacInstruction == kSize);
-    if (x86_feature_test(X86_FEATURE_SMAP)) {
-        memcpy(patch->dest_addr, kClacInstruction, kSize);
-    } else {
-        memset(patch->dest_addr, kNopInstruction, kSize);
-    }
-}
-}
-
-static inline bool ac_flag(void) {
-    return x86_save_flags() & X86_FLAGS_AC;
-}
-
-static bool can_access(const void* base, size_t len) {
-    LTRACEF("can_access: base %p, len %zu\n", base, len);
-
-    // We don't care about whether pages are actually mapped or what their
-    // permissions are, as long as they are in the user address space.  We
-    // rely on a page fault occurring if an actual permissions error occurs.
-    DEBUG_ASSERT(x86_get_cr0() & X86_CR0_WP);
-    return is_user_address_range((vaddr_t)base, len);
-}
-
-zx_status_t arch_copy_from_user(void* dst, const void* src, size_t len) {
-    DEBUG_ASSERT(!ac_flag());
-
-    if (!can_access(src, len))
-        return ZX_ERR_INVALID_ARGS;
-
-    thread_t* thr = get_current_thread();
-    zx_status_t status = _x86_copy_to_or_from_user(dst, src, len,
-                                                   &thr->arch.page_fault_resume);
-
-    DEBUG_ASSERT(!ac_flag());
-    return status;
-}
-
-zx_status_t arch_copy_to_user(void* dst, const void* src, size_t len) {
-    DEBUG_ASSERT(!ac_flag());
-
-    if (!can_access(dst, len))
-        return ZX_ERR_INVALID_ARGS;
-
-    thread_t* thr = get_current_thread();
-    zx_status_t status = _x86_copy_to_or_from_user(dst, src, len,
-                                                   &thr->arch.page_fault_resume);
-
-    DEBUG_ASSERT(!ac_flag());
-    return status;
-}
diff --git a/kernel/arch/x86/uspace_entry.S b/kernel/arch/x86/uspace_entry.S
deleted file mode 100644
index fe3d759..0000000
--- a/kernel/arch/x86/uspace_entry.S
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <asm.h>
-#include <arch/x86/descriptor.h>
-
-// x86_uspace_entry(uintptr_t arg1, uintptr_t arg2, uintptr_t sp, uintptr_t pc, uint64_t rflags)
-FUNCTION(x86_uspace_entry)
-    /* push a fake 64bit interrupt stack frame and iret to it */
-    push_value $USER_DATA_SELECTOR    // ss
-    push_value %rdx                   // sp
-    push_value %r8                    // rflags
-    push_value $USER_CODE_64_SELECTOR // cs
-    push_value %rcx                   // pc
-
-    ALL_CFI_UNDEFINED
-
-    // Clear registers
-    xorl %eax, %eax /* set %rax = 0 */
-    xorl %ebx, %ebx
-    xorl %ecx, %ecx
-    xorl %edx, %edx
-    // Don't clear rdi or rsi, since they have the user arguments.
-    xorl %ebp, %ebp
-    xorl %r8d, %r8d
-    xorl %r9d, %r9d
-    xorl %r10d, %r10d
-    xorl %r11d, %r11d
-    xorl %r12d, %r12d
-    xorl %r13d, %r13d
-    xorl %r14d, %r14d
-    xorl %r15d, %r15d
-
-    // We do not need to clear extended register state, since the kernel only
-    // uses the general purpose registers, and the extended state is initialized
-    // to a cleared state.
-
-    swapgs
-
-    mov %ax, %ds
-    mov %ax, %es
-    mov %ax, %fs
-    mov %ax, %gs
-
-    iretq
-END_FUNCTION(x86_uspace_entry)
diff --git a/kernel/dev/hdcp/amlogic_s912/hdcp.cpp b/kernel/dev/hdcp/amlogic_s912/hdcp.cpp
deleted file mode 100644
index 7a6e2ec..0000000
--- a/kernel/dev/hdcp/amlogic_s912/hdcp.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <reg.h>
-#include <stdio.h>
-#include <trace.h>
-#include <string.h>
-#include <lib/cbuf.h>
-#include <arch/arm64/periphmap.h>
-#include <arch/arm64/smccc.h>
-#include <kernel/thread.h>
-#include <dev/interrupt.h>
-#include <pdev/driver.h>
-#include <zircon/boot/driver-config.h>
-
-static vaddr_t preset_base;
-static vaddr_t hiu_base;
-static vaddr_t hdmitx_base;
-
-#define TOP_OFFSET_MASK      (0x0UL << 24)
-#define DWC_OFFSET_MASK      (0x10UL << 24)
-#define HDMITX_ADDR_PORT                                (0x00)
-#define HDMITX_DATA_PORT                                (0x04)
-
-#define DISPLAY_MASK(start, count) (((1 << (count)) - 1) << (start))
-#define DISPLAY_SET_MASK(mask, start, count, value) \
-                        ((mask & ~DISPLAY_MASK(start, count)) | \
-                                (((value) << (start)) & DISPLAY_MASK(start, count)))
-
-#define READ32_PRESET_REG(a)             readl(preset_base + a)
-#define WRITE32_PRESET_REG(a, v)         writel(v, preset_base + a)
-
-#define READ32_HDMITX_REG(a)             readl(hdmitx_base + a)
-#define WRITE32_HDMITX_REG(a, v)         writel(v, hdmitx_base + a)
-
-#define READ32_HHI_REG(a)                readl(hiu_base + a)
-#define WRITE32_HHI_REG(a, v)            writel(v, hiu_base + a)
-
-#define SET_BIT32(x, dest, value, count, start) \
-            WRITE32_##x##_REG(dest, (READ32_##x##_REG(dest) & ~DISPLAY_MASK(start, count)) | \
-                                (((value) << (start)) & DISPLAY_MASK(start, count)))
-
-#define HHI_HDMI_CLK_CNTL                               (0x73 << 2)
-#define HHI_GCLK_MPEG2                                  (0x52 << 2)
-#define HHI_MEM_PD_REG0                                 (0x40 << 2)
-#define PRESET0_REGISTER                                (0x404)
-#define PRESET2_REGISTER                                (0x40C)
-#define HDMITX_TOP_SW_RESET                             (TOP_OFFSET_MASK + 0x000)
-#define HDMITX_TOP_CLK_CNTL                             (TOP_OFFSET_MASK + 0x001)
-#define HDMITX_DWC_MC_LOCKONCLOCK                       (DWC_OFFSET_MASK + 0x4006)
-#define HDMITX_DWC_MC_CLKDIS                            (DWC_OFFSET_MASK + 0x4001)
-#define HDMITX_DWC_A_APIINTMSK                          (DWC_OFFSET_MASK + 0x5008)
-#define HDMITX_DWC_A_VIDPOLCFG                          (DWC_OFFSET_MASK + 0x5009)
-#define HDMITX_DWC_A_OESSWCFG                           (DWC_OFFSET_MASK + 0x500A)
-
-static void hdmitx_writereg(uint32_t addr, uint32_t data) {
-    // determine if we are writing to HDMI TOP (AMLOGIC Wrapper) or HDMI IP
-    uint32_t offset = (addr & DWC_OFFSET_MASK) >> 24;
-    addr = addr & 0xffff;
-    WRITE32_HDMITX_REG(HDMITX_ADDR_PORT + offset, addr);
-    WRITE32_HDMITX_REG(HDMITX_ADDR_PORT + offset, addr); // FIXME: Need to write twice!
-    WRITE32_HDMITX_REG(HDMITX_DATA_PORT + offset, data);
-}
-
-static void s912_hdcp_init(const void* driver_data, uint32_t length) {
-    ASSERT(length >= sizeof(dcfg_amlogic_hdcp_driver_t));
-    auto driver = static_cast<const dcfg_amlogic_hdcp_driver_t *>(driver_data);
-    ASSERT(driver->preset_phys && driver->hiu_phys && driver->hdmitx_phys);
-
-    // get virtual addresses of our peripheral bases
-    preset_base = periph_paddr_to_vaddr(driver->preset_phys);
-    hiu_base = periph_paddr_to_vaddr(driver->hiu_phys);
-    hdmitx_base = periph_paddr_to_vaddr(driver->hdmitx_phys);
-    ASSERT(preset_base && hiu_base && hdmitx_base);
-
-    // enable clocks
-    SET_BIT32(HHI, HHI_HDMI_CLK_CNTL, 0x0100, 16, 0);
-
-    // enable clk81 (needed for HDMI module and a bunch of other modules)
-    SET_BIT32(HHI, HHI_GCLK_MPEG2, 1, 1, 4);
-
-    // power up HDMI Memory (bits 15:8)
-    SET_BIT32(HHI, HHI_MEM_PD_REG0, 0, 8, 8);
-
-    // reset hdmi related blocks (HIU, HDMI SYS, HDMI_TX)
-    WRITE32_PRESET_REG(PRESET0_REGISTER, (1 << 19));
-    WRITE32_PRESET_REG(PRESET2_REGISTER, (1 << 15));
-    WRITE32_PRESET_REG(PRESET2_REGISTER, (1 << 2));
-
-    // // Bring HDMI out of reset
-    hdmitx_writereg(HDMITX_TOP_SW_RESET, 0);
-    spin(200);
-    hdmitx_writereg(HDMITX_TOP_CLK_CNTL, 0x000000ff);
-    hdmitx_writereg(HDMITX_DWC_MC_LOCKONCLOCK, 0xff);
-    hdmitx_writereg(HDMITX_DWC_MC_CLKDIS, 0x00);
-
-    /* Configure HDCP */
-    uint32_t data32  = 0;
-    data32 |= (0 << 7);
-    data32 |= (0 << 6);
-    data32 |= (0 << 4);
-    data32 |= (0 << 3);
-    data32 |= (0 << 2);
-    data32 |= (0 << 1);
-    data32 |= (1 << 0);
-    hdmitx_writereg(HDMITX_DWC_A_APIINTMSK, data32);
-
-    data32  = 0;
-    data32 |= (0 << 5);
-    data32 |= (1 << 4);
-    data32 |= (1 << 3);
-    data32 |= (1 << 1);
-    hdmitx_writereg(HDMITX_DWC_A_VIDPOLCFG, data32);
-
-    hdmitx_writereg(HDMITX_DWC_A_OESSWCFG, 0x40);
-
-    arm_smccc_smc(0x82000012, 0, 0, 0, 0, 0, 0, 0);
-}
-
-LK_PDEV_INIT(s912_hdcp_init, KDRV_AMLOGIC_HDCP, s912_hdcp_init, LK_INIT_LEVEL_PLATFORM);
diff --git a/kernel/dev/hdcp/amlogic_s912/rules.mk b/kernel/dev/hdcp/amlogic_s912/rules.mk
deleted file mode 100644
index e21058e..0000000
--- a/kernel/dev/hdcp/amlogic_s912/rules.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2018 The Fuchsia Authors
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/hdcp.cpp
-
-MODULE_DEPS += \
-	kernel/dev/pdev \
-
-include make/module.mk
diff --git a/kernel/dev/hw_rng/debug.cpp b/kernel/dev/hw_rng/debug.cpp
deleted file mode 100644
index c18c771..0000000
--- a/kernel/dev/hw_rng/debug.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016, Google, Inc. All rights reserved
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <dev/hw_rng.h>
-
-#include <debug.h>
-#include <fbl/algorithm.h>
-#include <lib/console.h>
-#include <stdlib.h>
-
-static int cmd_rng32(int argc, const cmd_args* argv, uint32_t flags) {
-    uint32_t val = hw_rng_get_u32();
-    printf("Random val = %u (0x%08x)\n", val, val);
-    return ZX_OK;
-}
-
-static int cmd_rng(int argc, const cmd_args* argv, uint32_t flags) {
-    if ((argc < 2) || (argc > 3)) {
-        printf("Invalid argument count\n\n"
-               "Usage : %s <N> [wait]\n"
-               "N     : Number of bytes to generate.\n"
-               "wait  : true  -> wait indefinitely for bytes to be generated\n"
-               "      : false -> terminate if HW generator runs out of entropy (default)\n",
-               argv[0].str);
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    printf("Generating %lu random bytes\n", argv[1].u);
-
-    size_t offset = 0;
-    bool wait = (argc == 3) ? argv[2].b : false;
-    while (offset < argv[1].u) {
-        uint8_t bytes[16];
-        size_t todo, done;
-
-        todo = fbl::min(sizeof(bytes), argv[1].u - offset);
-        done = hw_rng_get_entropy(bytes, todo, wait);
-        DEBUG_ASSERT(done <= todo);
-
-        hexdump8_ex(bytes, done, offset);
-        offset += done;
-
-        if (done < todo) {
-            printf("Entropy exhausted after %zu byte%s\n",
-                   offset, offset == 1 ? "" : "s");
-            break;
-        }
-    }
-
-    return ZX_OK;
-}
-
-STATIC_COMMAND_START
-STATIC_COMMAND("rng32",
-               "Generate and print a random 32 bit unsigned integer using the HW RNG",
-               &cmd_rng32)
-STATIC_COMMAND("rng",
-               "Generate and print N random bytes using the HW RNG",
-               &cmd_rng)
-STATIC_COMMAND_END(hw_rng);
diff --git a/kernel/dev/hw_rng/include/dev/hw_rng.h b/kernel/dev/hw_rng/include/dev/hw_rng.h
deleted file mode 100644
index 2d06874..0000000
--- a/kernel/dev/hw_rng/include/dev/hw_rng.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016, Google, Inc. All rights reserved
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <assert.h>
-#include <zircon/compiler.h>
-#include <debug.h>
-#include <err.h>
-#include <sys/types.h>
-
-__BEGIN_CDECLS
-
-size_t hw_rng_get_entropy(void* buf, size_t len, bool block);
-
-static inline uint32_t hw_rng_get_u32(void) {
-    uint32_t ret;
-    __UNUSED size_t fetched;
-
-    fetched = hw_rng_get_entropy(&ret, sizeof(ret), true);
-    DEBUG_ASSERT(fetched == sizeof(ret));
-    return ret;
-}
-
-__END_CDECLS
diff --git a/kernel/dev/hw_rng/rules.mk b/kernel/dev/hw_rng/rules.mk
deleted file mode 100644
index ed59e9a..0000000
--- a/kernel/dev/hw_rng/rules.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/debug.cpp
-
-include make/module.mk
diff --git a/kernel/dev/intel_rng/intel-rng.cpp b/kernel/dev/intel_rng/intel-rng.cpp
deleted file mode 100644
index 2d93caf..0000000
--- a/kernel/dev/intel_rng/intel-rng.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <dev/hw_rng.h>
-
-#include <arch/x86/feature.h>
-#include <arch/x86/x86intrin.h>
-#include <fbl/algorithm.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-
-enum entropy_instr {
-    ENTROPY_INSTR_RDSEED,
-    ENTROPY_INSTR_RDRAND,
-};
-static ssize_t get_entropy_from_instruction(void* buf, size_t len, bool block,
-                                            enum entropy_instr instr);
-static ssize_t get_entropy_from_rdseed(void* buf, size_t len, bool block);
-static ssize_t get_entropy_from_rdrand(void* buf, size_t len, bool block);
-
-/* @brief Get entropy from the CPU using RDSEED.
- *
- * len must be at most SSIZE_MAX
- *
- * If |block|=true, it will retry the RDSEED instruction until |len| bytes are
- * written to |buf|.  Otherwise, it will fetch data from RDSEED until either
- * |len| bytes are written to |buf| or RDSEED is unable to return entropy.
- *
- * Returns the number of bytes written to the buffer on success (potentially 0),
- * and a negative value on error.
- */
-static ssize_t get_entropy_from_cpu(void* buf, size_t len, bool block) {
-    /* TODO(security, ZX-984): Move this to a shared kernel/user lib, so we can write usermode
-     * tests against this code */
-
-    if (len >= SSIZE_MAX) {
-        static_assert(ZX_ERR_INVALID_ARGS < 0, "");
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (x86_feature_test(X86_FEATURE_RDSEED)) {
-        return get_entropy_from_rdseed(buf, len, block);
-    } else if (x86_feature_test(X86_FEATURE_RDRAND)) {
-        return get_entropy_from_rdrand(buf, len, block);
-    }
-
-    /* We don't have an entropy source */
-    static_assert(ZX_ERR_NOT_SUPPORTED < 0, "");
-    return ZX_ERR_NOT_SUPPORTED;
-}
-
-__attribute__((target("rdrnd,rdseed"))) static bool instruction_step(enum entropy_instr instr,
-                                                                     unsigned long long int* val) {
-    switch (instr) {
-    case ENTROPY_INSTR_RDRAND:
-        return _rdrand64_step(val);
-    case ENTROPY_INSTR_RDSEED:
-        return _rdseed64_step(val);
-    default:
-        panic("Invalid entropy instruction %d\n", (int)instr);
-    }
-}
-
-static ssize_t get_entropy_from_instruction(void* buf, size_t len, bool block,
-                                            enum entropy_instr instr) {
-
-    size_t written = 0;
-    while (written < len) {
-        unsigned long long int val = 0;
-        if (!instruction_step(instr, &val)) {
-            if (!block) {
-                break;
-            }
-            continue;
-        }
-        const size_t to_copy = fbl::min(len - written, sizeof(val));
-        memcpy(static_cast<uint8_t*>(buf) + written, &val, to_copy);
-        written += to_copy;
-    }
-    if (block) {
-        DEBUG_ASSERT(written == len);
-    }
-    return (ssize_t)written;
-}
-
-static ssize_t get_entropy_from_rdseed(void* buf, size_t len, bool block) {
-    return get_entropy_from_instruction(buf, len, block, ENTROPY_INSTR_RDSEED);
-}
-
-static ssize_t get_entropy_from_rdrand(void* buf, size_t len, bool block) {
-    // TODO(security, ZX-983): This method is not compliant with Intel's "Digital Random
-    // Number Generator (DRNG) Software Implementation Guide".  We are using
-    // rdrand in a way that is explicitly against their recommendations.  This
-    // needs to be corrected, but this fallback is a compromise to allow our
-    // development platforms that don't support RDSEED to get some degree of
-    // hardware-based randomization.
-    return get_entropy_from_instruction(buf, len, block, ENTROPY_INSTR_RDRAND);
-}
-
-size_t hw_rng_get_entropy(void* buf, size_t len, bool block) {
-    if (!len) {
-        return 0;
-    }
-
-    ssize_t res = get_entropy_from_cpu(buf, len, block);
-    if (res < 0) {
-        return 0;
-    }
-    return (size_t)res;
-}
diff --git a/kernel/dev/intel_rng/rules.mk b/kernel/dev/intel_rng/rules.mk
deleted file mode 100644
index 4d3b4f5..0000000
--- a/kernel/dev/intel_rng/rules.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/intel-rng.cpp \
-
-MODULE_DEPS += kernel/dev/hw_rng
-
-include make/module.mk
diff --git a/kernel/dev/interrupt/arm_gic/common/arm_gic_hw_interface.cpp b/kernel/dev/interrupt/arm_gic/common/arm_gic_hw_interface.cpp
deleted file mode 100644
index 3f0cf3b..0000000
--- a/kernel/dev/interrupt/arm_gic/common/arm_gic_hw_interface.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2012-2015 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-#include <dev/interrupt/arm_gic_common.h>
-#include <dev/interrupt/arm_gic_hw_interface.h>
-#include <err.h>
-#include <zircon/types.h>
-
-static const struct arm_gic_hw_interface_ops* gic_ops = nullptr;
-
-zx_status_t gic_get_gicv(paddr_t* gicv_paddr) {
-    return gic_ops->get_gicv(gicv_paddr);
-}
-
-void gic_read_gich_state(IchState* state) {
-    gic_ops->read_gich_state(state);
-}
-
-void gic_write_gich_state(IchState* state, uint32_t hcr) {
-    gic_ops->write_gich_state(state, hcr);
-}
-
-uint32_t gic_default_gich_vmcr() {
-    return gic_ops->default_gich_vmcr();
-}
-
-uint64_t gic_get_lr_from_vector(bool hw, uint8_t prio, uint32_t vector) {
-    return gic_ops->get_lr_from_vector(hw, prio, vector);
-}
-
-uint32_t gic_get_vector_from_lr(uint64_t lr) {
-    return gic_ops->get_vector_from_lr(lr);
-}
-
-uint8_t gic_get_num_pres() {
-    return gic_ops->get_num_pres();
-}
-
-uint8_t gic_get_num_lrs() {
-    return gic_ops->get_num_lrs();
-}
-
-void arm_gic_hw_interface_register(const struct arm_gic_hw_interface_ops* ops) {
-    gic_ops = ops;
-}
-
-bool arm_gic_is_registered() {
-    return gic_ops != nullptr;
-}
diff --git a/kernel/dev/interrupt/arm_gic/common/include/dev/interrupt/arm_gic_common.h b/kernel/dev/interrupt/arm_gic/common/include/dev/interrupt/arm_gic_common.h
deleted file mode 100644
index f1e2548..0000000
--- a/kernel/dev/interrupt/arm_gic/common/include/dev/interrupt/arm_gic_common.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2013, Google Inc. All rights reserved.
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <dev/interrupt.h>
-#include <sys/types.h>
-
-#define GIC_BASE_SGI 0
-#define GIC_BASE_PPI 16
-#define GIC_BASE_SPI 32
-
-// GIC Revision
-enum {
-    GICV2 = 2,
-    GICV3 = 3,
-    GICV4 = 4,
-};
-
-enum {
-    // Ignore cpu_mask and forward interrupt to all CPUs other than the current cpu
-    ARM_GIC_SGI_FLAG_TARGET_FILTER_NOT_SENDER = 0x1,
-    // Ignore cpu_mask and forward interrupt to current CPU only
-    ARM_GIC_SGI_FLAG_TARGET_FILTER_SENDER = 0x2,
-    ARM_GIC_SGI_FLAG_TARGET_FILTER_MASK = 0x3,
-
-    // Only forward the interrupt to CPUs that has the interrupt configured as group 1 (non-secure)
-    ARM_GIC_SGI_FLAG_NS = 0x4,
-};
-
-// Registers a software generated interrupt handler.
-static inline zx_status_t gic_register_sgi_handler(unsigned int vector, int_handler handler) {
-    DEBUG_ASSERT(vector < GIC_BASE_PPI);
-    return register_int_handler(vector, handler, nullptr);
-}
diff --git a/kernel/dev/interrupt/arm_gic/common/include/dev/interrupt/arm_gic_hw_interface.h b/kernel/dev/interrupt/arm_gic/common/include/dev/interrupt/arm_gic_hw_interface.h
deleted file mode 100644
index 6b9b0d0..0000000
--- a/kernel/dev/interrupt/arm_gic/common/include/dev/interrupt/arm_gic_hw_interface.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2013, Google Inc. All rights reserved.
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <zircon/types.h>
-
-struct IchState;
-
-// GIC HW interface
-struct arm_gic_hw_interface_ops {
-    zx_status_t (*get_gicv)(paddr_t* gicv_paddr);
-    void (*read_gich_state)(IchState* state);
-    void (*write_gich_state)(IchState* state, uint32_t hcr);
-    uint32_t (*default_gich_vmcr)();
-    uint64_t (*get_lr_from_vector)(bool hw, uint8_t prio, uint32_t vector);
-    uint32_t (*get_vector_from_lr)(uint64_t lr);
-    uint8_t (*get_num_pres)();
-    uint8_t (*get_num_lrs)();
-};
-
-// Get the GICV physical address.
-zx_status_t gic_get_gicv(paddr_t* gicv_paddr);
-
-// Reads the GICH state.
-void gic_read_gich_state(IchState* state);
-
-// Writes the GICH state.
-void gic_write_gich_state(IchState* state, uint32_t hcr);
-
-// Returns the default GICH_VMCR value. Used to initialize GICH_VMCR.
-uint32_t gic_default_gich_vmcr();
-
-// Returns a list register based on the given interrupt vector.
-uint64_t gic_get_lr_from_vector(bool hw, uint8_t prio, uint32_t vector);
-
-// Returns an interrupt vector based on the given list register.
-uint32_t gic_get_vector_from_lr(uint64_t lr);
-
-// Returns the number of preemption bits.
-uint8_t gic_get_num_pres();
-
-// Returns the number of list registers.
-uint8_t gic_get_num_lrs();
-
-// Registers the ops of the GIC driver initialized with HW interface layer.
-void arm_gic_hw_interface_register(const struct arm_gic_hw_interface_ops* ops);
-
-// Returns whether the GIC driver has been registered.
-bool arm_gic_is_registered();
diff --git a/kernel/dev/interrupt/arm_gic/common/rules.mk b/kernel/dev/interrupt/arm_gic/common/rules.mk
deleted file mode 100644
index f8cdf35..0000000
--- a/kernel/dev/interrupt/arm_gic/common/rules.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/arm_gic_hw_interface.cpp \
-
-include make/module.mk
diff --git a/kernel/dev/interrupt/arm_gic/v2/arm_gicv2.cpp b/kernel/dev/interrupt/arm_gic/v2/arm_gicv2.cpp
deleted file mode 100644
index b2976e9..0000000
--- a/kernel/dev/interrupt/arm_gic/v2/arm_gicv2.cpp
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2012-2015 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arm64/hypervisor/gic/gicv2.h>
-#include <arch/arm64/periphmap.h>
-#include <arch/ops.h>
-#include <assert.h>
-#include <bits.h>
-#include <debug.h>
-#include <dev/interrupt.h>
-#include <dev/interrupt/arm_gic_common.h>
-#include <dev/interrupt/arm_gicv2_regs.h>
-#include <dev/interrupt/arm_gicv2m.h>
-#include <dev/interrupt/arm_gicv2m_msi.h>
-#include <err.h>
-#include <inttypes.h>
-#include <kernel/stats.h>
-#include <kernel/thread.h>
-#include <lib/ktrace.h>
-#include <lk/init.h>
-#include <pdev/driver.h>
-#include <pdev/interrupt.h>
-#include <reg.h>
-#include <sys/types.h>
-#include <trace.h>
-#include <zircon/boot/driver-config.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-#include <arch/arm64.h>
-#define iframe arm64_iframe_short
-#define IFRAME_PC(frame) ((frame)->elr)
-
-static spin_lock_t gicd_lock;
-#define GICD_LOCK_FLAGS SPIN_LOCK_FLAG_INTERRUPTS
-
-// values read from zbi
-vaddr_t arm_gicv2_gic_base = 0;
-uint64_t arm_gicv2_gicd_offset = 0;
-uint64_t arm_gicv2_gicc_offset = 0;
-uint64_t arm_gicv2_gich_offset = 0;
-uint64_t arm_gicv2_gicv_offset = 0;
-static uint32_t ipi_base = 0;
-
-static uint max_irqs = 0;
-
-static zx_status_t arm_gic_init();
-
-static zx_status_t gic_configure_interrupt(unsigned int vector,
-                                           enum interrupt_trigger_mode tm,
-                                           enum interrupt_polarity pol);
-
-static void suspend_resume_fiq(bool resume_gicc, bool resume_gicd) {
-}
-
-static bool gic_is_valid_interrupt(uint vector, uint32_t flags) {
-    return (vector < max_irqs);
-}
-
-static uint32_t gic_get_base_vector() {
-    // ARM Generic Interrupt Controller v2 chapter 2.1
-    // INTIDs 0-15 are local CPU interrupts
-    return 16;
-}
-
-static uint32_t gic_get_max_vector() {
-    return max_irqs;
-}
-
-static void gic_set_enable(uint vector, bool enable) {
-    int reg = vector / 32;
-    uint32_t mask = (uint32_t)(1ULL << (vector % 32));
-
-    if (enable) {
-        GICREG(0, GICD_ISENABLER(reg)) = mask;
-    } else {
-        GICREG(0, GICD_ICENABLER(reg)) = mask;
-    }
-}
-
-static void gic_init_percpu_early() {
-    GICREG(0, GICC_CTLR) = 0x201;   // EnableGrp1 and EOImodeNS
-    GICREG(0, GICC_PMR) = 0xff;     // unmask interrupts at all priority levels
-}
-
-static void arm_gic_suspend_cpu(uint level) {
-    suspend_resume_fiq(false, false);
-}
-
-static void arm_gic_resume_cpu(uint level) {
-    spin_lock_saved_state_t state;
-    bool resume_gicd = false;
-
-    spin_lock_save(&gicd_lock, &state, GICD_LOCK_FLAGS);
-    if (!(GICREG(0, GICD_CTLR) & 1)) {
-        dprintf(SPEW, "%s: distributor is off, calling arm_gic_init instead\n", __func__);
-        arm_gic_init();
-        resume_gicd = true;
-    } else {
-        gic_init_percpu_early();
-    }
-    spin_unlock_restore(&gicd_lock, state, GICD_LOCK_FLAGS);
-    suspend_resume_fiq(true, resume_gicd);
-}
-
-// disable for now. we will need to add suspend/resume support to dev/pdev for this to work
-#if 0
-LK_INIT_HOOK_FLAGS(arm_gic_suspend_cpu, arm_gic_suspend_cpu,
-                   LK_INIT_LEVEL_PLATFORM, LK_INIT_FLAG_CPU_SUSPEND);
-
-LK_INIT_HOOK_FLAGS(arm_gic_resume_cpu, arm_gic_resume_cpu,
-                   LK_INIT_LEVEL_PLATFORM, LK_INIT_FLAG_CPU_RESUME);
-#endif
-
-static int arm_gic_max_cpu() {
-    return (GICREG(0, GICD_TYPER) >> 5) & 0x7;
-}
-
-static zx_status_t arm_gic_init() {
-    uint i;
-    // see if we're gic v2
-    uint rev = 0;
-    uint32_t pidr2 = GICREG(0, GICD_PIDR2);
-    if (pidr2 != 0) {
-        uint rev = BITS_SHIFT(pidr2, 7, 4);
-        if (rev != GICV2) {
-            return ZX_ERR_NOT_FOUND;
-        }
-    } else {
-        // some v2's return a null PIDR2
-        pidr2 = GICREG(0, GICD_V3_PIDR2);
-        rev = BITS_SHIFT(pidr2, 7, 4);
-        if (rev >= GICV3) {
-            // looks like a gic v3
-            return ZX_ERR_NOT_FOUND;
-        }
-        // HACK: if gicv2 and v3 pidr2 seems to be blank, assume we're v2 and continue
-    }
-
-    uint32_t typer = GICREG(0, GICD_TYPER);
-    uint32_t it_lines_number = BITS_SHIFT(typer, 4, 0);
-    max_irqs = (it_lines_number + 1) * 32;
-    LTRACEF("arm_gic_init max_irqs: %u\n", max_irqs);
-    assert(max_irqs <= MAX_INT);
-
-    for (i = 0; i < max_irqs; i += 32) {
-        GICREG(0, GICD_ICENABLER(i / 32)) = ~0;
-        GICREG(0, GICD_ICPENDR(i / 32)) = ~0;
-    }
-
-    if (arm_gic_max_cpu() > 0) {
-        // Set external interrupts to target cpu 0
-        for (i = 32; i < max_irqs; i += 4) {
-            GICREG(0, GICD_ITARGETSR(i / 4)) = 0x01010101;
-        }
-    }
-    // Initialize all the SPIs to edge triggered
-    for (i = GIC_BASE_SPI; i < max_irqs; i++) {
-        gic_configure_interrupt(i, IRQ_TRIGGER_MODE_EDGE, IRQ_POLARITY_ACTIVE_HIGH);
-    }
-
-    GICREG(0, GICD_CTLR) = 1; // enable GIC0
-
-    gic_init_percpu_early();
-
-    return ZX_OK;
-}
-
-static zx_status_t arm_gic_sgi(u_int irq, u_int flags, u_int cpu_mask) {
-    u_int val =
-        ((flags & ARM_GIC_SGI_FLAG_TARGET_FILTER_MASK) << 24) |
-        ((cpu_mask & 0xff) << 16) |
-        ((flags & ARM_GIC_SGI_FLAG_NS) ? (1U << 15) : 0) |
-        (irq & 0xf);
-
-    if (irq >= 16) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    LTRACEF("GICD_SGIR: %x\n", val);
-
-    GICREG(0, GICD_SGIR) = val;
-
-    return ZX_OK;
-}
-
-static zx_status_t gic_mask_interrupt(unsigned int vector) {
-    if (vector >= max_irqs) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    gic_set_enable(vector, false);
-
-    return ZX_OK;
-}
-
-static zx_status_t gic_unmask_interrupt(unsigned int vector) {
-    if (vector >= max_irqs) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    gic_set_enable(vector, true);
-
-    return ZX_OK;
-}
-
-static zx_status_t gic_configure_interrupt(unsigned int vector,
-                                           enum interrupt_trigger_mode tm,
-                                           enum interrupt_polarity pol) {
-    // Only configurable for SPI interrupts
-    if ((vector >= max_irqs) || (vector < GIC_BASE_SPI)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (pol != IRQ_POLARITY_ACTIVE_HIGH) {
-        // TODO: polarity should actually be configure through a GPIO controller
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-
-    // type is encoded with two bits, MSB of the two determine type
-    // 16 irqs encoded per ICFGR register
-    uint32_t reg_ndx = vector >> 4;
-    uint32_t bit_shift = ((vector & 0xf) << 1) + 1;
-    uint32_t reg_val = GICREG(0, GICD_ICFGR(reg_ndx));
-    if (tm == IRQ_TRIGGER_MODE_EDGE) {
-        reg_val |= (1 << bit_shift);
-    } else {
-        reg_val &= ~(1 << bit_shift);
-    }
-    GICREG(0, GICD_ICFGR(reg_ndx)) = reg_val;
-
-    return ZX_OK;
-}
-
-static zx_status_t gic_get_interrupt_config(unsigned int vector,
-                                            enum interrupt_trigger_mode* tm,
-                                            enum interrupt_polarity* pol) {
-    if (vector >= max_irqs) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (tm) {
-        *tm = IRQ_TRIGGER_MODE_EDGE;
-    }
-    if (pol) {
-        *pol = IRQ_POLARITY_ACTIVE_HIGH;
-    }
-
-    return ZX_OK;
-}
-
-static unsigned int gic_remap_interrupt(unsigned int vector) {
-    return vector;
-}
-
-static void gic_handle_irq(struct iframe* frame) {
-    // get the current vector
-    uint32_t iar = GICREG(0, GICC_IAR);
-    unsigned int vector = iar & 0x3ff;
-
-    if (vector >= 0x3fe) {
-        // spurious
-        return;
-    }
-
-    // tracking external hardware irqs in this variable
-    if (vector >= 32)
-        CPU_STATS_INC(interrupts);
-
-    uint cpu = arch_curr_cpu_num();
-
-    ktrace_tiny(TAG_IRQ_ENTER, (vector << 8) | cpu);
-
-    LTRACEF_LEVEL(2, "iar 0x%x cpu %u currthread %p vector %u pc %#" PRIxPTR "\n", iar, cpu,
-                  get_current_thread(), vector, (uintptr_t)IFRAME_PC(frame));
-
-    // deliver the interrupt
-    struct int_handler_struct* handler = pdev_get_int_handler(vector);
-    interrupt_eoi eoi = IRQ_EOI_DEACTIVATE;
-    if (handler->handler) {
-        eoi = handler->handler(handler->arg);
-    }
-    GICREG(0, GICC_EOIR) = iar;
-    if (eoi == IRQ_EOI_DEACTIVATE) {
-        GICREG(0, GICC_DIR) = iar;
-    }
-
-    LTRACEF_LEVEL(2, "cpu %u exit\n", cpu);
-
-    ktrace_tiny(TAG_IRQ_EXIT, (vector << 8) | cpu);
-}
-
-static void gic_handle_fiq(struct iframe* frame) {
-    PANIC_UNIMPLEMENTED;
-}
-
-static zx_status_t gic_send_ipi(cpu_mask_t target, mp_ipi_t ipi) {
-    uint gic_ipi_num = ipi + ipi_base;
-
-    // filter out targets outside of the range of cpus we care about
-    target &= ((1UL << SMP_MAX_CPUS) - 1);
-    if (target != 0) {
-        LTRACEF("target 0x%x, gic_ipi %u\n", target, gic_ipi_num);
-        arm_gic_sgi(gic_ipi_num, ARM_GIC_SGI_FLAG_NS, target);
-    }
-
-    return ZX_OK;
-}
-
-static interrupt_eoi arm_ipi_halt_handler(void*) {
-    LTRACEF("cpu %u\n", arch_curr_cpu_num());
-
-    arch_disable_ints();
-    while (true) {
-    }
-
-    return IRQ_EOI_DEACTIVATE;
-}
-
-static void gic_init_percpu() {
-    mp_set_curr_cpu_online(true);
-    unmask_interrupt(MP_IPI_GENERIC + ipi_base);
-    unmask_interrupt(MP_IPI_RESCHEDULE + ipi_base);
-    unmask_interrupt(MP_IPI_INTERRUPT + ipi_base);
-    unmask_interrupt(MP_IPI_HALT + ipi_base);
-}
-
-static void gic_shutdown() {
-    // Turn off all GIC0 interrupts at the distributor.
-    GICREG(0, GICD_CTLR) = 0;
-}
-
-// Returns true if any PPIs are enabled on the calling CPU.
-static bool is_ppi_enabled() {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    // PPIs are 16-31.
-    uint32_t ppi_mask = 0xffff0000;
-
-    // GICD_ISENABLER0 is banked so it corresponds to *this* CPU's interface.
-    return (GICREG(0, GICD_ISENABLER(0)) & ppi_mask) != 0;
-}
-
-// Returns true if any SPIs are enabled on the calling CPU.
-static bool is_spi_enabled() {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    // We're going to check four interrupts at a time.  Build a repeated mask for the current CPU.
-    // Each byte in the mask is a CPU bit mask corresponding to CPU0..CPU7 (lsb..msb).
-    uint cpu_num = arch_curr_cpu_num();
-    DEBUG_ASSERT(cpu_num < 8);
-    uint32_t mask = 0x01010101U << cpu_num;
-
-    for (unsigned int vector = GIC_BASE_SPI; vector < max_irqs; vector += 4) {
-        uint32_t reg = GICREG(0, GICD_ITARGETSR(vector / 4));
-        if (reg & mask) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static void gic_shutdown_cpu() {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    // Before we shutdown the GIC, make sure we've migrated/disabled any and all peripheral
-    // interrupts targeted at this CPU (PPIs and SPIs).
-    DEBUG_ASSERT(!is_ppi_enabled());
-    DEBUG_ASSERT(!is_spi_enabled());
-
-    // Turn off interrupts at the CPU interface.
-    GICREG(0, GICC_CTLR) = 0;
-}
-
-static const struct pdev_interrupt_ops gic_ops = {
-    .mask = gic_mask_interrupt,
-    .unmask = gic_unmask_interrupt,
-    .configure = gic_configure_interrupt,
-    .get_config = gic_get_interrupt_config,
-    .is_valid = gic_is_valid_interrupt,
-    .get_base_vector = gic_get_base_vector,
-    .get_max_vector = gic_get_max_vector,
-    .remap = gic_remap_interrupt,
-    .send_ipi = gic_send_ipi,
-    .init_percpu_early = gic_init_percpu_early,
-    .init_percpu = gic_init_percpu,
-    .handle_irq = gic_handle_irq,
-    .handle_fiq = gic_handle_fiq,
-    .shutdown = gic_shutdown,
-    .shutdown_cpu = gic_shutdown_cpu,
-    .msi_is_supported = arm_gicv2m_msi_is_supported,
-    .msi_supports_masking = arm_gicv2m_msi_supports_masking,
-    .msi_mask_unmask = arm_gicv2m_msi_mask_unmask,
-    .msi_alloc_block = arm_gicv2m_msi_alloc_block,
-    .msi_free_block = arm_gicv2m_msi_free_block,
-    .msi_register_handler = arm_gicv2m_msi_register_handler,
-};
-
-static void arm_gic_v2_init(const void* driver_data, uint32_t length) {
-    ASSERT(length >= sizeof(dcfg_arm_gicv2_driver_t));
-    auto driver = static_cast<const dcfg_arm_gicv2_driver_t*>(driver_data);
-    ASSERT(driver->mmio_phys);
-
-    arm_gicv2_gic_base = periph_paddr_to_vaddr(driver->mmio_phys);
-    ASSERT(arm_gicv2_gic_base);
-    arm_gicv2_gicd_offset = driver->gicd_offset;
-    arm_gicv2_gicc_offset = driver->gicc_offset;
-    arm_gicv2_gich_offset = driver->gich_offset;
-    arm_gicv2_gicv_offset = driver->gicv_offset;
-    ipi_base = driver->ipi_base;
-
-    if (arm_gic_init() != ZX_OK) {
-        if (driver->optional) {
-            // failed to detect gic v2 but it's marked optional. continue
-            return;
-        }
-        printf("GICv2: failed to detect GICv2, interrupts will be broken\n");
-        return;
-    }
-
-    dprintf(SPEW, "detected GICv2 (ID %#x)\n", GICREG(0, GICC_IIDR));
-
-    // pass the list of physical and virtual addresses for the GICv2m register apertures
-    if (driver->msi_frame_phys) {
-        // the following arrays must be static because arm_gicv2m_init stashes the pointer
-        static paddr_t GICV2M_REG_FRAMES[] = {0};
-        static vaddr_t GICV2M_REG_FRAMES_VIRT[] = {0};
-
-        GICV2M_REG_FRAMES[0] = driver->msi_frame_phys;
-        GICV2M_REG_FRAMES_VIRT[0] = periph_paddr_to_vaddr(driver->msi_frame_phys);
-        ASSERT(GICV2M_REG_FRAMES_VIRT[0]);
-        arm_gicv2m_init(GICV2M_REG_FRAMES, GICV2M_REG_FRAMES_VIRT, countof(GICV2M_REG_FRAMES));
-    }
-    pdev_register_interrupts(&gic_ops);
-
-    zx_status_t status = gic_register_sgi_handler(MP_IPI_GENERIC + ipi_base, &mp_mbx_generic_irq);
-    DEBUG_ASSERT(status == ZX_OK);
-    status = gic_register_sgi_handler(MP_IPI_RESCHEDULE + ipi_base, &mp_mbx_reschedule_irq);
-    DEBUG_ASSERT(status == ZX_OK);
-    status = gic_register_sgi_handler(MP_IPI_INTERRUPT + ipi_base, &mp_mbx_interrupt_irq);
-    DEBUG_ASSERT(status == ZX_OK);
-    status = gic_register_sgi_handler(MP_IPI_HALT + ipi_base, &arm_ipi_halt_handler);
-    DEBUG_ASSERT(status == ZX_OK);
-
-    gicv2_hw_interface_register();
-}
-
-LK_PDEV_INIT(arm_gic_v2_init, KDRV_ARM_GIC_V2, arm_gic_v2_init, LK_INIT_LEVEL_PLATFORM_EARLY);
diff --git a/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m.cpp b/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m.cpp
deleted file mode 100644
index ffd8082..0000000
--- a/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016, Google Inc. All rights reserved.
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <assert.h>
-#include <dev/interrupt/arm_gic_common.h>
-#include <dev/interrupt/arm_gicv2_regs.h>
-#include <dev/interrupt/arm_gicv2m.h>
-#include <err.h>
-#include <string.h>
-#include <trace.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-// Section 9.7
-#define MSI_TYPER_OFFSET (0x008)     // Type Register
-#define MSI_SETSPI_NS_OFFSET (0x040) // Doorbell register (whack here for interrupt)
-#define MSI_IIDR_OFFSET (0xFCC)      // Interface ID register
-#define REG_RD(base, off) (((volatile uint32_t*)(base))[(off) >> 2])
-
-// Section 9.9.1
-#define MIN_VALID_MSI_SPI (32)
-#define MAX_VALID_MSI_SPI (1020)
-
-static const paddr_t* g_reg_frames;
-static const vaddr_t* g_reg_frames_virt;
-static uint g_reg_frame_count;
-
-void arm_gicv2m_init(const paddr_t* reg_frames, const vaddr_t* reg_frames_virt, const uint reg_frame_count) {
-    // Protect against double init.
-    DEBUG_ASSERT(!g_reg_frames);
-    DEBUG_ASSERT(!g_reg_frame_count);
-
-    // If the user has no register frames, they should be using arm_gic, not
-    // arm_gicv2m
-    DEBUG_ASSERT(reg_frames);
-    DEBUG_ASSERT(reg_frame_count);
-
-    // Stash the frame info
-    g_reg_frames = reg_frames;
-    g_reg_frames_virt = reg_frames_virt;
-    g_reg_frame_count = reg_frame_count;
-
-    // Walk the list of regions, and make sure that all of the controlled SPIs
-    // are configured for edge triggered mode.
-    for (uint i = 0; i < g_reg_frame_count; ++i) {
-        uint32_t type_reg = REG_RD(g_reg_frames_virt[i], MSI_TYPER_OFFSET);
-        uint base_spi = (type_reg >> 16) & 0x3FF;
-        uint num_spi = type_reg & 0x3FF;
-
-        dprintf(SPEW, "GICv2m %u: base spi %u count %u\n", i, base_spi, num_spi);
-
-        for (uint i = 0; i < num_spi; ++i) {
-            uint spi_id = base_spi + i;
-            if ((spi_id < MIN_VALID_MSI_SPI) || (spi_id > MAX_VALID_MSI_SPI)) {
-                TRACEF("Invalid SPI ID (%u) found in GICv2m register frame @%p\n",
-                       spi_id, (void*)g_reg_frames[i]);
-                continue;
-            }
-
-            uint reg_ndx = spi_id >> 4;
-            uint bit_shift = ((spi_id & 0xF) << 1) + 1;
-            uint32_t reg_val = GICREG(0, GICD_ICFGR(reg_ndx));
-            reg_val |= (0x1u << bit_shift);
-            GICREG(0, GICD_ICFGR(reg_ndx)) = reg_val;
-        }
-    }
-}
-
-zx_status_t arm_gicv2m_get_frame_info(const uint frame_ndx, arm_gicv2m_frame_info_t* out_info) {
-    if (!out_info) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    *out_info = {};
-
-    if (!g_reg_frames || !g_reg_frame_count) {
-        return ZX_ERR_UNAVAILABLE;
-    }
-
-    if (frame_ndx >= g_reg_frame_count) {
-        return ZX_ERR_NOT_FOUND;
-    }
-
-    uint32_t type_reg = REG_RD(g_reg_frames_virt[frame_ndx], MSI_TYPER_OFFSET);
-    uint base_spi = (type_reg >> 16) & 0x3FF;
-    uint num_spi = type_reg & 0x3FF;
-    uint last_spi = base_spi + num_spi - 1;
-
-    if (!num_spi ||
-        (base_spi < MIN_VALID_MSI_SPI) ||
-        (last_spi > MAX_VALID_MSI_SPI)) {
-        return ZX_ERR_BAD_STATE;
-    }
-
-    out_info->start_spi_id = base_spi;
-    out_info->end_spi_id = last_spi;
-    out_info->doorbell = g_reg_frames[frame_ndx] + MSI_SETSPI_NS_OFFSET;
-    out_info->iid = REG_RD(g_reg_frames_virt[frame_ndx], MSI_IIDR_OFFSET);
-
-    return ZX_OK;
-}
diff --git a/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m_msi.cpp b/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m_msi.cpp
deleted file mode 100644
index 5d17788..0000000
--- a/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m_msi.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016, Google Inc. All rights reserved.
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <dev/interrupt/arm_gicv2m.h>
-#include <dev/interrupt/arm_gicv2m_msi.h>
-#include <lib/pow2_range_allocator.h>
-#include <pow2.h>
-#include <string.h>
-#include <sys/types.h>
-#include <trace.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-p2ra_state_t g_32bit_targets;
-p2ra_state_t g_64bit_targets;
-
-static bool g_msi_initialized = false;
-zx_status_t arm_gicv2m_msi_init() {
-    zx_status_t ret;
-
-    ret = p2ra_init(&g_32bit_targets, MAX_MSI_IRQS);
-    if (ret != ZX_OK) {
-        TRACEF("Failed to initialize 32 bit allocation pool!\n");
-        return ret;
-    }
-
-    ret = p2ra_init(&g_64bit_targets, MAX_MSI_IRQS);
-    if (ret != ZX_OK) {
-        TRACEF("Failed to initialize 64 bit allocation pool!\n");
-        p2ra_free(&g_32bit_targets);
-        return ret;
-    }
-
-    /* TODO(johngro)
-     *
-     * Right now, the pow2 range allocator will not accept overlapping ranges.
-     * It may be possible for fancy GIC implementations to have multiple MSI
-     * frames aligned on 4k boundaries (for virtualisation) with either
-     * completely or partially overlapping IRQ ranges.  If/when we need to deal
-     * with hardware like this, we will need to come back here and make this
-     * system more sophisticated.
-     */
-    arm_gicv2m_frame_info_t info;
-    for (uint i = 0; arm_gicv2m_get_frame_info(i, &info) == ZX_OK; ++i) {
-        p2ra_state_t* pool = ((uint64_t)info.doorbell & 0xFFFFFFFF00000000)
-                                 ? &g_64bit_targets
-                                 : &g_32bit_targets;
-
-        uint len = info.end_spi_id - info.start_spi_id + 1;
-        ret = p2ra_add_range(pool, info.start_spi_id, len);
-        if (ret != ZX_OK) {
-            TRACEF("Failed to add MSI IRQ range [%u, %u] to allocator (ret %d).\n",
-                   info.start_spi_id, len, ret);
-            goto finished;
-        }
-    }
-
-finished:
-    if (ret != ZX_OK) {
-        p2ra_free(&g_32bit_targets);
-        p2ra_free(&g_64bit_targets);
-    }
-
-    g_msi_initialized = true;
-    return ret;
-}
-
-zx_status_t arm_gicv2m_msi_alloc_block(uint requested_irqs,
-                                       bool can_target_64bit,
-                                       bool is_msix,
-                                       msi_block_t* out_block) {
-    if (!out_block)
-        return ZX_ERR_INVALID_ARGS;
-
-    if (out_block->allocated)
-        return ZX_ERR_BAD_STATE;
-
-    if (!requested_irqs || (requested_irqs > MAX_MSI_IRQS))
-        return ZX_ERR_INVALID_ARGS;
-
-    zx_status_t ret = ZX_ERR_INTERNAL;
-    bool is_32bit = false;
-    uint alloc_size = 1u << log2_uint_ceil(requested_irqs);
-    uint alloc_start;
-
-    /* If this MSI request can tolerate a 64 bit target address, start by
-     * attempting to allocate from the 64 bit pool */
-    if (can_target_64bit)
-        ret = p2ra_allocate_range(&g_64bit_targets, alloc_size, &alloc_start);
-
-    /* No allocation yet?  Fall back on the 32 bit pool */
-    if (ret != ZX_OK) {
-        ret = p2ra_allocate_range(&g_32bit_targets, alloc_size, &alloc_start);
-        is_32bit = true;
-    }
-
-    /* If we have not managed to allocate yet, then we fail */
-    if (ret != ZX_OK)
-        return ret;
-
-    /* Find the target physical address for this allocation.
-     *
-     * TODO(johngro) : we could make this O(k) instead of O(n) by associating a
-     * context pointer with ranges registered with the pow2 allocator.  Right
-     * now, however, N tends to be 1, so it is difficult to be too concerned
-     * about this.
-     */
-    arm_gicv2m_frame_info_t info;
-    for (uint i = 0; (ret = arm_gicv2m_get_frame_info(i, &info)) == ZX_OK; ++i) {
-        uint alloc_end = alloc_start + alloc_size - 1;
-
-        if (((alloc_start >= info.start_spi_id) && (alloc_start <= info.end_spi_id)) &&
-            ((alloc_end >= info.start_spi_id) && (alloc_end <= info.end_spi_id)))
-            break;
-    }
-
-    /* This should never ever fail */
-    DEBUG_ASSERT(ret == ZX_OK);
-    if (ret != ZX_OK) {
-        p2ra_free_range(is_32bit ? &g_32bit_targets : &g_64bit_targets, alloc_start, alloc_size);
-        return ret;
-    }
-
-    LTRACEF("success: base spi %u size %u\n", alloc_start, alloc_size);
-
-    /* Success!  Fill out the bookkeeping and we are done */
-    out_block->platform_ctx = (void*)is_32bit;
-    out_block->base_irq_id = alloc_start;
-    out_block->num_irq = alloc_size;
-    out_block->tgt_addr = info.doorbell;
-    out_block->tgt_data = alloc_start;
-    out_block->allocated = true;
-    return ZX_OK;
-}
-
-bool arm_gicv2m_msi_is_supported() {
-    return g_msi_initialized;
-}
-
-bool arm_gicv2m_msi_supports_masking() {
-    return g_msi_initialized;
-}
-
-void arm_gicv2m_msi_free_block(msi_block_t* block) {
-    DEBUG_ASSERT(block);
-    DEBUG_ASSERT(block->allocated);
-
-    /* We stashed whether or not this came from the 32 bit pool in the platform context pointer */
-    p2ra_state_t* pool = block->platform_ctx ? &g_32bit_targets : &g_64bit_targets;
-    p2ra_free_range(pool, block->base_irq_id, block->num_irq);
-    memset(block, 0, sizeof(*block));
-}
-
-void arm_gicv2m_msi_register_handler(const msi_block_t* block,
-                                     uint msi_id,
-                                     int_handler handler,
-                                     void* ctx) {
-    DEBUG_ASSERT(block && block->allocated);
-    DEBUG_ASSERT(msi_id < block->num_irq);
-    zx_status_t status = register_int_handler(block->base_irq_id + msi_id, handler, ctx);
-    DEBUG_ASSERT(status == ZX_OK);
-}
-
-void arm_gicv2m_msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask) {
-    DEBUG_ASSERT(block && block->allocated);
-    DEBUG_ASSERT(msi_id < block->num_irq);
-    if (mask)
-        mask_interrupt(block->base_irq_id + msi_id);
-    else
-        unmask_interrupt(block->base_irq_id + msi_id);
-}
diff --git a/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m_pcie.cpp b/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m_pcie.cpp
deleted file mode 100644
index 786ad39..0000000
--- a/kernel/dev/interrupt/arm_gic/v2/arm_gicv2m_pcie.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2012-2015 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#if WITH_KERNEL_PCIE
-#include <dev/interrupt/arm_gicv2m_msi.h>
-#include <dev/pcie_bus_driver.h>
-#include <dev/pcie_platform.h>
-#include <dev/pcie_root.h>
-#include <fbl/alloc_checker.h>
-#include <fbl/ref_ptr.h>
-#include <inttypes.h>
-#include <lk/init.h>
-#include <pdev/driver.h>
-#include <pdev/interrupt.h>
-#include <trace.h>
-#include <zircon/boot/driver-config.h>
-#include <zircon/types.h>
-
-class ArmGicV2PciePlatformSupport : public PciePlatformInterface {
-public:
-    ArmGicV2PciePlatformSupport(bool has_msi_gic)
-        : PciePlatformInterface(has_msi_gic ? MsiSupportLevel::MSI_WITH_MASKING
-                                            : MsiSupportLevel::NONE) {}
-
-    zx_status_t AllocMsiBlock(uint requested_irqs,
-                              bool can_target_64bit,
-                              bool is_msix,
-                              msi_block_t* out_block) override {
-        return arm_gicv2m_msi_alloc_block(requested_irqs, can_target_64bit, is_msix, out_block);
-    }
-
-    void FreeMsiBlock(msi_block_t* block) override {
-        arm_gicv2m_msi_free_block(block);
-    }
-
-    void RegisterMsiHandler(const msi_block_t* block,
-                            uint msi_id,
-                            int_handler handler,
-                            void* ctx) override {
-        arm_gicv2m_msi_register_handler(block, msi_id, handler, ctx);
-    }
-
-    void MaskUnmaskMsi(const msi_block_t* block,
-                       uint msi_id,
-                       bool mask) override {
-        arm_gicv2m_msi_mask_unmask(block, msi_id, mask);
-    }
-};
-
-static void arm_gicv2_pcie_init(const void* driver_data, uint32_t length) {
-    ASSERT(length >= sizeof(dcfg_arm_gicv2_driver_t));
-    const dcfg_arm_gicv2_driver_t* driver =
-        reinterpret_cast<const dcfg_arm_gicv2_driver_t*>(driver_data);
-
-    // based on whether or not ZBI says we support MSI, initialize the v2m allocator
-    zx_status_t res;
-    bool use_msi;
-    if (driver->use_msi) {
-        dprintf(SPEW, "GICv2 MSI init\n");
-
-        // Initialize the MSI allocator
-        res = arm_gicv2m_msi_init();
-        if (res != ZX_OK) {
-            TRACEF("Failed to initialize MSI allocator (res = %d).  PCI will be "
-                   "restricted to legacy IRQ mode.\n",
-                   res);
-        }
-        use_msi = (res == ZX_OK);
-    } else {
-        use_msi = false;
-    }
-
-    // Initialize the PCI platform supported based on whether or not we support MSI
-    static ArmGicV2PciePlatformSupport platform_pcie_support(use_msi);
-
-    res = PcieBusDriver::InitializeDriver(platform_pcie_support);
-    if (res != ZX_OK) {
-        TRACEF("Failed to initialize PCI bus driver (res %d).  "
-               "PCI will be non-functional.\n",
-               res);
-    }
-}
-
-LK_PDEV_INIT(arm_gicv2_pcie_init, KDRV_ARM_GIC_V2, arm_gicv2_pcie_init, LK_INIT_LEVEL_PLATFORM);
-
-#endif // if WITH_KERNEL_PCIE
diff --git a/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2_regs.h b/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2_regs.h
deleted file mode 100644
index 1aee131..0000000
--- a/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2_regs.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2012-2016 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include <reg.h>
-
-extern uint64_t arm_gicv2_gic_base;
-extern uint64_t arm_gicv2_gicd_offset;
-extern uint64_t arm_gicv2_gicc_offset;
-extern uint64_t arm_gicv2_gich_offset;
-extern uint64_t arm_gicv2_gicv_offset;
-
-#define GICREG(gic, reg) (*REG32(arm_gicv2_gic_base + (reg)))
-#define GICD_OFFSET arm_gicv2_gicd_offset
-#define GICC_OFFSET arm_gicv2_gicc_offset
-#define GICH_OFFSET arm_gicv2_gich_offset
-#define GICV_OFFSET arm_gicv2_gicv_offset
-
-// CPU interface registers.
-#define GICC_CTLR (GICC_OFFSET + 0x0000)
-#define GICC_PMR (GICC_OFFSET + 0x0004)
-#define GICC_BPR (GICC_OFFSET + 0x0008)
-#define GICC_IAR (GICC_OFFSET + 0x000c)
-#define GICC_EOIR (GICC_OFFSET + 0x0010)
-#define GICC_RPR (GICC_OFFSET + 0x0014)
-#define GICC_HPPIR (GICC_OFFSET + 0x0018)
-#define GICC_APBR (GICC_OFFSET + 0x001c)
-#define GICC_AIAR (GICC_OFFSET + 0x0020)
-#define GICC_AEOIR (GICC_OFFSET + 0x0024)
-#define GICC_AHPPIR (GICC_OFFSET + 0x0028)
-#define GICC_APR(n) (GICC_OFFSET + 0x00d0 + (n)*4)
-#define GICC_NSAPR(n) (GICC_OFFSET + 0x00e0 + (n)*4)
-#define GICC_IIDR (GICC_OFFSET + 0x00fc)
-#define GICC_DIR (GICC_OFFSET + 0x1000)
-
-// Distributor registers.
-#define GICD_CTLR (GICD_OFFSET + 0x000)
-#define GICD_TYPER (GICD_OFFSET + 0x004)
-#define GICD_IIDR (GICD_OFFSET + 0x008)
-#define GICD_IGROUPR(n) (GICD_OFFSET + 0x080 + (n)*4)
-#define GICD_ISENABLER(n) (GICD_OFFSET + 0x100 + (n)*4)
-#define GICD_ICENABLER(n) (GICD_OFFSET + 0x180 + (n)*4)
-#define GICD_ISPENDR(n) (GICD_OFFSET + 0x200 + (n)*4)
-#define GICD_ICPENDR(n) (GICD_OFFSET + 0x280 + (n)*4)
-#define GICD_ISACTIVER(n) (GICD_OFFSET + 0x300 + (n)*4)
-#define GICD_ICACTIVER(n) (GICD_OFFSET + 0x380 + (n)*4)
-#define GICD_IPRIORITYR(n) (GICD_OFFSET + 0x400 + (n)*4)
-#define GICD_ITARGETSR(n) (GICD_OFFSET + 0x800 + (n)*4)
-#define GICD_ICFGR(n) (GICD_OFFSET + 0xc00 + (n)*4)
-#define GICD_NSACR(n) (GICD_OFFSET + 0xe00 + (n)*4)
-#define GICD_SGIR (GICD_OFFSET + 0xf00)
-#define GICD_CPENDSGIR(n) (GICD_OFFSET + 0xf10 + (n)*4)
-#define GICD_SPENDSGIR(n) (GICD_OFFSET + 0xf20 + (n)*4)
-
-#define GICD_CIDR0 (GICD_OFFSET + 0xff0)
-#define GICD_CIDR1 (GICD_OFFSET + 0xff4)
-#define GICD_CIDR2 (GICD_OFFSET + 0xff8)
-#define GICD_CIDR3 (GICD_OFFSET + 0xffc)
-#define GICD_PIDR0 (GICD_OFFSET + 0xfe0)
-#define GICD_PIDR1 (GICD_OFFSET + 0xfe4)
-#define GICD_PIDR2 (GICD_OFFSET + 0xfe8)
-#define GICD_PIDR3 (GICD_OFFSET + 0xfec)
-
-// we might need to check that we're not a gic v3, in which case look for the v3 PIDR2 reg
-#define GICD_V3_PIDR2 (GICD_OFFSET + 0xffe8)
-
-// Virtual interface control registers.
-#define GICH_ADDRESS (GICH_OFFSET + arm_gicv2_gic_base)
-
-// Virtual CPU interface registers.
-#define GICV_ADDRESS (GICV_OFFSET + arm_gicv2_gic_base)
-
-#define MAX_INT 1024
diff --git a/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2m.h b/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2m.h
deleted file mode 100644
index 777e45e..0000000
--- a/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2m.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016, Google Inc. All rights reserved.
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <sys/types.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-/**
- * Structure used to hold information about a GICv2m register frame
- * @see arm_gicv2m_get_frame_info
- */
-typedef struct arm_gicv2m_frame_info {
-    uint start_spi_id; /** The first valid SPI ID in the frame */
-    uint end_spi_id;   /** The last valid SPI ID in the frame */
-    paddr_t doorbell;  /** The physical address of the doorbell register */
-    uint32_t iid;      /** The value of the Interface ID register */
-} arm_gicv2m_frame_info_t;
-
-/**
- * Support for the MSI extensions to the GICv2 architecture.  See the ARM Server
- * Base System Architecture v3.0 (ARM_DEN_0029) Appendix E for details.
- *
- * @param reg_frames An array of physical addresses of the 4k V2M register
- * frames implemented by this platform's GIC.  Note: The memory backing this
- * array must be alive for the lifetime of the system.
- * @param reg_frame_count The number of entries in the reg_frames array.
- */
-void arm_gicv2m_init(const paddr_t* reg_frames, const vaddr_t* reg_frames_virt, uint reg_frame_count);
-
-/**
- * Fetch info about a specific GICv2m register frame
- *
- * @param frame_num The index of the frame to fetch info for
- * @param out_info A pointer to the structure which will hold info about the frame
- * @return A status code indicating the success or failure of the operation.
- * Status codes may include...
- *  ++ ZX_ERR_UNAVAILABLE The GICv2m subsystem was never initialized
- *  ++ ZX_ERR_NOT_FOUND frame_ndx is out of range
- *  ++ ZX_ERR_INVALID_ARGS out_info is NULL
- *  ++ ZX_ERR_BAD_STATE The frame index exists, but the registers in the frame
- *     appear to be corrupt or invalid (internal error)
- */
-zx_status_t arm_gicv2m_get_frame_info(uint frame_ndx, arm_gicv2m_frame_info_t* out_info);
diff --git a/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2m_msi.h b/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2m_msi.h
deleted file mode 100644
index 82832bb..0000000
--- a/kernel/dev/interrupt/arm_gic/v2/include/dev/interrupt/arm_gicv2m_msi.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-// Copyright (c) 2016, Google Inc. All rights reserved.
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <dev/interrupt.h>
-#include <sys/types.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-zx_status_t arm_gicv2m_msi_init();
-
-// Since ARM determines which GIC is used at runtime, this header sets up the gicv2m instances
-// of the MSI functions so they can be passed into the pbus interrupt function table, which
-// fulfills the interface specified in dev/interrupt.h.
-bool arm_gicv2m_msi_is_supported();
-bool arm_gicv2m_msi_supports_masking();
-void arm_gicv2m_msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask);
-zx_status_t arm_gicv2m_msi_alloc_block(uint requested_irqs,
-                                       bool can_target_64bit,
-                                       bool is_msix,
-                                       msi_block_t* out_block);
-void arm_gicv2m_msi_free_block(msi_block_t* block);
-void arm_gicv2m_msi_register_handler(const msi_block_t* block,
-                                     uint msi_id,
-                                     int_handler handler,
-                                     void* ctx);
diff --git a/kernel/dev/interrupt/arm_gic/v2/rules.mk b/kernel/dev/interrupt/arm_gic/v2/rules.mk
deleted file mode 100644
index a2ddf9e..0000000
--- a/kernel/dev/interrupt/arm_gic/v2/rules.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/arm_gicv2.cpp \
-	$(LOCAL_DIR)/arm_gicv2m.cpp \
-	$(LOCAL_DIR)/arm_gicv2m_msi.cpp \
-	$(LOCAL_DIR)/arm_gicv2m_pcie.cpp \
-
-MODULE_DEPS += \
-	kernel/dev/interrupt \
-	kernel/dev/interrupt/arm_gic/common \
-	kernel/dev/pdev \
-	kernel/dev/pdev/interrupt \
-	kernel/lib/pow2_range_allocator
-
-include make/module.mk
diff --git a/kernel/dev/interrupt/arm_gic/v3/arm_gicv3.cpp b/kernel/dev/interrupt/arm_gic/v3/arm_gicv3.cpp
deleted file mode 100644
index 0e1b94f..0000000
--- a/kernel/dev/interrupt/arm_gic/v3/arm_gicv3.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-// Copyright (c) 2017, Google Inc. All rights reserved.
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <arch/arch_ops.h>
-#include <arch/arm64/hypervisor/gic/gicv3.h>
-#include <arch/arm64/periphmap.h>
-#include <assert.h>
-#include <bits.h>
-#include <dev/interrupt.h>
-#include <dev/interrupt/arm_gic_common.h>
-#include <dev/interrupt/arm_gic_hw_interface.h>
-#include <err.h>
-#include <inttypes.h>
-#include <kernel/stats.h>
-#include <kernel/thread.h>
-#include <lib/ktrace.h>
-#include <lk/init.h>
-#include <pdev/driver.h>
-#include <pdev/interrupt.h>
-#include <string.h>
-#include <trace.h>
-#include <vm/vm.h>
-#include <zircon/boot/driver-config.h>
-#include <zircon/types.h>
-
-#define LOCAL_TRACE 0
-
-#include <arch/arm64.h>
-#define IFRAME_PC(frame) ((frame)->elr)
-
-// values read from zbi
-vaddr_t arm_gicv3_gic_base = 0;
-uint64_t arm_gicv3_gicd_offset = 0;
-uint64_t arm_gicv3_gicr_offset = 0;
-uint64_t arm_gicv3_gicr_stride = 0;
-
-//
-// IMX8M Errata: e11171: CA53: Cannot support single-core runtime wakeup
-
-// According to the GIC500 specification and the Arm Trusted Firmware design, when a CPU
-// core enters the deepest CPU idle state (power-down), it must disable the GIC500 CPU
-// interface and set the Redistributor register to indicate that this CPU is in sleep state.
-
-// On NXP IMX8M, However, if the CPU core is in WFI or power-down with CPU interface disabled,
-// another core cannot wake-up the powered-down core using SGI interrupt.
-
-// One workaround is to use another A53 core for the IRQ0 which is controlled by the IOMUX
-// GPR to generate an external interrupt to wake-up the powered-down core.
-// The SW workaround is implemented into default BSP release. The workaround commit tag is
-// “MLK-16804-04 driver: irqchip: Add IPI SW workaround for imx8mq" on the linux-imx project
-static uint64_t mx8_gpr_virt = 0;
-
-static uint32_t ipi_base = 0;
-
-// this header uses the arm_gicv3_gic_* variables above
-#include <dev/interrupt/arm_gicv3_regs.h>
-
-static uint gic_max_int;
-
-static bool gic_is_valid_interrupt(unsigned int vector, uint32_t flags) {
-    return (vector < gic_max_int);
-}
-
-static uint32_t gic_get_base_vector() {
-    // ARM Generic Interrupt Controller v3&4 chapter 2.2
-    // INTIDs 0-15 are local CPU interrupts
-    return 16;
-}
-
-static uint32_t gic_get_max_vector() {
-    return gic_max_int;
-}
-
-static void gic_wait_for_rwp(uint64_t reg) {
-    int count = 1000000;
-    while (GICREG(0, reg) & (1 << 31)) {
-        count -= 1;
-        if (!count) {
-            LTRACEF("arm_gicv3: rwp timeout 0x%x\n", GICREG(0, reg));
-            return;
-        }
-    }
-}
-
-static void gic_set_enable(uint vector, bool enable) {
-    int reg = vector / 32;
-    uint32_t mask = (uint32_t)(1ULL << (vector % 32));
-
-    if (vector < 32) {
-        for (uint i = 0; i < arch_max_num_cpus(); i++) {
-            if (enable) {
-                GICREG(0, GICR_ISENABLER0(i)) = mask;
-            } else {
-                GICREG(0, GICR_ICENABLER0(i)) = mask;
-            }
-            gic_wait_for_rwp(GICR_CTLR(i));
-        }
-    } else {
-        if (enable) {
-            GICREG(0, GICD_ISENABLER(reg)) = mask;
-        } else {
-            GICREG(0, GICD_ICENABLER(reg)) = mask;
-        }
-        gic_wait_for_rwp(GICD_CTLR);
-    }
-}
-
-static void gic_init_percpu_early() {
-    uint cpu = arch_curr_cpu_num();
-
-    // redistributer config: configure sgi/ppi as non-secure group 1.
-    GICREG(0, GICR_IGROUPR0(cpu)) = ~0;
-    gic_wait_for_rwp(GICR_CTLR(cpu));
-
-    // redistributer config: clear and mask sgi/ppi.
-    GICREG(0, GICR_ICENABLER0(cpu)) = 0xffffffff;
-    GICREG(0, GICR_ICPENDR0(cpu)) = ~0;
-    gic_wait_for_rwp(GICR_CTLR(cpu));
-
-    // TODO lpi init
-
-    // enable system register interface
-    uint32_t sre = gic_read_sre();
-    if (!(sre & 0x1)) {
-        gic_write_sre(sre | 0x1);
-        sre = gic_read_sre();
-        assert(sre & 0x1);
-    }
-
-    // set priority threshold to max.
-    gic_write_pmr(0xff);
-
-    // ICC_CTLR_EL1.EOImode.
-    gic_write_ctlr(1u << 1);
-
-    // enable group 1 interrupts.
-    gic_write_igrpen(1);
-}
-
-static zx_status_t gic_init() {
-    LTRACE_ENTRY;
-
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    uint pidr2 = GICREG(0, GICD_PIDR2);
-    uint rev = BITS_SHIFT(pidr2, 7, 4);
-    if (rev != GICV3 && rev != GICV4) {
-        return ZX_ERR_NOT_FOUND;
-    }
-
-    uint32_t typer = GICREG(0, GICD_TYPER);
-    uint32_t idbits = BITS_SHIFT(typer, 23, 19);
-    gic_max_int = (idbits + 1) * 32;
-
-    // disable the distributor
-    GICREG(0, GICD_CTLR) = 0;
-    gic_wait_for_rwp(GICD_CTLR);
-    __isb(ARM_MB_SY);
-
-    // distributor config: mask and clear all spis, set group 1.
-    uint i;
-    for (i = 32; i < gic_max_int; i += 32) {
-        GICREG(0, GICD_ICENABLER(i / 32)) = ~0;
-        GICREG(0, GICD_ICPENDR(i / 32)) = ~0;
-        GICREG(0, GICD_IGROUPR(i / 32)) = ~0;
-        GICREG(0, GICD_IGRPMODR(i / 32)) = 0;
-    }
-    gic_wait_for_rwp(GICD_CTLR);
-
-    // enable distributor with ARE, group 1 enable
-    GICREG(0, GICD_CTLR) = CTLR_ENABLE_G0 | CTLR_ENABLE_G1NS | CTLR_ARE_S;
-    gic_wait_for_rwp(GICD_CTLR);
-
-    // ensure we're running on cpu 0 and that cpu 0 corresponds to affinity 0.0.0.0
-    DEBUG_ASSERT(arch_curr_cpu_num() == 0);
-    DEBUG_ASSERT(arch_cpu_num_to_cpu_id(0u) == 0);     // AFF0
-    DEBUG_ASSERT(arch_cpu_num_to_cluster_id(0u) == 0); // AFF1
-
-    // TODO(maniscalco): If/when we support AFF2/AFF3, be sure to assert those here.
-
-    // set spi to target cpu 0 (affinity 0.0.0.0). must do this after ARE enable
-    uint max_cpu = BITS_SHIFT(typer, 7, 5);
-    if (max_cpu > 0) {
-        for (i = 32; i < gic_max_int; i++) {
-            GICREG64(0, GICD_IROUTER(i)) = 0;
-        }
-    }
-
-    gic_init_percpu_early();
-
-    mb();
-    __isb(ARM_MB_SY);
-
-    return ZX_OK;
-}
-
-static zx_status_t arm_gic_sgi(u_int irq, u_int flags, u_int cpu_mask) {
-    if (flags != ARM_GIC_SGI_FLAG_NS) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (irq >= 16) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    smp_mb();
-
-    uint cpu = 0;
-    uint cluster = 0;
-    uint64_t val = 0;
-    while (cpu_mask && cpu < arch_max_num_cpus()) {
-        u_int mask = 0;
-        while (arch_cpu_num_to_cluster_id(cpu) == cluster) {
-            if (cpu_mask & (1u << cpu)) {
-                mask |= 1u << arch_cpu_num_to_cpu_id(cpu);
-                cpu_mask &= ~(1u << cpu);
-            }
-            cpu += 1;
-        }
-
-        // Without the RS field set, we can only deal with the first
-        // 16 cpus within a single cluster
-        DEBUG_ASSERT((mask & 0xffff) == mask);
-
-        val = ((irq & 0xf) << 24) |
-              ((cluster & 0xff) << 16) |
-              (mask & 0xffff);
-
-        gic_write_sgi1r(val);
-        cluster += 1;
-        // Work around
-        if (mx8_gpr_virt) {
-            uint32_t regVal;
-            // pending irq32 to wakeup core
-            regVal = *(volatile uint32_t*)(mx8_gpr_virt + 0x4);
-            regVal |= (1 << 12);
-            *(volatile uint32_t*)(mx8_gpr_virt + 0x4) = regVal;
-            // delay
-            spin(50);
-            regVal &= ~(1 << 12);
-            *(volatile uint32_t*)(mx8_gpr_virt + 0x4) = regVal;
-        }
-    }
-
-    return ZX_OK;
-}
-
-static zx_status_t gic_mask_interrupt(unsigned int vector) {
-    LTRACEF("vector %u\n", vector);
-
-    if (vector >= gic_max_int) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    gic_set_enable(vector, false);
-
-    return ZX_OK;
-}
-
-static zx_status_t gic_unmask_interrupt(unsigned int vector) {
-    LTRACEF("vector %u\n", vector);
-
-    if (vector >= gic_max_int) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    gic_set_enable(vector, true);
-
-    return ZX_OK;
-}
-
-static zx_status_t gic_configure_interrupt(unsigned int vector,
-                                           enum interrupt_trigger_mode tm,
-                                           enum interrupt_polarity pol) {
-    LTRACEF("vector %u, trigger mode %d, polarity %d\n", vector, tm, pol);
-
-    if (vector <= 15 || vector >= gic_max_int) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (pol != IRQ_POLARITY_ACTIVE_HIGH) {
-        // TODO: polarity should actually be configure through a GPIO controller
-        return ZX_ERR_NOT_SUPPORTED;
-    }
-
-    uint reg = vector / 16;
-    uint mask = 0x2 << ((vector % 16) * 2);
-    uint32_t val = GICREG(0, GICD_ICFGR(reg));
-    if (tm == IRQ_TRIGGER_MODE_EDGE) {
-        val |= mask;
-    } else {
-        val &= ~mask;
-    }
-    GICREG(0, GICD_ICFGR(reg)) = val;
-
-    return ZX_OK;
-}
-
-static zx_status_t gic_get_interrupt_config(unsigned int vector,
-                                            enum interrupt_trigger_mode* tm,
-                                            enum interrupt_polarity* pol) {
-    LTRACEF("vector %u\n", vector);
-
-    if (vector >= gic_max_int) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    if (tm) {
-        *tm = IRQ_TRIGGER_MODE_EDGE;
-    }
-    if (pol) {
-        *pol = IRQ_POLARITY_ACTIVE_HIGH;
-    }
-
-    return ZX_OK;
-}
-
-static unsigned int gic_remap_interrupt(unsigned int vector) {
-    LTRACEF("vector %u\n", vector);
-    return vector;
-}
-
-// called from assembly
-static void gic_handle_irq(iframe* frame) {
-    // get the current vector
-    uint32_t iar = gic_read_iar();
-    unsigned vector = iar & 0x3ff;
-
-    LTRACEF_LEVEL(2, "iar %#x, vector %u\n", iar, vector);
-
-    if (vector >= 0x3fe) {
-        // spurious
-        // TODO check this
-        return;
-    }
-
-    // tracking external hardware irqs in this variable
-    if (vector >= 32) {
-        CPU_STATS_INC(interrupts);
-    }
-
-    uint cpu = arch_curr_cpu_num();
-
-    ktrace_tiny(TAG_IRQ_ENTER, (vector << 8) | cpu);
-
-    LTRACEF_LEVEL(2, "iar 0x%x cpu %u currthread %p vector %u pc %#" PRIxPTR "\n",
-                  iar, cpu, get_current_thread(), vector, (uintptr_t)IFRAME_PC(frame));
-
-    // deliver the interrupt
-    struct int_handler_struct* handler = pdev_get_int_handler(vector);
-    interrupt_eoi eoi = IRQ_EOI_DEACTIVATE;
-    if (handler->handler) {
-        eoi = handler->handler(handler->arg);
-    }
-    gic_write_eoir(vector);
-    if (eoi == IRQ_EOI_DEACTIVATE) {
-        gic_write_dir(vector);
-    }
-
-    LTRACEF_LEVEL(2, "cpu %u exit\n", cpu);
-
-    ktrace_tiny(TAG_IRQ_EXIT, (vector << 8) | cpu);
-}
-
-static void gic_handle_fiq(iframe* frame) {
-    PANIC_UNIMPLEMENTED;
-}
-
-static zx_status_t gic_send_ipi(cpu_mask_t target, mp_ipi_t ipi) {
-    uint gic_ipi_num = ipi + ipi_base;
-
-    // filter out targets outside of the range of cpus we care about
-    target &= (cpu_mask_t)(((1UL << arch_max_num_cpus()) - 1));
-    if (target != 0) {
-        LTRACEF("target 0x%x, gic_ipi %u\n", target, gic_ipi_num);
-        arm_gic_sgi(gic_ipi_num, ARM_GIC_SGI_FLAG_NS, target);
-    }
-
-    return ZX_OK;
-}
-
-static interrupt_eoi arm_ipi_halt_handler(void*) {
-    LTRACEF("cpu %u\n", arch_curr_cpu_num());
-
-    arch_disable_ints();
-    while (true) {
-    }
-
-    return IRQ_EOI_DEACTIVATE;
-}
-
-static void gic_init_percpu() {
-    mp_set_curr_cpu_online(true);
-    unmask_interrupt(MP_IPI_GENERIC + ipi_base);
-    unmask_interrupt(MP_IPI_RESCHEDULE + ipi_base);
-    unmask_interrupt(MP_IPI_INTERRUPT + ipi_base);
-    unmask_interrupt(MP_IPI_HALT + ipi_base);
-}
-
-static void gic_shutdown() {
-    // Turn off all GIC0 interrupts at the distributor.
-    GICREG(0, GICD_CTLR) = 0;
-}
-
-// Returns true if any PPIs are enabled on the calling CPU.
-static bool is_ppi_enabled() {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    // PPIs are 16-31.
-    uint32_t mask = 0xffff0000;
-
-    uint cpu_num = arch_curr_cpu_num();
-    uint32_t reg = GICREG(0, GICR_ICENABLER0(cpu_num));
-    if ((reg & mask) != 0) {
-        return true;
-    }
-
-    return false;
-}
-
-// Returns true if any SPIs are enabled on the calling CPU.
-static bool is_spi_enabled() {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    uint cpu_num = arch_curr_cpu_num();
-
-    // TODO(maniscalco): If/when we support AFF2/AFF3, update the mask below.
-    uint aff0 = arch_cpu_num_to_cpu_id(cpu_num);
-    uint aff1 = arch_cpu_num_to_cluster_id(cpu_num);
-    uint64_t aff_mask = (aff1 << 8) + aff0;
-
-    // Check each SPI to see if it's routed to this CPU.
-    for (uint i = 32u; i < gic_max_int; ++i) {
-        if ((GICREG64(0, GICD_IROUTER(i)) & aff_mask) != 0) {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static void gic_shutdown_cpu() {
-    DEBUG_ASSERT(arch_ints_disabled());
-
-    // Before we shutdown the GIC, make sure we've migrated/disabled any and all peripheral
-    // interrupts targeted at this CPU (PPIs and SPIs).
-    DEBUG_ASSERT(!is_ppi_enabled());
-    DEBUG_ASSERT(!is_spi_enabled());
-    // TODO(maniscalco): If/when we start using LPIs, make sure none are targeted at this CPU.
-
-    // Disable group 1 interrupts at the CPU interface.
-    gic_write_igrpen(0);
-}
-
-static bool gic_msi_is_supported() {
-    return false;
-}
-
-static bool gic_msi_supports_masking() {
-    return false;
-}
-
-static void gic_msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask) {
-    PANIC_UNIMPLEMENTED;
-}
-
-static zx_status_t gic_msi_alloc_block(uint requested_irqs,
-                                       bool can_target_64bit,
-                                       bool is_msix,
-                                       msi_block_t* out_block) {
-    PANIC_UNIMPLEMENTED;
-}
-
-static void gic_msi_free_block(msi_block_t* block) {
-    PANIC_UNIMPLEMENTED;
-}
-
-static void gic_msi_register_handler(const msi_block_t* block,
-                                     uint msi_id,
-                                     int_handler handler,
-                                     void* ctx) {
-    PANIC_UNIMPLEMENTED;
-}
-
-static const struct pdev_interrupt_ops gic_ops = {
-    .mask = gic_mask_interrupt,
-    .unmask = gic_unmask_interrupt,
-    .configure = gic_configure_interrupt,
-    .get_config = gic_get_interrupt_config,
-    .is_valid = gic_is_valid_interrupt,
-    .get_base_vector = gic_get_base_vector,
-    .get_max_vector = gic_get_max_vector,
-    .remap = gic_remap_interrupt,
-    .send_ipi = gic_send_ipi,
-    .init_percpu_early = gic_init_percpu_early,
-    .init_percpu = gic_init_percpu,
-    .handle_irq = gic_handle_irq,
-    .handle_fiq = gic_handle_fiq,
-    .shutdown = gic_shutdown,
-    .shutdown_cpu = gic_shutdown_cpu,
-    .msi_is_supported = gic_msi_is_supported,
-    .msi_supports_masking = gic_msi_supports_masking,
-    .msi_mask_unmask = gic_msi_mask_unmask,
-    .msi_alloc_block = gic_msi_alloc_block,
-    .msi_free_block = gic_msi_free_block,
-    .msi_register_handler = gic_msi_register_handler,
-};
-
-static void arm_gic_v3_init(const void* driver_data, uint32_t length) {
-    ASSERT(length >= sizeof(dcfg_arm_gicv3_driver_t));
-    auto driver = static_cast<const dcfg_arm_gicv3_driver_t*>(driver_data);
-    ASSERT(driver->mmio_phys);
-
-    LTRACE_ENTRY;
-
-    // If a GIC driver is already registered to the GIC interface it's means we are running GICv2
-    // and we do not need to initialize GICv3. Since we have added both GICv3 and GICv2 in board.mdi,
-    // both drivers are initialized
-    if (arm_gic_is_registered()) {
-        return;
-    }
-
-    if (driver->mx8_gpr_phys) {
-        printf("arm-gic-v3: Applying Errata e11171 for NXP MX8!\n");
-        mx8_gpr_virt = periph_paddr_to_vaddr(driver->mx8_gpr_phys);
-        ASSERT(mx8_gpr_virt);
-    }
-
-    arm_gicv3_gic_base = periph_paddr_to_vaddr(driver->mmio_phys);
-    ASSERT(arm_gicv3_gic_base);
-    arm_gicv3_gicd_offset = driver->gicd_offset;
-    arm_gicv3_gicr_offset = driver->gicr_offset;
-    arm_gicv3_gicr_stride = driver->gicr_stride;
-    ipi_base = driver->ipi_base;
-
-    arm_gicv3_gic_base = periph_paddr_to_vaddr(driver->mmio_phys);
-    ASSERT(arm_gicv3_gic_base);
-
-    if (gic_init() != ZX_OK) {
-        if (driver->optional) {
-            // failed to detect gic v3 but it's marked optional. continue
-            return;
-        }
-        printf("GICv3: failed to detect GICv3, interrupts will be broken\n");
-        return;
-    }
-
-    dprintf(SPEW, "detected GICv3\n");
-
-    pdev_register_interrupts(&gic_ops);
-
-    zx_status_t status =
-        gic_register_sgi_handler(MP_IPI_GENERIC + ipi_base, &mp_mbx_generic_irq);
-    DEBUG_ASSERT(status == ZX_OK);
-    status =
-        gic_register_sgi_handler(MP_IPI_RESCHEDULE + ipi_base, &mp_mbx_reschedule_irq);
-    DEBUG_ASSERT(status == ZX_OK);
-    status = gic_register_sgi_handler(MP_IPI_INTERRUPT + ipi_base, &mp_mbx_interrupt_irq);
-    DEBUG_ASSERT(status == ZX_OK);
-    status = gic_register_sgi_handler(MP_IPI_HALT + ipi_base, &arm_ipi_halt_handler);
-    DEBUG_ASSERT(status == ZX_OK);
-
-    gicv3_hw_interface_register();
-
-    LTRACE_EXIT;
-}
-
-LK_PDEV_INIT(arm_gic_v3_init, KDRV_ARM_GIC_V3, arm_gic_v3_init, LK_INIT_LEVEL_PLATFORM_EARLY);
diff --git a/kernel/dev/interrupt/arm_gic/v3/arm_gicv3_pcie.cpp b/kernel/dev/interrupt/arm_gic/v3/arm_gicv3_pcie.cpp
deleted file mode 100644
index 2b361d5..0000000
--- a/kernel/dev/interrupt/arm_gic/v3/arm_gicv3_pcie.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-// Copyright (c) 2012-2015 Travis Geiselbrecht
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#if WITH_KERNEL_PCIE
-#include <dev/pcie_bus_driver.h>
-#include <dev/pcie_platform.h>
-#include <dev/pcie_root.h>
-#include <inttypes.h>
-#include <lk/init.h>
-#include <pdev/driver.h>
-#include <pdev/interrupt.h>
-#include <trace.h>
-#include <zircon/boot/driver-config.h>
-#include <zircon/types.h>
-
-static void arm_gicv3_pcie_init(const void* driver_data, uint32_t length) {
-    ASSERT(length >= sizeof(dcfg_arm_gicv3_driver_t));
-    __UNUSED const dcfg_arm_gicv3_driver_t* driver =
-        reinterpret_cast<const dcfg_arm_gicv3_driver_t*>(driver_data);
-
-    // When GICv3 MSI support is added, initialize here
-
-    // Initialize the PCI platform, claiming no MSI support
-    static NoMsiPciePlatformInterface platform_pcie_support;
-
-    zx_status_t res = PcieBusDriver::InitializeDriver(platform_pcie_support);
-    if (res != ZX_OK) {
-        TRACEF("Failed to initialize PCI bus driver (res %d).  "
-               "PCI will be non-functional.\n",
-               res);
-    }
-}
-
-LK_PDEV_INIT(arm_gicv3_pcie_init, KDRV_ARM_GIC_V3, arm_gicv3_pcie_init, LK_INIT_LEVEL_PLATFORM);
-
-#endif // if WITH_KERNEL_PCIE
diff --git a/kernel/dev/interrupt/arm_gic/v3/include/dev/interrupt/arm_gicv3_regs.h b/kernel/dev/interrupt/arm_gic/v3/include/dev/interrupt/arm_gicv3_regs.h
deleted file mode 100644
index 65c256f..0000000
--- a/kernel/dev/interrupt/arm_gic/v3/include/dev/interrupt/arm_gicv3_regs.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include <arch/arm64.h>
-#include <reg.h>
-
-extern vaddr_t arm_gicv3_gic_base;
-extern uint64_t arm_gicv3_gicd_offset;
-extern uint64_t arm_gicv3_gicr_offset;
-extern uint64_t arm_gicv3_gicr_stride;
-
-#define BIT_32(bit) (1u << bit)
-#define BIT_64(bit) (1ul << bit)
-
-#define GICREG(gic, reg) (*REG32(arm_gicv3_gic_base + (reg)))
-#define GICREG64(gic, reg) (*REG64(arm_gicv3_gic_base + (reg)))
-#define GICD_OFFSET arm_gicv3_gicd_offset
-#define GICR_OFFSET arm_gicv3_gicr_offset
-#define GICR_STRIDE arm_gicv3_gicr_stride
-
-#define ICC_CTLR_EL1 "S3_0_C12_C12_4"
-#define ICC_PMR_EL1 "S3_0_C4_C6_0"
-#define ICC_IAR1_EL1 "S3_0_C12_C12_0"
-#define ICC_SRE_EL1 "S3_0_C12_C12_5"
-#define ICC_BPR1_EL1 "S3_0_C12_C12_3"
-#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7"
-#define ICC_EOIR1_EL1 "S3_0_C12_C12_1"
-#define ICC_DIR_EL1 "S3_0_C12_C11_1"
-#define ICC_SGI1R_EL1 "S3_0_C12_C11_5"
-
-/* distributor registers */
-
-#define GICD_CTLR (GICD_OFFSET + 0x0000)
-#define GICD_TYPER (GICD_OFFSET + 0x0004)
-#define GICD_IIDR (GICD_OFFSET + 0x0008)
-#define GICD_IGROUPR(n) (GICD_OFFSET + 0x0080 + (n)*4)
-#define GICD_ISENABLER(n) (GICD_OFFSET + 0x0100 + (n)*4)
-#define GICD_ICENABLER(n) (GICD_OFFSET + 0x0180 + (n)*4)
-#define GICD_ISPENDR(n) (GICD_OFFSET + 0x0200 + (n)*4)
-#define GICD_ICPENDR(n) (GICD_OFFSET + 0x0280 + (n)*4)
-#define GICD_ISACTIVER(n) (GICD_OFFSET + 0x0300 + (n)*4)
-#define GICD_ICACTIVER(n) (GICD_OFFSET + 0x0380 + (n)*4)
-#define GICD_IPRIORITYR(n) (GICD_OFFSET + 0x0400 + (n)*4)
-#define GICD_ITARGETSR(n) (GICD_OFFSET + 0x0800 + (n)*4)
-#define GICD_ICFGR(n) (GICD_OFFSET + 0x0c00 + (n)*4)
-#define GICD_IGRPMODR(n) (GICD_OFFSET + 0x0d00 + (n)*4)
-#define GICD_NSACR(n) (GICD_OFFSET + 0x0e00 + (n)*4)
-#define GICD_SGIR (GICD_OFFSET + 0x0f00)
-#define GICD_CPENDSGIR(n) (GICD_OFFSET + 0x0f10 + (n)*4)
-#define GICD_SPENDSGIR(n) (GICD_OFFSET + 0x0f20 + (n)*4)
-#define GICD_IROUTER(n) (GICD_OFFSET + 0x6000 + (n)*8)
-
-/* GICD_CTLR bit definitions */
-
-#define CTLR_ENABLE_G0 BIT_32(0)
-#define CTLR_ENABLE_G1NS BIT_32(1)
-#define CTLR_ENABLE_G1S BIT_32(2)
-#define CTLR_RES0 BIT_32(3)
-#define CTLR_ARE_S BIT_32(4)
-#define CTLR_ARE_NS BIT_32(5)
-#define CTLR_DS BIT_32(6)
-#define CTLR_E1NWF BIT_32(7)
-#define GICD_CTLR_RWP BIT_32(31)
-
-/* peripheral identification registers */
-
-#define GICD_CIDR0 (GICD_OFFSET + 0xfff0)
-#define GICD_CIDR1 (GICD_OFFSET + 0xfff4)
-#define GICD_CIDR2 (GICD_OFFSET + 0xfff8)
-#define GICD_CIDR3 (GICD_OFFSET + 0xfffc)
-#define GICD_PIDR0 (GICD_OFFSET + 0xffe0)
-#define GICD_PIDR1 (GICD_OFFSET + 0xffe4)
-#define GICD_PIDR2 (GICD_OFFSET + 0xffe8)
-#define GICD_PIDR3 (GICD_OFFSET + 0xffec)
-
-/* GICD_PIDR bit definitions and masks */
-
-#define GICD_PIDR2_ARCHREV_SHIFT 4
-#define GICD_PIDR2_ARCHREV_MASK 0xf
-
-/* redistributor registers */
-
-#define GICR_SGI_OFFSET (GICR_OFFSET + 0x10000)
-
-#define GICR_CTLR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0000)
-#define GICR_IIDR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0004)
-#define GICR_TYPER(i, n) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0008 + (n)*4)
-#define GICR_STATUSR(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0010)
-#define GICR_WAKER(i) (GICR_OFFSET + GICR_STRIDE * (i) + 0x0014)
-#define GICR_IGROUPR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0080)
-#define GICR_IGRPMOD0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0d00)
-#define GICR_ISENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0100)
-#define GICR_ICENABLER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0180)
-#define GICR_ISPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0200)
-#define GICR_ICPENDR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0280)
-#define GICR_ISACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0300)
-#define GICR_ICACTIVER0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0380)
-#define GICR_IPRIORITYR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0400)
-#define GICR_ICFGR0(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c00)
-#define GICR_ICFGR1(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0c04)
-#define GICR_NSACR(i) (GICR_SGI_OFFSET + GICR_STRIDE * (i) + 0x0e00)
-
-static inline void gic_write_ctlr(uint32_t val) {
-    __asm__ volatile("msr " ICC_CTLR_EL1 ", %0" :: "r"((uint64_t)val));
-    __isb(ARM_MB_SY);
-}
-
-static inline void gic_write_pmr(uint32_t val) {
-    __asm__ volatile("msr " ICC_PMR_EL1 ", %0" :: "r"((uint64_t)val));
-    __isb(ARM_MB_SY);
-    __dsb(ARM_MB_SY);
-}
-
-static inline void gic_write_igrpen(uint32_t val) {
-    __asm__ volatile("msr " ICC_IGRPEN1_EL1 ", %0" :: "r"((uint64_t)val));
-    __isb(ARM_MB_SY);
-}
-
-static inline uint32_t gic_read_sre(void) {
-    uint64_t temp;
-    __asm__ volatile("mrs %0, " ICC_SRE_EL1 : "=r"(temp));
-    return (uint32_t)temp;
-}
-
-static inline void gic_write_sre(uint32_t val) {
-    __asm__ volatile("msr " ICC_SRE_EL1 ", %0" :: "r"((uint64_t)val));
-    __isb(ARM_MB_SY);
-}
-
-static inline void gic_write_eoir(uint32_t val) {
-    __asm__ volatile("msr " ICC_EOIR1_EL1 ", %0" :: "r"((uint64_t)val));
-    __isb(ARM_MB_SY);
-}
-
-static inline void gic_write_dir(uint32_t val) {
-    __asm__ volatile("msr " ICC_DIR_EL1 ", %0" :: "r"((uint64_t)val));
-    __isb(ARM_MB_SY);
-}
-
-static inline uint32_t gic_read_iar() {
-    uint64_t temp;
-    __asm__ volatile("mrs %0, " ICC_IAR1_EL1 : "=r"(temp));
-    __dsb(ARM_MB_SY);
-    return (uint32_t)temp;
-}
-
-static inline void gic_write_sgi1r(uint64_t val) {
-    __asm__ volatile("msr " ICC_SGI1R_EL1 ", %0" :: "r"((uint64_t)val));
-    __isb(ARM_MB_SY);
-    __dsb(ARM_MB_SY);
-}
diff --git a/kernel/dev/interrupt/arm_gic/v3/rules.mk b/kernel/dev/interrupt/arm_gic/v3/rules.mk
deleted file mode 100644
index f11a265..0000000
--- a/kernel/dev/interrupt/arm_gic/v3/rules.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2017 The Fuchsia Authors
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-
-MODULE := $(LOCAL_DIR)
-
-KERNEL_INCLUDES += kernel/dev/interrupt/arm_gic/v2/include
-
-MODULE_SRCS += \
-	$(LOCAL_DIR)/arm_gicv3.cpp \
-	$(LOCAL_DIR)/arm_gicv3_pcie.cpp
-
-MODULE_DEPS += \
-	kernel/dev/interrupt \
-	kernel/dev/interrupt/arm_gic/common \
-	kernel/dev/pdev \
-	kernel/dev/pdev/interrupt \
-
-include make/module.mk
diff --git a/kernel/dev/interrupt/include/dev/interrupt.h b/kernel/dev/interrupt/include/dev/interrupt.h
deleted file mode 100644
index eb0e801..0000000
--- a/kernel/dev/interrupt/include/dev/interrupt.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2016 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <kernel/mp.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-__BEGIN_CDECLS
-
-#define MAX_MSI_IRQS 32u
-
-enum interrupt_trigger_mode {
-    IRQ_TRIGGER_MODE_EDGE = 0,
-    IRQ_TRIGGER_MODE_LEVEL = 1,
-};
-
-enum interrupt_polarity {
-    IRQ_POLARITY_ACTIVE_HIGH = 0,
-    IRQ_POLARITY_ACTIVE_LOW = 1,
-};
-
-zx_status_t mask_interrupt(unsigned int vector);
-zx_status_t unmask_interrupt(unsigned int vector);
-
-void shutdown_interrupts(void);
-
-// Shutdown interrupts for the calling CPU.
-//
-// Should be called before powering off the calling CPU.
-void shutdown_interrupts_curr_cpu(void);
-
-// Configure the specified interrupt vector.  If it is invoked, it muust be
-// invoked prior to interrupt registration
-zx_status_t configure_interrupt(unsigned int vector,
-                                enum interrupt_trigger_mode tm,
-                                enum interrupt_polarity pol);
-
-zx_status_t get_interrupt_config(unsigned int vector,
-                                 enum interrupt_trigger_mode* tm,
-                                 enum interrupt_polarity* pol);
-
-typedef interrupt_eoi (*int_handler)(void* arg);
-
-zx_status_t register_int_handler(unsigned int vector, int_handler handler, void* arg);
-
-// These return the [base, max] range of vectors that can be used with zx_interrupt syscalls
-// This api will need to evolve if valid vector ranges later are not contiguous
-uint32_t interrupt_get_base_vector(void);
-uint32_t interrupt_get_max_vector(void);
-
-bool is_valid_interrupt(unsigned int vector, uint32_t flags);
-
-unsigned int remap_interrupt(unsigned int vector);
-
-// sends an inter-processor interrupt
-zx_status_t interrupt_send_ipi(cpu_mask_t target, mp_ipi_t ipi);
-
-// performs per-cpu initialization for the interrupt controller
-void interrupt_init_percpu(void);
-
-// A structure which holds the state of a block of IRQs allocated by the
-// platform to be used for delivering MSI or MSI-X interrupts.
-typedef struct msi_block {
-    void*    platform_ctx; // Allocation context owned by the platform
-    uint64_t tgt_addr;     // The target write transaction physical address
-    bool     allocated;    // Whether or not this block has been allocated
-    uint     base_irq_id;  // The first IRQ id in the allocated block
-    uint     num_irq;      // The number of irqs in the allocated block
-
-    // The data which the device should write when triggering an IRQ.  Note,
-    // only the lower 16 bits are used when the block has been allocated for MSI
-    // instead of MSI-X
-    uint32_t tgt_data;
-} msi_block_t;
-
-// Methods used to determine if a platform supports MSI or not, and if so,
-// whether or not the platform can mask individual MSI vectors at the
-// platform level.
-//
-// If the platform supports MSI, it must supply valid implementations of
-// msi_alloc_block, msi_free_block, and msi_register_handler.
-//
-// If the platform supports MSI masking, it must supply a valid
-// implementation of MaskUnmaskMsi.
-bool msi_is_supported(void);
-bool msi_supports_masking(void);
-void msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask);
-
-// Method used for platform allocation of blocks of MSI and MSI-X compatible
-// IRQ targets.
-//
-// @param requested_irqs The total number of irqs being requested.
-// @param can_target_64bit True if the target address of the MSI block can
-//        be located past the 4GB boundary.  False if the target address must be
-//        in low memory.
-// @param is_msix True if this request is for an MSI-X compatible block.  False
-//        for plain old MSI.
-// @param out_block A pointer to the allocation bookkeeping to be filled out
-//        upon successful allocation of the requested block of IRQs.
-//
-// @return A status code indicating the success or failure of the operation.
-zx_status_t msi_alloc_block(uint requested_irqs,
-                            bool can_target_64bit,
-                            bool is_msix,
-                            msi_block_t* out_block);
-
-// Method used to free a block of MSI IRQs previously allocated by msi_alloc_block().
-// This does not unregister IRQ handlers.
-//
-// @param block A pointer to the block to be returned
-void msi_free_block(msi_block_t* block);
-
-// Register a handler function for a given msi_id within an msi_block_t. Passing a
-// NULL handler will effectively unregister a handler for a given msi_id within the
-// block.
-void msi_register_handler(const msi_block_t* block, uint msi_id, int_handler handler, void *ctx);
-__END_CDECLS
diff --git a/kernel/dev/interrupt/msi.cpp b/kernel/dev/interrupt/msi.cpp
deleted file mode 100644
index 8d3b99d..0000000
--- a/kernel/dev/interrupt/msi.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-// Methods in this file exist to provide default stubs for MSI
-// support so that individual platforms do not need to provide
-// them if they only partially support MSI.
-
-#include <dev/interrupt.h>
-
-#include <stdbool.h>
-#include <zircon/compiler.h>
-#include <zircon/types.h>
-
-__WEAK bool msi_is_supported() {
-    return false;
-}
-
-__WEAK bool msi_supports_masking() {
-    return false;
-}
-
-__WEAK void msi_mask_unmask(const msi_block_t* block, uint msi_id, bool mask) {
-    PANIC_UNIMPLEMENTED;
-}
-
-__WEAK zx_status_t msi_alloc_block(uint requested_irqs,
-                                   bool can_target_64bit,
-                                   bool is_msix,
-                                   msi_block_t* out_block) {
-    PANIC_UNIMPLEMENTED;
-    __UNREACHABLE;
-}
-
-__WEAK void msi_free_block(msi_block_t* block) {
-    PANIC_UNIMPLEMENTED;
-}
-
-__WEAK void msi_register_handler(const msi_block_t* block,
-                                 uint msi_id,
-                                 int_handler handler,
-                                 void *ctx) {
-    PANIC_UNIMPLEMENTED;
-}
diff --git a/kernel/dev/interrupt/rules.mk b/kernel/dev/interrupt/rules.mk
deleted file mode 100644
index 42d7b00..0000000
--- a/kernel/dev/interrupt/rules.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2016 The Fuchsia Authors
-# Copyright (c) 2008-2015 Travis Geiselbrecht
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS := \
-    $(LOCAL_DIR)/msi.cpp
-
-include make/module.mk
diff --git a/kernel/dev/iommu/dummy/dummy_iommu.cpp b/kernel/dev/iommu/dummy/dummy_iommu.cpp
deleted file mode 100644
index d7656f7..0000000
--- a/kernel/dev/iommu/dummy/dummy_iommu.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include <dev/iommu/dummy.h>
-
-#include <err.h>
-#include <fbl/ref_ptr.h>
-#include <ktl/move.h>
-#include <new>
-#include <vm/vm.h>
-
-#define INVALID_PADDR UINT64_MAX
-
-DummyIommu::DummyIommu() {
-}
-
-zx_status_t DummyIommu::Create(ktl::unique_ptr<const uint8_t[]> desc, size_t desc_len,
-                               fbl::RefPtr<Iommu>* out) {
-    if (desc_len != sizeof(zx_iommu_desc_dummy_t)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-
-    fbl::AllocChecker ac;
-    auto instance = fbl::AdoptRef<DummyIommu>(new (&ac) DummyIommu());
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    *out = ktl::move(instance);
-    return ZX_OK;
-}
-
-DummyIommu::~DummyIommu() {
-}
-
-bool DummyIommu::IsValidBusTxnId(uint64_t bus_txn_id) const {
-    return true;
-}
-
-zx_status_t DummyIommu::Map(uint64_t bus_txn_id, const fbl::RefPtr<VmObject>& vmo,
-                            uint64_t offset, size_t size, uint32_t perms,
-                            dev_vaddr_t* vaddr, size_t* mapped_len) {
-    DEBUG_ASSERT(vaddr);
-    DEBUG_ASSERT(mapped_len);
-
-    if (!IS_PAGE_ALIGNED(offset) || size == 0) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    if (perms & ~(IOMMU_FLAG_PERM_READ | IOMMU_FLAG_PERM_WRITE | IOMMU_FLAG_PERM_EXECUTE)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    if (perms == 0) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    if (offset + size < offset || offset + size > vmo->size()) {
-        return ZX_ERR_OUT_OF_RANGE;
-    }
-
-    auto lookup_fn = [](void* ctx, size_t offset, size_t index, paddr_t pa) {
-        paddr_t* paddr = static_cast<paddr_t*>(ctx);
-        *paddr = pa;
-        return ZX_OK;
-    };
-
-    paddr_t paddr = INVALID_PADDR;
-    zx_status_t status = vmo->Lookup(offset, fbl::min<size_t>(PAGE_SIZE, size), lookup_fn, &paddr);
-    if (status != ZX_OK) {
-        return status;
-    }
-    if (paddr == INVALID_PADDR) {
-        return ZX_ERR_BAD_STATE;
-    }
-
-    if (vmo->is_paged()) {
-        *vaddr = paddr;
-        *mapped_len = PAGE_SIZE;
-    } else {
-        *vaddr = paddr;
-        *mapped_len = ROUNDUP(size, PAGE_SIZE);
-    }
-    return ZX_OK;
-}
-
-zx_status_t DummyIommu::MapContiguous(uint64_t bus_txn_id, const fbl::RefPtr<VmObject>& vmo,
-                                      uint64_t offset, size_t size, uint32_t perms,
-                                      dev_vaddr_t* vaddr, size_t* mapped_len) {
-    DEBUG_ASSERT(vaddr);
-    DEBUG_ASSERT(mapped_len);
-
-    if (!IS_PAGE_ALIGNED(offset) || size == 0) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    if (perms & ~(IOMMU_FLAG_PERM_READ | IOMMU_FLAG_PERM_WRITE | IOMMU_FLAG_PERM_EXECUTE)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    if (perms == 0) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    uint64_t end;
-    if (add_overflow(offset, size, &end) || end > vmo->size()) {
-        return ZX_ERR_OUT_OF_RANGE;
-    }
-
-    if (!vmo->is_contiguous()) {
-        return ZX_ERR_NO_RESOURCES;
-    }
-
-    auto lookup_fn = [](void* ctx, size_t offset, size_t index, paddr_t pa) {
-        paddr_t* paddr = static_cast<paddr_t*>(ctx);
-        *paddr = pa;
-        return ZX_OK;
-    };
-
-    paddr_t paddr = INVALID_PADDR;
-    zx_status_t status = vmo->Lookup(offset, PAGE_SIZE, lookup_fn, &paddr);
-    if (status != ZX_OK) {
-        return status;
-    }
-    if (paddr == INVALID_PADDR) {
-        return ZX_ERR_BAD_STATE;
-    }
-
-    *vaddr = paddr;
-    *mapped_len = size;
-    return ZX_OK;
-}
-
-zx_status_t DummyIommu::Unmap(uint64_t bus_txn_id, dev_vaddr_t vaddr, size_t size) {
-    if (!IS_PAGE_ALIGNED(vaddr) || !IS_PAGE_ALIGNED(size)) {
-        return ZX_ERR_INVALID_ARGS;
-    }
-    return ZX_OK;
-}
-
-zx_status_t DummyIommu::ClearMappingsForBusTxnId(uint64_t bus_txn_id) {
-    return ZX_OK;
-}
-
-uint64_t DummyIommu::minimum_contiguity(uint64_t bus_txn_id) {
-    return PAGE_SIZE;
-}
-
-uint64_t DummyIommu::aspace_size(uint64_t bus_txn_id) {
-    return UINT64_MAX;
-}
diff --git a/kernel/dev/iommu/dummy/include/dev/iommu/dummy.h b/kernel/dev/iommu/dummy/include/dev/iommu/dummy.h
deleted file mode 100644
index 12b8fab..0000000
--- a/kernel/dev/iommu/dummy/include/dev/iommu/dummy.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <dev/iommu.h>
-#include <zircon/compiler.h>
-#include <zircon/syscalls/iommu.h>
-#include <ktl/unique_ptr.h>
-
-class DummyIommu final : public Iommu {
-public:
-    static zx_status_t Create(ktl::unique_ptr<const uint8_t[]> desc, size_t desc_len,
-                              fbl::RefPtr<Iommu>* out);
-
-    bool IsValidBusTxnId(uint64_t bus_txn_id) const final;
-
-    zx_status_t Map(uint64_t bus_txn_id, const fbl::RefPtr<VmObject>& vmo,
-                    uint64_t offset, size_t size, uint32_t perms,
-                    dev_vaddr_t* vaddr, size_t* mapped_len) final;
-    zx_status_t MapContiguous(uint64_t bus_txn_id, const fbl::RefPtr<VmObject>& vmo,
-                              uint64_t offset, size_t size, uint32_t perms,
-                              dev_vaddr_t* vaddr, size_t* mapped_len) final;
-    zx_status_t Unmap(uint64_t bus_txn_id, dev_vaddr_t vaddr, size_t size) final;
-
-    zx_status_t ClearMappingsForBusTxnId(uint64_t bus_txn_id) final;
-
-    uint64_t minimum_contiguity(uint64_t bus_txn_id) final;
-    uint64_t aspace_size(uint64_t bus_txn_id) final;
-
-    ~DummyIommu() final;
-
-    DISALLOW_COPY_ASSIGN_AND_MOVE(DummyIommu);
-private:
-    DummyIommu();
-};
diff --git a/kernel/dev/iommu/dummy/rules.mk b/kernel/dev/iommu/dummy/rules.mk
deleted file mode 100644
index ee350bb..0000000
--- a/kernel/dev/iommu/dummy/rules.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2017 The Fuchsia Authors
-#
-# Use of this source code is governed by a MIT-style
-# license that can be found in the LICENSE file or at
-# https://opensource.org/licenses/MIT
-
-LOCAL_DIR := $(GET_LOCAL_DIR)
-MODULE := $(LOCAL_DIR)
-
-MODULE_SRCS := \
-    $(LOCAL_DIR)/dummy_iommu.cpp
-
-include make/module.mk
diff --git a/kernel/dev/iommu/intel/context_table_state.cpp b/kernel/dev/iommu/intel/context_table_state.cpp
deleted file mode 100644
index 8fe52ea..0000000
--- a/kernel/dev/iommu/intel/context_table_state.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include "context_table_state.h"
-
-#include <ktl/unique_ptr.h>
-#include <ktl/move.h>
-#include <new>
-
-#include "device_context.h"
-#include "hw.h"
-#include "iommu_impl.h"
-
-namespace intel_iommu {
-
-ContextTableState::ContextTableState(uint8_t bus, bool extended, bool upper,
-                                     IommuImpl* parent, volatile ds::RootEntrySubentry* root_entry,
-                                     IommuPage page)
-        : parent_(parent), root_entry_(root_entry), page_(ktl::move(page)),
-          bus_(bus), extended_(extended), upper_(upper) {
-}
-
-ContextTableState::~ContextTableState() {
-    ds::RootEntrySubentry entry;
-    entry.ReadFrom(root_entry_);
-    entry.set_present(0);
-    entry.WriteTo(root_entry_);
-
-    // When modifying a present (extended) root entry, we must serially
-    // invalidate the context-cache, the PASID-cache, then the IOTLB (see
-    // 6.2.2.1 "Context-Entry Programming Considerations" in the VT-d spec,
-    // Oct 2014 rev).
-    parent_->InvalidateContextCacheGlobal();
-    // TODO(teisenbe): Invalidate the PASID cache once we support those
-    parent_->InvalidateIotlbGlobal();
-}
-
-zx_status_t ContextTableState::Create(uint8_t bus, bool extended, bool upper,
-                                      IommuImpl* parent, volatile ds::RootEntrySubentry* root_entry,
-                                      ktl::unique_ptr<ContextTableState>* table) {
-    ds::RootEntrySubentry entry;
-    entry.ReadFrom(root_entry);
-    DEBUG_ASSERT(!entry.present());
-
-    IommuPage page;
-    zx_status_t status = IommuPage::AllocatePage(&page);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    fbl::AllocChecker ac;
-    ktl::unique_ptr<ContextTableState> tbl(new (&ac) ContextTableState(bus, extended, upper,
-                                                                       parent, root_entry,
-                                                                       ktl::move(page)));
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    entry.set_present(1);
-    entry.set_context_table(tbl->page_.paddr() >> 12);
-    entry.WriteTo(root_entry);
-
-    *table = ktl::move(tbl);
-    return ZX_OK;
-}
-
-zx_status_t ContextTableState::CreateDeviceContext(ds::Bdf bdf, uint32_t domain_id,
-                                                   DeviceContext** context) {
-    DEBUG_ASSERT(bus_ == bdf.bus());
-
-    ktl::unique_ptr<DeviceContext> dev;
-    zx_status_t status;
-    if (extended_) {
-        DEBUG_ASSERT(upper_ == (bdf.dev() >= 16));
-        volatile ds::ExtendedContextTable* tbl = extended_table();
-        volatile ds::ExtendedContextEntry* entry = &tbl->entry[bdf.packed_dev_and_func() & 0x7f];
-        status = DeviceContext::Create(bdf, domain_id, parent_, entry, &dev);
-    } else {
-        volatile ds::ContextTable* tbl = table();
-        volatile ds::ContextEntry* entry = &tbl->entry[bdf.packed_dev_and_func()];
-        status = DeviceContext::Create(bdf, domain_id, parent_, entry, &dev);
-    }
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    *context = dev.get();
-    devices_.push_back(ktl::move(dev));
-    return ZX_OK;
-}
-
-zx_status_t ContextTableState::GetDeviceContext(ds::Bdf bdf, DeviceContext** context) {
-    for (auto& dev : devices_) {
-        if (dev.is_bdf(bdf)) {
-            *context = &dev;
-            return ZX_OK;
-        }
-    }
-    return ZX_ERR_NOT_FOUND;
-}
-
-} // namespace intel_iommu
diff --git a/kernel/dev/iommu/intel/context_table_state.h b/kernel/dev/iommu/intel/context_table_state.h
deleted file mode 100644
index ce5b177..0000000
--- a/kernel/dev/iommu/intel/context_table_state.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <fbl/intrusive_double_list.h>
-#include <fbl/macros.h>
-#include <ktl/unique_ptr.h>
-
-#include "hw.h"
-#include "iommu_page.h"
-
-namespace intel_iommu {
-
-class DeviceContext;
-class IommuImpl;
-
-class ContextTableState : public fbl::DoublyLinkedListable<ktl::unique_ptr<ContextTableState>> {
-public:
-    ~ContextTableState();
-
-    // Create a ContextTableState for the given bus.
-    // If |extended| is true, then this will represent a reg::ExtendedContextTable,
-    // and the table will handle translations for, depending on |upper|, either the
-    // lower (dev<16) or upper half of this bus.
-    // If |extended| is false, this represents a reg::ContextTable.
-    static zx_status_t Create(uint8_t bus, bool extended, bool upper,
-                              IommuImpl* parent, volatile ds::RootEntrySubentry* root_entry,
-                              ktl::unique_ptr<ContextTableState>* table);
-
-    // Check if this ContextTableState is for the given BDF
-    bool includes_bdf(ds::Bdf bdf) const {
-        if (bdf.bus() != bus_) {
-            return false;
-        }
-        if (!extended_) {
-            return true;
-        }
-        return (bdf.dev() >= 16) == upper_;
-    }
-
-    // Create a new DeviceContext representing the given BDF, and give it the specified domain_id.
-    // It is a fatal error to try to create a context for a BDF that already has one.
-    zx_status_t CreateDeviceContext(ds::Bdf bdf, uint32_t domain_id,
-                                    DeviceContext** context);
-
-    zx_status_t GetDeviceContext(ds::Bdf bdf, DeviceContext** context);
-
-private:
-    ContextTableState(uint8_t bus, bool extended, bool upper, IommuImpl* parent,
-                      volatile ds::RootEntrySubentry* root_entry, IommuPage page);
-
-    DISALLOW_COPY_ASSIGN_AND_MOVE(ContextTableState);
-
-    volatile ds::ContextTable* table() const {
-        DEBUG_ASSERT(!extended_);
-        return reinterpret_cast<volatile ds::ContextTable*>(page_.vaddr());
-    }
-
-    volatile ds::ExtendedContextTable* extended_table() const {
-        DEBUG_ASSERT(extended_);
-        return reinterpret_cast<volatile ds::ExtendedContextTable*>(page_.vaddr());
-    }
-
-    // Pointer to IOMMU that owns this ContextTableState
-    IommuImpl* const parent_;
-    // Pointer to the half of the Root Table Entry that decodes to this
-    // ContextTable.
-    volatile ds::RootEntrySubentry* const root_entry_;
-
-    // Page backing the ContextTable/ExtendedContextTable
-    const IommuPage page_;
-
-    // List of device configurations beneath this ContextTable.
-    fbl::DoublyLinkedList<ktl::unique_ptr<DeviceContext>> devices_;
-
-    const uint8_t bus_;
-    const bool extended_;
-    // Only valid if extended_ is true
-    const bool upper_;
-};
-
-} // namespace intel_iommu
diff --git a/kernel/dev/iommu/intel/device_context.cpp b/kernel/dev/iommu/intel/device_context.cpp
deleted file mode 100644
index b3ccbbf..0000000
--- a/kernel/dev/iommu/intel/device_context.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include "device_context.h"
-
-#include <fbl/auto_call.h>
-#include <ktl/unique_ptr.h>
-#include <kernel/range_check.h>
-#include <ktl/move.h>
-#include <new>
-#include <trace.h>
-#include <vm/vm.h>
-#include <vm/vm_object_paged.h>
-
-#include "hw.h"
-#include "iommu_impl.h"
-
-#define LOCAL_TRACE 0
-
-namespace intel_iommu {
-
-DeviceContext::DeviceContext(ds::Bdf bdf, uint32_t domain_id, IommuImpl* parent,
-                             volatile ds::ExtendedContextEntry* context_entry)
-        : parent_(parent), extended_context_entry_(context_entry), second_level_pt_(parent, this),
-          region_alloc_(), bdf_(bdf), extended_(true), domain_id_(domain_id) {
-}
-
-DeviceContext::DeviceContext(ds::Bdf bdf, uint32_t domain_id, IommuImpl* parent,
-                             volatile ds::ContextEntry* context_entry)
-        : parent_(parent), context_entry_(context_entry), second_level_pt_(parent, this),
-          region_alloc_(), bdf_(bdf), extended_(false),
-          domain_id_(domain_id) {
-}
-
-DeviceContext::~DeviceContext() {
-    bool was_present;
-    if (extended_) {
-        ds::ExtendedContextEntry entry;
-        entry.ReadFrom(extended_context_entry_);
-        was_present = entry.present();
-        entry.set_present(0);
-        entry.WriteTo(extended_context_entry_);
-    } else {
-        ds::ContextEntry entry;
-        entry.ReadFrom(context_entry_);
-        was_present = entry.present();
-        entry.set_present(0);
-        entry.WriteTo(context_entry_);
-    }
-
-    if (was_present) {
-        // When modifying a present (extended) context entry, we must serially
-        // invalidate the context-cache, the PASID-cache, then the IOTLB (see
-        // 6.2.2.1 "Context-Entry Programming Considerations" in the VT-d spec,
-        // Oct 2014 rev).
-        parent_->InvalidateContextCacheDomain(domain_id_);
-        // TODO(teisenbe): Invalidate the PASID cache once we support those
-        parent_->InvalidateIotlbDomainAll(domain_id_);
-    }
-
-    second_level_pt_.Destroy();
-}
-
-zx_status_t DeviceContext::InitCommon() {
-    // TODO(teisenbe): don't hardcode PML4_L
-    DEBUG_ASSERT(parent_->caps()->supports_48_bit_agaw());
-    zx_status_t status = second_level_pt_.Init(PML4_L);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    constexpr size_t kMaxAllocatorMemoryUsage = 16 * PAGE_SIZE;
-    fbl::RefPtr<RegionAllocator::RegionPool> region_pool =
-            RegionAllocator::RegionPool::Create(kMaxAllocatorMemoryUsage);
-    if (region_pool == nullptr) {
-        return ZX_ERR_NO_MEMORY;
-    }
-    status = region_alloc_.SetRegionPool(ktl::move(region_pool));
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // Start the allocations at 1MB to handle the equivalent of nullptr
-    // dereferences.
-    uint64_t base = 1ull << 20;
-    uint64_t size = aspace_size() - base;
-    region_alloc_.AddRegion({ .base = 1ull << 20, .size = size });
-    return ZX_OK;
-}
-
-zx_status_t DeviceContext::Create(ds::Bdf bdf, uint32_t domain_id, IommuImpl* parent,
-                                  volatile ds::ContextEntry* context_entry,
-                                  ktl::unique_ptr<DeviceContext>* device) {
-    ds::ContextEntry entry;
-    entry.ReadFrom(context_entry);
-
-    // It's a bug if we're trying to re-initialize an existing entry
-    ASSERT(!entry.present());
-
-    fbl::AllocChecker ac;
-    ktl::unique_ptr<DeviceContext> dev(new (&ac) DeviceContext(bdf, domain_id, parent,
-                                                               context_entry));
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    zx_status_t status = dev->InitCommon();
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    entry.set_present(1);
-    entry.set_fault_processing_disable(0);
-    entry.set_translation_type(ds::ContextEntry::kDeviceTlbDisabled);
-    // TODO(teisenbe): don't hardcode this
-    entry.set_address_width(ds::ContextEntry::k48Bit);
-    entry.set_domain_id(domain_id);
-    entry.set_second_level_pt_ptr(dev->second_level_pt_.phys() >> 12);
-
-    entry.WriteTo(context_entry);
-
-    *device = ktl::move(dev);
-    return ZX_OK;
-}
-
-zx_status_t DeviceContext::Create(ds::Bdf bdf, uint32_t domain_id, IommuImpl* parent,
-                                  volatile ds::ExtendedContextEntry* context_entry,
-                                  ktl::unique_ptr<DeviceContext>* device) {
-
-    ds::ExtendedContextEntry entry;
-    entry.ReadFrom(context_entry);
-
-    // It's a bug if we're trying to re-initialize an existing entry
-    ASSERT(!entry.present());
-
-    fbl::AllocChecker ac;
-    ktl::unique_ptr<DeviceContext> dev(new (&ac) DeviceContext(bdf, domain_id,
-                                                               parent, context_entry));
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    zx_status_t status = dev->InitCommon();
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    entry.set_present(1);
-    entry.set_fault_processing_disable(0);
-    entry.set_translation_type(ds::ExtendedContextEntry::kHostModeWithDeviceTlbDisabled);
-    entry.set_deferred_invld_enable(0);
-    entry.set_page_request_enable(0);
-    entry.set_nested_translation_enable(0);
-    entry.set_pasid_enable(0);
-    entry.set_global_page_enable(0);
-    // TODO(teisenbe): don't hardcode this
-    entry.set_address_width(ds::ExtendedContextEntry::k48Bit);
-    entry.set_no_exec_enable(1);
-    entry.set_write_protect_enable(1);
-    entry.set_cache_disable(0);
-    entry.set_extended_mem_type_enable(0);
-    entry.set_domain_id(domain_id);
-    entry.set_smep_enable(1);
-    entry.set_extended_accessed_flag_enable(0);
-    entry.set_execute_requests_enable(0);
-    entry.set_second_level_execute_bit_enable(0);
-    entry.set_second_level_pt_ptr(dev->second_level_pt_.phys() >> 12);
-
-    entry.WriteTo(context_entry);
-
-    *device = ktl::move(dev);
-    return ZX_OK;
-}
-
-namespace {
-
-uint perms_to_arch_mmu_flags(uint32_t perms) {
-    uint flags = 0;
-    if (perms & IOMMU_FLAG_PERM_READ) {
-        flags |= ARCH_MMU_FLAG_PERM_READ;
-    }
-    if (perms & IOMMU_FLAG_PERM_WRITE) {
-        flags |= ARCH_MMU_FLAG_PERM_WRITE;
-    }
-    if (perms & IOMMU_FLAG_PERM_EXECUTE) {
-        flags |= ARCH_MMU_FLAG_PERM_EXECUTE;
-    }
-    return flags;
-}
-
-} // namespace
-
-zx_status_t DeviceContext::SecondLevelMap(const fbl::RefPtr<VmObject>& vmo, uint64_t offset,
-                                          size_t size, uint32_t perms, bool map_contiguous,
-                                          paddr_t* virt_paddr, size_t* mapped_len) {
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(offset));
-
-    uint flags = perms_to_arch_mmu_flags(perms);
-
-    if (vmo->is_paged() && !static_cast<VmObjectPaged*>(vmo.get())->is_contiguous()) {
-        return SecondLevelMapDiscontiguous(vmo, offset, size, flags, map_contiguous,
-                                           virt_paddr, mapped_len);
-    }
-    return SecondLevelMapContiguous(vmo, offset, size, flags, virt_paddr, mapped_len);
-}
-
-zx_status_t DeviceContext::SecondLevelMapDiscontiguous(const fbl::RefPtr<VmObject>& vmo,
-                                                       uint64_t offset, size_t size, uint flags,
-                                                       bool map_contiguous, paddr_t* virt_paddr,
-                                                       size_t* mapped_len) {
-    // If we don't need to map everything, don't try to map more than
-    // the min contiguity at a time.
-    const uint64_t min_contig = minimum_contiguity();
-    if (!map_contiguous && size > min_contig) {
-        size = min_contig;
-    }
-
-    auto lookup_fn = [](void* ctx, size_t offset, size_t index, paddr_t pa) {
-        paddr_t* paddr = static_cast<paddr_t*>(ctx);
-        paddr[index] = pa;
-        return ZX_OK;
-    };
-
-    RegionAllocator::Region::UPtr region;
-    zx_status_t status = region_alloc_.GetRegion(size, min_contig, region);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // Reserve a spot in the allocated regions list, so the extension can't fail
-    // after we do the map.
-    fbl::AllocChecker ac;
-    allocated_regions_.reserve(allocated_regions_.size() + 1, &ac);
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    paddr_t base = region->base;
-    size_t remaining = size;
-
-    auto cleanup_partial = fbl::MakeAutoCall([&]() {
-        size_t allocated = base - region->base;
-        size_t unmapped;
-        second_level_pt_.UnmapPages(base, allocated / PAGE_SIZE, &unmapped);
-        DEBUG_ASSERT(unmapped == allocated / PAGE_SIZE);
-    });
-
-    while (remaining > 0) {
-        const size_t kNumEntriesPerLookup = 32;
-        size_t chunk_size = fbl::min(remaining, kNumEntriesPerLookup * PAGE_SIZE);
-        paddr_t paddrs[kNumEntriesPerLookup] = {};
-        status = vmo->Lookup(offset, chunk_size, lookup_fn, &paddrs);
-        if (status != ZX_OK) {
-            return status;
-        }
-
-        size_t map_len = chunk_size / PAGE_SIZE;
-        size_t mapped;
-        status = second_level_pt_.MapPages(base, paddrs, map_len, flags, &mapped);
-        if (status != ZX_OK) {
-            return status;
-        }
-        ASSERT(mapped == map_len);
-
-        base += chunk_size;
-        offset += chunk_size;
-        remaining -= chunk_size;
-    }
-
-    cleanup_partial.cancel();
-
-    *virt_paddr = region->base;
-    *mapped_len = size;
-
-    allocated_regions_.push_back(ktl::move(region), &ac);
-    // Check shouldn't be able to fail, since we reserved the capacity already
-    ASSERT(ac.check());
-
-    LTRACEF("Map(%02x:%02x.%1x): -> [%p, %p) %#x\n", bdf_.bus(), bdf_.dev(), bdf_.func(),
-            (void*)*virt_paddr, (void*)(*virt_paddr + *mapped_len), flags);
-    return ZX_OK;
-}
-
-zx_status_t DeviceContext::SecondLevelMapContiguous(const fbl::RefPtr<VmObject>& vmo,
-                                                    uint64_t offset, size_t size, uint flags,
-                                                    paddr_t* virt_paddr, size_t* mapped_len) {
-
-    DEBUG_ASSERT(!vmo->is_paged() || static_cast<VmObjectPaged*>(vmo.get())->is_contiguous());
-
-    auto lookup_fn = [](void* ctx, size_t offset, size_t index, paddr_t pa) {
-        paddr_t* paddr = static_cast<paddr_t*>(ctx);
-        *paddr = pa;
-        return ZX_OK;
-    };
-
-    // Lookup the page in the VMO at the given offset. Since we know the VMO is
-    // contiguous, we can just extrapolate the rest of the addresses from the
-    // first.
-    paddr_t paddr = UINT64_MAX;
-    zx_status_t status = vmo->Lookup(offset, PAGE_SIZE, lookup_fn, &paddr);
-    if (status != ZX_OK) {
-        return status;
-    }
-    DEBUG_ASSERT(paddr != UINT64_MAX);
-
-    RegionAllocator::Region::UPtr region;
-    uint64_t min_contig = minimum_contiguity();
-    status = region_alloc_.GetRegion(size, min_contig, region);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // Reserve a spot in the allocated regions list, so the extension can't fail
-    // after we do the map.
-    fbl::AllocChecker ac;
-    allocated_regions_.reserve(allocated_regions_.size() + 1, &ac);
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    size_t map_len = size / PAGE_SIZE;
-    size_t mapped;
-    status = second_level_pt_.MapPagesContiguous(region->base, paddr, map_len, flags, &mapped);
-    if (status != ZX_OK) {
-        return status;
-    }
-    ASSERT(mapped == map_len);
-
-    *virt_paddr = region->base;
-    *mapped_len = map_len * PAGE_SIZE;
-
-    allocated_regions_.push_back(ktl::move(region), &ac);
-    // Check shouldn't be able to fail, since we reserved the capacity already
-    ASSERT(ac.check());
-
-    LTRACEF("Map(%02x:%02x.%1x): [%p, %p) -> %p %#x\n", bdf_.bus(), bdf_.dev(), bdf_.func(),
-            (void*)paddr, (void*)(paddr + size), (void*)paddr, flags);
-    return ZX_OK;
-}
-
-zx_status_t DeviceContext::SecondLevelMapIdentity(paddr_t base, size_t size, uint32_t perms) {
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(base));
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(size));
-
-    uint flags = perms_to_arch_mmu_flags(perms);
-
-    RegionAllocator::Region::UPtr region;
-    zx_status_t status = region_alloc_.GetRegion({ base, size }, region);
-    if (status != ZX_OK) {
-        return status;
-    }
-
-    // Reserve a spot in the allocated regions list, so the extension can't fail
-    // after we do the map.
-    fbl::AllocChecker ac;
-    allocated_regions_.reserve(allocated_regions_.size() + 1, &ac);
-    if (!ac.check()) {
-        return ZX_ERR_NO_MEMORY;
-    }
-
-    size_t map_len = size / PAGE_SIZE;
-    size_t mapped;
-    status = second_level_pt_.MapPagesContiguous(base, base, map_len, flags, &mapped);
-    if (status != ZX_OK) {
-        return status;
-    }
-    ASSERT(mapped == map_len);
-
-    allocated_regions_.push_back(ktl::move(region), &ac);
-    ASSERT(ac.check());
-    return ZX_OK;
-}
-
-zx_status_t DeviceContext::SecondLevelUnmap(paddr_t virt_paddr, size_t size) {
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(virt_paddr));
-    DEBUG_ASSERT(IS_PAGE_ALIGNED(size));
-
-    // Check if we're trying to partially unmap a region, and if so fail.
-    for (size_t i = 0; i < allocated_regions_.size(); ++i) {
-        const auto& region = allocated_regions_[i];
-
-        paddr_t intersect_base;
-        size_t intersect_size;
-        if (!GetIntersect(virt_paddr, size, region->base, region->size,
-                          &intersect_base, &intersect_size)) {
-            continue;
-        }
-
-        if (intersect_base != region->base || intersect_size != region->size) {
-            return ZX_ERR_NOT_SUPPORTED;
-        }
-    }
-
-    for (size_t i = 0; i < allocated_regions_.size(); ++i) {
-        const auto& region = allocated_regions_[i];
-        if (region->base < virt_paddr || region->base + region->size > virt_paddr + size) {
-            continue;
-        }
-
-        size_t unmapped;
-        LTRACEF("Unmap(%02x:%02x.%1x): [%p, %p)\n", bdf_.bus(), bdf_.dev(), bdf_.func(),
-                (void*)region->base, (void*)(region->base + region->size));
-        zx_status_t status = second_level_pt_.UnmapPages(region->base, region->size / PAGE_SIZE,
-                                                         &unmapped);
-        // Unmap should only be able to fail if an input was invalid
-        ASSERT(status == ZX_OK);
-        allocated_regions_.erase(i);
-        i--;
-    }
-
-    return ZX_OK;
-}
-
-uint64_t DeviceContext::minimum_contiguity() const {
-    // TODO(teisenbe): Do not hardcode this.
-    return 1ull << 20;
-}
-
-uint64_t DeviceContext::aspace_size() const {
-    // TODO(teisenbe): Do not hardcode this
-    // 2^48 is the size of an address space using 4-levevel translation.
-    return 1ull << 48;
-}
-
-} // namespace intel_iommu
diff --git a/kernel/dev/iommu/intel/device_context.h b/kernel/dev/iommu/intel/device_context.h
deleted file mode 100644
index 5a2e6b4..0000000
--- a/kernel/dev/iommu/intel/device_context.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <fbl/intrusive_double_list.h>
-#include <fbl/macros.h>
-#include <ktl/unique_ptr.h>
-#include <fbl/vector.h>
-#include <region-alloc/region-alloc.h>
-#include <vm/vm_object.h>
-
-#include "hw.h"
-#include "second_level_pt.h"
-
-namespace intel_iommu {
-
-class IommuImpl;
-
-class DeviceContext : public fbl::DoublyLinkedListable<ktl::unique_ptr<DeviceContext>> {
-public:
-    ~DeviceContext();
-
-    // Create a new DeviceContext representing the given BDF.  It is a fatal error
-    // to try to create a context for a BDF that already has one.
-    static zx_status_t Create(ds::Bdf bdf, uint32_t domain_id, IommuImpl* parent,
-                              volatile ds::ExtendedContextEntry* context_entry,
-                              ktl::unique_ptr<DeviceContext>* device);
-    static zx_status_t Create(ds::Bdf bdf, uint32_t domain_id, IommuImpl* parent,
-                              volatile ds::ContextEntry* context_entry,
-                              ktl::unique_ptr<DeviceContext>* device);
-
-    // Check if this DeviceContext is for the given BDF
-    bool is_bdf(ds::Bdf bdf) const {
-        return bdf_ == bdf;
-    }
-
-    uint32_t domain_id() const { return domain_id_; }
-
-    uint64_t minimum_contiguity() const;
-    uint64_t aspace_size() const;
-
-    // Use the second-level translation table to map the host pages in the given
-    // range on |vmo| to the guest's address |*virt_paddr|.  |size| is in bytes.
-    // |mapped_len| may be larger than |size|, if |size| was not page-aligned.
-    //
-    // If |map_contiguous| is false, this function may return a partial mapping,
-    // in which case |mapped_len| will indicate how many bytes were actually mapped.
-    //
-    // If |map_contiguous| is true, this function will never return a partial
-    // mapping, and |mapped_len| should be equal to |size|.
-    zx_status_t SecondLevelMap(const fbl::RefPtr<VmObject>& vmo,
-                               uint64_t offset, size_t size, uint32_t perms,
-                               bool map_contiguous, paddr_t* virt_paddr, size_t* mapped_len);
-    zx_status_t SecondLevelUnmap(paddr_t virt_paddr, size_t size);
-
-    // Use the second-level translation table to identity-map the given range of
-    // host pages.
-    zx_status_t SecondLevelMapIdentity(paddr_t base, size_t size, uint32_t perms);
-
-private:
-    DeviceContext(ds::Bdf bdf, uint32_t domain_id, IommuImpl* parent,
-                  volatile ds::ExtendedContextEntry* context_entry);
-    DeviceContext(ds::Bdf bdf, uint32_t domain_id, IommuImpl* parent,
-                  volatile ds::ContextEntry* context_entry);
-
-    DISALLOW_COPY_ASSIGN_AND_MOVE(DeviceContext);
-
-    // Shared initialization code for the two public Create() methods
-    zx_status_t InitCommon();
-
-    // Map a VMO which may consist of discontiguous physical pages. If
-    // |map_contiguous| is true, this must either map the whole requested range
-    // contiguously, or fail. If |map_contiguous| is false, it may return
-    // success with a partial mapping.
-    zx_status_t SecondLevelMapDiscontiguous(const fbl::RefPtr<VmObject>& vmo,
-                                            uint64_t offset, size_t size, uint flags,
-                                            bool map_contiguous, paddr_t* virt_paddr,
-                                            size_t* mapped_len);
-
-    // Map a VMO which consists of contiguous physical pages. Currently we assume
-    // that all contiguous VMOs should be mapped as a contiguous range, so this
-    // function will not return a partial mapping.
-    zx_status_t SecondLevelMapContiguous(const fbl::RefPtr<VmObject>& vmo,
-                                         uint64_t offset, size_t size, uint flags,
-                                         paddr_t* virt_paddr, size_t* mapped_len);
-
-    IommuImpl* const parent_;
-    union {
-        volatile ds::ExtendedContextEntry* const extended_context_entry_;
-        volatile ds::ContextEntry* const context_entry_;
-    };
-
-    // Page tables used for translating requests-without-PASID and for nested
-    // translation of requests-with-PASID.
-    SecondLevelPageTable second_level_pt_;
-    RegionAllocator region_alloc_;
-    // TODO(ZX-3210) Use a better data structure for these.  If the
-    // region nodes were intrusive, we wouldn't need to have a
-    // resizable array for this and we could have cheaper removal.  We
-    // can fix this up when it's a problem though.
-    //
-    fbl::Vector<RegionAllocator::Region::UPtr> allocated_regions_;
-
-    const ds::Bdf bdf_;
-    const bool extended_;
-    const uint32_t domain_id_;
-};
-
-} // namespace intel_iommu
diff --git a/kernel/dev/iommu/intel/domain_allocator.cpp b/kernel/dev/iommu/intel/domain_allocator.cpp
deleted file mode 100644
index ba5363b..0000000
--- a/kernel/dev/iommu/intel/domain_allocator.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#include "domain_allocator.h"
-
-#include <assert.h>
-
-namespace intel_iommu {
-
-DomainAllocator::DomainAllocator()
-        // Note that next_domain_id_ starts at 1, since under some conditions 0 is
-        // an invalid domain ID (i.e. if CM is set in the capability register).
-        : num_domains_(0), next_domain_id_(1) { }
-
-zx_status_t DomainAllocator::Allocate(uint32_t* domain_id) {
-    if (next_domain_id_ >= num_domains_) {
-        return ZX_ERR_NO_RESOURCES;
-    }
-
-    // This allocator should be enough, since the hardware should have enough
-    // domain IDs for each device hanging off of it. If we start deallocating
-    // Context Entries, we'll need to make this allocator more sophisticated to
-    // manage the ID reuse.
-    *domain_id = next_domain_id_++;
-    return ZX_OK;
-}
-
-void DomainAllocator::set_num_domains(uint32_t num) {
-    ASSERT(num >= next_domain_id_);
-    num_domains_ = num;
-}
-
-} // namespace intel_iommu
diff --git a/kernel/dev/iommu/intel/domain_allocator.h b/kernel/dev/iommu/intel/domain_allocator.h
deleted file mode 100644
index e0b4bb3..0000000
--- a/kernel/dev/iommu/intel/domain_allocator.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <err.h>
-#include <stdint.h>
-
-#include <fbl/macros.h>
-
-namespace intel_iommu {
-
-// Manages the domain ID space for a given IOMMU.  This is not thread-safe.
-class DomainAllocator {
-public:
-    DomainAllocator();
-
-    // Get an unused domain ID.
-    // Returns ZX_ERR_NO_RESOURCES if one cannot be found.
-    zx_status_t Allocate(uint32_t* domain_id);
-
-    // Set the number of domain IDs this instance manages.  Panics if this call
-    // would reduce the max domain ID to below the current highest allocated one.
-    void set_num_domains(uint32_t num);
-
-private:
-    DISALLOW_COPY_ASSIGN_AND_MOVE(DomainAllocator);
-
-    uint32_t num_domains_;
-    uint32_t next_domain_id_;
-};
-
-} // namespace intel_iommu
diff --git a/kernel/dev/iommu/intel/hw.h b/kernel/dev/iommu/intel/hw.h
deleted file mode 100644
index 3f35b06..0000000
--- a/kernel/dev/iommu/intel/hw.h
+++ /dev/null
@@ -1,499 +0,0 @@
-// Copyright 2018 The Fuchsia Authors
-//
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file or at
-// https://opensource.org/licenses/MIT
-
-#pragma once
-
-#include <arch/ops.h>
-#include <err.h>
-#include <hwreg/bitfields.h>
-#include <kernel/atomic.h>
-#include <stdint.h>
-#include <zircon/compiler.h>
-
-namespace intel_iommu {
-
-namespace reg {
-
-class Version : public hwreg::RegisterBase<Version, uint32_t> {
-public:
-    static constexpr uint32_t kAddr = 0x0;
-    static auto Get() { return hwreg::RegisterAddr<Version>(kAddr); }
-
-    DEF_FIELD(3, 0, minor);
-    DEF_FIELD(7, 4, major);
-    DEF_RSVDZ_FIELD(31, 8);
-};
-
-class Capability : public hwreg::RegisterBase<Capability, uint64_t> {
-public:
-    static constexpr uint32_t kAddr = 0x8;
-    static auto Get() { return hwreg::RegisterAddr<Capability>(kAddr); }
-
-    DEF_FIELD(2, 0, num_domains);
-    DEF_BIT(3, adv_fault_logging);
-    DEF_BIT(4, required_write_buf_flushing);
-    DEF_BIT(5, supports_protected_low_mem);
-    DEF_BIT(6, supports_protected_high_mem);
-    DEF_BIT(7, caching_mode);
-    DEF_RSVDZ_BIT(8);
-    DEF_BIT(9, supports_39_bit_agaw);
-    DEF_BIT(10, supports_48_bit_agaw);
-    DEF_RSVDZ_BIT(11);
-    DEF_RSVDZ_BIT(12);
-    DEF_RSVDZ_FIELD(15, 13);
-    DEF_FIELD(21, 16, max_guest_addr_width);
-    DEF_BIT(22, supports_zero_length_read);
-    DEF_RSVDZ_BIT(23);
-    DEF_FIELD(33, 24, fault_recording_register_offset);
-    DEF_BIT(34, supports_second_level_2mb_page);
-    DEF_BIT(35, supports_second_level_1gb_page);
-    DEF_RSVDZ_FIELD(37, 36);
-    DEF_RSVDZ_BIT(38);
-    DEF_BIT(39, supports_page_selective_invld);
-    DEF_FIELD(47, 40, num_fault_recording_reg);
-    DEF_FIELD(53, 48, max_addr_mask_value);
-    DEF_BIT(54, supports_write_draining);
-    DEF_BIT(55, supports_read_draining);
-    DEF_BIT(56, supports_first_level_1gb_page);
-    DEF_RSVDZ_FIELD(58, 57);
-    DEF_BIT(59, supports_posted_interrupts);
-    DEF_RSVDZ_FIELD(63, 60);
-};
-
-class ExtendedCapability : public hwreg::RegisterBase<ExtendedCapability, uint64_t> {
-public:
-    static constexpr uint32_t kAddr = 0x10;
-    static auto Get() { return hwreg::RegisterAddr<ExtendedCapability>(kAddr); }
-
-    DEF_BIT(0, page_walk_coherency);
-    DEF_BIT(1, supports_queued_invld);
-    DEF_BIT(2, supports_device_tlb);
-    DEF_BIT(3, supports_interrupt_remapping);
-    DEF_BIT(4, supports_extended_interrupt_mode);
-    DEF_BIT(6, supports_pass_through);
-    DEF_BIT(7, supports_snoop_control);
-    DEF_FIELD(17, 8, iotlb_register_offset);
-    DEF_RSVDZ_FIELD(19, 18);
-    DEF_FIELD(23, 20, max_handle_mask_value);
-    DEF_BIT(24, supports_extended_context);
-    DEF_BIT(25, supports_memory_type);
-    DEF_BIT(26, supports_nested_translation);
-    DEF_BIT(27, supports_deferred_invld);
-    DEF_BIT(28, supports_pasid);
-    DEF_BIT(29, supports_page_requests);
-    DEF_BIT(30, supports_execute_requests);
-    DEF_BIT(31, supports_supervisor_requests);
-    DEF_RSVDZ_BIT(32);
-    DEF_BIT(33, supports_no_write_flag);
-    DEF_BIT(34, supports_extended_accessed_flag);
-    DEF_FIELD(39, 35, pasid_size)