<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://open-iov.org/index.php?action=history&amp;feed=atom&amp;title=WPR_Management</id>
	<title>WPR Management - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://open-iov.org/index.php?action=history&amp;feed=atom&amp;title=WPR_Management"/>
	<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=WPR_Management&amp;action=history"/>
	<updated>2026-10-12T06:40:00Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://open-iov.org/index.php?title=WPR_Management&amp;diff=23992&amp;oldid=prev</id>
		<title>WikiBot: Fix repository links: point to the cgit tree URLs</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=WPR_Management&amp;diff=23992&amp;oldid=prev"/>
		<updated>2026-10-12T04:41:02Z</updated>

		<summary type="html">&lt;p&gt;Fix repository links: point to the cgit tree URLs&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 04:41, 12 October 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l3&quot;&gt;Line 3:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 3:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= WPR (Write/Read Protect Region) Management =&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= WPR (Write/Read Protect Region) Management =&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;blockquote&amp;gt;'''Historical document — superseded.''' WPR is the '''write-protected region of VRAM reserved for firmware''', not a generic read/write-protect mechanism; the read-protect framing below is historical reverse-engineering material. Canonical documentation: [https://git.vgpu.io/open-iov/&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;blob/master&lt;/del&gt;/docs/03-architecture/06-host-module-and-hybrid-model.md &amp;lt;code&amp;gt;../docs/03-architecture/06-host-module-and-hybrid-model.md&amp;lt;/code&amp;gt;].&amp;lt;/blockquote&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;blockquote&amp;gt;'''Historical document — superseded.''' WPR is the '''write-protected region of VRAM reserved for firmware''', not a generic read/write-protect mechanism; the read-protect framing below is historical reverse-engineering material. Canonical documentation: [https://git.vgpu.io/open-iov&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;.git&lt;/ins&gt;/&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;tree&lt;/ins&gt;/docs/03-architecture/06-host-module-and-hybrid-model.md &amp;lt;code&amp;gt;../docs/03-architecture/06-host-module-and-hybrid-model.md&amp;lt;/code&amp;gt;].&amp;lt;/blockquote&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Overview ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== Overview ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key my_wiki:diff::1.12:old-23958:rev-23992 --&gt;
&lt;/table&gt;</summary>
		<author><name>WikiBot</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=WPR_Management&amp;diff=23958&amp;oldid=prev</id>
		<title>WikiBot: Carry the site-wide About/licensing message on every page (2026-10-12)</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=WPR_Management&amp;diff=23958&amp;oldid=prev"/>
		<updated>2026-10-12T04:29:53Z</updated>

		<summary type="html">&lt;p&gt;Carry the site-wide About/licensing message on every page (2026-10-12)&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 04:29, 12 October 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{About message}}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= WPR (Write/Read Protect Region) Management =&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= WPR (Write/Read Protect Region) Management =&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key my_wiki:diff::1.12:old-23858:rev-23958 --&gt;
&lt;/table&gt;</summary>
		<author><name>WikiBot</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=WPR_Management&amp;diff=23858&amp;oldid=prev</id>
		<title>WikiBot: Re-sync page from tracked wiki source: fix cross-document links and diagram; refresh status</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=WPR_Management&amp;diff=23858&amp;oldid=prev"/>
		<updated>2026-10-12T04:10:06Z</updated>

		<summary type="html">&lt;p&gt;Re-sync page from tracked wiki source: fix cross-document links and diagram; refresh status&lt;/p&gt;
&lt;a href=&quot;https://open-iov.org/index.php?title=WPR_Management&amp;amp;diff=23858&amp;amp;oldid=23835&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>WikiBot</name></author>
	</entry>
	<entry>
		<id>https://open-iov.org/index.php?title=WPR_Management&amp;diff=23835&amp;oldid=prev</id>
		<title>WikiBot: Remove unpaired blockquote tags left by reference cleanup</title>
		<link rel="alternate" type="text/html" href="https://open-iov.org/index.php?title=WPR_Management&amp;diff=23835&amp;oldid=prev"/>
		<updated>2026-10-12T03:58:31Z</updated>

		<summary type="html">&lt;p&gt;Remove unpaired blockquote tags left by reference cleanup&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;span id=&amp;quot;wpr-writeread-protect-region-management&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
= WPR (Write/Read Protect Region) Management =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;overview&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
WPR (Write Protect Region / Read Protect Region) provides memory isolation for vGPU by protecting guest memory regions from unauthorized access. The GSP firmware implements WPR through two handlers at '''0x04F00B0C''' and '''0x04F00C78''' (62 KB each).&lt;br /&gt;
&amp;lt;span id=&amp;quot;key-addresses&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Key Addresses ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Handler&lt;br /&gt;
! Address&lt;br /&gt;
! Size&lt;br /&gt;
! Role&lt;br /&gt;
|-&lt;br /&gt;
| WPR Handler 1&lt;br /&gt;
| 0x04F00B0C&lt;br /&gt;
| 62 KB&lt;br /&gt;
| Primary WPR management&lt;br /&gt;
|-&lt;br /&gt;
| WPR Handler 2&lt;br /&gt;
| 0x04F00C78&lt;br /&gt;
| 62 KB&lt;br /&gt;
| Secondary/timeout handling&lt;br /&gt;
|-&lt;br /&gt;
| String Table&lt;br /&gt;
| 60 locations&lt;br /&gt;
| —&lt;br /&gt;
| Completion/timeout strings&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;string-references-60-total&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== String References (60 Total) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;completion-events&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Completion Events ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;WPR_WRITE_COMPLETE      0x5E478F8&lt;br /&gt;
WPR_READ_COMPLETE       0x5E478E0&lt;br /&gt;
NV_WPR_WRITE_COMPLETE   0x5E478C8&lt;br /&gt;
NV_WPR_READ_COMPLETE    0x5E478B0&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;timeout-events&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Timeout Events ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;WPR_WRITE_TIMEOUT       0x5E47898&lt;br /&gt;
WPR_READ_TIMEOUT        0x5E47880&lt;br /&gt;
NV_WPR_WRITE_TIMEOUT    0x5E47868&lt;br /&gt;
NV_WPR_READ_TIMEOUT     0x5E47850&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;wpr-state-machine&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== WPR State Machine ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;handler-1-0x04f00b0c-primary&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Handler 1: 0x04F00B0C (Primary) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;typedef enum {&lt;br /&gt;
    WPR_STATE_IDLE = 0,&lt;br /&gt;
    WPR_STATE_WRITE_PENDING = 1,&lt;br /&gt;
    WPR_STATE_READ_PENDING = 2,&lt;br /&gt;
    WPR_STATE_COMPLETE = 3,&lt;br /&gt;
    WPR_STATE_TIMEOUT = 4,&lt;br /&gt;
    WPR_STATE_ERROR = 0xFFFF&lt;br /&gt;
} wpr_state_t;&lt;br /&gt;
&lt;br /&gt;
typedef struct {&lt;br /&gt;
    uint64_t region_base;      // Protected region base&lt;br /&gt;
    uint64_t region_size;      // Region size (page-aligned)&lt;br /&gt;
    uint32_t vf_id;            // Owning VF&lt;br /&gt;
    uint32_t flags;            // WPR_WRITE | WPR_READ | WPR_EXECUTE&lt;br /&gt;
    wpr_state_t state;&lt;br /&gt;
    uint64_t timeout_ns;       // Operation timeout&lt;br /&gt;
    void *completion_cb;       // Callback on complete&lt;br /&gt;
    void *timeout_cb;          // Callback on timeout&lt;br /&gt;
} wpr_region_t;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;operation-flow&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Operation Flow ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;write-protect&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
==== Write Protect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;1. VF requests WPR_WRITE on region [base, base+size)&lt;br /&gt;
2. Handler validates alignment (4KB) and permissions&lt;br /&gt;
3. Programs MMU/IOMMU write-protect bits&lt;br /&gt;
4. Starts timeout timer (configurable)&lt;br /&gt;
5. On GPU write attempt:&lt;br /&gt;
   a. Trap to GSP via page fault&lt;br /&gt;
   b. Check if VF owns region&lt;br /&gt;
   c. If allowed: emulate write, return OK&lt;br /&gt;
   d. If denied: trigger WPR_WRITE_COMPLETE/NV_WPR_WRITE_COMPLETE&lt;br /&gt;
6. On timeout: trigger WPR_WRITE_TIMEOUT/NV_WPR_WRITE_TIMEOUT&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;read-protect&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
==== Read Protect ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;1. VF requests WPR_READ on region&lt;br /&gt;
2. Programs MMU/IOMMU read-protect bits&lt;br /&gt;
3. On GPU read attempt:&lt;br /&gt;
   a. Trap to GSP&lt;br /&gt;
   b. Return zero/poison data or emulate&lt;br /&gt;
   c. Trigger WPR_READ_COMPLETE/NV_WPR_READ_COMPLETE&lt;br /&gt;
4. On timeout: trigger WPR_READ_TIMEOUT/NV_WPR_READ_TIMEOUT&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;vbios-parsing-handler-2-0x04f00c78&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== VBIOS Parsing (Handler 2: 0x04F00C78) ==&lt;br /&gt;
&lt;br /&gt;
The WPR handlers parse VBIOS structures for legacy compatibility:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;int parse_vbios_for_wpr(void *vbios_ptr, size_t size) {&lt;br /&gt;
    // Search for signatures:&lt;br /&gt;
    // 0xAA55 - Standard VBIOS signature&lt;br /&gt;
    // 0x57464F4E (&amp;quot;WFON&amp;quot;) - WPR enable&lt;br /&gt;
    // 0x5746564E (&amp;quot;WFVN&amp;quot;) - WPR version&lt;br /&gt;
    &lt;br /&gt;
    for (offset = 0; offset &amp;lt; size; offset += 0x1000) {&lt;br /&gt;
        uint32_t sig = *(uint32_t*)(vbios_ptr + offset);&lt;br /&gt;
        &lt;br /&gt;
        if (sig == 0xAA55) {&lt;br /&gt;
            // Check for WPR structures&lt;br /&gt;
            parse_wpr_tables(vbios_ptr + offset);&lt;br /&gt;
        }&lt;br /&gt;
        else if (sig == 0x57464F4E || sig == 0x5746564E) {&lt;br /&gt;
            // WPR enabled in VBIOS&lt;br /&gt;
            wpr_vbios_enabled = true;&lt;br /&gt;
            wpr_vbios_offset = offset;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;integration-with-gsp-subsystems&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Integration with GSP Subsystems ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;memory-allocator-0x429b450&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Memory Allocator (0x429B450) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;// Allocate WPR metadata structures&lt;br /&gt;
wpr_region_t *wpr_alloc_region {&lt;br /&gt;
    return UNK_ram_058A1A9C(0x429B450, sizeof(wpr_region_t));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Allocate bounce buffers for emulation&lt;br /&gt;
void *wpr_alloc_bounce(size_t size) {&lt;br /&gt;
    return UNK_ram_058A1A9C(0x429B450, size);&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;dmacopy-engine-0x0588f9c4-0x05aec86c&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== DMA/Copy Engine (0x0588F9C4, 0x05AEC86C) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;// Copy data for WPR emulation&lt;br /&gt;
int wpr_emulate_access(wpr_region_t *rgn, void *dst, void *src, size_t size) {&lt;br /&gt;
    return UNK_ram_0588F9C4(dma_engine, src, dst, size);&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;logging-0x05ab7da0&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Logging (0x05AB7DA0) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;// Log WPR events&lt;br /&gt;
void wpr_log_event(const char *event_str, uint32_t vf_id, uint64_t addr) {&lt;br /&gt;
    UNK_ram_05AB7DA0(1, &amp;amp;event_str);  // Log string&lt;br /&gt;
    UNK_ram_05AB7DA0(2, &amp;amp;vf_id);      // Log VF ID&lt;br /&gt;
    UNK_ram_05AB7DA0(3, &amp;amp;addr);       // Log address&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;vgpu-io-integration&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== vGPU-IO Integration ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;kernel-wpr-api&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Kernel WPR API ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;struct gsp_wpr_ops {&lt;br /&gt;
    int (*protect_write)(struct gsp_device *gsp, &lt;br /&gt;
                         uint32_t vf_id,&lt;br /&gt;
                         uint64_t base, uint64_t size);&lt;br /&gt;
    int (*protect_read)(struct gsp_device *gsp,&lt;br /&gt;
                        uint32_t vf_id,&lt;br /&gt;
                        uint64_t base, uint64_t size);&lt;br /&gt;
    int (*unprotect)(struct gsp_device *gsp,&lt;br /&gt;
                     uint32_t vf_id,&lt;br /&gt;
                     uint64_t base);&lt;br /&gt;
    int (*set_timeout)(struct gsp_device *gsp,&lt;br /&gt;
                       uint32_t vf_id,&lt;br /&gt;
                       uint64_t timeout_ns);&lt;br /&gt;
    int (*register_callback)(struct gsp_device *gsp,&lt;br /&gt;
                             uint32_t vf_id,&lt;br /&gt;
                             enum wpr_event_type type,&lt;br /&gt;
                             void (*cb)(struct wpr_event *));&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static const struct gsp_wpr_ops gsp_wpr_ops = {.protect_write = gsp_wpr_write_protect,.protect_read = gsp_wpr_read_protect,.unprotect = gsp_wpr_unprotect,.set_timeout = gsp_wpr_set_timeout,.register_callback = gsp_wpr_register_callback,&lt;br /&gt;
};&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;vf-wpr-lifecycle&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== VF WPR Lifecycle ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;// VF initialization: register WPR regions&lt;br /&gt;
int gsp_vf_wpr_init(struct gsp_vf *vf) {&lt;br /&gt;
    // Protect VF's page tables&lt;br /&gt;
    gsp_wpr_ops.protect_write(vf-&amp;gt;gsp, vf-&amp;gt;id,&lt;br /&gt;
                              vf-&amp;gt;pt_base, vf-&amp;gt;pt_size);&lt;br /&gt;
    &lt;br /&gt;
    // Protect VF's command buffers&lt;br /&gt;
    gsp_wpr_ops.protect_write(vf-&amp;gt;gsp, vf-&amp;gt;id,&lt;br /&gt;
                              vf-&amp;gt;cmd_base, vf-&amp;gt;cmd_size);&lt;br /&gt;
    &lt;br /&gt;
    // Set default timeout (10ms)&lt;br /&gt;
    gsp_wpr_ops.set_timeout(vf-&amp;gt;gsp, vf-&amp;gt;id, 10000000);&lt;br /&gt;
    &lt;br /&gt;
    // Register completion callbacks&lt;br /&gt;
    gsp_wpr_ops.register_callback(vf-&amp;gt;gsp, vf-&amp;gt;id,&lt;br /&gt;
                                  WPR_EVENT_WRITE_COMPLETE,&lt;br /&gt;
                                  vf_wpr_write_complete_cb);&lt;br /&gt;
    gsp_wpr_ops.register_callback(vf-&amp;gt;gsp, vf-&amp;gt;id,&lt;br /&gt;
                                  WPR_EVENT_TIMEOUT,&lt;br /&gt;
                                  vf_wpr_timeout_cb);&lt;br /&gt;
    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// VF cleanup&lt;br /&gt;
void gsp_vf_wpr_fini(struct gsp_vf *vf) {&lt;br /&gt;
    gsp_wpr_ops.unprotect(vf-&amp;gt;gsp, vf-&amp;gt;id, vf-&amp;gt;pt_base);&lt;br /&gt;
    gsp_wpr_ops.unprotect(vf-&amp;gt;gsp, vf-&amp;gt;id, vf-&amp;gt;cmd_base);&lt;br /&gt;
    //.. unregister callbacks&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;callback-handling&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Callback Handling ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;static void vf_wpr_write_complete_cb(struct wpr_event *evt) {&lt;br /&gt;
    struct gsp_vf *vf = evt-&amp;gt;vf;&lt;br /&gt;
    &lt;br /&gt;
    // Log the write attempt&lt;br /&gt;
    dev_dbg(vf-&amp;gt;dev, &amp;quot;WPR write complete: VF=%u addr=0x%llx\n&amp;quot;,&lt;br /&gt;
            vf-&amp;gt;id, evt-&amp;gt;address);&lt;br /&gt;
    &lt;br /&gt;
    // If this was a page table update, invalidate TLB&lt;br /&gt;
    if (evt-&amp;gt;address &amp;gt;= vf-&amp;gt;pt_base &amp;amp;&amp;amp; &lt;br /&gt;
        evt-&amp;gt;address &amp;lt; vf-&amp;gt;pt_base + vf-&amp;gt;pt_size) {&lt;br /&gt;
        gsp_tlb_invalidate(vf-&amp;gt;gsp, vf-&amp;gt;id);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static void vf_wpr_timeout_cb(struct wpr_event *evt) {&lt;br /&gt;
    struct gsp_vf *vf = evt-&amp;gt;vf;&lt;br /&gt;
    &lt;br /&gt;
    dev_warn(vf-&amp;gt;dev, &amp;quot;WPR timeout: VF=%u type=%d addr=0x%llx\n&amp;quot;,&lt;br /&gt;
             vf-&amp;gt;id, evt-&amp;gt;type, evt-&amp;gt;address);&lt;br /&gt;
    &lt;br /&gt;
    // Escalate: reset VF or throttle&lt;br /&gt;
    if (evt-&amp;gt;type == WPR_EVENT_WRITE_TIMEOUT) {&lt;br /&gt;
        gsp_vf_throttle(vf);&lt;br /&gt;
    } else {&lt;br /&gt;
        gsp_vf_reset(vf);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;error-codes&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Error Codes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Code&lt;br /&gt;
! Name&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| ETIME&lt;br /&gt;
| Operation timed out&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| EDEV&lt;br /&gt;
| Device error&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| EOVERFLOW&lt;br /&gt;
| Region too large&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| EINVAL&lt;br /&gt;
| Invalid alignment&lt;br /&gt;
|-&lt;br /&gt;
| 0x51&lt;br /&gt;
| ENOMEM&lt;br /&gt;
| Out of memory&lt;br /&gt;
|-&lt;br /&gt;
| 0x56&lt;br /&gt;
| EBUSY&lt;br /&gt;
| Region busy&lt;br /&gt;
|-&lt;br /&gt;
| 0xFFFF&lt;br /&gt;
| EPERM&lt;br /&gt;
| Permission denied&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;debugging&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Debugging ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;monitor-these-addresses&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Monitor These Addresses ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;0x04296048: Global error flag&lt;br /&gt;
0x0429B750+0x111300: Error status register&lt;br /&gt;
0x05E47850-0x05E478F8: WPR string table&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;gsp-log-patterns&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== GSP Log Patterns ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;WPR_WRITE_COMPLETE    VF=&amp;amp;lt;id&amp;amp;gt; ADDR=&amp;amp;lt;addr&amp;amp;gt;&lt;br /&gt;
WPR_READ_COMPLETE     VF=&amp;amp;lt;id&amp;amp;gt; ADDR=&amp;amp;lt;addr&amp;amp;gt;&lt;br /&gt;
WPR_WRITE_TIMEOUT     VF=&amp;amp;lt;id&amp;amp;gt; ADDR=&amp;amp;lt;addr&amp;amp;gt;&lt;br /&gt;
WPR_READ_TIMEOUT      VF=&amp;amp;lt;id&amp;amp;gt; ADDR=&amp;amp;lt;addr&amp;amp;gt;&lt;br /&gt;
NV_WPR_WRITE_COMPLETE VF=&amp;amp;lt;id&amp;amp;gt; ADDR=&amp;amp;lt;addr&amp;amp;gt;&lt;br /&gt;
NV_WPR_READ_COMPLETE  VF=&amp;amp;lt;id&amp;amp;gt; ADDR=&amp;amp;lt;addr&amp;amp;gt;&lt;br /&gt;
NV_WPR_WRITE_TIMEOUT  VF=&amp;amp;lt;id&amp;amp;gt; ADDR=&amp;amp;lt;addr&amp;amp;gt;&lt;br /&gt;
NV_WPR_READ_TIMEOUT   VF=&amp;amp;lt;id&amp;amp;gt; ADDR=&amp;amp;lt;addr&amp;amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;span id=&amp;quot;trace-points&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
=== Trace Points ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;// In kernel driver&lt;br /&gt;
trace_gsp_wpr_protect(vf_id, base, size, type);&lt;br /&gt;
trace_gsp_wpr_event(vf_id, event_type, address, status);&lt;br /&gt;
trace_gsp_wpr_timeout(vf_id, address, elapsed_ns);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span id=&amp;quot;reference&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
== Reference ==&lt;br /&gt;
&lt;br /&gt;
* Handler 1: &amp;lt;code&amp;gt;FUN_ram_04f00b0c_ram_04f00b0c.c&amp;lt;/code&amp;gt; (62 KB)&lt;br /&gt;
* Handler 2: &amp;lt;code&amp;gt;FUN_ram_04f00c78_ram_04f00c78.c&amp;lt;/code&amp;gt; (62 KB)&lt;br /&gt;
* RPC Types: Handled via primary/secondary dispatchers&lt;/div&gt;</summary>
		<author><name>WikiBot</name></author>
	</entry>
</feed>