20 #include "modules/Module.h" 21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/Service.h" 23 #include "pedigree/kernel/ServiceFeatures.h" 24 #include "pedigree/kernel/ServiceManager.h" 25 #include "pedigree/kernel/graphics/Graphics.h" 26 #include "pedigree/kernel/graphics/GraphicsService.h" 27 #include "pedigree/kernel/machine/Device.h" 28 #include "pedigree/kernel/machine/Display.h" 29 #include "pedigree/kernel/machine/Framebuffer.h" 30 #include "pedigree/kernel/machine/Machine.h" 31 #include "pedigree/kernel/machine/Vga.h" 32 #include "pedigree/kernel/processor/IoBase.h" 33 #include "pedigree/kernel/processor/MemoryMappedIo.h" 34 #include "pedigree/kernel/processor/types.h" 35 #include "pedigree/kernel/utilities/List.h" 36 #include "pedigree/kernel/utilities/String.h" 37 #include "pedigree/kernel/utilities/Vector.h" 38 #include "pedigree/kernel/utilities/new" 40 #include "vm_device_version.h" 42 #define DEBUG_VMWARE_GFX 0 49 Graphics::PixelFormat fmt;
50 } g_VbeIndexedModes[] = {
52 Graphics::Bits16_Rgb555},
53 {0, 80, 25, Graphics::Bits8_Idx}
56 #define SUPPORTED_MODES_SIZE \ 57 (sizeof(g_VbeIndexedModes) / sizeof(g_VbeIndexedModes[0])) 69 :
Display(pDev), m_pIo(0), m_Framebuffer(0), m_CommandRegion(0),
70 m_pFramebufferRawAddress(0)
72 m_pIo = m_Addresses[0]->m_Io;
75 writeRegister(SVGA_REG_ID, SVGA_MAKE_ID(2));
76 if (readRegister(SVGA_REG_ID) != SVGA_MAKE_ID(2))
78 WARNING(
"vmware-gfx not a compatible SVGA device");
83 uintptr_t fbBase = readRegister(SVGA_REG_FB_START);
84 size_t fbSize = readRegister(SVGA_REG_VRAM_SIZE);
87 uintptr_t cmdBase = readRegister(SVGA_REG_MEM_START);
88 size_t cmdSize = readRegister(SVGA_REG_MEM_SIZE);
91 size_t caps = readRegister(SVGA_REG_CAPABILITIES);
94 size_t maxWidth = readRegister(SVGA_REG_MAX_WIDTH);
95 size_t maxHeight = readRegister(SVGA_REG_MAX_HEIGHT);
98 writeRegister(SVGA_REG_GUEST_ID, 0x500A);
102 "vmware-gfx found, caps=" <<
Hex << caps
103 <<
", maximum resolution is " <<
Dec 104 << maxWidth <<
"x" << maxHeight <<
Hex);
106 "vmware-gfx framebuffer at " 107 <<
Hex << fbBase <<
" - " << (fbBase + fbSize)
108 <<
", command FIFO at " << cmdBase);
110 if (m_Addresses[1]->m_Address == fbBase)
112 m_Framebuffer =
static_cast<MemoryMappedIo *
>(m_Addresses[1]->m_Io);
115 m_Addresses[2]->map();
117 m_pFramebufferRawAddress = m_Addresses[1];
121 m_Framebuffer =
static_cast<MemoryMappedIo *
>(m_Addresses[2]->m_Io);
124 m_Addresses[1]->map();
126 m_pFramebufferRawAddress = m_Addresses[2];
130 writeRegister(SVGA_REG_CONFIG_DONE, 0);
133 writeRegister(SVGA_REG_ENABLE, 0);
136 volatile uint32_t *fifo =
reinterpret_cast<volatile uint32_t *
>(
137 m_CommandRegion->virtualAddress());
139 if (caps & SVGA_CAP_EXTENDED_FIFO)
141 size_t numFifoRegs = readRegister(SVGA_REG_MEM_REGS);
142 size_t fifoExtendedBase = numFifoRegs * 4;
144 fifo[SVGA_FIFO_MIN] =
146 fifo[SVGA_FIFO_MAX] =
148 fifo[SVGA_FIFO_NEXT_CMD] = fifo[SVGA_FIFO_STOP] =
152 "vmware-gfx using extended fifo, caps=" 153 << fifo[SVGA_FIFO_CAPABILITIES]
154 <<
", flags=" << fifo[SVGA_FIFO_FLAGS]);
158 fifo[SVGA_FIFO_MIN] =
160 fifo[SVGA_FIFO_MAX] =
162 fifo[SVGA_FIFO_NEXT_CMD] = fifo[SVGA_FIFO_STOP] = 16;
166 reinterpret_cast<uintptr_t>(m_Framebuffer->virtualAddress()),
this);
170 pProvider->pDisplay =
this;
171 pProvider->pFramebuffer = m_pFramebuffer;
172 pProvider->maxWidth = maxWidth;
173 pProvider->maxHeight = maxHeight;
174 pProvider->maxTextWidth = 0;
175 pProvider->maxTextHeight = 0;
176 pProvider->maxDepth = 32;
177 pProvider->bHardwareAccel =
true;
185 bool bSuccess =
false;
188 bSuccess = pService->
serve(
207 str =
"vmware guest tools, graphics card";
214 sm.width = readRegister(SVGA_REG_WIDTH);
215 sm.height = readRegister(SVGA_REG_HEIGHT);
216 sm.pf.
nBpp = readRegister(SVGA_REG_BITS_PER_PIXEL);
218 size_t redMask = readRegister(SVGA_REG_RED_MASK);
219 size_t greenMask = readRegister(SVGA_REG_GREEN_MASK);
220 size_t blueMask = readRegister(SVGA_REG_BLUE_MASK);
226 if (redMask > blueMask)
227 sm.pf2 = Graphics::Bits24_Rgb;
229 sm.pf2 = Graphics::Bits24_Bgr;
232 if ((redMask == greenMask) && (greenMask == blueMask))
235 sm.pf2 = Graphics::Bits16_Argb;
237 sm.pf2 = Graphics::Bits16_Rgb555;
240 sm.pf2 = Graphics::Bits16_Rgb565;
243 sm.pf2 = Graphics::Bits32_Argb;
247 sm.bytesPerPixel = sm.pf.
nBpp / 8;
248 sm.bytesPerLine = readRegister(SVGA_REG_BYTES_PER_LINE);
257 for (
size_t i = 0; i < SUPPORTED_MODES_SIZE; i++)
260 pMode->id = g_VbeIndexedModes[i].id;
261 pMode->width = g_VbeIndexedModes[i].width;
262 pMode->height = g_VbeIndexedModes[i].height;
263 pMode->pf2 = g_VbeIndexedModes[i].fmt;
284 writeRegister(SVGA_REG_ENABLE, 0);
288 setMode(sm.width, sm.height, Graphics::bitsPerPixel(sm.pf2));
303 size_t maxWidth = readRegister(SVGA_REG_MAX_WIDTH);
304 size_t maxHeight = readRegister(SVGA_REG_MAX_HEIGHT);
310 if (nWidth > maxWidth)
312 if (nHeight > maxHeight)
315 setMode(nWidth, nHeight, nBpp);
322 writeRegister(SVGA_REG_ENABLE, 1);
325 writeRegister(SVGA_REG_WIDTH, w);
326 writeRegister(SVGA_REG_HEIGHT, h);
327 writeRegister(SVGA_REG_BITS_PER_PIXEL, bpp);
329 size_t fbOffset = readRegister(SVGA_REG_FB_OFFSET);
330 size_t width = readRegister(SVGA_REG_WIDTH);
331 size_t height = readRegister(SVGA_REG_HEIGHT);
332 size_t depth = readRegister(SVGA_REG_DEPTH);
333 uintptr_t fbBase = readRegister(SVGA_REG_FB_START);
335 size_t redMask = readRegister(SVGA_REG_RED_MASK);
336 size_t greenMask = readRegister(SVGA_REG_GREEN_MASK);
337 size_t blueMask = readRegister(SVGA_REG_BLUE_MASK);
339 size_t bytesPerLine = readRegister(SVGA_REG_BYTES_PER_LINE);
340 size_t bytesPerPixel = bytesPerLine / w;
342 m_pFramebuffer->setWidth(w);
343 m_pFramebuffer->setHeight(h);
344 m_pFramebuffer->setBytesPerPixel(bytesPerPixel);
345 m_pFramebuffer->setBytesPerLine(bytesPerLine);
347 Graphics::PixelFormat pf;
351 if (redMask > blueMask)
352 pf = Graphics::Bits24_Rgb;
354 pf = Graphics::Bits24_Bgr;
357 if ((redMask == greenMask) && (greenMask == blueMask))
360 pf = Graphics::Bits16_Argb;
362 pf = Graphics::Bits16_Rgb555;
365 pf = Graphics::Bits16_Rgb565;
368 pf = Graphics::Bits32_Argb;
371 m_pFramebuffer->setFormat(pf);
372 m_pFramebuffer->setXPos(0);
373 m_pFramebuffer->setYPos(0);
374 m_pFramebuffer->setParent(0);
378 m_pFramebufferRawAddress->map(height * bytesPerLine,
true,
true);
379 m_pFramebuffer->setFramebuffer(
380 reinterpret_cast<uintptr_t>(m_Framebuffer->virtualAddress()));
383 m_pFramebuffer->rect(0, 0, w, h, 0);
386 writeRegister(SVGA_REG_CONFIG_DONE, 1);
389 "vmware-gfx entered mode " 390 <<
Dec << width <<
"x" << height <<
"x" << depth <<
Hex 391 <<
", mode framebuffer is " << (fbBase + fbOffset));
394 void redraw(
size_t x,
size_t y,
size_t w,
size_t h)
397 writeRegister(SVGA_REG_CONFIG_DONE, 0);
399 if (w > m_pFramebuffer->getWidth())
400 w = m_pFramebuffer->getWidth();
401 if (h > m_pFramebuffer->getHeight())
402 h = m_pFramebuffer->getHeight();
404 writeFifo(SVGA_CMD_UPDATE);
411 writeRegister(SVGA_REG_CONFIG_DONE, 1);
414 void copy(
size_t x1,
size_t y1,
size_t x2,
size_t y2,
size_t w,
size_t h)
417 writeRegister(SVGA_REG_CONFIG_DONE, 0);
419 writeFifo(SVGA_CMD_RECT_COPY);
428 writeRegister(SVGA_REG_CONFIG_DONE, 1);
447 size_t x = ~0UL,
size_t y = ~0UL,
size_t w = ~0UL,
size_t h = ~0UL)
457 m_pDisplay->redraw(x, y, w, h);
461 size_t srcx,
size_t srcy,
size_t destx,
size_t desty,
size_t w,
462 size_t h,
bool bLowestCall =
true)
466 m_pDisplay->copy(srcx, srcy, destx, desty, w, h);
482 m_pIo->
write32(offset, SVGA_INDEX_PORT);
483 return m_pIo->
read32(SVGA_VALUE_PORT);
486 void writeRegister(
size_t offset, uint32_t value)
488 m_pIo->
write32(offset, SVGA_INDEX_PORT);
489 m_pIo->
write32(value, SVGA_VALUE_PORT);
492 void writeFifo(uint32_t value)
494 volatile uint32_t *fifo =
reinterpret_cast<volatile uint32_t *
>(
495 m_CommandRegion->virtualAddress());
498 if (((fifo[SVGA_FIFO_NEXT_CMD] + 4) == fifo[SVGA_FIFO_STOP]) ||
499 (fifo[SVGA_FIFO_NEXT_CMD] == (fifo[SVGA_FIFO_MAX] - 4)))
502 DEBUG_LOG(
"vmware-gfx synchronising full fifo");
509 "vmware-gfx fifo write at " << fifo[SVGA_FIFO_NEXT_CMD]
510 <<
" val=" << value);
512 "vmware-gfx min is at " << fifo[SVGA_FIFO_MIN]
513 <<
" and current position is " 514 << fifo[SVGA_FIFO_STOP]);
518 fifo[fifo[SVGA_FIFO_NEXT_CMD] / 4] = value;
519 if (fifo[SVGA_FIFO_NEXT_CMD] == (fifo[SVGA_FIFO_MAX] - 4))
520 fifo[SVGA_FIFO_NEXT_CMD] = fifo[SVGA_FIFO_MIN];
522 fifo[SVGA_FIFO_NEXT_CMD] += 4;
524 asm volatile(
"" : : :
"memory");
529 writeRegister(SVGA_REG_SYNC, 1);
530 while (readRegister(SVGA_REG_BUSY))
542 static bool bFound =
false;
544 static void callback(
Device *pDevice)
554 Device::searchByVendorIdAndDeviceId(
555 PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_SVGA2, callback);
564 MODULE_INFO(
"vmware-gfx", &entry, &exit,
"pci",
"config");
566 VmwareGraphics::~VmwareGraphics() =
default;
567 VmwareGraphics::VmwareFramebuffer::~VmwareFramebuffer() =
default;
void pushBack(const T &value)
virtual void copy(size_t srcx, size_t srcy, size_t destx, size_t desty, size_t w, size_t h, bool bLowestCall=true)
virtual bool getScreenModes(List< Display::ScreenMode * > &sms)
void setMode(size_t w, size_t h, size_t bpp)
virtual bool provides(Type service)
virtual Vga * getVga(size_t n)=0
Abstrace base class for hardware I/O capabilities.
virtual void dump(String &str)
virtual bool setMode(int mode)=0
virtual bool getCurrentScreenMode(Display::ScreenMode &sm)
virtual bool setScreenMode(size_t nWidth, size_t nHeight, size_t nBpp)
virtual uint32_t read32(size_t offset=0)=0
virtual void hwRedraw(size_t x=~0UL, size_t y=~0UL, size_t w=~0UL, size_t h=~0UL)
Inherited by drivers that provide a hardware redraw function.
Abstracts the system's framebuffer offering.
Service * getService(const String &serviceName)
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
size_t readRegister(size_t offset)
virtual bool setScreenMode(Display::ScreenMode sm)
virtual bool setScreenMode(size_t modeId)
ServiceFeatures * enumerateOperations(const String &serviceName)
virtual void write32(uint32_t value, size_t offset=0)=0
virtual void getName(String &str)
virtual bool setScreenMode(ScreenMode sm)