Features/PC System Flash: Difference between revisions

From QEMU
No edit summary
Line 1: Line 1:
This is a proposal for a simple flash emulation on QEMU/KVM.
This is a proposal for PC System Flash emulation for on QEMU/KVM.
 
=Flash Hardware=
Leverage the pre-existing CFI flash support in qemu/hw/pflash_cfi01.c (or perhaps qemu/hw/pflash_cfi02.c).


=Command line interface=
=Command line interface=
To enable saving of the flash contents, a -flash
Today the (currently existing) -pflash parameter has no use with
a command line parameter would be added.  This parameter
an x86 or x86-64 systemTo enable PC system flash, this parameter
normally will override the -bios file usage.
would now be used on x86 & x86-64 systems.
 
The -bios parameter would take priority over
<Pre>
-pflash, but one or both could be used with qemu/kvm as follows:
-flash path    path to filename for saving flash contents
</Pre>
 
If the flash path does not exist, then the -bios file will be read to
initialize the flash contents.  If the flash path does exist, then it
will be used instead of the -bios file contents.
 
=VM hardware interface=
 
==Hardware resources==
The flash will be available as memory mapped io just below 0x100000000 (4GB).  For example, if the -flash file was 0x100000 (1MB) in size, then the flash will be available in memory space from 0xfff00000 through 0xffffffff.
 
==Normal reads==
The flash content can be read in 1, 2, 4 or 8 byte sizes like the
current read-only bios romThe read accesses are not required to be aligned.
 
==Programming interface==
Aside from normal flash read operations, the flash can be communicated
with via special sequences of memory read and write operations.
 
This interface supports 32-bit aligned 32-bit data operations as
well as 64-bit aligned 64-bit operations.
 
In the following examples, the address 0xfffffffc is used for 32-bit
examples, and 0xfffffff8 is used for 64-bit examples.  However,
any properly aligned address can be used from 0x100000000-sizeof(bios.bin)
up through 0xfffffff8 (for 64-bit operations) or 0xfffffffc (for 32-bit
operations).
 
Only 1 flash communication operation can occur at one time.  If any
flash write occurs in another area of the flash, the the previous
operation will be cancelled.
 
===Entering flash communication mode===
32-bit access:
<Pre>
write32(addr=0xfffffffc, data=0x5a5a5a5a)
read32(addr=0xfffffffc) => returns 0xa5a5a5a5
</Pre>
64-bit access:
<Pre>
write64(addr=0xfffffff8, data=0x5a5a5a5a5a5a5a5a)
read64(addr=0xfffffff8) => returns 0xa5a5a5a5a5a5a5a5
</Pre>
 
===Program flash===
* The flash must be in flash communication mode
32-bit access:
<Pre>
write32(addr=0xfffffffc, data=0x0)
read32(addr=0xfffffffc) => returns current flash contents
write32(addr=0xfffffffc, data=new flash contents)
read32(addr=0xfffffffc) => returns new flash contents
read32(addr=0xfffffffc) => returns new flash contents ^ 0xffffffff
</Pre>
64-bit access:
<Pre>
write64(addr=0xfffffff8, data=0x0)
read64(addr=0xfffffff8) => returns current flash contents
write64(addr=0xfffffff8, data=new flash contents)
read64(addr=0xfffffff8) => returns new flash contents
read64(addr=0xfffffff8) => returns new flash contents ^ 0xffffffffffffffff
</Pre>
* Following a successful program operation, the flash will immediately return to normal read mode.
 
===Flash size read===
* The flash must be in flash communication mode
32-bit access:
<Pre>
write32(addr=0xfffffffc, data=0x1)
read32(addr=0xfffffffc) => returns the size of the flash device
read32(addr=0xfffffffc) => returns the flash size ^ 0xffffffff
</Pre>
64-bit access:
<Pre>
write64(addr=0xfffffff8, data=0x1)
read64(addr=0xfffffff8) => returns the size of the flash device
read64(addr=0xfffffff8) => returns the flash size ^ 0xffffffffffffffff
</Pre>
* Following a flash size read operation, the flash will immediately return to normal read mode.
 
===Interruptions===
* If the sequences above are not followed exactly, then the flash device should cancel the operation and immediately enter read mode.
* If a non-aligned write operation or a 1 or 2 byte write occurs to the  flash while a flash operation is in progress, then the current operation is immediately cancelled.
* If a properly aligned write operation occurs to an different address or of a different size while another operation is in progress, then the current operation is immediately cancelled.  If the write was the proper value to begin entering flash communication mode, then it will be accepted, and the sequence can proceed as a new operation.
 
==Examples==
* 32-bit flash write example at address 0xffff0000.  Data: old=0x76543210, new=0xfedcba98
<Pre>
write32(addr=0xffff0000, data=0x5a5a5a5a)
read32(addr=0xffff0000) => returns 0xa5a5a5a5
write32(addr=0xffff0000, data=0x0)
read32(addr=0xffff0000) => returns 0x76543210
write32(addr=0xffff0000, data=0xfedcba98)
read32(addr=0xffff0000) => returns 0xfedcba98
read32(addr=0xffff0000) => returns 0x01234567
</Pre>


* 64-bit read flash size example at address 0xffff0000.  Flash size=0x100000
{| class='wikitable' border=1
<Pre>
! -bios used !! -pflash used !! Result
write64(addr=0xffff0000, data=0x5a5a5a5a5a5a5a5a)
|-
read64(addr=0xffff0000) => returns 0xa5a5a5a5a5a5a5a5
| <Center>N</Center> || <Center>N</Center> || (no change) 'bios.bin' will be loaded as rom image.
write64(addr=0xffff0000, data=0x1)
|-
read64(addr=0xffff0000) => returns 0x0000000000100000
| <Center>Y</Center> || <Center>N</Center> || (no change) -bios parameter will be loaded as rom image.
read64(addr=0xffff0000) => returns 0xffffffffffefffff
|-
</Pre>
| <Center>N</Center> || <Center>Y</Center>
| ('''changing''') -pflash parameter will be loaded as flash image just below 4GB.


=Why this complicated?=
'bios.bin' will be ''ignored''.
Programming flash in this proposal is simplistic by real hardware standards.  Yet, for a VM we could easily make the flash region use a simple read/write interface.
|-
| <Center>Y</Center> || <Center>Y</Center>
| ('''changing''') -bios parameter will be loaded as rom image just below 4GB.


The downside to this would be that buggy code which inadvertently writes to the flash region might very easily corrupt the flash image of the VM.  With a little complexity required to write the flash, we guard against this issue in most cases.
-pflash parameter will be loaded as flash image just below the bios rom image.
|}

Revision as of 23:24, 13 March 2011

This is a proposal for PC System Flash emulation for on QEMU/KVM.

Flash Hardware

Leverage the pre-existing CFI flash support in qemu/hw/pflash_cfi01.c (or perhaps qemu/hw/pflash_cfi02.c).

Command line interface

Today the (currently existing) -pflash parameter has no use with an x86 or x86-64 system. To enable PC system flash, this parameter would now be used on x86 & x86-64 systems. The -bios parameter would take priority over -pflash, but one or both could be used with qemu/kvm as follows:

-bios used -pflash used Result
N
N
(no change) 'bios.bin' will be loaded as rom image.
Y
N
(no change) -bios parameter will be loaded as rom image.
N
Y
(changing) -pflash parameter will be loaded as flash image just below 4GB.

'bios.bin' will be ignored.

Y
Y
(changing) -bios parameter will be loaded as rom image just below 4GB.

-pflash parameter will be loaded as flash image just below the bios rom image.