 6f2b175a09
			
		
	
	
		6f2b175a09
		
	
	
	
	
		
			
			This patch adds an 64bit pci bar for vram.  It is turned off by default.
It can be enabled by setting the size of the 64bit bar to be larger than
the 32bit bar.  Both 32bit and 64bit bar refer to the same memory.  Only
the first part of the memory is available via 32bit bar.
The intention is to allow large vram sizes for 64bit guests, by allowing
the vram bar being mapped above 4G, so we don't have to squeeze it into
the pci I/O window below 4G.
With vram_size_mb=16 and vram64_size_mb=256 it looks like this:
00:02.0 VGA compatible controller: Red Hat, Inc. Device 0100 (rev 02) (prog-if 00 [VGA controller])
        Subsystem: Red Hat, Inc Device 1100
        Physical Slot: 2
        Flags: fast devsel, IRQ 10
        Memory at f8000000 (32-bit, non-prefetchable) [size=64M]
        Memory at fc000000 (32-bit, non-prefetchable) [size=16M]
        Memory at fd020000 (32-bit, non-prefetchable) [size=8K]
        I/O ports at c5a0 [size=32]
        Memory at ffe0000000 (64-bit, prefetchable) [size=256M]
        Expansion ROM at fd000000 [disabled] [size=64K]
[ mapping above 4G needs patched seabios:
  http://www.kraxel.org/cgit/seabios/commit/?h=pci64 ]
		
	
			
		
			
				
	
	
		
			154 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "qemu-common.h"
 | |
| 
 | |
| #include "console.h"
 | |
| #include "hw.h"
 | |
| #include "pci.h"
 | |
| #include "vga_int.h"
 | |
| #include "qemu-thread.h"
 | |
| 
 | |
| #include "ui/qemu-spice.h"
 | |
| #include "ui/spice-display.h"
 | |
| 
 | |
| enum qxl_mode {
 | |
|     QXL_MODE_UNDEFINED,
 | |
|     QXL_MODE_VGA,
 | |
|     QXL_MODE_COMPAT, /* spice 0.4.x */
 | |
|     QXL_MODE_NATIVE,
 | |
| };
 | |
| 
 | |
| #ifndef QXL_VRAM64_RANGE_INDEX
 | |
| #define QXL_VRAM64_RANGE_INDEX 4
 | |
| #endif
 | |
| 
 | |
| #define QXL_UNDEFINED_IO UINT32_MAX
 | |
| 
 | |
| #define QXL_NUM_DIRTY_RECTS 64
 | |
| 
 | |
| typedef struct PCIQXLDevice {
 | |
|     PCIDevice          pci;
 | |
|     SimpleSpiceDisplay ssd;
 | |
|     int                id;
 | |
|     uint32_t           debug;
 | |
|     uint32_t           guestdebug;
 | |
|     uint32_t           cmdlog;
 | |
|     enum qxl_mode      mode;
 | |
|     uint32_t           cmdflags;
 | |
|     int                generation;
 | |
|     uint32_t           revision;
 | |
| 
 | |
|     int32_t            num_memslots;
 | |
|     int32_t            num_surfaces;
 | |
| 
 | |
|     uint32_t           current_async;
 | |
|     QemuMutex          async_lock;
 | |
| 
 | |
|     struct guest_slots {
 | |
|         QXLMemSlot     slot;
 | |
|         void           *ptr;
 | |
|         uint64_t       size;
 | |
|         uint64_t       delta;
 | |
|         uint32_t       active;
 | |
|     } guest_slots[NUM_MEMSLOTS];
 | |
| 
 | |
|     struct guest_primary {
 | |
|         QXLSurfaceCreate surface;
 | |
|         uint32_t       commands;
 | |
|         uint32_t       resized;
 | |
|         int32_t        qxl_stride;
 | |
|         uint32_t       abs_stride;
 | |
|         uint32_t       bits_pp;
 | |
|         uint32_t       bytes_pp;
 | |
|         uint8_t        *data;
 | |
|     } guest_primary;
 | |
| 
 | |
|     struct surfaces {
 | |
|         QXLPHYSICAL    cmds[NUM_SURFACES];
 | |
|         uint32_t       count;
 | |
|         uint32_t       max;
 | |
|     } guest_surfaces;
 | |
|     QXLPHYSICAL        guest_cursor;
 | |
| 
 | |
|     QemuMutex          track_lock;
 | |
| 
 | |
|     /* thread signaling */
 | |
|     QemuThread         main;
 | |
|     int                pipe[2];
 | |
| 
 | |
|     /* ram pci bar */
 | |
|     QXLRam             *ram;
 | |
|     VGACommonState     vga;
 | |
|     uint32_t           num_free_res;
 | |
|     QXLReleaseInfo     *last_release;
 | |
|     uint32_t           last_release_offset;
 | |
|     uint32_t           oom_running;
 | |
| 
 | |
|     /* rom pci bar */
 | |
|     QXLRom             shadow_rom;
 | |
|     QXLRom             *rom;
 | |
|     QXLModes           *modes;
 | |
|     uint32_t           rom_size;
 | |
|     MemoryRegion       rom_bar;
 | |
| 
 | |
|     /* vram pci bar */
 | |
|     uint32_t           vram_size;
 | |
|     MemoryRegion       vram_bar;
 | |
|     uint32_t           vram32_size;
 | |
|     MemoryRegion       vram32_bar;
 | |
| 
 | |
|     /* io bar */
 | |
|     MemoryRegion       io_bar;
 | |
| 
 | |
|     /* user-friendly properties (in megabytes) */
 | |
|     uint32_t          ram_size_mb;
 | |
|     uint32_t          vram_size_mb;
 | |
|     uint32_t          vram32_size_mb;
 | |
| 
 | |
|     /* qxl_render_update state */
 | |
|     int                render_update_cookie_num;
 | |
|     int                num_dirty_rects;
 | |
|     QXLRect            dirty[QXL_NUM_DIRTY_RECTS];
 | |
|     QEMUBH            *update_area_bh;
 | |
| } PCIQXLDevice;
 | |
| 
 | |
| #define PANIC_ON(x) if ((x)) {                         \
 | |
|     printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
 | |
|     abort();                                           \
 | |
| }
 | |
| 
 | |
| #define dprint(_qxl, _level, _fmt, ...)                                 \
 | |
|     do {                                                                \
 | |
|         if (_qxl->debug >= _level) {                                    \
 | |
|             fprintf(stderr, "qxl-%d: ", _qxl->id);                      \
 | |
|             fprintf(stderr, _fmt, ## __VA_ARGS__);                      \
 | |
|         }                                                               \
 | |
|     } while (0)
 | |
| 
 | |
| #define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
 | |
| 
 | |
| /* qxl.c */
 | |
| void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
 | |
| void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
 | |
| 
 | |
| void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
 | |
|                            struct QXLRect *area, struct QXLRect *dirty_rects,
 | |
|                            uint32_t num_dirty_rects,
 | |
|                            uint32_t clear_dirty_region,
 | |
|                            qxl_async_io async, QXLCookie *cookie);
 | |
| void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
 | |
|                                uint32_t count);
 | |
| void qxl_spice_oom(PCIQXLDevice *qxl);
 | |
| void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
 | |
| void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
 | |
| void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
 | |
| 
 | |
| /* qxl-logger.c */
 | |
| void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
 | |
| void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
 | |
| 
 | |
| /* qxl-render.c */
 | |
| void qxl_render_resize(PCIQXLDevice *qxl);
 | |
| void qxl_render_update(PCIQXLDevice *qxl);
 | |
| void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
 | |
| void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie);
 | |
| void qxl_render_update_area_bh(void *opaque);
 |