[SerialICE] New patch to review for serialice: b00c6de LUA interface change for Qemu

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Sun Oct 28 21:09:05 CET 2012


Kyösti Mälkki (kyosti.malkki at 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 at 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 at 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



More information about the SerialICE mailing list