Complete QEMU platform using SystemC modules

active?fid=146

Moving all QEMU devices to SystemC models implies connect different SytemC models to QEMU simulator. In PC platform (and in QEMU) devices are connected by two different ways: PCI bus and I/O ports (direct connection to CPU). This last way will be called I/O Bus. For historical reasons and backward compatibility some old original components are connected to this I/O Bus (mainly the timer, the DMA controller and the IRQ controller). All other (modern) peripherals are connected using the PCI bus.

Also, we must take in account that the first approach to enable SystemC use on QEMU was to connect just only one SystemC device and now we are planning to plug a lot of devices.

For both reasons, the proposal is to enhance the existing SC_Bridge (that is the module that controls the SystemC simulation and the communication between SystemC modules with QEMU) to control more than one device to all SystemC devices. That bridge will receive different bus accesses from the PCI and the I/O Bus, and the Bridge will send the access to the right SystemC module through the corresponding TLM socket. This task will be done using GreenRouter, using one GreenRouter for the PCI Bus and one for the I/O Bus (to avoid address collision we maintain the two buses separated).

Also, we need to develop a new SC_Link_IO (similar to the existing SC_Link_PCI) for the connection to the IO Bus. Both links will send bus transactions (from PCI or I/O bus) to the Bridge.

With this strategy, we avoid the use of many different instances of SystemC simulator as if we had multiple sc_link/sc_bridge/sc_module, one per device. Only one instance of the OSCI simulator is used that contains all the SystemC devices. The simulator controlled by the new SystemC Bridge in the same way that the actual SystemC Bridge do.

As said in the previous section, SystemC modules can use QEMU functionality through the Back-end interface or calling the QEMU functions directly (this last use can be for the case of timer or IRQ controller that has not any external interface and uses QEMU functions).

PCI Bus

Configuration registers and regions

Each PCI device enumerates itself publishing a set of register (config registers) telling to the O.S. what type of device is, vendor ID, etc. This information is used by the O.S. to know what PCI devices system has, and to load the proper drivers. Also, PCI devices publish what type of regions it had (memory or I/O) and size of each region (called BAR). In QEMU, devices also links a Read function and a Write function to each BAR.

QEMU manages these configuration registers asking to each device to fill its own structure, that later QEMU will publish to O.S. Same is done for the In our implementation, sc_link_pci may ask SC_modules to fill this structure. This may be done through the sc_bridge and every module has to publish a special method like sc_set_config_registers(uint8_t *pci_conf). sc_link_pci has to call this method for every module to be plugged into PCI bus, so sc_link_pci needs to know what devices has, and some mechanism to call this function (to be done).

Address decoding

When O.S. accesses to a BAR of a PCI device, QEMU calls the previously registered function for that BAR, passing address and data. In our implementation, the unique sc_link_pci may receive all accesses to different BARs from PCI devices to the same read or write function, and send it to the sc_bridge. The sc_bridge will contain one GreenRouter (or PCIeRouter) to send each access to the proper PCI device. The table containing range address - port of the GreenRouter (or PCIeRouter), will be maintained by the sc_link_pci, because the O.S. is who give addresses to the published BARs dynamically (to be done) The sc_bridge will contain also all the mechanism of synchronization between QEMU and SystemC (done).

TLM socket to use

Because we manage the PCI-specific characteristics (configuration registers, BARs) outside the SystemC world, the communication between PCI devices and the sc_bridge is a very simple point-to-point protocol (sc_bridge uses only read/write to a address of the device). We have the possibility to use PCIeSocket for devices in the PCI bus (PCIe is a new standard to replace older PCI standard). If we use this PCIeSocket, we have the chance to add configuration support to the socket, and use this new mechanism when available instead of the sc_link_pci/sc_bridge tables and functions.

List of PCI devices

  • 00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02)

    0600: 8086:1237 (rev 02)
    Subsystem: 1af4:1100
    Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
    Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
    In <qemu>/hw/piix_pci.c
  • 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]

    0601: 8086:7000    
    Subsystem: 1af4:1100
    Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
    Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
    Latency: 0
    In <qemu>/hw/piix_pci.c
  • 00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]

    0101: 8086:7010 (prog-if 80 [Master])
    Subsystem: 1af4:1100
    Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
    Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
    Latency: 64
    Region 4: I/O ports at c000 [size=16]
    In <qemu>/hw/ide.c
  • 00:01.2 USB Controller: Intel Corporation 82371SB PIIX3 USB [Natoma/Triton II] (rev 01)

    0c03: 8086:7020 (rev 01) (prog-if 00 [UHCI])
    Subsystem: 1af4:1100
    Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
    Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
    Latency: 64
    Interrupt: pin D routed to IRQ 9
    Region 4: I/O ports at c020 [size=32]
    In <qemu>/hw/usb-uhci.c
  • 00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)

    0680: 8086:7113 (rev 03)
    Subsystem: 1af4:1100
    Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
    Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
    Interrupt: pin A routed to IRQ 9
    In <qemu>/hw/acpi.c
  • 00:02.0 VGA compatible controller: Cirrus Logic GD 5446

    0300: 1013:00b8 (prog-if 00 [VGA])
    Subsystem: 1af4:1100
    Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
    Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
    Region 0: Memory at f0000000 (32-bit, prefetchable) [size=32M]
    Region 1: Memory at f2000000 (32-bit, non-prefetchable) [size=4K]
    In <qemu>/hw/cirrus_vga.c
  • 00:03.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8029(AS)

    0200: 10ec:8029
    Subsystem: 1af4:1100
    Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
    Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
    Interrupt: pin A routed to IRQ 10
    Region 0: I/O ports at c100 [size=256]
    In <qemu>/hw/ne2000.c
  • 00:04.0 RAM memory: Unknown device 1af4:1002

    0500: 1af4:1002
    Subsystem: 1af4:0005
    Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
    Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
    Interrupt: pin A routed to IRQ 9
    Region 0: I/O ports at c200 [size=32]
    In <qemu>/hw/virtio-balloon.c
    This device is something related to KVM... investigate it further

I/O Bus

Old perihperals of the PC architecture are connected to CPU using I/O ports. The addresses for these devices are fixed in QEMU. The sc_link_io may register all these addresses and call sc_bridge each time one of these addresses is accessed. sc_bridge must decode the address to know what device is called (this time the addresses are static), and send the transaction for the righ port. We can use another instance of GreenRouter for this task.

List of I/O devices

Maybe incomplete or with mistakes...

  • 8259 interrupt controller

    IOPort Address: 0x20, 0xa0
    In <qemu>/hw/i8259.c
  • 8254 timer

    IOPort Address: 0x40
    In <qemu>/hw/i8254.c
  • ioapic

    IOMemory Address: 0xfec00000 (size: 0x1000)
    In <qemu>/hw/apic.c
        http://www.intel.com/Assets/PDF/manual/253668.pdf Intel® 64 and IA-32 Architectures Software Developer’s Manual (sec 9)
        http://www.intel.com/design/chipsets/datashts/290566.htm Intel® 82093AA DS
        http://www.intel.com/design/pentium/datashts/242016.HTM Intel® MultiProcessor Specification (sec 3.6)
  • PC speaker

    IOPort Address: 0x61
    In <qemu>/hw/pcspk.c
  • hpet

    IOMemory Address: 0xfed00000 (size: 0x400);
    In <qemu>/hw/hpet.c
  • rtc

    IOPort Address: 0x70
    In <qemu>/hw/mc146818rtc.c
  • serial port (4)

    IOPort Address: 0x3f8, 0x2f8, 0x3e8, 0x2e8 
    IRQ: 4, 3, 4, 3
    In <qemu>/hw/serial.c
  • parallel port (3)

    IOPort Address: 0x378, 0x278, 0x3bc
    IRQ: 7, 7, 7
    In <qemu>/hw/parallel.c
  • i8042 PC Keyboard

    IOPort Address: 0x60, 0x64
    IRQ: 1, 12
    In <qemu>/hw/pckbd.c
  • DMA

    IOPort Address: 0x00-001f, 0x80-8f, 0xc0-00df
    In <qemu>/hw/dma.c
  • Floppy disk emulator (Intel 82078)

    IOPort Address: 0x3f0 ???
    In <qemu>/hw/fdc.c

TLM socket to use

The communication between devices and the sc_bridge in this case is very simple (again read/write to a address of the device only). For that reaseon, a generic and simple socket can be use. We plan to use GSGPSocket for that bus.


Filename/TitleSize
whole_qemu_sc.png103.71 KB