Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1641
-gerrit
commit b00c6de1f3feb04ad136c83275ac3fd8893cb0f0 Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Mon May 7 20:31:52 2012 +0300
LUA interface change for Qemu
This changes interface between Qemu and LUA to support modular scripting system. Single-file serialice.lua script is deleted,
New modular scripts will require lua >= 5.2 with integrated bitlib.
Change-Id: I7c4678ab6313857d81233aadfb6a44b7e7ca4ed0 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- SerialICE/scripts/serialice.lua | 773 ---------------------------------------- qemu-0.15.x/serialice-lua.c | 271 +++++++------- qemu-0.15.x/serialice.c | 136 +++---- qemu-0.15.x/serialice.h | 41 ++- 4 files changed, 205 insertions(+), 1016 deletions(-)
diff --git a/SerialICE/scripts/serialice.lua b/SerialICE/scripts/serialice.lua deleted file mode 100644 index 0e7e902..0000000 --- a/SerialICE/scripts/serialice.lua +++ /dev/null @@ -1,773 +0,0 @@ --- --- SerialICE --- --- Copyright (c) 2009 coresystems GmbH --- --- Permission is hereby granted, free of charge, to any person obtaining a copy --- of this software and associated documentation files (the "Software"), to deal --- in the Software without restriction, including without limitation the rights --- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --- copies of the Software, and to permit persons to whom the Software is --- furnished to do so, subject to the following conditions: --- --- The above copyright notice and this permission notice shall be included in --- all copies or substantial portions of the Software. --- --- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL --- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN --- THE SOFTWARE. --- - -io.write("SerialICE: Starting LUA script\n") - --- If you get an error here, install bitlib --- (ie. http://luaforge.net/projects/bitlib/) -require("bit") - -function printf(s,...) - return io.write(s:format(...)) -end - -function size_suffix(size) - if size == 1 then return "b" - elseif size == 2 then return "w" - elseif size == 4 then return "l" - elseif size == 8 then return "ll" - else return string.format("invalid size: %d", size) - end -end - -function size_data(size, data) - if size == 1 then return string.format("%02x", data) - elseif size == 2 then return string.format("%04x", data) - elseif size == 4 then return string.format("%08x", data) - elseif size == 8 then return string.format("%16x", data) - else return string.format("Error: size=%x", size) - end -end - -function pci_bdf(bus, dev, func, reg) - return 0x80000000 + bus*65536 + dev*2048 + func*256 + reg -end - -car_regions = { list = nil } - -function new_car_region(start, size) - car_regions.list = { next = car_regions.list, start = start, size = size } - SerialICE_register_physical(start, size) -end - -function is_car(addr) - if car_regions.list == nil then - return false - end - local l = car_regions.list - while l do - if addr >= l.start and addr < l.start + l.size then - return true - end - l = l.next - end - return false -end - -function new_list() - return { list = nil } -end - -function prepend_to_list(list, value) - list.list = { next = list.list, value = value } -end - -function walk_list(list, ...) - if list == nil or list.list == nil then - return false - end - local l = list.list - while l do - if l.value(...) then - return true - end - l = l.next - end - return false -end - -io_read_hooks = new_list() -io_write_hooks = new_list() -io_read_log_hooks = new_list() -io_write_log_hooks = new_list() - -msr_read_hooks = new_list() -msr_write_hooks = new_list() - -mem_read_log_hooks = new_list() -mem_write_log_hooks = new_list() - -prepend_to_list(mem_read_log_hooks, function(addr, size, data, target) - if (PCIe_bar ~= 0) and addr >= PCIe_bar and addr <= (PCIe_bar + PCIe_size) then - printf("PCIe %x:%02x.%x R.%02x => %s\n", - bit.band(0xff,bit.rshift(addr, 20)), - bit.band(0x1f,bit.rshift(addr, 15)), - bit.band(0x7,bit.rshift(addr, 12)), - bit.band(0xfff,addr), - size_data(size, data)) - return true - end -end) - -prepend_to_list(mem_write_log_hooks, function(addr, size, data, target) - if (PCIe_bar ~= 0) and addr >= PCIe_bar and addr <= (PCIe_bar + PCIe_size) then - printf("PCIe %x:%02x.%x R.%02x <= %s\n", - bit.band(0xff,bit.rshift(addr, 20)), - bit.band(0x1f,bit.rshift(addr, 15)), - bit.band(0x7,bit.rshift(addr, 12)), - bit.band(0xfff,addr), - size_data(size, data)) - return true - end -end) - -prepend_to_list(io_write_log_hooks, function(port, size, data, target) - if port == 0xcf9 then - printf("Reset triggered at %04x:%04x\n", regs.cs, regs.eip); - return true - end -end) - -prepend_to_list(io_write_log_hooks, function(port, size, data, target) - if port == 0xcf8 then - return true -- Ignore - end - if port >= 0xcfc and port <= 0xcff then - printf("PCI %x:%02x.%x R.%02x <= %s\n", - bit.band(0xff,bit.rshift(SerialICE_pci_device, 16)), - bit.band(0x1f,bit.rshift(SerialICE_pci_device, 11)), - bit.band(0x7,bit.rshift(SerialICE_pci_device, 8)), - bit.band(0xff,SerialICE_pci_device + (port - 0xcfc)), - size_data(size, data)) - return true - end -end) - -prepend_to_list(io_read_log_hooks, function(port, size, data, target) - if port == 0xcf8 then - return true -- Ignore - end - if port >= 0xcfc and port <= 0xcff then - printf("PCI %x:%02x.%x R.%02x => %s\n", - bit.band(0xff,bit.rshift(SerialICE_pci_device, 16)), - bit.band(0x1f,bit.rshift(SerialICE_pci_device, 11)), - bit.band(0x7,bit.rshift(SerialICE_pci_device, 8)), - bit.band(0xff,SerialICE_pci_device + (port - 0xcfc)), - size_data(size, data)) - return true - end -end) - --- handle MTRRs -prepend_to_list(msr_write_hooks, -function(addr, hi, lo, filtered) - if addr >= 0x200 and addr < 0x210 then - if addr % 2 == 0 then - mt = lo % 0x100 - if mt == 0 then memtype = "Uncacheable" - elseif mt == 1 then memtype = "Write-Combine" - elseif mt == 4 then memtype = "Write-Through" - elseif mt == 5 then memtype = "Write-Protect" - elseif mt == 6 then memtype = "Write-Back" - else memtype = "Unknown" - end - printf("CPU: Set MTRR %x base to %08x.%08x (%s)\n", (addr - 0x200) / 2, hi, bit.band(lo, 0xffffff00), memtype) - else - if bit.band(lo, 0x800) == 0x800 then - valid = "valid" - else - valid = "disabled" - end - printf("CPU: Set MTRR %x mask to %08x.%08x (%s)\n", (addr - 0x200) / 2, hi, bit.band(lo, 0xfffff000), valid) - end - return true - end - return false -end) - -function trim (s) - return (string.gsub(s, "^%s*(.-)%s*$", "%1")) -end - -mainboard = trim(SerialICE_mainboard) - -if northbridge == "intel-i945" then - prepend_to_list(io_write_hooks, function(port, size, data, filter) - if port == 0xcfc then - -- Catch PCIe base address - if SerialICE_pci_device == pci_bdf(0,0,0,0x48) then - PCIe_bar = bit.band(0xfc000000,data) % 0x100000000 - PCIe_size = 64 * 1024 -- hard coded for now. - printf("PCIe BAR set up: 0x%08x\n", PCIe_bar) - return true - end - end - return false - end) -end - --- In the beginning, during RAM initialization, it is essential that --- all DRAM accesses are handled by the target, or RAM will not work --- correctly. After RAM initialization, RAM access has no "special" --- meaning anymore, so we can just use Qemu's memory (and thus get --- an incredible speed-up) - -ram_is_initialized = false - --- Set to "true" to log read access (code fetches) to 0xe0000 to 0xfffff - -log_rom_access = false - --- Set to "true" to log CS:IP for each access - -ip_logging = false - --- Remember the PCI device selected via IO CF8 - -SerialICE_pci_device = 0 - -rom_size = 4 * 1024 * 1024 -rom_base = 0x100000000 - rom_size - --- SerialICE_io_read_filter is the filter function for IO reads. --- --- Parameters: --- port IO port to be read --- data_size Size of the IO read --- Return values: --- caught True if the filter intercepted the read --- data Value returned if the read was intercepted - -function SerialICE_io_read_filter(port, data_size) - local data = 0 - local caught = false - - -- ********************************************************** - -- - - -- if port == 0x42 then - -- printf("WARNING: Hijacking timer port 0x42\n") - -- data = 0x80 - -- caught = true - -- end - - -- ********************************************************** - -- - -- Serial Port handling - - if port >= 0x3f8 and port <= 0x3ff then - printf("Serial I/O read (filtered)\n") - data = 0xff - caught = true - end - - -- ********************************************************** - -- - - if ( port == 0x60 and data_size == 1 ) then - if ( regs.eip == 0xbd6d and regs.eax == 0x8aa and regs.ecx == 0x00fffff0 ) then - -- f000:bd6d - printf("Skipping keyboard timeout...\n") - regs.eax = 0x01aa - regs.ecx = 0x0010 - end - end - - return caught, data -end - -SerialICE_superio_4e_reg = 0 -SerialICE_superio_2e_reg = 0 -SerialICE_superio_2e_ldn = 0 - -PCIe_bar = 0 -PCIe_size = 0 - --- SerialICE_io_write_filter is the filter function for IO writes. --- --- Parameters: --- port IO port to be written to --- size Size of the IO write --- data Data to be written to --- Return values: --- caught True if the filter intercepted the write --- data Value returned if the write was *not* intercepted - -function SerialICE_io_write_filter(port, size, data) - filter = { filter = false, data = data } - if walk_list(io_write_hooks, port, size, data, filter) then - return filter.filter, filter.data - end - -- ********************************************************** - -- - -- PCI config space handling - - if port == 0xcf8 then - SerialICE_pci_device = data - return false, data - end - - if port == 0xcfc then - -- Phoenix BIOS reconfigures 0:1f.0 reg 0x80/0x82. - -- This effectively wipes out our communication channel - -- so we mut not allow it. - if SerialICE_pci_device == 0x8000f880 then - printf("LPC (filtered)\n") - return true, data - end - - return false, data - end - - -- ********************************************************** - -- - -- Dell 1850 BMC filter - - if port == 0xe8 then - -- lua lacks a switch statement - if data == 0x44656c6c then printf("BMC: Dell\n") - elseif data == 0x50726f74 then printf("BMC: Prot\n") - elseif data == 0x496e6974 then - printf("BMC: Init (filtered)\n") - return true, data - else - printf("BMC: unknown %08x\n", data) - end - return false, data - end - - -- ********************************************************** - -- - -- SuperIO config handling - - if port == 0x4e then - SerialICE_superio_4e_reg = data - return false, data - end - - if port == 0x4f then - -- Don't allow that our Serial power gets disabled. - if SerialICE_superio_4e_reg == 0x02 then - printf("SuperIO (filtered)\n") - return true, data - end - -- XXX what's this? - if SerialICE_superio_4e_reg == 0x24 then - printf("SuperIO (filtered)\n") - return true, data - end - end - - if port == 0x2e then - -- We start requiring a decent state machine - SerialICE_superio_2e_reg = data - return false, data - end - - if port == 0x2f then - -- Winbond - if SerialICE_superio_2e_reg == 0x06 then - SerialICE_superio_2e_ldn = data - return false, data - end - - -- Don't allow that our SIO power gets disabled. - if SerialICE_superio_2e_reg == 0x02 then - printf("SuperIO (filtered)\n") - return true, data - end - - -- XXX what's this? - if SerialICE_superio_2e_reg == 0x24 then - printf("SuperIO (filtered)\n") - return true, data - end - end - - -- ********************************************************** - -- - -- Serial Port handling - - - if port > 0x3f8 and port <= 0x3ff then - printf("serial I/O (filtered)\n") - return true, data - end - - if port == 0x3f8 then - printf("COM1: %c\n", data) - return true, data - end - - -- ********************************************************** - -- - -- Intel 82945 (reference BIOS) RAM switch - -- - - -- The RAM initialization code for the i945 used by AMI and - -- Phoenix uses the same POST codes. We use this to determine - -- when RAM init is done on that chipset. - -- Not catching the end of RAM init is not problematic, except - -- that it makes decompression of the BIOS core to RAM incredibly - -- slow as the decompressor inner loop has to be fetched - -- permanently from the target (several reads/writes per - -- decompressed byte). - - if port == 0x80 and data == 0xff37 and ram_is_initialized == false then - ram_is_initialized = true - -- Register low RAM 0x00000000 - 0x000dffff - SerialICE_register_physical(0x00000000, 0xa0000) - -- SMI/VGA memory should go to the target... - SerialICE_register_physical(0x000c0000, 0x20000) - printf("\nLow RAM accesses are now directed to Qemu.\n") - - return false, data - end - - if port == 0xcf9 and data == 0x06 then - SerialICE_system_reset() - return false, data - end - - if ( port == 0xed and data == 0x40 ) then - if ( regs.eip == 0x3ed and regs.ecx == 0x00000290 ) then - printf("Skipping IO delay...\n") - -- f100:03ed - regs.ecx = 0x05 - end - end - - if ( port == 0xed and data == 0x83 ) - then - if ( regs.eip == 0x1bb and regs.ecx == 0x0000fff0 ) then - printf("Skipping IO delay...\n") - -- e002:01bb - regs.ecx = 0x10 - regs.ebx = 0x01 - end - end - - return false, data -end - - --- SerialICE_memory_read_filter is the filter function for memory reads --- --- Parameters: --- addr memory address to be read --- size Size of the memory read --- Return values: --- to_hw True if the read should be directed to the target --- to_qemu True if the read should be directed to Qemu --- result Read result if both to_hw and to_qemu are false - -function SerialICE_memory_read_filter(addr, size) - - -- Example: catch memory read and return a value - -- defined in this script: - -- - -- if addr == 0xfec14004 and size == 4 then - -- return false, false, 0x23232323 - -- end - - -- Cache-As-RAM is exclusively - -- handled by Qemu (RAM backed) - if is_car(addr) then - return false, true, 0 - end - - if addr >= rom_base and addr <= 0xffffffff then - -- ROM accesses go to Qemu only - return false, true, 0 - elseif addr >= PCIe_bar and addr <= (PCIe_bar + PCIe_size) then - -- PCIe MMIO config space accesses are - -- exclusively handled by the SerialICE - -- target - return true, false, 0 - elseif addr >= 0xfed10000 and addr <= 0xfed1ffff then - -- Intel chipset BARs are exclusively - -- handled by the SerialICE target - return true, false, 0 - elseif addr >= 0xfee00000 and addr <= 0xfeefffff then - -- Local APIC.. Hm, not sure what to do here. - -- We should avoid that someone wakes up cores - -- on the target system that go wild. - return true, false, 0 -- XXX Handled by target - elseif addr >= 0xfec00000 and addr <= 0xfecfffff then - -- IO APIC.. Hm, not sure what to do here. - return true, false, 0 -- XXX Handled by target - elseif addr >= 0xfed40000 and addr <= 0xfed45000 then - -- ICH7 TPM - -- Phoenix "Secure" Core bails out if we don't pass this on ;-) - return true, false, 0 - elseif addr >= 0x000e0000 and addr <= 0x000fffff then - -- Low ROM accesses go to Qemu memory - return false, true, 0 - elseif addr >= 0x000a0000 and addr <= 0x000affff then - -- SMI/VGA go to target - return true, false, 0 - elseif addr >= 0x00000000 and addr <= 0x000dffff then - -- RAM access. This is handled by SerialICE - -- but *NOT* exclusively. Writes should end - -- up in Qemu memory, too - if not ram_is_initialized then - -- RAM init has not not been marked done yet. - -- so send reads to the target only. - return true, false, 0 - end - -- RAM init is done. Send all RAM accesses - -- to Qemu. Using the target as storage would - -- only slow execution down. - -- TODO handle VGA / SMI memory correctly - return false, true, 0 - elseif addr >= 0x00100000 and addr <= 0xcfffffff then - -- 3.25GB RAM. This is handled by SerialICE. - -- We refrain from backing up this memory in Qemu - -- because Qemu would need 3.25G RAM on the host - -- and firmware usually does not intensively use - -- high memory anyways. - return true, false, 0 - else - printf("\nWARNING: undefined load operation @%08x\n", addr) - -- Fall through and handle by Qemu - end - return false, true, 0 -end - --- SerialICE_memory_write_filter is the filter function for memory writes --- --- Parameters: --- addr memory address to write to --- size Size of the memory write --- data Data to be written --- Return values: --- to_hw True if the write should be directed to the target --- to_qemu True if the write should be directed to Qemu --- result Data to be written (may be changed in filter) - -function SerialICE_memory_write_filter(addr, size, data) - -- Cache-As-RAM is exclusively - -- handled by Qemu (RAM backed) - if is_car(addr) then - return false, true, data - end - - if addr >= rom_base and addr <= 0xffffffff then - printf("\nWARNING: write access to ROM?\n") - -- ROM accesses go to Qemu only - return false, true, data - elseif addr >= PCIe_bar and addr <= (PCIe_bar + PCIe_size) then - -- PCIe MMIO config space accesses are - -- exclusively handled by the SerialICE - -- target - return true, false, data - elseif addr >= 0xfed10000 and addr <= 0xfed1ffff then - -- Intel chipset BARs are exclusively - -- handled by the SerialICE target - return true, false, data - elseif addr >= 0xfee00000 and addr <= 0xfeefffff then - -- Local APIC.. Hm, not sure what to do here. - -- We should avoid that someone wakes up cores - -- on the target system that go wild. - return true, false, data - elseif addr >= 0xfec00000 and addr <= 0xfecfffff then - -- IO APIC.. Hm, not sure what to do here. - return true, false, data - elseif addr >= 0xfed40000 and addr <= 0xfed45000 then - -- ICH7 TPM - return true, false, data - elseif addr >= 0x000e0000 and addr <= 0x000fffff then - -- Low ROM accesses go to Qemu memory - return false, true, data - elseif addr >= 0x000a0000 and addr <= 0x000affff then - -- SMI/VGA go to target - return true, true, data - elseif addr >= 0x00000000 and addr <= 0x000dffff then - -- RAM access. This is handled by SerialICE during - -- RAM initialization and by Qemu later on. - if not ram_is_initialized then - return true, true, data - end - -- Don't send writes to the target for speed reasons. - return false, true, data - elseif addr >= 0x00100000 and addr <= 0xcfffffff then - if addr == 0x00100000 then - if regs.cs == 0xe002 and regs.eip == 0x07fb then - -- skip high memory wipe - regs.ecx = 0x10 - end - if regs.cs == 0xe002 and regs.eip == 0x076c and regs.edi == 0x3f then - -- skip high memory test - regs.edi=1; - end - end - - -- 3.25 GB RAM ... This is handled by SerialICE - return true, false, data - else - printf("\nWARNING: undefined store operation @%08x\n", addr) - -- Fall through, send to SerialICE - end - - return true, false, data -end - - -function log_cs_ip() - if (ip_logging) then printf("[%04x:%04x] -- ", regs.cs, regs.eip) end -end - -function SerialICE_msr_read_filter(addr, hi, lo) - -- Intel CPU microcode revision check. - if addr == 0x8b then - -- fake microcode revision of my 0x6f6 Core 2 Duo Mobile - return true, 0xc7, 0x00 - end - - return false, hi, lo -end - -function SerialICE_msr_write_filter(addr, hi, lo) - -- Intel CPU microcode update - if addr == 0x79 then - return true, 0, 0xffff0000 - end - - return false, hi, lo -end - -function SerialICE_cpuid_filter(in_eax, in_ecx, eax, ebx, ecx, edx) - -- Set number of cores to 1 on Core Duo and Atom to trick the - -- firmware into not trying to wake up non-BSP nodes. - if in_eax == 1 then - ebx = bit.band(0xff00ffff, ebx); - ebx = bit.bor(0x00010000, ebx); - return true, eax, ebx, ecx, edx - end - - -- return false, so the result is not filtered. - return false, eax, ebx, ecx, edx -end - - --- -------------------------------------------------------------------- --- logging functions - -function SerialICE_memory_write_log(addr, size, data, target) - if addr >= 0x00000000 and addr <= 0x0009ffff and ram_is_initialized then - return - end - if addr >= 0x000c0000 and addr <= 0x000dffff and ram_is_initialized then - return - end - - log_cs_ip() - - if walk_list(mem_write_log_hooks, addr, size, data, target) then - return - end - - printf("MEM: write%s %08x <= %s", size_suffix(size), addr, size_data(size, data)) - if target then - printf(" *") - end - printf("\n") -end - -function SerialICE_memory_read_log(addr, size, data, target) - if addr >= 0x00000000 and addr <= 0x0009ffff and ram_is_initialized then - return - end - if addr >= 0x000c0000 and addr <= 0x000dffff and ram_is_initialized then - return - end - if addr >= 0xe0000 and addr <= 0xfffff and not log_rom_access then - return - end - if addr >= rom_base and addr <= 0xffffffff and not log_rom_access then - return - end - - log_cs_ip() - - if walk_list(mem_read_log_hooks, addr, size, data, target) then - return - end - - printf("MEM: read%s %08x => %s", size_suffix(size), addr, size_data(size, data)) - if target then - printf(" *") - end - printf("\n") -end - -function SerialICE_io_write_log(port, size, data, target) - log_cs_ip() - if walk_list(io_write_log_hooks, port, size, data, target) then - return - end - - printf("IO: out%s %04x <= %s\n", size_suffix(size), port, size_data(size, data)) -end - -function SerialICE_io_read_log(port, size, data, target) - log_cs_ip() - if walk_list(io_read_log_hooks, port, size, data, target) then - return - end - - printf("IO: in%s %04x => %s\n", size_suffix(size), port, size_data(size, data)) -end - -function SerialICE_msr_write_log(addr, hi, lo, filtered) - log_cs_ip() - if not walk_list(msr_write_hooks, addr, hi, lo, filtered) then - printf("CPU: wrmsr %08x <= %08x.%08x\n", addr, hi, lo) - end -end - -function SerialICE_msr_read_log(addr, hi, lo, filtered) - log_cs_ip() - if not walk_list(msr_write_hooks, addr, hi, lo, filtered) then - printf("CPU: rdmsr %08x => %08x.%08x\n", addr, hi, lo) - end -end - -function SerialICE_cpuid_log(in_eax, in_ecx, out_eax, out_ebx, out_ecx, out_edx, filtered) - log_cs_ip() - printf("CPU: CPUID eax: %08x; ecx: %08x => %08x.%08x.%08x.%08x\n", - in_eax, in_ecx, out_eax, out_ebx, out_ecx, out_edx) -end - --- -------------------------------------------------------------------- --- This initialization is executed right after target communication --- has been established - -printf("SerialICE: Registering physical memory areas for Cache-As-Ram:\n") - --- Register Phoenix BIOS Cache as RAM area as normal RAM --- 0xffd80000 - 0xffdfffff -new_car_region(0xffd80000, 0x80000) - --- Register AMI BIOS Cache as RAM area as normal RAM --- 0xffbc0000 - 0xffbfffff -new_car_region(0xffbc0000, 0x40000) - --- current Phoenix BIOS -new_car_region(0xde000, 0x2000) - -printf("SerialICE: LUA script initialized.\n") - -return true - diff --git a/qemu-0.15.x/serialice-lua.c b/qemu-0.15.x/serialice-lua.c index 638f1d3..0216eb2 100644 --- a/qemu-0.15.x/serialice-lua.c +++ b/qemu-0.15.x/serialice-lua.c @@ -43,12 +43,11 @@
#define LOG_IO 1 #define LOG_MEMORY 2 -#define LOG_TARGET 4 +#define LOG_MSR 4
static lua_State *L; - -extern const char *serialice_mainboard; -static const char *serialice_lua_script = "serialice.lua"; +extern char *serialice_mainboard; +static const SerialICE_filter lua_ops;
// ************************************************************************** // LUA scripting interface and callbacks @@ -193,10 +192,12 @@ static int serialice_lua_registers(void) return 0; }
-int serialice_lua_init(void) +const SerialICE_filter * serialice_lua_init(const char *serialice_lua_script) { int status;
+ printf("SerialICE: LUA init...\n"); + /* Create a LUA context and load LUA libraries */ L = luaL_newstate(); luaL_openlibs(L); @@ -228,18 +229,13 @@ int serialice_lua_init(void) } lua_pop(L, 1);
- return 0; + return &lua_ops; }
-#if 0 -/* not used yet */ -int serialice_lua_exit(void) +void serialice_lua_exit(void) { lua_close(L); - return 0; } -#endif -
const char *serialice_lua_execute(const char *cmd) { @@ -255,59 +251,60 @@ const char *serialice_lua_execute(const char *cmd) return errstring; }
-int serialice_io_read_filter(uint32_t * data, uint16_t port, int size) +static int io_read_pre(uint16_t port, int size) { - int ret, result; + int ret = 0, result;
lua_getglobal(L, "SerialICE_io_read_filter"); lua_pushinteger(L, port); // port lua_pushinteger(L, size); // datasize + result = lua_pcall(L, 2, 2, 0); if (result) { fprintf(stderr, "Failed to run function SerialICE_io_read_filter: %s\n", lua_tostring(L, -1)); exit(1); } - *data = lua_tointeger(L, -1); - ret = lua_toboolean(L, -2); - lua_pop(L, 2);
+ ret |= lua_toboolean(L, -1) ? READ_FROM_QEMU : 0; + ret |= lua_toboolean(L, -2) ? READ_FROM_SERIALICE : 0; + lua_pop(L, 2); return ret; }
-int serialice_io_write_filter(uint32_t * data, uint16_t port, int size) +static int io_write_pre(uint32_t * data, uint16_t port, int size) { - int ret, result; + int ret = 0, result;
lua_getglobal(L, "SerialICE_io_write_filter"); lua_pushinteger(L, port); // port lua_pushinteger(L, size); // datasize lua_pushinteger(L, *data); // data
- result = lua_pcall(L, 3, 2, 0); + result = lua_pcall(L, 3, 3, 0); if (result) { fprintf(stderr, "Failed to run function SerialICE_io_write_filter: %s\n", lua_tostring(L, -1)); exit(1); } - *data = lua_tointeger(L, -1); - ret = lua_toboolean(L, -2); - lua_pop(L, 2);
+ *data = lua_tointeger(L, -1); + ret |= lua_toboolean(L, -2) ? WRITE_TO_QEMU : 0; + ret |= lua_toboolean(L, -3) ? WRITE_TO_SERIALICE : 0; + lua_pop(L, 3); return ret; }
- -int serialice_memory_read_filter(uint32_t addr, uint32_t * data, - int size) +static int memory_read_pre(uint32_t addr, int size) { int ret = 0, result;
lua_getglobal(L, "SerialICE_memory_read_filter"); - lua_pushinteger(L, addr); // addr - lua_pushinteger(L, size); // datasize - result = lua_pcall(L, 2, 3, 0); + lua_pushinteger(L, addr); + lua_pushinteger(L, size); + + result = lua_pcall(L, 2, 2, 0); if (result) { fprintf(stderr, "Failed to run function SerialICE_memory_read_filter: %s\n", @@ -315,27 +312,22 @@ int serialice_memory_read_filter(uint32_t addr, uint32_t * data, exit(1); }
- *data = lua_tointeger(L, -1); // result - - ret |= lua_toboolean(L, -2) ? READ_FROM_QEMU : 0; // to_qemu - ret |= lua_toboolean(L, -3) ? READ_FROM_SERIALICE : 0; // to_hw - - lua_pop(L, 3); - + ret |= lua_toboolean(L, -1) ? READ_FROM_QEMU : 0; + ret |= lua_toboolean(L, -2) ? READ_FROM_SERIALICE : 0; + lua_pop(L, 2); return ret; }
- -int serialice_memory_write_filter(uint32_t addr, int size, +static int memory_write_pre(uint32_t addr, int size, uint32_t * data) { int ret = 0, result; - int write_to_qemu, write_to_serialice;
lua_getglobal(L, "SerialICE_memory_write_filter"); lua_pushinteger(L, addr); // address lua_pushinteger(L, size); // datasize lua_pushinteger(L, *data); // data + result = lua_pcall(L, 3, 3, 0); if (result) { fprintf(stderr, @@ -343,82 +335,67 @@ int serialice_memory_write_filter(uint32_t addr, int size, lua_tostring(L, -1)); exit(1); } + *data = lua_tointeger(L, -1); - write_to_qemu = lua_toboolean(L, -2); - write_to_serialice = lua_toboolean(L, -3); + ret |= lua_toboolean(L, -2) ? WRITE_TO_QEMU : 0; + ret |= lua_toboolean(L, -3) ? WRITE_TO_SERIALICE : 0; lua_pop(L, 3); - - ret |= write_to_qemu ? WRITE_TO_QEMU : 0; - ret |= write_to_serialice ? WRITE_TO_SERIALICE : 0; - return ret; }
-int serialice_wrmsr_filter(uint32_t addr, uint32_t * hi, uint32_t * lo) +static int wrmsr_pre(uint32_t addr, uint32_t * hi, uint32_t * lo) { - int ret, result; + int ret = 0, result;
lua_getglobal(L, "SerialICE_msr_write_filter"); lua_pushinteger(L, addr); // port lua_pushinteger(L, *hi); // high lua_pushinteger(L, *lo); // low - result = lua_pcall(L, 3, 3, 0); + + result = lua_pcall(L, 3, 4, 0); if (result) { fprintf(stderr, - "Failed to run function SerialICE_msr_write_filter: %s\n", - lua_tostring(L, -1)); + "Failed to run function SerialICE_msr_write_filter: %s\n", lua_tostring(L, -1)); exit(1); } - ret = lua_toboolean(L, -3); - if (ret) { - *hi = lua_tointeger(L, -1); - *lo = lua_tointeger(L, -2); - } - lua_pop(L, 3);
+ *lo = lua_tointeger(L, -1); + *hi = lua_tointeger(L, -2); + ret |= lua_toboolean(L, -3) ? WRITE_TO_QEMU : 0; + ret |= lua_toboolean(L, -4) ? WRITE_TO_SERIALICE : 0; + lua_pop(L, 4); return ret; }
-int serialice_rdmsr_filter(uint32_t addr, uint32_t * hi, uint32_t * lo) +static int rdmsr_pre(uint32_t addr) { - int ret, result; + int ret = 0, result;
lua_getglobal(L, "SerialICE_msr_read_filter"); - lua_pushinteger(L, addr); // port - lua_pushinteger(L, *hi); // high - lua_pushinteger(L, *lo); // low - result = lua_pcall(L, 3, 3, 0); + lua_pushinteger(L, addr); + + result = lua_pcall(L, 1, 2, 0); if (result) { fprintf(stderr, - "Failed to run function SerialICE_msr_read_filter: %s\n", - lua_tostring(L, -1)); + "Failed to run function SerialICE_msr_read_filter: %s\n", lua_tostring(L, -1)); exit(1); } - ret = lua_toboolean(L, -3); - if (ret) { - *hi = lua_tointeger(L, -1); - *lo = lua_tointeger(L, -2); - } - lua_pop(L, 3);
+ ret |= lua_toboolean(L, -1) ? WRITE_TO_QEMU : 0; + ret |= lua_toboolean(L, -2) ? WRITE_TO_SERIALICE : 0; + lua_pop(L, 2); return ret; }
-int serialice_cpuid_filter(uint32_t eax, uint32_t ecx, - cpuid_regs_t * regs) +static int cpuid_pre(uint32_t eax, uint32_t ecx) { - int ret, result; + int ret = 0, result;
lua_getglobal(L, "SerialICE_cpuid_filter"); - lua_pushinteger(L, eax); // eax before calling lua_pushinteger(L, ecx); // ecx before calling - // and the registers after calling cpuid - lua_pushinteger(L, regs->eax); // eax - lua_pushinteger(L, regs->ebx); // ebx - lua_pushinteger(L, regs->ecx); // ecx - lua_pushinteger(L, regs->edx); // edx - result = lua_pcall(L, 6, 5, 0); + + result = lua_pcall(L, 2, 2, 0); if (result) { fprintf(stderr, "Failed to run function SerialICE_cpuid_filter: %s\n", @@ -426,59 +403,54 @@ int serialice_cpuid_filter(uint32_t eax, uint32_t ecx, exit(1); }
- ret = lua_toboolean(L, -5); - if (ret) { - regs->eax = lua_tointeger(L, -4); - regs->ebx = lua_tointeger(L, -3); - regs->ecx = lua_tointeger(L, -2); - regs->edx = lua_tointeger(L, -1); - } - lua_pop(L, 5); - + ret |= lua_toboolean(L, -1) ? WRITE_TO_QEMU : 0; + ret |= lua_toboolean(L, -2) ? WRITE_TO_SERIALICE : 0; + lua_pop(L, 2); return ret; }
/* SerialICE output loggers */
-static void __read_log(int flags, uint32_t data, uint32_t addr, int size) +static void __read_post(int flags, uint32_t *data) { int result;
if (flags & LOG_MEMORY) { lua_getglobal(L, "SerialICE_memory_read_log"); - } else { + } else if (flags & LOG_IO) { lua_getglobal(L, "SerialICE_io_read_log"); + } else { + fprintf(stderr, "serialice_read_log: bad type\n"); + exit(1); }
- lua_pushinteger(L, addr); // addr/port - lua_pushinteger(L, size); // datasize - lua_pushinteger(L, data); // data - lua_pushboolean(L, ((flags & LOG_TARGET) != 0)); - - result = lua_pcall(L, 4, 0, 0); + lua_pushinteger(L, *data); + result = lua_pcall(L, 1, 1, 0); if (result) { fprintf(stderr, "Failed to run function SerialICE_%s_read_log: %s\n", (flags & LOG_MEMORY) ? "memory" : "io", lua_tostring(L, -1)); exit(1); } + *data = lua_tointeger(L, -1); + lua_pop(L, 1); }
-static void __write_log(int flags, uint32_t data, uint32_t addr, int size) +static void __write_post(int flags) { int result;
if (flags & LOG_MEMORY) { lua_getglobal(L, "SerialICE_memory_write_log"); - } else { + } else if (flags & LOG_IO) { lua_getglobal(L, "SerialICE_io_write_log"); + } else if (flags & LOG_MSR) { + lua_getglobal(L, "SerialICE_msr_write_log"); + } else { + fprintf(stderr, "serialice_write_log: bad type\n"); + exit(1); }
- lua_pushinteger(L, addr); // addr/port - lua_pushinteger(L, size); // datasize - lua_pushinteger(L, data); // data - lua_pushboolean(L, ((flags & LOG_TARGET) != 0)); - - result = lua_pcall(L, 4, 0, 0); + result = lua_pcall(L, 0, 0, 0); if (result) { fprintf(stderr, "Failed to run function SerialICE_%s_write_log: %s\n", (flags & LOG_MEMORY) ? "memory" : "io", lua_tostring(L, -1)); @@ -486,81 +458,86 @@ static void __write_log(int flags, uint32_t data, uint32_t addr, int size) } }
-void serialice_memory_read_log(int caught, uint32_t data, uint32_t addr, int size) +static void memory_read_post(uint32_t * data) { - __read_log(LOG_MEMORY | (caught ? LOG_TARGET : 0), data, addr, size); + __read_post(LOG_MEMORY, data); }
-void serialice_memory_write_log(int caught, uint32_t data, uint32_t addr, int size) +static void memory_write_post(void) { - __write_log(LOG_MEMORY | (caught ? LOG_TARGET : 0), data, addr, size); + __write_post(LOG_MEMORY); }
- -void serialice_io_read_log(int caught, uint32_t data, uint32_t addr, int size) +static void io_read_post(uint32_t * data) { - __read_log(LOG_IO | (caught ? LOG_TARGET : 0), data, addr, size); + __read_post(LOG_IO, data); }
-void serialice_io_write_log(int caught, uint32_t data, uint32_t addr, int size) +static void io_write_post(void) { - __write_log(LOG_IO | (caught ? LOG_TARGET : 0), data, addr, size); + __write_post(LOG_IO); }
-void serialice_wrmsr_log(uint32_t addr, uint32_t hi, - uint32_t lo, int filtered) +static void wrmsr_post(void) { - int result; - - lua_getglobal(L, "SerialICE_msr_write_log"); - lua_pushinteger(L, addr); // addr/port - lua_pushinteger(L, hi); // datasize - lua_pushinteger(L, lo); // data - lua_pushboolean(L, filtered); // data - result = lua_pcall(L, 4, 0, 0); - if (result) { - fprintf(stderr, "Failed to run function SerialICE_msr_write_log: %s\n", - lua_tostring(L, -1)); - exit(1); - } + __write_post(LOG_MSR); }
-void serialice_rdmsr_log(uint32_t addr, uint32_t hi, - uint32_t lo, int filtered) +static void rdmsr_post(uint32_t *hi, uint32_t *lo) { int result;
lua_getglobal(L, "SerialICE_msr_read_log"); - lua_pushinteger(L, addr); // addr/port - lua_pushinteger(L, hi); // datasize - lua_pushinteger(L, lo); // data - lua_pushboolean(L, filtered); // data - result = lua_pcall(L, 4, 0, 0); + lua_pushinteger(L, *hi); + lua_pushinteger(L, *lo); + + result = lua_pcall(L, 2, 2, 0); if (result) { fprintf(stderr, "Failed to run function SerialICE_msr_read_log: %s\n", - lua_tostring(L, -1)); + lua_tostring(L, -1)); exit(1); } + *hi = lua_tointeger(L, -2); + *lo = lua_tointeger(L, -1); + lua_pop(L, 2); }
-void serialice_cpuid_log(uint32_t eax, uint32_t ecx, cpuid_regs_t res, - int filtered) +static void cpuid_post(cpuid_regs_t * res) { int result;
lua_getglobal(L, "SerialICE_cpuid_log"); + lua_pushinteger(L, res->eax); // output: eax + lua_pushinteger(L, res->ebx); // output: ebx + lua_pushinteger(L, res->ecx); // output: ecx + lua_pushinteger(L, res->edx); // output: edx
- lua_pushinteger(L, eax); // input: eax - lua_pushinteger(L, ecx); // input: ecx - lua_pushinteger(L, res.eax); // output: eax - lua_pushinteger(L, res.ebx); // output: ebx - lua_pushinteger(L, res.ecx); // output: ecx - lua_pushinteger(L, res.edx); // output: edx - lua_pushboolean(L, filtered); // data - result = lua_pcall(L, 7, 0, 0); + result = lua_pcall(L, 4, 4, 0); if (result) { fprintf(stderr, "Failed to run function SerialICE_cpuid_log: %s\n", lua_tostring(L, -1)); exit(1); } + res->edx = lua_tointeger(L, -1); + res->ecx = lua_tointeger(L, -2); + res->ebx = lua_tointeger(L, -3); + res->eax = lua_tointeger(L, -4); + lua_pop(L, 4); } + +static const SerialICE_filter lua_ops = { + .io_read_pre = io_read_pre, + .io_read_post = io_read_post, + .io_write_pre = io_write_pre, + .io_write_post = io_write_post, + .load_pre = memory_read_pre, + .load_post = memory_read_post, + .store_pre = memory_write_pre, + .store_post = memory_write_post, + .rdmsr_pre = rdmsr_pre, + .rdmsr_post = rdmsr_post, + .wrmsr_pre = wrmsr_pre, + .wrmsr_post = wrmsr_post, + .cpuid_pre = cpuid_pre, + .cpuid_post = cpuid_post, +}; diff --git a/qemu-0.15.x/serialice.c b/qemu-0.15.x/serialice.c index 80c7cca..398f378 100644 --- a/qemu-0.15.x/serialice.c +++ b/qemu-0.15.x/serialice.c @@ -42,10 +42,13 @@ #include "serialice.h" #include "sysemu.h"
+#define SERIALICE_LUA_SCRIPT "serialice.lua" + #define DEFAULT_RAM_SIZE 128 #define BIOS_FILENAME "bios.bin"
const SerialICE_target *target; +const SerialICE_filter *filter;
int serialice_active = 0;
@@ -54,52 +57,56 @@ int serialice_active = 0;
uint64_t serialice_rdmsr(uint32_t addr, uint32_t key) { - uint32_t hi, lo; - uint64_t ret; - int filtered; + uint32_t hi = 0, lo = 0; + uint64_t data;
- filtered = serialice_rdmsr_filter(addr, &hi, &lo); - if (!filtered) { - target->rdmsr(addr, key, &hi, &lo); - } + int mux = filter->rdmsr_pre(addr);
- ret = hi; - ret <<= 32; - ret |= lo; + if (mux & READ_FROM_SERIALICE) + target->rdmsr(addr, key, &hi, &lo);
- serialice_rdmsr_log(addr, hi, lo, filtered); + if (mux & READ_FROM_QEMU) { + data = cpu_rdmsr(addr); + hi = (data >> 32); + lo = (data & 0xffffffff); + }
- return ret; + filter->rdmsr_post(&hi, &lo); + data = hi; + data <<= 32; + data |= lo; + return data; }
void serialice_wrmsr(uint64_t data, uint32_t addr, uint32_t key) { - uint32_t hi, lo; - int filtered; + uint32_t hi = (data >> 32); + uint32_t lo = (data & 0xffffffff);
- hi = (data >> 32); - lo = (data & 0xffffffff); + int mux = filter->wrmsr_pre(addr, &hi, &lo);
- filtered = serialice_wrmsr_filter(addr, &hi, &lo); - - if (!filtered) { + if (mux & WRITE_TO_SERIALICE) target->wrmsr(addr, key, hi, lo); + if (mux & WRITE_TO_QEMU) { + data = lo | ((uint64_t)hi)<<32; + cpu_wrmsr(addr, data); } - - serialice_wrmsr_log(addr, hi, lo, filtered); + filter->wrmsr_post(); }
cpuid_regs_t serialice_cpuid(uint32_t eax, uint32_t ecx) { cpuid_regs_t ret; - int filtered; + ret.eax = ret.ebx = ret.ecx = ret.edx = 0;
- target->cpuid(eax, ecx, &ret); + int mux = filter->cpuid_pre(eax, ecx);
- filtered = serialice_cpuid_filter(eax, ecx, &ret); - - serialice_cpuid_log(eax, ecx, ret, filtered); + if (mux & READ_FROM_SERIALICE) + target->cpuid(eax, ecx, &ret); + if (mux & READ_FROM_QEMU) + ret = cpu_cpuid(eax, ecx);
+ filter->cpuid_post(&ret); return ret; }
@@ -113,7 +120,7 @@ cpuid_regs_t serialice_cpuid(uint32_t eax, uint32_t ecx) void serialice_log_load(int caught, uint32_t addr, uint32_t result, unsigned int data_size) { - serialice_memory_read_log(caught, result, addr, data_size); + filter->load_post(&result); }
/* This function can grab Qemu load ops and forward them to the SerialICE @@ -121,58 +128,34 @@ void serialice_log_load(int caught, uint32_t addr, uint32_t result, * * @return 0: pass on to Qemu; 1: handled locally. */ -int serialice_handle_load(uint32_t addr, uint32_t * result, - unsigned int data_size) +int serialice_handle_load(uint32_t addr, uint32_t * data, unsigned int size) { - int source; - - source = serialice_memory_read_filter(addr, result, data_size); + int mux = filter->load_pre(addr, size);
- if (source & READ_FROM_SERIALICE) { - *result = target->load(addr, data_size); - return 1; - } - - if (source & READ_FROM_QEMU) { - return 0; - } + if (mux & READ_FROM_SERIALICE) + *data = target->load(addr, size);
- /* No source for load, so the source is the script */ - return 1; + return !(mux & READ_FROM_QEMU); }
// ************************************************************************** // memory store handling
-static void serialice_log_store(int caught, uint32_t addr, uint32_t val, - unsigned int data_size) -{ - serialice_memory_write_log(caught, val, addr, data_size); -} - /* This function can grab Qemu store ops and forward them to the SerialICE * target * * @return 0: Qemu exclusive or shared; 1: SerialICE exclusive. */
-int serialice_handle_store(uint32_t addr, uint32_t val, unsigned int data_size) +int serialice_handle_store(uint32_t addr, uint32_t data, unsigned int size) { - int write_to_target, write_to_qemu, ret; - uint32_t filtered_data = val; - - ret = serialice_memory_write_filter(addr, data_size, &filtered_data); + int mux = filter->store_pre(addr, size, &data);
- write_to_target = ((ret & WRITE_TO_SERIALICE) != 0); - write_to_qemu = ((ret & WRITE_TO_QEMU) != 0); - - serialice_log_store(write_to_target, addr, filtered_data, data_size); - - if (write_to_target) { - target->store(addr, data_size, filtered_data); - } + if (mux & WRITE_TO_SERIALICE) + target->store(addr, size, data);
- return (write_to_qemu == 0); + filter->store_post(); + return !(mux & WRITE_TO_QEMU); }
#define mask_data(val,bytes) (val & (((uint64_t)1<<(bytes*8))-1)) @@ -180,33 +163,30 @@ int serialice_handle_store(uint32_t addr, uint32_t val, unsigned int data_size) uint32_t serialice_io_read(uint16_t port, unsigned int size) { uint32_t data = 0; - int filtered; + int mux = filter->io_read_pre(port, size);
- filtered = serialice_io_read_filter(&data, port, size); - if (!filtered) { + if (mux & READ_FROM_QEMU) + data = cpu_io_read_wrapper(port, size); + if (mux & READ_FROM_SERIALICE) data = target->io_read(port, size); - }
data = mask_data(data, size); - serialice_io_read_log(0, data, port, size); + filter->io_read_post(&data); return data; }
void serialice_io_write(uint16_t port, unsigned int size, uint32 data) { - uint32_t filtered_data = mask_data(data, size); - int filtered; - - filtered = serialice_io_write_filter(&filtered_data, port, size); + data = mask_data(data, size); + int mux = filter->io_write_pre(&data, port, size); + data = mask_data(data, size);
- if (filtered) { - data = mask_data(filtered_data, size); - } else { - data = mask_data(filtered_data, size); + if (mux & WRITE_TO_QEMU) + cpu_io_write_wrapper(port, size, data); + if (mux & WRITE_TO_SERIALICE) target->io_write(port, size, data); - }
- serialice_io_write_log(0, data, port, size); + filter->io_write_post(); }
// ************************************************************************** @@ -222,7 +202,7 @@ static void serialice_init(void) target->mainboard();
printf("SerialICE: LUA init...\n"); - serialice_lua_init(); + filter = serialice_lua_init(SERIALICE_LUA_SCRIPT);
/* Let the rest of Qemu know we're alive */ serialice_active = 1; diff --git a/qemu-0.15.x/serialice.h b/qemu-0.15.x/serialice.h index 3a12b53..23e3af6 100644 --- a/qemu-0.15.x/serialice.h +++ b/qemu-0.15.x/serialice.h @@ -41,9 +41,6 @@ extern const char *serialice_device; extern int serialice_active;
-int serialice_lua_init(void); -const char *serialice_lua_execute(const char *cmd); - uint32_t serialice_io_read(uint16_t port, unsigned int size); void serialice_io_write(uint16_t port, unsigned int size, uint32_t data);
@@ -79,20 +76,28 @@ const SerialICE_target *serialice_serial_init(void); void serialice_serial_exit(void);
/* serialice LUA */ -int serialice_io_read_filter(uint32_t * data, uint16_t port, int size); -int serialice_io_write_filter(uint32_t * data, uint16_t port, int size); -int serialice_memory_read_filter(uint32_t addr, uint32_t * data, int size); -int serialice_memory_write_filter(uint32_t addr, int size, uint32_t * data); -int serialice_cpuid_filter(uint32_t eax, uint32_t ecx, cpuid_regs_t * regs); -int serialice_rdmsr_filter(uint32_t addr, uint32_t * hi, uint32_t * lo); -int serialice_wrmsr_filter(uint32_t addr, uint32_t * hi, uint32_t * lo); - -void serialice_io_read_log(int caught, uint32_t data, uint32_t addr, int size); -void serialice_io_write_log(int caught, uint32_t data, uint32_t addr, int size); -void serialice_memory_read_log(int caught, uint32_t data, uint32_t addr, int size); -void serialice_memory_write_log(int caught, uint32_t data, uint32_t addr, int size); -void serialice_rdmsr_log(uint32_t addr, uint32_t hi, uint32_t lo, int filtered); -void serialice_wrmsr_log(uint32_t addr, uint32_t hi, uint32_t lo, int filtered); -void serialice_cpuid_log(uint32_t eax, uint32_t ecx, cpuid_regs_t res, int filtered); +typedef struct { + int (*io_read_pre) (uint16_t port, int size); + void (*io_read_post) (uint32_t * data); + int (*io_write_pre) (uint32_t * data, uint16_t port, int size); + void (*io_write_post) (void); + + int (*load_pre) (uint32_t addr, int size); + void (*load_post) (uint32_t * data); + int (*store_pre) (uint32_t addr, int size, uint32_t * data); + void (*store_post) (void); + + int (*rdmsr_pre) (uint32_t addr); + void (*rdmsr_post) (uint32_t * hi, uint32_t * lo); + int (*wrmsr_pre) (uint32_t addr, uint32_t * hi, uint32_t * lo); + void (*wrmsr_post) (void); + + int (*cpuid_pre) (uint32_t eax, uint32_t ecx); + void (*cpuid_post) (cpuid_regs_t * res); +} SerialICE_filter; + +const SerialICE_filter *serialice_lua_init(const char *serialice_lua_script); +void serialice_lua_exit(void); +const char *serialice_lua_execute(const char *cmd);
#endif