[SerialICE] New patch to review for serialice: 7fb6c48 Add simba, modular filtering

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Sun Oct 28 21:09:06 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/1642

-gerrit

commit 7fb6c48cfb4e9e5d2e948b936b3c499598e55061
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Sun Oct 28 10:41:54 2012 +0200

    Add simba, modular filtering
    
    This implement the core interface of IO and memory operations
    between Qemu and SerialICE LUA filter scripts.
    
    Change-Id: I116fa45597c321155c7e24bb20e497c3e93640b0
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 SerialICE/simba/core_io.lua   |  84 +++++++++++++
 SerialICE/simba/cpu.lua       |  77 ++++++++++++
 SerialICE/simba/hooks.lua     | 274 ++++++++++++++++++++++++++++++++++++++++++
 SerialICE/simba/interface.lua | 161 +++++++++++++++++++++++++
 SerialICE/simba/memory.lua    | 198 ++++++++++++++++++++++++++++++
 SerialICE/simba/output.lua    |  71 +++++++++++
 SerialICE/simba/serialice.lua |  69 +++++++++++
 7 files changed, 934 insertions(+)

diff --git a/SerialICE/simba/core_io.lua b/SerialICE/simba/core_io.lua
new file mode 100644
index 0000000..38a2df0
--- /dev/null
+++ b/SerialICE/simba/core_io.lua
@@ -0,0 +1,84 @@
+-- **********************************************************
+--
+
+function io_undefined(f, action)
+	action.to_hw = true
+	action.to_qemu = false
+	action.undefined = true
+	return true
+end
+
+function io_post(f, action)
+	if (action.write) then
+		printk(f, action, "out%s %04x <= %s\n", size_suffix(action.size), action.addr, size_data(action.size, action.data))
+	else
+		printk(f, action, " in%s %04x => %s\n", size_suffix(action.size), action.addr, size_data(action.size, action.data))
+	end
+	return true
+end
+
+function io_base_post(f, action)
+	if (action.write) then
+		printk(f, action, "[%04x] <= %s\n", bit32.band(action.addr, (f.size - 1)), size_data(action.size, action.data))
+	else
+		printk(f, action, "[%04x] => %s\n", bit32.band(action.addr, (f.size - 1)), size_data(action.size, action.data))
+	end
+	return true
+end
+
+filter_io_fallback = {
+	id = -1,
+	name = "IO",
+	pre = io_undefined,
+	post = io_post,
+	base = 0x0,
+	size = 0x10000,
+}
+
+-- **********************************************************
+--
+
+function mem_undefined(f, action)
+	if (action.write) then
+		action.to_hw = true
+		action.to_qemu = false
+	else
+		action.to_hw = false
+		action.to_qemu = true
+	end
+	action.undefined = true
+	return true
+end
+
+function mem_post(f, action)
+	if (action.write) then
+		printk(f, action, "write%s %08x <= %s", size_suffix(action.size), action.addr, size_data(action.size, action.data))
+	else
+		printk(f, action, " read%s %08x => %s", size_suffix(action.size), action.addr, size_data(action.size, action.data))
+	end
+	if action.to_hw then
+		printf(" *")
+	end
+	printf("\n")
+	return true
+end
+
+function mem_base_post(f, action)
+	if (action.write) then
+		printk(f, action, "[%08x] <= %s\n", bit32.band(action.addr, (f.size - 1)), size_data(action.size, action.data))
+	else
+		printk(f, action, "[%08x] => %s\n", bit32.band(action.addr, (f.size - 1)), size_data(action.size, action.data))
+	end
+	return true
+end
+
+
+filter_mem_fallback = {
+	id = -1,
+	name = "MEM",
+	pre = mem_undefined,
+	post = mem_post,
+	base = 0x0,
+	size = 0x100000000
+}
+
diff --git a/SerialICE/simba/cpu.lua b/SerialICE/simba/cpu.lua
new file mode 100644
index 0000000..00162ae
--- /dev/null
+++ b/SerialICE/simba/cpu.lua
@@ -0,0 +1,77 @@
+-- **********************************************************
+-- CPU MSR filters
+
+function var_mtrr_post(f, action)
+
+	local addr = action.rin.ecx
+	local hi = action.rin.edx
+	local lo = action.rin.eax
+
+	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
+		printk(f, action, "Set MTRR %x base to %08x.%08x (%s)\n", (addr - 0x200) / 2, hi, bit32.band(lo, 0xffffff00), memtype)
+	else
+		if bit32.band(lo, 0x800) == 0x800 then
+			valid = "valid"
+		else
+			valid = "disabled"
+		end
+		printk(f, action, "Set MTRR %x mask to %08x.%08x (%s)\n", (addr - 0x200) / 2, hi, bit32.band(lo, 0xfffff000), valid)
+	end
+end
+
+function cpumsr_pre(f, action)
+	return handle_action(f, action)
+end
+
+function cpumsr_post(f, action)
+	if action.write then
+		printk(f, action, "[%08x] <= %08x.%08x\n",
+			action.rin.ecx,	action.rin.edx, action.rin.eax)
+		if action.addr >= 0x200 and action.addr < 0x210 then
+			var_mtrr_post(f, action)
+		end
+	else
+		printk(f, action, "[%08x] => %08x.%08x\n",
+			action.rin.ecx,	action.rout.edx, action.rout.eax)
+	end
+	return true
+end
+
+
+filter_cpumsr_fallback = {
+	id = -1,
+	name = "CPU MSR",
+	pre = cpumsr_pre,
+	post = cpumsr_post,
+}
+
+
+-- **********************************************************
+-- CPUID filters
+
+function cpuid_pre(f, action)
+	return handle_action(f, action)
+end
+
+function cpuid_post(f, action)
+	printk(f, action, "eax: %08x; ecx: %08x => %08x.%08x.%08x.%08x\n",
+			action.rin.eax, action.rin.ecx,
+			action.rout.eax, action.rout.ebx, action.rout.ecx, action.rout.edx)
+	return true
+end
+
+filter_cpuid_fallback = {
+	id = -1,
+	name = "CPUID",
+	pre = cpuid_pre,
+	post = cpuid_post,
+}
+
diff --git a/SerialICE/simba/hooks.lua b/SerialICE/simba/hooks.lua
new file mode 100644
index 0000000..fa61ab4
--- /dev/null
+++ b/SerialICE/simba/hooks.lua
@@ -0,0 +1,274 @@
+
+
+function new_list()
+	return { list = nil }
+end
+
+next_filter_id = 1
+next_action_id = 1
+current_parent_id = 0
+
+function action_id()
+	local n = next_action_id
+	next_action_id = next_action_id + 1
+	return n
+end
+
+function new_parent_action()
+	current_parent_id = action_id()
+end
+
+
+io_hooks = new_list()
+mem_hooks = new_list()
+
+cpumsr_hooks = new_list()
+cpuid_hooks = new_list()
+
+
+function enable_hook(list, filter)
+	if not filter then
+		printks(froot, "Enable_hook called with filter==nil\n")
+		return
+	end
+
+	local l = list.list
+	local found = false
+	while l and not found do
+		found = (l.hook == filter)
+		l = l.next
+	end
+	if not found then
+		if (filter.id < 0) then
+			filter.id = next_filter_id
+			next_filter_id = next_filter_id + 1
+		end
+		list.list = { next = list.list, hook = filter }
+	end
+	if (list == io_hooks) then
+		printks(fresource, "[%04x] IO [%04x-%04x] = %s\n",
+				filter.id, filter.base, filter.base + filter.size - 1, filter.name)
+	elseif (list == mem_hooks) then
+		printks(fresource, "[%04x] MEM [%08x-%08x] = %s\n",
+				filter.id, filter.base, filter.base + filter.size - 1, filter.name)
+	else
+		printks(fresource, "[%04x] %s\n", filter.id, filter.name)
+	end
+	filter.enable = true
+end
+
+function disable_hook(list, filter)
+	if not filter then
+		return
+	end
+	local l = list.list
+	local found = false
+	while l and not found do
+		found = (l.hook == filter)
+		l = l.next
+	end
+	if found then
+		printks(froot, "id=%04x disabled\n", filter.id)
+		filter.enable = false
+	else
+		printks(filter, "disabled\n", filter.id)
+		filter.enable = false
+	end
+end
+
+prev_filter = nil
+
+function walk_pre_hooks(list, action)
+	if list == nil or list.list == nil then
+		return false
+	end
+	local logged = false
+	local l = list.list
+	local f = nil
+
+	local no_base_check = true
+	if list == io_hooks or list == mem_hooks then
+		no_base_check = false
+	end
+
+	while l and not logged do
+		f = l.hook
+		if no_base_check or action.addr >= f.base and action.addr < f.base + f.size then
+			if f.enable and f.pre then
+				logged = f.pre(f, action)
+			end
+		end
+		l = l.next
+	end
+
+	if prev_filter ~= f and not action.ignore then
+		prev_filter = f
+		new_parent_action()
+	end
+	if action.dropped then
+		action.to_hw = false
+		action.to_qemu = false
+	end
+end
+
+function walk_post_hooks(list, action)
+	if list == nil or list.list == nil then
+		return false
+	end
+	local logged = false
+	local l = list.list
+	local f = nil
+
+	local no_base_check = true
+	if list == io_hooks or list == mem_hooks then
+		no_base_check = false
+	end
+
+	while l and not logged do
+		f = l.hook
+		if no_base_check or action.addr >= f.base and action.addr < f.base + f.size then
+			if f.enable and f.post then
+				if no_base_check then
+					-- cpuid or cpumsr
+					logged = f.post(f, action)
+				else
+					-- io or mem
+					if f.post(f, action) then
+						action.f = f
+						logged = f.hide and not log_everything
+					end
+				end
+			end
+		end
+		l = l.next
+	end
+end
+
+function generic_io_bar(bar)
+	if not bar.f then
+		local f = {}
+		f.id = -1
+		f.pre = handle_action
+		f.post = io_base_post
+		f.hide = true
+		f.name = bar.name
+		f.size = bar.size
+		bar.f = f
+	end
+	bar.f.base = bit32.band(bar.val, bit32.bnot(bar.size-1))
+	if (bar.f.base ~= 0) then
+		enable_hook(io_hooks, bar.f)
+	else
+		disable_hook(io_hooks, bar.f)
+	end
+end
+
+function generic_mmio_bar(bar)
+	if not bar.f then
+		local f = {}
+		f.id = -1
+		f.pre = handle_action
+		f.post = mem_base_post
+		f.hide = true
+		f.name = bar.name
+		f.size = bar.size
+		bar.f = f
+	end
+	bar.f.base = bit32.band(bar.val, bit32.bnot(bar.size-1))
+	if bar.f.base ~= 0 then
+		enable_hook(mem_hooks, bar.f)
+	else
+		disable_hook(mem_hooks, bar.f)
+	end
+end
+
+PRE_HOOK = 1
+POST_HOOK = 2
+
+function handle_action(f, action)
+	action.to_hw = true
+	return true
+end
+
+function drop_action(f, action, data)
+	if action.stage == POST_HOOK then
+		printk(f, action, "ERROR: Cannot drop action in a post-hook.\n")
+		return true
+	end
+	action.dropped = true
+	action.data = data
+	return true
+end
+
+function ignore_action(f, action)
+	action.ignore = true
+end
+
+function fake_action(f, action, data)
+	if action.stage == POST_HOOK and action.write then
+		printk(f, action, "ERROR: Cannot fake write in a post-hook.\n")
+		return true
+	end
+	action.faked = true
+	action.data = data
+	return true
+end
+
+
+function skip_filter(f, action)
+	return false
+end
+
+function pre_action(action, dir_wr, addr, size, data)
+	action.stage = PRE_HOOK
+	-- CS:IP logging
+	action.cs = regs.cs
+	action.eip = regs.eip
+	action.parent_id = 0
+	action.my_id = 0
+
+	-- no filter, not filtered
+	action.f = nil
+	action.ignore = false
+	action.undefined = false
+	action.faked = false
+	action.dropped = false
+	action.to_hw = false
+	action.to_qemu = false
+
+	action.write = dir_wr
+	action.addr = addr
+
+	action.data = 0
+	action.size = size
+	if action.write then
+		if size == 1 then
+			action.data = bit32.band(0xff, data)
+		elseif size == 2 then
+			action.data = bit32.band(0xffff, data)
+		elseif size == 4 then
+			action.data = bit32.band(0xffffffff, data)
+		end
+	end
+end
+
+function post_action(action, data)
+	action.stage = POST_HOOK
+	action.parent_id = current_parent_id
+	action.my_id = action_id()
+
+	if not action.write then
+		if not action.faked and not action.dropped then
+			action.data = data
+		end
+	end
+end
+
+function load_regs(regs, eax, ebx, ecx, edx)
+	regs.eax = eax
+	regs.ebx = ebx
+	regs.ecx = ecx
+	regs.edx = edx
+end
+
+
diff --git a/SerialICE/simba/interface.lua b/SerialICE/simba/interface.lua
new file mode 100644
index 0000000..48ff8de
--- /dev/null
+++ b/SerialICE/simba/interface.lua
@@ -0,0 +1,161 @@
+
+-- IO, MMIO, RAM and ROM access
+io_action = {}
+mem_action = {}
+
+IO_READ = false
+IO_WRITE = true
+MEM_READ = false
+MEM_WRITE = true
+
+-- CPUID and CPU MSR
+MSR_READ = false
+MSR_WRITE = true
+CPUID = false
+
+cpu_action = {}
+cpu_action.rin = {}
+cpu_action.rout = {}
+
+
+
+-- SerialICE_io_read_filter is the filter function for IO reads.
+--
+-- Parameters:
+--   addr	IO port to be read
+--   size	Size of the IO 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
+
+function SerialICE_io_read_filter(addr, size)
+	pre_action(io_action, IO_READ, addr, size, 0)
+	walk_pre_hooks(io_hooks, io_action)
+	return io_action.to_hw, io_action.to_qemu
+end
+
+-- Parameters:
+--   data	Data from hw or Qemu
+-- Return values:
+--   result	Data to give back to Qemu
+
+function SerialICE_io_read_log(data)
+	post_action(io_action, data)
+	walk_post_hooks(io_hooks, io_action)
+	return io_action.data
+end
+
+-- SerialICE_io_write_filter is the filter function for IO writes.
+--
+-- Parameters:
+--   addr	IO port to be written to
+--   size	Size of the IO write
+--   data	Data to be written to
+-- 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
+--   data	Data to be written (possible changed in filter)
+
+function SerialICE_io_write_filter(addr, size, data)
+	pre_action(io_action, IO_WRITE, addr, size, data)
+	walk_pre_hooks(io_hooks, io_action)
+	return io_action.to_hw, io_action.to_qemu, io_action.data
+end
+
+function SerialICE_io_write_log()
+	post_action(io_action)
+	walk_post_hooks(io_hooks, io_action)
+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
+
+function SerialICE_memory_read_filter(addr, size)
+	pre_action(mem_action, MEM_READ, addr, size, 0)
+	walk_pre_hooks(mem_hooks, mem_action)
+	return mem_action.to_hw, mem_action.to_qemu
+end
+
+function SerialICE_memory_read_log(data)
+	post_action(mem_action, data)
+	walk_post_hooks(mem_hooks, mem_action)
+	return mem_action.data
+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)
+	pre_action(mem_action, MEM_WRITE, addr, size, data)
+	walk_pre_hooks(mem_hooks, mem_action)
+	return mem_action.to_hw, mem_action.to_qemu, mem_action.data
+end
+
+function SerialICE_memory_write_log()
+	post_action(mem_action, 0)
+	walk_post_hooks(mem_hooks, mem_action)
+end
+
+function SerialICE_msr_read_filter(addr)
+	pre_action(cpu_action, MSR_READ, 0, 0, 0)
+	load_regs(cpu_action.rin, 0, 0, addr, 0)
+
+	walk_pre_hooks(cpumsr_hooks, cpu_action)
+	return cpu_action.to_hw, cpu_action.to_qemu
+end
+
+function SerialICE_msr_read_log(hi, lo)
+	local rout = cpu_action.rout
+	post_action(cpu_action, 0)
+	load_regs(cpu_action.rout, lo, 0, 0, hi)
+	walk_post_hooks(cpumsr_hooks, cpu_action)
+	return rout.edx, rout.eax
+end
+
+function SerialICE_msr_write_filter(addr, hi, lo)
+	local rin = cpu_action.rin
+	pre_action(cpu_action, MSR_WRITE, 0, 0, 0)
+	load_regs(cpu_action.rin, lo, 0, addr, hi)
+	walk_pre_hooks(cpumsr_hooks, cpu_action)
+	return cpu_action.to_hw, cpu_action.to_qemu, rin.edx, rin.eax
+end
+
+function SerialICE_msr_write_log()
+	post_action(cpu_action, 0)
+	load_regs(cpu_action.rout, 0, 0, 0, 0)
+	walk_post_hooks(cpumsr_hooks, cpu_action)
+end
+
+function SerialICE_cpuid_filter(eax, ecx)
+	pre_action(cpu_action, CPUID, 0, 0, 0)
+	load_regs(cpu_action.rin, eax, 0, ecx, 0)
+	walk_pre_hooks(cpuid_hooks, cpu_action)
+	return cpu_action.to_hw, cpu_action.to_qemu
+end
+
+function SerialICE_cpuid_log(eax, ebx, ecx, edx)
+	local rout = cpu_action.rout
+	post_action(cpu_action, 0)
+	load_regs(cpu_action.rout, eax, ebx, ecx, edx)
+	walk_post_hooks(cpuid_hooks, cpu_action)
+	return rout.eax, rout.ebx, rout.ecx, rout.edx
+end
+
diff --git a/SerialICE/simba/memory.lua b/SerialICE/simba/memory.lua
new file mode 100644
index 0000000..11bc6ed
--- /dev/null
+++ b/SerialICE/simba/memory.lua
@@ -0,0 +1,198 @@
+
+-- **********************************************************
+-- ROM access
+
+function mem_qemu_rom_pre(f, action)
+	action.to_hw = false
+	action.to_qemu = true
+	-- Reads from ROM space do not count for filter change.
+	if not action.write then
+		ignore_action(f, action)
+	end
+	return true
+end
+
+function mem_rom_post(f, action)
+	if not action.write then
+		return true
+	end
+	-- Writes to ROM space fall-thru to the fallback filter,
+	-- so they get logged there.
+	return false
+end
+
+filter_rom_low = {
+	id = -1,
+	name = "ROM_LO",
+	pre = mem_qemu_rom_pre,
+	post = mem_rom_post,
+	hide = hide_rom_access,
+	base = 0xE0000,
+	size = 0x20000
+}
+filter_rom_high = {
+	id = -1,
+	name = "ROM_HI",
+	pre = mem_qemu_rom_pre,
+	post = mem_rom_post,
+	hide = hide_rom_access,
+	base = rom_base,
+	size = rom_size,
+}
+
+-- **********************************************************
+-- CAR access
+
+function car_qemu_only(f, action)
+	action.to_hw = false
+	action.to_qemu = true
+	return true
+end
+
+function car_post(f, action)
+	return true
+end
+
+function new_car_region(start, size)
+	f = {}
+	f.id = -1
+	f.name = "CAR"
+	f.base = start
+	f.size = size
+	f.pre = car_qemu_only
+	f.post = car_post
+	f.hide = true
+	enable_hook(mem_hooks, f)
+	SerialICE_register_physical(start, size)
+end
+
+
+-- **********************************************************
+-- RAM access.
+
+-- 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)
+
+-- 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).
+
+ram_is_initialized = false
+
+-- This is handled by SerialICE but *NOT* exclusively.
+-- Writes end up in Qemu memory, too
+function mem_ram_low(f, action)
+	if ram_is_initialized then
+		-- RAM init is done. Send all RAM accesses
+		-- to Qemu. Using the target as storage would
+		-- only slow execution down.
+		action.to_hw = false
+		action.to_qemu = true
+	else
+		-- RAM init has not been marked done yet.
+		-- so send reads to the target only.
+		action.to_hw = true
+		action.to_qemu = action.write
+	end
+	return true
+end
+
+-- SMI/VGA writes go to target and qemu
+-- SMI/VGA reads come from target
+function mem_smi_vga(f, action)
+	if action.write then
+		action.to_hw = true
+		action.to_qemu = true
+	else
+		action.to_hw = true
+		action.to_qemu = false
+	end
+	return true
+end
+
+
+function mem_post_pre_ram_only(f, action)
+	return ram_is_initialized
+end
+
+filter_ram_low = {
+	id = -1,
+	name = "MEM",
+	pre = mem_ram_low,
+	post = mem_post_pre_ram_only,
+	hide = true,
+	base = 0x0,
+	size = 0xa0000
+}
+
+filter_smi_vga = {
+	id = -1,
+	name = "SMI_VGA",
+	pre = mem_smi_vga,
+	post = mem_post,
+	hide = true,
+	base = 0x000a0000,
+	size = 0x00010000,
+}
+
+filter_ram_low_2 = {
+	id = -1,
+	name = "MEM",
+	pre = mem_ram_low,
+	post = mem_post_pre_ram_only,
+	hide = true,
+	base = 0xc0000,
+	size = 0x20000
+}
+
+
+function mem_target_only(f, action)
+	action.to_hw = true
+	action.to_qemu = false
+	return true
+end
+
+-- 3.25GB RAM. This is handled by SerialICE.
+-- FIXME: use TOLM here
+
+-- We refrain from backing up this memory in Qemu because Qemu would
+-- need lots of ram on the host and firmware usually does not intensively
+-- use high memory anyways.
+filter_ram_high = {
+	id = -1,
+	name = "MEM",
+	pre = mem_target_only,
+	post = mem_post_pre_ram_only,
+	hide = true,
+	base = 0x100000,
+	size = 0xd0000000 - 0x100000
+}
+
+
+function ram_enabled()
+	return ram_is_initialized
+end
+
+function enable_ram()
+
+	enable_hook(mem_hooks, filter_ram_low)
+	enable_hook(mem_hooks, filter_smi_vga)
+	enable_hook(mem_hooks, filter_ram_low_2)
+	enable_hook(mem_hooks, filter_ram_high)
+
+	-- Register low RAM 0x00000000 - 0x000dffff
+	SerialICE_register_physical(0x00000000, 0xa0000)
+	-- SMI/VGA memory should go to the target...
+	SerialICE_register_physical(0x000c0000, 0x20000)
+	--printf("Low RAM accesses are now directed to Qemu.\n")
+	ram_is_initialized = true
+end
+
+
+
+
diff --git a/SerialICE/simba/output.lua b/SerialICE/simba/output.lua
new file mode 100644
index 0000000..41210da
--- /dev/null
+++ b/SerialICE/simba/output.lua
@@ -0,0 +1,71 @@
+
+
+froot = {
+	id = 0,
+	name = "SerialICE",
+}
+
+fresource = {
+	id = -1,
+	name = "Resource",
+}
+
+-- -------------------------------------------------------------------
+-- logging functions
+
+function printf(s,...)
+	return io.write(s:format(...))
+end
+
+function printk(f, action, fmt, ...)
+	printf("[%04x:%04x] ", action.cs, action.eip)
+	printf("%04x.%04x ", action.parent_id, action.my_id)
+
+	local str = " "
+	if action.dropped or action.faked then
+		str = "!"
+	end
+	if action.undefined then
+		str = "#"
+	end
+
+	if action.f then
+		printf("%s %s,%s: ", str, f.name, action.f.name)
+		printf(fmt, ...)
+	else
+		printf("%s %s: ", str, f.name)
+		printf(fmt, ...)
+	end
+end
+
+function printks(f, fmt, ...)
+	printf("[%04x:%04x] ", 0, 0)
+	printf("%04x.%04x ", 0, 0)
+	printf("  %s: ", f.name)
+	printf(fmt, ...)
+end
+
+function trim (s)
+	return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
+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
+
+
+
diff --git a/SerialICE/simba/serialice.lua b/SerialICE/simba/serialice.lua
new file mode 100644
index 0000000..c179f8c
--- /dev/null
+++ b/SerialICE/simba/serialice.lua
@@ -0,0 +1,69 @@
+-- SerialICE
+--
+-- Copyright (c) 2009 coresystems GmbH
+-- Copyright (c) 2012 Kyösti Mälkki <kyosti.malkki at gmail.com>
+--
+-- 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")
+
+
+-- Set to "false" to show undecoded access for the specified class
+hide_rom_access = true
+
+-- Set to "true" to log every memory and IO access
+log_everything = false
+
+
+rom_size = 4 * 1024 * 1024
+rom_base = 0x100000000 - rom_size
+
+
+-- --------------------------------------------------------------------
+-- This initialization is executed right after target communication
+-- has been established
+
+dofile("interface.lua")
+dofile("output.lua")
+dofile("hooks.lua")
+dofile("core_io.lua")
+dofile("memory.lua")
+dofile("cpu.lua")
+
+function do_minimal_setup()
+	enable_hook(io_hooks, filter_io_fallback)
+	enable_hook(mem_hooks, filter_mem_fallback)
+	enable_hook(cpumsr_hooks, filter_cpumsr_fallback)
+	enable_hook(cpuid_hooks, filter_cpuid_fallback)
+	enable_hook(mem_hooks, filter_rom_low)
+	enable_hook(mem_hooks, filter_rom_high)
+end
+
+function do_default_setup()
+	enable_ram()
+end
+
+do_minimal_setup()
+do_default_setup()
+
+printks(froot, "LUA script initialized.\n")
+
+return true
+



More information about the SerialICE mailing list