[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