From nobody Sun Nov 24 11:48:11 2024 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=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1722936527; cv=none; d=zohomail.com; s=zohoarc; b=KVrRuT+T0YebEB4sumMqD8EWAISEj+CZGE9kQYWOmmHeETdEZxeTcYwGnqNxlhNAAKo+FMDuwRoRp0yECdIrIQnigvChVu/rue1LCtq2c2cR+9I1/sna+gfF7jGcXYT55T+aoh+aykTvv2QjmhXcJjHGOwhRiLLSvDI01plxSU8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1722936527; h=Content-Type:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=KAlhIHX6tS4E1n4BogBiXgp4i+6SzrRiVFW1tB1ecR0=; b=ds9r+RTUj1FgPSrajOTYxV8yFadMmw/vYaEhKfZyTtdmIcE5ntRTSjYBxjSEYFL7MQTxe3Ka07dCINmFLIEc0ZnBfKNiH1BsSygIFVulGXv8DrsNLRBWmEJ0C8OoVxJJPaCJLjXHiNSzhx9vjkhxF23DyCvpSsksXxWIMDizwcg= 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 1722936527271342.83743005622716; Tue, 6 Aug 2024 02:28:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sbGUS-0002vG-JD; Tue, 06 Aug 2024 05:28:24 -0400 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 1sbGUQ-0002mU-Ea for qemu-devel@nongnu.org; Tue, 06 Aug 2024 05:28:22 -0400 Received: from mail-ed1-x535.google.com ([2a00:1450:4864:20::535]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sbGUM-0002T6-U1 for qemu-devel@nongnu.org; Tue, 06 Aug 2024 05:28:22 -0400 Received: by mail-ed1-x535.google.com with SMTP id 4fb4d7f45d1cf-5b8c2a6135eso982388a12.0 for ; Tue, 06 Aug 2024 02:28:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1722936496; x=1723541296; darn=nongnu.org; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=KAlhIHX6tS4E1n4BogBiXgp4i+6SzrRiVFW1tB1ecR0=; b=CE39AAeX+lEuuC2VT3omRDM/YG3od8c9V7I3ckuttbXAAdrsHRAiTgfMCSPJW8lQPI MUTjrHZ6SOLtq/tTIMjqBKgrQrze6KILEEQD1bbp+A7CCEURcaKqhdRQ9CS9EeiVQ1qJ avsGwxFvtbZe+8xaELpysYIR7VgRvIbr1x63wCiA6AYt8diIPDIyXcu5AXbgcXbcx0GD YQerR63raMKByoAUoxNllxGAiaNeHFznlZV2YXrk6xRW1kHecxenadjmxsyl66MTdmp0 QR6pASHZbFM9luPuSrpBXwSHwfC+yJPmLXJDgDwQ/i4LkYxdg5IZYeeKVjTuBUPHftn1 ellA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722936496; x=1723541296; h=cc:to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=KAlhIHX6tS4E1n4BogBiXgp4i+6SzrRiVFW1tB1ecR0=; b=JqNAsjFQ+3pMuppxw32RqhdqzLL9UNDYQiujIlP8mC5FLPUyq8FseB02zb93pNjYYk NnQjbzYWAbryEsLaTxA3LVcgD3hz2iA62SFb6wPUTiVURTdfIxqPBoOrqhebQ1GKkJHV CEHUiXszgoWGYKv1l6ZsJjy9VYu/tYWDLfoxS4xRNrGq6j6Jb9jrEAlL7bcalSAgQ+qM tYaVODBZ+q6So2Cov7PB1cfSje/aQdg1NHzou73qKnASnUNfb34Vus9XkWjfnN9EmKEC KIFStejYTdh3bbFpYe6zJmmRcZ1SYHUg//EqmKROwDVsVK9YcSHR0Cbc6X1hVakebbaF yBTw== X-Gm-Message-State: AOJu0Yzq0ewvUUIfDkzmNo0iZDV8jHSVv9WWEdkxMh502fI2BHcfCLqz XZeBvn7X7PSS0D0Ezus9uK3Ro5pmmAmHtCe+DvtoWnLuNoQjaxQc9lF1SxBXbK720H52qBYfaVJ QSM/v38UZ3btd2Gee9h1UV4oYp/on9oSK X-Google-Smtp-Source: AGHT+IHpLQblTzwQrlDpXGleJA25LxgnRTK3Gx/eitUUKelSpvnEy97AUXoLzlPSuTHckbp1x6YOm8lA4iZYblldhKM= X-Received: by 2002:a05:6402:655:b0:5b9:fe2f:48e4 with SMTP id 4fb4d7f45d1cf-5b9fe2f490dmr8321295a12.6.1722936495326; Tue, 06 Aug 2024 02:28:15 -0700 (PDT) MIME-Version: 1.0 From: Zero Tang Date: Tue, 6 Aug 2024 17:28:01 +0800 Message-ID: Subject: [PATCH] hw/misc: Add a virtual PCILeech device To: qemu-devel@nongnu.org Cc: mst@redhat.com, marcel.apfelbaum@gmail.com Content-Type: multipart/alternative; boundary="000000000000c64ce3061f006973" 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=2a00:1450:4864:20::535; envelope-from=zero.tangptr@gmail.com; helo=mail-ed1-x535.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, FREEMAIL_FROM=0.001, HK_RANDOM_ENVFROM=0.001, HK_RANDOM_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham 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 @gmail.com) X-ZM-MESSAGEID: 1722936529191116600 Content-Transfer-Encoding: quoted-printable --000000000000c64ce3061f006973 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 VGhpcyB2aXJ0dWFsIFBDSUxlZWNoIGRldmljZSBhaW1zIHRvIGhlbHAgc2VjdXJpdHkgcmVzZWFy Y2hlcnMgYXR0YWNrIHRoZQpndWVzdCB2aWEgRE1BIGFuZCB0ZXN0IHRoZWlyIElPTU1VIGRlZmVu c2VzLgpUaGlzIGRldmljZSBpcyBpbnRlbmRlZCB0byBzdXBwb3J0IGFueSBzeXN0ZW1zIHdpdGgg UENJLCBidXQgSSBhbSBvbmx5IGFibGUKdG8gdGVzdCB4ODYtYmFzZWQgZ3Vlc3RzLgpGb3Igd2hh dCBQQ0lMZWVjaCBpcywgY2hlY2sgUENJTGVlY2ggR2l0SHViIHJlcG9zaXRvcnk6Cmh0dHBzOi8v Z2l0aHViLmNvbS91ZnJpc2svcGNpbGVlY2gKVGhlIFFFTVUtUENJTGVlY2ggcGx1Z2luIGlzIGN1 cnJlbnRseSBhd2FpdGluZyBtZXJnaW5nOgpodHRwczovL2dpdGh1Yi5jb20vdWZyaXNrL0xlZWNo Q29yZS1wbHVnaW5zL3B1bGwvMTAKClRoaXMgaXMgbXkgZmlyc3QgdGltZSBjb250cmlidXRpbmcg dG8gUUVNVSBhbmQgSSBhbSBzb3JyeSB0aGF0IEkgZm9yZ290IHRvCmluY2x1ZGUgYSAiW1BBVENI XSIgcHJlZml4IGluIHRoZSB0aXRsZSBmcm9tIG15IHByZXZpb3VzIGVtYWlsIGFuZCB0aGF0IEkK ZGlkbid0IGNjIHRvIHJlbGV2YW50IG1haW50YWluZXJzLgpJZiBuZWVkZWQsIGFkZCBteSBuYW1l IGFuZCBjb250YWN0IGluZm8gaW50byB0aGUgbWFpbnRhaW5lcidzIGxpc3QuCgpTaWduZWQtb2Zm LWJ5OiBaZXJvIFRhbmcgPHplcm8udGFuZ3B0ckBnbWFpbC5jb20+Ci0tLQogaHcvbWlzYy9LY29u ZmlnICAgICB8ICAgNSArKysrCiBody9taXNjL21lc29uLmJ1aWxkIHwgICAxICsKIGh3L21pc2Mv cGNpbGVlY2guYyAgfCAyOTEKKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrPQorKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKys9 CisrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKz0KKysKIDMgZmlsZXMgY2hhbmdlZCwgMjk3IGluc2VydGlvbnMo KykKCmRpZmYgLS1naXQgYS9ody9taXNjL0tjb25maWcgYi9ody9taXNjL0tjb25maWcKaW5kZXgg MWUwODc4NWI4My4uNmMzZWE3YmY3NCAxMDA2NDQKLS0tIGEvaHcvbWlzYy9LY29uZmlnCisrKyBi L2h3L21pc2MvS2NvbmZpZwpAQCAtMzAsNiArMzAsMTEgQEAgY29uZmlnIEVEVQogICAgIGRlZmF1 bHQgeSBpZiBURVNUX0RFVklDRVMKICAgICBkZXBlbmRzIG9uIFBDSSAmJiBNU0lfTk9OQlJPS0VO CgorY29uZmlnIFBDSUxFRUNICisgICAgYm9vbAorICAgIGRlZmF1bHQgeQorICAgIGRlcGVuZHMg b24gUENJCisKIGNvbmZpZyBQQ0E5NTUyCiAgICAgYm9vbAogICAgIGRlcGVuZHMgb24gSTJDCmRp ZmYgLS1naXQgYS9ody9taXNjL21lc29uLmJ1aWxkIGIvaHcvbWlzYy9tZXNvbi5idWlsZAppbmRl eCAyY2E4NzE3YmUyLi5lNzk5MzFiOWE2IDEwMDY0NAotLS0gYS9ody9taXNjL21lc29uLmJ1aWxk CisrKyBiL2h3L21pc2MvbWVzb24uYnVpbGQKQEAgLTEsNSArMSw2IEBACiBzeXN0ZW1fc3MuYWRk KHdoZW46ICdDT05GSUdfQVBQTEVTTUMnLCBpZl90cnVlOiBmaWxlcygnYXBwbGVzbWMuYycpKQog c3lzdGVtX3NzLmFkZCh3aGVuOiAnQ09ORklHX0VEVScsIGlmX3RydWU6IGZpbGVzKCdlZHUuYycp KQorc3lzdGVtX3NzLmFkZCh3aGVuOiAnQ09ORklHX1BDSUxFRUNIJywgaWZfdHJ1ZTogZmlsZXMo J3BjaWxlZWNoLmMnKSkKIHN5c3RlbV9zcy5hZGQod2hlbjogJ0NPTkZJR19GV19DRkdfRE1BJywg aWZfdHJ1ZTogZmlsZXMoJ3ZtY29yZWluZm8uYycpKQogc3lzdGVtX3NzLmFkZCh3aGVuOiAnQ09O RklHX0lTQV9ERUJVRycsIGlmX3RydWU6IGZpbGVzKCdkZWJ1Z2V4aXQuYycpKQogc3lzdGVtX3Nz LmFkZCh3aGVuOiAnQ09ORklHX0lTQV9URVNUREVWJywgaWZfdHJ1ZTogZmlsZXMoJ3BjLXRlc3Rk ZXYuYycpKQpkaWZmIC0tZ2l0IGEvaHcvbWlzYy9wY2lsZWVjaC5jIGIvaHcvbWlzYy9wY2lsZWVj aC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAuLjI1MmE1NzAxNjEKLS0t IC9kZXYvbnVsbAorKysgYi9ody9taXNjL3BjaWxlZWNoLmMKQEAgLTAsMCArMSwyOTEgQEAKKy8q CisgKiBRRU1VIFZpcnR1YWwgUENJTGVlY2ggRGV2aWNlCisgKgorICogQ29weXJpZ2h0IChjKSAy MDI0IFplcm8gVGFuZworICoKKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUg b2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhCisgKiBjb3B5IG9mIHRoaXMgc29m dHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiJTb2Z0d2FyZSIp LAorICogdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVk aW5nIHdpdGhvdXQKbGltaXRhdGlvbgorICogdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlm eSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCisgKiBhbmQvb3Igc2Vs bCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0 aGUKKyAqIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9s bG93aW5nIGNvbmRpdGlvbnM6CisgKgorICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5k IHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQKaW4KKyAqIGFsbCBjb3Bp ZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgorICoKKyAqIFRIRSBT T0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5E LCBFWFBSRVNTCk9SCisgKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRI RSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKKyAqIEZJVE5FU1MgRk9SIEEgUEFSVElD VUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMClRIRQor ICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwg REFNQUdFUyBPUiBPVEhFUgorICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBD T05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcKKyAqIEZST00sIE9VVCBPRiBPUiBJ TiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIKKyAqIERF QUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KKyAqLworCisjaW5jbHVkZSAicWVtdS9vc2RlcC5oIgor I2luY2x1ZGUgInFlbXUvdW5pdHMuaCIKKyNpbmNsdWRlICJody9wY2kvcGNpLmgiCisjaW5jbHVk ZSAiaHcvaHcuaCIKKyNpbmNsdWRlICJody9wY2kvbXNpLmgiCisjaW5jbHVkZSAicWVtdS90aW1l ci5oIgorI2luY2x1ZGUgImh3L3FkZXYtcHJvcGVydGllcy5oIgorI2luY2x1ZGUgImh3L3FkZXYt cHJvcGVydGllcy1zeXN0ZW0uaCIKKyNpbmNsdWRlICJxb20vb2JqZWN0LmgiCisjaW5jbHVkZSAi cWVtdS9tYWluLWxvb3AuaCIgLyogaW90aHJlYWQgbXV0ZXggKi8KKyNpbmNsdWRlICJxZW11L21v ZHVsZS5oIgorI2luY2x1ZGUgInFhcGkvdmlzaXRvci5oIgorCisjZGVmaW5lIFRZUEVfUENJTEVF Q0hfREVWSUNFICJwY2lsZWVjaCIKKworc3RydWN0IExlZWNoUmVxdWVzdEhlYWRlciB7CisgICAg dWludDhfdCBlbmRpYW5uZXNzOyAvKiAwIC0gTGl0dGxlLCAxIC0gQmlnICovCisgICAgdWludDhf dCBjb21tYW5kOyAgICAvKiAwIC0gUmVhZCwgMSAtIFdyaXRlICovCisgICAgdWludDhfdCByZXNl cnZlZFs2XTsKKyAgICAvKiBWYXJpYWJsZSBFbmRpYW5uZXNzICovCisgICAgdWludDY0X3QgYWRk cmVzczsKKyAgICB1aW50NjRfdCBsZW5ndGg7Cit9OworCitzdHJ1Y3QgTGVlY2hSZXNwb25zZUhl YWRlciB7CisgICAgdWludDhfdCBlbmRpYW5uZXNzOyAvKiAwIC0gTGl0dGxlLCAxIC0gQmlnICov CisgICAgdWludDhfdCByZXNlcnZlZFszXTsKKyAgICBNZW1UeFJlc3VsdCByZXN1bHQ7CisgICAg dWludDY0X3QgbGVuZ3RoOyAgICAvKiBJbmRpY2F0ZXMgbGVuZ3RoIG9mIGRhdGEgZm9sbG93ZWQg YnkgaGVhZGVyICovCit9OworCisvKiBWZXJpZnkgdGhlIGhlYWRlciBsZW5ndGggKi8KK3N0YXRp Y19hc3NlcnQoc2l6ZW9mKHN0cnVjdCBMZWVjaFJlcXVlc3RIZWFkZXIpID0zRD0zRCAyNCk7Citz dGF0aWNfYXNzZXJ0KHNpemVvZihzdHJ1Y3QgTGVlY2hSZXNwb25zZUhlYWRlcikgPTNEPTNEIDE2 KTsKKworc3RydWN0IFBjaUxlZWNoU3RhdGUgeworICAgIC8qIEludGVybmFsIFN0YXRlICovCisg ICAgUENJRGV2aWNlIGRldmljZTsKKyAgICBRZW11VGhyZWFkIHRocmVhZDsKKyAgICBRZW11TXV0 ZXggbXV0ZXg7CisgICAgYm9vbCBlbmRpYW5uZXNzOworICAgIGJvb2wgc3RvcHBpbmc7CisgICAg LyogQ29tbXVuaWNhdGlvbiAqLworICAgIGNoYXIgKmhvc3Q7CisgICAgdWludDE2X3QgcG9ydDsK KyAgICBpbnQgc29ja2ZkOworfTsKKwordHlwZWRlZiBzdHJ1Y3QgTGVlY2hSZXF1ZXN0SGVhZGVy IExlZWNoUmVxdWVzdEhlYWRlcjsKK3R5cGVkZWYgc3RydWN0IFBjaUxlZWNoU3RhdGUgUGNpTGVl Y2hTdGF0ZTsKKworREVDTEFSRV9JTlNUQU5DRV9DSEVDS0VSKFBjaUxlZWNoU3RhdGUsIFBDSUxF RUNILCBUWVBFX1BDSUxFRUNIX0RFVklDRSkKKworc3RhdGljIHZvaWQgcGNpX2xlZWNoX3Byb2Nl c3Nfd3JpdGVfcmVxdWVzdChQY2lMZWVjaFN0YXRlICpzdGF0ZSwKKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgTGVlY2hSZXF1ZXN0SGVhZGVyICpyZXF1ZXN0LAor ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5jb21pbmcp Cit7CisgICAgY2hhciBidWZmWzEwMjRdOworICAgIGZvciAodWludDY0X3QgaSA9M0QgMDsgaSA8 IHJlcXVlc3QtPmxlbmd0aDsgaSArPTNEIHNpemVvZihidWZmKSkgeworICAgICAgICBzdHJ1Y3Qg TGVlY2hSZXNwb25zZUhlYWRlciByZXNwb25zZSA9M0QgeyAwIH07CisgICAgICAgIGNoYXIqIHJl c3BvbnNlX2J1ZmZlciA9M0QgKGNoYXIgKikmcmVzcG9uc2U7CisgICAgICAgIGNvbnN0IHVpbnQ2 NF90IHdyaXRlbGVuID0zRCAocmVxdWVzdC0+bGVuZ3RoIC0gaSkgPD0zRCBzaXplb2YoYnVmZj0K KSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZXF1ZXN0LT5s ZW5ndGggLSBpKSA6CnNpemVvZihidWZmKTsKKyAgICAgICAgc3NpemVfdCByZWN2bGVuID0zRCAw LCBzZW5kbGVuID0zRCAwOworICAgICAgICB3aGlsZSAocmVjdmxlbiA8IHdyaXRlbGVuKSB7Cisg ICAgICAgICAgICByZWN2bGVuICs9M0QgcmVjdihpbmNvbWluZywgJmJ1ZmZbcmVjdmxlbl0sIHdy aXRlbGVuIC0gcmVjdmxlbiwKMCk7CisgICAgICAgIH0KKyAgICAgICAgcmVzcG9uc2UuZW5kaWFu bmVzcyA9M0Qgc3RhdGUtPmVuZGlhbm5lc3M7CisgICAgICAgIHJlc3BvbnNlLnJlc3VsdCA9M0Qg cGNpX2RtYV93cml0ZSgmc3RhdGUtPmRldmljZSwgcmVxdWVzdC0+YWRkcmVzcz0KICsKaSwKKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IGJ1ZmYsCndyaXRlbGVuKTsKKyAgICAgICAgaWYgKHJlc3BvbnNlLnJlc3VsdCkgeworICAgICAg ICAgICAgcHJpbnRmKCJQQ0lMZWVjaDogQWRkcmVzcyAweCVsWCBXcml0ZSBFcnJvciEgTWVtVHhS ZXN1bHQ6CjB4JVhcbiIsCisgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPmFkZHJlc3MgKyBp LCByZXNwb25zZS5yZXN1bHQpOworICAgICAgICB9CisgICAgICAgIHJlc3BvbnNlLmxlbmd0aCA9 M0QgMDsKKyAgICAgICAgd2hpbGUgKHNlbmRsZW4gPCBzaXplb2Yoc3RydWN0IExlZWNoUmVzcG9u c2VIZWFkZXIpKSB7CisgICAgICAgICAgICBzZW5kbGVuICs9M0Qgc2VuZChpbmNvbWluZywgJnJl c3BvbnNlX2J1ZmZlcltzZW5kbGVuXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXpl b2Yoc3RydWN0IExlZWNoUmVzcG9uc2VIZWFkZXIpIC0gc2VuZGxlbiwKMCk7CisgICAgICAgIH0K KyAgICB9Cit9CisKK3N0YXRpYyB2b2lkIHBjaV9sZWVjaF9wcm9jZXNzX3JlYWRfcmVxdWVzdChQ Y2lMZWVjaFN0YXRlICpzdGF0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgTGVlY2hSZXF1ZXN0SGVhZGVyICpyZXF1ZXN0LAorICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5jb21pbmcpCit7CisgICAgY2hhciBidWZm WzEwMjRdOworICAgIGZvciAodWludDY0X3QgaSA9M0QgMDsgaSA8IHJlcXVlc3QtPmxlbmd0aDsg aSArPTNEIHNpemVvZihidWZmKSkgeworICAgICAgICBzdHJ1Y3QgTGVlY2hSZXNwb25zZUhlYWRl ciByZXNwb25zZSA9M0QgeyAwIH07CisgICAgICAgIGNoYXIqIHJlc3BvbnNlX2J1ZmZlciA9M0Qg KGNoYXIgKikmcmVzcG9uc2U7CisgICAgICAgIGNvbnN0IHVpbnQ2NF90IHJlYWRsZW4gPTNEIChy ZXF1ZXN0LT5sZW5ndGggLSBpKSA8PTNEIHNpemVvZihidWZmKT0KID8KKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIChyZXF1ZXN0LT5sZW5ndGggLSBpKSA6IHNpemVvZihidWZm KTsKKyAgICAgICAgc3NpemVfdCBzZW5kbGVuID0zRCAwOworICAgICAgICByZXNwb25zZS5lbmRp YW5uZXNzID0zRCBzdGF0ZS0+ZW5kaWFubmVzczsKKyAgICAgICAgcmVzcG9uc2UucmVzdWx0ID0z RCBwY2lfZG1hX3JlYWQoJnN0YXRlLT5kZXZpY2UsIHJlcXVlc3QtPmFkZHJlc3MgKwppLAorICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg YnVmZiwgcmVhZGxlbik7CisgICAgICAgIGlmIChyZXNwb25zZS5yZXN1bHQpIHsKKyAgICAgICAg ICAgIHByaW50ZigiUENJTGVlY2g6IEFkZHJlc3MgMHglbFggUmVhZCBFcnJvciEgTWVtVHhSZXN1 bHQ6CjB4JVhcbiIsCisgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPmFkZHJlc3MgKyBpLCBy ZXNwb25zZS5yZXN1bHQpOworICAgICAgICB9CisgICAgICAgIHJlc3BvbnNlLmxlbmd0aCA9M0Qg KHJlcXVlc3QtPmVuZGlhbm5lc3MgIT0zRCBzdGF0ZS0+ZW5kaWFubmVzcykgPworICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBic3dhcDY0KHJlYWRsZW4pIDogcmVh ZGxlbjsKKyAgICAgICAgd2hpbGUgKHNlbmRsZW4gPCBzaXplb2Yoc3RydWN0IExlZWNoUmVzcG9u c2VIZWFkZXIpKSB7CisgICAgICAgICAgICBzZW5kbGVuICs9M0Qgc2VuZChpbmNvbWluZywgJnJl c3BvbnNlX2J1ZmZlcltzZW5kbGVuXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXpl b2Yoc3RydWN0IExlZWNoUmVzcG9uc2VIZWFkZXIpIC0gc2VuZGxlbiwKMCk7CisgICAgICAgIH0K KyAgICAgICAgc2VuZGxlbiA9M0QgMDsKKyAgICAgICAgd2hpbGUgKHNlbmRsZW4gPCByZWFkbGVu KSB7CisgICAgICAgICAgICBzZW5kbGVuICs9M0Qgc2VuZChpbmNvbWluZywgJmJ1ZmZbc2VuZGxl bl0sIHJlYWRsZW4gLSBzZW5kbGVuLAowKTsKKyAgICAgICAgfQorICAgIH0KK30KKworc3RhdGlj IHZvaWQgKnBjaV9sZWVjaF93b3JrZXJfdGhyZWFkKHZvaWQgKm9wYXF1ZSkKK3sKKyAgICBQY2lM ZWVjaFN0YXRlICpzdGF0ZSA9M0QgUENJTEVFQ0gob3BhcXVlKTsKKyAgICB3aGlsZSAoMSkgewor ICAgICAgICBMZWVjaFJlcXVlc3RIZWFkZXIgcmVxdWVzdDsKKyAgICAgICAgY2hhciAqcmVxdWVz dF9idWZmZXIgPTNEIChjaGFyICopJnJlcXVlc3Q7CisgICAgICAgIHNzaXplX3QgcmVjZWl2ZWQg PTNEIDA7CisgICAgICAgIGludCBpbmNvbWluZzsKKyAgICAgICAgc3RydWN0IHNvY2thZGRyIGFk ZHJlc3M7CisgICAgICAgIHNvY2tsZW5fdCBhZGRybGVuOworICAgICAgICAvKiBDaGVjayBpZiB3 ZSBhcmUgc3RvcHBpbmcuICovCisgICAgICAgIHFlbXVfbXV0ZXhfbG9jaygmc3RhdGUtPm11dGV4 KTsKKyAgICAgICAgaWYgKHN0YXRlLT5zdG9wcGluZykgeworICAgICAgICAgICAgcWVtdV9tdXRl eF91bmxvY2soJnN0YXRlLT5tdXRleCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQor ICAgICAgICBxZW11X211dGV4X3VubG9jaygmc3RhdGUtPm11dGV4KTsKKyAgICAgICAgLyogQWNj ZXB0IFBDSUxlZWNoIHJlcXVlc3RzLiAqLworICAgICAgICAvKiBVc2UgSFRUUDEuMC1saWtlIHBy b3RvY29sIGZvciBzaW1wbGljaXR5LiAqLworICAgICAgICBpbmNvbWluZyA9M0QgYWNjZXB0KHN0 YXRlLT5zb2NrZmQsICZhZGRyZXNzLCAmYWRkcmxlbik7CisgICAgICAgIGlmIChpbmNvbWluZyA8 IDApIHsKKyAgICAgICAgICAgIHB1dHMoIldBUk5JTkc6IEZhaWxlZCB0byBhY2NlcHQgc29ja2V0 IGZvciBQQ0lMZWVjaCEgU2tpcHBpbmcgIgorICAgICAgICAgICAgICAgICAiUmVxdWVzdC4uLlxu Iik7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICAvKiBHZXQgUENJ TGVlY2ggcmVxdWVzdHMuICovCisgICAgICAgIHdoaWxlIChyZWNlaXZlZCA8IHNpemVvZihMZWVj aFJlcXVlc3RIZWFkZXIpKSB7CisgICAgICAgICAgICByZWNlaXZlZCArPTNEIHJlY3YoaW5jb21p bmcsICZyZXF1ZXN0X2J1ZmZlcltyZWNlaXZlZF0sCisgICAgICAgICAgICAgICAgICAgICAgICAg ICAgc2l6ZW9mKExlZWNoUmVxdWVzdEhlYWRlcikgLSByZWNlaXZlZCwgMCk7CisgICAgICAgIH0K KyAgICAgICAgLyogU3dhcCBlbmRpYW5uZXNzLiAqLworICAgICAgICBpZiAocmVxdWVzdC5lbmRp YW5uZXNzICE9M0Qgc3RhdGUtPmVuZGlhbm5lc3MpIHsKKyAgICAgICAgICAgIHJlcXVlc3QuYWRk cmVzcyA9M0QgYnN3YXA2NChyZXF1ZXN0LmFkZHJlc3MpOworICAgICAgICAgICAgcmVxdWVzdC5s ZW5ndGggPTNEIGJzd2FwNjQocmVxdWVzdC5sZW5ndGgpOworICAgICAgICB9CisgICAgICAgIC8q IFByb2Nlc3MgUENJTGVlY2ggcmVxdWVzdHMuICovCisgICAgICAgIHFlbXVfbXV0ZXhfbG9jaygm c3RhdGUtPm11dGV4KTsKKyAgICAgICAgaWYgKHJlcXVlc3QuY29tbWFuZCkgeworICAgICAgICAg ICAgcGNpX2xlZWNoX3Byb2Nlc3Nfd3JpdGVfcmVxdWVzdChzdGF0ZSwgJnJlcXVlc3QsIGluY29t aW5nKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHBjaV9sZWVjaF9wcm9jZXNzX3Jl YWRfcmVxdWVzdChzdGF0ZSwgJnJlcXVlc3QsIGluY29taW5nKTsKKyAgICAgICAgfQorICAgICAg ICBxZW11X211dGV4X3VubG9jaygmc3RhdGUtPm11dGV4KTsKKyAgICAgICAgY2xvc2UoaW5jb21p bmcpOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIHZvaWQgcGNpX2xlZWNo X3JlYWxpemUoUENJRGV2aWNlICpwZGV2LCBFcnJvciAqKmVycnApCit7CisgICAgUGNpTGVlY2hT dGF0ZSAqc3RhdGUgPTNEIFBDSUxFRUNIKHBkZXYpOworICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBz b2NrX2FkZHI7CisgICAgY2hhciBob3N0X2lwWzE2XTsKKyAgICBzdHJ1Y3QgaG9zdGVudCAqaGUg PTNEIGdldGhvc3RieW5hbWUoc3RhdGUtPmhvc3QpOworICAgIGlmIChoZSA9M0Q9M0QgTlVMTCkg eworICAgICAgICBwdXRzKCJnZXRob3N0YnluYW1lIGZhaWxlZCEiKTsKKyAgICAgICAgZXhpdChF WElUX0ZBSUxVUkUpOworICAgIH0KKyAgICAvKiBJbml0aWFsaXplIHRoZSBzb2NrZXQgZm9yIFBD SUxlZWNoLiAqLworICAgIHN0YXRlLT5zb2NrZmQgPTNEIHNvY2tldChBRl9JTkVULCBTT0NLX1NU UkVBTSwgMCk7CisgICAgaWYgKHN0YXRlLT5zb2NrZmQgPCAwKSB7CisgICAgICAgIHB1dHMoIkZh aWxlZCB0byBpbml0aWFsaXplIHNvY2tldCBmb3IgUENJTGVlY2ghIik7CisgICAgICAgIGV4aXQo RVhJVF9GQUlMVVJFKTsKKyAgICB9CisgICAgc29ja19hZGRyLnNpbl9mYW1pbHkgPTNEIEFGX0lO RVQ7CisgICAgc29ja19hZGRyLnNpbl9hZGRyID0zRCAqKHN0cnVjdCBpbl9hZGRyICopaGUtPmhf YWRkcjsKKyAgICBzb2NrX2FkZHIuc2luX3BvcnQgPTNEIGh0b25zKHN0YXRlLT5wb3J0KTsKKyAg ICBpbmV0X250b3AoQUZfSU5FVCwgJnNvY2tfYWRkci5zaW5fYWRkciwgaG9zdF9pcCwgc2l6ZW9m KGhvc3RfaXApKTsKKyAgICBpZiAoYmluZChzdGF0ZS0+c29ja2ZkLCAoc3RydWN0IHNvY2thZGRy ICopJnNvY2tfYWRkciwKc2l6ZW9mKHNvY2tfYWRkcikpCisgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwgMCkgeworICAg ICAgICBwdXRzKCJGYWlsZWQgdG8gYmluZCBzb2NrZXQgZm9yIFBDSUxlZWNoISIpOworICAgICAg ICBjbG9zZShzdGF0ZS0+c29ja2ZkKTsKKyAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOworICAg IH0KKyAgICBpZiAobGlzdGVuKHN0YXRlLT5zb2NrZmQsIDEwKSA8IDApIHsKKyAgICAgICAgcHV0 cygiRmFpbGVkIHRvIGxpc3RlbiB0byBzb2NrZXQgZm9yIFBDSUxlZWNoISIpOworICAgICAgICBj bG9zZShzdGF0ZS0+c29ja2ZkKTsKKyAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOworICAgIH0K KyAgICBwcmludGYoIklORk86IFBDSUxlZWNoIGlzIGxpc3RlbmluZyBvbiAlczoldS4uLlxuIiwg aG9zdF9pcCwKc3RhdGUtPnBvcnQpOworICAgIC8qIEluaXRpYWxpemUgdGhlIHRocmVhZCBmb3Ig UENJTGVlY2guICovCisgICAgcWVtdV9tdXRleF9pbml0KCZzdGF0ZS0+bXV0ZXgpOworICAgIHFl bXVfdGhyZWFkX2NyZWF0ZSgmc3RhdGUtPnRocmVhZCwgInBjaWxlZWNoIiwgcGNpX2xlZWNoX3dv cmtlcl90aHJlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHN0YXRlLCBRRU1VX1RIUkVBRF9KT0lOQUJMRSk7Cit9CisKK3N0YXRpYyB2b2lkIHBjaV9sZWVj aF9maW5hbGl6ZShQQ0lEZXZpY2UgKnBkZXYpCit7CisgICAgUGNpTGVlY2hTdGF0ZSAqc3RhdGUg PTNEIFBDSUxFRUNIKHBkZXYpOworICAgIHB1dHMoIlN0b3BwaW5nIFBDSUxlZWNoIFdvcmtlci4u LiIpOworICAgIHFlbXVfbXV0ZXhfbG9jaygmc3RhdGUtPm11dGV4KTsKKyAgICBzdGF0ZS0+c3Rv cHBpbmcgPTNEIHRydWU7CisgICAgcWVtdV9tdXRleF91bmxvY2soJnN0YXRlLT5tdXRleCk7Cisg ICAgY2xvc2Uoc3RhdGUtPnNvY2tmZCk7CisgICAgcWVtdV90aHJlYWRfam9pbigmc3RhdGUtPnRo cmVhZCk7CisgICAgcWVtdV9tdXRleF9kZXN0cm95KCZzdGF0ZS0+bXV0ZXgpOworfQorCitjaGFy IHBjaV9sZWVjaF9kZWZhdWx0X2hvc3RbXSA9M0QgIjAuMC4wLjAiOworCitzdGF0aWMgdm9pZCBw Y2lfbGVlY2hfaW5zdGFuY2VfaW5pdChPYmplY3QgKm9iaikKK3sKKyAgICBpbnQgeCA9M0QgMTsK KyAgICBjaGFyKiB5ID0zRCAoY2hhciAqKSZ4OworICAgIFBjaUxlZWNoU3RhdGUgKnN0YXRlID0z RCBQQ0lMRUVDSChvYmopOworICAgIC8qIFFFTVUncyBTdHJpbmctUHJvcGVydHkgY2FuJ3Qgc3Bl Y2lmeSBkZWZhdWx0IHZhbHVlLiAqLworICAgIC8qIFNvIHdlIGhhdmUgdG8gc2V0IHRoZSBkZWZh dWx0IG9uIG91ciBvd24uICovCisgICAgaWYgKHN0YXRlLT5ob3N0ID0zRD0zRCBOVUxMKSB7Cisg ICAgICAgIHN0YXRlLT5ob3N0ID0zRCBwY2lfbGVlY2hfZGVmYXVsdF9ob3N0OworICAgIH0KKyAg ICAvKiBTYXZlIE91ciBFbmRpYW5uZXNzLiAqLworICAgIHN0YXRlLT5lbmRpYW5uZXNzID0zRCAo KnkgPTNEPTNEIDApOworfQorCitzdGF0aWMgUHJvcGVydHkgbGVlY2hfcHJvcGVydGllc1tdID0z RCB7CisgICAgREVGSU5FX1BST1BfVUlOVDE2KCJwb3J0IiwgUGNpTGVlY2hTdGF0ZSwgcG9ydCwg Njc4OSksCisgICAgREVGSU5FX1BST1BfU1RSSU5HKCJob3N0IiwgUGNpTGVlY2hTdGF0ZSwgaG9z dCksCisgICAgREVGSU5FX1BST1BfRU5EX09GX0xJU1QoKSwKK307CisKK3N0YXRpYyB2b2lkIHBj aV9sZWVjaF9jbGFzc19pbml0KE9iamVjdENsYXNzICpjbGFzcywgdm9pZCAqZGF0YSkKK3sKKyAg ICBEZXZpY2VDbGFzcyAqZGMgPTNEIERFVklDRV9DTEFTUyhjbGFzcyk7CisgICAgUENJRGV2aWNl Q2xhc3MgKmsgPTNEIFBDSV9ERVZJQ0VfQ0xBU1MoY2xhc3MpOworICAgIGstPnJlYWxpemUgPTNE IHBjaV9sZWVjaF9yZWFsaXplOworICAgIGstPmV4aXQgPTNEIHBjaV9sZWVjaF9maW5hbGl6ZTsK KyAgICAvKiBDaGFuZ2UgdGhlIFZlbmRvci9EZXZpY2UgSUQgdG8geW91ciBmYXZvci4gKi8KKyAg ICAvKiBUaGVzZSBhcmUgdGhlIGRlZmF1bHQgdmFsdWVzIGZyb20gUENJTGVlY2gtRlBHQS4gKi8K KyAgICBrLT52ZW5kb3JfaWQgPTNEIFBDSV9WRU5ET1JfSURfWElMSU5YOworICAgIGstPmRldmlj ZV9pZCA9M0QgMHgwNjY2OworICAgIGstPnJldmlzaW9uID0zRCAwOworICAgIGstPmNsYXNzX2lk ID0zRCBQQ0lfQ0xBU1NfTkVUV09SS19FVEhFUk5FVDsKKyAgICBkZXZpY2VfY2xhc3Nfc2V0X3By b3BzKGRjLCBsZWVjaF9wcm9wZXJ0aWVzKTsKKyAgICBzZXRfYml0KERFVklDRV9DQVRFR09SWV9N SVNDLCBkYy0+Y2F0ZWdvcmllcyk7Cit9CisKK3N0YXRpYyB2b2lkIHBjaV9sZWVjaF9yZWdpc3Rl cl90eXBlcyh2b2lkKQoreworICAgIHN0YXRpYyBJbnRlcmZhY2VJbmZvIGludGVyZmFjZXNbXSA9 M0QgeworICAgICAgICB7SU5URVJGQUNFX0NPTlZFTlRJT05BTF9QQ0lfREVWSUNFfSwKKyAgICAg ICAge30sCisgICAgfTsKKyAgICBzdGF0aWMgY29uc3QgVHlwZUluZm8gbGVlY2hfaW5mbyA9M0Qg eworICAgICAgICAubmFtZSA9M0QgVFlQRV9QQ0lMRUVDSF9ERVZJQ0UsCisgICAgICAgIC5wYXJl bnQgPTNEIFRZUEVfUENJX0RFVklDRSwKKyAgICAgICAgLmluc3RhbmNlX3NpemUgPTNEIHNpemVv ZihQY2lMZWVjaFN0YXRlKSwKKyAgICAgICAgLmluc3RhbmNlX2luaXQgPTNEIHBjaV9sZWVjaF9p bnN0YW5jZV9pbml0LAorICAgICAgICAuY2xhc3NfaW5pdCA9M0QgcGNpX2xlZWNoX2NsYXNzX2lu aXQsCisgICAgICAgIC5pbnRlcmZhY2VzID0zRCBpbnRlcmZhY2VzLAorICAgIH07CisgICAgdHlw ZV9yZWdpc3Rlcl9zdGF0aWMoJmxlZWNoX2luZm8pOworfQorCit0eXBlX2luaXQocGNpX2xlZWNo X3JlZ2lzdGVyX3R5cGVzKQ== --000000000000c64ce3061f006973 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
This virtual PCILeec= h device aims to help security researchers attack the guest via DMA and tes= t their IOMMU defenses.
T= his device is intended to support any systems with PCI, but I am only able = to test x86-based guests.
For what PCILeech is, check PCILeech GitHub repository:=C2=A0https://github.com/ufrisk/pcileech=
The QEMU-PCILeech plugin is currently awaiting merging:=C2= =A0https://= github.com/ufrisk/LeechCore-plugins/pull/10

Th= is is my first time contributing to QEMU and I am sorry that I forgot to in= clude a "[PATCH]" prefix in the title from my previous email and = that I didn't cc to relevant maintainers.
If needed, add my n= ame and contact info into the maintainer's list.

Signed-off-by: Zero Tang <z= ero.tangptr@gmail.com>
---
=C2=A0hw/misc/Kconfig =C2=A0 =C2=A0 | =C2=A0= 5 ++++
=C2=A0hw/misc/meson.build | =C2=A0 1 +
=C2=A0hw/misc/pcileech= .c =C2=A0| 291 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++
=C2=A03 files changed, 297 insertions(+)

diff -= -git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 1e08785b83..6c3ea7bf74 10= 0644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -30,6 +30,11 @= @ config EDU
=C2=A0 =C2=A0 =C2=A0default y if TEST_DEVICES
=C2=A0 =C2= =A0 =C2=A0depends on PCI && MSI_NONBROKEN
=C2=A0
+config PCIL= EECH
+ =C2=A0 =C2=A0bool
+ =C2=A0 =C2=A0default y
+ =C2=A0 =C2=A0d= epends on PCI
+
=C2=A0config PCA9552
=C2=A0 =C2=A0 =C2=A0bool
= =C2=A0 =C2=A0 =C2=A0depends on I2C
diff --git a/hw/misc/meson.build b/hw= /misc/meson.build
index 2ca8717be2..e79931b9a6 100644
--- a/hw/misc/m= eson.build
+++ b/hw/misc/meson.build
@@ -1,5 +1,6 @@
=C2=A0system_= ss.add(when: 'CONFIG_APPLESMC', if_true: files('applesmc.c'= ))
=C2=A0system_ss.add(when: 'CONFIG_EDU', if_true: files('e= du.c'))
+system_ss.add(when: 'CONFIG_PCILEECH', if_true: fil= es('pcileech.c'))
=C2=A0system_ss.add(when: 'CONFIG_FW_CFG_D= MA', if_true: files('vmcoreinfo.c'))
=C2=A0system_ss.add(whe= n: 'CONFIG_ISA_DEBUG', if_true: files('debugexit.c'))
= =C2=A0system_ss.add(when: 'CONFIG_ISA_TESTDEV', if_true: files('= ;pc-testdev.c'))
diff --git a/hw/misc/pcileech.c b/hw/misc/pcileech.= c
new file mode 100644
index 0000000000..252a570161
--- /dev/null<= br>+++ b/hw/misc/pcileech.c
@@ -0,0 +1,291 @@
+/*
+ * QEMU Virtual= PCILeech Device
+ *
+ * Copyright (c) 2024 Zero Tang
+ *
+ * P= ermission is hereby granted, free of charge, to any person obtaining a
+= * copy of this software and associated documentation files (the "Soft= ware"),
+ * to deal in the Software without restriction, including = without limitation
+ * the rights to use, copy, modify, merge, publish, = distribute, sublicense,
+ * and/or sell copies of the Software, and to p= ermit persons to whom the
+ * Software is furnished to do so, subject to= the following conditions:
+ *
+ * The above copyright notice and thi= s permission notice shall be included in
+ * all copies or substantial p= ortions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS= ", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING = BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A = PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHOR= S OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIA= BILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *= FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ *= DEALINGS IN THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h&quo= t;
+#include "qemu/units.h"
+#include "hw/pci/pci.h&qu= ot;
+#include "hw/hw.h"
+#include "hw/pci/msi.h"<= br>+#include "qemu/timer.h"
+#include "hw/qdev-properties= .h"
+#include "hw/qdev-properties-system.h"
+#include = "qom/object.h"
+#include "qemu/main-loop.h" /* iothr= ead mutex */
+#include "qemu/module.h"
+#include "qapi= /visitor.h"
+
+#define TYPE_PCILEECH_DEVICE "pcileech"=
+
+struct LeechRequestHeader {
+ =C2=A0 =C2=A0uint8_t endianness;= /* 0 - Little, 1 - Big */
+ =C2=A0 =C2=A0uint8_t command; =C2=A0 =C2=A0= /* 0 - Read, 1 - Write */
+ =C2=A0 =C2=A0uint8_t reserved[6];
+ =C2= =A0 =C2=A0/* Variable Endianness */
+ =C2=A0 =C2=A0uint64_t address;
= + =C2=A0 =C2=A0uint64_t length;
+};
+
+struct LeechResponseHeader = {
+ =C2=A0 =C2=A0uint8_t endianness; /* 0 - Little, 1 - Big */
+ =C2= =A0 =C2=A0uint8_t reserved[3];
+ =C2=A0 =C2=A0MemTxResult result;
+ = =C2=A0 =C2=A0uint64_t length; =C2=A0 =C2=A0/* Indicates length of data foll= owed by header */
+};
+
+/* Verify the header length */
+static= _assert(sizeof(struct LeechRequestHeader) =3D=3D 24);
+static_assert(siz= eof(struct LeechResponseHeader) =3D=3D 16);
+
+struct PciLeechState {=
+ =C2=A0 =C2=A0/* Internal State */
+ =C2=A0 =C2=A0PCIDevice device;=
+ =C2=A0 =C2=A0QemuThread thread;
+ =C2=A0 =C2=A0QemuMutex mutex;+ =C2=A0 =C2=A0bool endianness;
+ =C2=A0 =C2=A0bool stopping;
+ =C2= =A0 =C2=A0/* Communication */
+ =C2=A0 =C2=A0char *host;
+ =C2=A0 =C2= =A0uint16_t port;
+ =C2=A0 =C2=A0int sockfd;
+};
+
+typedef str= uct LeechRequestHeader LeechRequestHeader;
+typedef struct PciLeechState= PciLeechState;
+
+DECLARE_INSTANCE_CHECKER(PciLeechState, PCILEECH, = TYPE_PCILEECH_DEVICE)
+
+static void pci_leech_process_write_request(= PciLeechState *state,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0LeechRequestHeader *request,
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int in= coming)
+{
+ =C2=A0 =C2=A0char buff[1024];
+ =C2=A0 =C2=A0for (uin= t64_t i =3D 0; i < request->length; i +=3D sizeof(buff)) {
+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0struct LeechResponseHeader response =3D { 0 };
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0char* response_buffer =3D (char *)&response= ;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0const uint64_t writelen =3D (request->= length - i) <=3D sizeof(buff) ?
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (request->length - i) : sizeof(buff);+ =C2=A0 =C2=A0 =C2=A0 =C2=A0ssize_t recvlen =3D 0, sendlen =3D 0;
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0while (recvlen < writelen) {
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0recvlen +=3D recv(incoming, &buff[recvle= n], writelen - recvlen, 0);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0response.endianness =3D state->endianness;
+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0response.result =3D pci_dma_write(&state->de= vice, request->address + i,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0buff, writelen);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0if= (response.result) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf(&= quot;PCILeech: Address 0x%lX Write Error! MemTxResult: 0x%X\n",
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reques= t->address + i, response.result);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0response.length =3D 0;
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0while (sendlen < sizeof(struct LeechResponseHeader)) {
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sendlen +=3D send(incoming, &r= esponse_buffer[sendlen],
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof(struct LeechResp= onseHeader) - sendlen, 0);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 = =C2=A0}
+}
+
+static void pci_leech_process_read_request(PciLeechS= tate *state,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0LeechRequestHeader *request,
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int incoming)=
+{
+ =C2=A0 =C2=A0char buff[1024];
+ =C2=A0 =C2=A0for (uint64_t i= =3D 0; i < request->length; i +=3D sizeof(buff)) {
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0struct LeechResponseHeader response =3D { 0 };
+ =C2=A0= =C2=A0 =C2=A0 =C2=A0char* response_buffer =3D (char *)&response;
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0const uint64_t readlen =3D (request->length -= i) <=3D sizeof(buff) ?
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(request->length - i) : sizeof(buff);
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0ssize_t sendlen =3D 0;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0response.e= ndianness =3D state->endianness;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0respons= e.result =3D pci_dma_read(&state->device, request->address + i,+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0buff, rea= dlen);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0if (response.result) {
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("PCILeech: Address 0x%lX Read= Error! MemTxResult: 0x%X\n",
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0request->address + i, response.result)= ;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0respons= e.length =3D (request->endianness !=3D state->endianness) ?
+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0bswap64(readlen) : readlen;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0while (sendl= en < sizeof(struct LeechResponseHeader)) {
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0sendlen +=3D send(incoming, &response_buffer[sendlen],=
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof(struct LeechResponseHeader) - sendlen, 0= );
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0sendle= n =3D 0;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0while (sendlen < readlen) {
= + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sendlen +=3D send(incoming, &= ;buff[sendlen], readlen - sendlen, 0);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}+ =C2=A0 =C2=A0}
+}
+
+static void *pci_leech_worker_thread(void = *opaque)
+{
+ =C2=A0 =C2=A0PciLeechState *state =3D PCILEECH(opaque);=
+ =C2=A0 =C2=A0while (1) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0LeechRequest= Header request;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0char *request_buffer =3D (c= har *)&request;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0ssize_t received =3D 0;=
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0int incoming;
+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0struct sockaddr address;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0socklen_t ad= drlen;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Check if we are stopping. */
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_mutex_lock(&state->mutex);
+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0if (state->stopping) {
+ =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0qemu_mutex_unlock(&state->mutex);
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}<= br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_mutex_unlock(&state->mutex);+ =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Accept PCILeech requests. */
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0/* Use HTTP1.0-like protocol for simplicity. */
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0incoming =3D accept(state->sockfd, &addre= ss, &addrlen);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0if (incoming < 0) {+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0puts("WARNING: Failed to = accept socket for PCILeech! Skipping "
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Request...\n");
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0continue;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}<= br>+ =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Get PCILeech requests. */
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0while (received < sizeof(LeechRequestHeader)) {
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0received +=3D recv(incoming, &= ;request_buffer[received],
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof(LeechRequestH= eader) - received, 0);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0= =C2=A0 =C2=A0/* Swap endianness. */
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0if (re= quest.endianness !=3D state->endianness) {
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0request.address =3D bswap64(request.address);
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0request.length =3D bswap64(request.length= );
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Pro= cess PCILeech requests. */
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_mutex_lock(= &state->mutex);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0if (request.command)= {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pci_leech_process_write_re= quest(state, &request, incoming);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0} els= e {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pci_leech_process_read_re= quest(state, &request, incoming);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
= + =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_mutex_unlock(&state->mutex);
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0close(incoming);
+ =C2=A0 =C2=A0}
+ =C2=A0= =C2=A0return NULL;
+}
+
+static void pci_leech_realize(PCIDevice = *pdev, Error **errp)
+{
+ =C2=A0 =C2=A0PciLeechState *state =3D PCILE= ECH(pdev);
+ =C2=A0 =C2=A0struct sockaddr_in sock_addr;
+ =C2=A0 =C2= =A0char host_ip[16];
+ =C2=A0 =C2=A0struct hostent *he =3D gethostbyname= (state->host);
+ =C2=A0 =C2=A0if (he =3D=3D NULL) {
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0puts("gethostbyname failed!");
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0exit(EXIT_FAILURE);
+ =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0= /* Initialize the socket for PCILeech. */
+ =C2=A0 =C2=A0state->sockf= d =3D socket(AF_INET, SOCK_STREAM, 0);
+ =C2=A0 =C2=A0if (state->sock= fd < 0) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0puts("Failed to initializ= e socket for PCILeech!");
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(EXIT_FA= ILURE);
+ =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0sock_addr.sin_family =3D AF_I= NET;
+ =C2=A0 =C2=A0sock_addr.sin_addr =3D *(struct in_addr *)he->h_a= ddr;
+ =C2=A0 =C2=A0sock_addr.sin_port =3D htons(state->port);
+ = =C2=A0 =C2=A0inet_ntop(AF_INET, &sock_addr.sin_addr, host_ip, sizeof(ho= st_ip));
+ =C2=A0 =C2=A0if (bind(state->sockfd, (struct sockaddr *)&a= mp;sock_addr, sizeof(sock_addr))
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0< 0) {
+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0puts("Failed to bind socket for PCILeech!"= ;);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0close(state->sockfd);
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0exit(EXIT_FAILURE);
+ =C2=A0 =C2=A0}
+ =C2=A0 =C2= =A0if (listen(state->sockfd, 10) < 0) {
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0puts("Failed to listen to socket for PCILeech!");
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0close(state->sockfd);
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0exit(EXIT_FAILURE);
+ =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0printf("I= NFO: PCILeech is listening on %s:%u...\n", host_ip, state->port);+ =C2=A0 =C2=A0/* Initialize the thread for PCILeech. */
+ =C2=A0 =C2= =A0qemu_mutex_init(&state->mutex);
+ =C2=A0 =C2=A0qemu_thread_cre= ate(&state->thread, "pcileech", pci_leech_worker_thread,+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0state, QEMU_THREAD_JOINABLE);
+}
+
+static void pci_leec= h_finalize(PCIDevice *pdev)
+{
+ =C2=A0 =C2=A0PciLeechState *state = =3D PCILEECH(pdev);
+ =C2=A0 =C2=A0puts("Stopping PCILeech Worker..= .");
+ =C2=A0 =C2=A0qemu_mutex_lock(&state->mutex);
+ =C2= =A0 =C2=A0state->stopping =3D true;
+ =C2=A0 =C2=A0qemu_mutex_unlock(= &state->mutex);
+ =C2=A0 =C2=A0close(state->sockfd);
+ =C2= =A0 =C2=A0qemu_thread_join(&state->thread);
+ =C2=A0 =C2=A0qemu_m= utex_destroy(&state->mutex);
+}
+
+char pci_leech_default_h= ost[] =3D "0.0.0.0";
+
+static void pci_leech_instance_init= (Object *obj)
+{
+ =C2=A0 =C2=A0int x =3D 1;
+ =C2=A0 =C2=A0char* = y =3D (char *)&x;
+ =C2=A0 =C2=A0PciLeechState *state =3D PCILEECH(o= bj);
+ =C2=A0 =C2=A0/* QEMU's String-Property can't specify defa= ult value. */
+ =C2=A0 =C2=A0/* So we have to set the default on our own= . */
+ =C2=A0 =C2=A0if (state->host =3D=3D NULL) {
+ =C2=A0 =C2=A0= =C2=A0 =C2=A0state->host =3D pci_leech_default_host;
+ =C2=A0 =C2=A0= }
+ =C2=A0 =C2=A0/* Save Our Endianness. */
+ =C2=A0 =C2=A0state->= endianness =3D (*y =3D=3D 0);
+}
+
+static Property leech_properti= es[] =3D {
+ =C2=A0 =C2=A0DEFINE_PROP_UINT16("port", PciLeechS= tate, port, 6789),
+ =C2=A0 =C2=A0DEFINE_PROP_STRING("host", P= ciLeechState, host),
+ =C2=A0 =C2=A0DEFINE_PROP_END_OF_LIST(),
+};+
+static void pci_leech_class_init(ObjectClass *class, void *data)
= +{
+ =C2=A0 =C2=A0DeviceClass *dc =3D DEVICE_CLASS(class);
+ =C2=A0 = =C2=A0PCIDeviceClass *k =3D PCI_DEVICE_CLASS(class);
+ =C2=A0 =C2=A0k-&g= t;realize =3D pci_leech_realize;
+ =C2=A0 =C2=A0k->exit =3D pci_leech= _finalize;
+ =C2=A0 =C2=A0/* Change the Vendor/Device ID to your favor. = */
+ =C2=A0 =C2=A0/* These are the default values from PCILeech-FPGA. */=
+ =C2=A0 =C2=A0k->vendor_id =3D PCI_VENDOR_ID_XILINX;
+ =C2=A0 = =C2=A0k->device_id =3D 0x0666;
+ =C2=A0 =C2=A0k->revision =3D 0;+ =C2=A0 =C2=A0k->class_id =3D PCI_CLASS_NETWORK_ETHERNET;
+ =C2=A0= =C2=A0device_class_set_props(dc, leech_properties);
+ =C2=A0 =C2=A0set_= bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static void pc= i_leech_register_types(void)
+{
+ =C2=A0 =C2=A0static InterfaceInfo i= nterfaces[] =3D {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0{INTERFACE_CONVENTIONAL_P= CI_DEVICE},
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0{},
+ =C2=A0 =C2=A0};
+ = =C2=A0 =C2=A0static const TypeInfo leech_info =3D {
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0.name =3D TYPE_PCILEECH_DEVICE,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.= parent =3D TYPE_PCI_DEVICE,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.instance_size = =3D sizeof(PciLeechState),
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.instance_init = =3D pci_leech_instance_init,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.class_init = =3D pci_leech_class_init,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.interfaces =3D i= nterfaces,
+ =C2=A0 =C2=A0};
+ =C2=A0 =C2=A0type_register_static(&= ;leech_info);
+}
+
+type_init(pci_leech_register_types)

= --000000000000c64ce3061f006973--