From 7bd295953d2f8e53e0eedb7aab41e1cc9324e913 Mon Sep 17 00:00:00 2001 From: Ivan De Cesaris Date: Fri, 18 Apr 2014 11:19:40 +0200 Subject: [PATCH] quark_x10xx: fix IO r/w operations with paging enabled Paging checking and disabling wasn't present for IO r/w, so the commands were successful only when paging wasn't enabled (e.g. EFI boot phase). Change-Id: I41366c0fadff3ea1eb8a153291f20a46cd9ddec1 Signed-off-by: Ivan De Cesaris Reviewed-on: http://openocd.zylin.com/2118 Tested-by: jenkins Reviewed-by: Peter Stuge Reviewed-by: Paul Fertser --- src/target/x86_32_common.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c index 34da39b9..0f75c97f 100644 --- a/src/target/x86_32_common.c +++ b/src/target/x86_32_common.c @@ -670,6 +670,7 @@ int x86_32_common_read_io(struct target *t, uint32_t addr, /* if CS.D bit=1 then its a 32 bit code segment, else 16 */ bool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D; int retval = ERROR_FAIL; + bool pg_disabled = false; LOG_DEBUG("addr=%08" PRIx32 ", size=%d, buf=%p", addr, size, buf); check_not_halted(t); if (!buf || !addr) { @@ -681,6 +682,13 @@ int x86_32_common_read_io(struct target *t, uint32_t addr, LOG_ERROR("%s error EDX write", __func__); return retval; } + /* to access physical memory, switch off the CR0.PG bit */ + if (x86_32->is_paging_enabled(t)) { + retval = x86_32->disable_paging(t); + if (retval != ERROR_OK) + return retval; + pg_disabled = true; + } switch (size) { case BYTE: if (use32) @@ -704,6 +712,13 @@ int x86_32_common_read_io(struct target *t, uint32_t addr, LOG_ERROR("%s invalid read io size", __func__); return ERROR_FAIL; } + /* restore CR0.PG bit if needed */ + if (pg_disabled) { + retval = x86_32->enable_paging(t); + if (retval != ERROR_OK) + return retval; + pg_disabled = false; + } uint32_t regval = 0; retval = x86_32->read_hw_reg(t, EAX, ®val, 0); if (retval != ERROR_OK) { @@ -729,6 +744,7 @@ int x86_32_common_write_io(struct target *t, uint32_t addr, LOG_DEBUG("addr=%08" PRIx32 ", size=%d, buf=%p", addr, size, buf); check_not_halted(t); int retval = ERROR_FAIL; + bool pg_disabled = false; if (!buf || !addr) { LOG_ERROR("%s invalid params buf=%p, addr=%08" PRIx32, __func__, buf, addr); return retval; @@ -747,6 +763,13 @@ int x86_32_common_write_io(struct target *t, uint32_t addr, LOG_ERROR("%s error on EAX write", __func__); return retval; } + /* to access physical memory, switch off the CR0.PG bit */ + if (x86_32->is_paging_enabled(t)) { + retval = x86_32->disable_paging(t); + if (retval != ERROR_OK) + return retval; + pg_disabled = true; + } switch (size) { case BYTE: if (use32) @@ -770,6 +793,13 @@ int x86_32_common_write_io(struct target *t, uint32_t addr, LOG_ERROR("%s invalid write io size", __func__); return ERROR_FAIL; } + /* restore CR0.PG bit if needed */ + if (pg_disabled) { + retval = x86_32->enable_paging(t); + if (retval != ERROR_OK) + return retval; + pg_disabled = false; + } retval = x86_32->transaction_status(t); if (retval != ERROR_OK) { LOG_ERROR("%s error on io write", __func__); -- 2.39.5