qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [PATCH v5] Add resolutions via the command-line


From: G 3
Subject: [Qemu-ppc] [PATCH v5] Add resolutions via the command-line
Date: Sun, 2 Oct 2016 18:22:03 -0400

Add the ability to add resolutions from the command-line. This patch works by looking for a property called 'fb-modes' in the QEMU,VGA node of OpenBIOS.
If it is found all the resolutions are parsed and loaded.

Example command-line:

-prom-env resolutions=512x342,640x480,800x600,1024x600,1200x700,1440x900


Signed-off-by: John Arbuckle <address@hidden>
---
v5
Switched from using 'resolutions' to 'fb-modes' in the QEMU,VGA node as Mark requested.

v4
Removed all ASCII text processing code and replaced it with integer processing code.

v3
Changed implementation of atoi().
Removed strlen() implementation.
Removed pow() implementation.
Changed entry_id from pointer to automatic variable.

v2
Implemented my own malloc(), strlen(), pow(), and atoi() functions.
Removed free() calls.
Changed get_set_count() to get_resolution_set_count().

QemuVGADriver/src/QemuVga.c | 107 ++++++++++++++++++++++++++++++++++ +++++++++-
 1 file changed, 105 insertions(+), 2 deletions(-)

diff --git a/QemuVGADriver/src/QemuVga.c b/QemuVGADriver/src/QemuVga.c
index 4584242..28daa02 100644
--- a/QemuVGADriver/src/QemuVga.c
+++ b/QemuVGADriver/src/QemuVga.c
@@ -18,9 +18,25 @@ static struct vMode vModes[] =  {
        { 1600, 1200 },
        { 1920, 1080 },
        { 1920, 1200 },
-       { 0,0 }
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
+       { 0,0 },
 };

+/* The number of width-height pairs in the above vModes structure */
+#define AVAILABLE_SLOTS 20
+
+
 static void VgaWriteB(UInt16 port, UInt8 val)
 {
        UInt8 *ptr;
@@ -148,11 +164,98 @@ static InterruptMemberNumber PCIInterruptHandler (InterruptSetMember ISTmember,
 #endif


+/* Returns the number of resolutions in the vModes array */
+static int get_number_of_resolutions()
+{
+       int size_of_array, num_of_resolutions, index;
+       
+       num_of_resolutions = 0;
+       size_of_array = sizeof(vModes) / sizeof(struct vMode);
+       
+       for(index = 0; index < size_of_array; index++)
+       {
+               if (vModes[index].width != 0) {
+                       num_of_resolutions++;
+               }
+       }
+       
+       return num_of_resolutions;
+}
+
+
+/* Looks in the /options node for the value of the resolutions property */
+static int add_user_resolutions(void)
+{      
+       RegEntryID entry_id;
+       OSErr err;
+       OSStatus os_status = noErr;
+       Boolean is_done;
+       void *value;
+       RegPropertyValueSize property_size = -1;
+       int index, res_set_count, *res_values;
+
+       #define PROPERTY_NAME "fb-modes"
+       #define NODE_PATH "Devices:device-tree:pci:QEMU,VGA"
+
+       /* init the entry variable */
+       err = RegistryEntryIDInit(&entry_id);
+       if (err != noErr) {
+               lprintf("Error: Failed to init entry variable! (Error: %d)\n", 
err);
+               return err;
+       }
+       is_done = false;
+
+       /* Get the entry ID value */
+ err = RegistryCStrEntryLookup(NULL /* start root */, NODE_PATH, &entry_id);
+       if (err != noErr) {
+               lprintf("RegistryCStrEntryLookup() failure (Error: %d)\n", err);
+               return err;
+       }
+
+       /* Get the size of the property */
+ os_status = RegistryPropertyGetSize(&entry_id, PROPERTY_NAME, &property_size);
+       if (os_status != noErr) {
+ lprintf("Error: Failed to get property size! (Error: %d)\n", os_status);
+               return os_status;
+       }
+
+       /* Allocate memory to the value variable */
+       value = (void *) PoolAllocateResident(property_size, false);
+       if (value == NULL) {
+               lprintf("Error: Failed to allocate memory to value variable\n");
+               return -1;
+       }
+
+       /* Get the value of the property */
+ err = RegistryPropertyGet(&entry_id, PROPERTY_NAME, value, &property_size);
+       if (err != noErr) {
+ lprintf("Error: Failed to find property value %s! (Error: %d)\n", PROPERTY_NAME, err);
+               return err;
+       }
+       
+       res_values = value;
+ res_set_count = property_size/4/2; /* divide by bytes per cell then by cells per set */
+       
+ /* Limit the number of resolutions to number of available slots in vMode */ + res_set_count = (res_set_count > AVAILABLE_SLOTS ? AVAILABLE_SLOTS : res_set_count);
+
+       /* Load each resolution set */
+       for(index = 0; index < res_set_count; index++)
+       {
+               vModes[index].width = *(res_values++);
+               vModes[index].height = *(res_values++);
+       }
+       return 0;
+}
+
+
 OSStatus QemuVga_Init(void)
 {
        UInt16 id, i;
        UInt32 mem, width, height, depth;

+       add_user_resolutions();
+
        lprintf("First MMIO read...\n");
        id = DispiReadW(VBE_DISPI_INDEX_ID);
        mem = DispiReadW(VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
@@ -183,7 +286,7 @@ OSStatus QemuVga_Init(void)
                i = 0;
        }
        GLOBAL.bootMode = i;
-       GLOBAL.numModes = sizeof(vModes) / sizeof(struct vMode) - 1;
+       GLOBAL.numModes = get_number_of_resolutions();

        QemuVga_SetMode(GLOBAL.bootMode, depth, 0);

--
2.6.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]