From patchwork Sun Oct 2 22:22:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Programmingkid X-Patchwork-Id: 677564 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3snKSW0skzz9ryr for ; Mon, 3 Oct 2016 09:23:07 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=BrLDKyLU; dkim-atps=neutral Received: from localhost ([::1]:32812 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bqp9z-0000Fb-NY for incoming@patchwork.ozlabs.org; Sun, 02 Oct 2016 18:23:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46302) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bqp9J-0008Mk-36 for qemu-devel@nongnu.org; Sun, 02 Oct 2016 18:22:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bqp9H-0001dY-RS for qemu-devel@nongnu.org; Sun, 02 Oct 2016 18:22:21 -0400 Received: from mail-it0-x241.google.com ([2607:f8b0:4001:c0b::241]:35150) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bqp9B-0001aQ-Ue; Sun, 02 Oct 2016 18:22:14 -0400 Received: by mail-it0-x241.google.com with SMTP id l13so6044369itl.2; Sun, 02 Oct 2016 15:22:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:message-id:cc:content-transfer-encoding:from:subject :date:to; bh=WawMgAvmk/WcDuwbLyVXfiswlZWpqPSudYkn9ZXz5Ag=; b=BrLDKyLUJZRRfke6E3r6i8v7DuD9mmZav4LINp/ZVKmY/MPG/yYyZkcYbwLVAVupy5 DPgiRW8F0FNEz006Om4E2ly3aj5GFyp9DyNZqTPe4+qpRrIxdjmhYKxuRqJ4t/WKpWVL AsD7SEfzroyyWk+w5y9+dc+o1fuersU8Fu4F9az4z0kWCT8gjy1M7+DS7VHd3XDNMluY qCEIG4R2bTLG4+wN2Gb3hgIKMuXqYgS4W9iwg1YXDS+Jw+w4n4WvWQg2papifwxR941V WebXyE25ZvZX3kXzJWvBJLMYddRB3/yzo3cDCG8mCOb4/dlyxQTsXPEmbIyef1y0820n 6Hdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:message-id:cc :content-transfer-encoding:from:subject:date:to; bh=WawMgAvmk/WcDuwbLyVXfiswlZWpqPSudYkn9ZXz5Ag=; b=Ffk51570JsyZREZfYcttZiMffQCDuyiTBORsfjMTc1SNLDbuNWz32X4TnIe5t02cJU 4qyqH6UzcJ125iPhvIe1OBUHVqchT+syanqdDOIeYpM0IfPpU2O0UTP1um9qv79G6+b9 7pzmm9BKb4j0dy2SPftwLruQgnV51r7FLOCbWxQR38cSHl7WLf0GIjd7nLxhCk57cKox /MBPxomdbvFiXmlH+tt6/YHbMhaJJ8bPweGPwG0VrgZSwuTIt2wqlt45Ahnw7vDQgKUV ncO0aoF0qlX1ytMTBPOpzdOLQwxJdd+iJqfJp7A0Xuw3BNM774F2/es+NTfmki0zIzDY 8FEg== X-Gm-Message-State: AA6/9Rn9rsI4h+PgZrHWtdkwVM++7Rx3IfimHxLV9mSKt/MR9hIfh/NgqLVm9NcnBwQWKw== X-Received: by 10.36.236.132 with SMTP id g126mr4179388ith.36.1475446932084; Sun, 02 Oct 2016 15:22:12 -0700 (PDT) Received: from [192.168.0.9] (d199-74-164-53.col.wideopenwest.com. [74.199.53.164]) by smtp.gmail.com with ESMTPSA id b36sm10669871iod.36.2016.10.02.15.22.10 (version=TLS1 cipher=AES128-SHA bits=128/128); Sun, 02 Oct 2016 15:22:11 -0700 (PDT) Mime-Version: 1.0 (Apple Message framework v753.1) Message-Id: From: G 3 Date: Sun, 2 Oct 2016 18:22:03 -0400 To: Benjamin Herrenschmidt X-Mailer: Apple Mail (2.753.1) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:4001:c0b::241 Subject: [Qemu-devel] [PATCH v5] Add resolutions via the command-line X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "list@suse.de:PowerPC list:PowerPC" , qemu-devel qemu-devel Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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 --- 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(-) 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); 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; +} + +