<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.friendos.dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=ThePuzzlemaker</id>
	<title>FriendOS Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.friendos.dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=ThePuzzlemaker"/>
	<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php/Special:Contributions/ThePuzzlemaker"/>
	<updated>2026-06-01T10:29:06Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.38.4</generator>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Category:River&amp;diff=46</id>
		<title>Category:River</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Category:River&amp;diff=46"/>
		<updated>2023-11-03T00:11:20Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;{{DISPLAYTITLE:Category:river}}&amp;lt;/span&amp;gt;&lt;br /&gt;
See [[River|river]].&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Category:River&amp;diff=45</id>
		<title>Category:River</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Category:River&amp;diff=45"/>
		<updated>2023-11-03T00:11:06Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Created page with &amp;quot;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;{{DISPLAYNAME:Category:river}}&amp;lt;/span&amp;gt; See river.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;{{DISPLAYNAME:Category:river}}&amp;lt;/span&amp;gt;&lt;br /&gt;
See [[River|river]].&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=River&amp;diff=44</id>
		<title>River</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=River&amp;diff=44"/>
		<updated>2023-11-03T00:10:25Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Created page with &amp;quot;&amp;lt;span display=&amp;quot;none&amp;quot;&amp;gt;{{DISPLAYTITLE:river}}&amp;lt;/span&amp;gt; Category:River  River is an experimental capability-based operating system written by ThePuzzlemaker in Rust for RISCV64. (For those wondering, the name is taken from RISC-V: &amp;quot;RIscV&amp;quot; + &amp;quot;ER&amp;quot;). This project is not intended to be used in production, but instead just as a project for learning about advanced OS concepts and existing kernels.  River takes inspiration from repnop's Vanadinite, the se...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span display=&amp;quot;none&amp;quot;&amp;gt;{{DISPLAYTITLE:river}}&amp;lt;/span&amp;gt;&lt;br /&gt;
[[Category:River]]&lt;br /&gt;
&lt;br /&gt;
River is an experimental capability-based operating system written by [[User:ThePuzzlemaker|ThePuzzlemaker]] in Rust for RISCV64. (For those wondering, the name is taken from RISC-V: &amp;quot;RIscV&amp;quot; + &amp;quot;ER&amp;quot;). This project is not intended to be used in production, but instead just as a project for learning about advanced OS concepts and existing kernels.&lt;br /&gt;
&lt;br /&gt;
River takes inspiration from repnop's Vanadinite, the seL4 project, GWU Composite (which has some very helpful accompanying lectures), Fucshia/Zircon, and XV6/RISC-V. Thanks goes to all the amazing people who have helped me through my insanity as I try to figure this stuff out.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* GitHub: [https://github.com/ThePuzzlemaker/river ThePuzzlemaker/river]&lt;br /&gt;
* [[:Category:River|Category Index]]&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Category:X86&amp;diff=43</id>
		<title>Category:X86</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Category:X86&amp;diff=43"/>
		<updated>2023-11-02T23:50:39Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span display=&amp;quot;none&amp;quot;&amp;gt;{{DISPLAYTITLE:Category:x86}}&amp;lt;/span&amp;gt;&lt;br /&gt;
[[Category:Architectures]]&lt;br /&gt;
TODO&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Template:Lowercase_title&amp;diff=42</id>
		<title>Template:Lowercase title</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Template:Lowercase_title&amp;diff=42"/>
		<updated>2023-11-02T23:49:49Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;{{DISPLAYTITLE:{{#if:{{NAMESPACE}}|{{NAMESPACE}}:|}}{{lcfirst:{{PAGENAME}}}}}}&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Template:Lowercase_title&amp;diff=41</id>
		<title>Template:Lowercase title</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Template:Lowercase_title&amp;diff=41"/>
		<updated>2023-11-02T23:49:26Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Created page with &amp;quot;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;{{DISPLAYTITLE:{{#if:{{NAMESPACE}}|{{NAMESPACE}}:|}}{{lcfirst:{{PAGENAME}}}}}}&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt; {{documentation|content=  ==Purpose== This template makes the first letter in a page's title appear lowercase (MediaWiki otherwise forces titles to start with an uppercase letter).  ==Usage== Just include it in the article:  &amp;lt;nowiki&amp;gt;{{lowercase title}}&amp;lt;/nowiki&amp;gt;  ==Dependencies== This Template requires the Extension:ParserFunctions to work.  }} &amp;lt;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span style=&amp;quot;display:none&amp;quot;&amp;gt;{{DISPLAYTITLE:{{#if:{{NAMESPACE}}|{{NAMESPACE}}:|}}{{lcfirst:{{PAGENAME}}}}}}&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation|content=&lt;br /&gt;
&lt;br /&gt;
==Purpose==&lt;br /&gt;
This template makes the first letter in a page's title appear lowercase (MediaWiki otherwise forces titles to start with an uppercase letter).&lt;br /&gt;
&lt;br /&gt;
==Usage==&lt;br /&gt;
Just include it in the article:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;{{lowercase title}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dependencies==&lt;br /&gt;
This Template requires the [[Extension:ParserFunctions]] to work.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Category:Architectures&amp;diff=40</id>
		<title>Category:Architectures</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Category:Architectures&amp;diff=40"/>
		<updated>2023-11-02T23:45:43Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Main_Page&amp;diff=39</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Main_Page&amp;diff=39"/>
		<updated>2023-11-02T23:45:14Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: /* Helpful Links */ Make that actually link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Welcome to the FriendOS Wiki! ==&lt;br /&gt;
&lt;br /&gt;
The FriendOS Wiki is a community-driven wiki for the [https://discord.gg/U9feA9z669 FriendOS Discord server]. This wiki, as well as the Discord server, are intended to create a more inclusive, supportive, and welcoming environment for people learning about operating systems development, which historically is not very common. The purpose of this wiki is to provide resources for newbies and veterans alike, as well as allowing contributions from the community members so that people can easily create &amp;amp; share information about the concepts that they frequently work with. If you think you have something to contribute, make an account and start writing! If you have comments or questions, you can discuss the wiki in the #wiki channel on the Discord server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://discord.gg/U9feA9z669 Discord invite link]&lt;br /&gt;
* [[Special:AllPages|See all pages]]&lt;br /&gt;
* [[:Category:Architectures|Architectures Index]]&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Main_Page&amp;diff=38</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Main_Page&amp;diff=38"/>
		<updated>2023-11-02T23:44:28Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: /* Helpful Links */ Architectures index&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Welcome to the FriendOS Wiki! ==&lt;br /&gt;
&lt;br /&gt;
The FriendOS Wiki is a community-driven wiki for the [https://discord.gg/U9feA9z669 FriendOS Discord server]. This wiki, as well as the Discord server, are intended to create a more inclusive, supportive, and welcoming environment for people learning about operating systems development, which historically is not very common. The purpose of this wiki is to provide resources for newbies and veterans alike, as well as allowing contributions from the community members so that people can easily create &amp;amp; share information about the concepts that they frequently work with. If you think you have something to contribute, make an account and start writing! If you have comments or questions, you can discuss the wiki in the #wiki channel on the Discord server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://discord.gg/U9feA9z669 Discord invite link]&lt;br /&gt;
* [[Special:AllPages|See all pages]]&lt;br /&gt;
* [[Category:Architectures|Architectures Index]]&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Category:X86&amp;diff=37</id>
		<title>Category:X86</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Category:X86&amp;diff=37"/>
		<updated>2023-11-02T23:43:45Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Architectures]]&lt;br /&gt;
TODO&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Category:RISCV&amp;diff=36</id>
		<title>Category:RISCV</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Category:RISCV&amp;diff=36"/>
		<updated>2023-11-02T23:43:30Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Architectures]]&lt;br /&gt;
TODO&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Category:RISCV&amp;diff=35</id>
		<title>Category:RISCV</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Category:RISCV&amp;diff=35"/>
		<updated>2023-11-02T23:42:56Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Created page with &amp;quot;TODO&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;TODO&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=34</id>
		<title>RISC-V/Paging</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=34"/>
		<updated>2023-11-02T23:42:30Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Fix category reference&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:RISCV]]&lt;br /&gt;
Paging in RISC-V can be enabled by first setting up a page table, then pointing the CPU to that page table via the [[RISC-V/CSR#satp | &amp;lt;code&amp;gt;satp&amp;lt;/code&amp;gt; CSR]]. This article will describe these steps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Paging type can be determined at runtime using the device tree, its typically located in the CPU specific nodes, such as `cpu@x` where x denotes which number of CPU it is, it will be located under the `mmu-type` property in the form of a string such as `riscv,svY` is either &amp;quot;32&amp;quot;, &amp;quot;39&amp;quot;, &amp;quot;48&amp;quot;, or &amp;quot;57&amp;quot; depending on paging type.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
&lt;br /&gt;
There are many acronyms and other terms that are used in the RISC-V specification which, for the purpose of brevity and consistency, will be used in this article as well. I will assume a baseline knowledge of the purpose and basics of paging and virtual addressing.&lt;br /&gt;
&lt;br /&gt;
=== PPNs and VPNs ===&lt;br /&gt;
&lt;br /&gt;
A physical page number (or PPN) is a unique, page-aligned identifier for a page in physical memory. The number of PPN segments for an address will depend on the paging mode.&lt;br /&gt;
&lt;br /&gt;
To construct a PPN from a physical address, you can simply (logically, not arithmetically) shift the value right by 12 bits (as 2**12 = 4096). Note that this operation will truncate the offset into the page, if the address was not page-aligned.&lt;br /&gt;
&lt;br /&gt;
A virtual page number (or VPN) is very similar to a PPN, but in the virtual address space. Again, the number of VPN segments for a virtual address will depend on the paging mode.&lt;br /&gt;
&lt;br /&gt;
=== RSW ===&lt;br /&gt;
Bits marked as RSW indicate that they can be written, read, and handled in any way the OS wants without causing issues. These can be used as OS-specific flags.&lt;br /&gt;
&lt;br /&gt;
== RISC-V Page Table Layout ==&lt;br /&gt;
&lt;br /&gt;
There are various paging modes available in the RISC-V ISA, differing by the number of virtual address bits:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Memory Size !! SXLEN&lt;br /&gt;
|-&lt;br /&gt;
| Sv32 || 4GiB || 32-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv39 || 512GiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv48 || 256TiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv57 || 128PiB || 64-bit only&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Feel free to choose between these modes as you see fit; this page will describe all of them. Note that in 64-bit systems, Sv39 is more than enough for most hobby operating systems (though it is not much more difficult to go further).&lt;br /&gt;
&lt;br /&gt;
=== Sv32 ===&lt;br /&gt;
&lt;br /&gt;
Sv32 is the only available paging mode for a 32 bit system, it provides 32 bit virtual addresses, and 34 bit physical addresses.&lt;br /&gt;
&lt;br /&gt;
'''Address and PTE Layouts'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Sv32 virtual address&lt;br /&gt;
!Bit Range (inclusive)&lt;br /&gt;
!Length (bits)&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-11&lt;br /&gt;
|12&lt;br /&gt;
|Page offset&lt;br /&gt;
|-&lt;br /&gt;
|12-21&lt;br /&gt;
|10&lt;br /&gt;
|Page VPN (VPN[0])&lt;br /&gt;
|-&lt;br /&gt;
|22-31&lt;br /&gt;
|10&lt;br /&gt;
|Megapage VPN (VPN[0])&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Sv32 physical address&lt;br /&gt;
!Bit Range (inclusive)&lt;br /&gt;
!Length (bits)&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-11&lt;br /&gt;
|12&lt;br /&gt;
|Page offset&lt;br /&gt;
|-&lt;br /&gt;
|12-21&lt;br /&gt;
|10&lt;br /&gt;
|PPN[0]&lt;br /&gt;
|-&lt;br /&gt;
|22-33&lt;br /&gt;
|12&lt;br /&gt;
|PPN[1]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Sv32 page table entry layout&lt;br /&gt;
!Bit Range (inclusive)&lt;br /&gt;
!Length (bits)&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|Valid flag (V)&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Readable flag (R)&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|Writable flag (W)&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Executable flag (X)&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|1&lt;br /&gt;
|U-mode accessible flag (U)&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|Global flag (G)&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|Accessed flag (A)&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|1&lt;br /&gt;
|Dirty flag (D)&lt;br /&gt;
|-&lt;br /&gt;
|8-9&lt;br /&gt;
|2&lt;br /&gt;
|RSW&lt;br /&gt;
|-&lt;br /&gt;
|10-19&lt;br /&gt;
|10&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|20-31&lt;br /&gt;
|12&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sv39 ===&lt;br /&gt;
&lt;br /&gt;
Sv39 is the simplest paging mode for 64-bit systems (though larger modes are not too much more difficult to implement). It supports the standard 4KiB pages, as well as 2MiB megapages and 1GiB gigapages. &lt;br /&gt;
&lt;br /&gt;
TODO: actually describe what a page table looks like, and also PTE's RWX encoding&lt;br /&gt;
&lt;br /&gt;
==== Address and PTE Layouts ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 virtual address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || Page VPN (&amp;lt;nowiki&amp;gt;VPN[0]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || Megapage VPN (&amp;lt;nowiki&amp;gt;VPN[1]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 30-38 || 9 || Gigapage VPN (&amp;lt;nowiki&amp;gt;VPN[2]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 physical address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || &amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || &amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 30-55 || 26 || &amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 page table entry layout&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Valid flag (V)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Readable flag (R)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1 || Writable flag (W)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || Executable flag (X)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 1 || U-mode accessible flag (U)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || 1 || Global flag (G)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || 1 || Accessed flag (A)&lt;br /&gt;
|-&lt;br /&gt;
| 7 || 1 || Dirty flag (D)&lt;br /&gt;
|-&lt;br /&gt;
| 8-9 || 2 || RSW&lt;br /&gt;
|-&lt;br /&gt;
| 10-18 || 9 || &amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 19-27 || 9 || &amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 28-53 || 26 || &amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 54-60 || 7 || Reserved&lt;br /&gt;
|-&lt;br /&gt;
| 61-62 || 2 || PBMT (TODO)&lt;br /&gt;
|-&lt;br /&gt;
| 63 || 1 || N bit (TODO)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sv48 ===&lt;br /&gt;
&lt;br /&gt;
TODO: Explain&lt;br /&gt;
&lt;br /&gt;
==== Address and PTE Layouts ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv48 virtual address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || Page VPN (&amp;lt;nowiki&amp;gt;VPN[0]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || Megapage VPN (&amp;lt;nowiki&amp;gt;VPN[1]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 30-38 || 9 || Gigapage VPN (&amp;lt;nowiki&amp;gt;VPN[2]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 39-47 || 9 || (&amp;lt;nowiki&amp;gt;VPN[3]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv48 physical address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || (&amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || (&amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 30-38 || 9 || (&amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 39-47 || 9 || (&amp;lt;nowiki&amp;gt;PPN[3]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv48 page table entry layout&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Valid flag (V)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Readable flag (R)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1 || Writable flag (W)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || Executable flag (X)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 1 || U-mode accessible flag (U)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || 1 || Global flag (G)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || 1 || Accessed flag (A)&lt;br /&gt;
|-&lt;br /&gt;
| 7 || 1 || Dirty flag (D)&lt;br /&gt;
|-&lt;br /&gt;
| 8-9 || 2 || RSW&lt;br /&gt;
|-&lt;br /&gt;
| 10-18 || 9 || &amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 19-27 || 9 || &amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 28-36 || 9 || &amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 37-53 || 17 || &amp;lt;nowiki&amp;gt;PPN[3]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 54-60 || 7 || Reserved&lt;br /&gt;
|-&lt;br /&gt;
| 61-62 || 2 || PBMT (TODO)&lt;br /&gt;
|-&lt;br /&gt;
| 63 || 1 || N bit (TODO)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sv57 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Enabling Paging ==&lt;br /&gt;
&lt;br /&gt;
TODO: Explain better&lt;br /&gt;
&lt;br /&gt;
Paging on RISC-V is split into 4 different modes, 32 bit, 39 bit, 48 bit, and 57 bit. 32 bit is only available on 32 bit systems, and not available on 64 bit systems.&lt;br /&gt;
Paging is handled by the `SATP` CSR which contains 3 separate sections, the PPN(Physical Page Number) which is similar to the physical address, the ASID(Address Space Identifier), and finally, the Mode. To enable paging you need to write a paging mode into the Mode section of the `SATP` register. On 64 bits you can write 0 for no paging, 8 for Sv39, 9 for Sv48, 10 for Sv57, and in the future 11 will be available for 64 bits. On 32 bits you can write 0 for no paging, or 1 for Sv32.&lt;br /&gt;
&lt;br /&gt;
Rust example code:&lt;br /&gt;
&lt;br /&gt;
32 bits&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot; line&amp;gt;&lt;br /&gt;
pub unsafe fn enable_paging(root_page_table: usize) {&lt;br /&gt;
    let ppn = root_page_table &amp;gt;&amp;gt; 12;&lt;br /&gt;
    let mode = 1 &amp;lt;&amp;lt; 31;&lt;br /&gt;
&lt;br /&gt;
    let write = mode | ppn;&lt;br /&gt;
&lt;br /&gt;
    core::arch::asm(&lt;br /&gt;
        &amp;quot;csrw satp, {}&amp;quot;,&lt;br /&gt;
        in(reg) write&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
64 bits&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot; line&amp;gt;&lt;br /&gt;
pub unsafe fn enable_paging(root_page_table: usize, mode: u8) {&lt;br /&gt;
    let ppn = root_page_table &amp;gt;&amp;gt; 12;&lt;br /&gt;
    let new_mode = (mode &amp;amp; 0xf) &amp;lt;&amp;lt; 60;&lt;br /&gt;
&lt;br /&gt;
    let write = mode | ppn;&lt;br /&gt;
&lt;br /&gt;
    core::arch::asm(&lt;br /&gt;
        &amp;quot;csrw satp, {}&amp;quot;,&lt;br /&gt;
        in(reg) write&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=33</id>
		<title>RISC-V/Paging</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=33"/>
		<updated>2023-11-02T23:42:06Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Add to Category:RISC-V&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:RISC-V]]&lt;br /&gt;
Paging in RISC-V can be enabled by first setting up a page table, then pointing the CPU to that page table via the [[RISC-V/CSR#satp | &amp;lt;code&amp;gt;satp&amp;lt;/code&amp;gt; CSR]]. This article will describe these steps.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Paging type can be determined at runtime using the device tree, its typically located in the CPU specific nodes, such as `cpu@x` where x denotes which number of CPU it is, it will be located under the `mmu-type` property in the form of a string such as `riscv,svY` is either &amp;quot;32&amp;quot;, &amp;quot;39&amp;quot;, &amp;quot;48&amp;quot;, or &amp;quot;57&amp;quot; depending on paging type.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
&lt;br /&gt;
There are many acronyms and other terms that are used in the RISC-V specification which, for the purpose of brevity and consistency, will be used in this article as well. I will assume a baseline knowledge of the purpose and basics of paging and virtual addressing.&lt;br /&gt;
&lt;br /&gt;
=== PPNs and VPNs ===&lt;br /&gt;
&lt;br /&gt;
A physical page number (or PPN) is a unique, page-aligned identifier for a page in physical memory. The number of PPN segments for an address will depend on the paging mode.&lt;br /&gt;
&lt;br /&gt;
To construct a PPN from a physical address, you can simply (logically, not arithmetically) shift the value right by 12 bits (as 2**12 = 4096). Note that this operation will truncate the offset into the page, if the address was not page-aligned.&lt;br /&gt;
&lt;br /&gt;
A virtual page number (or VPN) is very similar to a PPN, but in the virtual address space. Again, the number of VPN segments for a virtual address will depend on the paging mode.&lt;br /&gt;
&lt;br /&gt;
=== RSW ===&lt;br /&gt;
Bits marked as RSW indicate that they can be written, read, and handled in any way the OS wants without causing issues. These can be used as OS-specific flags.&lt;br /&gt;
&lt;br /&gt;
== RISC-V Page Table Layout ==&lt;br /&gt;
&lt;br /&gt;
There are various paging modes available in the RISC-V ISA, differing by the number of virtual address bits:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Memory Size !! SXLEN&lt;br /&gt;
|-&lt;br /&gt;
| Sv32 || 4GiB || 32-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv39 || 512GiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv48 || 256TiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv57 || 128PiB || 64-bit only&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Feel free to choose between these modes as you see fit; this page will describe all of them. Note that in 64-bit systems, Sv39 is more than enough for most hobby operating systems (though it is not much more difficult to go further).&lt;br /&gt;
&lt;br /&gt;
=== Sv32 ===&lt;br /&gt;
&lt;br /&gt;
Sv32 is the only available paging mode for a 32 bit system, it provides 32 bit virtual addresses, and 34 bit physical addresses.&lt;br /&gt;
&lt;br /&gt;
'''Address and PTE Layouts'''&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Sv32 virtual address&lt;br /&gt;
!Bit Range (inclusive)&lt;br /&gt;
!Length (bits)&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-11&lt;br /&gt;
|12&lt;br /&gt;
|Page offset&lt;br /&gt;
|-&lt;br /&gt;
|12-21&lt;br /&gt;
|10&lt;br /&gt;
|Page VPN (VPN[0])&lt;br /&gt;
|-&lt;br /&gt;
|22-31&lt;br /&gt;
|10&lt;br /&gt;
|Megapage VPN (VPN[0])&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Sv32 physical address&lt;br /&gt;
!Bit Range (inclusive)&lt;br /&gt;
!Length (bits)&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0-11&lt;br /&gt;
|12&lt;br /&gt;
|Page offset&lt;br /&gt;
|-&lt;br /&gt;
|12-21&lt;br /&gt;
|10&lt;br /&gt;
|PPN[0]&lt;br /&gt;
|-&lt;br /&gt;
|22-33&lt;br /&gt;
|12&lt;br /&gt;
|PPN[1]&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+Sv32 page table entry layout&lt;br /&gt;
!Bit Range (inclusive)&lt;br /&gt;
!Length (bits)&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|Valid flag (V)&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Readable flag (R)&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|Writable flag (W)&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|Executable flag (X)&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|1&lt;br /&gt;
|U-mode accessible flag (U)&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|Global flag (G)&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|Accessed flag (A)&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|1&lt;br /&gt;
|Dirty flag (D)&lt;br /&gt;
|-&lt;br /&gt;
|8-9&lt;br /&gt;
|2&lt;br /&gt;
|RSW&lt;br /&gt;
|-&lt;br /&gt;
|10-19&lt;br /&gt;
|10&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|20-31&lt;br /&gt;
|12&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sv39 ===&lt;br /&gt;
&lt;br /&gt;
Sv39 is the simplest paging mode for 64-bit systems (though larger modes are not too much more difficult to implement). It supports the standard 4KiB pages, as well as 2MiB megapages and 1GiB gigapages. &lt;br /&gt;
&lt;br /&gt;
TODO: actually describe what a page table looks like, and also PTE's RWX encoding&lt;br /&gt;
&lt;br /&gt;
==== Address and PTE Layouts ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 virtual address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || Page VPN (&amp;lt;nowiki&amp;gt;VPN[0]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || Megapage VPN (&amp;lt;nowiki&amp;gt;VPN[1]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 30-38 || 9 || Gigapage VPN (&amp;lt;nowiki&amp;gt;VPN[2]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 physical address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || &amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || &amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 30-55 || 26 || &amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 page table entry layout&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Valid flag (V)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Readable flag (R)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1 || Writable flag (W)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || Executable flag (X)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 1 || U-mode accessible flag (U)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || 1 || Global flag (G)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || 1 || Accessed flag (A)&lt;br /&gt;
|-&lt;br /&gt;
| 7 || 1 || Dirty flag (D)&lt;br /&gt;
|-&lt;br /&gt;
| 8-9 || 2 || RSW&lt;br /&gt;
|-&lt;br /&gt;
| 10-18 || 9 || &amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 19-27 || 9 || &amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 28-53 || 26 || &amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 54-60 || 7 || Reserved&lt;br /&gt;
|-&lt;br /&gt;
| 61-62 || 2 || PBMT (TODO)&lt;br /&gt;
|-&lt;br /&gt;
| 63 || 1 || N bit (TODO)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sv48 ===&lt;br /&gt;
&lt;br /&gt;
TODO: Explain&lt;br /&gt;
&lt;br /&gt;
==== Address and PTE Layouts ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv48 virtual address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || Page VPN (&amp;lt;nowiki&amp;gt;VPN[0]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || Megapage VPN (&amp;lt;nowiki&amp;gt;VPN[1]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 30-38 || 9 || Gigapage VPN (&amp;lt;nowiki&amp;gt;VPN[2]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 39-47 || 9 || (&amp;lt;nowiki&amp;gt;VPN[3]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv48 physical address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || (&amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || (&amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 30-38 || 9 || (&amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 39-47 || 9 || (&amp;lt;nowiki&amp;gt;PPN[3]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv48 page table entry layout&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Valid flag (V)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Readable flag (R)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1 || Writable flag (W)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || Executable flag (X)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 1 || U-mode accessible flag (U)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || 1 || Global flag (G)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || 1 || Accessed flag (A)&lt;br /&gt;
|-&lt;br /&gt;
| 7 || 1 || Dirty flag (D)&lt;br /&gt;
|-&lt;br /&gt;
| 8-9 || 2 || RSW&lt;br /&gt;
|-&lt;br /&gt;
| 10-18 || 9 || &amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 19-27 || 9 || &amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 28-36 || 9 || &amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 37-53 || 17 || &amp;lt;nowiki&amp;gt;PPN[3]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 54-60 || 7 || Reserved&lt;br /&gt;
|-&lt;br /&gt;
| 61-62 || 2 || PBMT (TODO)&lt;br /&gt;
|-&lt;br /&gt;
| 63 || 1 || N bit (TODO)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sv57 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Enabling Paging ==&lt;br /&gt;
&lt;br /&gt;
TODO: Explain better&lt;br /&gt;
&lt;br /&gt;
Paging on RISC-V is split into 4 different modes, 32 bit, 39 bit, 48 bit, and 57 bit. 32 bit is only available on 32 bit systems, and not available on 64 bit systems.&lt;br /&gt;
Paging is handled by the `SATP` CSR which contains 3 separate sections, the PPN(Physical Page Number) which is similar to the physical address, the ASID(Address Space Identifier), and finally, the Mode. To enable paging you need to write a paging mode into the Mode section of the `SATP` register. On 64 bits you can write 0 for no paging, 8 for Sv39, 9 for Sv48, 10 for Sv57, and in the future 11 will be available for 64 bits. On 32 bits you can write 0 for no paging, or 1 for Sv32.&lt;br /&gt;
&lt;br /&gt;
Rust example code:&lt;br /&gt;
&lt;br /&gt;
32 bits&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot; line&amp;gt;&lt;br /&gt;
pub unsafe fn enable_paging(root_page_table: usize) {&lt;br /&gt;
    let ppn = root_page_table &amp;gt;&amp;gt; 12;&lt;br /&gt;
    let mode = 1 &amp;lt;&amp;lt; 31;&lt;br /&gt;
&lt;br /&gt;
    let write = mode | ppn;&lt;br /&gt;
&lt;br /&gt;
    core::arch::asm(&lt;br /&gt;
        &amp;quot;csrw satp, {}&amp;quot;,&lt;br /&gt;
        in(reg) write&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
64 bits&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;rust&amp;quot; line&amp;gt;&lt;br /&gt;
pub unsafe fn enable_paging(root_page_table: usize, mode: u8) {&lt;br /&gt;
    let ppn = root_page_table &amp;gt;&amp;gt; 12;&lt;br /&gt;
    let new_mode = (mode &amp;amp; 0xf) &amp;lt;&amp;lt; 60;&lt;br /&gt;
&lt;br /&gt;
    let write = mode | ppn;&lt;br /&gt;
&lt;br /&gt;
    core::arch::asm(&lt;br /&gt;
        &amp;quot;csrw satp, {}&amp;quot;,&lt;br /&gt;
        in(reg) write&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=13</id>
		<title>RISC-V/Paging</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=13"/>
		<updated>2022-11-24T03:11:35Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Paging in RISC-V can be enabled by first setting up a page table, then pointing the CPU to that page table via the [[RISC-V/CSR#satp | &amp;lt;code&amp;gt;satp&amp;lt;/code&amp;gt; CSR]]. This article will describe these steps.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
&lt;br /&gt;
There are many acronyms and other terms that are used in the RISC-V specification which, for the purpose of brevity and consistency, will be used in this article as well. I will assume a baseline knowledge of the purpose and basics of paging and virtual addressing.&lt;br /&gt;
&lt;br /&gt;
=== PPNs and VPNs ===&lt;br /&gt;
&lt;br /&gt;
A physical page number (or PPN) is a unique, page-aligned identifier for a page in physical memory. The number of PPN segments for an address will depend on the paging mode.&lt;br /&gt;
&lt;br /&gt;
To construct a PPN from a physical address, you can simply (logically, not arithmetically) shift the value right by 12 bits (as 2**12 = 4096). Note that this operation will truncate the offset into the page, if the address was not page-aligned.&lt;br /&gt;
&lt;br /&gt;
A virtual page number (or VPN) is very similar to a PPN, but in the virtual address space. Again, the number of VPN segments for a virtual address will depend on the paging mode.&lt;br /&gt;
&lt;br /&gt;
== RISC-V Page Table Layout ==&lt;br /&gt;
&lt;br /&gt;
There are various paging modes available in the RISC-V ISA, differing by the number of virtual address bits:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Memory Size !! SXLEN&lt;br /&gt;
|-&lt;br /&gt;
| Sv32 || 4GiB || 32-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv39 || 512GiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv48 || 256TiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv57 || 128PiB || 64-bit only&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Feel free to choose between these modes as you see fit; this page will describe all of them. Note that in 64-bit systems, Sv39 is more than enough for most hobby operating systems (though it is not much more difficult to go further).&lt;br /&gt;
&lt;br /&gt;
=== Sv32 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Sv39 ===&lt;br /&gt;
&lt;br /&gt;
Sv39 is the simplest paging mode for 64-bit systems (though larger modes are not too much more difficult to implement). It supports the standard 4KiB pages, as well as 2MiB megapages and 1GiB gigapages. &lt;br /&gt;
&lt;br /&gt;
TODO: actually describe what a page table looks like, and also PTE's RWX encoding&lt;br /&gt;
&lt;br /&gt;
==== Address and PTE Layouts ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 virtual address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || Page VPN (&amp;lt;nowiki&amp;gt;VPN[0]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || Megapage VPN (&amp;lt;nowiki&amp;gt;VPN[1]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| 30-38 || 9 || Gigapage VPN (&amp;lt;nowiki&amp;gt;VPN[2]&amp;lt;/nowiki&amp;gt;)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 physical address&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-11 || 12 || Page offset&lt;br /&gt;
|-&lt;br /&gt;
| 12-20 || 9 || &amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 21-29 || 9 || &amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 30-55 || 26 || &amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mw-collapsible&amp;quot;&lt;br /&gt;
|+ Sv39 page table entry layout&lt;br /&gt;
|-&lt;br /&gt;
! Bit Range (inclusive) !! Length (bits) !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Valid flag (V)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Readable flag (R)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1 || Writable flag (W)&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || Executable flag (X)&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 1 || U-mode accessible flag (U)&lt;br /&gt;
|-&lt;br /&gt;
| 5 || 1 || Global flag (G)&lt;br /&gt;
|-&lt;br /&gt;
| 6 || 1 || Accessed flag (A)&lt;br /&gt;
|-&lt;br /&gt;
| 7 || 1 || Dirty flag (D)&lt;br /&gt;
|-&lt;br /&gt;
| 8-9 || 2 || RSW (TODO)&lt;br /&gt;
|-&lt;br /&gt;
| 10-18 || 9 || &amp;lt;nowiki&amp;gt;PPN[0]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 19-27 || 9 || &amp;lt;nowiki&amp;gt;PPN[1]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 28-53 || 26 || &amp;lt;nowiki&amp;gt;PPN[2]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 54-60 || 7 || Reserved&lt;br /&gt;
|-&lt;br /&gt;
| 61-62 || 2 || PBMT (TODO)&lt;br /&gt;
|-&lt;br /&gt;
| 63 || 1 || N bit (TODO)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sv48 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Sv57 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Enabling Paging ==&lt;br /&gt;
&lt;br /&gt;
TODO&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=12</id>
		<title>RISC-V/Paging</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=12"/>
		<updated>2022-11-24T02:53:52Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Describe PPNs and VPNs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Paging in RISC-V can be enabled by first setting up a page table, then pointing the CPU to that page table via the [[RISC-V/CSR#satp | &amp;lt;code&amp;gt;satp&amp;lt;/code&amp;gt; CSR]]. This article will describe these steps.&lt;br /&gt;
&lt;br /&gt;
== Terminology ==&lt;br /&gt;
&lt;br /&gt;
There are many acronyms and other terms that are used in the RISC-V specification which, for the purpose of brevity and consistency, will be used in this article as well. I will assume a baseline knowledge of the purpose and basics of paging and virtual addressing.&lt;br /&gt;
&lt;br /&gt;
=== PPNs and VPNs ===&lt;br /&gt;
&lt;br /&gt;
A physical page number (or PPN) is a unique, page-aligned identifier for a page in physical memory. The number of PPN segments for an address will depend on the paging mode.&lt;br /&gt;
&lt;br /&gt;
To construct a PPN from a physical address, you can simply (logically, not arithmetically) shift the value right by 12 bits (as 2**12 = 4096). Note that this operation will truncate the offset into the page, if the address was not page-aligned.&lt;br /&gt;
&lt;br /&gt;
A virtual page number (or VPN) is very similar to a PPN, but in the virtual address space. Again, the number of VPN segments for a virtual address will depend on the paging mode.&lt;br /&gt;
&lt;br /&gt;
== RISC-V Page Table Layout ==&lt;br /&gt;
&lt;br /&gt;
There are various paging modes available in the RISC-V ISA, differing by the number of virtual address bits:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Memory Size !! SXLEN&lt;br /&gt;
|-&lt;br /&gt;
| Sv32 || 4GiB || 32-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv39 || 512GiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv48 || 256TiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv57 || 128PiB || 64-bit only&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Feel free to choose between these modes as you see fit; this page will describe all of them. Note that in 64-bit systems, Sv39 is more than enough for most hobby operating systems (though it is not much more difficult to go further).&lt;br /&gt;
&lt;br /&gt;
=== Sv32 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Sv39 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Sv48 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Sv57 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Enabling Paging ==&lt;br /&gt;
&lt;br /&gt;
TODO&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=7</id>
		<title>RISC-V/Paging</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=RISC-V/Paging&amp;diff=7"/>
		<updated>2022-11-23T21:21:10Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Created page with &amp;quot;Paging in RISC-V can be enabled by first setting up a page table, then pointing the CPU to that page table via the  &amp;lt;code&amp;gt;satp&amp;lt;/code&amp;gt; CSR. This article will describe these steps.  == RISC-V Page Table Layout ==  There are various paging strategies available in the RISC-V ISA, differing by the number of virtual address bits: {| class=&amp;quot;wikitable&amp;quot; |- ! Name !! Memory Size !! SXLEN |- | Sv32 || 4GiB || 32-bit only |- | Sv39 || 512GiB || 64-bit only |- |...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Paging in RISC-V can be enabled by first setting up a page table, then pointing the CPU to that page table via the [[RISC-V/CSR#satp | &amp;lt;code&amp;gt;satp&amp;lt;/code&amp;gt; CSR]]. This article will describe these steps.&lt;br /&gt;
&lt;br /&gt;
== RISC-V Page Table Layout ==&lt;br /&gt;
&lt;br /&gt;
There are various paging strategies available in the RISC-V ISA, differing by the number of virtual address bits:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Memory Size !! SXLEN&lt;br /&gt;
|-&lt;br /&gt;
| Sv32 || 4GiB || 32-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv39 || 512GiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv48 || 256TiB || 64-bit only&lt;br /&gt;
|-&lt;br /&gt;
| Sv57 || 128PiB || 64-bit only&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Feel free to choose between these strategies as you see fit; this page will describe all of them. Note that in 64-bit systems, Sv39 is more than enough for most hobby operating systems (though it is not much more difficult to go further).&lt;br /&gt;
&lt;br /&gt;
=== Sv32 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Sv39 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Sv48 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== Sv57 ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Enabling Paging ==&lt;br /&gt;
&lt;br /&gt;
TODO&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.friendos.dev/index.php?title=Main_Page&amp;diff=6</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.friendos.dev/index.php?title=Main_Page&amp;diff=6"/>
		<updated>2022-11-23T20:11:02Z</updated>

		<summary type="html">&lt;p&gt;ThePuzzlemaker: Create a better welcome page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Welcome to the FriendOS Wiki! ==&lt;br /&gt;
&lt;br /&gt;
The FriendOS Wiki is a community-driven wiki for the [https://discord.gg/U9feA9z669 FriendOS Discord server]. This wiki, as well as the Discord server, are intended to create a more inclusive, supportive, and welcoming environment for people learning about operating systems development, which historically is not very common.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Helpful Links ==&lt;br /&gt;
&lt;br /&gt;
* [https://discord.gg/U9feA9z669 Discord invite link]&lt;br /&gt;
* [[Special:AllPages|See all pages]]&lt;/div&gt;</summary>
		<author><name>ThePuzzlemaker</name></author>
	</entry>
</feed>