[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Add resolutions via the command-line
From: |
G 3 |
Subject: |
[Qemu-devel] [PATCH] Add resolutions via the command-line |
Date: |
Sat, 17 Sep 2016 23:31:59 -0400 |
Add the ability to add resolutions from the command-line. This patch
works by
looking for a property called 'resolutions' in the options 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>
---
QemuVGADriver/src/QemuVga.c | 227 ++++++++++++++++++++++++++++++++++
+++++++++-
1 file changed, 225 insertions(+), 2 deletions(-)
diff --git a/QemuVGADriver/src/QemuVga.c b/QemuVGADriver/src/QemuVga.c
index 4584242..d74fa41 100644
--- a/QemuVGADriver/src/QemuVga.c
+++ b/QemuVGADriver/src/QemuVga.c
@@ -3,6 +3,7 @@
#include "DriverQDCalls.h"
#include "QemuVga.h"
#include <Timer.h>
+#include <stdlib.h>
/* List of supported modes */
struct vMode {
@@ -18,7 +19,21 @@ static struct vMode vModes[] = {
{ 1600, 1200 },
{ 1920, 1080 },
{ 1920, 1200 },
- { 0,0 }
+
+ /* The rest are place holders */
+ { 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 },
};
static void VgaWriteB(UInt16 port, UInt8 val)
@@ -147,11 +162,219 @@ static InterruptMemberNumber
PCIInterruptHandler(InterruptSetMember ISTmember,
}
#endif
+/*
+ * Get the resolution set at the specified index.
+ * The string returned needs to be freed when no longer used.
+ */
+static char *get_set(const char *resolution_set_str, int set_number)
+{
+ const int max_buf_size = 100;
+ char c, *buffer;
+ int index, comma_count;
+
+ buffer = (char *) malloc(max_buf_size);
+ comma_count = 0;
+ index = 0;
+ set_number++; /* Makes things easier to understand */
+
+ c = *(resolution_set_str++);
+ while (c != '\0') {
+ buffer[index++] = c;
+ c = *(resolution_set_str++);
+ if (c == ',') {
+ comma_count++;
+ if (comma_count == set_number || index >= max_buf_size)
{
+ buffer[index] = '\0';
+ return buffer;
+ }
+
+ else {
+ /* reset the buffer */
+ index = 0;
+ c = *(resolution_set_str++);
+ }
+ }
+ }
+
+ buffer[index] = '\0';
+
+ return buffer;
+}
+
+/*
+ * Get the number of resolution sets
+ */
+
+static int get_set_count(const char *resolution_sets_str)
+{
+ char c;
+ int count;
+
+ /* Count the number of commas */
+ count = 0;
+ c = *(resolution_sets_str++);
+ while (c != '\0') {
+ if (c == ',') {
+ count++;
+ }
+ c = *(resolution_sets_str++);
+ }
+
+ return count + 1;
+}
+
+/*
+ * Returns the width value of a resolution set
+ * Example:
+ * input: 16000x9000
+ * output: 16000
+ */
+
+static int get_width(const char *resolution_str)
+{
+ int index;
+ char c;
+ const int max_buf_size = 25;
+ char buffer[max_buf_size];
+ c = *(resolution_str++);
+ index = 0;
+ while (c != 'x' && index < max_buf_size) {
+ buffer[index++] = c;
+ c = *(resolution_str++);
+ }
+
+ /* Terminate string */
+ buffer[index] = '\0';
+
+ return atoi(buffer);
+}
+
+/*
+ * Returns the height value of a resolution set
+ * Example
+ * input: 16000x9000
+ * output: 9000
+ */
+
+static int get_height(const char *resolution_str)
+{
+ int index;
+ char c;
+ const int max_buf_size = 25;
+ char buffer[max_buf_size];
+
+ /* skip to character after x */
+ while (*resolution_str != 'x') {
+ resolution_str++;
+ }
+ resolution_str++;
+
+ /* Add digits of the height to the buffer */
+ index = 0;
+ c = *(resolution_str++);
+ while (c != '\0') {
+ buffer[index++] = c;
+ c = *(resolution_str++);
+ if(index >= max_buf_size) {
+ break;
+ }
+ }
+
+ /* Terminate string */
+ buffer[index] = '\0';
+
+ return atoi(buffer);
+}
+
+/*
+ * Looks in the /chosen node for the value of the resolutions property
+ */
+static int add_user_resolutions(void)
+{
+ RegEntryID *entry_id;
+ OSErr err;
+ Boolean is_done;
+ void *value;
+ RegPropertyValueSize property_size;
+ int index, res_set_count;
+ char *set_str;
+
+ #define PROPERTY_NAME "resolutions"
+ #define NODE_PATH "Devices:device-tree:options"
+
+ /* init the entry variable */
+ err = RegistryEntryIDInit(entry_id);
+ if (err != noErr) {
+ lprintf("Error: Failed to init entry variable! (%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 (%d)\n", err);
+ return err;
+ }
+
+ /* Get the size of the property */
+ err = RegistryPropertyGetSize(entry_id, PROPERTY_NAME,
&property_size);
+ if (err != noErr) {
+ lprintf("Error: Failed to get property size! (%d)\n", err);
+ return err;
+ }
+
+ /* allocate memory to the value variable */
+ value = (void *) malloc(property_size);
+
+ /* 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!\n",
PROPERTY_NAME);
+ return err;
+ }
+
+ /* Limit the number of resolutions to 20 */
+ #define sane_number_of_resolutions 20
+ res_set_count = get_set_count(value);
+ res_set_count = (res_set_count > sane_number_of_resolutions ?
sane_number_of_resolutions : res_set_count);
+
+ /* Add each resolution set */
+ for(index = 0; index < res_set_count; index++) {
+ set_str = get_set(value, index);
+ vModes[index].width = get_width(set_str);
+ vModes[index].height = get_height(set_str);
+ free(set_str);
+ }
+
+ free(value);
+}
+
+/* Returns the number of resolutions */
+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++)
+ {
+ /* Don't count any place holders */
+ if (vModes[index].width != 0) {
+ num_of_resolutions++;
+ }
+ }
+
+ return num_of_resolutions;
+}
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);
@@ -183,7 +406,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
- [Qemu-devel] [PATCH] Add resolutions via the command-line,
G 3 <=
- Re: [Qemu-devel] [PATCH] Add resolutions via the command-line, Benjamin Herrenschmidt, 2016/09/19
- Re: [Qemu-devel] [PATCH] Add resolutions via the command-line, G 3, 2016/09/19
- Re: [Qemu-devel] [PATCH] Add resolutions via the command-line, G 3, 2016/09/20
- Re: [Qemu-devel] [PATCH] Add resolutions via the command-line, Benjamin Herrenschmidt, 2016/09/20
- Re: [Qemu-devel] [PATCH] Add resolutions via the command-line, G 3, 2016/09/20
- Re: [Qemu-devel] [PATCH] Add resolutions via the command-line, Benjamin Herrenschmidt, 2016/09/20
- Re: [Qemu-devel] [PATCH] Add resolutions via the command-line, G 3, 2016/09/20