Skip to content

Commit

Permalink
Expose IONDRVFramebuffer nub without IOGraphics dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
Goldfish64 committed May 15, 2021
1 parent ff16c84 commit 3816c90
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 175 deletions.
14 changes: 7 additions & 7 deletions UEFIGraphicsFB/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,20 @@
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOClass</key>
<string>$(PRODUCT_NAME:rfc1034identifier)</string>
<key>IOMatchCategory</key>
<string>$(PRODUCT_NAME:rfc1034identifier)</string>
<key>IOMatchCategory</key>
<string>IOPlatformDevice</string>
<key>IOName</key>
<string>display</string>
<key>IOProviderClass</key>
<string>IOResources</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
<string>AppleACPIPlatformExpert</string>
<key>name</key>
<data>ZGlzcGxheQ==</data>
</dict>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2021 Goldfish64. All rights reserved.</string>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.iokit.IOGraphicsFamily</key>
<string>2.0</string>
<key>com.apple.kpi.iokit</key>
<string>8.0.0</string>
<key>com.apple.kpi.libkern</key>
Expand Down
151 changes: 19 additions & 132 deletions UEFIGraphicsFB/UEFIGraphicsFB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,158 +7,45 @@

#include "UEFIGraphicsFB.h"

#include <pexpert/pexpert.h>

OSDefineMetaClassAndStructors(UEFIGraphicsFB, super);

static char const pixelFormatString16[] = IO16BitDirectPixels "\0";
static char const pixelFormatString32[] = IO32BitDirectPixels "\0";

void UEFIGraphicsFB::logPrint(const char *func, const char *format, ...) {
char tmp[1024];
tmp[0] = '\0';
va_list va;
va_start(va, format);
vsnprintf(tmp, sizeof (tmp), format, va);
va_end(va);

IOLog("UEFIGraphicsFB::%s(): %s\n", func, tmp);
}

bool UEFIGraphicsFB::start(IOService *provider) {
if (!PE_state.initialized) {
SYSLOG("PE state is not initialized");
return false;
}

//
// Pull video parameters from kernel for later.
// Pull video parameters from kernel.
//
videoBaseAddress = (UInt32) PE_state.video.v_baseAddr;
videoDisplay = (UInt32) PE_state.video.v_display;
videoWidth = (UInt32) PE_state.video.v_width;
videoHeight = (UInt32) PE_state.video.v_height;
videoDepth = (UInt32) PE_state.video.v_depth;
videoBytesPerRow = (UInt32) PE_state.video.v_rowBytes;

if (videoDepth != kUEFIBitDepth16 && videoDepth != kUEFIBitDepth32) {
SYSLOG("Unsupported bit depth %u", videoDepth);
return false;
}
UInt32 videoBaseAddress = (UInt32) PE_state.video.v_baseAddr;
UInt32 videoWidth = (UInt32) PE_state.video.v_width;
UInt32 videoHeight = (UInt32) PE_state.video.v_height;
UInt32 videoDepth = (UInt32) PE_state.video.v_depth;
UInt32 videoBytesPerRow = (UInt32) PE_state.video.v_rowBytes;

if (!super::start(provider)) {
return false;
}

SYSLOG("Framebuffer is at %X (width %u height %u bits %u)", videoBaseAddress, videoWidth, videoHeight, videoDepth);
return true;
}

void UEFIGraphicsFB::stop(IOService *provider) {
if (videoMemory != NULL) {
videoMemory->release();
videoMemory = NULL;
}

super::stop(provider);
}

IOReturn UEFIGraphicsFB::enableController() {
//
// Map framebuffer memory.
// Create framebuffer memory properties.
// IONDRVFramebuffer will pull this information on start.
//
videoMemory = IODeviceMemory::withRange(videoBaseAddress, videoHeight * videoBytesPerRow);
if (videoMemory == NULL) {
return kIOReturnDeviceError;
}
IODeviceMemory::InitElement fbMemList[1];
fbMemList[0].start = videoBaseAddress;
fbMemList[0].length = videoHeight * videoBytesPerRow;
DBGLOG("Framebuffer memory start 0x%llX length 0x%llX", fbMemList[0].start, fbMemList[0].length);

DBGLOG("Framebuffer is enabled");
return kIOReturnSuccess;
}

bool UEFIGraphicsFB::isConsoleDevice() {
return true;
}

IODeviceMemory* UEFIGraphicsFB::getApertureRange(IOPixelAperture aperture) {
if (kIOFBSystemAperture != aperture) {
return NULL;
}

if (videoMemory != NULL) {
videoMemory->retain();
}
return videoMemory;
}

const char *UEFIGraphicsFB::getPixelFormats() {
return NULL;
}

IOItemCount UEFIGraphicsFB::getDisplayModeCount() {
return kUEFIDisplayModeCount;
}

IOReturn UEFIGraphicsFB::getDisplayModes(IODisplayModeID *allDisplayModes) {
allDisplayModes[0] = kUEFIDisplayModeID;
return kIOReturnSuccess;
}

IOReturn UEFIGraphicsFB::getInformationForDisplayMode(IODisplayModeID displayMode, IODisplayModeInformation *info) {
if (displayMode != kUEFIDisplayModeID) {
return kIOReturnBadArgument;
}

bzero(info, sizeof (*info));
OSArray *fbMemArray = IODeviceMemory::arrayFromList(fbMemList, 1);
setDeviceMemory(fbMemArray);
fbMemArray->release();

info->nominalWidth = videoWidth;
info->nominalHeight = videoHeight;
info->refreshRate = 60<<16;
info->maxDepthIndex = kUEFIDisplayDepthIndex;

return kIOReturnSuccess;
}

UInt64 UEFIGraphicsFB::getPixelFormatsForDisplayMode(IODisplayModeID displayMode, IOIndex depth) {
//
// Obsolete method that always returns zero.
// IONDRVFramebuffer looks for either IOPCIDevice or IOPlatformDevice named "display".
//
return 0;
}

IOReturn UEFIGraphicsFB::getPixelInformation(IODisplayModeID displayMode, IOIndex depth, IOPixelAperture aperture, IOPixelInformation *pixelInfo) {
if (displayMode != kUEFIDisplayModeID || depth != kUEFIDisplayDepthIndex) {
return kIOReturnBadArgument;
}
if (aperture != kIOFBSystemAperture) {
return kIOReturnUnsupportedMode;
}

bzero(pixelInfo, sizeof (*pixelInfo));

pixelInfo->bytesPerRow = videoBytesPerRow;
pixelInfo->bitsPerPixel = videoDepth;
pixelInfo->pixelType = kIORGBDirectPixels;
pixelInfo->bitsPerComponent = 8;
pixelInfo->componentCount = 3;
pixelInfo->componentMasks[0] = 0xFF0000;
pixelInfo->componentMasks[1] = 0x00FF00;
pixelInfo->componentMasks[2] = 0x0000FF;
pixelInfo->activeWidth = videoWidth;
pixelInfo->activeHeight = videoHeight;
registerService();

if (videoDepth == kUEFIBitDepth32) {
strlcpy(&pixelInfo->pixelFormat[0], &pixelFormatString32[0], sizeof (IOPixelEncoding));
} else if (videoDepth == kUEFIBitDepth16) {
strlcpy(&pixelInfo->pixelFormat[0], &pixelFormatString16[0], sizeof (IOPixelEncoding));
}

return kIOReturnSuccess;
}

IOReturn UEFIGraphicsFB::getCurrentDisplayMode(IODisplayModeID *displayMode, IOIndex *depth) {
*displayMode = kUEFIDisplayModeID;
*depth = kUEFIDisplayDepthIndex;

return kIOReturnSuccess;
SYSLOG("Framebuffer is at 0x%X (width %u height %u bits %u bytes/row %u)", videoBaseAddress, videoWidth, videoHeight, videoDepth, videoBytesPerRow);
return true;
}
50 changes: 14 additions & 36 deletions UEFIGraphicsFB/UEFIGraphicsFB.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
#ifndef _UEFI_GRAPHICS_FB_H_
#define _UEFI_GRAPHICS_FB_H_

#include <IOKit/graphics/IOFramebuffer.h>
#include <IOKit/IOPlatformExpert.h>
#include <pexpert/pexpert.h>

#define super IOFramebuffer
#define super IOPlatformDevice

#define SYSLOG(str, ...) logPrint(__FUNCTION__, str, ## __VA_ARGS__)

Expand All @@ -20,49 +21,26 @@
#define DBGLOG(str, ...) {}
#endif

#define kUEFIDisplayModeCount 1
#define kUEFIDisplayModeID 1
#define kUEFIDisplayDepthIndex 0

#define kUEFIBitDepth16 16
#define kUEFIBitDepth32 32

class UEFIGraphicsFB : public super {
OSDeclareDefaultStructors(UEFIGraphicsFB);

private:
UInt32 videoBaseAddress;
UInt32 videoDisplay;
UInt32 videoWidth;
UInt32 videoHeight;
UInt32 videoDepth;
UInt32 videoBytesPerRow;

IODeviceMemory *videoMemory;

void logPrint(const char *func, const char *format, ...);
inline void logPrint(const char *func, const char *format, ...) {
char tmp[512];
tmp[0] = '\0';
va_list va;
va_start(va, format);
vsnprintf(tmp, sizeof (tmp), format, va);
va_end(va);
IOLog("UEFIGraphicsFB::%s(): %s\n", func, tmp);
}

public:
//
// IOService functions.
// IOService overrides.
//
virtual bool start(IOService *provider) APPLE_KEXT_OVERRIDE;
virtual void stop(IOService *provider) APPLE_KEXT_OVERRIDE;


//
// IOFramebuffer functions.
//
virtual IOReturn enableController() APPLE_KEXT_OVERRIDE;
virtual bool isConsoleDevice() APPLE_KEXT_OVERRIDE;
virtual IODeviceMemory *getApertureRange(IOPixelAperture aperture) APPLE_KEXT_OVERRIDE;
virtual const char *getPixelFormats() APPLE_KEXT_OVERRIDE;
virtual IOItemCount getDisplayModeCount() APPLE_KEXT_OVERRIDE;
virtual IOReturn getDisplayModes(IODisplayModeID *allDisplayModes) APPLE_KEXT_OVERRIDE;
virtual IOReturn getInformationForDisplayMode(IODisplayModeID displayMode, IODisplayModeInformation *info) APPLE_KEXT_OVERRIDE;
virtual UInt64 getPixelFormatsForDisplayMode(IODisplayModeID displayMode, IOIndex depth) APPLE_KEXT_OVERRIDE;
virtual IOReturn getPixelInformation(IODisplayModeID displayMode, IOIndex depth, IOPixelAperture aperture, IOPixelInformation *pixelInfo) APPLE_KEXT_OVERRIDE;
virtual IOReturn getCurrentDisplayMode(IODisplayModeID *displayMode, IOIndex *depth) APPLE_KEXT_OVERRIDE;
};

#endif

0 comments on commit 3816c90

Please sign in to comment.