[SerialICE] New patch to review for serialice: dfdca16 Add legacy PC80 devices in IO space
Kyösti Mälkki (kyosti.malkki@gmail.com)
gerrit at coreboot.org
Sun Oct 28 21:09:07 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/1646
-gerrit
commit dfdca1655cd73597ed71cbb21b9b04e33798934f
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date: Sun Oct 28 11:13:35 2012 +0200
Add legacy PC80 devices in IO space
These devices appear at fixed IO addresses and are mostly implemented
in the southbridge chip.
Change-Id: I4a20058e0cbc31f1b5777fe99966c0499909a553
Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
SerialICE/simba/pc80.lua | 546 ++++++++++++++++++++++++++++++++++++++++++
SerialICE/simba/serialice.lua | 11 +
2 files changed, 557 insertions(+)
diff --git a/SerialICE/simba/pc80.lua b/SerialICE/simba/pc80.lua
new file mode 100644
index 0000000..7ce439c
--- /dev/null
+++ b/SerialICE/simba/pc80.lua
@@ -0,0 +1,546 @@
+-- **********************************************************
+--
+-- Debug POST port at IO 0x80
+
+function debugport_post(f, action)
+ if action.write then
+ printk(f, action, "*** %02x ***\n", action.data)
+ return true
+ end
+ return false
+end
+
+filter_debugport = {
+ id = -1,
+ name = "POST",
+ pre = handle_action,
+ post = debugport_post,
+ hide = true,
+ base = 0x80,
+ size = 0x1
+}
+
+
+-- **********************************************************
+--
+-- i8259 PIC
+
+function i8259_pre(f, action)
+ local master = (bit32.rshift(0x05, action.addr) == 0x1)
+ local slave = (bit32.rshift(0x05, action.addr) == 0x5)
+ local reg = bit32.band(0x03, action.addr)
+ if reg == 0 or reg == 1 then
+ return handle_action(f, action)
+ end
+ return skip_filter(f, action)
+end
+
+function i8259_post(f,action)
+ local reg = bit32.band(0x03, action.addr)
+ if reg == 0 or reg == 1 then
+ return true
+ end
+ return false
+end
+
+function i8259_edge_pre(f, action)
+ return handle_action(f, action)
+end
+
+function i8259_edge_post(f,action)
+ return true
+end
+
+filter_i8259_master = {
+ id = -1,
+ name = "i8259 A",
+ pre = i8259_pre,
+ post = i8259_post,
+ hide = hide_i8259_io,
+ base = 0x20,
+ size = 0x20
+}
+
+filter_i8259_slave = {
+ id = -1,
+ name = "i8259 B",
+ pre = i8259_pre,
+ post = i8259_post,
+ hide = hide_i8259_io,
+ base = 0xa0,
+ size = 0x20
+}
+
+filter_i8259_edge = {
+ id = -1,
+ name = "i8259 C",
+ pre = i8259_edge_pre,
+ post = i8259_edge_post,
+ hide = hide_i8259_io,
+ base = 0x4d0,
+ size = 0x2
+}
+
+-- **********************************************************
+--
+-- i8237 DMA
+
+function i8237_pre(f, action)
+ if action.addr == 0x80 then
+ return skip_filter(f, action)
+ end
+ return handle_action(f, action)
+end
+
+function i8237_post(f, action)
+ if action.addr == 0x80 then
+ return false
+ end
+ return true
+end
+
+
+filter_i8237_a = {
+ id = -1,
+ name = "i8237 A",
+ pre = i8237_pre,
+ post = i8237_post,
+ hide = hide_i8237_io,
+ base = 0x00,
+ size = 0x20
+}
+filter_i8237_b = {
+ id = -1,
+ name = "i8237 B",
+ pre = i8237_pre,
+ post = i8237_post,
+ hide = hide_i8237_io,
+ base = 0x80,
+ size = 0x20
+}
+filter_i8237_c = {
+ id = -1,
+ name = "i8237 C",
+ pre = i8237_pre,
+ post = i8237_post,
+ hide = hide_i8237_io,
+ base = 0xc0,
+ size = 0x20
+}
+
+
+-- **********************************************************
+--
+-- i8254 IRQ0 and Speaker
+
+function i8254_pre(f, action)
+
+ -- nothing to do on reads
+ if not action.write then
+ return handle_action(f, action)
+ end
+
+ local reg = bit32.band(0x03, action.addr)
+ if reg >= 0x0 and reg < 0x03 then
+ local counter_n = 0
+ local counter_p = 0
+ if f.counter[reg].lsb then
+ f.counter[reg].lsb = f.counter[reg].after_lsb
+ counter_n = action.data
+ counter_p = bit32.band(0xff00, f.counter[reg].init)
+ else
+ counter_n = bit32.lshift(action.data, 8)
+ counter_p = bit32.band(0x00ff, f.counter[reg].init)
+ end
+ f.counter[reg].init = bit32.bor(counter_n, counter_p)
+ elseif reg == 0x03 then
+ local reg2 = bit32.rshift(action.data, 6)
+ local rwsel = bit32.band(0x3, bit32.rshift(action.data, 4))
+ if reg2 == 0x3 then
+ if bit32.band(0x10, action.data) == 0 then
+ f.counter[0].readback = (bit32.band(0x2, action.data) ~= 0)
+ f.counter[1].readback = (bit32.band(0x4, action.data) ~= 0)
+ f.counter[2].readback = (bit32.band(0x8, action.data) ~= 0)
+ end
+ if bit32.band(0x20, action.data) == 0 then
+ f.counter[0].latch = (bit32.band(0x2, action.data) ~= 0)
+ f.counter[1].latch = (bit32.band(0x4, action.data) ~= 0)
+ f.counter[2].latch = (bit32.band(0x8, action.data) ~= 0)
+ end
+ elseif rwsel == 0x0 then
+ f.counter[reg2].latch = true
+ else
+ f.counter[reg2].mode = bit32.band(0xf, action.data)
+ if rwsel == 0x1 then
+ f.counter[reg2].lsb = true
+ f.counter[reg2].after_lsb = true
+ elseif rwsel == 0x2 then
+ f.counter[reg2].lsb = false
+ f.counter[reg2].after_lsb = false
+ elseif rwsel == 03 then
+ f.counter[reg2].lsb = true
+ f.counter[reg2].after_lsb = false
+ end
+ end
+ end
+ return handle_action(f, action)
+end
+
+function i8254_post(f, action)
+ local reg = bit32.band(0x03, action.addr)
+ if reg >= 0x0 and reg < 0x03 then
+ if action.write then
+ local mode = bit32.band(0x0f, f.counter[reg].mode);
+ local modestr = "Mode" .. mode
+ if mode == 0x4 then
+ modestr = "Square Wave"
+ elseif mode == 0x6 then
+ modestr = "Rate Generator"
+ end
+ if bit32.band(0x01, mode) ~= 0 then
+ modestr = modestr .. " (BCD)"
+ end
+
+ local period = 838 * f.counter[reg].init
+ if reg == 0 then
+ if period == 0 then
+ printk(f, action, "IRQ0 disabled\n")
+ else
+ printk(f, action, "IRQ0 (%s): %d ns\n", modestr, period)
+ end
+ elseif reg == 1 then
+ if period == 0 then
+ printk(f, action, "Refresh disabled\n")
+ else
+ printk(f, action, "Refresh (%s): %d ns\n", modestr, period)
+ end
+ elseif reg == 2 then
+ if period ~= 0 then
+ local spktone = 1193000 / f.counter[reg].init
+ printk(f, action, "Speaker Tone (%s): %d kHz\n", modestr, spktone)
+ end
+ end
+ else
+ if f.counter[reg].readback then
+ f.counter[reg].readback = false
+ f.counter[reg].status = action.data
+ printk(f, action, "[%d] status = %02x\n", reg, f.counter[reg].status)
+ end
+ if f.counter[reg].latch then
+ f.counter[reg].latch = false
+ f.counter[reg].current = action.data
+ printk(f, action, "[%d] current = %d\n", reg, f.counter[reg].current)
+ end
+ end
+ elseif reg == 0x03 then
+ end
+ return true
+end
+
+i8254_counters = {}
+i8254_counters[0x0] = { init=0, current=0, latch, readback, status=0 }
+i8254_counters[0x1] = { init=0, current=0, latch, readback, status=0 }
+i8254_counters[0x2] = { init=0, current=0, latch, readback, status=0 }
+
+filter_i8254_a = {
+ id = -1,
+ name = "i8254 A",
+ pre = i8254_pre,
+ post = i8254_post,
+ base = 0x40,
+ hide = hide_i8254_io,
+ size = 4,
+ counter = i8254_counters,
+}
+filter_i8254_b = {
+ id = -1,
+ name = "i8254 B",
+ pre = i8254_pre,
+ post = i8254_post,
+ base = 0x50,
+ hide = hide_i8254_io,
+ size = 4,
+ counter = i8254_counters,
+}
+
+
+-- **********************************************************
+--
+-- i8042 KBD, A20, Reset(?)
+
+function i8042_write(f, action)
+ if action.addr == 0x60 then
+ f.reg.data = action.data
+ f.reg.sts = bit32.band(f.reg.sts, 0xf7)
+ if (f.reg.cmd == 0xd1) then
+ f.reg.A20 = (bit32.band(0x02, action.data) == 0x02)
+ end
+ return handle_action(f, action)
+ end
+ if action.addr == 0x64 then
+ f.reg.cmd = action.data
+ f.reg.sts = bit32.bor(f.reg.sts, 0x0a)
+ return handle_action(f, action)
+ end
+ return skip_filter(f, action)
+end
+
+function i8042_read(f, action)
+ if action.addr == 0x60 then
+ f.reg.sts = bit32.band(f.reg.sts, 0xfe)
+ return handle_action(f, action)
+ end
+ if action.addr == 0x64 then
+ return handle_action(f, action)
+ end
+ return skip_filter(f, action)
+end
+
+function i8042_pre(f, action)
+ if (action.write) then
+ return i8042_write(f, action)
+ else
+ return i8042_read(f, action)
+ end
+end
+
+function i8042_post(f, action)
+ if action.addr == 0x60 then
+ if action.write and f.reg.cmd == 0xd1 then
+ if f.reg.A20 then
+ printk(f, action, "A20 enabled\n")
+ else
+ printk(f, action, "A20 disabled\n")
+ end
+ end
+ return true
+ end
+ if action.addr == 0x64 then
+ return true
+ end
+ return false
+end
+
+filter_i8042 = {
+ id = -1,
+ name = "i8042",
+ pre = i8042_pre,
+ post = i8042_post,
+ hide = hide_i8042_io,
+ base = 0x60,
+ size = 0x5,
+ reg = { data = 0, sts = 0, cmd = 0, A20 = 0 }
+}
+
+
+-- **********************************************************
+--
+-- CMOS nvram
+
+
+function nvram_bank(addr)
+ if bit32.band(0xfe, addr) == 0x70 then
+ return 1
+ elseif bit32.band(0xfe, addr) == 0x72 then
+ return 2
+ elseif bit32.band(0xfe, addr) == 0x74 then
+ return 2
+ else
+ return 0
+ end
+end
+
+function nvram_write(f, action)
+ local val = action.data
+ local rtc = false
+ local is_index = (bit32.band(0x01, action.addr) == 0x0)
+ local bank = nvram_bank(action.addr)
+
+ if bank == 1 then
+ if is_index then
+ f.reg.p70 = bit32.band(0x7f, val)
+ if f.reg.p70 < 0x0E then
+ rtc = true
+ end
+ else
+ f.nvram_data[f.reg.p70] = val
+ f.nvram_set[f.reg.p70] = true
+ if f.reg.p70 < 0x0E then
+ rtc = true
+ end
+ end
+ elseif bank == 2 then
+ if is_index then
+ f.reg.p72 = bit32.band(0x7f, val)
+ else
+ local index = 0x80 + f.reg.p72
+ f.nvram_data[index] = val
+ f.nvram_set[index] = true
+ end
+ end
+ if cache_nvram and not rtc then
+ return fake_action(f, action, val)
+ else
+ return handle_action(f, action)
+ end
+end
+
+function nvram_read(f, action)
+ local val = 0
+ local rtc = false
+ local is_index = (bit32.band(0x01, action.addr) == 0x0)
+ local bank = nvram_bank(action.addr)
+
+ if bank == 1 then
+ if is_index then
+ -- NMI returned as 0
+ val = f.reg.p70
+ if f.reg.p70 < 0x0E then
+ rtc = true
+ end
+ else
+ if f.reg.p70 < 0x0E then
+ rtc = true
+ elseif f.nvram_set[f.reg.p70] then
+ val = f.nvram_data[f.reg.p70]
+ end
+ end
+ else -- bank
+ if is_index then
+ -- NMI returned as 0
+ val = f.reg.p72
+ else
+ local index = 0x80 + f.reg.p72
+ if f.nvram_set[index] then
+ val = f.nvram_data[index]
+ end
+ end
+ end
+ if cache_nvram and not rtc then
+ return fake_action(f, action, val)
+ else
+ return handle_action(f, action)
+ end
+end
+
+function nvram_pre(f, action)
+ if (action.write) then
+ return nvram_write(f, action)
+ else
+ return nvram_read(f, action)
+ end
+end
+
+function nvram_post(f, action)
+ if bit32.band(0x01, action.addr) == 0x0 then
+ return true
+ end
+
+ local bank = nvram_bank(action.addr)
+ if (action.write) then
+ if bank == 1 then
+ printk(f, action, "[%02x] <= %02x\n", f.reg.p70, action.data)
+ elseif bank == 2 then
+ printk(f, action, "[%02x] <= %02x\n", 0x80 + f.reg.p72, action.data)
+ end
+ else
+ if bank == 1 then
+ printk(f, action, "[%02x] => %02x\n", f.reg.p70, action.data)
+ elseif bank == 2 then
+ printk(f, action, "[%02x] => %02x\n", 0x80 + f.reg.p72, action.data)
+ end
+ end
+ return true
+end
+
+filter_nvram = {
+ id = -1,
+ name = "NVram",
+ pre = nvram_pre,
+ post = nvram_post,
+ base = 0x70,
+ size = 8,
+ hide = hide_nvram_io,
+ reg = { p70 = 0, p72 = 0 },
+ nvram_data = {},
+ nvram_set = {},
+}
+
+
+-- **********************************************************
+--
+-- Reset at 0xcf9
+
+function sys_rst_pre(f, action)
+ if action.size == 1 then
+ if action.write and bit32.band(action.data, 0x04) == 0x04 then
+ SerialICE_system_reset()
+ end
+ return handle_action(f, action)
+ end
+ return skip_filter(f, action)
+end
+
+function sys_rst_post(f, action)
+ if action.size == 1 then
+ if action.write then
+ printk(f, action, "Control = %02x\n", action.data)
+ return true
+ end
+ end
+ return false
+end
+
+filter_reset = {
+ id = -1,
+ name = "Reset",
+ pre = sys_rst_pre,
+ post = sys_rst_post,
+ hide = false,
+ base = 0xcf9,
+ size = 1
+}
+
+-- **********************************************************
+--
+-- VGA io
+
+function vga_io_pre(f, action)
+ return skip_filter(f, action)
+end
+
+function vga_io_post(f, action)
+ return true
+end
+
+filter_vga_io = {
+ id = -1,
+ name = "VGA",
+ pre = vga_io_pre,
+ post = vga_io_post,
+ hide = false,
+ base = 0x3c0,
+ size = 0x20,
+}
+
+
+-- **********************************************************
+--
+-- Enable all PC80 stuff
+
+function enable_hook_pc80()
+ enable_hook(io_hooks, filter_i8237_a)
+ enable_hook(io_hooks, filter_i8237_b)
+ enable_hook(io_hooks, filter_i8237_c)
+ enable_hook(io_hooks, filter_i8259_master)
+ enable_hook(io_hooks, filter_i8259_slave)
+ enable_hook(io_hooks, filter_i8259_edge)
+ enable_hook(io_hooks, filter_i8042)
+ enable_hook(io_hooks, filter_i8254_a)
+ enable_hook(io_hooks, filter_i8254_b)
+ enable_hook(io_hooks, filter_reset)
+ enable_hook(io_hooks, filter_nvram)
+ enable_hook(io_hooks, filter_vga_io)
+ enable_hook(io_hooks, filter_debugport)
+end
+
diff --git a/SerialICE/simba/serialice.lua b/SerialICE/simba/serialice.lua
index 5529068..4b63e25 100644
--- a/SerialICE/simba/serialice.lua
+++ b/SerialICE/simba/serialice.lua
@@ -29,11 +29,20 @@ io.write("SerialICE: Starting LUA script\n")
hide_rom_access = true
hide_pci_io_cfg = true
hide_pci_mm_cfg = true
+hide_nvram_io = true
+hide_i8042_io = false
+hide_i8237_io = true
+hide_i8254_io = true
+hide_i8259_io = true
-- Set to "true" to log every memory and IO access
log_everything = false
+-- Use lua table for NVram
+-- RTC registers 0x0-0xd go to HW
+cache_nvram = false
+
rom_size = 4 * 1024 * 1024
rom_base = 0x100000000 - rom_size
@@ -49,6 +58,7 @@ dofile("core_io.lua")
dofile("memory.lua")
dofile("cpu.lua")
dofile("pci_cfg.lua")
+dofile("pc80.lua")
function do_minimal_setup()
enable_hook(io_hooks, filter_io_fallback)
@@ -62,6 +72,7 @@ end
function do_default_setup()
enable_ram()
enable_hook(io_hooks, filter_pci_io_cfg)
+ enable_hook_pc80()
end
do_minimal_setup()
More information about the SerialICE
mailing list