Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1642
-gerrit
commit 7fb6c48cfb4e9e5d2e948b936b3c499598e55061 Author: Kyösti Mälkki kyosti.malkki@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@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@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 +