From: Efimov Vasily <real@ispras.ru>
To: qemu-devel@nongnu.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Kirill Batuzov <batuzovk@ispras.ru>,
Efimov Vasily <real@ispras.ru>,
"Michael S. Tsirkin" <mst@redhat.com>
Subject: [Qemu-devel] [PATCH 0/3] PAM emulation improvement
Date: Thu, 16 Jul 2015 11:35:01 +0300 [thread overview]
Message-ID: <1437035704-11299-1-git-send-email-real@ispras.ru> (raw)
This patch series improves PAM emulation.
PAM defines 4 memory access redirection modes. In mode 1 reads are directed to
RAM and writes are directed to PCI. In mode 2 it is contrary. In mode 0 all
access is directed to PCI. In mode 3 it is directed to RAM. Modes 0 and 3 are
well emulated but modes 1 and 2 are not. The cause is: aliases are used
while more complicated logic is required.
The idea is to use ROM device like memory regions for mode 1 and 2 emulation
instead of aliases. Writes are directed to proper destination region by
specified I/O callback. Read redirection depends on type of source region.
In most cases source region is RAM (or ROM), so ram_addr of PAM region is set to
ram_addr of source region with offset. Otherwise, when source region is an I/O
region, reading is redirected to source region read callback by PAM region one.
Read source and write destination regions are updated by the memory
commit callback.
Note that we cannot use I/O region for PAM as it will violate "trying to execute
code outside RAM or ROM" assertion.
Qemu distribution includes SeaBIOS which has hacks to work around incorrect
modes 1 and 2 emulation.
This patch series is tested using modified SeaBIOS. It is forced to use mode 2
for copying its data. BIOS reads a value from memory and immediately writes it
to same address. According to PAM definition, reads are directed to PCI (i.e. to
BIOS ROM) and writes are directed to RAM.
The patch for SeaBIOS is listed below.
Both SeaBIOS versions works with new PAM but the modified one does not work with
old PAM.
======
diff --git a/src/fw/shadow.c b/src/fw/shadow.c
index 4f00006..5b0e527 100644
--- a/src/fw/shadow.c
+++ b/src/fw/shadow.c
@@ -26,32 +26,43 @@ static void
__make_bios_writable_intel(u16 bdf, u32 pam0)
{
// Make ram from 0xc0000-0xf0000 writable
- int clear = 0;
int i;
+ unsigned *mem, *mem_limit;
for (i=0; i<6; i++) {
u32 pam = pam0 + 1 + i;
int reg = pci_config_readb(bdf, pam);
- if (CONFIG_OPTIONROMS_DEPLOYED && (reg & 0x11) != 0x11) {
- // Need to copy optionroms to work around qemu implementation
- void *mem = (void*)(BUILD_ROM_START + i * 32*1024);
- memcpy((void*)BUILD_BIOS_TMP_ADDR, mem, 32*1024);
+ if ((reg & 0x11) != 0x11) {
+ mem = (unsigned *)(BUILD_ROM_START + i * 32 * 1024);
+ pci_config_writeb(bdf, pam, 0x22);
+ mem_limit = mem + 32 * 1024 / sizeof(unsigned);
+
+ while (mem < mem_limit) {
+ volatile unsigned tmp = *mem;
+ *mem = tmp;
+ mem++;
+ }
pci_config_writeb(bdf, pam, 0x33);
- memcpy(mem, (void*)BUILD_BIOS_TMP_ADDR, 32*1024);
- clear = 1;
} else {
pci_config_writeb(bdf, pam, 0x33);
}
}
- if (clear)
- memset((void*)BUILD_BIOS_TMP_ADDR, 0, 32*1024);
// Make ram from 0xf0000-0x100000 writable
int reg = pci_config_readb(bdf, pam0);
- pci_config_writeb(bdf, pam0, 0x30);
if (reg & 0x10)
// Ram already present.
return;
+ pci_config_writeb(bdf, pam0, 0x22);
+ mem = (unsigned *)BUILD_BIOS_ADDR;
+ mem_limit = mem + 32 * 1024 / sizeof(unsigned);
+ while (mem < mem_limit) {
+ volatile unsigned tmp = *mem;
+ *mem = tmp;
+ mem++;
+ }
+ pci_config_writeb(bdf, pam0, 0x33);
+
// Copy bios.
extern u8 code32flat_start[], code32flat_end[];
memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET
@@ -61,17 +72,6 @@ __make_bios_writable_intel(u16 bdf, u32 pam0)
static void
make_bios_writable_intel(u16 bdf, u32 pam0)
{
- int reg = pci_config_readb(bdf, pam0);
- if (!(reg & 0x10)) {
- // QEMU doesn't fully implement the piix shadow capabilities -
- // if ram isn't backing the bios segment when shadowing is
- // disabled, the code itself wont be in memory. So, run the
- // code from the high-memory flash location.
- u32 pos = (u32)__make_bios_writable_intel + BIOS_SRC_OFFSET;
- void (*func)(u16 bdf, u32 pam0) = (void*)pos;
- func(bdf, pam0);
- return;
- }
// Ram already present - just enable writes
__make_bios_writable_intel(bdf, pam0);
}
Efimov Vasily (3):
memory: make function invalidate_and_set_dirty public
memory: make function memory_access_is_direct public
PAM: make PAM emulation closer to documentation
exec.c | 14 +--
hw/pci-host/pam.c | 238 ++++++++++++++++++++++++++++++++++++-----
include/exec/memory-internal.h | 15 +++
include/hw/pci-host/pam.h | 10 +-
4 files changed, 239 insertions(+), 38 deletions(-)
--
1.9.1
next reply other threads:[~2015-07-16 8:35 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-16 8:35 Efimov Vasily [this message]
2015-07-16 8:35 ` [Qemu-devel] [PATCH 1/3] memory: make function invalidate_and_set_dirty public Efimov Vasily
2015-07-16 8:35 ` [Qemu-devel] [PATCH 2/3] memory: make function memory_access_is_direct public Efimov Vasily
2015-07-16 8:35 ` [Qemu-devel] [PATCH 3/3] PAM: make PAM emulation closer to documentation Efimov Vasily
2015-07-16 9:05 ` Paolo Bonzini
2015-07-16 10:51 ` Ефимов Василий
2015-07-16 11:10 ` Paolo Bonzini
2015-07-16 14:41 ` Ефимов Василий
2015-07-16 17:52 ` Paolo Bonzini
2015-07-17 9:50 ` Ефимов Василий
2015-07-17 10:10 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1437035704-11299-1-git-send-email-real@ispras.ru \
--to=real@ispras.ru \
--cc=batuzovk@ispras.ru \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).