From nobody Thu Jan 8 13:19:45 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=jablonski.xyz ARC-Seal: i=1; a=rsa-sha256; t=1767239898; cv=none; d=zohomail.com; s=zohoarc; b=nsUZik5VCxctLy1wFZmHSFNOm16Y2VyoCQXntn65KBz9OlP5ROBlhrEH8Oz2MpHeZLq8Nd3yfyMOTOCleNkXHbiqcdlUKeCgUnl0bL6SFIIB2OrgCBfl7XBPp0iFX+Vh5NT06uGbuky8WTqVVWnSjVx185uXNwedMTzJdz96ajM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1767239898; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=1/oQvf+7oFxMlLhS7xldh1B7Xf0xiDTcW0n9KdiVD7A=; b=X4rDgBfvyn/lFhZLk0MwfsjuXD/40dI3cx8NaTuG4vwS8+zZsu90kyDdp4ps9a/90tga8TEEGdX2TtcErCkk8J2bVC+xiPOPqX18RtAemYD38O5YCwt7oJc9E634UXMTPyoYuZoZ4vhNujnmzNPbd8JEjxo1iV6dpe4mRArvrfc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1767239898401353.63500120845026; Wed, 31 Dec 2025 19:58:18 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vb9ob-0002Gc-Ug; Wed, 31 Dec 2025 22:57:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vb9oa-0002FU-8X for qemu-devel@nongnu.org; Wed, 31 Dec 2025 22:57:32 -0500 Received: from fhigh-b3-smtp.messagingengine.com ([202.12.124.154]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vb9oY-0003iI-8X for qemu-devel@nongnu.org; Wed, 31 Dec 2025 22:57:32 -0500 Received: from phl-compute-03.internal (phl-compute-03.internal [10.202.2.43]) by mailfhigh.stl.internal (Postfix) with ESMTP id 5E5707A008F; Wed, 31 Dec 2025 22:57:29 -0500 (EST) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-03.internal (MEProxy); Wed, 31 Dec 2025 22:57:29 -0500 Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 31 Dec 2025 22:57:28 -0500 (EST) Received: from localhost (chomposaur [local]) by chomposaur (OpenSMTPD) with ESMTPA id cf25ce26; Thu, 1 Jan 2026 03:57:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jablonski.xyz; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to; s=fm1; t=1767239849; x= 1767326249; bh=1/oQvf+7oFxMlLhS7xldh1B7Xf0xiDTcW0n9KdiVD7A=; b=A dBLFivlpcUhXnCSG15WQE5B466tPty38JrMrbWDEYJGOXO4OEo2/7tljD9xS4DZX lsh/Jjeg2JhTY6qeZDnHMx+A0zuN4MWdsJeOyaLy6cSfrml9pZt+gTT2fChjEXvL rHbx1+pxWVIKeC3swfbczSKQNx7RTDscghKY/EvmO9WlCVYoErkEDlQupz7g/sQh qPuWMQhIihGegJa7ovp8BfM5QpMJV81kDL4jHoywZWehLXg9ifArctKLuOdlPOzV x08vbnMT0DytpoTvM0UHRThyCbE+CieyizoHjiAdokOfVtNFr4W1qDhDd488ZMzw 7bMOLR+UbQkw5jdjH0/Og== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm2; t=1767239849; x=1767326249; bh=1 /oQvf+7oFxMlLhS7xldh1B7Xf0xiDTcW0n9KdiVD7A=; b=riugsOYB8ukZCRFUl rsaX2T7b3eW5dnUpaVIUYWnutVcZWdfnl163l2GZxw08F6sXhb6yMOtYNY1X9PGv W0brtfTBSVxnP1aXPw45cue5tSXeEOzhd+ef3+zWtdfdnBGgairElY7v5puI2i6R s1+wrCSKy0CnxqCDY+PM3r2mbbT2zlB8P3kBHxaL4wPWnUZxM7d0EhjeeqGzA7Re 2+ZBXZIGgySwfcZpHm7hd+OhEJmpQZwBsy62TVPirl3w6JHeCYYnYWmjImOYqGFV AbdY0ZB3qKI1OP4IFp9sN0msmWa0927w2pg4LyuaRBKu/0a4BccGnINExBhQOFKv 8zNyQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgdekgeejiecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecufghrlhcuvffnffculdejtddmnecujfgurhephffvvefuff fkofgjfhgggfestdekredtredttdenucfhrhhomhepvehhrgguucflrggslhhonhhskhhi uceotghhrggusehjrggslhhonhhskhhirdighiiiqeenucggtffrrghtthgvrhhnpefgie etjefhleehfeeiteejgfeljeffhfeuffdvudeijefgueeuuedvvdekjefhleenucevlhhu shhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegthhgrugesjhgrsg hlohhnshhkihdrgiihiidpnhgspghrtghpthhtohepfedpmhhouggvpehsmhhtphhouhht pdhrtghpthhtoheptghhrggusehjrggslhhonhhskhhirdighiiipdhrtghpthhtohepqh gvmhhuqdguvghvvghlsehnohhnghhnuhdrohhrghdprhgtphhtthhopegsrghlrghtohhn segvihhkrdgsmhgvrdhhuh X-ME-Proxy: Feedback-ID: ib26944c1:Fastmail From: Chad Jablonski To: qemu-devel@nongnu.org Cc: balaton@eik.bme.hu, Chad Jablonski Subject: [PATCH v2 2/7] ati-vga: Implement CCE/PM4 microcode register handling Date: Wed, 31 Dec 2025 22:55:50 -0500 Message-ID: <20260101035555.1300511-3-chad@jablonski.xyz> X-Mailer: git-send-email 2.51.2 In-Reply-To: <20260101035555.1300511-1-chad@jablonski.xyz> References: <20260101035555.1300511-1-chad@jablonski.xyz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=202.12.124.154; envelope-from=chad@jablonski.xyz; helo=fhigh-b3-smtp.messagingengine.com X-Spam_score_int: -2 X-Spam_score: -0.3 X-Spam_bar: / X-Spam_report: (-0.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FROM_SUSPICIOUS_NTLD=0.498, PDS_OTHER_BAD_TLD=1.997, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @jablonski.xyz) X-ZM-MESSAGEID: 1767239900489158500 Content-Type: text/plain; charset="utf-8" Implement registers used for loading and reading microcode for the CCE engine. Loading the microcode is the first step for any driver implementing CCE. Reading, while not used by drivers is very helpful for any reverse engineering and testing work. The microcode is currently stored but not used. This lays the groundwork for future RE work on the microcode. There's some quirky behavior around microcode reads that isn't documented elsewhere. There appear to be two internal pointers, one for reading and one for writing that can get out of sync. Comments in the code expand on this. Tested and validated against a Rage 128 Pro Ultra (PCI 1002:5446). Signed-off-by: Chad Jablonski --- hw/display/ati.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ hw/display/ati_cce.h | 26 ++++++++++++++++++++++++ hw/display/ati_int.h | 2 ++ 3 files changed, 75 insertions(+) create mode 100644 hw/display/ati_cce.h diff --git a/hw/display/ati.c b/hw/display/ati.c index 33f8e211dc..e291926470 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -510,6 +510,31 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr,= unsigned int size) case DEFAULT_SC_BOTTOM_RIGHT: val =3D s->regs.default_sc_bottom_right; break; + case PM4_MICROCODE_ADDR: + val =3D s->cce.microcode.addr; + break; + case PM4_MICROCODE_RADDR: + val =3D 0; + break; + case PM4_MICROCODE_DATAH: + val =3D (s->cce.microcode.microcode[s->cce.microcode.raddr] >> 32)= & + 0xffffffff; + break; + case PM4_MICROCODE_DATAL: + val =3D s->cce.microcode.microcode[s->cce.microcode.raddr] & 0xfff= fffff; + s->cce.microcode.addr +=3D 1; + /* + * The write address (addr) is always copied into the + * read address (raddr) after a DATAL read. This leads + * to surprising behavior when the PM4_MICROCODE_ADDR + * instead of the PM4_MICROCODE_RADDR register is set to + * a value just before a read. The first read after this + * will reflect the previous raddr before incrementing and + * re-syncing with addr. This is expected and observed on + * the hardware. + */ + s->cce.microcode.raddr =3D s->cce.microcode.addr; + break; default: break; } @@ -932,6 +957,28 @@ void ati_reg_write(ATIVGAState *s, hwaddr addr, case DEFAULT_SC_BOTTOM_RIGHT: s->regs.default_sc_bottom_right =3D data & 0x3fff3fff; break; + case PM4_MICROCODE_ADDR: + s->cce.microcode.addr =3D data; + break; + case PM4_MICROCODE_RADDR: + s->cce.microcode.raddr =3D data; + s->cce.microcode.addr =3D data; + break; + case PM4_MICROCODE_DATAH: { + uint64_t curr =3D s->cce.microcode.microcode[s->cce.microcode.addr= ]; + uint64_t low =3D curr & 0xffffffff; + uint64_t high =3D (data & 0x1f) << 32; + s->cce.microcode.microcode[s->cce.microcode.addr] =3D high | low; + break; + } + case PM4_MICROCODE_DATAL: { + uint64_t curr =3D s->cce.microcode.microcode[s->cce.microcode.addr= ]; + uint64_t low =3D data & 0xffffffff; + uint64_t high =3D curr & (0xffffffffull << 32); + s->cce.microcode.microcode[s->cce.microcode.addr] =3D high | low; + s->cce.microcode.addr +=3D 1; + break; + } default: break; } diff --git a/hw/display/ati_cce.h b/hw/display/ati_cce.h new file mode 100644 index 0000000000..f2ef1345de --- /dev/null +++ b/hw/display/ati_cce.h @@ -0,0 +1,26 @@ +/* + * QEMU ATI SVGA emulation + * CCE engine functions + * + * Copyright (c) 2025 Chad Jablonski + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef ATI_CCE_H +#define ATI_CCE_H + +#include "qemu/osdep.h" +#include "qemu/log.h" + +typedef struct ATIPM4MicrocodeState { + uint8_t addr; + uint8_t raddr; + uint64_t microcode[256]; +} ATIPM4MicrocodeState; + +typedef struct ATICCEState { + ATIPM4MicrocodeState microcode; +} ATICCEState; + +#endif /* ATI_CCE_H */ diff --git a/hw/display/ati_int.h b/hw/display/ati_int.h index ea1a8bceab..ed6307151b 100644 --- a/hw/display/ati_int.h +++ b/hw/display/ati_int.h @@ -14,6 +14,7 @@ #include "hw/i2c/bitbang_i2c.h" #include "vga_int.h" #include "qom/object.h" +#include "ati_cce.h" =20 /*#define DEBUG_ATI*/ =20 @@ -100,6 +101,7 @@ struct ATIVGAState { MemoryRegion io; MemoryRegion mm; ATIVGARegs regs; + ATICCEState cce; }; =20 const char *ati_reg_name(int num); --=20 2.51.2