<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://tech-pubs.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Raion</id>
	<title>TechPubs Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://tech-pubs.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Raion"/>
	<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php/Special:Contributions/Raion"/>
	<updated>2026-04-21T13:55:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Irixstat&amp;diff=490</id>
		<title>Irixstat</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Irixstat&amp;diff=490"/>
		<updated>2026-03-02T17:59:29Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;a screencap of irixstat on winterm &amp;#039;&amp;#039;&amp;#039;irixstat&amp;#039;&amp;#039;&amp;#039; is a program under development by Raion of IRIX Network that acts as an ncurses-based osview clone for IRIX.   == Program Overview == At the top each load average is printed on its own line, then total RAM of the system, then free RAM, CPU usage graph with delta calculations and a graph for memory...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Irixstat winterm.jpg|alt=irixstat, an ncurses application showing off load, memory and processes|thumb|a screencap of irixstat on winterm]]&lt;br /&gt;
&#039;&#039;&#039;irixstat&#039;&#039;&#039; is a program under development by [[User:Raion|Raion]] of IRIX Network that acts as an ncurses-based osview clone for IRIX. &lt;br /&gt;
&lt;br /&gt;
== Program Overview ==&lt;br /&gt;
At the top each load average is printed on its own line, then total RAM of the system, then free RAM, CPU usage graph with delta calculations and a graph for memory usage. Below that, a top process chart. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;As of 2026, irixstat does not perform any process management or system management tools. It&#039;s merely a viewer.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Building irixstat ==&lt;br /&gt;
&#039;&#039;&#039;irixstat is packaged in nekoware&#039;&#039;&#039;, however it is buildable as well. To do so, install ncurses, [https://codeberg.org/SolusRaion/irixstat download the code], and adjust the Makefile.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=File:Irixstat_winterm.jpg&amp;diff=489</id>
		<title>File:Irixstat winterm.jpg</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=File:Irixstat_winterm.jpg&amp;diff=489"/>
		<updated>2026-03-02T17:54:14Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;irixstat application in winterm/xwsh&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Ethernet_Drivers&amp;diff=488</id>
		<title>Kernel: Ethernet Drivers</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Ethernet_Drivers&amp;diff=488"/>
		<updated>2026-02-06T07:05:43Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This document describes the architecture and common patterns for Ethernet network drivers in IRIX based on analysis of three production drivers: Alteon Tigon (high-end), TI ThunderLAN (mid-range O2), and IOC3 (integrated ASIC). Understanding these patterns is essential for porting modern Ethernet controllers to IRIX.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
IRIX Ethernet drivers follow a consistent architecture across all hardware:&lt;br /&gt;
* &#039;&#039;&#039;PCI infrastructure integration&#039;&#039;&#039; via pciio_* APIs&lt;br /&gt;
* &#039;&#039;&#039;Hardware graph (hwgraph) registration&#039;&#039;&#039; for device discovery&lt;br /&gt;
* &#039;&#039;&#039;Etherif framework&#039;&#039;&#039; providing standard network interface&lt;br /&gt;
* &#039;&#039;&#039;Descriptor ring management&#039;&#039;&#039; for DMA transfers&lt;br /&gt;
* &#039;&#039;&#039;Interrupt handling&#039;&#039;&#039; at splimp() level&lt;br /&gt;
* &#039;&#039;&#039;MII/PHY management&#039;&#039;&#039; for link negotiation&lt;br /&gt;
* &#039;&#039;&#039;Packet scheduling&#039;&#039;&#039; (RSVP) support&lt;br /&gt;
&lt;br /&gt;
== Driver Initialization Flow ==&lt;br /&gt;
&lt;br /&gt;
=== Module Loading ===&lt;br /&gt;
&lt;br /&gt;
All drivers follow this initialization sequence:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;if_XXinit()&#039;&#039;&#039; - Called once at boot by edtinit()&lt;br /&gt;
#* Registers PCI vendor/device IDs via pciio_driver_register()&lt;br /&gt;
#* Registers idbg debug functions&lt;br /&gt;
# &#039;&#039;&#039;if_XXattach()&#039;&#039;&#039; - Called for each matching PCI device&lt;br /&gt;
#* Creates hwgraph vertices&lt;br /&gt;
#* Maps PCI memory regions&lt;br /&gt;
#* Allocates descriptor rings&lt;br /&gt;
#* Initializes hardware&lt;br /&gt;
#* Registers interrupt handlers&lt;br /&gt;
# &#039;&#039;&#039;if_XXopen()&#039;&#039;&#039; - Called when interface is configured&lt;br /&gt;
#* Gets unit number from device_controller_num_get()&lt;br /&gt;
#* Calls ether_attach() to register with network stack&lt;br /&gt;
&lt;br /&gt;
=== Critical Initialization Order ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. pciio_driver_register() - Register with PCI subsystem&lt;br /&gt;
2. Allocate private state structure (ei/ti/ei_info)&lt;br /&gt;
3. hwgraph_char_device_add() - Create device vertex&lt;br /&gt;
4. pciio_piotrans_addr() - Map register spaces&lt;br /&gt;
5. Allocate DMA-able memory via contig_memalloc()&lt;br /&gt;
6. Initialize hardware (reset, PHY, MAC)&lt;br /&gt;
7. pciio_intr_alloc() + pciio_intr_connect()&lt;br /&gt;
8. ether_attach() - Final registration&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Memory Management ==&lt;br /&gt;
&lt;br /&gt;
=== DMA Memory Allocation ===&lt;br /&gt;
&lt;br /&gt;
IRIX requires &#039;&#039;&#039;physically contiguous memory&#039;&#039;&#039; for DMA descriptor rings. Use contig_memalloc() with specific alignment requirements:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Descriptor Ring Requirements:&#039;&#039;&#039;&lt;br /&gt;
* Alteon TX ring: 64K alignment for 512-entry ring&lt;br /&gt;
* IOC3 TX ring: 64K alignment for 512-entry ring&lt;br /&gt;
* IOC3 RX ring: 4K alignment&lt;br /&gt;
* ThunderLAN: Page-aligned&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example (IOC3):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
size = NTXD * TXDSZ;  // 512 * 128 bytes&lt;br /&gt;
npgs = (size + NBPP - 1) / NBPP;&lt;br /&gt;
pgno = contig_memalloc(npgs, ALIGNMENT_PAGES, VM_DIRECT);&lt;br /&gt;
ei-&amp;gt;txd = (struct eftxd*)small_pfntova_K0(pgno);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cache Coherency - CRITICAL ===&lt;br /&gt;
&lt;br /&gt;
IRIX systems (especially Origin/Octane with Heart chipset) require &#039;&#039;&#039;explicit cache management&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Heart Coherency WAR:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if HEART_COHERENCY_WAR&lt;br /&gt;
#define CACHE_WB(addr, len) heart_dcache_wb_inval((addr), (len))&lt;br /&gt;
#else&lt;br /&gt;
#define CACHE_WB(addr, len)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if HEART_INVALIDATE_WAR  &lt;br /&gt;
#define CACHE_INVAL(addr, len) heart_invalidate_war((addr), (len))&lt;br /&gt;
#else&lt;br /&gt;
#define CACHE_INVAL(addr, len)&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;When to flush caches:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Before DMA read (RX):&#039;&#039;&#039; CACHE_INVAL() on receive buffers&lt;br /&gt;
* &#039;&#039;&#039;Before DMA write (TX):&#039;&#039;&#039; CACHE_WB() on transmit data&lt;br /&gt;
* &#039;&#039;&#039;After descriptor update:&#039;&#039;&#039; CACHE_WB() on descriptor memory&lt;br /&gt;
* &#039;&#039;&#039;IP32 (O2) specific:&#039;&#039;&#039; Always use __vm_dcache_inval() and dki_dcache_wb()&lt;br /&gt;
&lt;br /&gt;
== PCI Infrastructure Integration ==&lt;br /&gt;
&lt;br /&gt;
=== Address Translation ===&lt;br /&gt;
&lt;br /&gt;
IRIX requires explicit DMA address translation for 64-bit capable devices:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Command DMA (descriptors, control):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define KVTOIOADDR_CMD(ei, addr) \&lt;br /&gt;
    pciio_dmatrans_addr((ei)-&amp;gt;conn_vhdl, 0, \&lt;br /&gt;
        kvtophys((caddr_t)(addr)), sizeof(int), \&lt;br /&gt;
        PCIIO_DMA_A64 | PCIIO_DMA_CMD)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data DMA (packet buffers):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Fast path using pre-allocated DMA map&lt;br /&gt;
#define KVTOIOADDR_DATA(ei, addr) \&lt;br /&gt;
    pciio_dmamap_addr((ei)-&amp;gt;fastmap, \&lt;br /&gt;
        kvtophys((caddr_t)(addr)), sizeof(int))&lt;br /&gt;
&lt;br /&gt;
// Allocate fast map during init:&lt;br /&gt;
ei-&amp;gt;fastmap = pciio_dmamap_alloc(conn_vhdl, dev_desc, &lt;br /&gt;
    sizeof(int), PCIIO_DMA_DATA | PCIIO_DMA_A64 | PCIIO_FIXED);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interrupt Registration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Set interrupt name and priority&lt;br /&gt;
device_desc_intr_name_set(dev_desc, &amp;quot;Ethernet&amp;quot;);&lt;br /&gt;
device_desc_intr_swlevel_set(dev_desc, (ilvl_t)splimp);&lt;br /&gt;
&lt;br /&gt;
// Allocate and connect interrupt&lt;br /&gt;
ei-&amp;gt;intr = pciio_intr_alloc(conn_vhdl, dev_desc, &lt;br /&gt;
                             PCIIO_INTR_LINE_A, enet_vhdl);&lt;br /&gt;
pciio_intr_connect(ei-&amp;gt;intr, (intr_func_t)if_XXintr, &lt;br /&gt;
                   (intr_arg_t)ei, NULL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Descriptor Ring Architecture ==&lt;br /&gt;
&lt;br /&gt;
All three drivers use &#039;&#039;&#039;producer/consumer ring buffers&#039;&#039;&#039; with hardware/software indices:&lt;br /&gt;
&lt;br /&gt;
=== Common Ring Structure ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct driver_info {&lt;br /&gt;
    // TX ring&lt;br /&gt;
    struct txd *txd;           // TX descriptor array&lt;br /&gt;
    struct mbuf **txm;         // Pending TX mbufs&lt;br /&gt;
    int txhead;                // SW produce index&lt;br /&gt;
    int txtail;                // SW consume index&lt;br /&gt;
    &lt;br /&gt;
    // RX ring  &lt;br /&gt;
    struct rxd *rxd;           // RX descriptor array&lt;br /&gt;
    struct mbuf **rxm;         // Posted RX mbufs&lt;br /&gt;
    int rxhead;                // SW consume index&lt;br /&gt;
    int rxtail;                // SW produce index&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ring Index Management ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Critical macro patterns:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define NEXTTXD(i) (((i) + 1) &amp;amp; (NTXD - 1))  // Ring must be power-of-2&lt;br /&gt;
#define DELTATXD(h,t) ((h - t) &amp;amp; (NTXD - 1)) // Free descriptors&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IOC3-specific gotcha:&#039;&#039;&#039; Hardware compares RX indices modulo-16, so allocate 15 extra buffers:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define NRBUFADJ(n) (n + 15)  // Required for IOC3 only&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Transmit Path ==&lt;br /&gt;
&lt;br /&gt;
=== Etherif Transmit Function ===&lt;br /&gt;
&lt;br /&gt;
The transmit function must handle:&lt;br /&gt;
# Mbuf chain validation and coalescing&lt;br /&gt;
# Ethernet header insertion&lt;br /&gt;
# DMA address setup&lt;br /&gt;
# Descriptor programming&lt;br /&gt;
# Hardware checksum offload (if supported)&lt;br /&gt;
# Self-snoop for packet capture&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Typical signature:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int XX_transmit(&lt;br /&gt;
    struct etherif *eif,&lt;br /&gt;
    struct etheraddr *edst,   // Destination MAC&lt;br /&gt;
    struct etheraddr *esrc,   // Source MAC  &lt;br /&gt;
    u_short type,             // EtherType&lt;br /&gt;
    struct mbuf *m0)          // Packet chain&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mbuf Alignment Requirements ===&lt;br /&gt;
&lt;br /&gt;
Different hardware has different alignment constraints:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IOC3 requirements:&#039;&#039;&#039;&lt;br /&gt;
* Data0 (in descriptor): must be even length if buf1 is used&lt;br /&gt;
* Buf1 pointer: must be 2-byte aligned&lt;br /&gt;
* Buf2 pointer: must be 128-byte aligned AND buf1 must be even length&lt;br /&gt;
* No buffer may cross page boundary&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution patterns:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Check alignment&lt;br /&gt;
#define MALIGN2(m)   ALIGNED(mtod((m), u_long), 2)&lt;br /&gt;
#define MALIGN128(m) ALIGNED(mtod((m), u_long), 128)&lt;br /&gt;
&lt;br /&gt;
// Copy if misaligned&lt;br /&gt;
if (!MALIGN2(m0) || mbuf_crosses_page(m0))&lt;br /&gt;
    goto copyall;&lt;br /&gt;
&lt;br /&gt;
copyall:&lt;br /&gt;
    m = m_vget(M_DONTWAIT, mlen, MT_DATA);&lt;br /&gt;
    m_datacopy(m0, 0, mlen, mtod(m, caddr_t));&lt;br /&gt;
    m_freem(m0);&lt;br /&gt;
    m0 = m;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hardware Checksum Offload ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IOC3 TX checksum:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if (m0-&amp;gt;m_flags &amp;amp; M_CKSUMMED) {&lt;br /&gt;
    struct ip *ip = mtod(m0, struct ip*);&lt;br /&gt;
    int hlen = ip-&amp;gt;ip_hl &amp;lt;&amp;lt; 2;&lt;br /&gt;
    &lt;br /&gt;
    // Compute pseudo-header checksum&lt;br /&gt;
    __uint32_t cksum = ((ip-&amp;gt;ip_len - hlen)&lt;br /&gt;
        + htons((ushort)ip-&amp;gt;ip_p)&lt;br /&gt;
        + (ip-&amp;gt;ip_src.s_addr &amp;gt;&amp;gt; 16)&lt;br /&gt;
        + (ip-&amp;gt;ip_src.s_addr &amp;amp; 0xffff)&lt;br /&gt;
        + (ip-&amp;gt;ip_dst.s_addr &amp;gt;&amp;gt; 16)  &lt;br /&gt;
        + (ip-&amp;gt;ip_dst.s_addr &amp;amp; 0xffff));&lt;br /&gt;
    &lt;br /&gt;
    // Subtract ethernet header contribution&lt;br /&gt;
    cksum += 0xffff ^ (type + MAC_checksum_contrib);&lt;br /&gt;
    &lt;br /&gt;
    // Store adjustment in TCP/UDP header&lt;br /&gt;
    mtod(m0, u_short*)[sumoff/2] = fold_checksum(cksum);&lt;br /&gt;
    &lt;br /&gt;
    // Set descriptor flags&lt;br /&gt;
    txd-&amp;gt;cmd |= (sumoff &amp;lt;&amp;lt; ETXD_CHKOFF_SHIFT) | ETXD_DOCHECKSUM;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Errata:&#039;&#039;&#039; IOC3 rev 0 has a bug - it fails to take one&#039;s complement. Disable TX checksum for rev 0 chips.&lt;br /&gt;
&lt;br /&gt;
=== Descriptor Update Pattern ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Fill descriptor fields&lt;br /&gt;
txd-&amp;gt;cmd = flags | length;&lt;br /&gt;
txd-&amp;gt;bufcnt = total_length;&lt;br /&gt;
txd-&amp;gt;p1 = KVTOIOADDR_DATA(ei, mbuf_data);&lt;br /&gt;
&lt;br /&gt;
// CRITICAL: Writeback cache before hardware sees it&lt;br /&gt;
CACHE_WB((void *)txd, TXDSZ);&lt;br /&gt;
&lt;br /&gt;
// Save mbuf for later freeing&lt;br /&gt;
ei-&amp;gt;txm[ei-&amp;gt;txhead] = m0;&lt;br /&gt;
&lt;br /&gt;
// Update software index&lt;br /&gt;
ei-&amp;gt;txhead = NEXTTXD(ei-&amp;gt;txhead);&lt;br /&gt;
&lt;br /&gt;
// Notify hardware (write produce register)&lt;br /&gt;
W_REG(ei-&amp;gt;regs-&amp;gt;etpir, (ei-&amp;gt;txhead * TXDSZ));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Receive Path ==&lt;br /&gt;
&lt;br /&gt;
=== RX Buffer Posting ===&lt;br /&gt;
&lt;br /&gt;
Drivers must maintain a pool of posted receive buffers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void ef_fill(struct ef_info *ei) {&lt;br /&gt;
    int head = ei-&amp;gt;rxhead;&lt;br /&gt;
    int tail = ei-&amp;gt;rxtail;&lt;br /&gt;
    int n = ei-&amp;gt;nrbuf - DELTARXD(head, tail);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; n; i++) {&lt;br /&gt;
        m = m_vget(M_DONTWAIT, sizeof(struct rxbuf), MT_DATA);&lt;br /&gt;
        if (!m) break;&lt;br /&gt;
        &lt;br /&gt;
        rb = mtod(m, struct rxbuf*);&lt;br /&gt;
        ei-&amp;gt;rxm[tail] = m;&lt;br /&gt;
        ei-&amp;gt;rxd[tail] = KVTOIOADDR_DATA(ei, rb);&lt;br /&gt;
        &lt;br /&gt;
        // Invalidate for DMA&lt;br /&gt;
        CACHE_INVAL(rb, sizeof(struct rxbuf));&lt;br /&gt;
        CACHE_WB(mtod(m, caddr_t), sizeof(struct rxbuf));&lt;br /&gt;
        &lt;br /&gt;
        tail = NEXTRXD(tail);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ei-&amp;gt;rxtail = tail;&lt;br /&gt;
    W_REG(ei-&amp;gt;regs-&amp;gt;erpir, (ERPIR_ARM | (tail * RXDSZ)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interrupt Handler ===&lt;br /&gt;
&lt;br /&gt;
IRIX interrupt handlers run at &#039;&#039;&#039;splimp()&#039;&#039;&#039; priority and must:&lt;br /&gt;
# Read/clear interrupt status&lt;br /&gt;
# Process received packets&lt;br /&gt;
# Reclaim completed TX descriptors  &lt;br /&gt;
# Rearm interrupt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Typical pattern:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void if_XXintr(struct XX_info *ei) {&lt;br /&gt;
    int s;&lt;br /&gt;
    struct mbuf *mact, *m;&lt;br /&gt;
    &lt;br /&gt;
    s = mutex_bitlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK);&lt;br /&gt;
    &lt;br /&gt;
    // Read and clear interrupt status&lt;br /&gt;
    isr = R_REG(ei-&amp;gt;regs-&amp;gt;eisr);&lt;br /&gt;
    W_REG(ei-&amp;gt;regs-&amp;gt;eisr, isr);&lt;br /&gt;
    &lt;br /&gt;
    // Process RX&lt;br /&gt;
    if (isr &amp;amp; EISR_RXTHRESH) {&lt;br /&gt;
        mact = ef_recv(ei);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Reclaim TX&lt;br /&gt;
    if (isr &amp;amp; EISR_TXDONE) {&lt;br /&gt;
        ef_reclaim(ei);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Handle errors&lt;br /&gt;
    if (isr &amp;amp; EISR_ERROR) {&lt;br /&gt;
        handle_errors(ei);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Rearm&lt;br /&gt;
    W_REG(ei-&amp;gt;regs-&amp;gt;erpir, ERPIR_ARM | produce_index);&lt;br /&gt;
    &lt;br /&gt;
    mutex_bitunlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK, s);&lt;br /&gt;
    &lt;br /&gt;
    // Send packets up AFTER releasing lock&lt;br /&gt;
    while (mact) {&lt;br /&gt;
        m = mact;&lt;br /&gt;
        mact = mact-&amp;gt;m_act;&lt;br /&gt;
        ether_input(&amp;amp;ei-&amp;gt;eif, 0, m);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RX Checksum Validation ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if ((ntohs(eh-&amp;gt;ether_type) == ETHERTYPE_IP)&lt;br /&gt;
    &amp;amp;&amp;amp; (rlen &amp;gt;= 60)  &lt;br /&gt;
    &amp;amp;&amp;amp; ((ip-&amp;gt;ip_off &amp;amp; (IP_OFFMASK|IP_MF)) == 0)&lt;br /&gt;
    &amp;amp;&amp;amp; ((ip-&amp;gt;ip_p == IPPROTO_TCP) || (ip-&amp;gt;ip_p == IPPROTO_UDP))) {&lt;br /&gt;
    &lt;br /&gt;
    // IOC3 provides checksum in descriptor&lt;br /&gt;
    cksum = rxd-&amp;gt;w0 &amp;amp; ERXBUF_IPCKSUM_MASK;&lt;br /&gt;
    &lt;br /&gt;
    // Finish calculation (add pseudo-header, subtract ether header)&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
    if (cksum == 0xffff)&lt;br /&gt;
        m-&amp;gt;m_flags |= M_CKSUMMED;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PHY Management (MII Interface) ==&lt;br /&gt;
&lt;br /&gt;
=== PHY Detection and Reset ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int ef_phyprobe(struct ef_info *ei) {&lt;br /&gt;
    int i, r2, r3, val;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 32; i++) {&lt;br /&gt;
        ei-&amp;gt;phyunit = i;&lt;br /&gt;
        r2 = ef_phyget(ei, MII_PHY_ID_HI);&lt;br /&gt;
        r3 = ef_phyget(ei, MII_PHY_ID_LO);&lt;br /&gt;
        val = (r2 &amp;lt;&amp;lt; 12) | (r3 &amp;gt;&amp;gt; 4);&lt;br /&gt;
        &lt;br /&gt;
        switch (val) {&lt;br /&gt;
        case PHY_QS6612X:&lt;br /&gt;
        case PHY_ICS1889:&lt;br /&gt;
        case PHY_DP83840:&lt;br /&gt;
            ei-&amp;gt;phytype = val;&lt;br /&gt;
            ei-&amp;gt;phyrev = r3 &amp;amp; 0xf;&lt;br /&gt;
            return val;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return -1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MII Read/Write ===&lt;br /&gt;
&lt;br /&gt;
Hardware provides two main approaches:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Approach 1: Dedicated MII registers (IOC3, ThunderLAN):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int ef_phyget(struct ef_info *ei, int reg) {&lt;br /&gt;
    // Wait for ready&lt;br /&gt;
    while (regs-&amp;gt;micr &amp;amp; MICR_BUSY)&lt;br /&gt;
        DELAYBUS(1);&lt;br /&gt;
        &lt;br /&gt;
    // Trigger read&lt;br /&gt;
    regs-&amp;gt;micr = MICR_READTRIG | &lt;br /&gt;
                 (ei-&amp;gt;phyunit &amp;lt;&amp;lt; MICR_PHYADDR_SHIFT) | reg;&lt;br /&gt;
                 &lt;br /&gt;
    // Wait for completion&lt;br /&gt;
    while (regs-&amp;gt;micr &amp;amp; MICR_BUSY)&lt;br /&gt;
        DELAYBUS(1);&lt;br /&gt;
        &lt;br /&gt;
    return (regs-&amp;gt;midr_r &amp;amp; MIDR_DATA_MASK);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Approach 2: GPIO bit-banging (Alteon, ThunderLAN alt):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Send sync pattern (32 cycles of 1)&lt;br /&gt;
// Send start bits (01)&lt;br /&gt;
// Send opcode (10=read, 01=write)&lt;br /&gt;
// Send PHY address (5 bits)&lt;br /&gt;
// Send register (5 bits)&lt;br /&gt;
// Turnaround and read data (16 bits)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Auto-negotiation ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void ef_autonego(struct ef_info *ei) {&lt;br /&gt;
    int timeout = 20000;&lt;br /&gt;
    &lt;br /&gt;
    // Enable auto-negotiation&lt;br /&gt;
    ef_phyput(ei, MII_CTRL, MII_CTRL_AUTOEN | MII_CTRL_RESTART);&lt;br /&gt;
    &lt;br /&gt;
    // Wait for completion&lt;br /&gt;
    while (!(ef_phyget(ei, MII_STATUS) &amp;amp; MII_STATUS_ANDONE)) {&lt;br /&gt;
        DELAY(100);&lt;br /&gt;
        if (timeout-- &amp;lt;= 0) {&lt;br /&gt;
            // Default to 10Mbit half-duplex&lt;br /&gt;
            ei-&amp;gt;speed100 = 0;&lt;br /&gt;
            ei-&amp;gt;fullduplex = 0;&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Parse negotiation result&lt;br /&gt;
    r4 = ef_phyget(ei, MII_AN_ADV);&lt;br /&gt;
    r5 = ef_phyget(ei, MII_AN_LPAR);&lt;br /&gt;
    &lt;br /&gt;
    if ((r4 &amp;amp; MII_TXFD) &amp;amp;&amp;amp; (r5 &amp;amp; MII_TXFD)) {&lt;br /&gt;
        ei-&amp;gt;speed100 = 1;&lt;br /&gt;
        ei-&amp;gt;fullduplex = 1;&lt;br /&gt;
    } else if ((r4 &amp;amp; MII_TX) &amp;amp;&amp;amp; (r5 &amp;amp; MII_TX)) {&lt;br /&gt;
        ei-&amp;gt;speed100 = 1;&lt;br /&gt;
        ei-&amp;gt;fullduplex = 0;&lt;br /&gt;
    }&lt;br /&gt;
    // ... etc&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Watchdog and Error Handling ==&lt;br /&gt;
&lt;br /&gt;
=== Periodic Watchdog ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void ef_watchdog(struct ifnet *ifp) {&lt;br /&gt;
    struct ef_info *ei = eiftoei(ifptoeif(ifp));&lt;br /&gt;
    &lt;br /&gt;
    // Update statistics&lt;br /&gt;
    ef_getcdc(ei);  // Collision/defer counters&lt;br /&gt;
    &lt;br /&gt;
    // Check PHY status&lt;br /&gt;
    ef_phyerr(ei);&lt;br /&gt;
    &lt;br /&gt;
    // Reclaim TX descriptors&lt;br /&gt;
    ef_reclaim(ei);&lt;br /&gt;
    &lt;br /&gt;
    // Refill RX buffers&lt;br /&gt;
    ef_fill(ei);&lt;br /&gt;
    &lt;br /&gt;
    // Check for missed interrupts&lt;br /&gt;
    ef_intr(ei);&lt;br /&gt;
    &lt;br /&gt;
    // Reschedule&lt;br /&gt;
    ei-&amp;gt;if_timer = WATCHDOG_INTERVAL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Link State Monitoring ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void ef_phyerr(struct ef_info *ei) {&lt;br /&gt;
    int reg1 = ef_phyget(ei, MII_STATUS);&lt;br /&gt;
    &lt;br /&gt;
    // Link status (latched low, read twice)&lt;br /&gt;
    if (!(reg1 &amp;amp; MII_STATUS_LINK)) {&lt;br /&gt;
        if (!(ei-&amp;gt;flags &amp;amp; EIF_LINKDOWN)) {&lt;br /&gt;
            cmn_err(CE_WARN, &amp;quot;ef%d: link fail - check cable&amp;quot;, &lt;br /&gt;
                    ei-&amp;gt;unit);&lt;br /&gt;
            ei-&amp;gt;flags |= EIF_LINKDOWN;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        if (ei-&amp;gt;flags &amp;amp; EIF_LINKDOWN) {&lt;br /&gt;
            cmn_err(CE_NOTE, &amp;quot;ef%d: link ok&amp;quot;, ei-&amp;gt;unit);&lt;br /&gt;
            ei-&amp;gt;flags &amp;amp;= ~EIF_LINKDOWN;&lt;br /&gt;
            ef_reinit(ei);  // May need to adjust speed/duplex&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Check for remote fault, jabber, etc.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RSVP/Packet Scheduling ==&lt;br /&gt;
&lt;br /&gt;
IRIX supports packet scheduling for QoS. Drivers must:&lt;br /&gt;
# Report available TX descriptors&lt;br /&gt;
# Signal when descriptors become available&lt;br /&gt;
# Optionally interrupt on each TX completion when scheduling active&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int ef_txfree_len(struct ifnet *ifp) {&lt;br /&gt;
    struct ef_info *ei = eiftoei(ifptoeif(ifp));&lt;br /&gt;
    return (NTXD - DELTATXD(ei-&amp;gt;txhead, ei-&amp;gt;txtail));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static void ef_setstate(struct ifnet *ifp, int setting) {&lt;br /&gt;
    struct ef_info *ei = eiftoei(ifptoeif(ifp));&lt;br /&gt;
    if (setting)&lt;br /&gt;
        ei-&amp;gt;flags |= EIF_PSENABLED;&lt;br /&gt;
    else&lt;br /&gt;
        ei-&amp;gt;flags &amp;amp;= ~EIF_PSENABLED;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// In transmit path:&lt;br /&gt;
if ((ei-&amp;gt;flags &amp;amp; EIF_PSENABLED) &amp;amp;&amp;amp; &lt;br /&gt;
    ((ei-&amp;gt;txhead &amp;amp; ei-&amp;gt;intfreq) == 0)) {&lt;br /&gt;
    txd-&amp;gt;cmd |= ETXD_INTWHENDONE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// In interrupt handler:&lt;br /&gt;
if (ei-&amp;gt;flags &amp;amp; EIF_PSENABLED) {&lt;br /&gt;
    ps_txq_stat(eiftoifp(&amp;amp;ei-&amp;gt;eif), ef_txfree_len(&amp;amp;ei-&amp;gt;if));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// During init:&lt;br /&gt;
struct ps_parms ps_params;&lt;br /&gt;
ps_params.bandwidth = ei-&amp;gt;speed100 ? 100000000 : 10000000;&lt;br /&gt;
ps_params.flags = 0;&lt;br /&gt;
ps_params.txfree = NTXD;&lt;br /&gt;
ps_params.txfree_func = ef_txfree_len;&lt;br /&gt;
ps_params.state_func = ef_setstate;&lt;br /&gt;
ps_init(eiftoifp(&amp;amp;ei-&amp;gt;eif), &amp;amp;ps_params);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Locking and Synchronization ==&lt;br /&gt;
&lt;br /&gt;
IRIX uses &#039;&#039;&#039;bitlocks&#039;&#039;&#039; for driver synchronization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Initialize lock during attach&lt;br /&gt;
init_bitlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK, &amp;quot;ef drv lock&amp;quot;, 0);&lt;br /&gt;
&lt;br /&gt;
// Acquire in all paths that touch hardware&lt;br /&gt;
s = mutex_bitlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK);&lt;br /&gt;
// ... critical section ...&lt;br /&gt;
mutex_bitunlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK, s);&lt;br /&gt;
&lt;br /&gt;
// Check if locked (for assertions)&lt;br /&gt;
ASSERT(ei-&amp;gt;flags &amp;amp; EIF_LOCK);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lock hierarchy:&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;ifnet lock&#039;&#039;&#039; (IFNET_LOCK) - Highest level, held during ioctl&lt;br /&gt;
# &#039;&#039;&#039;Driver bitlock&#039;&#039;&#039; - Protects hardware access and descriptor rings&lt;br /&gt;
# &#039;&#039;&#039;Separate TX/RX locks&#039;&#039;&#039; - Some drivers use separate locks for TX and RX paths&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Critical sections that need locking:&#039;&#039;&#039;&lt;br /&gt;
* Descriptor ring manipulation&lt;br /&gt;
* Hardware register access&lt;br /&gt;
* mbuf list operations&lt;br /&gt;
* Statistics updates&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Operations outside lock:&#039;&#039;&#039;&lt;br /&gt;
* ether_input() - Network stack must be called without driver lock&lt;br /&gt;
* m_freem() - Can be called outside lock&lt;br /&gt;
&lt;br /&gt;
== Common Pitfalls and Gotchas ==&lt;br /&gt;
&lt;br /&gt;
=== Cache Coherency ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Forgetting cache flushes causes random packet corruption.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Always CACHE_WB before DMA write, CACHE_INVAL before DMA read.&lt;br /&gt;
&lt;br /&gt;
=== Descriptor Alignment ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Hardware silently uses wrong memory if alignment is incorrect.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Use contig_memalloc with correct alignment parameter.&lt;br /&gt;
&lt;br /&gt;
=== mbuf Chain Fragmentation ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Each mbuf may require a separate DMA descriptor, exhausting hardware resources.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Coalesce into single mbuf if chain too long or poorly aligned.&lt;br /&gt;
&lt;br /&gt;
=== Register Write Ordering ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Posted writes may not complete before hardware starts DMA.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Read back critical registers to force write completion:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
W_REG(ei-&amp;gt;regs-&amp;gt;emcr, EMCR_RST);&lt;br /&gt;
R_REG(ei-&amp;gt;regs-&amp;gt;emcr);  // Force write to complete&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOC3 RX Index Comparison ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Hardware compares RX indices modulo-16, causing premature ring full condition.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Post 15 extra buffers (NRBUFADJ macro).&lt;br /&gt;
&lt;br /&gt;
=== Interrupt Re-arming ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Forgetting to rearm causes no more interrupts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Always write to interrupt rearm register at end of handler.&lt;br /&gt;
&lt;br /&gt;
=== Link State During Init ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Reading MII status during PHY reset gives false link-down errors.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Delay link state checking until after auto-negotiation completes.&lt;br /&gt;
&lt;br /&gt;
=== Multicast Filter Collisions ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Multiple multicast addresses may hash to same filter bit.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Maintain collision counter; keep filter bit set if any addresses hash to it.&lt;br /&gt;
&lt;br /&gt;
== Hardware-Specific Considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Alteon Tigon ===&lt;br /&gt;
* &#039;&#039;&#039;Firmware loading&#039;&#039;&#039; - Must load code/data into on-chip SRAM&lt;br /&gt;
* &#039;&#039;&#039;Event ring&#039;&#039;&#039; - Asynchronous events in addition to interrupts&lt;br /&gt;
* &#039;&#039;&#039;Large SRAM&#039;&#039;&#039; - Can hold many packets on-chip&lt;br /&gt;
* &#039;&#039;&#039;Sophisticated coalescing&#039;&#039;&#039; - Configurable interrupt coalescing&lt;br /&gt;
&lt;br /&gt;
=== TI ThunderLAN ===&lt;br /&gt;
* &#039;&#039;&#039;List-based DMA&#039;&#039;&#039; - Multiple fragments per packet&lt;br /&gt;
* &#039;&#039;&#039;Integrated PHY&#039;&#039;&#039; - On-chip 10Mbit PHY plus MII for external PHY&lt;br /&gt;
* &#039;&#039;&#039;EEPROM access&#039;&#039;&#039; - Complex protocol for reading MAC address&lt;br /&gt;
* &#039;&#039;&#039;Dual channels&#039;&#039;&#039; - Separate TX/RX channels with independent DMA&lt;br /&gt;
&lt;br /&gt;
=== IOC3 ===&lt;br /&gt;
* &#039;&#039;&#039;Integrated PCI-X bridge&#039;&#039;&#039; - Shares functions with serial/parallel ports&lt;br /&gt;
* &#039;&#039;&#039;Hardware checksumming&#039;&#039;&#039; - TX and RX checksum offload&lt;br /&gt;
* &#039;&#039;&#039;SSRAM buffer&#039;&#039;&#039; - On-chip packet buffer (64KB or 128KB)&lt;br /&gt;
* &#039;&#039;&#039;Parity checking&#039;&#039;&#039; - Optional parity on SSRAM&lt;br /&gt;
* &#039;&#039;&#039;NIC EEPROM&#039;&#039;&#039; - Number-in-a-can for MAC address&lt;br /&gt;
&lt;br /&gt;
== Testing and Debugging ==&lt;br /&gt;
&lt;br /&gt;
=== Debug Print Macros ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define DBG_PRINT(a) if (ei-&amp;gt;if_flags &amp;amp; IFF_DEBUG) printf a&lt;br /&gt;
&lt;br /&gt;
// Usage:&lt;br /&gt;
DBG_PRINT((&amp;quot;ef%d: txhead=%d txtail=%d\n&amp;quot;, unit, txhead, txtail));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dump Functions ===&lt;br /&gt;
Every driver should provide idbg dump functions:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
idbg_addfunc(&amp;quot;ef_dump&amp;quot;, (void (*)())ef_dump);&lt;br /&gt;
&lt;br /&gt;
static void ef_dump(int unit) {&lt;br /&gt;
    ef_dumpif(ifp);    // Interface statistics&lt;br /&gt;
    ef_dumpei(ei);     // Driver private state&lt;br /&gt;
    ef_dumpregs(ei);   // Hardware registers&lt;br /&gt;
    ef_dumpphy(ei);    // PHY registers&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Common Debug Points ===&lt;br /&gt;
* RX ring full - Check if ef_fill() is being called&lt;br /&gt;
* TX ring full - Check if ef_reclaim() is working  &lt;br /&gt;
* Checksum failures - Verify pseudo-header calculation&lt;br /&gt;
* Link flapping - Check PHY registers and cable&lt;br /&gt;
* DMA errors - Verify descriptor alignment and cache flushing&lt;br /&gt;
* Interrupt storms - Ensure status register is being cleared&lt;br /&gt;
&lt;br /&gt;
== Porting Checklist ==&lt;br /&gt;
&lt;br /&gt;
When porting a new Ethernet controller to IRIX:&lt;br /&gt;
&lt;br /&gt;
=== 1. PCI Infrastructure ===&lt;br /&gt;
* Register vendor/device ID in if_XXinit()&lt;br /&gt;
* Map register spaces with pciio_piotrans_addr()&lt;br /&gt;
* Enable bus master and memory space in PCI config&lt;br /&gt;
* Set cache line size and latency timer&lt;br /&gt;
&lt;br /&gt;
=== 2. Memory Management ===&lt;br /&gt;
* Allocate descriptor rings with contig_memalloc()&lt;br /&gt;
* Verify alignment requirements met&lt;br /&gt;
* Allocate mbuf tracking arrays with kmem_zalloc()&lt;br /&gt;
* Create fast DMA map with pciio_dmamap_alloc()&lt;br /&gt;
&lt;br /&gt;
=== 3. Hardware Initialization ===&lt;br /&gt;
* Reset chip and verify self-test passes&lt;br /&gt;
* Probe and initialize PHY&lt;br /&gt;
* Configure MAC address from EEPROM/NIC&lt;br /&gt;
* Set up descriptor ring base addresses&lt;br /&gt;
* Configure DMA parameters (burst size, etc.)&lt;br /&gt;
* Enable checksumming if supported&lt;br /&gt;
&lt;br /&gt;
=== 4. Descriptor Management ===&lt;br /&gt;
* Implement ring index macros (NEXT, DELTA)&lt;br /&gt;
* Handle cache coherency (CACHE_WB/CACHE_INVAL)&lt;br /&gt;
* Translate addresses with KVTOIOADDR_CMD/DATA&lt;br /&gt;
* Post initial RX buffers&lt;br /&gt;
&lt;br /&gt;
=== 5. Interrupt Handling ===&lt;br /&gt;
* Register handler with pciio_intr_alloc/connect&lt;br /&gt;
* Read and clear interrupt status&lt;br /&gt;
* Process RX and TX completions&lt;br /&gt;
* Handle error conditions&lt;br /&gt;
* Rearm interrupts&lt;br /&gt;
&lt;br /&gt;
=== 6. Network Integration ===&lt;br /&gt;
* Implement etherif operations vector&lt;br /&gt;
* Call ether_attach() with correct inventory type&lt;br /&gt;
* Support multicast filtering&lt;br /&gt;
* Implement SIOCADDMULTI/SIOCDELMULTI ioctls&lt;br /&gt;
* Handle IFF_PROMISC and IFF_ALLMULTI&lt;br /&gt;
&lt;br /&gt;
=== 7. Packet Scheduling ===&lt;br /&gt;
* Implement txfree_len callback&lt;br /&gt;
* Implement setstate callback&lt;br /&gt;
* Call ps_init() during initialization&lt;br /&gt;
* Optionally interrupt per-packet when PS enabled&lt;br /&gt;
&lt;br /&gt;
=== 8. Testing ===&lt;br /&gt;
* Basic ping test (small packets)&lt;br /&gt;
* Large transfer test (TCP bulk data)&lt;br /&gt;
* Multicast functionality&lt;br /&gt;
* Promiscuous mode (tcpdump)&lt;br /&gt;
* Link up/down handling&lt;br /&gt;
* Error recovery (cable unplug/replug)&lt;br /&gt;
* Performance testing (ttcp, netperf)&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
IRIX Ethernet drivers follow a well-defined architecture that balances hardware flexibility with software consistency. Key principles:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Explicit cache management&#039;&#039;&#039; for DMA coherency&lt;br /&gt;
* &#039;&#039;&#039;Physically contiguous&#039;&#039;&#039; descriptor rings&lt;br /&gt;
* &#039;&#039;&#039;Producer/consumer rings&#039;&#039;&#039; with power-of-2 sizes&lt;br /&gt;
* &#039;&#039;&#039;Bitlocks&#039;&#039;&#039; for synchronization&lt;br /&gt;
* &#039;&#039;&#039;PHY auto-negotiation&#039;&#039;&#039; with error recovery&lt;br /&gt;
* &#039;&#039;&#039;Hardware/software index split&#039;&#039;&#039; for lock-free updates&lt;br /&gt;
* &#039;&#039;&#039;PCI infrastructure integration&#039;&#039;&#039; for portability&lt;br /&gt;
&lt;br /&gt;
Understanding these patterns enables efficient porting of modern Ethernet controllers to the IRIX platform while avoiding common pitfalls around cache coherency, alignment, and interrupt handling.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Ethernet_Drivers&amp;diff=487</id>
		<title>Kernel: Ethernet Drivers</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Ethernet_Drivers&amp;diff=487"/>
		<updated>2026-02-06T07:04:28Z</updated>

		<summary type="html">&lt;p&gt;Raion: Initial Commit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This document describes the architecture and common patterns for Ethernet network drivers in IRIX based on analysis of three production drivers: Alteon Tigon (high-end), TI ThunderLAN (mid-range O2), and IOC3 (integrated ASIC). Understanding these patterns is essential for porting modern Ethernet controllers to IRIX.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
IRIX Ethernet drivers follow a consistent architecture across all hardware:&lt;br /&gt;
* &#039;&#039;&#039;PCI infrastructure integration&#039;&#039;&#039; via pciio_* APIs&lt;br /&gt;
* &#039;&#039;&#039;Hardware graph (hwgraph) registration&#039;&#039;&#039; for device discovery&lt;br /&gt;
* &#039;&#039;&#039;Etherif framework&#039;&#039;&#039; providing standard network interface&lt;br /&gt;
* &#039;&#039;&#039;Descriptor ring management&#039;&#039;&#039; for DMA transfers&lt;br /&gt;
* &#039;&#039;&#039;Interrupt handling&#039;&#039;&#039; at splimp() level&lt;br /&gt;
* &#039;&#039;&#039;MII/PHY management&#039;&#039;&#039; for link negotiation&lt;br /&gt;
* &#039;&#039;&#039;Packet scheduling&#039;&#039;&#039; (RSVP) support&lt;br /&gt;
&lt;br /&gt;
== Driver Initialization Flow ==&lt;br /&gt;
&lt;br /&gt;
=== Module Loading ===&lt;br /&gt;
&lt;br /&gt;
All drivers follow this initialization sequence:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;if_XXinit()&#039;&#039;&#039; - Called once at boot by edtinit()&lt;br /&gt;
#* Registers PCI vendor/device IDs via pciio_driver_register()&lt;br /&gt;
#* Registers idbg debug functions&lt;br /&gt;
# &#039;&#039;&#039;if_XXattach()&#039;&#039;&#039; - Called for each matching PCI device&lt;br /&gt;
#* Creates hwgraph vertices&lt;br /&gt;
#* Maps PCI memory regions&lt;br /&gt;
#* Allocates descriptor rings&lt;br /&gt;
#* Initializes hardware&lt;br /&gt;
#* Registers interrupt handlers&lt;br /&gt;
# &#039;&#039;&#039;if_XXopen()&#039;&#039;&#039; - Called when interface is configured&lt;br /&gt;
#* Gets unit number from device_controller_num_get()&lt;br /&gt;
#* Calls ether_attach() to register with network stack&lt;br /&gt;
&lt;br /&gt;
=== Critical Initialization Order ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. pciio_driver_register() - Register with PCI subsystem&lt;br /&gt;
2. Allocate private state structure (ei/ti/ei_info)&lt;br /&gt;
3. hwgraph_char_device_add() - Create device vertex&lt;br /&gt;
4. pciio_piotrans_addr() - Map register spaces&lt;br /&gt;
5. Allocate DMA-able memory via contig_memalloc()&lt;br /&gt;
6. Initialize hardware (reset, PHY, MAC)&lt;br /&gt;
7. pciio_intr_alloc() + pciio_intr_connect()&lt;br /&gt;
8. ether_attach() - Final registration&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Memory Management ==&lt;br /&gt;
&lt;br /&gt;
=== DMA Memory Allocation ===&lt;br /&gt;
&lt;br /&gt;
IRIX requires &#039;&#039;&#039;physically contiguous memory&#039;&#039;&#039; for DMA descriptor rings. Use contig_memalloc() with specific alignment requirements:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Descriptor Ring Requirements:&#039;&#039;&#039;&lt;br /&gt;
* Alteon TX ring: 64K alignment for 512-entry ring&lt;br /&gt;
* IOC3 TX ring: 64K alignment for 512-entry ring&lt;br /&gt;
* IOC3 RX ring: 4K alignment&lt;br /&gt;
* ThunderLAN: Page-aligned&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example (IOC3):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
size = NTXD * TXDSZ;  // 512 * 128 bytes&lt;br /&gt;
npgs = (size + NBPP - 1) / NBPP;&lt;br /&gt;
pgno = contig_memalloc(npgs, ALIGNMENT_PAGES, VM_DIRECT);&lt;br /&gt;
ei-&amp;gt;txd = (struct eftxd*)small_pfntova_K0(pgno);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cache Coherency - CRITICAL ===&lt;br /&gt;
&lt;br /&gt;
IRIX systems (especially Origin/Octane with Heart chipset) require &#039;&#039;&#039;explicit cache management&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Heart Coherency WAR:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#if HEART_COHERENCY_WAR&lt;br /&gt;
#define CACHE_WB(addr, len) heart_dcache_wb_inval((addr), (len))&lt;br /&gt;
#else&lt;br /&gt;
#define CACHE_WB(addr, len)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if HEART_INVALIDATE_WAR  &lt;br /&gt;
#define CACHE_INVAL(addr, len) heart_invalidate_war((addr), (len))&lt;br /&gt;
#else&lt;br /&gt;
#define CACHE_INVAL(addr, len)&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;When to flush caches:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Before DMA read (RX):&#039;&#039;&#039; CACHE_INVAL() on receive buffers&lt;br /&gt;
* &#039;&#039;&#039;Before DMA write (TX):&#039;&#039;&#039; CACHE_WB() on transmit data&lt;br /&gt;
* &#039;&#039;&#039;After descriptor update:&#039;&#039;&#039; CACHE_WB() on descriptor memory&lt;br /&gt;
* &#039;&#039;&#039;IP32 (O2) specific:&#039;&#039;&#039; Always use __vm_dcache_inval() and dki_dcache_wb()&lt;br /&gt;
&lt;br /&gt;
== PCI Infrastructure Integration ==&lt;br /&gt;
&lt;br /&gt;
=== Address Translation ===&lt;br /&gt;
&lt;br /&gt;
IRIX requires explicit DMA address translation for 64-bit capable devices:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Command DMA (descriptors, control):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define KVTOIOADDR_CMD(ei, addr) \&lt;br /&gt;
    pciio_dmatrans_addr((ei)-&amp;gt;conn_vhdl, 0, \&lt;br /&gt;
        kvtophys((caddr_t)(addr)), sizeof(int), \&lt;br /&gt;
        PCIIO_DMA_A64 | PCIIO_DMA_CMD)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data DMA (packet buffers):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Fast path using pre-allocated DMA map&lt;br /&gt;
#define KVTOIOADDR_DATA(ei, addr) \&lt;br /&gt;
    pciio_dmamap_addr((ei)-&amp;gt;fastmap, \&lt;br /&gt;
        kvtophys((caddr_t)(addr)), sizeof(int))&lt;br /&gt;
&lt;br /&gt;
// Allocate fast map during init:&lt;br /&gt;
ei-&amp;gt;fastmap = pciio_dmamap_alloc(conn_vhdl, dev_desc, &lt;br /&gt;
    sizeof(int), PCIIO_DMA_DATA | PCIIO_DMA_A64 | PCIIO_FIXED);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interrupt Registration ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Set interrupt name and priority&lt;br /&gt;
device_desc_intr_name_set(dev_desc, &amp;quot;Ethernet&amp;quot;);&lt;br /&gt;
device_desc_intr_swlevel_set(dev_desc, (ilvl_t)splimp);&lt;br /&gt;
&lt;br /&gt;
// Allocate and connect interrupt&lt;br /&gt;
ei-&amp;gt;intr = pciio_intr_alloc(conn_vhdl, dev_desc, &lt;br /&gt;
                             PCIIO_INTR_LINE_A, enet_vhdl);&lt;br /&gt;
pciio_intr_connect(ei-&amp;gt;intr, (intr_func_t)if_XXintr, &lt;br /&gt;
                   (intr_arg_t)ei, NULL);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Descriptor Ring Architecture ==&lt;br /&gt;
&lt;br /&gt;
All three drivers use &#039;&#039;&#039;producer/consumer ring buffers&#039;&#039;&#039; with hardware/software indices:&lt;br /&gt;
&lt;br /&gt;
=== Common Ring Structure ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct driver_info {&lt;br /&gt;
    // TX ring&lt;br /&gt;
    struct txd *txd;           // TX descriptor array&lt;br /&gt;
    struct mbuf **txm;         // Pending TX mbufs&lt;br /&gt;
    int txhead;                // SW produce index&lt;br /&gt;
    int txtail;                // SW consume index&lt;br /&gt;
    &lt;br /&gt;
    // RX ring  &lt;br /&gt;
    struct rxd *rxd;           // RX descriptor array&lt;br /&gt;
    struct mbuf **rxm;         // Posted RX mbufs&lt;br /&gt;
    int rxhead;                // SW consume index&lt;br /&gt;
    int rxtail;                // SW produce index&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ring Index Management ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Critical macro patterns:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define NEXTTXD(i) (((i) + 1) &amp;amp; (NTXD - 1))  // Ring must be power-of-2&lt;br /&gt;
#define DELTATXD(h,t) ((h - t) &amp;amp; (NTXD - 1)) // Free descriptors&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IOC3-specific gotcha:&#039;&#039;&#039; Hardware compares RX indices modulo-16, so allocate 15 extra buffers:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define NRBUFADJ(n) (n + 15)  // Required for IOC3 only&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Transmit Path ==&lt;br /&gt;
&lt;br /&gt;
=== Etherif Transmit Function ===&lt;br /&gt;
&lt;br /&gt;
The transmit function must handle:&lt;br /&gt;
# Mbuf chain validation and coalescing&lt;br /&gt;
# Ethernet header insertion&lt;br /&gt;
# DMA address setup&lt;br /&gt;
# Descriptor programming&lt;br /&gt;
# Hardware checksum offload (if supported)&lt;br /&gt;
# Self-snoop for packet capture&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Typical signature:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int XX_transmit(&lt;br /&gt;
    struct etherif *eif,&lt;br /&gt;
    struct etheraddr *edst,   // Destination MAC&lt;br /&gt;
    struct etheraddr *esrc,   // Source MAC  &lt;br /&gt;
    u_short type,             // EtherType&lt;br /&gt;
    struct mbuf *m0)          // Packet chain&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mbuf Alignment Requirements ===&lt;br /&gt;
&lt;br /&gt;
Different hardware has different alignment constraints:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IOC3 requirements:&#039;&#039;&#039;&lt;br /&gt;
* Data0 (in descriptor): must be even length if buf1 is used&lt;br /&gt;
* Buf1 pointer: must be 2-byte aligned&lt;br /&gt;
* Buf2 pointer: must be 128-byte aligned AND buf1 must be even length&lt;br /&gt;
* No buffer may cross page boundary&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution patterns:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Check alignment&lt;br /&gt;
#define MALIGN2(m)   ALIGNED(mtod((m), u_long), 2)&lt;br /&gt;
#define MALIGN128(m) ALIGNED(mtod((m), u_long), 128)&lt;br /&gt;
&lt;br /&gt;
// Copy if misaligned&lt;br /&gt;
if (!MALIGN2(m0) || mbuf_crosses_page(m0))&lt;br /&gt;
    goto copyall;&lt;br /&gt;
&lt;br /&gt;
copyall:&lt;br /&gt;
    m = m_vget(M_DONTWAIT, mlen, MT_DATA);&lt;br /&gt;
    m_datacopy(m0, 0, mlen, mtod(m, caddr_t));&lt;br /&gt;
    m_freem(m0);&lt;br /&gt;
    m0 = m;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hardware Checksum Offload ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IOC3 TX checksum:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if (m0-&amp;gt;m_flags &amp;amp; M_CKSUMMED) {&lt;br /&gt;
    struct ip *ip = mtod(m0, struct ip*);&lt;br /&gt;
    int hlen = ip-&amp;gt;ip_hl &amp;lt;&amp;lt; 2;&lt;br /&gt;
    &lt;br /&gt;
    // Compute pseudo-header checksum&lt;br /&gt;
    __uint32_t cksum = ((ip-&amp;gt;ip_len - hlen)&lt;br /&gt;
        + htons((ushort)ip-&amp;gt;ip_p)&lt;br /&gt;
        + (ip-&amp;gt;ip_src.s_addr &amp;gt;&amp;gt; 16)&lt;br /&gt;
        + (ip-&amp;gt;ip_src.s_addr &amp;amp; 0xffff)&lt;br /&gt;
        + (ip-&amp;gt;ip_dst.s_addr &amp;gt;&amp;gt; 16)  &lt;br /&gt;
        + (ip-&amp;gt;ip_dst.s_addr &amp;amp; 0xffff));&lt;br /&gt;
    &lt;br /&gt;
    // Subtract ethernet header contribution&lt;br /&gt;
    cksum += 0xffff ^ (type + MAC_checksum_contrib);&lt;br /&gt;
    &lt;br /&gt;
    // Store adjustment in TCP/UDP header&lt;br /&gt;
    mtod(m0, u_short*)[sumoff/2] = fold_checksum(cksum);&lt;br /&gt;
    &lt;br /&gt;
    // Set descriptor flags&lt;br /&gt;
    txd-&amp;gt;cmd |= (sumoff &amp;lt;&amp;lt; ETXD_CHKOFF_SHIFT) | ETXD_DOCHECKSUM;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Errata:&#039;&#039;&#039; IOC3 rev 0 has a bug - it fails to take one&#039;s complement. Disable TX checksum for rev 0 chips.&lt;br /&gt;
&lt;br /&gt;
=== Descriptor Update Pattern ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Fill descriptor fields&lt;br /&gt;
txd-&amp;gt;cmd = flags | length;&lt;br /&gt;
txd-&amp;gt;bufcnt = total_length;&lt;br /&gt;
txd-&amp;gt;p1 = KVTOIOADDR_DATA(ei, mbuf_data);&lt;br /&gt;
&lt;br /&gt;
// CRITICAL: Writeback cache before hardware sees it&lt;br /&gt;
CACHE_WB((void *)txd, TXDSZ);&lt;br /&gt;
&lt;br /&gt;
// Save mbuf for later freeing&lt;br /&gt;
ei-&amp;gt;txm[ei-&amp;gt;txhead] = m0;&lt;br /&gt;
&lt;br /&gt;
// Update software index&lt;br /&gt;
ei-&amp;gt;txhead = NEXTTXD(ei-&amp;gt;txhead);&lt;br /&gt;
&lt;br /&gt;
// Notify hardware (write produce register)&lt;br /&gt;
W_REG(ei-&amp;gt;regs-&amp;gt;etpir, (ei-&amp;gt;txhead * TXDSZ));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Receive Path ==&lt;br /&gt;
&lt;br /&gt;
=== RX Buffer Posting ===&lt;br /&gt;
&lt;br /&gt;
Drivers must maintain a pool of posted receive buffers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void ef_fill(struct ef_info *ei) {&lt;br /&gt;
    int head = ei-&amp;gt;rxhead;&lt;br /&gt;
    int tail = ei-&amp;gt;rxtail;&lt;br /&gt;
    int n = ei-&amp;gt;nrbuf - DELTARXD(head, tail);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; n; i++) {&lt;br /&gt;
        m = m_vget(M_DONTWAIT, sizeof(struct rxbuf), MT_DATA);&lt;br /&gt;
        if (!m) break;&lt;br /&gt;
        &lt;br /&gt;
        rb = mtod(m, struct rxbuf*);&lt;br /&gt;
        ei-&amp;gt;rxm[tail] = m;&lt;br /&gt;
        ei-&amp;gt;rxd[tail] = KVTOIOADDR_DATA(ei, rb);&lt;br /&gt;
        &lt;br /&gt;
        // Invalidate for DMA&lt;br /&gt;
        CACHE_INVAL(rb, sizeof(struct rxbuf));&lt;br /&gt;
        CACHE_WB(mtod(m, caddr_t), sizeof(struct rxbuf));&lt;br /&gt;
        &lt;br /&gt;
        tail = NEXTRXD(tail);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ei-&amp;gt;rxtail = tail;&lt;br /&gt;
    W_REG(ei-&amp;gt;regs-&amp;gt;erpir, (ERPIR_ARM | (tail * RXDSZ)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Interrupt Handler ===&lt;br /&gt;
&lt;br /&gt;
IRIX interrupt handlers run at &#039;&#039;&#039;splimp()&#039;&#039;&#039; priority and must:&lt;br /&gt;
# Read/clear interrupt status&lt;br /&gt;
# Process received packets&lt;br /&gt;
# Reclaim completed TX descriptors  &lt;br /&gt;
# Rearm interrupt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Typical pattern:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void if_XXintr(struct XX_info *ei) {&lt;br /&gt;
    int s;&lt;br /&gt;
    struct mbuf *mact, *m;&lt;br /&gt;
    &lt;br /&gt;
    s = mutex_bitlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK);&lt;br /&gt;
    &lt;br /&gt;
    // Read and clear interrupt status&lt;br /&gt;
    isr = R_REG(ei-&amp;gt;regs-&amp;gt;eisr);&lt;br /&gt;
    W_REG(ei-&amp;gt;regs-&amp;gt;eisr, isr);&lt;br /&gt;
    &lt;br /&gt;
    // Process RX&lt;br /&gt;
    if (isr &amp;amp; EISR_RXTHRESH) {&lt;br /&gt;
        mact = ef_recv(ei);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Reclaim TX&lt;br /&gt;
    if (isr &amp;amp; EISR_TXDONE) {&lt;br /&gt;
        ef_reclaim(ei);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Handle errors&lt;br /&gt;
    if (isr &amp;amp; EISR_ERROR) {&lt;br /&gt;
        handle_errors(ei);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Rearm&lt;br /&gt;
    W_REG(ei-&amp;gt;regs-&amp;gt;erpir, ERPIR_ARM | produce_index);&lt;br /&gt;
    &lt;br /&gt;
    mutex_bitunlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK, s);&lt;br /&gt;
    &lt;br /&gt;
    // Send packets up AFTER releasing lock&lt;br /&gt;
    while (mact) {&lt;br /&gt;
        m = mact;&lt;br /&gt;
        mact = mact-&amp;gt;m_act;&lt;br /&gt;
        ether_input(&amp;amp;ei-&amp;gt;eif, 0, m);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RX Checksum Validation ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if ((ntohs(eh-&amp;gt;ether_type) == ETHERTYPE_IP)&lt;br /&gt;
    &amp;amp;&amp;amp; (rlen &amp;gt;= 60)  &lt;br /&gt;
    &amp;amp;&amp;amp; ((ip-&amp;gt;ip_off &amp;amp; (IP_OFFMASK|IP_MF)) == 0)&lt;br /&gt;
    &amp;amp;&amp;amp; ((ip-&amp;gt;ip_p == IPPROTO_TCP) || (ip-&amp;gt;ip_p == IPPROTO_UDP))) {&lt;br /&gt;
    &lt;br /&gt;
    // IOC3 provides checksum in descriptor&lt;br /&gt;
    cksum = rxd-&amp;gt;w0 &amp;amp; ERXBUF_IPCKSUM_MASK;&lt;br /&gt;
    &lt;br /&gt;
    // Finish calculation (add pseudo-header, subtract ether header)&lt;br /&gt;
    // ...&lt;br /&gt;
    &lt;br /&gt;
    if (cksum == 0xffff)&lt;br /&gt;
        m-&amp;gt;m_flags |= M_CKSUMMED;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PHY Management (MII Interface) ==&lt;br /&gt;
&lt;br /&gt;
=== PHY Detection and Reset ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int ef_phyprobe(struct ef_info *ei) {&lt;br /&gt;
    int i, r2, r3, val;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 32; i++) {&lt;br /&gt;
        ei-&amp;gt;phyunit = i;&lt;br /&gt;
        r2 = ef_phyget(ei, MII_PHY_ID_HI);&lt;br /&gt;
        r3 = ef_phyget(ei, MII_PHY_ID_LO);&lt;br /&gt;
        val = (r2 &amp;lt;&amp;lt; 12) | (r3 &amp;gt;&amp;gt; 4);&lt;br /&gt;
        &lt;br /&gt;
        switch (val) {&lt;br /&gt;
        case PHY_QS6612X:&lt;br /&gt;
        case PHY_ICS1889:&lt;br /&gt;
        case PHY_DP83840:&lt;br /&gt;
            ei-&amp;gt;phytype = val;&lt;br /&gt;
            ei-&amp;gt;phyrev = r3 &amp;amp; 0xf;&lt;br /&gt;
            return val;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return -1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== MII Read/Write ===&lt;br /&gt;
&lt;br /&gt;
Hardware provides two main approaches:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Approach 1: Dedicated MII registers (IOC3, ThunderLAN):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int ef_phyget(struct ef_info *ei, int reg) {&lt;br /&gt;
    // Wait for ready&lt;br /&gt;
    while (regs-&amp;gt;micr &amp;amp; MICR_BUSY)&lt;br /&gt;
        DELAYBUS(1);&lt;br /&gt;
        &lt;br /&gt;
    // Trigger read&lt;br /&gt;
    regs-&amp;gt;micr = MICR_READTRIG | &lt;br /&gt;
                 (ei-&amp;gt;phyunit &amp;lt;&amp;lt; MICR_PHYADDR_SHIFT) | reg;&lt;br /&gt;
                 &lt;br /&gt;
    // Wait for completion&lt;br /&gt;
    while (regs-&amp;gt;micr &amp;amp; MICR_BUSY)&lt;br /&gt;
        DELAYBUS(1);&lt;br /&gt;
        &lt;br /&gt;
    return (regs-&amp;gt;midr_r &amp;amp; MIDR_DATA_MASK);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Approach 2: GPIO bit-banging (Alteon, ThunderLAN alt):&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Send sync pattern (32 cycles of 1)&lt;br /&gt;
// Send start bits (01)&lt;br /&gt;
// Send opcode (10=read, 01=write)&lt;br /&gt;
// Send PHY address (5 bits)&lt;br /&gt;
// Send register (5 bits)&lt;br /&gt;
// Turnaround and read data (16 bits)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Auto-negotiation ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void ef_autonego(struct ef_info *ei) {&lt;br /&gt;
    int timeout = 20000;&lt;br /&gt;
    &lt;br /&gt;
    // Enable auto-negotiation&lt;br /&gt;
    ef_phyput(ei, MII_CTRL, MII_CTRL_AUTOEN | MII_CTRL_RESTART);&lt;br /&gt;
    &lt;br /&gt;
    // Wait for completion&lt;br /&gt;
    while (!(ef_phyget(ei, MII_STATUS) &amp;amp; MII_STATUS_ANDONE)) {&lt;br /&gt;
        DELAY(100);&lt;br /&gt;
        if (timeout-- &amp;lt;= 0) {&lt;br /&gt;
            // Default to 10Mbit half-duplex&lt;br /&gt;
            ei-&amp;gt;speed100 = 0;&lt;br /&gt;
            ei-&amp;gt;fullduplex = 0;&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Parse negotiation result&lt;br /&gt;
    r4 = ef_phyget(ei, MII_AN_ADV);&lt;br /&gt;
    r5 = ef_phyget(ei, MII_AN_LPAR);&lt;br /&gt;
    &lt;br /&gt;
    if ((r4 &amp;amp; MII_TXFD) &amp;amp;&amp;amp; (r5 &amp;amp; MII_TXFD)) {&lt;br /&gt;
        ei-&amp;gt;speed100 = 1;&lt;br /&gt;
        ei-&amp;gt;fullduplex = 1;&lt;br /&gt;
    } else if ((r4 &amp;amp; MII_TX) &amp;amp;&amp;amp; (r5 &amp;amp; MII_TX)) {&lt;br /&gt;
        ei-&amp;gt;speed100 = 1;&lt;br /&gt;
        ei-&amp;gt;fullduplex = 0;&lt;br /&gt;
    }&lt;br /&gt;
    // ... etc&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Watchdog and Error Handling ==&lt;br /&gt;
&lt;br /&gt;
=== Periodic Watchdog ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void ef_watchdog(struct ifnet *ifp) {&lt;br /&gt;
    struct ef_info *ei = eiftoei(ifptoeif(ifp));&lt;br /&gt;
    &lt;br /&gt;
    // Update statistics&lt;br /&gt;
    ef_getcdc(ei);  // Collision/defer counters&lt;br /&gt;
    &lt;br /&gt;
    // Check PHY status&lt;br /&gt;
    ef_phyerr(ei);&lt;br /&gt;
    &lt;br /&gt;
    // Reclaim TX descriptors&lt;br /&gt;
    ef_reclaim(ei);&lt;br /&gt;
    &lt;br /&gt;
    // Refill RX buffers&lt;br /&gt;
    ef_fill(ei);&lt;br /&gt;
    &lt;br /&gt;
    // Check for missed interrupts&lt;br /&gt;
    ef_intr(ei);&lt;br /&gt;
    &lt;br /&gt;
    // Reschedule&lt;br /&gt;
    ei-&amp;gt;if_timer = WATCHDOG_INTERVAL;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Link State Monitoring ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static void ef_phyerr(struct ef_info *ei) {&lt;br /&gt;
    int reg1 = ef_phyget(ei, MII_STATUS);&lt;br /&gt;
    &lt;br /&gt;
    // Link status (latched low, read twice)&lt;br /&gt;
    if (!(reg1 &amp;amp; MII_STATUS_LINK)) {&lt;br /&gt;
        if (!(ei-&amp;gt;flags &amp;amp; EIF_LINKDOWN)) {&lt;br /&gt;
            cmn_err(CE_WARN, &amp;quot;ef%d: link fail - check cable&amp;quot;, &lt;br /&gt;
                    ei-&amp;gt;unit);&lt;br /&gt;
            ei-&amp;gt;flags |= EIF_LINKDOWN;&lt;br /&gt;
        }&lt;br /&gt;
    } else {&lt;br /&gt;
        if (ei-&amp;gt;flags &amp;amp; EIF_LINKDOWN) {&lt;br /&gt;
            cmn_err(CE_NOTE, &amp;quot;ef%d: link ok&amp;quot;, ei-&amp;gt;unit);&lt;br /&gt;
            ei-&amp;gt;flags &amp;amp;= ~EIF_LINKDOWN;&lt;br /&gt;
            ef_reinit(ei);  // May need to adjust speed/duplex&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Check for remote fault, jabber, etc.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== RSVP/Packet Scheduling ==&lt;br /&gt;
&lt;br /&gt;
IRIX supports packet scheduling for QoS. Drivers must:&lt;br /&gt;
# Report available TX descriptors&lt;br /&gt;
# Signal when descriptors become available&lt;br /&gt;
# Optionally interrupt on each TX completion when scheduling active&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int ef_txfree_len(struct ifnet *ifp) {&lt;br /&gt;
    struct ef_info *ei = eiftoei(ifptoeif(ifp));&lt;br /&gt;
    return (NTXD - DELTATXD(ei-&amp;gt;txhead, ei-&amp;gt;txtail));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
static void ef_setstate(struct ifnet *ifp, int setting) {&lt;br /&gt;
    struct ef_info *ei = eiftoei(ifptoeif(ifp));&lt;br /&gt;
    if (setting)&lt;br /&gt;
        ei-&amp;gt;flags |= EIF_PSENABLED;&lt;br /&gt;
    else&lt;br /&gt;
        ei-&amp;gt;flags &amp;amp;= ~EIF_PSENABLED;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// In transmit path:&lt;br /&gt;
if ((ei-&amp;gt;flags &amp;amp; EIF_PSENABLED) &amp;amp;&amp;amp; &lt;br /&gt;
    ((ei-&amp;gt;txhead &amp;amp; ei-&amp;gt;intfreq) == 0)) {&lt;br /&gt;
    txd-&amp;gt;cmd |= ETXD_INTWHENDONE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// In interrupt handler:&lt;br /&gt;
if (ei-&amp;gt;flags &amp;amp; EIF_PSENABLED) {&lt;br /&gt;
    ps_txq_stat(eiftoifp(&amp;amp;ei-&amp;gt;eif), ef_txfree_len(&amp;amp;ei-&amp;gt;if));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// During init:&lt;br /&gt;
struct ps_parms ps_params;&lt;br /&gt;
ps_params.bandwidth = ei-&amp;gt;speed100 ? 100000000 : 10000000;&lt;br /&gt;
ps_params.flags = 0;&lt;br /&gt;
ps_params.txfree = NTXD;&lt;br /&gt;
ps_params.txfree_func = ef_txfree_len;&lt;br /&gt;
ps_params.state_func = ef_setstate;&lt;br /&gt;
ps_init(eiftoifp(&amp;amp;ei-&amp;gt;eif), &amp;amp;ps_params);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Locking and Synchronization ==&lt;br /&gt;
&lt;br /&gt;
IRIX uses &#039;&#039;&#039;bitlocks&#039;&#039;&#039; for driver synchronization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Initialize lock during attach&lt;br /&gt;
init_bitlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK, &amp;quot;ef drv lock&amp;quot;, 0);&lt;br /&gt;
&lt;br /&gt;
// Acquire in all paths that touch hardware&lt;br /&gt;
s = mutex_bitlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK);&lt;br /&gt;
// ... critical section ...&lt;br /&gt;
mutex_bitunlock(&amp;amp;ei-&amp;gt;flags, EIF_LOCK, s);&lt;br /&gt;
&lt;br /&gt;
// Check if locked (for assertions)&lt;br /&gt;
ASSERT(ei-&amp;gt;flags &amp;amp; EIF_LOCK);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lock hierarchy:&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;ifnet lock&#039;&#039;&#039; (IFNET_LOCK) - Highest level, held during ioctl&lt;br /&gt;
# &#039;&#039;&#039;Driver bitlock&#039;&#039;&#039; - Protects hardware access and descriptor rings&lt;br /&gt;
# &#039;&#039;&#039;Separate TX/RX locks&#039;&#039;&#039; - Some drivers use separate locks for TX and RX paths&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Critical sections that need locking:&#039;&#039;&#039;&lt;br /&gt;
* Descriptor ring manipulation&lt;br /&gt;
* Hardware register access&lt;br /&gt;
* mbuf list operations&lt;br /&gt;
* Statistics updates&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Operations outside lock:&#039;&#039;&#039;&lt;br /&gt;
* ether_input() - Network stack must be called without driver lock&lt;br /&gt;
* m_freem() - Can be called outside lock&lt;br /&gt;
&lt;br /&gt;
== Common Pitfalls and Gotchas ==&lt;br /&gt;
&lt;br /&gt;
=== Cache Coherency ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Forgetting cache flushes causes random packet corruption.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Always CACHE_WB before DMA write, CACHE_INVAL before DMA read.&lt;br /&gt;
&lt;br /&gt;
=== Descriptor Alignment ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Hardware silently uses wrong memory if alignment is incorrect.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Use contig_memalloc with correct alignment parameter.&lt;br /&gt;
&lt;br /&gt;
=== mbuf Chain Fragmentation ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Each mbuf may require a separate DMA descriptor, exhausting hardware resources.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Coalesce into single mbuf if chain too long or poorly aligned.&lt;br /&gt;
&lt;br /&gt;
=== Register Write Ordering ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Posted writes may not complete before hardware starts DMA.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Read back critical registers to force write completion:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
W_REG(ei-&amp;gt;regs-&amp;gt;emcr, EMCR_RST);&lt;br /&gt;
R_REG(ei-&amp;gt;regs-&amp;gt;emcr);  // Force write to complete&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IOC3 RX Index Comparison ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Hardware compares RX indices modulo-16, causing premature ring full condition.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Post 15 extra buffers (NRBUFADJ macro).&lt;br /&gt;
&lt;br /&gt;
=== Interrupt Re-arming ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Forgetting to rearm causes no more interrupts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Always write to interrupt rearm register at end of handler.&lt;br /&gt;
&lt;br /&gt;
=== Link State During Init ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Reading MII status during PHY reset gives false link-down errors.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Delay link state checking until after auto-negotiation completes.&lt;br /&gt;
&lt;br /&gt;
=== Multicast Filter Collisions ===&lt;br /&gt;
&#039;&#039;&#039;Problem:&#039;&#039;&#039; Multiple multicast addresses may hash to same filter bit.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solution:&#039;&#039;&#039; Maintain collision counter; keep filter bit set if any addresses hash to it.&lt;br /&gt;
&lt;br /&gt;
== Hardware-Specific Considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Alteon Tigon ===&lt;br /&gt;
* &#039;&#039;&#039;Firmware loading&#039;&#039;&#039; - Must load code/data into on-chip SRAM&lt;br /&gt;
* &#039;&#039;&#039;Event ring&#039;&#039;&#039; - Asynchronous events in addition to interrupts&lt;br /&gt;
* &#039;&#039;&#039;Large SRAM&#039;&#039;&#039; - Can hold many packets on-chip&lt;br /&gt;
* &#039;&#039;&#039;Sophisticated coalescing&#039;&#039;&#039; - Configurable interrupt coalescing&lt;br /&gt;
&lt;br /&gt;
=== TI ThunderLAN ===&lt;br /&gt;
* &#039;&#039;&#039;List-based DMA&#039;&#039;&#039; - Multiple fragments per packet&lt;br /&gt;
* &#039;&#039;&#039;Integrated PHY&#039;&#039;&#039; - On-chip 10Mbit PHY plus MII for external PHY&lt;br /&gt;
* &#039;&#039;&#039;EEPROM access&#039;&#039;&#039; - Complex protocol for reading MAC address&lt;br /&gt;
* &#039;&#039;&#039;Dual channels&#039;&#039;&#039; - Separate TX/RX channels with independent DMA&lt;br /&gt;
&lt;br /&gt;
=== IOC3 ===&lt;br /&gt;
* &#039;&#039;&#039;Integrated PCI-X bridge&#039;&#039;&#039; - Shares functions with serial/parallel ports&lt;br /&gt;
* &#039;&#039;&#039;Hardware checksumming&#039;&#039;&#039; - TX and RX checksum offload&lt;br /&gt;
* &#039;&#039;&#039;SSRAM buffer&#039;&#039;&#039; - On-chip packet buffer (64KB or 128KB)&lt;br /&gt;
* &#039;&#039;&#039;Parity checking&#039;&#039;&#039; - Optional parity on SSRAM&lt;br /&gt;
* &#039;&#039;&#039;NIC EEPROM&#039;&#039;&#039; - Number-in-a-can for MAC address&lt;br /&gt;
&lt;br /&gt;
== Testing and Debugging ==&lt;br /&gt;
&lt;br /&gt;
=== Debug Print Macros ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define DBG_PRINT(a) if (ei-&amp;gt;if_flags &amp;amp; IFF_DEBUG) printf a&lt;br /&gt;
&lt;br /&gt;
// Usage:&lt;br /&gt;
DBG_PRINT((&amp;quot;ef%d: txhead=%d txtail=%d\n&amp;quot;, unit, txhead, txtail));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dump Functions ===&lt;br /&gt;
Every driver should provide idbg dump functions:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
idbg_addfunc(&amp;quot;ef_dump&amp;quot;, (void (*)())ef_dump);&lt;br /&gt;
&lt;br /&gt;
static void ef_dump(int unit) {&lt;br /&gt;
    ef_dumpif(ifp);    // Interface statistics&lt;br /&gt;
    ef_dumpei(ei);     // Driver private state&lt;br /&gt;
    ef_dumpregs(ei);   // Hardware registers&lt;br /&gt;
    ef_dumpphy(ei);    // PHY registers&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Common Debug Points ===&lt;br /&gt;
* RX ring full - Check if ef_fill() is being called&lt;br /&gt;
* TX ring full - Check if ef_reclaim() is working  &lt;br /&gt;
* Checksum failures - Verify pseudo-header calculation&lt;br /&gt;
* Link flapping - Check PHY registers and cable&lt;br /&gt;
* DMA errors - Verify descriptor alignment and cache flushing&lt;br /&gt;
* Interrupt storms - Ensure status register is being cleared&lt;br /&gt;
&lt;br /&gt;
== Porting Checklist ==&lt;br /&gt;
&lt;br /&gt;
When porting a new Ethernet controller to IRIX:&lt;br /&gt;
&lt;br /&gt;
=== 1. PCI Infrastructure ===&lt;br /&gt;
* [ ] Register vendor/device ID in if_XXinit()&lt;br /&gt;
* [ ] Map register spaces with pciio_piotrans_addr()&lt;br /&gt;
* [ ] Enable bus master and memory space in PCI config&lt;br /&gt;
* [ ] Set cache line size and latency timer&lt;br /&gt;
&lt;br /&gt;
=== 2. Memory Management ===&lt;br /&gt;
* [ ] Allocate descriptor rings with contig_memalloc()&lt;br /&gt;
* [ ] Verify alignment requirements met&lt;br /&gt;
* [ ] Allocate mbuf tracking arrays with kmem_zalloc()&lt;br /&gt;
* [ ] Create fast DMA map with pciio_dmamap_alloc()&lt;br /&gt;
&lt;br /&gt;
=== 3. Hardware Initialization ===&lt;br /&gt;
* [ ] Reset chip and verify self-test passes&lt;br /&gt;
* [ ] Probe and initialize PHY&lt;br /&gt;
* [ ] Configure MAC address from EEPROM/NIC&lt;br /&gt;
* [ ] Set up descriptor ring base addresses&lt;br /&gt;
* [ ] Configure DMA parameters (burst size, etc.)&lt;br /&gt;
* [ ] Enable checksumming if supported&lt;br /&gt;
&lt;br /&gt;
=== 4. Descriptor Management ===&lt;br /&gt;
* [ ] Implement ring index macros (NEXT, DELTA)&lt;br /&gt;
* [ ] Handle cache coherency (CACHE_WB/CACHE_INVAL)&lt;br /&gt;
* [ ] Translate addresses with KVTOIOADDR_CMD/DATA&lt;br /&gt;
* [ ] Post initial RX buffers&lt;br /&gt;
&lt;br /&gt;
=== 5. Interrupt Handling ===&lt;br /&gt;
* [ ] Register handler with pciio_intr_alloc/connect&lt;br /&gt;
* [ ] Read and clear interrupt status&lt;br /&gt;
* [ ] Process RX and TX completions&lt;br /&gt;
* [ ] Handle error conditions&lt;br /&gt;
* [ ] Rearm interrupts&lt;br /&gt;
&lt;br /&gt;
=== 6. Network Integration ===&lt;br /&gt;
* [ ] Implement etherif operations vector&lt;br /&gt;
* [ ] Call ether_attach() with correct inventory type&lt;br /&gt;
* [ ] Support multicast filtering&lt;br /&gt;
* [ ] Implement SIOCADDMULTI/SIOCDELMULTI ioctls&lt;br /&gt;
* [ ] Handle IFF_PROMISC and IFF_ALLMULTI&lt;br /&gt;
&lt;br /&gt;
=== 7. Packet Scheduling ===&lt;br /&gt;
* [ ] Implement txfree_len callback&lt;br /&gt;
* [ ] Implement setstate callback  &lt;br /&gt;
* [ ] Call ps_init() during initialization&lt;br /&gt;
* [ ] Optionally interrupt per-packet when PS enabled&lt;br /&gt;
&lt;br /&gt;
=== 8. Testing ===&lt;br /&gt;
* [ ] Basic ping test (small packets)&lt;br /&gt;
* [ ] Large transfer test (TCP bulk data)&lt;br /&gt;
* [ ] Multicast functionality&lt;br /&gt;
* [ ] Promiscuous mode (tcpdump)&lt;br /&gt;
* [ ] Link up/down handling&lt;br /&gt;
* [ ] Error recovery (cable unplug/replug)&lt;br /&gt;
* [ ] Performance testing (ttcp, netperf)&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
IRIX Ethernet drivers follow a well-defined architecture that balances hardware flexibility with software consistency. Key principles:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Explicit cache management&#039;&#039;&#039; for DMA coherency&lt;br /&gt;
* &#039;&#039;&#039;Physically contiguous&#039;&#039;&#039; descriptor rings&lt;br /&gt;
* &#039;&#039;&#039;Producer/consumer rings&#039;&#039;&#039; with power-of-2 sizes&lt;br /&gt;
* &#039;&#039;&#039;Bitlocks&#039;&#039;&#039; for synchronization&lt;br /&gt;
* &#039;&#039;&#039;PHY auto-negotiation&#039;&#039;&#039; with error recovery&lt;br /&gt;
* &#039;&#039;&#039;Hardware/software index split&#039;&#039;&#039; for lock-free updates&lt;br /&gt;
* &#039;&#039;&#039;PCI infrastructure integration&#039;&#039;&#039; for portability&lt;br /&gt;
&lt;br /&gt;
Understanding these patterns enables efficient porting of modern Ethernet controllers to the IRIX platform while avoiding common pitfalls around cache coherency, alignment, and interrupt handling.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kindler&amp;diff=486</id>
		<title>Kindler</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kindler&amp;diff=486"/>
		<updated>2026-01-28T04:05:11Z</updated>

		<summary type="html">&lt;p&gt;Raion: Replaced content with &amp;quot;&amp;#039;&amp;#039;&amp;#039;Kindler&amp;#039;&amp;#039;&amp;#039; is a flexible, declarative build system that is cross-platform. In fact, it was designed by Raion to explicitly support both modern Unix-likes and IRIX alike.   == Availability == Kindler is going to be included in Nekoware but it can also be used with the Nekoware SDK, which offers Lua.   == Why Use Kindler for an IRIX project == Kindler understands mipspro. So does Autotools, but CMake? No. Meson? No.  Kindler understands IRIX&amp;#039;s lim...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Kindler&#039;&#039;&#039; is a flexible, declarative build system that is cross-platform. In fact, it was designed by [[User:Raion|Raion]] to explicitly support both modern Unix-likes and IRIX alike. &lt;br /&gt;
&lt;br /&gt;
== Availability ==&lt;br /&gt;
Kindler is going to be included in [[Nekoware]] but it can also be used with the Nekoware SDK, which offers Lua. &lt;br /&gt;
&lt;br /&gt;
== Why Use Kindler for an IRIX project ==&lt;br /&gt;
Kindler understands mipspro. So does Autotools, but CMake? No. Meson? No.&lt;br /&gt;
&lt;br /&gt;
Kindler understands IRIX&#039;s limitations and gives verbose diagnostic info. &lt;br /&gt;
&lt;br /&gt;
Kindler can coexist with Meson or CMake in the same project.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kindler&amp;diff=485</id>
		<title>Kindler</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kindler&amp;diff=485"/>
		<updated>2026-01-26T05:45:52Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;= Kindler Build System Specification = &amp;#039;&amp;#039;&amp;#039;Version:&amp;#039;&amp;#039;&amp;#039; 0.1.0 (Draft)  &amp;#039;&amp;#039;&amp;#039;Last Updated:&amp;#039;&amp;#039;&amp;#039; January 2026  &amp;#039;&amp;#039;&amp;#039;Status:&amp;#039;&amp;#039;&amp;#039; Design Phase  &amp;#039;&amp;#039;&amp;#039;AI Disclosure:&amp;#039;&amp;#039;&amp;#039; Claude and Grok provided assistance ----  == 1. Overview == &amp;#039;&amp;#039;&amp;#039;Kindler&amp;#039;&amp;#039;&amp;#039; is a declarative, cached, bootstrapped build system for UNIX-like platforms. It does not build software directly—instead, it generates build files (Makefiles, Ninja files) that native build tools execute.  === Core Philosophy ===  # &amp;#039;&amp;#039;&amp;#039;Portable:&amp;#039;&amp;#039;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Kindler Build System Specification =&lt;br /&gt;
&#039;&#039;&#039;Version:&#039;&#039;&#039; 0.1.0 (Draft)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Last Updated:&#039;&#039;&#039; January 2026&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Status:&#039;&#039;&#039; Design Phase&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;AI Disclosure:&#039;&#039;&#039; Claude and Grok provided assistance&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 1. Overview ==&lt;br /&gt;
&#039;&#039;&#039;Kindler&#039;&#039;&#039; is a declarative, cached, bootstrapped build system for UNIX-like platforms. It does not build software directly—instead, it generates build files (Makefiles, Ninja files) that native build tools execute.&lt;br /&gt;
&lt;br /&gt;
=== Core Philosophy ===&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Portable:&#039;&#039;&#039; Runs on any POSIX-compliant system with Lua 5.1+&lt;br /&gt;
# &#039;&#039;&#039;Declarative:&#039;&#039;&#039; Project files describe &#039;&#039;what&#039;&#039; to build, not &#039;&#039;how&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;Non-blocking:&#039;&#039;&#039; Warns about problems but never prevents builds&lt;br /&gt;
# &#039;&#039;&#039;Generator-based:&#039;&#039;&#039; Outputs to Make/Ninja, doesn&#039;t reinvent the wheel&lt;br /&gt;
# &#039;&#039;&#039;Cached:&#039;&#039;&#039; Bootstraps once per system, reuses platform knowledge&lt;br /&gt;
# &#039;&#039;&#039;Interoperable:&#039;&#039;&#039; Plays nice with other build systems&lt;br /&gt;
&lt;br /&gt;
=== What Kindler IS ===&lt;br /&gt;
&lt;br /&gt;
* A project description parser (UCL format)&lt;br /&gt;
* A platform/compiler database (hint files + cache)&lt;br /&gt;
* A discovery tool (bootstrap scanner)&lt;br /&gt;
* A build file generator (POSIX Make, GNU Make, Ninja)&lt;br /&gt;
* A module loader (Lua hooks for complex tasks)&lt;br /&gt;
&lt;br /&gt;
=== What Kindler IS NOT ===&lt;br /&gt;
&lt;br /&gt;
* A compiler (it doesn&#039;t compile anything)&lt;br /&gt;
* A package manager (it doesn&#039;t fetch dependencies)&lt;br /&gt;
* A scripting language (no Turing-complete logic in project files)&lt;br /&gt;
* A build executor (Make/Ninja do the actual building)&lt;br /&gt;
* A replacement for CMake/Meson for all use cases&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 2. Architecture ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Bootstrap Phase ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; One-time system profiling to build a knowledge cache.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Steps:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
# Detect OS via &amp;lt;code&amp;gt;uname&amp;lt;/code&amp;gt; and match against OS hints&lt;br /&gt;
# Load OS-specific hints file (&amp;lt;code&amp;gt;hints/os/&amp;lt;osname&amp;gt;.lua&amp;lt;/code&amp;gt;)&lt;br /&gt;
# Scan for compilers listed in OS hints&lt;br /&gt;
# Detect available libraries (via pkg-config/pkgconf)&lt;br /&gt;
# Optionally scan system headers&lt;br /&gt;
# Serialize all findings to cache (&amp;lt;code&amp;gt;~/.config/kindler/cache/&amp;lt;hostname&amp;gt;.lua&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cache Format:&#039;&#039;&#039; Lua source files (portable, debuggable)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cache Invalidation:&#039;&#039;&#039; 30-day TTL or manual re-bootstrap&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Project Files (UCL Format) ===&lt;br /&gt;
Projects are described in UCL (Universal Configuration Language), a human-readable, non-Turing-complete format.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ucl&lt;br /&gt;
 &amp;lt;code&amp;gt;project {&lt;br /&gt;
     name = &amp;quot;myapp&amp;quot;;&lt;br /&gt;
     lang = &amp;quot;c99&amp;quot;;&lt;br /&gt;
     version = &amp;quot;1.0.0&amp;quot;;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 dependencies {&lt;br /&gt;
     requires = [&amp;quot;mbedtls &amp;gt;= 2.16&amp;quot;, &amp;quot;pthread&amp;quot;];&lt;br /&gt;
     prefer = &amp;quot;static&amp;quot;;  # or &amp;quot;shared&amp;quot;, &amp;quot;any&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 build {&lt;br /&gt;
     sources = [&amp;quot;main.c&amp;quot;, &amp;quot;net.c&amp;quot;, &amp;quot;util.c&amp;quot;];&lt;br /&gt;
     output = &amp;quot;myapp&amp;quot;;&lt;br /&gt;
     type = &amp;quot;executable&amp;quot;;  # or &amp;quot;static&amp;quot;, &amp;quot;shared&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 config {&lt;br /&gt;
     debug {&lt;br /&gt;
         cflags = [&amp;quot;-g&amp;quot;, &amp;quot;-O0&amp;quot;];&lt;br /&gt;
         defines = [&amp;quot;DEBUG=1&amp;quot;];&lt;br /&gt;
     };&lt;br /&gt;
     release {&lt;br /&gt;
         cflags = [&amp;quot;-O2&amp;quot;];&lt;br /&gt;
         defines = [&amp;quot;NDEBUG&amp;quot;];&lt;br /&gt;
     };&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Key Sections:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;project&amp;lt;/code&amp;gt; — Name, language, metadata&lt;br /&gt;
* &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt; — External libraries (resolved via pkg-config + OS hints)&lt;br /&gt;
* &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; — Source files, output, artifact type&lt;br /&gt;
* &amp;lt;code&amp;gt;config&amp;lt;/code&amp;gt; — Build configurations (debug, release, custom)&lt;br /&gt;
* &amp;lt;code&amp;gt;modules&amp;lt;/code&amp;gt; — Optional Lua modules for complex tasks&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 2.3 Hints System ===&lt;br /&gt;
Hints are Lua tables that describe platform/compiler capabilities.&lt;br /&gt;
&lt;br /&gt;
==== OS Hints (&amp;lt;code&amp;gt;hints/os/&amp;lt;osname&amp;gt;.lua&amp;lt;/code&amp;gt;) ====&lt;br /&gt;
lua&lt;br /&gt;
 &amp;lt;code&amp;gt;return {&lt;br /&gt;
     irix65 = {&lt;br /&gt;
         posix = &amp;quot;yes&amp;quot;,&lt;br /&gt;
         architectures = {&amp;quot;sgi-mips&amp;quot;, &amp;quot;sgi-mips64&amp;quot;},&lt;br /&gt;
         compilers = {&amp;quot;mipspro&amp;quot;, &amp;quot;gcc&amp;quot;},  &#039;&#039;-- native first&#039;&#039;&lt;br /&gt;
         endian = &amp;quot;big&amp;quot;,&lt;br /&gt;
         abi_list = {&amp;quot;n32&amp;quot;, &amp;quot;o32&amp;quot;, &amp;quot;n64&amp;quot;},  &#039;&#039;-- default first&#039;&#039;&lt;br /&gt;
         include_path = &amp;quot;/usr/include&amp;quot;,&lt;br /&gt;
         library_search_paths = {&amp;quot;/usr/lib&amp;quot;, &amp;quot;/usr/lib32&amp;quot;, &amp;quot;/usr/lib64&amp;quot;},&lt;br /&gt;
         standard_libs = {&amp;quot;c&amp;quot;, &amp;quot;m&amp;quot;, &amp;quot;pthread&amp;quot;},&lt;br /&gt;
         headers = {&amp;quot;stdio.h&amp;quot;, &amp;quot;stdlib.h&amp;quot;, &amp;quot;unistd.h&amp;quot;, ...},&lt;br /&gt;
     }&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Compiler Hints (&amp;lt;code&amp;gt;hints/compiler/&amp;lt;compiler&amp;gt;.lua&amp;lt;/code&amp;gt;) ====&lt;br /&gt;
lua&lt;br /&gt;
 &amp;lt;code&amp;gt;return {&lt;br /&gt;
     mipspro = {&lt;br /&gt;
         architecture = {&amp;quot;sgi-mips&amp;quot;, &amp;quot;sgi-mips64&amp;quot;},&lt;br /&gt;
         [&amp;quot;compiler.drivers&amp;quot;] = {&amp;quot;/usr/bin/cc&amp;quot;, &amp;quot;/usr/bin/c99&amp;quot;, &amp;quot;/usr/bin/CC&amp;quot;},&lt;br /&gt;
         languages = {&amp;quot;ansi-c&amp;quot;, &amp;quot;c99&amp;quot;, &amp;quot;c++98&amp;quot;, &amp;quot;c++03&amp;quot;},&lt;br /&gt;
         [&amp;quot;ansi-c.driver&amp;quot;] = &amp;quot;cc&amp;quot;,   &#039;&#039;-- Use `cc` for ANSI C&#039;&#039;&lt;br /&gt;
         [&amp;quot;c99.driver&amp;quot;] = &amp;quot;c99&amp;quot;,     &#039;&#039;-- Use `c99` for C99 (NOT cc -std=c99!)&#039;&#039;&lt;br /&gt;
         [&amp;quot;c++98.driver&amp;quot;] = &amp;quot;CC&amp;quot;,&lt;br /&gt;
         version_flag = &amp;quot;-version&amp;quot;,&lt;br /&gt;
         warning_flags = &amp;quot;-fullwarn&amp;quot;,&lt;br /&gt;
         pic_flag = &amp;quot;-KPIC&amp;quot;,&lt;br /&gt;
         shared_link_flags = &amp;quot;-shared&amp;quot;,&lt;br /&gt;
         rpath_flag = &amp;quot;-rpath&amp;quot;,&lt;br /&gt;
         uses_ranlib = &amp;quot;no&amp;quot;,&lt;br /&gt;
         atomic_builtins = &amp;quot;no&amp;quot;,&lt;br /&gt;
         thread_local = &amp;quot;no&amp;quot;,&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 ```&lt;br /&gt;
 &lt;br /&gt;
 **Key Principle:** Hints describe *capabilities*, not build commands. The generator converts hints → build rules.&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;---&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
 ### 2.4 Dependency Resolution&lt;br /&gt;
 &lt;br /&gt;
 **Strategy:**&lt;br /&gt;
 1. Parse `dependencies.requires` from project file&lt;br /&gt;
 2. Check OS hints for `library_mappings` (platform-specific knowledge)&lt;br /&gt;
 3. Query pkg-config/pkgconf for library flags&lt;br /&gt;
 4. Fall back to generic search in `library_search_paths`&lt;br /&gt;
 5. Respect `dependencies.prefer` (static/shared/any)&lt;br /&gt;
 6. Warn if library not found, but don&#039;t block&lt;br /&gt;
 &lt;br /&gt;
 **Example Flow:**&lt;br /&gt;
 ```&lt;br /&gt;
 User requests: &amp;quot;mbedtls &amp;gt;= 2.16&amp;quot;&lt;br /&gt;
   ↓&lt;br /&gt;
 Check OS hints: library_mappings.mbedtls → {pkg_config = &amp;quot;mbedtls&amp;quot;}&lt;br /&gt;
   ↓&lt;br /&gt;
 Run: pkg-config &#039;&#039;--modversion mbedtls → &amp;quot;2.28.0&amp;quot; ✓&#039;&#039;&lt;br /&gt;
   ↓&lt;br /&gt;
 Run: pkg-config &#039;&#039;--libs --static mbedtls → &amp;quot;-lmbedtls -lmbedx509 -lmbedcrypto&amp;quot;&#039;&#039;&lt;br /&gt;
   ↓&lt;br /&gt;
 Cache result: mbedtls.libs = {...}&amp;lt;/code&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 2.5 Build File Generation ===&lt;br /&gt;
&#039;&#039;&#039;Supported Targets:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* POSIX Make (maximum portability)&lt;br /&gt;
* GNU Make (extensions like pattern rules)&lt;br /&gt;
* Ninja (fast incremental builds)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Generator Responsibilities:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Read project file + cache&lt;br /&gt;
* Resolve dependencies&lt;br /&gt;
* Select compiler based on language + OS hints&lt;br /&gt;
* Construct CFLAGS/LDFLAGS from hints + config&lt;br /&gt;
* Output build rules to target format&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example Output (POSIX Make):&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
make&lt;br /&gt;
 &amp;lt;code&amp;gt;# Generated by Kindler v0.1.0&lt;br /&gt;
 # Config: debug&lt;br /&gt;
 &lt;br /&gt;
 CC = /usr/bin/c99&lt;br /&gt;
 CFLAGS = -g -O0 -DDEBUG=1 -fullwarn&lt;br /&gt;
 LDFLAGS = &lt;br /&gt;
 LIBS = -lmbedtls -lmbedx509 -lmbedcrypto -lpthread&lt;br /&gt;
 &lt;br /&gt;
 OBJS = main.o net.o util.o&lt;br /&gt;
 &lt;br /&gt;
 all: myapp&lt;br /&gt;
 &lt;br /&gt;
 myapp: $(OBJS)&lt;br /&gt;
 	$(CC) $(OBJS) $(LIBS) -o myapp $(LDFLAGS)&lt;br /&gt;
 &lt;br /&gt;
 .c.o:&lt;br /&gt;
 	$(CC) $(CFLAGS) -c $&lt;br /&gt;
 &lt;br /&gt;
 clean:&lt;br /&gt;
 	rm -f $(OBJS) myapp&amp;lt;/code&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 2.6 Module System ===&lt;br /&gt;
For complex tasks that exceed UCL&#039;s capabilities, users write &#039;&#039;&#039;Lua modules&#039;&#039;&#039; that hook into build phases.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Module Example:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
lua&lt;br /&gt;
 &amp;lt;code&amp;gt;&#039;&#039;-- modules/version_gen.lua&#039;&#039;&lt;br /&gt;
 return {&lt;br /&gt;
     name = &amp;quot;version_gen&amp;quot;,&lt;br /&gt;
     hooks = {&amp;quot;pre-build&amp;quot;},&lt;br /&gt;
     &lt;br /&gt;
     [&amp;quot;pre-build&amp;quot;] = function(context)&lt;br /&gt;
         &#039;&#039;-- Generate version.h from git tags&#039;&#039;&lt;br /&gt;
         local handle = io.popen(&amp;quot;git describe --tags&amp;quot;)&lt;br /&gt;
         local version = handle:read(&amp;quot;*a&amp;quot;):gsub(&amp;quot;\n&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
         handle:close()&lt;br /&gt;
         &lt;br /&gt;
         local f = io.open(&amp;quot;version.h&amp;quot;, &amp;quot;w&amp;quot;)&lt;br /&gt;
         f:write(&#039;#define VERSION &amp;quot;&#039; .. version .. &#039;&amp;quot;\n&#039;)&lt;br /&gt;
         f:close()&lt;br /&gt;
         &lt;br /&gt;
         print(&amp;quot;Generated version.h: &amp;quot; .. version)&lt;br /&gt;
     end&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Hook Phases:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;pre-parse&amp;lt;/code&amp;gt; — Before reading project file&lt;br /&gt;
* &amp;lt;code&amp;gt;post-parse&amp;lt;/code&amp;gt; — After parsing, before generation&lt;br /&gt;
* &amp;lt;code&amp;gt;pre-build&amp;lt;/code&amp;gt; — After Makefile generation&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Loading Modules:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ucl&lt;br /&gt;
 &amp;lt;code&amp;gt;modules {&lt;br /&gt;
     load = [&amp;quot;version_gen&amp;quot;, &amp;quot;custom_checks&amp;quot;];&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 3. Supported Platforms (v0.1.0) ==&lt;br /&gt;
&#039;&#039;&#039;Target Systems:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* IRIX 6.5.x (MIPS, MIPS64)&lt;br /&gt;
* GNU/Linux (glibc 2.17+)&lt;br /&gt;
* NetBSD 9.0+&lt;br /&gt;
* FreeBSD 13.0+&lt;br /&gt;
* Solaris 11+ / OpenIndiana (if testable)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Required Tools:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Lua 5.1, 5.2, 5.3, or 5.4&lt;br /&gt;
* POSIX shell (&amp;lt;code&amp;gt;/bin/sh&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;uname&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mkdir&amp;lt;/code&amp;gt;&lt;br /&gt;
* pkg-config or pkgconf (recommended)&lt;br /&gt;
* Make or Ninja&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 4. Design Decisions ==&lt;br /&gt;
&lt;br /&gt;
=== 4.1 Why UCL? ===&lt;br /&gt;
&lt;br /&gt;
* Human-readable (better than JSON, simpler than YAML)&lt;br /&gt;
* Not Turing-complete (forces separation of config vs. logic)&lt;br /&gt;
* Lua-parseable (no external dependencies)&lt;br /&gt;
&lt;br /&gt;
=== 4.2 Why Generate, Not Build? ===&lt;br /&gt;
&lt;br /&gt;
* Leverage decades of Make/Ninja optimization&lt;br /&gt;
* Interoperate with existing toolchains&lt;br /&gt;
* Users get native incremental builds &amp;quot;for free&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 4.3 Why Lua Source Caches? ===&lt;br /&gt;
&lt;br /&gt;
* Portable across architectures (unlike bytecode)&lt;br /&gt;
* Fast to parse (Lua&#039;s parser is optimized)&lt;br /&gt;
* Debuggable (users can inspect/edit caches)&lt;br /&gt;
&lt;br /&gt;
=== 4.4 Why Non-Blocking Warnings? ===&lt;br /&gt;
&lt;br /&gt;
* Developers know their toolchains better than Kindler does&lt;br /&gt;
* Experimental builds should be possible&lt;br /&gt;
* Kindler provides info, humans make decisions&lt;br /&gt;
&lt;br /&gt;
=== 4.5 Why Per-Driver Language Selection? ===&lt;br /&gt;
&lt;br /&gt;
* Compilers like MIPSpro use &#039;&#039;different binaries&#039;&#039; for C89 vs C99&lt;br /&gt;
* GCC-style &amp;lt;code&amp;gt;-std=&amp;lt;/code&amp;gt; flags are not universal&lt;br /&gt;
* Hints encode the &amp;quot;right way&amp;quot; per compiler&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 5. Limitations &amp;amp; Non-Goals ==&lt;br /&gt;
&#039;&#039;&#039;Limitations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* No dependency fetching (use system packages or vendor code)&lt;br /&gt;
* No cross-compilation auto-detection (user must bootstrap target system)&lt;br /&gt;
* No built-in testing framework (integrate with existing tools)&lt;br /&gt;
* No IDE integration (yet)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Non-Goals:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Replace CMake/Meson for GUI apps or complex projects&lt;br /&gt;
* Compete with Bazel/Buck for monorepos&lt;br /&gt;
* Support Windows natively (WSL/Cygwin maybe)&lt;br /&gt;
* Implement a package manager&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 6. Workflow Example ==&lt;br /&gt;
bash&lt;br /&gt;
 &amp;lt;code&amp;gt;&#039;&#039;# One-time bootstrap (per machine)&#039;&#039;&lt;br /&gt;
 $ kindler bootstrap&lt;br /&gt;
 Detecting OS... IRIX 6.5.30&lt;br /&gt;
 Found compilers: mipspro (/usr/bin/cc), gcc (/usr/local/bin/gcc)&lt;br /&gt;
 Scanning headers... 342 found&lt;br /&gt;
 Cache written: ~/.config/kindler/cache/sgi-onyx.lua&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;# Generate build files&#039;&#039;&lt;br /&gt;
 $ cd myproject/&lt;br /&gt;
 $ kindler generate --config=debug --target=make&lt;br /&gt;
 Reading: project.ucl&lt;br /&gt;
 Resolving dependencies... mbedtls [OK], pthread [OK]&lt;br /&gt;
 Generating: Makefile (POSIX)&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;# Build (using native tools)&#039;&#039;&lt;br /&gt;
 $ make&lt;br /&gt;
 cc -g -O0 -DDEBUG=1 -c main.c&lt;br /&gt;
 cc -g -O0 -DDEBUG=1 -c net.c&lt;br /&gt;
 cc main.o net.o -lmbedtls -lpthread -o myapp&lt;br /&gt;
 &lt;br /&gt;
 &#039;&#039;# Switch configs&#039;&#039;&lt;br /&gt;
 $ kindler generate --config=release --target=ninja&lt;br /&gt;
 Generating: build.ninja (Ninja)&lt;br /&gt;
 $ ninja&lt;br /&gt;
 [2/2] Linking myapp&amp;lt;/code&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== 7. Future Considerations (Post-v1.0) ==&lt;br /&gt;
&lt;br /&gt;
* IDE plugins (VSCode, Vim)&lt;br /&gt;
* CI/CD templates&lt;br /&gt;
* Cross-compilation wizard&lt;br /&gt;
* Hint database versioning&lt;br /&gt;
* Community hint repository&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Main_Page&amp;diff=484</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Main_Page&amp;diff=484"/>
		<updated>2026-01-22T05:34:21Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div id=&amp;quot;mf-home&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;MainPage&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div id=&amp;quot;mp-LeftColumn&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Welcome&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Welcome to The TechPubs Wiki&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[Special:Statistics|{{NUMBEROFARTICLES}}]] [[Special:AllPages|articles]]&amp;lt;p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Tech-Pubs.net, or TechPubs, is a public wiki cataloging the hardware of the former Silicon Graphics Corporation.&amp;lt;/center&amp;gt;&amp;lt;div class=&amp;quot;sharethis-inline-follow-buttons&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-WorksColumns&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Games&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Getting Started&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
===== Setting up IRIX/Familiarization =====&lt;br /&gt;
• [[IRIX 101]]&lt;br /&gt;
&lt;br /&gt;
• [[Installing IRIX]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX Setup 101]]&lt;br /&gt;
&lt;br /&gt;
===== Setting up Software =====&lt;br /&gt;
• [[How To Find Commercial Software]]&lt;br /&gt;
&lt;br /&gt;
• [[Open Source Software|Open Source Software (See Software Section)]]&lt;br /&gt;
&lt;br /&gt;
===== Communities for Help =====&lt;br /&gt;
• [[IRIXNet]]&lt;br /&gt;
&lt;br /&gt;
• [[Reddit]]&lt;br /&gt;
&lt;br /&gt;
• [[SGUG]]&lt;br /&gt;
&lt;br /&gt;
===== Peripherals =====&lt;br /&gt;
• [[Nvme|NVME]]&lt;br /&gt;
&lt;br /&gt;
• [[Firewire]]&lt;br /&gt;
&lt;br /&gt;
• [[USB]]&lt;br /&gt;
&lt;br /&gt;
• [[Serial Tablets]]&lt;br /&gt;
&lt;br /&gt;
• [[Tape Drives]]&lt;br /&gt;
&lt;br /&gt;
===== Events =====&lt;br /&gt;
• [[Vintage Computer Festival]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIXNet Proposed Swap Meet]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resellers&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
• [[SGIDepot]]&lt;br /&gt;
&lt;br /&gt;
• [[Mashek]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Music&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Hardware&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
==== 68k-based SGIs (GL2 era) ====&lt;br /&gt;
• [[68k-based SGIs (IRIS Series)]]&lt;br /&gt;
&lt;br /&gt;
==== MIPS-based SGIs (IRIX era) ====&lt;br /&gt;
• [[Professional IRIS]]&lt;br /&gt;
&lt;br /&gt;
• [[Personal IRIS]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIS Indigo]]&lt;br /&gt;
&lt;br /&gt;
• [[Power Series]]&lt;br /&gt;
&lt;br /&gt;
• [[Crimson]]&lt;br /&gt;
&lt;br /&gt;
• [[Indy]]&lt;br /&gt;
&lt;br /&gt;
• [[Challenge S]]&lt;br /&gt;
&lt;br /&gt;
• [[Indigo 2]]&lt;br /&gt;
&lt;br /&gt;
• [[Challenge L]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 200]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx2]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 2000]]&lt;br /&gt;
&lt;br /&gt;
• [[Octane]]&lt;br /&gt;
&lt;br /&gt;
• [[O2]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 3000]]&lt;br /&gt;
&lt;br /&gt;
• [[Fuel]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 300]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 350]]&lt;br /&gt;
&lt;br /&gt;
• [[Tezro]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx4]]&lt;br /&gt;
&lt;br /&gt;
==== x86-based SGIs ====&lt;br /&gt;
• [[Visual Workstation 320]]&lt;br /&gt;
&lt;br /&gt;
• [[Visual Workstation 540]]&lt;br /&gt;
&lt;br /&gt;
• [[Visual Workstation Rebrands]]&lt;br /&gt;
&lt;br /&gt;
===== Itanium (IA-64) based SGIs =====&lt;br /&gt;
• [[SGI 750]]&lt;br /&gt;
&lt;br /&gt;
• [[Altix 330]]&lt;br /&gt;
&lt;br /&gt;
• [[Altix 350]]&lt;br /&gt;
&lt;br /&gt;
• [[Prism]]&amp;lt;br /&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-PrintWorks&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Software&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
===== IRIX Major Versions =====&lt;br /&gt;
• [[IRIX 6.5]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 6.2]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 5.3]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 4.0]]&lt;br /&gt;
&lt;br /&gt;
===== 4D1 Versions =====&lt;br /&gt;
• [[4D1-3.x]]&lt;br /&gt;
&lt;br /&gt;
• [[4D1-2.x]]&lt;br /&gt;
&lt;br /&gt;
===== GL2 Versions =====&lt;br /&gt;
• [[GL2-3.x]]&lt;br /&gt;
&lt;br /&gt;
• [[GL2-2.x]]&lt;br /&gt;
&lt;br /&gt;
• [[GL2-1.x]]&lt;br /&gt;
&lt;br /&gt;
===== RISC/OS =====&lt;br /&gt;
• [[RISC/OS]]&lt;br /&gt;
&lt;br /&gt;
===== Development Information =====&lt;br /&gt;
• [[IRIS Development Option|IRIS Development Option (IRIX 6.2 and prior)]]&lt;br /&gt;
&lt;br /&gt;
• [[MIPSPro|MIPSPro (IRIX 6.5)]]&lt;br /&gt;
&lt;br /&gt;
• [[GCC]]&lt;br /&gt;
&lt;br /&gt;
• [[Dbx|dbx (debugger)]]&lt;br /&gt;
&lt;br /&gt;
• [[optxeno]]&lt;br /&gt;
&lt;br /&gt;
• [[Nekoware SDK]]&lt;br /&gt;
&lt;br /&gt;
===== Open Source Distributions =====&lt;br /&gt;
• [[SGI Freeware]]&lt;br /&gt;
&lt;br /&gt;
• [[Nekoware]]&lt;br /&gt;
&lt;br /&gt;
• [[SGUG RSE]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IRIX Minor Versions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 5.0 and 5.1]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 6.0 and 6.1]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Subsystems =====&lt;br /&gt;
• [[:Category:Filesystems|Filesystems]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div id=&amp;quot;mp-RightColumn&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-News&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt; &lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;News&#039;&#039;&#039; &amp;lt;/div&amp;gt;&#039;&#039;&#039;01/22/2026&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Performance issues resolved -- moved to LSWS and got rid of varnish. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;11/14/2025&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
100 articles! We&#039;re working hard to provide the highest quality SGI resource on the web!&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Info&amp;quot; class=&amp;quot;mp-box&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-Encyclopedia&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Policies and Information&#039;&#039;&#039; &amp;lt;/div&amp;gt;[[Style Guide]]&lt;br /&gt;
[[TechPubs Wiki:About|About The TechPubs Wiki]]&lt;br /&gt;
&lt;br /&gt;
[[TechPubs Wiki:Copyrights|Copyright Information]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-OtherArticles&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;Tutorials&#039;&#039;&#039; &amp;lt;/div&amp;gt;• [[IRIX 101]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
• [[Setting Up NFS]]&lt;br /&gt;
&lt;br /&gt;
• [[How To Find Commercial Software]]&lt;br /&gt;
&lt;br /&gt;
• [[Porting Software to IRIX]]&lt;br /&gt;
&lt;br /&gt;
• [[SSH Setup for 6.5]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX Gigabit Card Hack]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-AttentionArticles&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;Articles Needing Attention&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
						[[:Category:Stubs|Stub Articles]]&lt;br /&gt;
&lt;br /&gt;
[[:Category:No Images|Articles Needing Images]]&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;SGI in Popular Culture&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Jurassic Park]]&lt;br /&gt;
&lt;br /&gt;
[[Nintendo 64]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Main_Page&amp;diff=483</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Main_Page&amp;diff=483"/>
		<updated>2026-01-22T02:13:19Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div id=&amp;quot;mf-home&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;MainPage&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div id=&amp;quot;mp-LeftColumn&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Welcome&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Welcome to The TechPubs Wiki&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[Special:Statistics|{{NUMBEROFARTICLES}}]] [[Special:AllPages|articles]]&amp;lt;p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Tech-Pubs.net, or TechPubs, is a public wiki cataloging the hardware of the former Silicon Graphics Corporation.&amp;lt;/center&amp;gt;&amp;lt;div class=&amp;quot;sharethis-inline-follow-buttons&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-WorksColumns&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Games&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Getting Started&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
===== Setting up IRIX/Familiarization =====&lt;br /&gt;
• [[IRIX 101]]&lt;br /&gt;
&lt;br /&gt;
• [[Installing IRIX]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX Setup 101]]&lt;br /&gt;
&lt;br /&gt;
===== Setting up Software =====&lt;br /&gt;
• [[How To Find Commercial Software]]&lt;br /&gt;
&lt;br /&gt;
• [[Open Source Software|Open Source Software (See Software Section)]]&lt;br /&gt;
&lt;br /&gt;
===== Communities for Help =====&lt;br /&gt;
• [[IRIXNet]]&lt;br /&gt;
&lt;br /&gt;
• [[Reddit]]&lt;br /&gt;
&lt;br /&gt;
• [[SGUG]]&lt;br /&gt;
&lt;br /&gt;
===== Peripherals =====&lt;br /&gt;
• [[Nvme|NVME]]&lt;br /&gt;
&lt;br /&gt;
• [[Firewire]]&lt;br /&gt;
&lt;br /&gt;
• [[USB]]&lt;br /&gt;
&lt;br /&gt;
• [[Serial Tablets]]&lt;br /&gt;
&lt;br /&gt;
• [[Tape Drives]]&lt;br /&gt;
&lt;br /&gt;
===== Events =====&lt;br /&gt;
• [[Vintage Computer Festival]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIXNet Proposed Swap Meet]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resellers&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
• [[SGIDepot]]&lt;br /&gt;
&lt;br /&gt;
• [[Mashek]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Music&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Hardware&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
==== 68k-based SGIs (GL2 era) ====&lt;br /&gt;
• [[68k-based SGIs (IRIS Series)]]&lt;br /&gt;
&lt;br /&gt;
==== MIPS-based SGIs (IRIX era) ====&lt;br /&gt;
• [[Professional IRIS]]&lt;br /&gt;
&lt;br /&gt;
• [[Personal IRIS]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIS Indigo]]&lt;br /&gt;
&lt;br /&gt;
• [[Power Series]]&lt;br /&gt;
&lt;br /&gt;
• [[Crimson]]&lt;br /&gt;
&lt;br /&gt;
• [[Indy]]&lt;br /&gt;
&lt;br /&gt;
• [[Challenge S]]&lt;br /&gt;
&lt;br /&gt;
• [[Indigo 2]]&lt;br /&gt;
&lt;br /&gt;
• [[Challenge L]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 200]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx2]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 2000]]&lt;br /&gt;
&lt;br /&gt;
• [[Octane]]&lt;br /&gt;
&lt;br /&gt;
• [[O2]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 3000]]&lt;br /&gt;
&lt;br /&gt;
• [[Fuel]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 300]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 350]]&lt;br /&gt;
&lt;br /&gt;
• [[Tezro]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx4]]&lt;br /&gt;
&lt;br /&gt;
==== x86-based SGIs ====&lt;br /&gt;
• [[Visual Workstation 320]]&lt;br /&gt;
&lt;br /&gt;
• [[Visual Workstation 540]]&lt;br /&gt;
&lt;br /&gt;
• [[Visual Workstation Rebrands]]&lt;br /&gt;
&lt;br /&gt;
===== Itanium (IA-64) based SGIs =====&lt;br /&gt;
• [[SGI 750]]&lt;br /&gt;
&lt;br /&gt;
• [[Altix 330]]&lt;br /&gt;
&lt;br /&gt;
• [[Altix 350]]&lt;br /&gt;
&lt;br /&gt;
• [[Prism]]&amp;lt;br /&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-PrintWorks&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Software&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
===== IRIX Major Versions =====&lt;br /&gt;
• [[IRIX 6.5]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 6.2]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 5.3]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 4.0]]&lt;br /&gt;
&lt;br /&gt;
===== 4D1 Versions =====&lt;br /&gt;
• [[4D1-3.x]]&lt;br /&gt;
&lt;br /&gt;
• [[4D1-2.x]]&lt;br /&gt;
&lt;br /&gt;
===== GL2 Versions =====&lt;br /&gt;
• [[GL2-3.x]]&lt;br /&gt;
&lt;br /&gt;
• [[GL2-2.x]]&lt;br /&gt;
&lt;br /&gt;
• [[GL2-1.x]]&lt;br /&gt;
&lt;br /&gt;
===== RISC/OS =====&lt;br /&gt;
• [[RISC/OS]]&lt;br /&gt;
&lt;br /&gt;
===== Development Information =====&lt;br /&gt;
• [[IRIS Development Option|IRIS Development Option (IRIX 6.2 and prior)]]&lt;br /&gt;
&lt;br /&gt;
• [[MIPSPro|MIPSPro (IRIX 6.5)]]&lt;br /&gt;
&lt;br /&gt;
• [[GCC]]&lt;br /&gt;
&lt;br /&gt;
• [[Dbx|dbx (debugger)]]&lt;br /&gt;
&lt;br /&gt;
• [[optxeno]]&lt;br /&gt;
&lt;br /&gt;
• [[Nekoware SDK]]&lt;br /&gt;
&lt;br /&gt;
===== Open Source Distributions =====&lt;br /&gt;
• [[SGI Freeware]]&lt;br /&gt;
&lt;br /&gt;
• [[Nekoware]]&lt;br /&gt;
&lt;br /&gt;
• [[SGUG RSE]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IRIX Minor Versions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 5.0 and 5.1]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 6.0 and 6.1]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Subsystems =====&lt;br /&gt;
• [[:Category:Filesystems|Filesystems]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div id=&amp;quot;mp-RightColumn&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-News&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt; &lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;News&#039;&#039;&#039; &amp;lt;/div&amp;gt;&#039;&#039;&#039;01/21/2026&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some performance issues are being monitored. We&#039;re still adding new content, often weekly!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;11/14/2025&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
100 articles! We&#039;re working hard to provide the highest quality SGI resource on the web!&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Info&amp;quot; class=&amp;quot;mp-box&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-Encyclopedia&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Policies and Information&#039;&#039;&#039; &amp;lt;/div&amp;gt;[[Style Guide]]&lt;br /&gt;
[[TechPubs Wiki:About|About The TechPubs Wiki]]&lt;br /&gt;
&lt;br /&gt;
[[TechPubs Wiki:Copyrights|Copyright Information]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-OtherArticles&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;Tutorials&#039;&#039;&#039; &amp;lt;/div&amp;gt;• [[IRIX 101]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
• [[Setting Up NFS]]&lt;br /&gt;
&lt;br /&gt;
• [[How To Find Commercial Software]]&lt;br /&gt;
&lt;br /&gt;
• [[Porting Software to IRIX]]&lt;br /&gt;
&lt;br /&gt;
• [[SSH Setup for 6.5]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX Gigabit Card Hack]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-AttentionArticles&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;Articles Needing Attention&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
						[[:Category:Stubs|Stub Articles]]&lt;br /&gt;
&lt;br /&gt;
[[:Category:No Images|Articles Needing Images]]&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;SGI in Popular Culture&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Jurassic Park]]&lt;br /&gt;
&lt;br /&gt;
[[Nintendo 64]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Main_Page&amp;diff=482</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Main_Page&amp;diff=482"/>
		<updated>2026-01-21T05:11:58Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div id=&amp;quot;mf-home&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;MainPage&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div id=&amp;quot;mp-LeftColumn&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Welcome&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Welcome to The TechPubs Wiki&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;center&amp;gt;[[Special:Statistics|{{NUMBEROFARTICLES}}]] [[Special:AllPages|articles]]&amp;lt;p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
					Tech-Pubs.net, or TechPubs, is a public wiki cataloging the hardware of the former Silicon Graphics Corporation.&amp;lt;/center&amp;gt;&amp;lt;div class=&amp;quot;sharethis-inline-follow-buttons&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-WorksColumns&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Games&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Getting Started&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
===== Setting up IRIX/Familiarization =====&lt;br /&gt;
• [[IRIX 101]]&lt;br /&gt;
&lt;br /&gt;
• [[Installing IRIX]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX Setup 101]]&lt;br /&gt;
&lt;br /&gt;
===== Setting up Software =====&lt;br /&gt;
• [[How To Find Commercial Software]]&lt;br /&gt;
&lt;br /&gt;
• [[Open Source Software|Open Source Software (See Software Section)]]&lt;br /&gt;
&lt;br /&gt;
===== Communities for Help =====&lt;br /&gt;
• [[IRIXNet]]&lt;br /&gt;
&lt;br /&gt;
• [[Reddit]]&lt;br /&gt;
&lt;br /&gt;
• [[SGUG]]&lt;br /&gt;
&lt;br /&gt;
===== Peripherals =====&lt;br /&gt;
• [[Nvme|NVME]]&lt;br /&gt;
&lt;br /&gt;
• [[Firewire]]&lt;br /&gt;
&lt;br /&gt;
• [[USB]]&lt;br /&gt;
&lt;br /&gt;
• [[Serial Tablets]]&lt;br /&gt;
&lt;br /&gt;
• [[Tape Drives]]&lt;br /&gt;
&lt;br /&gt;
===== Events =====&lt;br /&gt;
• [[Vintage Computer Festival]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIXNet Proposed Swap Meet]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resellers&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
• [[SGIDepot]]&lt;br /&gt;
&lt;br /&gt;
• [[Mashek]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Music&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Hardware&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
==== 68k-based SGIs (GL2 era) ====&lt;br /&gt;
• [[68k-based SGIs (IRIS Series)]]&lt;br /&gt;
&lt;br /&gt;
==== MIPS-based SGIs (IRIX era) ====&lt;br /&gt;
• [[Professional IRIS]]&lt;br /&gt;
&lt;br /&gt;
• [[Personal IRIS]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIS Indigo]]&lt;br /&gt;
&lt;br /&gt;
• [[Power Series]]&lt;br /&gt;
&lt;br /&gt;
• [[Crimson]]&lt;br /&gt;
&lt;br /&gt;
• [[Indy]]&lt;br /&gt;
&lt;br /&gt;
• [[Challenge S]]&lt;br /&gt;
&lt;br /&gt;
• [[Indigo 2]]&lt;br /&gt;
&lt;br /&gt;
• [[Challenge L]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 200]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx2]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 2000]]&lt;br /&gt;
&lt;br /&gt;
• [[Octane]]&lt;br /&gt;
&lt;br /&gt;
• [[O2]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 3000]]&lt;br /&gt;
&lt;br /&gt;
• [[Fuel]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 300]]&lt;br /&gt;
&lt;br /&gt;
• [[Origin 350]]&lt;br /&gt;
&lt;br /&gt;
• [[Tezro]]&lt;br /&gt;
&lt;br /&gt;
• [[Onyx4]]&lt;br /&gt;
&lt;br /&gt;
==== x86-based SGIs ====&lt;br /&gt;
• [[Visual Workstation 320]]&lt;br /&gt;
&lt;br /&gt;
• [[Visual Workstation 540]]&lt;br /&gt;
&lt;br /&gt;
• [[Visual Workstation Rebrands]]&lt;br /&gt;
&lt;br /&gt;
===== Itanium (IA-64) based SGIs =====&lt;br /&gt;
• [[SGI 750]]&lt;br /&gt;
&lt;br /&gt;
• [[Altix 330]]&lt;br /&gt;
&lt;br /&gt;
• [[Altix 350]]&lt;br /&gt;
&lt;br /&gt;
• [[Prism]]&amp;lt;br /&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-PrintWorks&amp;quot; class=&amp;quot;mp-box mp-tall&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Software&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
					&lt;br /&gt;
===== IRIX Major Versions =====&lt;br /&gt;
• [[IRIX 6.5]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 6.2]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 5.3]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 4.0]]&lt;br /&gt;
&lt;br /&gt;
===== 4D1 Versions =====&lt;br /&gt;
• [[4D1-3.x]]&lt;br /&gt;
&lt;br /&gt;
• [[4D1-2.x]]&lt;br /&gt;
&lt;br /&gt;
===== GL2 Versions =====&lt;br /&gt;
• [[GL2-3.x]]&lt;br /&gt;
&lt;br /&gt;
• [[GL2-2.x]]&lt;br /&gt;
&lt;br /&gt;
• [[GL2-1.x]]&lt;br /&gt;
&lt;br /&gt;
===== RISC/OS =====&lt;br /&gt;
• [[RISC/OS]]&lt;br /&gt;
&lt;br /&gt;
===== Development Information =====&lt;br /&gt;
• [[IRIS Development Option|IRIS Development Option (IRIX 6.2 and prior)]]&lt;br /&gt;
&lt;br /&gt;
• [[MIPSPro|MIPSPro (IRIX 6.5)]]&lt;br /&gt;
&lt;br /&gt;
• [[GCC]]&lt;br /&gt;
&lt;br /&gt;
• [[Dbx|dbx (debugger)]]&lt;br /&gt;
&lt;br /&gt;
• [[optxeno]]&lt;br /&gt;
&lt;br /&gt;
• [[Nekoware SDK]]&lt;br /&gt;
&lt;br /&gt;
===== Open Source Distributions =====&lt;br /&gt;
• [[SGI Freeware]]&lt;br /&gt;
&lt;br /&gt;
• [[Nekoware]]&lt;br /&gt;
&lt;br /&gt;
• [[SGUG RSE]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IRIX Minor Versions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 5.0 and 5.1]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX 6.0 and 6.1]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Subsystems =====&lt;br /&gt;
• [[:Category:Filesystems|Filesystems]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div id=&amp;quot;mp-RightColumn&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-News&amp;quot; class=&amp;quot;mp-box mp-wide&amp;quot;&amp;gt; &lt;br /&gt;
			&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-image mw-no-invert&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;News&#039;&#039;&#039; &amp;lt;/div&amp;gt;&#039;&#039;&#039;01/21/2026&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some performance issues are being monitored. We&#039;re still adding new content, often weekly!&lt;br /&gt;
&#039;&#039;&#039;11/14/2025&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
100 articles! We&#039;re working hard to provide the highest quality SGI resource on the web!&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;mp-Info&amp;quot; class=&amp;quot;mp-box&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;mp-innerBox&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-Encyclopedia&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell_top&amp;quot;&amp;gt; &#039;&#039;&#039;Policies and Information&#039;&#039;&#039; &amp;lt;/div&amp;gt;[[Style Guide]]&lt;br /&gt;
[[TechPubs Wiki:About|About The TechPubs Wiki]]&lt;br /&gt;
&lt;br /&gt;
[[TechPubs Wiki:Copyrights|Copyright Information]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-OtherArticles&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;Tutorials&#039;&#039;&#039; &amp;lt;/div&amp;gt;• [[IRIX 101]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
• [[Setting Up NFS]]&lt;br /&gt;
&lt;br /&gt;
• [[How To Find Commercial Software]]&lt;br /&gt;
&lt;br /&gt;
• [[Porting Software to IRIX]]&lt;br /&gt;
&lt;br /&gt;
• [[SSH Setup for 6.5]]&lt;br /&gt;
&lt;br /&gt;
• [[IRIX Gigabit Card Hack]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;mp-AttentionArticles&amp;quot; class=&amp;quot;mp-subBox&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;Articles Needing Attention&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-content&amp;quot;&amp;gt; &lt;br /&gt;
						[[:Category:Stubs|Stub Articles]]&lt;br /&gt;
&lt;br /&gt;
[[:Category:No Images|Articles Needing Images]]&lt;br /&gt;
&lt;br /&gt;
					&amp;lt;div class=&amp;quot;mp-header incell&amp;quot;&amp;gt; &#039;&#039;&#039;SGI in Popular Culture&#039;&#039;&#039; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Jurassic Park]]&lt;br /&gt;
&lt;br /&gt;
[[Nintendo 64]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Category:Kernel_Documentation&amp;diff=481</id>
		<title>Category:Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Category:Kernel_Documentation&amp;diff=481"/>
		<updated>2026-01-10T17:58:42Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;This page catalogs documentation of the IRIX kernel&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page catalogs documentation of the IRIX kernel&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Process/Time_Management_Syscalls&amp;diff=480</id>
		<title>Kernel: Process/Time Management Syscalls</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Process/Time_Management_Syscalls&amp;diff=480"/>
		<updated>2026-01-09T23:59:42Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
IRIX has many syscalls grouped by core process identity, time management, scheduling control, profiling, and signal-related system calls in the IRIX kernel. These calls operate on vproc_t (virtual process) structures, which encapsulate state shared across threads (uthreads) in multi-threaded processes.&lt;br /&gt;
Key areas:&lt;br /&gt;
&lt;br /&gt;
Time retrieval/setting&lt;br /&gt;
UID/GID manipulation (System V and BSD semantics)&lt;br /&gt;
Process group/session control&lt;br /&gt;
Nice value and real-time priority adjustments&lt;br /&gt;
Profiling (clock-based, shared-library, R10000 event counters)&lt;br /&gt;
Signal blocking/masking, pending checks, suspend, handler installation, alternate stacks&lt;br /&gt;
Miscellaneous (pause, umask, ulimit, vhangup, sysconf)&lt;br /&gt;
&lt;br /&gt;
The implementation blends System V, BSD, and POSIX behaviors, with extensions for IRIX-specific features (e.g., Frame Scheduler via schedctl).&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Time Management&lt;br /&gt;
&lt;br /&gt;
gtime: Returns current time-of-day in seconds.&lt;br /&gt;
stime: Sets system clock.&lt;br /&gt;
alarm: Sets interval timer on real-time clock.&lt;br /&gt;
times: Returns process and child CPU times.&lt;br /&gt;
&lt;br /&gt;
Identity Management&lt;br /&gt;
&lt;br /&gt;
setuid / setreuid: Set real/effective UID.&lt;br /&gt;
setgid / setregid: Set real/effective GID (with XPG4 variant for saved-GID semantics).&lt;br /&gt;
getuid / getgid: Return real and effective IDs.&lt;br /&gt;
setgroups / getgroups: Manage supplementary group list.&lt;br /&gt;
umask: Set/get file creation mask (per-uthread, shared).&lt;br /&gt;
&lt;br /&gt;
Process Group and Session&lt;br /&gt;
&lt;br /&gt;
setpgrp: System V style (flag=0 returns pgid).&lt;br /&gt;
BSDsetpgrp / BSDgetpgrp: BSD compatibility.&lt;br /&gt;
setpgid: POSIX version.&lt;br /&gt;
setsid: Create new session.&lt;br /&gt;
&lt;br /&gt;
Scheduling and Priority&lt;br /&gt;
&lt;br /&gt;
nice: Adjust nice value.&lt;br /&gt;
schedctl: Unified interface for:&lt;br /&gt;
Real-time fixed priority&lt;br /&gt;
Time slice setting&lt;br /&gt;
Nice adjustments (process, pgrp, user-wide via plistscan)&lt;br /&gt;
CPU affinity&lt;br /&gt;
Scheduling mode (free/gang)&lt;br /&gt;
Frame Scheduler (FRS) operations&lt;br /&gt;
Legacy hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Profiling&lt;br /&gt;
&lt;br /&gt;
profil: Traditional clock-based profiling.&lt;br /&gt;
sprofil: Shared-library profiling.&lt;br /&gt;
evc_profil: R10000 hardware event counter profiling (per-thread counters).&lt;br /&gt;
&lt;br /&gt;
Signal Handling&lt;br /&gt;
&lt;br /&gt;
sigpending: Return pending signal set.&lt;br /&gt;
sigsuspend: Atomically swap signal mask and sleep.&lt;br /&gt;
sigprocmask: Block/unblock signals.&lt;br /&gt;
sigaction: Install signal handler with mask/flags.&lt;br /&gt;
sigstack / sigaltstack: Set/query alternate signal stack (with XPG4 corrected behavior).&lt;br /&gt;
&lt;br /&gt;
Miscellaneous&lt;br /&gt;
&lt;br /&gt;
pause: Sleep until signal.&lt;br /&gt;
ulimit: Query/set resource limits (file size, data segment, descriptors).&lt;br /&gt;
vhangup: Invalidate controlling terminal.&lt;br /&gt;
sysconf: Runtime configuration values (e.g., _SC_ARG_MAX, _SC_NGROUPS_MAX).&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
vproc_t-Centric Design&lt;br /&gt;
All process-wide operations dispatch through VPROC_ macros on curvprocp, supporting shared state across uthreads.&lt;br /&gt;
Dual Semantics&lt;br /&gt;
&lt;br /&gt;
System V (setpgrp) and BSD/POSIX (setpgid, setsid) co-exist.&lt;br /&gt;
XPG4 variants for sigaltstack (correct stack direction) and setregid (saved-GID handling).&lt;br /&gt;
&lt;br /&gt;
schedctl Extensions&lt;br /&gt;
&lt;br /&gt;
Real-time fixed priorities (non-degrading).&lt;br /&gt;
Gang scheduling modes.&lt;br /&gt;
Full Frame Scheduler (FRS) user interface for hard real-time gangs.&lt;br /&gt;
User-wide nice operations via process table scan.&lt;br /&gt;
&lt;br /&gt;
Profiling Variants&lt;br /&gt;
&lt;br /&gt;
Clock-based, shared-library, and hardware counter (R10000) profiling.&lt;br /&gt;
Fast profiling mode.&lt;br /&gt;
&lt;br /&gt;
Signal Stack Handling&lt;br /&gt;
&lt;br /&gt;
Historical IRIX sigaltstack required user to account for stack growth direction; XPG4 variant fixes this.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong overlap:&lt;br /&gt;
&lt;br /&gt;
UID/GID, nice, alarm, times, pause, umask, ulimit nearly identical.&lt;br /&gt;
priocntl(2) analogous to schedctl for real-time classes.&lt;br /&gt;
Signal syscalls match POSIX.&lt;br /&gt;
Alternate stack via sigaltstack.&lt;br /&gt;
&lt;br /&gt;
Differences: No direct FRS; different real-time model.&lt;br /&gt;
BSD (FreeBSD, etc.)&lt;br /&gt;
Close matches:&lt;br /&gt;
&lt;br /&gt;
setreuid, setregid, setpgid, setsid, nice, getpriority/setpriority.&lt;br /&gt;
Signal interfaces standard.&lt;br /&gt;
sysconf for configuration.&lt;br /&gt;
&lt;br /&gt;
Differences: Separate syscalls instead of unified schedctl; weaker real-time support.&lt;br /&gt;
Overall, IRIX provides a rich unified scheduling interface (schedctl) with strong real-time extensions (FRS, fixed-priority) while maintaining compatibility with both SVR4 and BSD/POSIX. For reimplementation, focus on vproc dispatch and dual semantics; FRS is IRIX-specific.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_vnode_Operations&amp;diff=479</id>
		<title>Kernel: vnode Operations</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_vnode_Operations&amp;diff=479"/>
		<updated>2026-01-09T23:58:53Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Summary of known vfs operations and [[Kernel: vnode and vfs|vnode]] operations.&lt;br /&gt;
&lt;br /&gt;
=== 1. VFS Operations (&amp;lt;code&amp;gt;vfsops_t&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
These are operations on the &#039;&#039;&#039;filesystem as a whole&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Purpose / Semantics&lt;br /&gt;
!Typical FS Relevance&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mount&amp;lt;/code&amp;gt;&lt;br /&gt;
|Mount the filesystem; initialize structures, link root vnode.&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;umount&amp;lt;/code&amp;gt;&lt;br /&gt;
|Unmount; flush buffers, release resources.&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;sync&amp;lt;/code&amp;gt;&lt;br /&gt;
|Flush all dirty buffers and VM pages to disk.&lt;br /&gt;
|Persistent FS (EFS, XFS)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;statvfs&amp;lt;/code&amp;gt;&lt;br /&gt;
|Retrieve filesystem statistics (free space, block size).&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;vget&amp;lt;/code&amp;gt;&lt;br /&gt;
|Retrieve vnode by inode number or identifier.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;quotactl&amp;lt;/code&amp;gt;&lt;br /&gt;
|Manage quotas on filesystem (user/group limits).&lt;br /&gt;
|Optional, persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt;&lt;br /&gt;
|Integrate remote filesystem structures (NFS, exported FS).&lt;br /&gt;
|Network FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
|Return root vnode of filesystem.&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;reclaim&amp;lt;/code&amp;gt;&lt;br /&gt;
|Cleanup filesystem-specific vnode data before freeing vnode memory.&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;fsid&amp;lt;/code&amp;gt;&lt;br /&gt;
|Return filesystem ID.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;check&amp;lt;/code&amp;gt;&lt;br /&gt;
|Perform consistency or integrity checks (optional).&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;remount&amp;lt;/code&amp;gt;&lt;br /&gt;
|Update mount options without unmounting.&lt;br /&gt;
|Optional&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;statfs&amp;lt;/code&amp;gt;&lt;br /&gt;
|Return summarized filesystem status.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Pseudo-filesystems (pipefs, fifofs) stub most of these functions; only &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;vget&amp;lt;/code&amp;gt; may return in-memory structures.&lt;br /&gt;
* Real filesystems (EFS, XFS) implement almost all operations for proper filesystem management.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 2. Vnode Operations (&amp;lt;code&amp;gt;vnodeops_t&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
These are operations on &#039;&#039;&#039;individual vnodes&#039;&#039;&#039;, dispatched via the BHV layer.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operation&lt;br /&gt;
!Purpose / Semantics&lt;br /&gt;
!FS Relevance / Typical Implementation&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt;&lt;br /&gt;
|Read data from vnode into user or kernel buffer.&lt;br /&gt;
|All FS supporting files or streams&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt;&lt;br /&gt;
|Write data to vnode from buffer.&lt;br /&gt;
|All FS supporting files or streams&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ioctl&amp;lt;/code&amp;gt;&lt;br /&gt;
|Perform device-specific or FS-specific commands.&lt;br /&gt;
|Devices, pseudo-FS, streams&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;getattr&amp;lt;/code&amp;gt;&lt;br /&gt;
|Retrieve vnode attributes (mode, owner, size, timestamps).&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;setattr&amp;lt;/code&amp;gt;&lt;br /&gt;
|Update vnode attributes.&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;access&amp;lt;/code&amp;gt;&lt;br /&gt;
|Check access permissions.&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;lookup&amp;lt;/code&amp;gt;&lt;br /&gt;
|Resolve pathname component to vnode.&lt;br /&gt;
|Directory FS (EFS, XFS, pipefs limited)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;&lt;br /&gt;
|Create a new file.&lt;br /&gt;
|Persistent FS; pseudo-FS may stub&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;remove&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove a file.&lt;br /&gt;
|Persistent FS; pipefs/FIFO may implement&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mkdir&amp;lt;/code&amp;gt;&lt;br /&gt;
|Create directory.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;rmdir&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove directory.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;readdir&amp;lt;/code&amp;gt;&lt;br /&gt;
|Read directory entries.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;symlink&amp;lt;/code&amp;gt;&lt;br /&gt;
|Create symbolic link.&lt;br /&gt;
|Optional, persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;readlink&amp;lt;/code&amp;gt;&lt;br /&gt;
|Read symbolic link target.&lt;br /&gt;
|Optional, persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;rename&amp;lt;/code&amp;gt;&lt;br /&gt;
|Rename a file.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;link&amp;lt;/code&amp;gt;&lt;br /&gt;
|Create hard link.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;unlink&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove a link.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;fsync&amp;lt;/code&amp;gt;&lt;br /&gt;
|Flush vnode’s buffers to disk.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt;&lt;br /&gt;
|Map file pages into VM.&lt;br /&gt;
|Persistent FS, memory-mapped files&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;addmap&amp;lt;/code&amp;gt;&lt;br /&gt;
|Notify FS of memory mapping.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;delmap&amp;lt;/code&amp;gt;&lt;br /&gt;
|Notify FS of unmapped region.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;frlock&amp;lt;/code&amp;gt;&lt;br /&gt;
|File region locking.&lt;br /&gt;
|All FS supporting advisory locks&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;poll&amp;lt;/code&amp;gt;&lt;br /&gt;
|Determine readiness for I/O.&lt;br /&gt;
|Streams, pipes, devices&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;seek&amp;lt;/code&amp;gt;&lt;br /&gt;
|Validate seek operation.&lt;br /&gt;
|Regular files, optionally pseudo-FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;&lt;br /&gt;
|Called when last reference released; free resources.&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;reclaim&amp;lt;/code&amp;gt;&lt;br /&gt;
|Called to cleanup filesystem-specific vnode state.&lt;br /&gt;
|All FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;realvp&amp;lt;/code&amp;gt;&lt;br /&gt;
|Return underlying “real” vnode in layered FS.&lt;br /&gt;
|Stacked or layered FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;cover&amp;lt;/code&amp;gt;&lt;br /&gt;
|Return vnode that this vnode overlays.&lt;br /&gt;
|Stacked FS&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;link_removed&amp;lt;/code&amp;gt;&lt;br /&gt;
|Notify FS that a link was removed.&lt;br /&gt;
|Persistent FS&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Pseudo-filesystems&#039;&#039;&#039; (pipefs, fifofs):&lt;br /&gt;
** Implement &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;poll&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;&lt;br /&gt;
** Many other operations are stubs (&amp;lt;code&amp;gt;fs_nosys&amp;lt;/code&amp;gt;) because they have no persistent storage.&lt;br /&gt;
* &#039;&#039;&#039;Persistent filesystems&#039;&#039;&#039; (EFS, XFS):&lt;br /&gt;
** Implement almost all operations fully.&lt;br /&gt;
** VM integration (&amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;addmap&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;delmap&amp;lt;/code&amp;gt;) links vnode buffers with page cache.&lt;br /&gt;
** Locking (&amp;lt;code&amp;gt;frlock&amp;lt;/code&amp;gt;) and attribute operations are critical for filesystem consistency.&lt;br /&gt;
* &#039;&#039;&#039;Streams / devices:&#039;&#039;&#039;&lt;br /&gt;
** Integrate with &amp;lt;code&amp;gt;poll&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;select&amp;lt;/code&amp;gt; via pollhead structures.&lt;br /&gt;
** &amp;lt;code&amp;gt;ioctl&amp;lt;/code&amp;gt; is heavily used to expose device-specific functionality.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 3. Behavior Semantics ===&lt;br /&gt;
&lt;br /&gt;
* Vnode operations are &#039;&#039;&#039;dispatched via the behavior chain&#039;&#039;&#039;, allowing:&lt;br /&gt;
** &#039;&#039;&#039;Layered filesystems&#039;&#039;&#039;: stacking additional behaviors (e.g., shadow vnodes, network FS).&lt;br /&gt;
** &#039;&#039;&#039;Pseudo-filesystems&#039;&#039;&#039;: handle vnodes without disk backing.&lt;br /&gt;
* Operations are &#039;&#039;&#039;always invoked on BHV descriptors&#039;&#039;&#039;, not directly on vnodes. This ensures correct dispatch in multi-layer environments.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 4. Filesystem Type Considerations ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!FS Type&lt;br /&gt;
!Implemented Operations&lt;br /&gt;
|-&lt;br /&gt;
|Persistent (EFS/XFS)&lt;br /&gt;
|All VFS and vnode ops; full VM/page cache integration, locking, attributes&lt;br /&gt;
|-&lt;br /&gt;
|Pseudo-FS (pipefs/fifofs)&lt;br /&gt;
|&amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;poll&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;; stubs for most others&lt;br /&gt;
|-&lt;br /&gt;
|Device FS (devfs)&lt;br /&gt;
|&amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ioctl&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;poll&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;getattr&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;setattr&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Network FS (NFS-like)&lt;br /&gt;
|&amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;vget&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;lookup&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== 5. Reference / Lifecycle Management ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VFS ops:&#039;&#039;&#039; &amp;lt;code&amp;gt;reclaim&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;sync&amp;lt;/code&amp;gt; ensure global cleanup.&lt;br /&gt;
* &#039;&#039;&#039;Vnode ops:&#039;&#039;&#039; &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;reclaim&amp;lt;/code&amp;gt; ensure per-vnode cleanup.&lt;br /&gt;
* &#039;&#039;&#039;BHVs:&#039;&#039;&#039; behavior chain allows multiple layers to participate in cleanup or dispatch.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_malloc&amp;diff=478</id>
		<title>Kernel: malloc</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_malloc&amp;diff=478"/>
		<updated>2026-01-09T23:58:28Z</updated>

		<summary type="html">&lt;p&gt;Raion: Raion moved page Kernel:malloc to Kernel: malloc without leaving a redirect: Misspelled title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page documents the memory allocation subsystem of the IRIX kernel (`malloc`, `rmalloc`, and related functions) as implemented in the IRIX kernel. It is intended as a functional reference for reimplementation in other kernels (e.g., Illumos).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The IRIX memory allocation system provides:&lt;br /&gt;
&lt;br /&gt;
* Map-based memory management (`struct map`) for contiguous resource allocation.&lt;br /&gt;
* Page-aligned and color-aware allocations for cache efficiency (R4000-specific).&lt;br /&gt;
* Bitmap-based system page table (SPT) management.&lt;br /&gt;
* Waiting and non-waiting allocation paths (`VM_NOSLEEP` flag).&lt;br /&gt;
* Synchronization primitives using spinlocks and semaphores.&lt;br /&gt;
&lt;br /&gt;
Memory management in IRIX is based on two concepts:&lt;br /&gt;
&lt;br /&gt;
# **Maps** – contiguous resources tracked as a list of free/allocated blocks.&lt;br /&gt;
# **Bitmaps** – finer-grained allocation (e.g., pages, cache-colored pages) with alignment support.&lt;br /&gt;
&lt;br /&gt;
== Map Allocation API ==&lt;br /&gt;
&lt;br /&gt;
=== rmallocmap() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate and initialize a `struct map` for tracking resources.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039; `mapsiz` – number of entries in the map.  &lt;br /&gt;
&#039;&#039;&#039;Outputs:&#039;&#039;&#039; Pointer to newly allocated map, or NULL on failure.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Allocates memory for `mapsiz + 2` map entries.&lt;br /&gt;
* Allocates and initializes a synchronization structure (`lock + semaphore`).&lt;br /&gt;
* Stores pointers to synchronization primitives in the second map entry.&lt;br /&gt;
* Returns a fully initialized map ready for allocations.&lt;br /&gt;
&lt;br /&gt;
=== rmfreemap() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free a previously allocated map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039; Pointer to map.  &lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Waits for any threads currently blocked on the map.&lt;br /&gt;
* Destroys associated semaphore and spinlock.&lt;br /&gt;
* Frees both the map memory and the synchronization structure.&lt;br /&gt;
&lt;br /&gt;
=== malloc / malloc_wait / rmalloc / rmalloc_wait ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate contiguous units from a map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `mp` – pointer to map&lt;br /&gt;
* `size` – number of units&lt;br /&gt;
* Optional `flags` (`VM_NOSLEEP` for non-blocking)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Uses **first-fit allocation**.&lt;br /&gt;
* Non-blocking (`VM_NOSLEEP`) returns `0` if allocation fails.&lt;br /&gt;
* Blocking waits on the map’s semaphore until space becomes available.&lt;br /&gt;
* Returns the starting address of allocated space.&lt;br /&gt;
&lt;br /&gt;
=== mfree / rmfree ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free previously allocated space in a map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `mp` – pointer to map&lt;br /&gt;
* `size` – units to free&lt;br /&gt;
* `a` – base address&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Sorts the freed block into the map.&lt;br /&gt;
* Merges with adjacent free blocks if possible.&lt;br /&gt;
* Updates map’s size and count.&lt;br /&gt;
* Broadcasts to any waiting threads if space becomes available.&lt;br /&gt;
* Logs warnings if map overflow or invalid free occurs.&lt;br /&gt;
&lt;br /&gt;
== Bitmap-Based Page Table Management ==&lt;br /&gt;
&lt;br /&gt;
The IRIX kernel uses **bitmap structures** to manage system page tables (`spt`). This allows fine-grained allocation with support for color and alignment.&lt;br /&gt;
&lt;br /&gt;
=== sptalloc() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate pages from the system page table bitmap.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – pointer to system bitmap structure&lt;br /&gt;
* `want` – number of pages&lt;br /&gt;
* `flags` – allocation flags (`VM_NOSLEEP`, `VM_VACOLOR`, `VM_BREAKABLE`)&lt;br /&gt;
* `color` – desired cache color (for R4000)&lt;br /&gt;
* `alignment` – page boundary alignment (power of 2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Selects a bitmap (clean, stale, aged) for allocation.&lt;br /&gt;
* If color-specific allocation is requested, attempts color map first.&lt;br /&gt;
* Uses rotors to track possible starting positions for efficiency.&lt;br /&gt;
* Supports alignment constraints.&lt;br /&gt;
* Will optionally wait (blocking) if pages are unavailable.&lt;br /&gt;
* Updates bitmap counters and rotors on allocation.&lt;br /&gt;
&lt;br /&gt;
=== sptfree() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free pages back to the system page table bitmap.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – pointer to system bitmap&lt;br /&gt;
* `size` – number of pages&lt;br /&gt;
* `mapaddr` – base address of pages to free&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Updates `m_lowbit`, `m_highbit`, and `m_count` in the bitmap.&lt;br /&gt;
* Sets freed bits in the bitmap.&lt;br /&gt;
* Broadcasts to waiting threads.&lt;br /&gt;
&lt;br /&gt;
=== mergebitmaps() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Merge one bitmap into another (e.g., stale pages back into main SPT map).  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – system bitmap&lt;br /&gt;
* `to` – destination bitmap&lt;br /&gt;
* `from` – source bitmap&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Copies set bits from source to destination.&lt;br /&gt;
* Updates rotor information for SPT allocation.&lt;br /&gt;
* Clears source bitmap.&lt;br /&gt;
&lt;br /&gt;
=== bmapswtch() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Swap contents of two bitmaps.  &lt;br /&gt;
&#039;&#039;&#039;Use case:&#039;&#039;&#039; Replace an old bitmap with a new one without modifying allocation state.&lt;br /&gt;
&lt;br /&gt;
=== sptgetsizes() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Get counts of pages in different states (clean, stale, aged, in-transit).&lt;br /&gt;
&lt;br /&gt;
== Synchronization and Multi-Processor Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Spinlocks (`mutex_spinlock`) protect map structures during allocation.&lt;br /&gt;
* Bitmaps have a hierarchy of locks:&lt;br /&gt;
** Normal allocation lock (`MAP_ALLOCLOCK`)**&lt;br /&gt;
** Urgent lock (`MAP_URGENTLOCK`)** – signals to other threads to back off during replenishment.&lt;br /&gt;
* Wait queues (semaphores) are used for threads blocked on resources.&lt;br /&gt;
&lt;br /&gt;
== R4000-Specific Enhancements ==&lt;br /&gt;
&lt;br /&gt;
* **Cache-colored allocation:** ensures pages allocated from a bitmap minimize cache conflicts.&lt;br /&gt;
* **sptvctst()** – tests for a free bit in a specific cache color.&lt;br /&gt;
* **color_alloc()** – allocates a page of a specific color.&lt;br /&gt;
* **sptaligntst()** – ensures alignment in allocations.&lt;br /&gt;
&lt;br /&gt;
== Fault Checking ==&lt;br /&gt;
&lt;br /&gt;
* `kvfaultcheck()` inspects which CPUs have references to aged or temporary pages.&lt;br /&gt;
* Returns a CPU mask indicating CPUs that need TLB flushes.&lt;br /&gt;
* Integration with isolate debugging on multi-CPU systems (EVEREST/SN0).&lt;br /&gt;
&lt;br /&gt;
== Notes for Reimplementation ==&lt;br /&gt;
&lt;br /&gt;
* Map-based allocations are generic and can be adapted to other OS kernels.&lt;br /&gt;
* Bitmap-based page allocations depend on low-level page tables; rotors and color optimizations can be implemented optionally.&lt;br /&gt;
* Careful handling of spinlocks, semaphores, and wait queues is required in multi-processor environments.&lt;br /&gt;
* Ensure that alignment and cache color are power-of-two values for correctness.&lt;br /&gt;
* Debug assertions (`ASSERT`) in IRIX should be converted to runtime checks or kernel asserts in the new environment.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Poll_and_Select&amp;diff=477</id>
		<title>Kernel: Poll and Select</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Poll_and_Select&amp;diff=477"/>
		<updated>2026-01-09T23:57:52Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This section describes the behavior of IRIX’s [[Kernel:6.5 Kernel|6.5 Kernel]] &amp;lt;code&amp;gt;poll(2)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;select(2)&amp;lt;/code&amp;gt; system calls as observed from kernel behavior and historical design goals.&lt;br /&gt;
&lt;br /&gt;
It intentionally avoids implementation details and code structure, focusing instead on externally visible semantics, internal contracts, and compatibility considerations.&lt;br /&gt;
&lt;br /&gt;
== 1. Design philosophy ==&lt;br /&gt;
IRIX treats &amp;lt;code&amp;gt;poll(2)&amp;lt;/code&amp;gt; as the fundamental readiness-notification mechanism.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;select(2)&amp;lt;/code&amp;gt; is a compatibility interface layered atop &amp;lt;code&amp;gt;poll&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The IRIX design emphasizes:&lt;br /&gt;
&lt;br /&gt;
* Precise wakeups over broadcast signaling&lt;br /&gt;
* Predictable latency under high fd counts&lt;br /&gt;
* Scalability on large SMP systems&lt;br /&gt;
* Tolerance of imperfect or legacy drivers&lt;br /&gt;
* Compatibility with historical SVR4 semantics&lt;br /&gt;
&lt;br /&gt;
This leads to observable differences from Solaris and BSD-derived systems.&lt;br /&gt;
&lt;br /&gt;
== 2. Core readiness model ==&lt;br /&gt;
&lt;br /&gt;
=== 2.1 Explicit interest registration ===&lt;br /&gt;
When a thread calls &amp;lt;code&amp;gt;poll(2)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;select(2)&amp;lt;/code&amp;gt;, IRIX:&lt;br /&gt;
&lt;br /&gt;
* Actively registers the thread’s interest in each polled object&lt;br /&gt;
* Associates that interest with the object itself&lt;br /&gt;
* Records the specific events the thread is waiting for&lt;br /&gt;
&lt;br /&gt;
This differs from systems that merely re-scan descriptors after wakeup.&lt;br /&gt;
&lt;br /&gt;
Consequence:&lt;br /&gt;
&lt;br /&gt;
Only threads that expressed interest in a specific event are eligible to be woken.&lt;br /&gt;
&lt;br /&gt;
=== 2.2 Object-centric wakeups ===&lt;br /&gt;
Pollable kernel objects (files, sockets, devices) are responsible for:&lt;br /&gt;
&lt;br /&gt;
* Advertising readiness&lt;br /&gt;
* Waking interested threads when state changes&lt;br /&gt;
&lt;br /&gt;
Wakeups originate from the object, not from a global selector.&lt;br /&gt;
&lt;br /&gt;
Consequence:&lt;br /&gt;
&lt;br /&gt;
Wakeups are targeted and efficient, especially when many threads are polling unrelated objects.&lt;br /&gt;
&lt;br /&gt;
== 3. Wakeup precision and filtering ==&lt;br /&gt;
IRIX wakeups are event-filtered:&lt;br /&gt;
&lt;br /&gt;
* A thread is woken only if:&lt;br /&gt;
** The event matches its registered interest, or&lt;br /&gt;
** The event represents a terminal condition (e.g., hangup or error)&lt;br /&gt;
* Objects may request:&lt;br /&gt;
** Waking all interested threads&lt;br /&gt;
** Waking only a single waiting thread&lt;br /&gt;
&lt;br /&gt;
This behavior reduces unnecessary context switches.&lt;br /&gt;
&lt;br /&gt;
=== Comparison to Solaris ===&lt;br /&gt;
Solaris follows a similar object-centric model, but tends to wake broader sets of threads and rely more on post-wakeup filtering.&lt;br /&gt;
&lt;br /&gt;
== 4. Poll ordering and locality (“rotor behavior”) ==&lt;br /&gt;
IRIX introduces a locality optimization that influences how readiness scans resume after sleep:&lt;br /&gt;
&lt;br /&gt;
* When a thread wakes, IRIX records &#039;&#039;which descriptor triggered the wakeup&#039;&#039;&lt;br /&gt;
* Subsequent readiness scans preferentially resume near that descriptor&lt;br /&gt;
* If ambiguity exists (e.g., multiple wakeups or mixed object capabilities), the optimization is disabled&lt;br /&gt;
&lt;br /&gt;
This improves performance for workloads that repeatedly poll the same small subset of descriptors.&lt;br /&gt;
&lt;br /&gt;
=== Observable effects ===&lt;br /&gt;
&lt;br /&gt;
* Reduced latency for hot descriptors&lt;br /&gt;
* Slightly different readiness ordering than Solaris in some cases&lt;br /&gt;
* No effect on correctness or POSIX compliance&lt;br /&gt;
&lt;br /&gt;
== 5. Handling of partially pollable objects ==&lt;br /&gt;
IRIX supports environments where:&lt;br /&gt;
&lt;br /&gt;
* Some objects fully support readiness notification&lt;br /&gt;
* Others cannot actively signal readiness&lt;br /&gt;
&lt;br /&gt;
In such cases:&lt;br /&gt;
&lt;br /&gt;
* The thread may still block&lt;br /&gt;
* Optimizations that rely on precise wakeup hints are conservatively disabled&lt;br /&gt;
* Correctness is preserved at the cost of additional scanning&lt;br /&gt;
&lt;br /&gt;
=== Comparison to Solaris ===&lt;br /&gt;
Solaris generally expects pollable objects to fully participate in readiness signaling and is less tolerant of partial support.&lt;br /&gt;
&lt;br /&gt;
== 6. Race avoidance and readiness consistency ==&lt;br /&gt;
IRIX takes explicit measures to avoid lost wakeups:&lt;br /&gt;
&lt;br /&gt;
* Readiness is checked before sleeping&lt;br /&gt;
* Registration and wakeup are ordered to detect concurrent state changes&lt;br /&gt;
* If readiness changes during registration, the scan is immediately retried&lt;br /&gt;
&lt;br /&gt;
Consequence:&lt;br /&gt;
&lt;br /&gt;
A readiness event that occurs during a &amp;lt;code&amp;gt;poll(2)&amp;lt;/code&amp;gt; call is not silently lost.&lt;br /&gt;
&lt;br /&gt;
Solaris employs similar concepts, but IRIX favors immediate in-kernel recovery rather than deferring detection to later scans.&lt;br /&gt;
&lt;br /&gt;
== 7. Timeout behavior ==&lt;br /&gt;
IRIX timeouts:&lt;br /&gt;
&lt;br /&gt;
* Are internally rounded to system clock resolution&lt;br /&gt;
* Are conservatively extended to avoid early expiration&lt;br /&gt;
* May therefore exceed the requested timeout by a small margin&lt;br /&gt;
&lt;br /&gt;
This behavior prioritizes correctness over precision.&lt;br /&gt;
&lt;br /&gt;
Solaris typically offers finer-grained timeout resolution.&lt;br /&gt;
&lt;br /&gt;
== 8. Interaction with signals ==&lt;br /&gt;
If a polling thread receives a signal:&lt;br /&gt;
&lt;br /&gt;
* The poll is interrupted&lt;br /&gt;
* All readiness registrations made during the call are cleaned up&lt;br /&gt;
* The system call returns with &amp;lt;code&amp;gt;EINTR&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IRIX guarantees that interrupted polls do not leave stale readiness state behind.&lt;br /&gt;
&lt;br /&gt;
== 9. select(2) compatibility semantics ==&lt;br /&gt;
Although implemented atop &amp;lt;code&amp;gt;poll(2)&amp;lt;/code&amp;gt;, IRIX preserves traditional &amp;lt;code&amp;gt;select(2)&amp;lt;/code&amp;gt; behavior:&lt;br /&gt;
&lt;br /&gt;
* Invalid descriptors cause &amp;lt;code&amp;gt;select(2)&amp;lt;/code&amp;gt; to fail with &amp;lt;code&amp;gt;EBADF&amp;lt;/code&amp;gt;&lt;br /&gt;
* The same condition in &amp;lt;code&amp;gt;poll(2)&amp;lt;/code&amp;gt; results in per-descriptor error reporting&lt;br /&gt;
* Exceptional conditions are reported using historical bitmask semantics&lt;br /&gt;
&lt;br /&gt;
This ensures compatibility with legacy applications.&lt;br /&gt;
&lt;br /&gt;
== 10. Driver expectations ==&lt;br /&gt;
Kernel drivers participating in readiness notification are expected to:&lt;br /&gt;
&lt;br /&gt;
* Advertise readiness consistently&lt;br /&gt;
* Signal state changes when readiness transitions occur&lt;br /&gt;
* Maintain internal state sufficient to avoid missed notifications&lt;br /&gt;
&lt;br /&gt;
IRIX is tolerant of drivers that partially implement these expectations, though reduced performance or warnings may result.&lt;br /&gt;
&lt;br /&gt;
Solaris assumes stricter adherence to the readiness framework.&lt;br /&gt;
&lt;br /&gt;
== 11. Summary of key differences from Solaris ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Area&lt;br /&gt;
!IRIX&lt;br /&gt;
!Solaris&lt;br /&gt;
|-&lt;br /&gt;
|Readiness model&lt;br /&gt;
|Object-centric, targeted&lt;br /&gt;
|Object-centric, broader&lt;br /&gt;
|-&lt;br /&gt;
|Wakeup precision&lt;br /&gt;
|Highly filtered&lt;br /&gt;
|Moderately filtered&lt;br /&gt;
|-&lt;br /&gt;
|Poll ordering&lt;br /&gt;
|Locality-optimized&lt;br /&gt;
|Fairness-oriented&lt;br /&gt;
|-&lt;br /&gt;
|Partial poll support&lt;br /&gt;
|Tolerated&lt;br /&gt;
|Less common&lt;br /&gt;
|-&lt;br /&gt;
|Race recovery&lt;br /&gt;
|Immediate retry&lt;br /&gt;
|Deferred detection&lt;br /&gt;
|-&lt;br /&gt;
|Timeout precision&lt;br /&gt;
|Tick-based, conservative&lt;br /&gt;
|Higher resolution&lt;br /&gt;
|-&lt;br /&gt;
|select compatibility&lt;br /&gt;
|Strong legacy fidelity&lt;br /&gt;
|Version-dependent&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 12. Guidance for emulation or re-implementation ==&lt;br /&gt;
To mimic IRIX poll/select behavior:&lt;br /&gt;
&lt;br /&gt;
* Use object-centric readiness tracking&lt;br /&gt;
* Avoid broadcast wakeups&lt;br /&gt;
* Preserve per-event filtering&lt;br /&gt;
* Support conservative timeout rounding&lt;br /&gt;
* Clean up readiness state on interruption&lt;br /&gt;
* Preserve historical select(2) error behavior&lt;br /&gt;
&lt;br /&gt;
Attempting to directly transplant Solaris semantics without accounting for these differences will result in observable behavioral drift.&lt;br /&gt;
&lt;br /&gt;
== 13. Final note ==&lt;br /&gt;
IRIX poll/select behavior is best understood not as a variant of Solaris, but as a parallel evolution from the same SVR4 roots, shaped by IRIX’s scalability goals and long hardware lifespan.&lt;br /&gt;
&lt;br /&gt;
This behavior is intentional, consistent, and relied upon by real software.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_STREAMS&amp;diff=476</id>
		<title>Kernel: STREAMS</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_STREAMS&amp;diff=476"/>
		<updated>2026-01-09T23:57:41Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The IRIX [[STREAMS]] framework provides a modular, message-passing I/O subsystem for character devices, terminals, network protocols, and pseudo-devices. It uses queues (read/write pairs per module/driver), message blocks (mblk_t/dblk_t), and buffers for data transfer. The implementation is highly optimized for performance with:&lt;br /&gt;
&lt;br /&gt;
Per-CPU free lists (NUMA-aware) for message blocks, data blocks, and buffers of various sizes.&lt;br /&gt;
Cache coloring and alignment support.&lt;br /&gt;
Zone-based allocation for small structures.&lt;br /&gt;
Page-based buffering with coalescing and reclaim.&lt;br /&gt;
Global limits and dynamic reclamation via strgiveback.&lt;br /&gt;
MP-safe design using spinlocks per CPU.&lt;br /&gt;
&lt;br /&gt;
The core data structures are managed through list vectors (lf_listvec) per CPU, with separate pools for different buffer sizes (64B to full page).&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Initialization&lt;br /&gt;
&lt;br /&gt;
str_init_master: Initializes global structures for master CPU.&lt;br /&gt;
str_init_slave: Sets up per-CPU structures for slave CPUs.&lt;br /&gt;
str_init_memsize: Configures page limits based on physical memory.&lt;br /&gt;
str_init_alloc_bufs: Preallocates initial buffers per CPU.&lt;br /&gt;
strinit_giveback: Starts periodic page reclamation timer.&lt;br /&gt;
&lt;br /&gt;
Message Block Allocation&lt;br /&gt;
&lt;br /&gt;
allocb: Allocates mblk_t + dblk_t + buffer (various sizes).&lt;br /&gt;
allocb_nobuffer: Allocates only mblk_t/dblk_t (no data buffer).&lt;br /&gt;
esballoc: Attaches external buffer (zero-copy).&lt;br /&gt;
bufcall / esbbcall: Schedule callback when memory available.&lt;br /&gt;
&lt;br /&gt;
Queue Operations&lt;br /&gt;
&lt;br /&gt;
putq / putbq / insq: Insert message into queue (priority-ordered).&lt;br /&gt;
getq: Remove next message from queue.&lt;br /&gt;
rmvq: Remove specific message.&lt;br /&gt;
flushq / flushband: Discard messages (all or by band).&lt;br /&gt;
qenable: Schedule queue service routine.&lt;br /&gt;
canput / bcanput: Flow control checks.&lt;br /&gt;
&lt;br /&gt;
Buffer Management&lt;br /&gt;
&lt;br /&gt;
lf_get / lf_free: Node allocation/deallocation from per-CPU lists.&lt;br /&gt;
lf_addpage / lf_getpage_tiled: Page tiling and addition to free lists.&lt;br /&gt;
lf_freepage: Return full page to kernel VM.&lt;br /&gt;
str_preallocate: Initial buffer preallocation.&lt;br /&gt;
&lt;br /&gt;
Special Cases&lt;br /&gt;
&lt;br /&gt;
msgpullup: Coalesce message into single contiguous buffer.&lt;br /&gt;
copyb / copymsg / dupb / dupmsg: Copy or reference-count messages.&lt;br /&gt;
linkb / unlinkb: Chain management.&lt;br /&gt;
adjmsg: Trim bytes from head/tail.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Structures&lt;br /&gt;
&lt;br /&gt;
mblk_t: Message descriptor (pointers, type, flags, band).&lt;br /&gt;
dblk_t: Data block (buffer pointers, refcount, type, size, free routine).&lt;br /&gt;
queue_t: Read/write queue pair with flow control parameters.&lt;br /&gt;
qband_t: Per-priority-band flow control (for non-zero bands).&lt;br /&gt;
lf_listvec / listvec: Per-CPU free list vectors with multiple size classes.&lt;br /&gt;
strstat: Per-CPU statistics.&lt;br /&gt;
&lt;br /&gt;
Buffer Pools&lt;br /&gt;
&lt;br /&gt;
Fixed sizes: 64, 256, 512, 2048 bytes + full page.&lt;br /&gt;
Combined mblk_t/dblk_t pool.&lt;br /&gt;
Separate message header pool.&lt;br /&gt;
Page reclamation: strgiveback returns excess pages to kernel.&lt;br /&gt;
&lt;br /&gt;
NUMA Awareness&lt;br /&gt;
&lt;br /&gt;
Per-node, per-CPU list vectors.&lt;br /&gt;
Allocation prefers local node.&lt;br /&gt;
&lt;br /&gt;
Flow Control&lt;br /&gt;
&lt;br /&gt;
High/low water marks per queue and band.&lt;br /&gt;
QFULL / QB_FULL flags.&lt;br /&gt;
Back-enable nearest upstream service routine.&lt;br /&gt;
&lt;br /&gt;
Extended Free Routine&lt;br /&gt;
&lt;br /&gt;
esballoc supports external buffers with custom free function.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong similarity:&lt;br /&gt;
&lt;br /&gt;
Message block (mblk_t/dblk_t) and queue model nearly identical.&lt;br /&gt;
allocb, esballoc, putq, getq, canput, qenable.&lt;br /&gt;
Per-CPU caches and buffer pools.&lt;br /&gt;
Flow control with high/low water.&lt;br /&gt;
&lt;br /&gt;
Differences: illumos uses kmem_cache extensively; more modular.&lt;br /&gt;
BSD (FreeBSD, etc.)&lt;br /&gt;
Less similar:&lt;br /&gt;
&lt;br /&gt;
No native STREAMS (removed long ago).&lt;br /&gt;
Character I/O via cdevsw or tty.&lt;br /&gt;
Some ports emulate via compatibility layers.&lt;br /&gt;
&lt;br /&gt;
Overall, IRIX STREAMS is classic SVR4 with NUMA/per-CPU optimizations. illumos provides closest modern equivalent; BSD lacks native support. For replication: preserve per-CPU lists, buffer size classes, and queue scheduling semantics. Page reclamation and tiling logic are IRIX-specific.&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_vnode_and_vfs&amp;diff=475</id>
		<title>Kernel: vnode and vfs</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_vnode_and_vfs&amp;diff=475"/>
		<updated>2026-01-09T23:57:38Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;IRIX’s VFS (Virtual File System) and vnode architecture is conceptually similar to many UNIX-derived systems (BSD, System V, Solaris), but with some IRIX-specific behavior layering and STREAMS integration. The vnode system provides a uniform abstraction for all filesystem objects, enabling the kernel to operate generically on files, directories, FIFOs, and devices without knowing the underlying filesystem implementation.&lt;br /&gt;
&lt;br /&gt;
=== 1. Vnode: Abstract File Object ===&lt;br /&gt;
&lt;br /&gt;
* Purpose: Represents an in-memory file or pseudo-file object. Every file, device, pipe, or FIFO that a process can access has a corresponding vnode.&lt;br /&gt;
* Key Responsibilities:&lt;br /&gt;
** Maintain reference counts (&amp;lt;code&amp;gt;v_count&amp;lt;/code&amp;gt;) for lifecycle management.&lt;br /&gt;
** Track the type of file (&amp;lt;code&amp;gt;v_type&amp;lt;/code&amp;gt;), device association (&amp;lt;code&amp;gt;v_rdev&amp;lt;/code&amp;gt;), and filesystem association (&amp;lt;code&amp;gt;v_vfsp&amp;lt;/code&amp;gt;).&lt;br /&gt;
** Serve as a link to behavior-specific operations (via &amp;lt;code&amp;gt;v_bh&amp;lt;/code&amp;gt;).&lt;br /&gt;
** Integrate with streams (&amp;lt;code&amp;gt;v_stream&amp;lt;/code&amp;gt;) if the object is a pipe, TTY, or socket.&lt;br /&gt;
** Enable VM caching, delayed writes, and buffer trees for efficient I/O.&lt;br /&gt;
* Comparison to Solaris:  IRIX vnodes are conceptually similar to Solaris &amp;lt;code&amp;gt;vnode_t&amp;lt;/code&amp;gt;. Both provide:&lt;br /&gt;
** Reference counting&lt;br /&gt;
** Filesystem abstraction&lt;br /&gt;
** A behavior or operations layer&lt;br /&gt;
** VM caching integration  Differences: IRIX exposes &amp;lt;code&amp;gt;v_buf&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;v_dpages&amp;lt;/code&amp;gt; directly for buffer/page management; Solaris tends to isolate VM caching in the &amp;lt;code&amp;gt;vnode&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;vfs&amp;lt;/code&amp;gt; interface via &amp;lt;code&amp;gt;v_cache&amp;lt;/code&amp;gt; and VM layers.&lt;br /&gt;
&lt;br /&gt;
=== 2. Behavior Layer (BHV) ===&lt;br /&gt;
&lt;br /&gt;
* Purpose: Allows vnodes to stack filesystem-specific operations on top of a generic vnode.&lt;br /&gt;
* Mechanism:&lt;br /&gt;
** Each vnode has a behavior descriptor list (&amp;lt;code&amp;gt;v_bh&amp;lt;/code&amp;gt;).&lt;br /&gt;
** Filesystems (pipefs, efs, xfs, fifofs) insert their operations at initialization.&lt;br /&gt;
** Kernel vnode calls (&amp;lt;code&amp;gt;VOP_READ&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;VOP_WRITE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;VOP_CLOSE&amp;lt;/code&amp;gt;) traverse the behavior chain to find the appropriate function.&lt;br /&gt;
* Comparison to Solaris:  IRIX’s BHV is functionally similar to Solaris’ VOP vector and shadow vnode mechanism in layered filesystems, but IRIX’s BHV model explicitly allows multiple behaviors per vnode (stacked operations).&lt;br /&gt;
&lt;br /&gt;
=== 3. VFS: Virtual Filesystem Layer ===&lt;br /&gt;
&lt;br /&gt;
* Purpose: Represents a mounted filesystem in-memory, providing a global interface for:&lt;br /&gt;
** File lookup&lt;br /&gt;
** Attribute management&lt;br /&gt;
** Mount/unmount operations&lt;br /&gt;
** Import/export for NFS or network filesystems&lt;br /&gt;
* VFS Operations (&amp;lt;code&amp;gt;vfsops_t&amp;lt;/code&amp;gt;):&lt;br /&gt;
** &amp;lt;code&amp;gt;mount&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;umount&amp;lt;/code&amp;gt;: Mount/unmount filesystem&lt;br /&gt;
** &amp;lt;code&amp;gt;sync&amp;lt;/code&amp;gt;: Flush dirty data&lt;br /&gt;
** &amp;lt;code&amp;gt;statvfs&amp;lt;/code&amp;gt;: Retrieve filesystem statistics&lt;br /&gt;
** &amp;lt;code&amp;gt;vget&amp;lt;/code&amp;gt;: Lookup vnode by inode within the filesystem&lt;br /&gt;
** &amp;lt;code&amp;gt;quotactl&amp;lt;/code&amp;gt;: Manage quotas (if supported)&lt;br /&gt;
** &amp;lt;code&amp;gt;import&amp;lt;/code&amp;gt;: Handle import of remote filesystem data&lt;br /&gt;
** &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;: Provide vnode for root of FS&lt;br /&gt;
** &amp;lt;code&amp;gt;reclaim&amp;lt;/code&amp;gt;: Clean up filesystem-specific vnode state&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Note: In IRIX pipefs, most of these are &amp;lt;code&amp;gt;fs_nosys&amp;lt;/code&amp;gt; or dummy functions because pipefs is a pseudo-filesystem without persistent storage.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Comparison to Solaris:&lt;br /&gt;
** Very similar to Solaris &amp;lt;code&amp;gt;vfsops_t&amp;lt;/code&amp;gt;.&lt;br /&gt;
** Both systems separate filesystem-specific behavior (&amp;lt;code&amp;gt;vnodeops_t&amp;lt;/code&amp;gt;) from filesystem-wide operations (&amp;lt;code&amp;gt;vfsops_t&amp;lt;/code&amp;gt;).&lt;br /&gt;
** IRIX adds &amp;lt;code&amp;gt;vfs_insertbhv&amp;lt;/code&amp;gt; to bind a VFS to its BHV layer, enabling layered filesystems.&lt;br /&gt;
&lt;br /&gt;
=== 4. Vnode Operations (&amp;lt;code&amp;gt;vnodeops_t&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
* Purpose: Defines the operations you can perform on a vnode, such as read, write, ioctl, getattr, setattr, seek, poll, and more.&lt;br /&gt;
* IRIX Implementation Pattern:&lt;br /&gt;
** Functions take a behavior descriptor (&amp;lt;code&amp;gt;bhv_desc_t&amp;lt;/code&amp;gt;) instead of the vnode directly.&lt;br /&gt;
** For pseudo-filesystems like pipefs, the operations implement custom logic (e.g., &amp;lt;code&amp;gt;pipe_read&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;pipe_write&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;pipe_poll&amp;lt;/code&amp;gt;).&lt;br /&gt;
** Many operations are stubbed to &amp;lt;code&amp;gt;fs_nosys&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;fs_noerr&amp;lt;/code&amp;gt; if not meaningful (e.g., &amp;lt;code&amp;gt;vop_create&amp;lt;/code&amp;gt; in pipefs).&lt;br /&gt;
* Categories of operations:&lt;br /&gt;
*# File I/O: &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ioctl&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fsync&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fcntl&amp;lt;/code&amp;gt;&lt;br /&gt;
*# Attributes: &amp;lt;code&amp;gt;getattr&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;setattr&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;access&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;pathconf&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;attr_get/set&amp;lt;/code&amp;gt;&lt;br /&gt;
*# Directory/Namespace: &amp;lt;code&amp;gt;lookup&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;remove&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mkdir&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;rmdir&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;readdir&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;symlink&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;readlink&amp;lt;/code&amp;gt;&lt;br /&gt;
*# Locking/Mapping: &amp;lt;code&amp;gt;rwlock&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;rwunlock&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;addmap&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;delmap&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;frlock&amp;lt;/code&amp;gt;&lt;br /&gt;
*# Streams support: &amp;lt;code&amp;gt;strgetmsg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;strputmsg&amp;lt;/code&amp;gt;&lt;br /&gt;
*# Polling/Selection: &amp;lt;code&amp;gt;poll&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;select&amp;lt;/code&amp;gt; integration via &amp;lt;code&amp;gt;pollhead&amp;lt;/code&amp;gt;&lt;br /&gt;
*# Cleanup: &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reclaim&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;realvp&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cover&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;link_removed&amp;lt;/code&amp;gt;&lt;br /&gt;
* Comparison to Solaris:&lt;br /&gt;
** IRIX &amp;lt;code&amp;gt;vnodeops_t&amp;lt;/code&amp;gt; maps almost one-to-one to Solaris VOP functions.&lt;br /&gt;
** IRIX uses &amp;lt;code&amp;gt;bhv_desc_t&amp;lt;/code&amp;gt; for behavior dispatch; Solaris uses direct &amp;lt;code&amp;gt;vnode_t*&amp;lt;/code&amp;gt; and VOP macros.&lt;br /&gt;
** &amp;lt;code&amp;gt;pipefs&amp;lt;/code&amp;gt; shows how pseudo-filesystems are inserted into the BHV chain.&lt;br /&gt;
&lt;br /&gt;
=== 5. Lifecycle Management ===&lt;br /&gt;
&lt;br /&gt;
* Reference counting (&amp;lt;code&amp;gt;v_count&amp;lt;/code&amp;gt;) is used by:&lt;br /&gt;
** VFS, FS operations, streams, and user-level file descriptors.&lt;br /&gt;
* Inactive/Teardown:&lt;br /&gt;
** &amp;lt;code&amp;gt;vnode_inactive&amp;lt;/code&amp;gt; is called when the last reference is released.&lt;br /&gt;
** Pseudo-filesystems clean up buffers, semaphores, SVs, and polling structures.&lt;br /&gt;
* Reclaim:&lt;br /&gt;
** &amp;lt;code&amp;gt;vop_reclaim&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;fs_noerr&amp;lt;/code&amp;gt;) allows the FS to free internal structures before the vnode memory itself is freed.&lt;br /&gt;
* Comparison to Solaris:&lt;br /&gt;
** IRIX inactive/reclaim closely mirrors Solaris, where &amp;lt;code&amp;gt;VN_RELE&amp;lt;/code&amp;gt; triggers &amp;lt;code&amp;gt;VOP_INACTIVE&amp;lt;/code&amp;gt; and may later call &amp;lt;code&amp;gt;VOP_RECLAIM&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 6. Integration with Poll/Select ===&lt;br /&gt;
&lt;br /&gt;
* Each vnode supporting streams or pseudo-filesystems exposes a &amp;lt;code&amp;gt;poll&amp;lt;/code&amp;gt; operation (&amp;lt;code&amp;gt;pipe_poll&amp;lt;/code&amp;gt; example).&lt;br /&gt;
* Vnode maintains pollheads (&amp;lt;code&amp;gt;pi_rpq&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;pi_wpq&amp;lt;/code&amp;gt;) to manage sleeping readers/writers.&lt;br /&gt;
* Poll/select logic interacts directly with vnodes’ wait queues, using semaphores and SVs to wake sleeping processes.&lt;br /&gt;
* IRIX integrates select/poll tightly with its behavior layer: the &amp;lt;code&amp;gt;vnodeops&amp;lt;/code&amp;gt; dispatch ensures the correct filesystem or pseudo-device handles events.&lt;br /&gt;
&lt;br /&gt;
=== 7. Streams and Pseudo-Filesystems ===&lt;br /&gt;
&lt;br /&gt;
* Vnodes can represent STREAMS objects (&amp;lt;code&amp;gt;v_stream&amp;lt;/code&amp;gt;), which include pipes, ttys, sockets.&lt;br /&gt;
* Pseudo-filesystems like pipefs, fifofs, or STREAMS-based devices rely on vnodes for identity but do not implement persistent storage.&lt;br /&gt;
* Pipefs shows:&lt;br /&gt;
** Behavior insertion (&amp;lt;code&amp;gt;pipe_bhv&amp;lt;/code&amp;gt;)&lt;br /&gt;
** Read/write/poll implemented at the vnode level&lt;br /&gt;
** Attribute, locking, and inactive handling integrated with BHV and semaphores&lt;br /&gt;
&lt;br /&gt;
=== 8. Key Semantic Takeaways vs. Solaris/OpenSolaris ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Feature&lt;br /&gt;
!IRIX&lt;br /&gt;
!Solaris / OpenSolaris&lt;br /&gt;
!Notes&lt;br /&gt;
|-&lt;br /&gt;
|Vnode abstraction&lt;br /&gt;
|Generic file object&lt;br /&gt;
|Generic file object&lt;br /&gt;
|Conceptually identical&lt;br /&gt;
|-&lt;br /&gt;
|Behavior Layer&lt;br /&gt;
|&amp;lt;code&amp;gt;v_bh&amp;lt;/code&amp;gt;, multiple behaviors&lt;br /&gt;
|VOP vector, shadow vnode&lt;br /&gt;
|IRIX allows stacking; Solaris uses layered vnode/shadow vnodes&lt;br /&gt;
|-&lt;br /&gt;
|VFS interface&lt;br /&gt;
|&amp;lt;code&amp;gt;vfsops_t&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;vfsops_t&amp;lt;/code&amp;gt;&lt;br /&gt;
|Almost identical; mount/unmount, sync, statvfs, vget&lt;br /&gt;
|-&lt;br /&gt;
|Vnode ops&lt;br /&gt;
|&amp;lt;code&amp;gt;vnodeops_t&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;vnodeops_t&amp;lt;/code&amp;gt;&lt;br /&gt;
|Nearly identical; both separate FS operations from global FS ops&lt;br /&gt;
|-&lt;br /&gt;
|Streams integration&lt;br /&gt;
|&amp;lt;code&amp;gt;v_stream&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;v_stream&amp;lt;/code&amp;gt; (STREAMS)&lt;br /&gt;
|Very similar; IRIX integrates tightly with select/poll via SVs/semaphores&lt;br /&gt;
|-&lt;br /&gt;
|Page/Buffer caching&lt;br /&gt;
|&amp;lt;code&amp;gt;v_dpages&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v_buf&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v_pc&amp;lt;/code&amp;gt;&lt;br /&gt;
|Solaris uses &amp;lt;code&amp;gt;v_cache&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;v_pages&amp;lt;/code&amp;gt;&lt;br /&gt;
|IRIX exposes more VM/buffer fields directly&lt;br /&gt;
|-&lt;br /&gt;
|Poll/select&lt;br /&gt;
|&amp;lt;code&amp;gt;pollhead&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sv_wait_sig&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;pollhead&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;selwait&amp;lt;/code&amp;gt;&lt;br /&gt;
|Both implement readiness/wakeup mechanisms; IRIX uses semaphores/SV directly&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 9. Summary ===&lt;br /&gt;
IRIX vnode/VFS system is:&lt;br /&gt;
&lt;br /&gt;
* Highly modular: behavior layers allow multiple filesystems and pseudo-filesystems to stack operations.&lt;br /&gt;
* Stream-aware: supports pipes, ttys, FIFOs, and sockets in a unified way.&lt;br /&gt;
* Poll/select integrated: readiness queues and SVs are part of each vnode.&lt;br /&gt;
* VM-aware: page cache, dirty pages, buffers, and delwri structures are exposed.&lt;br /&gt;
* Reference-counted: ensures proper lifecycle management via &amp;lt;code&amp;gt;inactive&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;reclaim&amp;lt;/code&amp;gt;.&lt;br /&gt;
* OpenSolaris-like: almost all concepts map directly to Solaris VFS/vnode system.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Kernel: vnode Operations]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_pfile&amp;diff=474</id>
		<title>Kernel: pfile</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_pfile&amp;diff=474"/>
		<updated>2026-01-09T23:57:08Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The pfile (physical file) object in the IRIX kernel represents per-open-file state beyond the vnode (file system-independent) and vfile (open file description) layers. It primarily manages the current file offset (pf_offset) and associated synchronization (pf_offlock). In single-cell (non-distributed) configurations, the pfile layer directly handles offset and flag operations. In distributed (multi-cell) environments using Cellular IRIX features, higher layers (DC - Distributed Coordinator, DS - Distributed Server) take over offset and flag management for coherence across cells.&lt;br /&gt;
The pfile is integrated via the behavior descriptor (bhv_desc_t) mechanism, part of IRIX&#039;s chained vnode/behavior system. This allows stacking behaviors (e.g., pfile on top of filesystem-specific behaviors) on a common vfile_t structure. The pfile behavior is registered through pfile_ops (a vfileops_t table) at position VFILE_POSITION_PFILE.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
The implementation provides operations for creation, offset management, flag handling, teardown, close, and migration.&lt;br /&gt;
Initialization (pfile_init)&lt;br /&gt;
Allocates a kernel zone (pfile_zone) for efficient pfile_t structures using kmem_zone_init.&lt;br /&gt;
Creation (pfile_create)&lt;br /&gt;
Called on file open: allocates a pfile_t from the zone, initializes offset mutex and sets offset to 0, creates and inserts a bhv_desc_t (pf_bd) into the vfile_t behavior chain at the initial position.&lt;br /&gt;
Migration (pfile_target_migrate)&lt;br /&gt;
Used during distributed target migration (e.g., cell handover): creates a new pfile behavior, inserts it into the chain, and sets a specific offset (preserving position across migration).&lt;br /&gt;
Flag Management (pfile_setflags)&lt;br /&gt;
Locks the vfile_t, modifies open flags (vf_flag) using atomic mask/or operations, unlocks.&lt;br /&gt;
Offset Access (pfile_getoffset / pfile_setoffset)&lt;br /&gt;
Simple unprotected read/write of pf_offset. VFILE_NO_OFFSET is ignored on set.&lt;br /&gt;
Locked Offset Access (pfile_getoffset_locked / pfile_setoffset_locked)&lt;br /&gt;
Optional locking of pf_offlock (cell mutex) around offset operations for distributed safety.&lt;br /&gt;
Teardown (pfile_teardown)&lt;br /&gt;
Destroys offset mutex, removes behavior from chain (if vnode exists), frees pfile_t to zone. Asserts mutex not held.&lt;br /&gt;
Close Handling (pfile_close)&lt;br /&gt;
Called twice per close (first/last): decrements vf_count in vfile_t, returns flags indicating last close.&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures&lt;br /&gt;
&lt;br /&gt;
pfile_t (from pfile_private.h):&lt;br /&gt;
off_t pf_offset — current file position.&lt;br /&gt;
mutex_t pf_offlock — mutex protecting offset in distributed mode.&lt;br /&gt;
bhv_desc_t pf_bd — behavior descriptor linking to vfile.&lt;br /&gt;
&lt;br /&gt;
vfileops_t pfile_ops — operations table registered in behavior chain:&lt;br /&gt;
Position: VFILE_POSITION_PFILE&lt;br /&gt;
Functions: setflags, getoffset, setoffset, locked variants, teardown, close.&lt;br /&gt;
&lt;br /&gt;
Integration with vfile_t:&lt;br /&gt;
Contains vf_flag (open flags), vf_count (reference count), vf_bh (behavior chain head).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Distributed vs Single-Cell Behavior&lt;br /&gt;
&lt;br /&gt;
Single-cell: pfile directly manages offset/flags.&lt;br /&gt;
Multi-cell (Cellular IRIX): DC/DS layers override; pfile provides fallback or local cache.&lt;br /&gt;
&lt;br /&gt;
Behavior Chain Mechanics&lt;br /&gt;
Uses bhv_desc_t chaining (bhv_insert_initial, bhv_insert, bhv_remove). Allows dynamic stacking of behaviors (e.g., pfile over XFS/EFS vnode).&lt;br /&gt;
Migration Support&lt;br /&gt;
pfile_target_migrate enables seamless offset preservation during distributed file target changes (rare in standard IRIX, specific to Cellular configurations).&lt;br /&gt;
== Similarities to illumos and BSD libc/kernel Implementations ==&lt;br /&gt;
IRIX file handling differs significantly from modern open-file-description models due to its vnode/behavior layering.&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Moderate similarity in layered vnode design (vnode ops, but no direct behavior chaining). File offsets live in struct file (user fd) or uio; no separate pfile-like object. Distributed features (Cluster) use different mechanisms. illumos uses struct cred, zones; no exact pfile equivalent.&lt;br /&gt;
BSD (FreeBSD, etc.)&lt;br /&gt;
Less similar: file offsets in struct file (per-fd), with filedesc table. Vnode ops direct, no behavior descriptors/chaining. No distributed cell concept; clustering separate. Close handling simpler (single decrement).&lt;br /&gt;
Overall, IRIX&#039;s pfile is unique to its bhv_desc_t behavior system, designed for extensibility and distributed coherence. For replication or porting, focus on exact behavior insertion order and mutex usage. No direct illumos/BSD analog for easy porting; closest is Solaris vnode layering but without pfile separation.&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_malloc&amp;diff=473</id>
		<title>Kernel: malloc</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_malloc&amp;diff=473"/>
		<updated>2026-01-09T23:56:26Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page documents the memory allocation subsystem of the IRIX kernel (`malloc`, `rmalloc`, and related functions) as implemented in the IRIX kernel. It is intended as a functional reference for reimplementation in other kernels (e.g., Illumos).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The IRIX memory allocation system provides:&lt;br /&gt;
&lt;br /&gt;
* Map-based memory management (`struct map`) for contiguous resource allocation.&lt;br /&gt;
* Page-aligned and color-aware allocations for cache efficiency (R4000-specific).&lt;br /&gt;
* Bitmap-based system page table (SPT) management.&lt;br /&gt;
* Waiting and non-waiting allocation paths (`VM_NOSLEEP` flag).&lt;br /&gt;
* Synchronization primitives using spinlocks and semaphores.&lt;br /&gt;
&lt;br /&gt;
Memory management in IRIX is based on two concepts:&lt;br /&gt;
&lt;br /&gt;
# **Maps** – contiguous resources tracked as a list of free/allocated blocks.&lt;br /&gt;
# **Bitmaps** – finer-grained allocation (e.g., pages, cache-colored pages) with alignment support.&lt;br /&gt;
&lt;br /&gt;
== Map Allocation API ==&lt;br /&gt;
&lt;br /&gt;
=== rmallocmap() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate and initialize a `struct map` for tracking resources.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039; `mapsiz` – number of entries in the map.  &lt;br /&gt;
&#039;&#039;&#039;Outputs:&#039;&#039;&#039; Pointer to newly allocated map, or NULL on failure.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Allocates memory for `mapsiz + 2` map entries.&lt;br /&gt;
* Allocates and initializes a synchronization structure (`lock + semaphore`).&lt;br /&gt;
* Stores pointers to synchronization primitives in the second map entry.&lt;br /&gt;
* Returns a fully initialized map ready for allocations.&lt;br /&gt;
&lt;br /&gt;
=== rmfreemap() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free a previously allocated map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039; Pointer to map.  &lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Waits for any threads currently blocked on the map.&lt;br /&gt;
* Destroys associated semaphore and spinlock.&lt;br /&gt;
* Frees both the map memory and the synchronization structure.&lt;br /&gt;
&lt;br /&gt;
=== malloc / malloc_wait / rmalloc / rmalloc_wait ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate contiguous units from a map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `mp` – pointer to map&lt;br /&gt;
* `size` – number of units&lt;br /&gt;
* Optional `flags` (`VM_NOSLEEP` for non-blocking)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Uses **first-fit allocation**.&lt;br /&gt;
* Non-blocking (`VM_NOSLEEP`) returns `0` if allocation fails.&lt;br /&gt;
* Blocking waits on the map’s semaphore until space becomes available.&lt;br /&gt;
* Returns the starting address of allocated space.&lt;br /&gt;
&lt;br /&gt;
=== mfree / rmfree ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free previously allocated space in a map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `mp` – pointer to map&lt;br /&gt;
* `size` – units to free&lt;br /&gt;
* `a` – base address&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Sorts the freed block into the map.&lt;br /&gt;
* Merges with adjacent free blocks if possible.&lt;br /&gt;
* Updates map’s size and count.&lt;br /&gt;
* Broadcasts to any waiting threads if space becomes available.&lt;br /&gt;
* Logs warnings if map overflow or invalid free occurs.&lt;br /&gt;
&lt;br /&gt;
== Bitmap-Based Page Table Management ==&lt;br /&gt;
&lt;br /&gt;
The IRIX kernel uses **bitmap structures** to manage system page tables (`spt`). This allows fine-grained allocation with support for color and alignment.&lt;br /&gt;
&lt;br /&gt;
=== sptalloc() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate pages from the system page table bitmap.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – pointer to system bitmap structure&lt;br /&gt;
* `want` – number of pages&lt;br /&gt;
* `flags` – allocation flags (`VM_NOSLEEP`, `VM_VACOLOR`, `VM_BREAKABLE`)&lt;br /&gt;
* `color` – desired cache color (for R4000)&lt;br /&gt;
* `alignment` – page boundary alignment (power of 2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Selects a bitmap (clean, stale, aged) for allocation.&lt;br /&gt;
* If color-specific allocation is requested, attempts color map first.&lt;br /&gt;
* Uses rotors to track possible starting positions for efficiency.&lt;br /&gt;
* Supports alignment constraints.&lt;br /&gt;
* Will optionally wait (blocking) if pages are unavailable.&lt;br /&gt;
* Updates bitmap counters and rotors on allocation.&lt;br /&gt;
&lt;br /&gt;
=== sptfree() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free pages back to the system page table bitmap.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – pointer to system bitmap&lt;br /&gt;
* `size` – number of pages&lt;br /&gt;
* `mapaddr` – base address of pages to free&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Updates `m_lowbit`, `m_highbit`, and `m_count` in the bitmap.&lt;br /&gt;
* Sets freed bits in the bitmap.&lt;br /&gt;
* Broadcasts to waiting threads.&lt;br /&gt;
&lt;br /&gt;
=== mergebitmaps() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Merge one bitmap into another (e.g., stale pages back into main SPT map).  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – system bitmap&lt;br /&gt;
* `to` – destination bitmap&lt;br /&gt;
* `from` – source bitmap&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Copies set bits from source to destination.&lt;br /&gt;
* Updates rotor information for SPT allocation.&lt;br /&gt;
* Clears source bitmap.&lt;br /&gt;
&lt;br /&gt;
=== bmapswtch() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Swap contents of two bitmaps.  &lt;br /&gt;
&#039;&#039;&#039;Use case:&#039;&#039;&#039; Replace an old bitmap with a new one without modifying allocation state.&lt;br /&gt;
&lt;br /&gt;
=== sptgetsizes() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Get counts of pages in different states (clean, stale, aged, in-transit).&lt;br /&gt;
&lt;br /&gt;
== Synchronization and Multi-Processor Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Spinlocks (`mutex_spinlock`) protect map structures during allocation.&lt;br /&gt;
* Bitmaps have a hierarchy of locks:&lt;br /&gt;
** Normal allocation lock (`MAP_ALLOCLOCK`)**&lt;br /&gt;
** Urgent lock (`MAP_URGENTLOCK`)** – signals to other threads to back off during replenishment.&lt;br /&gt;
* Wait queues (semaphores) are used for threads blocked on resources.&lt;br /&gt;
&lt;br /&gt;
== R4000-Specific Enhancements ==&lt;br /&gt;
&lt;br /&gt;
* **Cache-colored allocation:** ensures pages allocated from a bitmap minimize cache conflicts.&lt;br /&gt;
* **sptvctst()** – tests for a free bit in a specific cache color.&lt;br /&gt;
* **color_alloc()** – allocates a page of a specific color.&lt;br /&gt;
* **sptaligntst()** – ensures alignment in allocations.&lt;br /&gt;
&lt;br /&gt;
== Fault Checking ==&lt;br /&gt;
&lt;br /&gt;
* `kvfaultcheck()` inspects which CPUs have references to aged or temporary pages.&lt;br /&gt;
* Returns a CPU mask indicating CPUs that need TLB flushes.&lt;br /&gt;
* Integration with isolate debugging on multi-CPU systems (EVEREST/SN0).&lt;br /&gt;
&lt;br /&gt;
== Notes for Reimplementation ==&lt;br /&gt;
&lt;br /&gt;
* Map-based allocations are generic and can be adapted to other OS kernels.&lt;br /&gt;
* Bitmap-based page allocations depend on low-level page tables; rotors and color optimizations can be implemented optionally.&lt;br /&gt;
* Careful handling of spinlocks, semaphores, and wait queues is required in multi-processor environments.&lt;br /&gt;
* Ensure that alignment and cache color are power-of-two values for correctness.&lt;br /&gt;
* Debug assertions (`ASSERT`) in IRIX should be converted to runtime checks or kernel asserts in the new environment.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Signal_Infrastructure&amp;diff=472</id>
		<title>Kernel: Signal Infrastructure</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Signal_Infrastructure&amp;diff=472"/>
		<updated>2026-01-09T23:56:07Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX kernel signal infrastructure provides a comprehensive, POSIX-compliant signal delivery system with extensions for real-time, debugging, and multi-threaded processes. Signals are managed at both process (sigvec_t in proc_t) and thread (ut_sig, ut_sighold in uthread_t) levels, allowing per-thread signal masks and delivery while maintaining process-wide consistency.&lt;br /&gt;
Key features:&lt;br /&gt;
&lt;br /&gt;
Queued signals (sigqueue_t) for POSIX sigqueue and siginfo delivery.&lt;br /&gt;
Priority-based delivery with job control stops handled specially.&lt;br /&gt;
Alternate signal stacks (sigaltstack, legacy sigstack).&lt;br /&gt;
Signal contexts (ucontext_t, sigcontext) for setcontext/getcontext and signal handlers.&lt;br /&gt;
Debugging integration (/proc, ptrace).&lt;br /&gt;
Multi-threaded awareness — signals can target specific uthreads or the process.&lt;br /&gt;
Async signal delivery via async_vec_t for non-sleepable contexts.&lt;br /&gt;
&lt;br /&gt;
The system carefully handles races between signal posting, masking, and delivery using spinlocks and atomic operations.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Signal Posting&lt;br /&gt;
&lt;br /&gt;
sigtopid: Send signal to process by PID (handles async via async_call if SIG_NOSLEEP).&lt;br /&gt;
sigtouthread / sigtouthread_common: Deliver to specific uthread.&lt;br /&gt;
sigaddq / sigdeq / sigdelq: Manage queued siginfo structures.&lt;br /&gt;
sigqueue_alloc / sigqueue_free: Zone-based allocation.&lt;br /&gt;
&lt;br /&gt;
Signal Delivery&lt;br /&gt;
&lt;br /&gt;
issig: Check for pending unmasked signals (returns signal number).&lt;br /&gt;
fsig: Find first unheld signal.&lt;br /&gt;
psig: Process current signal — installs handler or takes default action.&lt;br /&gt;
sendsig: Set up user context and registers for handler entry.&lt;br /&gt;
stop / unstop: Job control and debugger stops.&lt;br /&gt;
&lt;br /&gt;
Context Management&lt;br /&gt;
&lt;br /&gt;
save/restore context functions for ucontext_t and legacy sigcontext.&lt;br /&gt;
irix5_*_savecontext / restorecontext: ABI-specific versions.&lt;br /&gt;
&lt;br /&gt;
Signal Waiting&lt;br /&gt;
&lt;br /&gt;
sigpending: Return pending signal set.&lt;br /&gt;
sigsuspend: Swap mask and sleep.&lt;br /&gt;
sigprocmask: Modify signal mask.&lt;br /&gt;
sigpoll / sigtimedwait: Wait for specific signals (POSIX sigwait family).&lt;br /&gt;
&lt;br /&gt;
Special Interfaces&lt;br /&gt;
&lt;br /&gt;
ptrace: Classic debugging interface.&lt;br /&gt;
sigaltstack / sigstack: Alternate signal stack control.&lt;br /&gt;
core: Generate core dump on fatal signals.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Structures&lt;br /&gt;
&lt;br /&gt;
sigvec_t (process-wide):&lt;br /&gt;
sv_sig, sv_sigign, sv_sigcatch: Pending, ignored, caught signals.&lt;br /&gt;
sv_hndlr[NSIG_HNDLRS]: Handler array.&lt;br /&gt;
sv_sigmasks, sv_signodefer, sv_sigrestart, sv_sigresethand: Per-signal flags.&lt;br /&gt;
sv_sigqueue: Head of queued siginfo list.&lt;br /&gt;
sv_pending: Count of queued signals.&lt;br /&gt;
&lt;br /&gt;
uthread_t signal fields:&lt;br /&gt;
ut_sig: Thread-private pending signals.&lt;br /&gt;
ut_sighold: Thread-private blocked mask.&lt;br /&gt;
ut_sigwait: Signals being waited on.&lt;br /&gt;
ut_cursig, ut_curinfo: Current signal and siginfo.&lt;br /&gt;
ut_suspmask: Saved mask during sigsuspend.&lt;br /&gt;
&lt;br /&gt;
sigqueue_t: Queued siginfo with chaining.&lt;br /&gt;
&lt;br /&gt;
Dual Delivery Model&lt;br /&gt;
&lt;br /&gt;
Signals can be process-directed (posted to sigvec_t) or thread-directed (sigtouthread).&lt;br /&gt;
VPROC_SENDSIG virtualizes delivery across threads.&lt;br /&gt;
Async delivery queue for non-sleepable contexts.&lt;br /&gt;
&lt;br /&gt;
Job Control Special Cases&lt;br /&gt;
&lt;br /&gt;
SIGCONT cancels pending stop signals.&lt;br /&gt;
Stop signals ignored if no handler and process orphaned (except SIGSTOP).&lt;br /&gt;
&lt;br /&gt;
Queued Signals&lt;br /&gt;
&lt;br /&gt;
sigqueue() delivers siginfo_t with value.&lt;br /&gt;
Multiple same-signal infos preserved only if SI_QUEUE, SI_ASYNCIO, etc.&lt;br /&gt;
&lt;br /&gt;
Alternate Stack&lt;br /&gt;
&lt;br /&gt;
prxy_sigsp, prxy_spsize, prxy_siglb: Track alternate stack base/size/low bound.&lt;br /&gt;
SS_ONSTACK flag managed carefully.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong similarity:&lt;br /&gt;
&lt;br /&gt;
sigqueue(), queued signals, siginfo_t.&lt;br /&gt;
sigprocmask, sigsuspend, sigaction semantics.&lt;br /&gt;
Alternate stack via sigaltstack.&lt;br /&gt;
Process + thread signal masks.&lt;br /&gt;
&lt;br /&gt;
Differences: illumos uses turnstiles; IRIX uses explicit queues and sv_t.&lt;br /&gt;
BSD (FreeBSD, etc.)&lt;br /&gt;
Moderate similarity:&lt;br /&gt;
&lt;br /&gt;
sigaction, sigprocmask, kill, sigaltstack.&lt;br /&gt;
Signal contexts for longjmp-style handlers.&lt;br /&gt;
&lt;br /&gt;
Differences: BSD simpler — no queued signals, weaker real-time, different threading model.&lt;br /&gt;
Overall, IRIX signal system is SVR4/POSIX compliant with strong multi-threading and queued signal support. illumos closest modern analog; BSD covers basics but lacks queued delivery and per-thread complexity. For replication: preserve dual process/thread model, queued siginfo handling, and careful ut_lock/sigvec coordination.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Virtual_Paging&amp;diff=471</id>
		<title>Kernel: Virtual Paging</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Virtual_Paging&amp;diff=471"/>
		<updated>2026-01-09T23:55:59Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX kernel virtual memory subsystem manages physical page allocation, deallocation, and mapping for kernel use. It features a sophisticated free page list organized by cache color buckets with separate queues for clean/stale and associated/unassociated pages, support for large pages (contiguous allocation and coalescing), NUMA-aware node-specific freelists, cache coloring and VCE avoidance, and optimizations for direct-mapped (K0/K1) vs K2 addresses.&lt;br /&gt;
Key characteristics:&lt;br /&gt;
&lt;br /&gt;
pfdat_t structures track per-page metadata (flags, use count, hash chains, etc.).&lt;br /&gt;
phead_t bucket arrays per node and page size manage free lists.&lt;br /&gt;
Aggressive cache line reuse and coloring to minimize conflicts.&lt;br /&gt;
Reservation system via memory pools to prevent deadlock.&lt;br /&gt;
Special handling for R10000 speculation bug (lowmem separation).&lt;br /&gt;
Poisoned page support for ECC/uncorrectable errors.&lt;br /&gt;
Kernel stack pool for fast allocation.&lt;br /&gt;
&lt;br /&gt;
The implementation prioritizes low-latency kernel allocation with careful TLB and cache management.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Core Allocation&lt;br /&gt;
&lt;br /&gt;
kvpalloc / kvpalloc_node: Allocate virtual + physical pages (K2 + physical).&lt;br /&gt;
kvalloc: Allocate only K2 virtual space.&lt;br /&gt;
kpalloc / kpalloc_node: Map physical pages into existing K2 space.&lt;br /&gt;
pagealloc / pagealloc_node / pagealloc_size: Core physical page allocator (single or large pages).&lt;br /&gt;
contig_memalloc / kmem_contig_alloc: Physically contiguous allocation.&lt;br /&gt;
&lt;br /&gt;
Deallocation&lt;br /&gt;
&lt;br /&gt;
kvpfree / kvpffree: Free virtual + physical (handles K0/K1/K2).&lt;br /&gt;
kvfree: Free only K2 virtual space.&lt;br /&gt;
pagefree / pagefree_size: Return physical page to freelist (with coalescing).&lt;br /&gt;
kmem_contig_free: Free contiguous block.&lt;br /&gt;
&lt;br /&gt;
Large Page Support&lt;br /&gt;
&lt;br /&gt;
lpage_alloc_contig_physmem: Allocate large contiguous block.&lt;br /&gt;
lpage_free_contig_physmem: Free large block.&lt;br /&gt;
lpage_coalesce: Background merging of adjacent free base pages.&lt;br /&gt;
lpage_split: Break large page into smaller ones.&lt;br /&gt;
&lt;br /&gt;
Special Cases&lt;br /&gt;
&lt;br /&gt;
page_mapin / page_mapout: Temporary mapping for copy/zero.&lt;br /&gt;
page_copy / page_zero: COW and fault-time zeroing (with BTE on SN0).&lt;br /&gt;
page_discard / page_error_clean: Handle ECC/poisoned pages.&lt;br /&gt;
kstack_alloc / kstack_free: Kernel stack page pool.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures (from pfdat.h, page.h, etc.)&lt;br /&gt;
&lt;br /&gt;
pfd_t (page frame data):&lt;br /&gt;
pf_flags: P_QUEUE, P_HASH, P_ANON, P_DONE, P_WAIT, P_DIRTY, P_DUMP, P_BULKDATA, P_ERROR, P_HWBAD, etc.&lt;br /&gt;
pf_use: Reference count.&lt;br /&gt;
pf_next/prev: Free list links.&lt;br /&gt;
pf_hchain: Hash chain.&lt;br /&gt;
pf_tag: Vnode or anon handle.&lt;br /&gt;
pf_pageno: File offset.&lt;br /&gt;
&lt;br /&gt;
phead_t (per-color bucket):&lt;br /&gt;
ph_count: Number of pages.&lt;br /&gt;
ph_list[PH_NLISTS]: CLEAN/STALE, ASSOC/NOASSOC (and POISONOUS on NUMA).&lt;br /&gt;
&lt;br /&gt;
Node-specific:&lt;br /&gt;
pg_free_t per node: freelists, phead arrays, rotors, counters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Free List Organization&lt;br /&gt;
&lt;br /&gt;
Per-node, per-page-size phead arrays.&lt;br /&gt;
Cache color bucketed (pheadmask).&lt;br /&gt;
Separate lists: CLEAN/STALE × ASSOC/NOASSOC (plus POISONOUS).&lt;br /&gt;
Rotor for round-robin uncached allocation.&lt;br /&gt;
&lt;br /&gt;
NUMA and Migration&lt;br /&gt;
&lt;br /&gt;
Node-local freelists.&lt;br /&gt;
Round-robin or radial search fallback.&lt;br /&gt;
Poisoned page handling (directory clearing, discard queues).&lt;br /&gt;
&lt;br /&gt;
R10000 Speculation Workaround&lt;br /&gt;
&lt;br /&gt;
Low memory (&amp;lt;256MB) separated.&lt;br /&gt;
Special sxbrk variants (low/high memory).&lt;br /&gt;
Kernel reference tracking (krpf) for DMA safety.&lt;br /&gt;
&lt;br /&gt;
Cache and TLB Optimizations&lt;br /&gt;
&lt;br /&gt;
Direct K0/K1 preferred when possible.&lt;br /&gt;
VCE avoidance via color validation.&lt;br /&gt;
Stale → clean promotion with selective cache flush.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong similarity:&lt;br /&gt;
&lt;br /&gt;
Page freelist with hash buckets and color awareness.&lt;br /&gt;
kmem allocator for kernel objects (zones similar to IRIX zones).&lt;br /&gt;
Contiguous allocation via vmem.&lt;br /&gt;
Page daemon (vhand equivalent).&lt;br /&gt;
NUMA support evolved differently (resource pools).&lt;br /&gt;
&lt;br /&gt;
Porting: illumos kmem/page subsystem closest; lacks exact phead coloring and large-page coalescing.&lt;br /&gt;
BSD (FreeBSD)&lt;br /&gt;
More divergent:&lt;br /&gt;
&lt;br /&gt;
Simple page queues (free, cache, etc.).&lt;br /&gt;
UMA/kmem for slabs, vm_page for physical.&lt;br /&gt;
Contiguous via contigmalloc.&lt;br /&gt;
No per-color buckets or large-page splitting.&lt;br /&gt;
&lt;br /&gt;
Porting: BSD simpler; lacks IRIX&#039;s sophisticated coloring, NUMA freelists, and coalescing.&lt;br /&gt;
Overall, IRIX VM is classic SVR4 with heavy MIPS/NUMA/R10000 optimizations. illumos provides nearest modern analog; BSD too simplified for direct mapping. For replication: preserve pfdat flags, phead structure, node freelists, and coalescing logic.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_ELF_Loader&amp;diff=470</id>
		<title>Kernel: ELF Loader</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_ELF_Loader&amp;diff=470"/>
		<updated>2026-01-09T23:55:52Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
The IRIX kernel&#039;s ELF loader manages the execution of ELF-format binaries on MIPS-based systems, accommodating 32-bit and 64-bit architectures along with multiple ABIs. It performs tasks such as validating file headers, preparing the user stack and arguments, mapping memory segments, handling dynamic linking, and applying hardware-specific adjustments. Integration with kernel components like address space handling, virtual memory allocation, process control, and resource management ensures efficient and reliable execution.&lt;br /&gt;
&lt;br /&gt;
The loader supports ABI transitions during execution, resource pre-allocation for constrained environments, and extensions for MIPS hardware errata. It processes both static and dynamic executables, coordinating with the runtime linker for shared libraries.&lt;br /&gt;
&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
&lt;br /&gt;
The loader comprises several core operations that orchestrate the execution process. Below is a detailed functional overview of these operations, describing their roles, inputs, logic, and outputs.&lt;br /&gt;
&lt;br /&gt;
=== Header Retrieval and Validation ===&lt;br /&gt;
&lt;br /&gt;
This function reads the ELF header and program headers from the executable file. It validates essential fields such as the magic number, class (32-bit or 64-bit), data encoding, file type (executable or dynamic), and MIPS-specific architecture flags. It determines the ABI version based on machine type and flags, ensuring compatibility with the system&#039;s capabilities. On success, it provides the parsed headers for further processing; failures result in errors like invalid executable format or bad request due to unsupported architecture.&lt;br /&gt;
&lt;br /&gt;
=== ELF Execution Dispatch ===&lt;br /&gt;
&lt;br /&gt;
The primary entry point for ELF binary execution dispatches based on the file&#039;s class to handle 32-bit or 64-bit specifics. It retrieves headers, scans program headers for dynamic linking indicators, auxiliary setup needs, and hardware options. It calculates auxiliary vector size, allocates kernel space for argument building, constructs the user stack, and reserves memory resources if required for batch processing. The process splits to manage stack usage, proceeding to image removal and new address space creation. Errors lead to cleanup and restoration of original state.&lt;br /&gt;
&lt;br /&gt;
=== Execution Completion ===&lt;br /&gt;
&lt;br /&gt;
Continuing from the dispatch, this phase removes the existing process image, creates a new address space with affinity considerations, and maps segments. For dynamic binaries, it loads the runtime linker, builds extended auxiliary vectors, and sets up the stack with execution parameters. It configures registers, including floating-point unit settings based on architecture, and transfers control to the entry point. Failures trigger process termination with detailed logging.&lt;br /&gt;
&lt;br /&gt;
=== Segment Mapping ===&lt;br /&gt;
&lt;br /&gt;
This operation maps ELF segments into the address space, focusing on loadable sections. It computes protections (read, write, execute) and flags (local mapping, heap consideration), handles zero-fill regions, and applies workarounds for hardware issues in executable pages. It identifies special program headers for dynamic linking, shared libraries, and options. Mapping occurs with file-backed regions, supporting checkpointing. Errors include memory shortages or invalid segment orders.&lt;br /&gt;
&lt;br /&gt;
=== Dynamic Shared Object Mapping ===&lt;br /&gt;
&lt;br /&gt;
Accessible from user space, this function maps segments for shared objects, typically invoked by the runtime linker. It validates file descriptors and permissions, copies program headers from user space, and performs mappings with potential workarounds. On memory errors, it attempts relocation to an alternate address range. Success returns the base address; failures unmap partial allocations.&lt;br /&gt;
&lt;br /&gt;
=== Memory Requirement Calculation ===&lt;br /&gt;
&lt;br /&gt;
These utilities estimate the physical memory needed for execution, summing requirements for writable segments, the user stack, and the runtime linker. Computations account for page alignments and cache results for repeated use, updating on file changes. This supports early reservation in resource-managed environments, preventing failures during critical phases.&lt;br /&gt;
&lt;br /&gt;
=== Hardware Workaround Check ===&lt;br /&gt;
&lt;br /&gt;
For specific CPU errata, this checks program headers for cleanliness indicators regarding problematic instructions. If needed, it flags the use of proxy mechanisms during mapping to mitigate issues in read-only executable regions.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
&lt;br /&gt;
=== MIPS Hardware Workarounds in PT_MIPS_OPTIONS ===&lt;br /&gt;
&lt;br /&gt;
IRIX scans PT_MIPS_OPTIONS sections for hardware patch flags:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;OHW_R5KCVTL&#039;&#039;&#039; (0x8): Indicates the binary is clean of the R5000 cvt.[ds].l bug. If absent on affected CPUs (with &#039;&#039;R5000_cvt_war&#039;&#039; enabled, typically n32/n64 ABIs), the kernel uses the &#039;&#039;mtext&#039;&#039; subsystem (proxy vnodes) to rewrite problematic instructions in read-only executable pages during mapping.&lt;br /&gt;
* &#039;&#039;&#039;OHW_R8KPFETCH&#039;&#039;&#039; (TFP_PREFETCH_WAR): On TFP (R8000) CPUs, non-dynamic MIPS4 binaries with prefetch instructions are rejected (EBADRQC) unless &#039;&#039;chk_ohw_r8kpfetch&#039;&#039; is non-zero. For dynamic binaries, the kernel sets a flag to add &#039;&#039;&#039;AT_PFETCHFD&#039;&#039;&#039; to auxv (see below).&lt;br /&gt;
&lt;br /&gt;
These flags trigger kernel-level instruction patching or rejection, not documented in public ELF ABI supplements.&lt;br /&gt;
&lt;br /&gt;
=== Extended Auxiliary Vector Entries ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;AT_PFETCHFD&#039;&#039;&#039;: Provides an open file descriptor to the executable for the runtime linker (rld) to apply prefetch instruction patches (no-ops) on TFP systems. Added when a dynamic binary requires the prefetch workaround.&lt;br /&gt;
&lt;br /&gt;
Standard auxv entries (AT_PHDR, AT_BASE, etc.) are used, but AT_PFETCHFD is an IRIX-specific extension.&lt;br /&gt;
&lt;br /&gt;
=== Memory Reservation (availsmem) for Exec ===&lt;br /&gt;
&lt;br /&gt;
* Functions &#039;&#039;elf_compute_availsmem&#039;&#039; and &#039;&#039;elf_get_availsmem&#039;&#039; precompute physical memory needs for writable segments (PF_W in PT_LOAD), user stack, and the runtime linker.&lt;br /&gt;
* Cached globally in &#039;&#039;runtime_loader_availsmem&#039;&#039; (recomputed if the runtime linker&#039;s vnode changes).&lt;br /&gt;
* For Miser batch jobs, reserves memory early via &#039;&#039;vm_pool_exec_reservemem&#039;&#039;; failure returns EMEMRETRY for retry.&lt;br /&gt;
&lt;br /&gt;
This mechanism prevents mid-exec failures in memory-constrained environments.&lt;br /&gt;
&lt;br /&gt;
=== Mapping Interfaces ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;execmap&#039;&#039; / &#039;&#039;mtext_execmap_vnode&#039;&#039;: Low-level mapping of file-backed regions with ZFOD, protections, and flags (e.g., MAP_LOCAL, MAP_BRK, MAP_PRIMARY).&lt;br /&gt;
* &#039;&#039;elfmap&#039;&#039;: User-called (from rld) to map DSO PT_LOAD segments. Supports alternate address relocation on ENOMEM by finding a free range and adjusting vaddrs.&lt;br /&gt;
* Integration with checkpointing (ckpt handles passed to mapping calls).&lt;br /&gt;
&lt;br /&gt;
=== Other Internal Behaviors ===&lt;br /&gt;
&lt;br /&gt;
* ABI transition handling: Temporarily sets process ABI proxy during exec; resets on failure.&lt;br /&gt;
* NUMA/affinity: New address space creation via &#039;&#039;aspm_exec_create&#039;&#039; and affinity link setup.&lt;br /&gt;
* FPU flags from PT_MIPS_OPTIONS (ODK_EXCEPTIONS): Sets precise exceptions or speculative mode in process FP flags.&lt;br /&gt;
* Runtime linker loading: Caches availsmem needs; sticky bit (VSVTX) on rld allows saving pregions.&lt;br /&gt;
* Error reporting: Detailed kill messages with reason codes for failed execs.&lt;br /&gt;
&lt;br /&gt;
These features extend standard ELF handling with IRIX-specific resource management, hardware errata mitigation, and kernel-runtime linker coordination.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:Virtual_Memory&amp;diff=469</id>
		<title>Kernel:Virtual Memory</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:Virtual_Memory&amp;diff=469"/>
		<updated>2026-01-09T23:55:35Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX virtual memory system manages physical and virtual memory resources on MIPS-based Silicon Graphics systems, supporting both 32-bit and 64-bit addressing modes with dynamic switching. It is designed for high-performance computing, graphics, and real-time applications, incorporating SVR4 features like demand paging, memory-mapped I/O (mmap, mprotect), and ELF executables. The system handles anonymous memory (e.g., heap, stack) via tree-based structures for copy-on-write efficiency during forks, and file-backed memory through vnode-integrated page caching. It supports large physical memory (up to 16 GB in later versions), virtual address spaces up to 1 TB per 64-bit process, and NUMA-aware allocation for multiprocessor scalability.&lt;br /&gt;
&lt;br /&gt;
Key aspects include page frame management, swapping to disk, variable page sizes for optimization, memory migration for load balancing, and reverse mapping for efficient invalidation. The VM subsystem integrates with IRIX&#039;s filesystem layers (e.g., XFS, EFS) for unified caching and I/O, and includes real-time enhancements like page locking to minimize latencies. It emphasizes multiprocessor efficiency with fine-grained locking, preemption, and hardware-specific optimizations for MIPS processors (e.g., R8000, R10000).&lt;br /&gt;
&lt;br /&gt;
== Key Components and Flow ==&lt;br /&gt;
&lt;br /&gt;
* **Address Space Management**: Processes operate in user or kernel mode, with virtual addresses mapped to physical memory or swap. User space is segmented (e.g., kuseg for 32-bit: 0-2GB), while kernel accesses extended regions.&lt;br /&gt;
* **Page Frame Data (pfdat)**: Tracks physical pages, including flags for states like hashed, queued, recycled, or bad. Supports replication in NUMA environments.&lt;br /&gt;
* **Anonymous Memory Handling**: Uses binary trees of anon structures for copy-on-write sharing post-fork, with caches for pages (pcache) and swap handles (scache).&lt;br /&gt;
* **File-Backed Caching**: Vnode page cache integrates with filesystems for demand-loaded pages, handling flush, invalidate, and toss operations.&lt;br /&gt;
* **Swapping and Paging**: Manages swap devices (up to 255), demand paging, and precomputation of memory needs (availsmem) for resource-constrained environments.&lt;br /&gt;
* **NUMA and Large Pages**: Node-specific data structures (pgdata, nodepda) for free lists and stats; supports multiple page sizes with coalescing and splitting.&lt;br /&gt;
* **Migration and Mapping**: Page migration for balancing; reverse maps (rmap) for quick invalidation during unmap or protection changes.&lt;br /&gt;
* **Real-Time Features**: Page locking, bounded interrupt latencies, and Miser integration for batch scheduling.&lt;br /&gt;
&lt;br /&gt;
Typical flow: On page fault (vfault/pfault), lookup in caches; if missing, allocate or swap in. Forks duplicate anon trees; exits prune and free resources. Memory pressure triggers swapping, coalescing, or migration.&lt;br /&gt;
&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
&lt;br /&gt;
The VM system comprises operations for memory allocation, mapping, fault handling, and resource management. Below is a detailed functional overview, describing roles, logic, and interactions.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous Memory Initialization and Allocation ===&lt;br /&gt;
Initializes global structures like allocation zones and shared anon lists. Creates new anon handles for regions, setting up locks and caches. Allocates and initializes anon nodes with reference counts and depth hints for tree management.&lt;br /&gt;
&lt;br /&gt;
=== Fork Handling (Duplication) ===&lt;br /&gt;
Duplicates anon structures for child processes, forming or extending binary trees to enable copy-on-write sharing. Allocates new leaf nodes for parent and child, linking them to the original root. Checks for tree depth and prunes if necessary. Reserves resources for potential cache growth.&lt;br /&gt;
&lt;br /&gt;
=== Exit or Region Free (Deallocation) ===&lt;br /&gt;
Disassociates regions from anon memory, removing leaf nodes and freeing pages/swap space. Collapses branches with single children recursively toward the root. Releases locks and nodes when reference counts reach zero.&lt;br /&gt;
&lt;br /&gt;
=== Tree Optimization (Collapse and Prune) ===&lt;br /&gt;
Reduces tree depth by merging parent-child pairs when one child is absent, transferring pages and swap handles. Selects survivor based on page count; discards covered pages. Prunes empty intermediate nodes with no pages/swap to prevent unbounded growth in long-lived forking processes.&lt;br /&gt;
&lt;br /&gt;
=== Page Insertion into Anon ===&lt;br /&gt;
Adds pages to leaf node caches, covering lower tree levels if needed. Ensures no duplicates; handles potential cache resizing.&lt;br /&gt;
&lt;br /&gt;
=== Page Modification Handling ===&lt;br /&gt;
Determines copy or steal for writes: Copies for shared or non-top-level pages; steals otherwise, clearing swap info and rehashing to top level. Heuristics for caching swapped pages when memory is abundant.&lt;br /&gt;
&lt;br /&gt;
=== Swap Handle Management ===&lt;br /&gt;
Merges or clears swap handles during collapses; transfers non-covered handles to survivors.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Cache Initialization ===&lt;br /&gt;
Sets up per-vnode caches during allocation or recycling, initializing hash structures and reference counts.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Lookup and Attachment ===&lt;br /&gt;
Searches caches for pages by logical number; attaches by incrementing use counts, resolving races with allocation/recycling.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Insertion ===&lt;br /&gt;
Adds pages to caches, resizing if needed; supports conditional insertion to handle races, freeing duplicates.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Removal and Invalidation ===&lt;br /&gt;
Removes pages from caches, marking bad or requeuing free; flushes/invalidates ranges, tossing to buffers if needed.&lt;br /&gt;
&lt;br /&gt;
=== Page Recycling and Migration ===&lt;br /&gt;
Recycles pages for reuse, removing from caches; migrates by copying state to new frames, updating caches atomically.&lt;br /&gt;
&lt;br /&gt;
=== Memory Requirement Estimation ===&lt;br /&gt;
Precomputes swap/memory needs for operations, caching for runtime linker and batch jobs.&lt;br /&gt;
&lt;br /&gt;
=== Hardware Workaround Checks ===&lt;br /&gt;
Scans for CPU errata indicators, flagging proxy use for instruction rewriting in executable pages.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
&lt;br /&gt;
=== Anonymous Memory Tree Structures ===&lt;br /&gt;
Binary trees of anon nodes for efficient copy-on-write: Leaves represent process-private pages; internal nodes share via parents. Depth hints and pruning thresholds (e.g., PRUNE_THRESHOLD) prevent degradation in forking servers. Covered pages discarded during merges; swap caches (scache) track out-of-memory handles.&lt;br /&gt;
&lt;br /&gt;
=== Shared Anonymous Pages (sanon) ===&lt;br /&gt;
Special lists for unreferenced, dirty, shared anon pages (psanonmem counter). Node-specific free lists with locks; removal macros handle MP races.&lt;br /&gt;
&lt;br /&gt;
=== Page and Swap Caches (pcache/scache) ===&lt;br /&gt;
Dual caches per anon/vnode: pcache hashes in-memory pages; scache manages swap handles for faulted-out pages. Dynamic resizing, preemption during long operations. Undocumented tokens for space reservation.&lt;br /&gt;
&lt;br /&gt;
=== Memory Reservation (availsmem) ===&lt;br /&gt;
Precomputes and reserves physical/swap memory for execs/forks, integrated with Miser for batch retries (EMEMRETRY). Global caching for runtime components.&lt;br /&gt;
&lt;br /&gt;
=== NUMA-Aware Data Structures ===&lt;br /&gt;
Per-node pgdata for free lists, stats, and rotors; nodepda integration for allocation. Large page (lpage) support with coalescing daemons, splitting, and stats (e.g., vfault/pfault retries by size).&lt;br /&gt;
&lt;br /&gt;
=== Page Migration and Reverse Mapping ===&lt;br /&gt;
Migr subsystem for NUMA balancing; rmap for efficient TLB shootdowns and unmaps. Pagemigr transfers states, handling object mutations.&lt;br /&gt;
&lt;br /&gt;
=== Hardware and Real-Time Extensions ===&lt;br /&gt;
Flags for MIPS errata (e.g., R5000 CVT, TFP prefetch); mtext proxies for instruction patching. Page locking for real-time, bounded latencies, and VCE avoidance for cache coloring.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Cache Synchronization ===&lt;br /&gt;
Reference counting (v_pcacheref) with wait bits for reclaim coordination; broadcast on zero refs. Integration with DMAPI, ShareII for extended file ops.&lt;br /&gt;
&lt;br /&gt;
These extend standard UNIX VM with SGI-specific optimizations for MIPS, NUMA, graphics, and HPC, emphasizing scalability and reliability.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Process_Scheduler&amp;diff=468</id>
		<title>Kernel: Process Scheduler</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Process_Scheduler&amp;diff=468"/>
		<updated>2026-01-09T23:55:24Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX process scheduler is accessed primarily through the schedctl(2) system call, which provides a rich set of scheduling controls reflecting IRIX&#039;s historical focus on real-time, multiprocessor, and high-performance computing workloads. It supports:&lt;br /&gt;
&lt;br /&gt;
Real-time fixed-priority scheduling (non-degrading)&lt;br /&gt;
Traditional UNIX nice-value adjustments (timeshare)&lt;br /&gt;
Process group and user-wide nice operations (BSD compatibility)&lt;br /&gt;
CPU affinity control&lt;br /&gt;
Scheduling mode selection (free/gang)&lt;br /&gt;
Full Frame Scheduler (FRS) interface for user-level hard real-time gangs&lt;br /&gt;
Legacy hooks for older scheduling extensions&lt;br /&gt;
&lt;br /&gt;
The implementation centers on vproc_t (virtual process) objects, which abstract scheduling attributes across processes/threads. Changes are applied via VPROC_ operations that update runqueue information safely.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Main Interface (schedctl)&lt;br /&gt;
Single entry point dispatching commands:&lt;br /&gt;
&lt;br /&gt;
MPTS_RTPRI / MPTS_GETRTPRI: Set/get real-time priority (range NDPHIMAX..NDPLOMIN). Superuser required except for self-demotion or within normal range.&lt;br /&gt;
MPTS_SLICE: Set per-process time slice (ticks).&lt;br /&gt;
MPTS_RENICE / variants: Adjust nice values for process, process group, or all processes of a user (emulating BSD setpriority/getpriority semantics).&lt;br /&gt;
MPTS_SETHINTS: Initialize PRDA hints (obsolete pthread-related).&lt;br /&gt;
MPTS_SETMASTER: Set scheduling master PID (legacy).&lt;br /&gt;
MPTS_SCHEDMODE: Set scheduling mode (SGS_FREE, SGS_GANG, etc.).&lt;br /&gt;
MPTS_AFFINITY_*: Enable/disable/query CPU affinity.&lt;br /&gt;
MPTS_FRS_*: Full Frame Scheduler user interface (create, enqueue, yield, etc.).&lt;br /&gt;
&lt;br /&gt;
Most operations require CAP_SCHED_MGT capability.&lt;br /&gt;
Process List Scanner (plistscanner / plistscan)&lt;br /&gt;
Utility for user-wide or group-wide operations:&lt;br /&gt;
&lt;br /&gt;
Scans entire process table via procscan().&lt;br /&gt;
Handles renice/getnice across all matching processes.&lt;br /&gt;
Safe credential access via pcred_access().&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Scheduling Parameters&lt;br /&gt;
&lt;br /&gt;
Real-time priorities: Fixed, non-degrading. Higher numerical value = higher priority.&lt;br /&gt;
NDPHIMAX (highest), NDPNORMMIN (boundary to timeshare), NDPLOMIN (lowest RT).&lt;br /&gt;
&lt;br /&gt;
Nice values: Traditional UNIX (-20..+19 translated via NZERO=20).&lt;br /&gt;
Time slice: Configurable in ticks (default system-wide).&lt;br /&gt;
&lt;br /&gt;
Scheduling Modes (via MPTS_SCHEDMODE)&lt;br /&gt;
&lt;br /&gt;
SGS_FREE: Default independent scheduling.&lt;br /&gt;
SGS_GANG: Gang scheduling (co-scheduling of related threads).&lt;br /&gt;
&lt;br /&gt;
CPU Affinity&lt;br /&gt;
Controlled via VPROC_SCHED_AFF; requires CAP_SCHED_MGT.&lt;br /&gt;
Frame Scheduler (FRS)&lt;br /&gt;
Hard real-time extension:&lt;br /&gt;
&lt;br /&gt;
User-level creation of scheduling &amp;quot;frames&amp;quot; (gangs).&lt;br /&gt;
Precise control over dispatch, yield, interrupt handling.&lt;br /&gt;
All FRS operations require CAP_SCHED_MGT.&lt;br /&gt;
Old FRS interface (MPTS_OLDFRS_*) returns ENOTSUP.&lt;br /&gt;
&lt;br /&gt;
Batch Job Restrictions&lt;br /&gt;
Processes in batch process groups (Miser) cannot be made real-time.&lt;br /&gt;
Permission Model&lt;br /&gt;
Heavy reliance on CAP_SCHED_MGT capability rather than simple uid==0 checks.&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Very close heritage (both SVR4 descendants):&lt;br /&gt;
&lt;br /&gt;
schedctl-like interface existed historically in Solaris.&lt;br /&gt;
Real-time fixed priorities (RT class).&lt;br /&gt;
PRIORITY/NICE control via priocntl(2).&lt;br /&gt;
Gang scheduling concepts (though Solaris used processor sets).&lt;br /&gt;
Frame Scheduler unique to IRIX; Solaris had alternative real-time extensions.&lt;br /&gt;
&lt;br /&gt;
Porting: illumos priocntl(2) system provides similar class/parameter control. FRS has no direct analog.&lt;br /&gt;
BSD (FreeBSD, NetBSD, OpenBSD)&lt;br /&gt;
More divergent:&lt;br /&gt;
&lt;br /&gt;
Nice via setpriority/getpriority (exact semantics matched by IRIX MPTS_RENICE_* variants).&lt;br /&gt;
Real-time via sched_setparam/sched_getparam (POSIX).&lt;br /&gt;
CPU affinity via cpuset(2).&lt;br /&gt;
No direct gang or frame scheduler equivalents.&lt;br /&gt;
No unified schedctl; separate syscalls.&lt;br /&gt;
&lt;br /&gt;
Porting: BSD nicer for nice/priority; lacks IRIX&#039;s unified interface and FRS. Real-time weaker than IRIX fixed-priority model.&lt;br /&gt;
Overall, IRIX scheduler reflects strong SVR4 real-time heritage with unique extensions (FRS, gang modes). illumos provides closest conceptual match; BSD covers nice semantics well but lacks advanced features. For replication, focus on vproc abstraction and capability checks. FRS is largely IRIX-specific and hard to port directly.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Mutex&amp;diff=467</id>
		<title>Kernel: Mutex</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Mutex&amp;diff=467"/>
		<updated>2026-01-09T23:54:26Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX kernel mutex implementation provides basic mutual exclusion primitives with priority inheritance to mitigate priority inversion, atomic owner tracking via compare-and-swap, optional metering/statistics, and integration with the broader [[Kernel:ksync]] (kernel synchronization) framework that includes sv_t (synchronization variables) for semaphores, condition variables, and other waitable objects.&lt;br /&gt;
The design uses a single-word owner field (m_bits) combining owner thread pointer with flags (lock bit, queue bit). Contention spins briefly then sleeps on a circular doubly-linked waiter queue. Priority inheritance propagates up blocked chains. The implementation supports debugging/metering via optional info structures and integrates with spinlocks, bitlocks, mrlocks, and semaphores through sv_t wrappers.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Initialization (kmutei_init)&lt;br /&gt;
Creates zones for mutex_t and sv_t structures. Initializes hash buckets for optional wchan info (debug/metering).&lt;br /&gt;
Allocation (mutex_alloc / init_mutex)&lt;br /&gt;
Zone-allocates mutex_t, clears bits, optionally allocates metering/info structure.&lt;br /&gt;
Deallocation (mutex_destroy / mutex_dealloc)&lt;br /&gt;
Frees info structure, zone-frees mutex.&lt;br /&gt;
Core Operations&lt;br /&gt;
&lt;br /&gt;
mutex_trylock: Atomic compare-and-swap to set owner; updates metering.&lt;br /&gt;
mutex_lock: Trylock → on miss, queue and sleep with priority inheritance probing.&lt;br /&gt;
mutex_unlock: Clears owner; if waiters, wakes highest-priority waiter (single thread).&lt;br /&gt;
mutex_wait: Queues thread, handles inheritance, blocks (non-breakable).&lt;br /&gt;
mutex_wake: Dequeues highest-priority waiter, transfers ownership, updates metering.&lt;br /&gt;
&lt;br /&gt;
Priority Inheritance&lt;br /&gt;
&lt;br /&gt;
resource_raise_owner_pri: Boosts owner priority to waiter’s.&lt;br /&gt;
resource_test_owner_pri: Detects inversion, raises or spins/yields.&lt;br /&gt;
drop_inheritance: Restores base priority on unlock.&lt;br /&gt;
Supports chained inheritance via k_inherit pointer.&lt;br /&gt;
&lt;br /&gt;
Waiter Queue Management&lt;br /&gt;
&lt;br /&gt;
Circular doubly-linked list in m_queue.&lt;br /&gt;
Queued in approximate priority order (mutex_queue).&lt;br /&gt;
Single waiter woken on unlock (mutex_wake).&lt;br /&gt;
&lt;br /&gt;
Synchronization Variables (sv_t)&lt;br /&gt;
General-purpose wait queue supporting:&lt;br /&gt;
&lt;br /&gt;
FIFO, LIFO, priority, keyed ordering.&lt;br /&gt;
Signal (wake one), broadcast (wake all), bounded broadcast.&lt;br /&gt;
Timed waits, signal-breakable waits.&lt;br /&gt;
Integration with mutex/spin/bit/mrlock/sema release.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures&lt;br /&gt;
&lt;br /&gt;
mutex_t:&lt;br /&gt;
__psunsigned_t m_bits — owner thread pointer + flags (low bit lock, next bit queue).&lt;br /&gt;
kthread_t *m_queue — circular waiter list head.&lt;br /&gt;
Optional m_info pointer for metering/wchan info.&lt;br /&gt;
&lt;br /&gt;
sv_t:&lt;br /&gt;
__psunsigned_t sv_queue — waiter pointer + lock bit + type (FIFO/LIFO/PRIO/KEYED).&lt;br /&gt;
Optional sv_info for metering.&lt;br /&gt;
&lt;br /&gt;
Flags/macros:&lt;br /&gt;
MUTEX_LOCKBIT, MUTEX_QUEUEBIT&lt;br /&gt;
SV_LOCK, SV_TYPE masks&lt;br /&gt;
KT_WMUTEX, KT_WSV thread sleep flags&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Priority Inheritance Details&lt;br /&gt;
&lt;br /&gt;
Aggressive: propagates through chains, handles indirect waits.&lt;br /&gt;
Temporary priority boost with KT_PS flag.&lt;br /&gt;
Supports real-time and timeshare scheduling.&lt;br /&gt;
&lt;br /&gt;
Metering and Debug (SEMAMETER/SEMAINFO)&lt;br /&gt;
&lt;br /&gt;
Optional per-object statistics (lock attempts, hold/wait times, contention).&lt;br /&gt;
Hash bucket lists for idbg scanning.&lt;br /&gt;
&lt;br /&gt;
sv_t Flexibility&lt;br /&gt;
&lt;br /&gt;
Unified queue for multiple lock types via wrapper functions.&lt;br /&gt;
Supports bounded broadcast (wakes only original waiter set).&lt;br /&gt;
Threshold wake (sv_threshold).&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos Implementation ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
&lt;br /&gt;
Strong similarity due to shared SVR4 heritage:&lt;br /&gt;
&lt;br /&gt;
Adaptive mutexes with priority inheritance (similar owner word, waiter lists).&lt;br /&gt;
&lt;br /&gt;
mutex_enter, mutex_tryenter, mutex_exit.&lt;br /&gt;
&lt;br /&gt;
Turnstiles for sleeping/waiting (similar to sv_t but more integrated).&lt;br /&gt;
&lt;br /&gt;
CVs and semaphores separate but similar.&lt;br /&gt;
&lt;br /&gt;
Metering via kstat or dtrace.&lt;br /&gt;
&lt;br /&gt;
Porting: illumos adaptive mutex closest match. Differences in turnstile priority blocking vs IRIX explicit inheritance chains.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_vfile&amp;diff=466</id>
		<title>Kernel: vfile</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_vfile&amp;diff=466"/>
		<updated>2026-01-09T23:54:02Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The vfile (virtual file) object in the IRIX kernel represents an open file description — the kernel-side structure that corresponds to an open file shared across processes (via fork, dup, etc.). It holds per-open state such as reference count, open flags, credentials, associated vnode or vsocket, and a behavior chain head for stacked behaviors (notably the pfile behavior for offset management).&lt;br /&gt;
The vfile layer sits between the per-process file descriptor table (fdt) and lower-level objects (vnode for files, vsocket for sockets). It manages reference counting, close semantics (including double-close protocol for races), credential handling, and integration with distributed (Cellular IRIX) features. The implementation emphasizes thread/sproc safety via spinlocks and careful race avoidance during close.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Initialization (vfile_init)&lt;br /&gt;
Initializes the file_zone for efficient allocation of vfile_t structures, sets up debugging lists/locks, calls vfile_cell_init() (distributed support) and pfile_init().&lt;br /&gt;
Creation (vfile_create)&lt;br /&gt;
Allocates a vfile_t from the zone, initializes:&lt;br /&gt;
&lt;br /&gt;
Spinlock (vf_lock)&lt;br /&gt;
Reference count = 1&lt;br /&gt;
Flags and credential hold&lt;br /&gt;
Behavior chain head (vf_bh)&lt;br /&gt;
Links into debug active list&lt;br /&gt;
Increments global SYSINFO.filecnt&lt;br /&gt;
&lt;br /&gt;
Allocation for Open (vfile_alloc)&lt;br /&gt;
Creates a vfile (with FINPROGRESS flag), allocates an fd via fdt_alloc, creates associated pfile behavior. Returns file pointer and fd; caller must call vfile_ready after successful VOP_OPEN.&lt;br /&gt;
Activation (vfile_ready)&lt;br /&gt;
Clears FINPROGRESS, sets associated vnode/vsocket pointer.&lt;br /&gt;
Undo on Failed Open (vfile_alloc_undo)&lt;br /&gt;
Reverses vfile_alloc when VOP_OPEN fails: removes fd, drops refcount, tears down pfile, destroys vfile.&lt;br /&gt;
Close Protocol (vfile_close, vfile_close_common, vfile_ref_release)&lt;br /&gt;
Implements a two-phase close to handle races between multiple threads/sprocs closing the same fd:&lt;br /&gt;
&lt;br /&gt;
vfile_close: Calls VFILE_CLOSE with VFILE_FIRSTCLOSE to probe if last reference.&lt;br /&gt;
vfile_close_common: Performs actual cleanup:&lt;br /&gt;
Cleans locks if present&lt;br /&gt;
Calls VOP_CLOSE (or VSOP_CLOSE) with appropriate lastclose flag&lt;br /&gt;
Handles double-call race by potentially issuing extra VOP_CLOSE&lt;br /&gt;
On true last close: flushes/invalidates if requested, releases vnode, removes GRIO reservations, tears down behaviors, destroys vfile&lt;br /&gt;
&lt;br /&gt;
vfile_ref_release: Used for non-close reference drops (e.g., rfork cleanup); only performs full close if last reference.&lt;br /&gt;
&lt;br /&gt;
Assignment Helper (vfile_assign)&lt;br /&gt;
Convenience wrapper: allocates vfile/fd, performs VOP_OPEN (updating vnode pointer if changed), readies vfile on success, undoes on failure.&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures (from ksys/vfile.h)&lt;br /&gt;
&lt;br /&gt;
vfile_t:&lt;br /&gt;
int vf_count — reference count (shared opens)&lt;br /&gt;
int vf_flag — open flags (FREAD, FWRITE, etc.) + internal (FINPROGRESS, FLCINVAL, FLCFLUSH, FPRIORITY)&lt;br /&gt;
cred_t *vf_cred — held credentials of opener&lt;br /&gt;
spinlock_t vf_lock — protects structure&lt;br /&gt;
bhv_head_t vf_bh — head of behavior chain (pfile inserted here)&lt;br /&gt;
void *vf_data — pointer to vnode_t or vsock_t (via VF_TO_VNODE/VF_TO_VSOCK)&lt;br /&gt;
Debug links (vf_next, vf_prev) for active list&lt;br /&gt;
&lt;br /&gt;
Macros:&lt;br /&gt;
VFLOCK / VFUNLOCK — spinlock wrappers&lt;br /&gt;
VFILE_CLOSE(fp, phase, info) — behavior chain dispatch for close&lt;br /&gt;
VFILE_TEARDOWN(fp) — behavior chain teardown dispatch&lt;br /&gt;
VF_IS_VNODE, VF_SET_DATA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Double-Close Protocol&lt;br /&gt;
IRIX uses a two-call close pattern (VFILE_FIRSTCLOSE, VFILE_SECONDCLOSE) via behavior chain to safely determine last close in multiprocessor/shared-process environments. Prevents race where one thread tears down structure while another assumes it still exists.&lt;br /&gt;
Flags and Special Handling&lt;br /&gt;
&lt;br /&gt;
FINPROGRESS: Set during open until vfile_ready&lt;br /&gt;
FLCINVAL / FLCFLUSH: Trigger VOP_FSYNC with invalidate or flush on last close&lt;br /&gt;
FPRIORITY: Indicates GRIO (Guaranteed Rate I/O) reservation&lt;br /&gt;
VFRLOCKS: Vnode has record locks → clean on close&lt;br /&gt;
&lt;br /&gt;
Distributed Support&lt;br /&gt;
References to DC/DS (Distributed Coordinator/Server) and VFILE_SKIPCLOSE indicate special handling in Cellular IRIX: last close may be deferred or coordinated remotely.&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Moderate similarity:&lt;br /&gt;
&lt;br /&gt;
Per-open state in struct file (referenced by filedesc table)&lt;br /&gt;
Reference counting and close races handled via closef()&lt;br /&gt;
Vnode ops with VOP_CLOSE(last)&lt;br /&gt;
Credential holding&lt;br /&gt;
No behavior chaining; vnode ops direct&lt;br /&gt;
No explicit pfile separation — offset in uio or per-read/write&lt;br /&gt;
&lt;br /&gt;
Porting: illumos file closer to vfile than BSD, but lacks behavior chain and double-close protocol.&lt;br /&gt;
BSD (FreeBSD, NetBSD, OpenBSD)&lt;br /&gt;
Closer in some aspects:&lt;br /&gt;
&lt;br /&gt;
struct file with reference count, flags, credential, pointer to fileops and data (vnode/socket)&lt;br /&gt;
Double-close avoidance via careful refcounting&lt;br /&gt;
closef() performs fdrop() → ops → free&lt;br /&gt;
No behavior chaining; direct fops dispatch&lt;br /&gt;
Offset not stored in file — managed per-I/O via uio&lt;br /&gt;
&lt;br /&gt;
Porting: BSD struct file semantically similar to vfile. Main differences: no bhv chain, no explicit pfile layer, different lock strategy.&lt;br /&gt;
Overall, IRIX vfile is unique due to bhv_desc_t behavior chaining and [[Kernel: pfile]] offset separation, designed for extensibility and Cellular IRIX distributed coherence. No direct equivalent in illumos/BSD for easy porting; closest analogs are struct file in both, but require adding behavior dispatch and double-close logic for fidelity.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Introduction&amp;diff=465</id>
		<title>Kernel: Introduction</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Introduction&amp;diff=465"/>
		<updated>2026-01-09T23:51:36Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;Kernel:&#039;&#039; namespace serves as a comprehensive, community-driven repository for detailed technical documentation of the IRIX kernel, derived from reverse engineering efforts on [[IRIX 6.5]] binaries. This initiative focuses on analyzing, decompiling, and annotating kernel object files to produce high-level, functional descriptions of subsystems, data structures, and behaviors. The documentation is intended to preserve and disseminate deep technical knowledge about IRIX&#039;s unique kernel architecture, which remains largely undocumented outside of original Silicon Graphics sources.&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
The primary goal is to create accurate, readable documentation of IRIX kernel components based on decompiled and extensively commented binary code. This effort emerged in response to the challenges encountered during the IRIX-32 project, where direct access to original source code proved impractical. By leveraging modern reverse engineering tools and AI-assisted analysis, the project aims to produce standalone technical articles that describe kernel functionality without relying on or distributing proprietary source code.&lt;br /&gt;
&lt;br /&gt;
A key operational objective is to maintain clear separation between active IRIX development communities and the volunteer reverse engineering team. This isolation ensures compliance with legal and ethical boundaries while allowing independent progress on documentation.&lt;br /&gt;
&lt;br /&gt;
Ultimately, these articles provide a reliable reference for understanding IRIX kernel internals, supporting historical preservation, academic study, and potential future reimplementations.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
IRIX represents a sophisticated UNIX variant optimized for high-performance graphics, scientific computing, and real-time applications on MIPS architecture. Many of its kernel innovations—particularly in virtual memory management, NUMA support, ELF loading, and hardware-specific optimizations—remain poorly documented in public sources. This namespace seeks to fill that gap by systematically documenting subsystems as they existed in IRIX 6.5, the final major release.&lt;br /&gt;
&lt;br /&gt;
The documentation serves as groundwork for skilled developers interested in faithfully reimplementing portions of the IRIX kernel. By providing detailed functional overviews, data structure descriptions, and behavioral analyses derived from binary analysis, it enables clean-room reimplementation efforts without exposure to original source code.&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
&lt;br /&gt;
Documentation is produced through careful reverse engineering of IRIX 6.5 kernel binaries. Primary tools include:&lt;br /&gt;
&lt;br /&gt;
* Ghidra for disassembly, decompilation, and structural analysis&lt;br /&gt;
* mips2c and related projects for improving decompiler output readability&lt;br /&gt;
* decomp.me for collaborative decompilation matching&lt;br /&gt;
&lt;br /&gt;
All articles are written from decompiled output that has been extensively commented and analyzed by engineers. A strict policy is maintained: no original source code is reproduced or distributed within these pages. Descriptions focus on functional behavior, data flows, and algorithmic logic. Where necessary, function prototypes (names, return types, and parameters) may be included for clarity, but only as derived from binary analysis.&lt;br /&gt;
&lt;br /&gt;
Articles emphasize high-level overviews, key data structures, and IRIX-specific behaviors while highlighting deviations from standard UNIX or SVR4 conventions.&lt;br /&gt;
&lt;br /&gt;
=== Personnel ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Młynar&#039;&#039;&#039; – Documenting Engineer from Politechnika Wrocławska: primary decompiler and commenter responsible for detailed analysis and annotation of kernel objects&lt;br /&gt;
* &#039;&#039;&#039;Yura&#039;&#039;&#039; – Engineer from Shenzhen: supporting documentation and verification. MIPS ASM analysis.&lt;br /&gt;
* &#039;&#039;&#039;Raion&#039;&#039;&#039; – Primary documenter and formatter: article structuring, MediaWiki formatting, and coordination&lt;br /&gt;
&lt;br /&gt;
This volunteer effort combines expertise in MIPS architecture, kernel internals, and reverse engineering to produce accurate technical documentation for the broader IRIX preservation community.&lt;br /&gt;
&lt;br /&gt;
[[Category: Kernel Documentation]]&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Introduction&amp;diff=464</id>
		<title>Kernel: Introduction</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Introduction&amp;diff=464"/>
		<updated>2026-01-09T23:46:22Z</updated>

		<summary type="html">&lt;p&gt;Raion: Raion moved page Kernel:Introduction to Kernel: Introduction without leaving a redirect: Misspelled title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Kernel:&#039;&#039; namespace serves as a comprehensive, community-driven repository for detailed technical documentation of the IRIX kernel, derived from reverse engineering efforts on [[IRIX 6.5]] binaries. This initiative focuses on analyzing, decompiling, and annotating kernel object files to produce high-level, functional descriptions of subsystems, data structures, and behaviors. The documentation is intended to preserve and disseminate deep technical knowledge about IRIX&#039;s unique kernel architecture, which remains largely undocumented outside of original Silicon Graphics sources.&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
The primary goal is to create accurate, readable documentation of IRIX kernel components based on decompiled and extensively commented binary code. This effort emerged in response to the challenges encountered during the IRIX-32 project, where direct access to original source code proved impractical. By leveraging modern reverse engineering tools and AI-assisted analysis, the project aims to produce standalone technical articles that describe kernel functionality without relying on or distributing proprietary source code.&lt;br /&gt;
&lt;br /&gt;
A key operational objective is to maintain clear separation between active IRIX development communities and the volunteer reverse engineering team. This isolation ensures compliance with legal and ethical boundaries while allowing independent progress on documentation.&lt;br /&gt;
&lt;br /&gt;
Ultimately, these articles provide a reliable reference for understanding IRIX kernel internals, supporting historical preservation, academic study, and potential future reimplementations.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
IRIX represents a sophisticated UNIX variant optimized for high-performance graphics, scientific computing, and real-time applications on MIPS architecture. Many of its kernel innovations—particularly in virtual memory management, NUMA support, ELF loading, and hardware-specific optimizations—remain poorly documented in public sources. This namespace seeks to fill that gap by systematically documenting subsystems as they existed in IRIX 6.5, the final major release.&lt;br /&gt;
&lt;br /&gt;
The documentation serves as groundwork for skilled developers interested in faithfully reimplementing portions of the IRIX kernel. By providing detailed functional overviews, data structure descriptions, and behavioral analyses derived from binary analysis, it enables clean-room reimplementation efforts without exposure to original source code.&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
&lt;br /&gt;
Documentation is produced through careful reverse engineering of IRIX 6.5 kernel binaries. Primary tools include:&lt;br /&gt;
&lt;br /&gt;
* Ghidra for disassembly, decompilation, and structural analysis&lt;br /&gt;
* mips2c and related projects for improving decompiler output readability&lt;br /&gt;
* decomp.me for collaborative decompilation matching&lt;br /&gt;
&lt;br /&gt;
All articles are written from decompiled output that has been extensively commented and analyzed by engineers. A strict policy is maintained: no original source code is reproduced or distributed within these pages. Descriptions focus on functional behavior, data flows, and algorithmic logic. Where necessary, function prototypes (names, return types, and parameters) may be included for clarity, but only as derived from binary analysis.&lt;br /&gt;
&lt;br /&gt;
Articles emphasize high-level overviews, key data structures, and IRIX-specific behaviors while highlighting deviations from standard UNIX or SVR4 conventions.&lt;br /&gt;
&lt;br /&gt;
=== Personnel ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Młynar&#039;&#039;&#039; – Documenting Engineer from Politechnika Wrocławska: primary decompiler and commenter responsible for detailed analysis and annotation of kernel objects&lt;br /&gt;
* &#039;&#039;&#039;Yura&#039;&#039;&#039; – Engineer from Shenzhen: supporting documentation and verification. MIPS ASM analysis.&lt;br /&gt;
* &#039;&#039;&#039;Raion&#039;&#039;&#039; – Primary documenter and formatter: article structuring, MediaWiki formatting, and coordination&lt;br /&gt;
&lt;br /&gt;
This volunteer effort combines expertise in MIPS architecture, kernel internals, and reverse engineering to produce accurate technical documentation for the broader IRIX preservation community.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_STREAMS&amp;diff=463</id>
		<title>Kernel: STREAMS</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_STREAMS&amp;diff=463"/>
		<updated>2026-01-09T05:16:17Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;The IRIX STREAMS framework provides a modular, message-passing I/O subsystem for character devices, terminals, network protocols, and pseudo-devices. It uses queues (read/write pairs per module/driver), message blocks (mblk_t/dblk_t), and buffers for data transfer. The implementation is highly optimized for performance with:  Per-CPU free lists (NUMA-aware) for message blocks, data blocks, and buffers of various sizes. Cache coloring and alignment support. Zone-based...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The IRIX [[STREAMS]] framework provides a modular, message-passing I/O subsystem for character devices, terminals, network protocols, and pseudo-devices. It uses queues (read/write pairs per module/driver), message blocks (mblk_t/dblk_t), and buffers for data transfer. The implementation is highly optimized for performance with:&lt;br /&gt;
&lt;br /&gt;
Per-CPU free lists (NUMA-aware) for message blocks, data blocks, and buffers of various sizes.&lt;br /&gt;
Cache coloring and alignment support.&lt;br /&gt;
Zone-based allocation for small structures.&lt;br /&gt;
Page-based buffering with coalescing and reclaim.&lt;br /&gt;
Global limits and dynamic reclamation via strgiveback.&lt;br /&gt;
MP-safe design using spinlocks per CPU.&lt;br /&gt;
&lt;br /&gt;
The core data structures are managed through list vectors (lf_listvec) per CPU, with separate pools for different buffer sizes (64B to full page).&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Initialization&lt;br /&gt;
&lt;br /&gt;
str_init_master: Initializes global structures for master CPU.&lt;br /&gt;
str_init_slave: Sets up per-CPU structures for slave CPUs.&lt;br /&gt;
str_init_memsize: Configures page limits based on physical memory.&lt;br /&gt;
str_init_alloc_bufs: Preallocates initial buffers per CPU.&lt;br /&gt;
strinit_giveback: Starts periodic page reclamation timer.&lt;br /&gt;
&lt;br /&gt;
Message Block Allocation&lt;br /&gt;
&lt;br /&gt;
allocb: Allocates mblk_t + dblk_t + buffer (various sizes).&lt;br /&gt;
allocb_nobuffer: Allocates only mblk_t/dblk_t (no data buffer).&lt;br /&gt;
esballoc: Attaches external buffer (zero-copy).&lt;br /&gt;
bufcall / esbbcall: Schedule callback when memory available.&lt;br /&gt;
&lt;br /&gt;
Queue Operations&lt;br /&gt;
&lt;br /&gt;
putq / putbq / insq: Insert message into queue (priority-ordered).&lt;br /&gt;
getq: Remove next message from queue.&lt;br /&gt;
rmvq: Remove specific message.&lt;br /&gt;
flushq / flushband: Discard messages (all or by band).&lt;br /&gt;
qenable: Schedule queue service routine.&lt;br /&gt;
canput / bcanput: Flow control checks.&lt;br /&gt;
&lt;br /&gt;
Buffer Management&lt;br /&gt;
&lt;br /&gt;
lf_get / lf_free: Node allocation/deallocation from per-CPU lists.&lt;br /&gt;
lf_addpage / lf_getpage_tiled: Page tiling and addition to free lists.&lt;br /&gt;
lf_freepage: Return full page to kernel VM.&lt;br /&gt;
str_preallocate: Initial buffer preallocation.&lt;br /&gt;
&lt;br /&gt;
Special Cases&lt;br /&gt;
&lt;br /&gt;
msgpullup: Coalesce message into single contiguous buffer.&lt;br /&gt;
copyb / copymsg / dupb / dupmsg: Copy or reference-count messages.&lt;br /&gt;
linkb / unlinkb: Chain management.&lt;br /&gt;
adjmsg: Trim bytes from head/tail.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Structures&lt;br /&gt;
&lt;br /&gt;
mblk_t: Message descriptor (pointers, type, flags, band).&lt;br /&gt;
dblk_t: Data block (buffer pointers, refcount, type, size, free routine).&lt;br /&gt;
queue_t: Read/write queue pair with flow control parameters.&lt;br /&gt;
qband_t: Per-priority-band flow control (for non-zero bands).&lt;br /&gt;
lf_listvec / listvec: Per-CPU free list vectors with multiple size classes.&lt;br /&gt;
strstat: Per-CPU statistics.&lt;br /&gt;
&lt;br /&gt;
Buffer Pools&lt;br /&gt;
&lt;br /&gt;
Fixed sizes: 64, 256, 512, 2048 bytes + full page.&lt;br /&gt;
Combined mblk_t/dblk_t pool.&lt;br /&gt;
Separate message header pool.&lt;br /&gt;
Page reclamation: strgiveback returns excess pages to kernel.&lt;br /&gt;
&lt;br /&gt;
NUMA Awareness&lt;br /&gt;
&lt;br /&gt;
Per-node, per-CPU list vectors.&lt;br /&gt;
Allocation prefers local node.&lt;br /&gt;
&lt;br /&gt;
Flow Control&lt;br /&gt;
&lt;br /&gt;
High/low water marks per queue and band.&lt;br /&gt;
QFULL / QB_FULL flags.&lt;br /&gt;
Back-enable nearest upstream service routine.&lt;br /&gt;
&lt;br /&gt;
Extended Free Routine&lt;br /&gt;
&lt;br /&gt;
esballoc supports external buffers with custom free function.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong similarity:&lt;br /&gt;
&lt;br /&gt;
Message block (mblk_t/dblk_t) and queue model nearly identical.&lt;br /&gt;
allocb, esballoc, putq, getq, canput, qenable.&lt;br /&gt;
Per-CPU caches and buffer pools.&lt;br /&gt;
Flow control with high/low water.&lt;br /&gt;
&lt;br /&gt;
Differences: illumos uses kmem_cache extensively; more modular.&lt;br /&gt;
BSD (FreeBSD, etc.)&lt;br /&gt;
Less similar:&lt;br /&gt;
&lt;br /&gt;
No native STREAMS (removed long ago).&lt;br /&gt;
Character I/O via cdevsw or tty.&lt;br /&gt;
Some ports emulate via compatibility layers.&lt;br /&gt;
&lt;br /&gt;
Overall, IRIX STREAMS is classic SVR4 with NUMA/per-CPU optimizations. illumos provides closest modern equivalent; BSD lacks native support. For replication: preserve per-CPU lists, buffer size classes, and queue scheduling semantics. Page reclamation and tiling logic are IRIX-specific.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Signal_Infrastructure&amp;diff=462</id>
		<title>Kernel: Signal Infrastructure</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Signal_Infrastructure&amp;diff=462"/>
		<updated>2026-01-04T03:52:14Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;== Overview == The IRIX kernel signal infrastructure provides a comprehensive, POSIX-compliant signal delivery system with extensions for real-time, debugging, and multi-threaded processes. Signals are managed at both process (sigvec_t in proc_t) and thread (ut_sig, ut_sighold in uthread_t) levels, allowing per-thread signal masks and delivery while maintaining process-wide consistency. Key features:  Queued signals (sigqueue_t) for POSIX sigqueue and siginfo delivery. P...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX kernel signal infrastructure provides a comprehensive, POSIX-compliant signal delivery system with extensions for real-time, debugging, and multi-threaded processes. Signals are managed at both process (sigvec_t in proc_t) and thread (ut_sig, ut_sighold in uthread_t) levels, allowing per-thread signal masks and delivery while maintaining process-wide consistency.&lt;br /&gt;
Key features:&lt;br /&gt;
&lt;br /&gt;
Queued signals (sigqueue_t) for POSIX sigqueue and siginfo delivery.&lt;br /&gt;
Priority-based delivery with job control stops handled specially.&lt;br /&gt;
Alternate signal stacks (sigaltstack, legacy sigstack).&lt;br /&gt;
Signal contexts (ucontext_t, sigcontext) for setcontext/getcontext and signal handlers.&lt;br /&gt;
Debugging integration (/proc, ptrace).&lt;br /&gt;
Multi-threaded awareness — signals can target specific uthreads or the process.&lt;br /&gt;
Async signal delivery via async_vec_t for non-sleepable contexts.&lt;br /&gt;
&lt;br /&gt;
The system carefully handles races between signal posting, masking, and delivery using spinlocks and atomic operations.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Signal Posting&lt;br /&gt;
&lt;br /&gt;
sigtopid: Send signal to process by PID (handles async via async_call if SIG_NOSLEEP).&lt;br /&gt;
sigtouthread / sigtouthread_common: Deliver to specific uthread.&lt;br /&gt;
sigaddq / sigdeq / sigdelq: Manage queued siginfo structures.&lt;br /&gt;
sigqueue_alloc / sigqueue_free: Zone-based allocation.&lt;br /&gt;
&lt;br /&gt;
Signal Delivery&lt;br /&gt;
&lt;br /&gt;
issig: Check for pending unmasked signals (returns signal number).&lt;br /&gt;
fsig: Find first unheld signal.&lt;br /&gt;
psig: Process current signal — installs handler or takes default action.&lt;br /&gt;
sendsig: Set up user context and registers for handler entry.&lt;br /&gt;
stop / unstop: Job control and debugger stops.&lt;br /&gt;
&lt;br /&gt;
Context Management&lt;br /&gt;
&lt;br /&gt;
save/restore context functions for ucontext_t and legacy sigcontext.&lt;br /&gt;
irix5_*_savecontext / restorecontext: ABI-specific versions.&lt;br /&gt;
&lt;br /&gt;
Signal Waiting&lt;br /&gt;
&lt;br /&gt;
sigpending: Return pending signal set.&lt;br /&gt;
sigsuspend: Swap mask and sleep.&lt;br /&gt;
sigprocmask: Modify signal mask.&lt;br /&gt;
sigpoll / sigtimedwait: Wait for specific signals (POSIX sigwait family).&lt;br /&gt;
&lt;br /&gt;
Special Interfaces&lt;br /&gt;
&lt;br /&gt;
ptrace: Classic debugging interface.&lt;br /&gt;
sigaltstack / sigstack: Alternate signal stack control.&lt;br /&gt;
core: Generate core dump on fatal signals.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Structures&lt;br /&gt;
&lt;br /&gt;
sigvec_t (process-wide):&lt;br /&gt;
sv_sig, sv_sigign, sv_sigcatch: Pending, ignored, caught signals.&lt;br /&gt;
sv_hndlr[NSIG_HNDLRS]: Handler array.&lt;br /&gt;
sv_sigmasks, sv_signodefer, sv_sigrestart, sv_sigresethand: Per-signal flags.&lt;br /&gt;
sv_sigqueue: Head of queued siginfo list.&lt;br /&gt;
sv_pending: Count of queued signals.&lt;br /&gt;
&lt;br /&gt;
uthread_t signal fields:&lt;br /&gt;
ut_sig: Thread-private pending signals.&lt;br /&gt;
ut_sighold: Thread-private blocked mask.&lt;br /&gt;
ut_sigwait: Signals being waited on.&lt;br /&gt;
ut_cursig, ut_curinfo: Current signal and siginfo.&lt;br /&gt;
ut_suspmask: Saved mask during sigsuspend.&lt;br /&gt;
&lt;br /&gt;
sigqueue_t: Queued siginfo with chaining.&lt;br /&gt;
&lt;br /&gt;
Dual Delivery Model&lt;br /&gt;
&lt;br /&gt;
Signals can be process-directed (posted to sigvec_t) or thread-directed (sigtouthread).&lt;br /&gt;
VPROC_SENDSIG virtualizes delivery across threads.&lt;br /&gt;
Async delivery queue for non-sleepable contexts.&lt;br /&gt;
&lt;br /&gt;
Job Control Special Cases&lt;br /&gt;
&lt;br /&gt;
SIGCONT cancels pending stop signals.&lt;br /&gt;
Stop signals ignored if no handler and process orphaned (except SIGSTOP).&lt;br /&gt;
&lt;br /&gt;
Queued Signals&lt;br /&gt;
&lt;br /&gt;
sigqueue() delivers siginfo_t with value.&lt;br /&gt;
Multiple same-signal infos preserved only if SI_QUEUE, SI_ASYNCIO, etc.&lt;br /&gt;
&lt;br /&gt;
Alternate Stack&lt;br /&gt;
&lt;br /&gt;
prxy_sigsp, prxy_spsize, prxy_siglb: Track alternate stack base/size/low bound.&lt;br /&gt;
SS_ONSTACK flag managed carefully.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong similarity:&lt;br /&gt;
&lt;br /&gt;
sigqueue(), queued signals, siginfo_t.&lt;br /&gt;
sigprocmask, sigsuspend, sigaction semantics.&lt;br /&gt;
Alternate stack via sigaltstack.&lt;br /&gt;
Process + thread signal masks.&lt;br /&gt;
&lt;br /&gt;
Differences: illumos uses turnstiles; IRIX uses explicit queues and sv_t.&lt;br /&gt;
BSD (FreeBSD, etc.)&lt;br /&gt;
Moderate similarity:&lt;br /&gt;
&lt;br /&gt;
sigaction, sigprocmask, kill, sigaltstack.&lt;br /&gt;
Signal contexts for longjmp-style handlers.&lt;br /&gt;
&lt;br /&gt;
Differences: BSD simpler — no queued signals, weaker real-time, different threading model.&lt;br /&gt;
Overall, IRIX signal system is SVR4/POSIX compliant with strong multi-threading and queued signal support. illumos closest modern analog; BSD covers basics but lacks queued delivery and per-thread complexity. For replication: preserve dual process/thread model, queued siginfo handling, and careful ut_lock/sigvec coordination.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Process/Time_Management_Syscalls&amp;diff=461</id>
		<title>Kernel: Process/Time Management Syscalls</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Process/Time_Management_Syscalls&amp;diff=461"/>
		<updated>2026-01-04T03:48:49Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;== Overview == IRIX has many syscalls grouped by core process identity, time management, scheduling control, profiling, and signal-related system calls in the IRIX kernel. These calls operate on vproc_t (virtual process) structures, which encapsulate state shared across threads (uthreads) in multi-threaded processes. Key areas:  Time retrieval/setting UID/GID manipulation (System V and BSD semantics) Process group/session control Nice value and real-time priority adjustm...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
IRIX has many syscalls grouped by core process identity, time management, scheduling control, profiling, and signal-related system calls in the IRIX kernel. These calls operate on vproc_t (virtual process) structures, which encapsulate state shared across threads (uthreads) in multi-threaded processes.&lt;br /&gt;
Key areas:&lt;br /&gt;
&lt;br /&gt;
Time retrieval/setting&lt;br /&gt;
UID/GID manipulation (System V and BSD semantics)&lt;br /&gt;
Process group/session control&lt;br /&gt;
Nice value and real-time priority adjustments&lt;br /&gt;
Profiling (clock-based, shared-library, R10000 event counters)&lt;br /&gt;
Signal blocking/masking, pending checks, suspend, handler installation, alternate stacks&lt;br /&gt;
Miscellaneous (pause, umask, ulimit, vhangup, sysconf)&lt;br /&gt;
&lt;br /&gt;
The implementation blends System V, BSD, and POSIX behaviors, with extensions for IRIX-specific features (e.g., Frame Scheduler via schedctl).&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Time Management&lt;br /&gt;
&lt;br /&gt;
gtime: Returns current time-of-day in seconds.&lt;br /&gt;
stime: Sets system clock.&lt;br /&gt;
alarm: Sets interval timer on real-time clock.&lt;br /&gt;
times: Returns process and child CPU times.&lt;br /&gt;
&lt;br /&gt;
Identity Management&lt;br /&gt;
&lt;br /&gt;
setuid / setreuid: Set real/effective UID.&lt;br /&gt;
setgid / setregid: Set real/effective GID (with XPG4 variant for saved-GID semantics).&lt;br /&gt;
getuid / getgid: Return real and effective IDs.&lt;br /&gt;
setgroups / getgroups: Manage supplementary group list.&lt;br /&gt;
umask: Set/get file creation mask (per-uthread, shared).&lt;br /&gt;
&lt;br /&gt;
Process Group and Session&lt;br /&gt;
&lt;br /&gt;
setpgrp: System V style (flag=0 returns pgid).&lt;br /&gt;
BSDsetpgrp / BSDgetpgrp: BSD compatibility.&lt;br /&gt;
setpgid: POSIX version.&lt;br /&gt;
setsid: Create new session.&lt;br /&gt;
&lt;br /&gt;
Scheduling and Priority&lt;br /&gt;
&lt;br /&gt;
nice: Adjust nice value.&lt;br /&gt;
schedctl: Unified interface for:&lt;br /&gt;
Real-time fixed priority&lt;br /&gt;
Time slice setting&lt;br /&gt;
Nice adjustments (process, pgrp, user-wide via plistscan)&lt;br /&gt;
CPU affinity&lt;br /&gt;
Scheduling mode (free/gang)&lt;br /&gt;
Frame Scheduler (FRS) operations&lt;br /&gt;
Legacy hooks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Profiling&lt;br /&gt;
&lt;br /&gt;
profil: Traditional clock-based profiling.&lt;br /&gt;
sprofil: Shared-library profiling.&lt;br /&gt;
evc_profil: R10000 hardware event counter profiling (per-thread counters).&lt;br /&gt;
&lt;br /&gt;
Signal Handling&lt;br /&gt;
&lt;br /&gt;
sigpending: Return pending signal set.&lt;br /&gt;
sigsuspend: Atomically swap signal mask and sleep.&lt;br /&gt;
sigprocmask: Block/unblock signals.&lt;br /&gt;
sigaction: Install signal handler with mask/flags.&lt;br /&gt;
sigstack / sigaltstack: Set/query alternate signal stack (with XPG4 corrected behavior).&lt;br /&gt;
&lt;br /&gt;
Miscellaneous&lt;br /&gt;
&lt;br /&gt;
pause: Sleep until signal.&lt;br /&gt;
ulimit: Query/set resource limits (file size, data segment, descriptors).&lt;br /&gt;
vhangup: Invalidate controlling terminal.&lt;br /&gt;
sysconf: Runtime configuration values (e.g., _SC_ARG_MAX, _SC_NGROUPS_MAX).&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
vproc_t-Centric Design&lt;br /&gt;
All process-wide operations dispatch through VPROC_ macros on curvprocp, supporting shared state across uthreads.&lt;br /&gt;
Dual Semantics&lt;br /&gt;
&lt;br /&gt;
System V (setpgrp) and BSD/POSIX (setpgid, setsid) co-exist.&lt;br /&gt;
XPG4 variants for sigaltstack (correct stack direction) and setregid (saved-GID handling).&lt;br /&gt;
&lt;br /&gt;
schedctl Extensions&lt;br /&gt;
&lt;br /&gt;
Real-time fixed priorities (non-degrading).&lt;br /&gt;
Gang scheduling modes.&lt;br /&gt;
Full Frame Scheduler (FRS) user interface for hard real-time gangs.&lt;br /&gt;
User-wide nice operations via process table scan.&lt;br /&gt;
&lt;br /&gt;
Profiling Variants&lt;br /&gt;
&lt;br /&gt;
Clock-based, shared-library, and hardware counter (R10000) profiling.&lt;br /&gt;
Fast profiling mode.&lt;br /&gt;
&lt;br /&gt;
Signal Stack Handling&lt;br /&gt;
&lt;br /&gt;
Historical IRIX sigaltstack required user to account for stack growth direction; XPG4 variant fixes this.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong overlap:&lt;br /&gt;
&lt;br /&gt;
UID/GID, nice, alarm, times, pause, umask, ulimit nearly identical.&lt;br /&gt;
priocntl(2) analogous to schedctl for real-time classes.&lt;br /&gt;
Signal syscalls match POSIX.&lt;br /&gt;
Alternate stack via sigaltstack.&lt;br /&gt;
&lt;br /&gt;
Differences: No direct FRS; different real-time model.&lt;br /&gt;
BSD (FreeBSD, etc.)&lt;br /&gt;
Close matches:&lt;br /&gt;
&lt;br /&gt;
setreuid, setregid, setpgid, setsid, nice, getpriority/setpriority.&lt;br /&gt;
Signal interfaces standard.&lt;br /&gt;
sysconf for configuration.&lt;br /&gt;
&lt;br /&gt;
Differences: Separate syscalls instead of unified schedctl; weaker real-time support.&lt;br /&gt;
Overall, IRIX provides a rich unified scheduling interface (schedctl) with strong real-time extensions (FRS, fixed-priority) while maintaining compatibility with both SVR4 and BSD/POSIX. For reimplementation, focus on vproc dispatch and dual semantics; FRS is IRIX-specific.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Virtual_Paging&amp;diff=460</id>
		<title>Kernel: Virtual Paging</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Virtual_Paging&amp;diff=460"/>
		<updated>2026-01-04T03:42:30Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;== Overview == The IRIX kernel virtual memory subsystem manages physical page allocation, deallocation, and mapping for kernel use. It features a sophisticated free page list organized by cache color buckets with separate queues for clean/stale and associated/unassociated pages, support for large pages (contiguous allocation and coalescing), NUMA-aware node-specific freelists, cache coloring and VCE avoidance, and optimizations for direct-mapped (K0/K1) vs K2 addresses....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX kernel virtual memory subsystem manages physical page allocation, deallocation, and mapping for kernel use. It features a sophisticated free page list organized by cache color buckets with separate queues for clean/stale and associated/unassociated pages, support for large pages (contiguous allocation and coalescing), NUMA-aware node-specific freelists, cache coloring and VCE avoidance, and optimizations for direct-mapped (K0/K1) vs K2 addresses.&lt;br /&gt;
Key characteristics:&lt;br /&gt;
&lt;br /&gt;
pfdat_t structures track per-page metadata (flags, use count, hash chains, etc.).&lt;br /&gt;
phead_t bucket arrays per node and page size manage free lists.&lt;br /&gt;
Aggressive cache line reuse and coloring to minimize conflicts.&lt;br /&gt;
Reservation system via memory pools to prevent deadlock.&lt;br /&gt;
Special handling for R10000 speculation bug (lowmem separation).&lt;br /&gt;
Poisoned page support for ECC/uncorrectable errors.&lt;br /&gt;
Kernel stack pool for fast allocation.&lt;br /&gt;
&lt;br /&gt;
The implementation prioritizes low-latency kernel allocation with careful TLB and cache management.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Core Allocation&lt;br /&gt;
&lt;br /&gt;
kvpalloc / kvpalloc_node: Allocate virtual + physical pages (K2 + physical).&lt;br /&gt;
kvalloc: Allocate only K2 virtual space.&lt;br /&gt;
kpalloc / kpalloc_node: Map physical pages into existing K2 space.&lt;br /&gt;
pagealloc / pagealloc_node / pagealloc_size: Core physical page allocator (single or large pages).&lt;br /&gt;
contig_memalloc / kmem_contig_alloc: Physically contiguous allocation.&lt;br /&gt;
&lt;br /&gt;
Deallocation&lt;br /&gt;
&lt;br /&gt;
kvpfree / kvpffree: Free virtual + physical (handles K0/K1/K2).&lt;br /&gt;
kvfree: Free only K2 virtual space.&lt;br /&gt;
pagefree / pagefree_size: Return physical page to freelist (with coalescing).&lt;br /&gt;
kmem_contig_free: Free contiguous block.&lt;br /&gt;
&lt;br /&gt;
Large Page Support&lt;br /&gt;
&lt;br /&gt;
lpage_alloc_contig_physmem: Allocate large contiguous block.&lt;br /&gt;
lpage_free_contig_physmem: Free large block.&lt;br /&gt;
lpage_coalesce: Background merging of adjacent free base pages.&lt;br /&gt;
lpage_split: Break large page into smaller ones.&lt;br /&gt;
&lt;br /&gt;
Special Cases&lt;br /&gt;
&lt;br /&gt;
page_mapin / page_mapout: Temporary mapping for copy/zero.&lt;br /&gt;
page_copy / page_zero: COW and fault-time zeroing (with BTE on SN0).&lt;br /&gt;
page_discard / page_error_clean: Handle ECC/poisoned pages.&lt;br /&gt;
kstack_alloc / kstack_free: Kernel stack page pool.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures (from pfdat.h, page.h, etc.)&lt;br /&gt;
&lt;br /&gt;
pfd_t (page frame data):&lt;br /&gt;
pf_flags: P_QUEUE, P_HASH, P_ANON, P_DONE, P_WAIT, P_DIRTY, P_DUMP, P_BULKDATA, P_ERROR, P_HWBAD, etc.&lt;br /&gt;
pf_use: Reference count.&lt;br /&gt;
pf_next/prev: Free list links.&lt;br /&gt;
pf_hchain: Hash chain.&lt;br /&gt;
pf_tag: Vnode or anon handle.&lt;br /&gt;
pf_pageno: File offset.&lt;br /&gt;
&lt;br /&gt;
phead_t (per-color bucket):&lt;br /&gt;
ph_count: Number of pages.&lt;br /&gt;
ph_list[PH_NLISTS]: CLEAN/STALE, ASSOC/NOASSOC (and POISONOUS on NUMA).&lt;br /&gt;
&lt;br /&gt;
Node-specific:&lt;br /&gt;
pg_free_t per node: freelists, phead arrays, rotors, counters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Free List Organization&lt;br /&gt;
&lt;br /&gt;
Per-node, per-page-size phead arrays.&lt;br /&gt;
Cache color bucketed (pheadmask).&lt;br /&gt;
Separate lists: CLEAN/STALE × ASSOC/NOASSOC (plus POISONOUS).&lt;br /&gt;
Rotor for round-robin uncached allocation.&lt;br /&gt;
&lt;br /&gt;
NUMA and Migration&lt;br /&gt;
&lt;br /&gt;
Node-local freelists.&lt;br /&gt;
Round-robin or radial search fallback.&lt;br /&gt;
Poisoned page handling (directory clearing, discard queues).&lt;br /&gt;
&lt;br /&gt;
R10000 Speculation Workaround&lt;br /&gt;
&lt;br /&gt;
Low memory (&amp;lt;256MB) separated.&lt;br /&gt;
Special sxbrk variants (low/high memory).&lt;br /&gt;
Kernel reference tracking (krpf) for DMA safety.&lt;br /&gt;
&lt;br /&gt;
Cache and TLB Optimizations&lt;br /&gt;
&lt;br /&gt;
Direct K0/K1 preferred when possible.&lt;br /&gt;
VCE avoidance via color validation.&lt;br /&gt;
Stale → clean promotion with selective cache flush.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong similarity:&lt;br /&gt;
&lt;br /&gt;
Page freelist with hash buckets and color awareness.&lt;br /&gt;
kmem allocator for kernel objects (zones similar to IRIX zones).&lt;br /&gt;
Contiguous allocation via vmem.&lt;br /&gt;
Page daemon (vhand equivalent).&lt;br /&gt;
NUMA support evolved differently (resource pools).&lt;br /&gt;
&lt;br /&gt;
Porting: illumos kmem/page subsystem closest; lacks exact phead coloring and large-page coalescing.&lt;br /&gt;
BSD (FreeBSD)&lt;br /&gt;
More divergent:&lt;br /&gt;
&lt;br /&gt;
Simple page queues (free, cache, etc.).&lt;br /&gt;
UMA/kmem for slabs, vm_page for physical.&lt;br /&gt;
Contiguous via contigmalloc.&lt;br /&gt;
No per-color buckets or large-page splitting.&lt;br /&gt;
&lt;br /&gt;
Porting: BSD simpler; lacks IRIX&#039;s sophisticated coloring, NUMA freelists, and coalescing.&lt;br /&gt;
Overall, IRIX VM is classic SVR4 with heavy MIPS/NUMA/R10000 optimizations. illumos provides nearest modern analog; BSD too simplified for direct mapping. For replication: preserve pfdat flags, phead structure, node freelists, and coalescing logic.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Process_Scheduler&amp;diff=459</id>
		<title>Kernel: Process Scheduler</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Process_Scheduler&amp;diff=459"/>
		<updated>2026-01-04T03:39:46Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;== Overview == The IRIX process scheduler is accessed primarily through the schedctl(2) system call, which provides a rich set of scheduling controls reflecting IRIX&amp;#039;s historical focus on real-time, multiprocessor, and high-performance computing workloads. It supports:  Real-time fixed-priority scheduling (non-degrading) Traditional UNIX nice-value adjustments (timeshare) Process group and user-wide nice operations (BSD compatibility) CPU affinity control Scheduling mode...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX process scheduler is accessed primarily through the schedctl(2) system call, which provides a rich set of scheduling controls reflecting IRIX&#039;s historical focus on real-time, multiprocessor, and high-performance computing workloads. It supports:&lt;br /&gt;
&lt;br /&gt;
Real-time fixed-priority scheduling (non-degrading)&lt;br /&gt;
Traditional UNIX nice-value adjustments (timeshare)&lt;br /&gt;
Process group and user-wide nice operations (BSD compatibility)&lt;br /&gt;
CPU affinity control&lt;br /&gt;
Scheduling mode selection (free/gang)&lt;br /&gt;
Full Frame Scheduler (FRS) interface for user-level hard real-time gangs&lt;br /&gt;
Legacy hooks for older scheduling extensions&lt;br /&gt;
&lt;br /&gt;
The implementation centers on vproc_t (virtual process) objects, which abstract scheduling attributes across processes/threads. Changes are applied via VPROC_ operations that update runqueue information safely.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Main Interface (schedctl)&lt;br /&gt;
Single entry point dispatching commands:&lt;br /&gt;
&lt;br /&gt;
MPTS_RTPRI / MPTS_GETRTPRI: Set/get real-time priority (range NDPHIMAX..NDPLOMIN). Superuser required except for self-demotion or within normal range.&lt;br /&gt;
MPTS_SLICE: Set per-process time slice (ticks).&lt;br /&gt;
MPTS_RENICE / variants: Adjust nice values for process, process group, or all processes of a user (emulating BSD setpriority/getpriority semantics).&lt;br /&gt;
MPTS_SETHINTS: Initialize PRDA hints (obsolete pthread-related).&lt;br /&gt;
MPTS_SETMASTER: Set scheduling master PID (legacy).&lt;br /&gt;
MPTS_SCHEDMODE: Set scheduling mode (SGS_FREE, SGS_GANG, etc.).&lt;br /&gt;
MPTS_AFFINITY_*: Enable/disable/query CPU affinity.&lt;br /&gt;
MPTS_FRS_*: Full Frame Scheduler user interface (create, enqueue, yield, etc.).&lt;br /&gt;
&lt;br /&gt;
Most operations require CAP_SCHED_MGT capability.&lt;br /&gt;
Process List Scanner (plistscanner / plistscan)&lt;br /&gt;
Utility for user-wide or group-wide operations:&lt;br /&gt;
&lt;br /&gt;
Scans entire process table via procscan().&lt;br /&gt;
Handles renice/getnice across all matching processes.&lt;br /&gt;
Safe credential access via pcred_access().&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Scheduling Parameters&lt;br /&gt;
&lt;br /&gt;
Real-time priorities: Fixed, non-degrading. Higher numerical value = higher priority.&lt;br /&gt;
NDPHIMAX (highest), NDPNORMMIN (boundary to timeshare), NDPLOMIN (lowest RT).&lt;br /&gt;
&lt;br /&gt;
Nice values: Traditional UNIX (-20..+19 translated via NZERO=20).&lt;br /&gt;
Time slice: Configurable in ticks (default system-wide).&lt;br /&gt;
&lt;br /&gt;
Scheduling Modes (via MPTS_SCHEDMODE)&lt;br /&gt;
&lt;br /&gt;
SGS_FREE: Default independent scheduling.&lt;br /&gt;
SGS_GANG: Gang scheduling (co-scheduling of related threads).&lt;br /&gt;
&lt;br /&gt;
CPU Affinity&lt;br /&gt;
Controlled via VPROC_SCHED_AFF; requires CAP_SCHED_MGT.&lt;br /&gt;
Frame Scheduler (FRS)&lt;br /&gt;
Hard real-time extension:&lt;br /&gt;
&lt;br /&gt;
User-level creation of scheduling &amp;quot;frames&amp;quot; (gangs).&lt;br /&gt;
Precise control over dispatch, yield, interrupt handling.&lt;br /&gt;
All FRS operations require CAP_SCHED_MGT.&lt;br /&gt;
Old FRS interface (MPTS_OLDFRS_*) returns ENOTSUP.&lt;br /&gt;
&lt;br /&gt;
Batch Job Restrictions&lt;br /&gt;
Processes in batch process groups (Miser) cannot be made real-time.&lt;br /&gt;
Permission Model&lt;br /&gt;
Heavy reliance on CAP_SCHED_MGT capability rather than simple uid==0 checks.&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Very close heritage (both SVR4 descendants):&lt;br /&gt;
&lt;br /&gt;
schedctl-like interface existed historically in Solaris.&lt;br /&gt;
Real-time fixed priorities (RT class).&lt;br /&gt;
PRIORITY/NICE control via priocntl(2).&lt;br /&gt;
Gang scheduling concepts (though Solaris used processor sets).&lt;br /&gt;
Frame Scheduler unique to IRIX; Solaris had alternative real-time extensions.&lt;br /&gt;
&lt;br /&gt;
Porting: illumos priocntl(2) system provides similar class/parameter control. FRS has no direct analog.&lt;br /&gt;
BSD (FreeBSD, NetBSD, OpenBSD)&lt;br /&gt;
More divergent:&lt;br /&gt;
&lt;br /&gt;
Nice via setpriority/getpriority (exact semantics matched by IRIX MPTS_RENICE_* variants).&lt;br /&gt;
Real-time via sched_setparam/sched_getparam (POSIX).&lt;br /&gt;
CPU affinity via cpuset(2).&lt;br /&gt;
No direct gang or frame scheduler equivalents.&lt;br /&gt;
No unified schedctl; separate syscalls.&lt;br /&gt;
&lt;br /&gt;
Porting: BSD nicer for nice/priority; lacks IRIX&#039;s unified interface and FRS. Real-time weaker than IRIX fixed-priority model.&lt;br /&gt;
Overall, IRIX scheduler reflects strong SVR4 real-time heritage with unique extensions (FRS, gang modes). illumos provides closest conceptual match; BSD covers nice semantics well but lacks advanced features. For replication, focus on vproc abstraction and capability checks. FRS is largely IRIX-specific and hard to port directly.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_pfile&amp;diff=458</id>
		<title>Kernel: pfile</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_pfile&amp;diff=458"/>
		<updated>2026-01-04T03:28:02Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;== Overview == The pfile (physical file) object in the IRIX kernel represents per-open-file state beyond the vnode (file system-independent) and vfile (open file description) layers. It primarily manages the current file offset (pf_offset) and associated synchronization (pf_offlock). In single-cell (non-distributed) configurations, the pfile layer directly handles offset and flag operations. In distributed (multi-cell) environments using Cellular IRIX features, higher la...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The pfile (physical file) object in the IRIX kernel represents per-open-file state beyond the vnode (file system-independent) and vfile (open file description) layers. It primarily manages the current file offset (pf_offset) and associated synchronization (pf_offlock). In single-cell (non-distributed) configurations, the pfile layer directly handles offset and flag operations. In distributed (multi-cell) environments using Cellular IRIX features, higher layers (DC - Distributed Coordinator, DS - Distributed Server) take over offset and flag management for coherence across cells.&lt;br /&gt;
The pfile is integrated via the behavior descriptor (bhv_desc_t) mechanism, part of IRIX&#039;s chained vnode/behavior system. This allows stacking behaviors (e.g., pfile on top of filesystem-specific behaviors) on a common vfile_t structure. The pfile behavior is registered through pfile_ops (a vfileops_t table) at position VFILE_POSITION_PFILE.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
The implementation provides operations for creation, offset management, flag handling, teardown, close, and migration.&lt;br /&gt;
Initialization (pfile_init)&lt;br /&gt;
Allocates a kernel zone (pfile_zone) for efficient pfile_t structures using kmem_zone_init.&lt;br /&gt;
Creation (pfile_create)&lt;br /&gt;
Called on file open: allocates a pfile_t from the zone, initializes offset mutex and sets offset to 0, creates and inserts a bhv_desc_t (pf_bd) into the vfile_t behavior chain at the initial position.&lt;br /&gt;
Migration (pfile_target_migrate)&lt;br /&gt;
Used during distributed target migration (e.g., cell handover): creates a new pfile behavior, inserts it into the chain, and sets a specific offset (preserving position across migration).&lt;br /&gt;
Flag Management (pfile_setflags)&lt;br /&gt;
Locks the vfile_t, modifies open flags (vf_flag) using atomic mask/or operations, unlocks.&lt;br /&gt;
Offset Access (pfile_getoffset / pfile_setoffset)&lt;br /&gt;
Simple unprotected read/write of pf_offset. VFILE_NO_OFFSET is ignored on set.&lt;br /&gt;
Locked Offset Access (pfile_getoffset_locked / pfile_setoffset_locked)&lt;br /&gt;
Optional locking of pf_offlock (cell mutex) around offset operations for distributed safety.&lt;br /&gt;
Teardown (pfile_teardown)&lt;br /&gt;
Destroys offset mutex, removes behavior from chain (if vnode exists), frees pfile_t to zone. Asserts mutex not held.&lt;br /&gt;
Close Handling (pfile_close)&lt;br /&gt;
Called twice per close (first/last): decrements vf_count in vfile_t, returns flags indicating last close.&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures&lt;br /&gt;
&lt;br /&gt;
pfile_t (from pfile_private.h):&lt;br /&gt;
off_t pf_offset — current file position.&lt;br /&gt;
mutex_t pf_offlock — mutex protecting offset in distributed mode.&lt;br /&gt;
bhv_desc_t pf_bd — behavior descriptor linking to vfile.&lt;br /&gt;
&lt;br /&gt;
vfileops_t pfile_ops — operations table registered in behavior chain:&lt;br /&gt;
Position: VFILE_POSITION_PFILE&lt;br /&gt;
Functions: setflags, getoffset, setoffset, locked variants, teardown, close.&lt;br /&gt;
&lt;br /&gt;
Integration with vfile_t:&lt;br /&gt;
Contains vf_flag (open flags), vf_count (reference count), vf_bh (behavior chain head).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Distributed vs Single-Cell Behavior&lt;br /&gt;
&lt;br /&gt;
Single-cell: pfile directly manages offset/flags.&lt;br /&gt;
Multi-cell (Cellular IRIX): DC/DS layers override; pfile provides fallback or local cache.&lt;br /&gt;
&lt;br /&gt;
Behavior Chain Mechanics&lt;br /&gt;
Uses bhv_desc_t chaining (bhv_insert_initial, bhv_insert, bhv_remove). Allows dynamic stacking of behaviors (e.g., pfile over XFS/EFS vnode).&lt;br /&gt;
Migration Support&lt;br /&gt;
pfile_target_migrate enables seamless offset preservation during distributed file target changes (rare in standard IRIX, specific to Cellular configurations).&lt;br /&gt;
== Similarities to illumos and BSD libc/kernel Implementations ==&lt;br /&gt;
IRIX file handling differs significantly from modern open-file-description models due to its vnode/behavior layering.&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Moderate similarity in layered vnode design (vnode ops, but no direct behavior chaining). File offsets live in struct file (user fd) or uio; no separate pfile-like object. Distributed features (Cluster) use different mechanisms. illumos uses struct cred, zones; no exact pfile equivalent.&lt;br /&gt;
BSD (FreeBSD, etc.)&lt;br /&gt;
Less similar: file offsets in struct file (per-fd), with filedesc table. Vnode ops direct, no behavior descriptors/chaining. No distributed cell concept; clustering separate. Close handling simpler (single decrement).&lt;br /&gt;
Overall, IRIX&#039;s pfile is unique to its bhv_desc_t behavior system, designed for extensibility and distributed coherence. For replication or porting, focus on exact behavior insertion order and mutex usage. No direct illumos/BSD analog for easy porting; closest is Solaris vnode layering but without pfile separation.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_vfile&amp;diff=457</id>
		<title>Kernel: vfile</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_vfile&amp;diff=457"/>
		<updated>2026-01-04T03:27:21Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;== Overview == The vfile (virtual file) object in the IRIX kernel represents an open file description — the kernel-side structure that corresponds to an open file shared across processes (via fork, dup, etc.). It holds per-open state such as reference count, open flags, credentials, associated vnode or vsocket, and a behavior chain head for stacked behaviors (notably the pfile behavior for offset management). The vfile layer sits between the per-process file descriptor...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The vfile (virtual file) object in the IRIX kernel represents an open file description — the kernel-side structure that corresponds to an open file shared across processes (via fork, dup, etc.). It holds per-open state such as reference count, open flags, credentials, associated vnode or vsocket, and a behavior chain head for stacked behaviors (notably the pfile behavior for offset management).&lt;br /&gt;
The vfile layer sits between the per-process file descriptor table (fdt) and lower-level objects (vnode for files, vsocket for sockets). It manages reference counting, close semantics (including double-close protocol for races), credential handling, and integration with distributed (Cellular IRIX) features. The implementation emphasizes thread/sproc safety via spinlocks and careful race avoidance during close.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Initialization (vfile_init)&lt;br /&gt;
Initializes the file_zone for efficient allocation of vfile_t structures, sets up debugging lists/locks, calls vfile_cell_init() (distributed support) and pfile_init().&lt;br /&gt;
Creation (vfile_create)&lt;br /&gt;
Allocates a vfile_t from the zone, initializes:&lt;br /&gt;
&lt;br /&gt;
Spinlock (vf_lock)&lt;br /&gt;
Reference count = 1&lt;br /&gt;
Flags and credential hold&lt;br /&gt;
Behavior chain head (vf_bh)&lt;br /&gt;
Links into debug active list&lt;br /&gt;
Increments global SYSINFO.filecnt&lt;br /&gt;
&lt;br /&gt;
Allocation for Open (vfile_alloc)&lt;br /&gt;
Creates a vfile (with FINPROGRESS flag), allocates an fd via fdt_alloc, creates associated pfile behavior. Returns file pointer and fd; caller must call vfile_ready after successful VOP_OPEN.&lt;br /&gt;
Activation (vfile_ready)&lt;br /&gt;
Clears FINPROGRESS, sets associated vnode/vsocket pointer.&lt;br /&gt;
Undo on Failed Open (vfile_alloc_undo)&lt;br /&gt;
Reverses vfile_alloc when VOP_OPEN fails: removes fd, drops refcount, tears down pfile, destroys vfile.&lt;br /&gt;
Close Protocol (vfile_close, vfile_close_common, vfile_ref_release)&lt;br /&gt;
Implements a two-phase close to handle races between multiple threads/sprocs closing the same fd:&lt;br /&gt;
&lt;br /&gt;
vfile_close: Calls VFILE_CLOSE with VFILE_FIRSTCLOSE to probe if last reference.&lt;br /&gt;
vfile_close_common: Performs actual cleanup:&lt;br /&gt;
Cleans locks if present&lt;br /&gt;
Calls VOP_CLOSE (or VSOP_CLOSE) with appropriate lastclose flag&lt;br /&gt;
Handles double-call race by potentially issuing extra VOP_CLOSE&lt;br /&gt;
On true last close: flushes/invalidates if requested, releases vnode, removes GRIO reservations, tears down behaviors, destroys vfile&lt;br /&gt;
&lt;br /&gt;
vfile_ref_release: Used for non-close reference drops (e.g., rfork cleanup); only performs full close if last reference.&lt;br /&gt;
&lt;br /&gt;
Assignment Helper (vfile_assign)&lt;br /&gt;
Convenience wrapper: allocates vfile/fd, performs VOP_OPEN (updating vnode pointer if changed), readies vfile on success, undoes on failure.&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures (from ksys/vfile.h)&lt;br /&gt;
&lt;br /&gt;
vfile_t:&lt;br /&gt;
int vf_count — reference count (shared opens)&lt;br /&gt;
int vf_flag — open flags (FREAD, FWRITE, etc.) + internal (FINPROGRESS, FLCINVAL, FLCFLUSH, FPRIORITY)&lt;br /&gt;
cred_t *vf_cred — held credentials of opener&lt;br /&gt;
spinlock_t vf_lock — protects structure&lt;br /&gt;
bhv_head_t vf_bh — head of behavior chain (pfile inserted here)&lt;br /&gt;
void *vf_data — pointer to vnode_t or vsock_t (via VF_TO_VNODE/VF_TO_VSOCK)&lt;br /&gt;
Debug links (vf_next, vf_prev) for active list&lt;br /&gt;
&lt;br /&gt;
Macros:&lt;br /&gt;
VFLOCK / VFUNLOCK — spinlock wrappers&lt;br /&gt;
VFILE_CLOSE(fp, phase, info) — behavior chain dispatch for close&lt;br /&gt;
VFILE_TEARDOWN(fp) — behavior chain teardown dispatch&lt;br /&gt;
VF_IS_VNODE, VF_SET_DATA&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Double-Close Protocol&lt;br /&gt;
IRIX uses a two-call close pattern (VFILE_FIRSTCLOSE, VFILE_SECONDCLOSE) via behavior chain to safely determine last close in multiprocessor/shared-process environments. Prevents race where one thread tears down structure while another assumes it still exists.&lt;br /&gt;
Flags and Special Handling&lt;br /&gt;
&lt;br /&gt;
FINPROGRESS: Set during open until vfile_ready&lt;br /&gt;
FLCINVAL / FLCFLUSH: Trigger VOP_FSYNC with invalidate or flush on last close&lt;br /&gt;
FPRIORITY: Indicates GRIO (Guaranteed Rate I/O) reservation&lt;br /&gt;
VFRLOCKS: Vnode has record locks → clean on close&lt;br /&gt;
&lt;br /&gt;
Distributed Support&lt;br /&gt;
References to DC/DS (Distributed Coordinator/Server) and VFILE_SKIPCLOSE indicate special handling in Cellular IRIX: last close may be deferred or coordinated remotely.&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Moderate similarity:&lt;br /&gt;
&lt;br /&gt;
Per-open state in struct file (referenced by filedesc table)&lt;br /&gt;
Reference counting and close races handled via closef()&lt;br /&gt;
Vnode ops with VOP_CLOSE(last)&lt;br /&gt;
Credential holding&lt;br /&gt;
No behavior chaining; vnode ops direct&lt;br /&gt;
No explicit pfile separation — offset in uio or per-read/write&lt;br /&gt;
&lt;br /&gt;
Porting: illumos file closer to vfile than BSD, but lacks behavior chain and double-close protocol.&lt;br /&gt;
BSD (FreeBSD, NetBSD, OpenBSD)&lt;br /&gt;
Closer in some aspects:&lt;br /&gt;
&lt;br /&gt;
struct file with reference count, flags, credential, pointer to fileops and data (vnode/socket)&lt;br /&gt;
Double-close avoidance via careful refcounting&lt;br /&gt;
closef() performs fdrop() → ops → free&lt;br /&gt;
No behavior chaining; direct fops dispatch&lt;br /&gt;
Offset not stored in file — managed per-I/O via uio&lt;br /&gt;
&lt;br /&gt;
Porting: BSD struct file semantically similar to vfile. Main differences: no bhv chain, no explicit pfile layer, different lock strategy.&lt;br /&gt;
Overall, IRIX vfile is unique due to bhv_desc_t behavior chaining and pfile offset separation, designed for extensibility and Cellular IRIX distributed coherence. No direct equivalent in illumos/BSD for easy porting; closest analogs are struct file in both, but require adding behavior dispatch and double-close logic for fidelity.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Mutex&amp;diff=456</id>
		<title>Kernel: Mutex</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Mutex&amp;diff=456"/>
		<updated>2026-01-04T03:24:39Z</updated>

		<summary type="html">&lt;p&gt;Raion: /* Similarities to illumos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX kernel mutex implementation provides basic mutual exclusion primitives with priority inheritance to mitigate priority inversion, atomic owner tracking via compare-and-swap, optional metering/statistics, and integration with the broader [[Kernel:ksync]] (kernel synchronization) framework that includes sv_t (synchronization variables) for semaphores, condition variables, and other waitable objects.&lt;br /&gt;
The design uses a single-word owner field (m_bits) combining owner thread pointer with flags (lock bit, queue bit). Contention spins briefly then sleeps on a circular doubly-linked waiter queue. Priority inheritance propagates up blocked chains. The implementation supports debugging/metering via optional info structures and integrates with spinlocks, bitlocks, mrlocks, and semaphores through sv_t wrappers.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Initialization (kmutei_init)&lt;br /&gt;
Creates zones for mutex_t and sv_t structures. Initializes hash buckets for optional wchan info (debug/metering).&lt;br /&gt;
Allocation (mutex_alloc / init_mutex)&lt;br /&gt;
Zone-allocates mutex_t, clears bits, optionally allocates metering/info structure.&lt;br /&gt;
Deallocation (mutex_destroy / mutex_dealloc)&lt;br /&gt;
Frees info structure, zone-frees mutex.&lt;br /&gt;
Core Operations&lt;br /&gt;
&lt;br /&gt;
mutex_trylock: Atomic compare-and-swap to set owner; updates metering.&lt;br /&gt;
mutex_lock: Trylock → on miss, queue and sleep with priority inheritance probing.&lt;br /&gt;
mutex_unlock: Clears owner; if waiters, wakes highest-priority waiter (single thread).&lt;br /&gt;
mutex_wait: Queues thread, handles inheritance, blocks (non-breakable).&lt;br /&gt;
mutex_wake: Dequeues highest-priority waiter, transfers ownership, updates metering.&lt;br /&gt;
&lt;br /&gt;
Priority Inheritance&lt;br /&gt;
&lt;br /&gt;
resource_raise_owner_pri: Boosts owner priority to waiter’s.&lt;br /&gt;
resource_test_owner_pri: Detects inversion, raises or spins/yields.&lt;br /&gt;
drop_inheritance: Restores base priority on unlock.&lt;br /&gt;
Supports chained inheritance via k_inherit pointer.&lt;br /&gt;
&lt;br /&gt;
Waiter Queue Management&lt;br /&gt;
&lt;br /&gt;
Circular doubly-linked list in m_queue.&lt;br /&gt;
Queued in approximate priority order (mutex_queue).&lt;br /&gt;
Single waiter woken on unlock (mutex_wake).&lt;br /&gt;
&lt;br /&gt;
Synchronization Variables (sv_t)&lt;br /&gt;
General-purpose wait queue supporting:&lt;br /&gt;
&lt;br /&gt;
FIFO, LIFO, priority, keyed ordering.&lt;br /&gt;
Signal (wake one), broadcast (wake all), bounded broadcast.&lt;br /&gt;
Timed waits, signal-breakable waits.&lt;br /&gt;
Integration with mutex/spin/bit/mrlock/sema release.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures&lt;br /&gt;
&lt;br /&gt;
mutex_t:&lt;br /&gt;
__psunsigned_t m_bits — owner thread pointer + flags (low bit lock, next bit queue).&lt;br /&gt;
kthread_t *m_queue — circular waiter list head.&lt;br /&gt;
Optional m_info pointer for metering/wchan info.&lt;br /&gt;
&lt;br /&gt;
sv_t:&lt;br /&gt;
__psunsigned_t sv_queue — waiter pointer + lock bit + type (FIFO/LIFO/PRIO/KEYED).&lt;br /&gt;
Optional sv_info for metering.&lt;br /&gt;
&lt;br /&gt;
Flags/macros:&lt;br /&gt;
MUTEX_LOCKBIT, MUTEX_QUEUEBIT&lt;br /&gt;
SV_LOCK, SV_TYPE masks&lt;br /&gt;
KT_WMUTEX, KT_WSV thread sleep flags&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Priority Inheritance Details&lt;br /&gt;
&lt;br /&gt;
Aggressive: propagates through chains, handles indirect waits.&lt;br /&gt;
Temporary priority boost with KT_PS flag.&lt;br /&gt;
Supports real-time and timeshare scheduling.&lt;br /&gt;
&lt;br /&gt;
Metering and Debug (SEMAMETER/SEMAINFO)&lt;br /&gt;
&lt;br /&gt;
Optional per-object statistics (lock attempts, hold/wait times, contention).&lt;br /&gt;
Hash bucket lists for idbg scanning.&lt;br /&gt;
&lt;br /&gt;
sv_t Flexibility&lt;br /&gt;
&lt;br /&gt;
Unified queue for multiple lock types via wrapper functions.&lt;br /&gt;
Supports bounded broadcast (wakes only original waiter set).&lt;br /&gt;
Threshold wake (sv_threshold).&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos Implementation ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
&lt;br /&gt;
Strong similarity due to shared SVR4 heritage:&lt;br /&gt;
&lt;br /&gt;
Adaptive mutexes with priority inheritance (similar owner word, waiter lists).&lt;br /&gt;
&lt;br /&gt;
mutex_enter, mutex_tryenter, mutex_exit.&lt;br /&gt;
&lt;br /&gt;
Turnstiles for sleeping/waiting (similar to sv_t but more integrated).&lt;br /&gt;
&lt;br /&gt;
CVs and semaphores separate but similar.&lt;br /&gt;
&lt;br /&gt;
Metering via kstat or dtrace.&lt;br /&gt;
&lt;br /&gt;
Porting: illumos adaptive mutex closest match. Differences in turnstile priority blocking vs IRIX explicit inheritance chains.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Mutex&amp;diff=455</id>
		<title>Kernel: Mutex</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Mutex&amp;diff=455"/>
		<updated>2026-01-04T03:23:40Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX kernel mutex implementation provides basic mutual exclusion primitives with priority inheritance to mitigate priority inversion, atomic owner tracking via compare-and-swap, optional metering/statistics, and integration with the broader [[Kernel:ksync]] (kernel synchronization) framework that includes sv_t (synchronization variables) for semaphores, condition variables, and other waitable objects.&lt;br /&gt;
The design uses a single-word owner field (m_bits) combining owner thread pointer with flags (lock bit, queue bit). Contention spins briefly then sleeps on a circular doubly-linked waiter queue. Priority inheritance propagates up blocked chains. The implementation supports debugging/metering via optional info structures and integrates with spinlocks, bitlocks, mrlocks, and semaphores through sv_t wrappers.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Initialization (kmutei_init)&lt;br /&gt;
Creates zones for mutex_t and sv_t structures. Initializes hash buckets for optional wchan info (debug/metering).&lt;br /&gt;
Allocation (mutex_alloc / init_mutex)&lt;br /&gt;
Zone-allocates mutex_t, clears bits, optionally allocates metering/info structure.&lt;br /&gt;
Deallocation (mutex_destroy / mutex_dealloc)&lt;br /&gt;
Frees info structure, zone-frees mutex.&lt;br /&gt;
Core Operations&lt;br /&gt;
&lt;br /&gt;
mutex_trylock: Atomic compare-and-swap to set owner; updates metering.&lt;br /&gt;
mutex_lock: Trylock → on miss, queue and sleep with priority inheritance probing.&lt;br /&gt;
mutex_unlock: Clears owner; if waiters, wakes highest-priority waiter (single thread).&lt;br /&gt;
mutex_wait: Queues thread, handles inheritance, blocks (non-breakable).&lt;br /&gt;
mutex_wake: Dequeues highest-priority waiter, transfers ownership, updates metering.&lt;br /&gt;
&lt;br /&gt;
Priority Inheritance&lt;br /&gt;
&lt;br /&gt;
resource_raise_owner_pri: Boosts owner priority to waiter’s.&lt;br /&gt;
resource_test_owner_pri: Detects inversion, raises or spins/yields.&lt;br /&gt;
drop_inheritance: Restores base priority on unlock.&lt;br /&gt;
Supports chained inheritance via k_inherit pointer.&lt;br /&gt;
&lt;br /&gt;
Waiter Queue Management&lt;br /&gt;
&lt;br /&gt;
Circular doubly-linked list in m_queue.&lt;br /&gt;
Queued in approximate priority order (mutex_queue).&lt;br /&gt;
Single waiter woken on unlock (mutex_wake).&lt;br /&gt;
&lt;br /&gt;
Synchronization Variables (sv_t)&lt;br /&gt;
General-purpose wait queue supporting:&lt;br /&gt;
&lt;br /&gt;
FIFO, LIFO, priority, keyed ordering.&lt;br /&gt;
Signal (wake one), broadcast (wake all), bounded broadcast.&lt;br /&gt;
Timed waits, signal-breakable waits.&lt;br /&gt;
Integration with mutex/spin/bit/mrlock/sema release.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures&lt;br /&gt;
&lt;br /&gt;
mutex_t:&lt;br /&gt;
__psunsigned_t m_bits — owner thread pointer + flags (low bit lock, next bit queue).&lt;br /&gt;
kthread_t *m_queue — circular waiter list head.&lt;br /&gt;
Optional m_info pointer for metering/wchan info.&lt;br /&gt;
&lt;br /&gt;
sv_t:&lt;br /&gt;
__psunsigned_t sv_queue — waiter pointer + lock bit + type (FIFO/LIFO/PRIO/KEYED).&lt;br /&gt;
Optional sv_info for metering.&lt;br /&gt;
&lt;br /&gt;
Flags/macros:&lt;br /&gt;
MUTEX_LOCKBIT, MUTEX_QUEUEBIT&lt;br /&gt;
SV_LOCK, SV_TYPE masks&lt;br /&gt;
KT_WMUTEX, KT_WSV thread sleep flags&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Priority Inheritance Details&lt;br /&gt;
&lt;br /&gt;
Aggressive: propagates through chains, handles indirect waits.&lt;br /&gt;
Temporary priority boost with KT_PS flag.&lt;br /&gt;
Supports real-time and timeshare scheduling.&lt;br /&gt;
&lt;br /&gt;
Metering and Debug (SEMAMETER/SEMAINFO)&lt;br /&gt;
&lt;br /&gt;
Optional per-object statistics (lock attempts, hold/wait times, contention).&lt;br /&gt;
Hash bucket lists for idbg scanning.&lt;br /&gt;
&lt;br /&gt;
sv_t Flexibility&lt;br /&gt;
&lt;br /&gt;
Unified queue for multiple lock types via wrapper functions.&lt;br /&gt;
Supports bounded broadcast (wakes only original waiter set).&lt;br /&gt;
Threshold wake (sv_threshold).&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong similarity due to shared SVR4 heritage:&lt;br /&gt;
&lt;br /&gt;
Adaptive mutexes with priority inheritance (similar owner word, waiter lists).&lt;br /&gt;
mutex_enter, mutex_tryenter, mutex_exit.&lt;br /&gt;
Turnstiles for sleeping/waiting (similar to sv_t but more integrated).&lt;br /&gt;
CVs and semaphores separate but similar.&lt;br /&gt;
Metering via kstat or dtrace.&lt;br /&gt;
&lt;br /&gt;
Porting: illumos adaptive mutex closest match. Differences in turnstile priority blocking vs IRIX explicit inheritance chains.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Mutex&amp;diff=454</id>
		<title>Kernel: Mutex</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Mutex&amp;diff=454"/>
		<updated>2026-01-04T03:23:07Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;== Overview == The IRIX kernel mutex implementation provides basic mutual exclusion primitives with priority inheritance to mitigate priority inversion, atomic owner tracking via compare-and-swap, optional metering/statistics, and integration with the broader ksync (kernel synchronization) framework that includes sv_t (synchronization variables) for semaphores, condition variables, and other waitable objects. The design uses a single-word owner field (m_bits) combining o...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX kernel mutex implementation provides basic mutual exclusion primitives with priority inheritance to mitigate priority inversion, atomic owner tracking via compare-and-swap, optional metering/statistics, and integration with the broader ksync (kernel synchronization) framework that includes sv_t (synchronization variables) for semaphores, condition variables, and other waitable objects.&lt;br /&gt;
The design uses a single-word owner field (m_bits) combining owner thread pointer with flags (lock bit, queue bit). Contention spins briefly then sleeps on a circular doubly-linked waiter queue. Priority inheritance propagates up blocked chains. The implementation supports debugging/metering via optional info structures and integrates with spinlocks, bitlocks, mrlocks, and semaphores through sv_t wrappers.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
Initialization (kmutei_init)&lt;br /&gt;
Creates zones for mutex_t and sv_t structures. Initializes hash buckets for optional wchan info (debug/metering).&lt;br /&gt;
Allocation (mutex_alloc / init_mutex)&lt;br /&gt;
Zone-allocates mutex_t, clears bits, optionally allocates metering/info structure.&lt;br /&gt;
Deallocation (mutex_destroy / mutex_dealloc)&lt;br /&gt;
Frees info structure, zone-frees mutex.&lt;br /&gt;
Core Operations&lt;br /&gt;
&lt;br /&gt;
mutex_trylock: Atomic compare-and-swap to set owner; updates metering.&lt;br /&gt;
mutex_lock: Trylock → on miss, queue and sleep with priority inheritance probing.&lt;br /&gt;
mutex_unlock: Clears owner; if waiters, wakes highest-priority waiter (single thread).&lt;br /&gt;
mutex_wait: Queues thread, handles inheritance, blocks (non-breakable).&lt;br /&gt;
mutex_wake: Dequeues highest-priority waiter, transfers ownership, updates metering.&lt;br /&gt;
&lt;br /&gt;
Priority Inheritance&lt;br /&gt;
&lt;br /&gt;
resource_raise_owner_pri: Boosts owner priority to waiter’s.&lt;br /&gt;
resource_test_owner_pri: Detects inversion, raises or spins/yields.&lt;br /&gt;
drop_inheritance: Restores base priority on unlock.&lt;br /&gt;
Supports chained inheritance via k_inherit pointer.&lt;br /&gt;
&lt;br /&gt;
Waiter Queue Management&lt;br /&gt;
&lt;br /&gt;
Circular doubly-linked list in m_queue.&lt;br /&gt;
Queued in approximate priority order (mutex_queue).&lt;br /&gt;
Single waiter woken on unlock (mutex_wake).&lt;br /&gt;
&lt;br /&gt;
Synchronization Variables (sv_t)&lt;br /&gt;
General-purpose wait queue supporting:&lt;br /&gt;
&lt;br /&gt;
FIFO, LIFO, priority, keyed ordering.&lt;br /&gt;
Signal (wake one), broadcast (wake all), bounded broadcast.&lt;br /&gt;
Timed waits, signal-breakable waits.&lt;br /&gt;
Integration with mutex/spin/bit/mrlock/sema release.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
Critical Structures&lt;br /&gt;
&lt;br /&gt;
mutex_t:&lt;br /&gt;
__psunsigned_t m_bits — owner thread pointer + flags (low bit lock, next bit queue).&lt;br /&gt;
kthread_t *m_queue — circular waiter list head.&lt;br /&gt;
Optional m_info pointer for metering/wchan info.&lt;br /&gt;
&lt;br /&gt;
sv_t:&lt;br /&gt;
__psunsigned_t sv_queue — waiter pointer + lock bit + type (FIFO/LIFO/PRIO/KEYED).&lt;br /&gt;
Optional sv_info for metering.&lt;br /&gt;
&lt;br /&gt;
Flags/macros:&lt;br /&gt;
MUTEX_LOCKBIT, MUTEX_QUEUEBIT&lt;br /&gt;
SV_LOCK, SV_TYPE masks&lt;br /&gt;
KT_WMUTEX, KT_WSV thread sleep flags&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Priority Inheritance Details&lt;br /&gt;
&lt;br /&gt;
Aggressive: propagates through chains, handles indirect waits.&lt;br /&gt;
Temporary priority boost with KT_PS flag.&lt;br /&gt;
Supports real-time and timeshare scheduling.&lt;br /&gt;
&lt;br /&gt;
Metering and Debug (SEMAMETER/SEMAINFO)&lt;br /&gt;
&lt;br /&gt;
Optional per-object statistics (lock attempts, hold/wait times, contention).&lt;br /&gt;
Hash bucket lists for idbg scanning.&lt;br /&gt;
&lt;br /&gt;
sv_t Flexibility&lt;br /&gt;
&lt;br /&gt;
Unified queue for multiple lock types via wrapper functions.&lt;br /&gt;
Supports bounded broadcast (wakes only original waiter set).&lt;br /&gt;
Threshold wake (sv_threshold).&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD Kernel Implementations ==&lt;br /&gt;
illumos (Solaris-derived)&lt;br /&gt;
Strong similarity due to shared SVR4 heritage:&lt;br /&gt;
&lt;br /&gt;
Adaptive mutexes with priority inheritance (similar owner word, waiter lists).&lt;br /&gt;
mutex_enter, mutex_tryenter, mutex_exit.&lt;br /&gt;
Turnstiles for sleeping/waiting (similar to sv_t but more integrated).&lt;br /&gt;
CVs and semaphores separate but similar.&lt;br /&gt;
Metering via kstat or dtrace.&lt;br /&gt;
&lt;br /&gt;
Porting: illumos adaptive mutex closest match. Differences in turnstile priority blocking vs IRIX explicit inheritance chains.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Libc:_malloc&amp;diff=453</id>
		<title>Libc: malloc</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Libc:_malloc&amp;diff=453"/>
		<updated>2025-12-30T19:10:34Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The IRIX libc malloc family (malloc, free, realloc, etc.) implements a classic System V-style dynamic memory allocator using a splay tree for managing free blocks of varying sizes, separate linked lists for small blocks, aggressive coalescing, and delayed freeing to preserve freed block contents across calls. It obtains more memory via sbrk (or equivalent GETCORE), aligns allocations to word boundaries, and handles non-contiguous arenas when necessary.&lt;br /&gt;
&lt;br /&gt;
This decompiled implementation reveals MIPS-specific details (e.g., word size alignment, conditional segmented memory handling), a unique delayed free mechanism using flist and Lfree to avoid disturbing freed data until the next allocation, and optimizations like small-block lists and history-based batch allocation.&lt;br /&gt;
&lt;br /&gt;
Also see: [[Kernel:malloc]]&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
The allocator centers on a splay tree of free blocks with supporting structures and routines for coalescing, tree maintenance, and arena growth.&lt;br /&gt;
&lt;br /&gt;
Core Allocation (_malloc / __malloc)&lt;br /&gt;
&lt;br /&gt;
Rounds size to word alignment (WORDSIZE, typically 8 on 64-bit MIPS). Checks last freed block (Lfree) for reuse. Performs pending frees via cleanfree(). Handles small requests (&amp;lt; MINSIZE) via _smalloc. Searches splay tree for best-fit (approximated via splaying). Falls back to Bottom chunk or _morecore() for new memory. Coalesces leftovers if large enough.&lt;br /&gt;
&lt;br /&gt;
Deallocation (free / __free / realfree)&lt;br /&gt;
free delays actual deallocation by placing pointer in circular flist buffer (size FREESIZE=32) and sets Lfree. Actual freeing occurs in next malloc/realloc via cleanfree() or when buffer fills. realfree coalesces with adjacent blocks, inserts into small lists or splay tree (leaf insertion without immediate splay), updates neighbor busy/free bits.&lt;br /&gt;
&lt;br /&gt;
Reallocation (realloc / _realloc)&lt;br /&gt;
&lt;br /&gt;
Attempts in-place expansion by forward merging. Extends via _morecore if at arena end. Falls back to new allocation + copy + free. Handles special recovery cases when allocation fails (shrink, small-block fallback, backward merge with copy).&lt;br /&gt;
&lt;br /&gt;
Small Block Allocation (_smalloc)&lt;br /&gt;
Maintains per-size linked lists (List[]) for sizes &amp;lt; MINSIZE. Batch-allocates multiples (powers of 2 based on history bits) from large blocks to reduce calls to main allocator.&lt;br /&gt;
&lt;br /&gt;
Arena Extension (_morecore)&lt;br /&gt;
&lt;br /&gt;
Requests memory via GETCORE (sbrk wrapper), aligns to page boundaries, doubles request size after threshold calls, handles contiguous/non-contiguous cases, creates new Bottom block.&lt;br /&gt;
&lt;br /&gt;
Tree Maintenance (t_splay, t_delete)&lt;br /&gt;
&lt;br /&gt;
Bottom-up splaying on access (in search/delete). Macro-based rotations for zig/zig-zig cases. Supports lists of equal-sized blocks within tree nodes (via LINKFOR/LINKBAK).&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
&lt;br /&gt;
=== Critical Structures for ABI Compatibility (from mallint.h) ===&lt;br /&gt;
Exact layout must match for binary compatibility; block headers overlap user data minimally.&lt;br /&gt;
&lt;br /&gt;
TREE (block header, placed before user data):&lt;br /&gt;
&lt;br /&gt;
size_t SIZE field in low bits: actual size + flags (BIT0 busy, BIT1 previous free).&lt;br /&gt;
&lt;br /&gt;
Tree fields: TREE *LEFT, RIGHT, PARENT.&lt;br /&gt;
List fields: TREE *LINKFOR, LINKBAK (for equal-size doubly-linked lists).&lt;br /&gt;
&lt;br /&gt;
Self-pointer at end of block for validation.&lt;br /&gt;
Macros: DATA(tp) (user pointer), BLOCK(p) (header from user), NEXT(tp), LAST(tp), BOTTOM(tp), etc.&lt;br /&gt;
&lt;br /&gt;
=== Global state: ===&lt;br /&gt;
TREE *Root — splay tree root.&lt;br /&gt;
&lt;br /&gt;
TREE *Bottom — last chunk at arena end.&lt;br /&gt;
&lt;br /&gt;
char *Baddr — current break address.&lt;br /&gt;
&lt;br /&gt;
char *Lfree — last freed pointer (data intact).&lt;br /&gt;
&lt;br /&gt;
VOID *flist[FREESIZE] + int freeidx — delayed free ring buffer.&lt;br /&gt;
&lt;br /&gt;
TREE *List[MINSIZE/WORDSIZE-1] — small block free lists.&lt;br /&gt;
&lt;br /&gt;
History vars: coresizemask, corecalls.&lt;br /&gt;
&lt;br /&gt;
Constants/macros:&lt;br /&gt;
WORDSIZE — typically 8 (64-bit) or 4.&lt;br /&gt;
&lt;br /&gt;
ALIGN — same as WORDSIZE.&lt;br /&gt;
MINSIZE — threshold for small lists (often 40-48 bytes).&lt;br /&gt;
&lt;br /&gt;
BIT0 (busy), BIT1 (prev free), BITS01.&lt;br /&gt;
&lt;br /&gt;
=== Delayed Free Mechanism ===&lt;br /&gt;
Unique to this implementation: free rarely calls realfree immediately. Instead buffers pointers in flist (preserves data in freed blocks). Next allocation frees buffered blocks (except possibly current realloc target). Enables optimizations assuming freed data undisturbed briefly.&lt;br /&gt;
&lt;br /&gt;
Splay Tree with Equal-Size Lists&lt;br /&gt;
&lt;br /&gt;
Free blocks ordered by size in splay tree. Equal-size blocks form doubly-linked lists within tree nodes (using extra fields). Insertion leaf-only; splaying on search/delete for amortization.&lt;br /&gt;
&lt;br /&gt;
=== Other Behaviors ===&lt;br /&gt;
malloc(0) returns unique pointer (size WORDSIZE).&lt;br /&gt;
&lt;br /&gt;
Aggressive coalescing forward/backward on free.&lt;br /&gt;
&lt;br /&gt;
No mmap for large blocks (pure sbrk).&lt;br /&gt;
&lt;br /&gt;
Thread-safe via optional locks (__LOCK_MALLOC).&lt;br /&gt;
&lt;br /&gt;
Special sgi page-end allocation adjustment.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD libc Implementations ==&lt;br /&gt;
To enable reimplementation via modified illumos/BSD sources:&lt;br /&gt;
&lt;br /&gt;
illumos libc (malloc.c in libc or watchmalloc)&lt;br /&gt;
&lt;br /&gt;
Extremely close — IRIX derived from same SVR4 lineage as Solaris/illumos:&lt;br /&gt;
&lt;br /&gt;
Nearly identical structure: splay tree + small lists + coalescing + delayed free via flist/Lfree.&lt;br /&gt;
&lt;br /&gt;
Same functions: realfree, t_splay, t_delete, _morecore.&lt;br /&gt;
&lt;br /&gt;
Identical delayed free ring buffer and cleanfree.&lt;br /&gt;
&lt;br /&gt;
Same small-block batching with history bits.&lt;br /&gt;
&lt;br /&gt;
Minor differences: illumos evolved (better thread support, umem alternative); may use mmap for large allocs.&lt;br /&gt;
&lt;br /&gt;
For reimplementation: illumos malloc.c is virtually the same base. Adjust MIPS alignment/constants, ensure exact header layout/macros, preserve delayed free and splay details.&lt;br /&gt;
&lt;br /&gt;
BSD libc (jemalloc or legacy)&lt;br /&gt;
&lt;br /&gt;
More divergent:&lt;br /&gt;
&lt;br /&gt;
Modern FreeBSD/NetBSD use jemalloc (arena-per-thread, red-black trees, extensive caching).&lt;br /&gt;
&lt;br /&gt;
Older BSD had simpler first-fit or dlmalloc-derived.&lt;br /&gt;
&lt;br /&gt;
No splay trees, no delayed free ring, different coalescing.&lt;br /&gt;
&lt;br /&gt;
jemalloc highly tuned for multi-thread, low fragmentation.&lt;br /&gt;
&lt;br /&gt;
For reimplementation: BSD sources less suitable as base; useful for ideas on thread arenas or modern features, but require major rewrite to match IRIX splay/delayed behavior.&lt;br /&gt;
&lt;br /&gt;
Overall, illumos/Solaris-derived malloc is the closest match for direct porting due to shared System V heritage and near-identical internals. Combine with IRIX specifics for exact ABI/behavior replication. Verify against mallint.h equivalents and test with IRIX binaries.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Libc:_malloc&amp;diff=452</id>
		<title>Libc: malloc</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Libc:_malloc&amp;diff=452"/>
		<updated>2025-12-30T19:09:58Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;The IRIX libc malloc family (malloc, free, realloc, etc.) implements a classic System V-style dynamic memory allocator using a splay tree for managing free blocks of varying sizes, separate linked lists for small blocks, aggressive coalescing, and delayed freeing to preserve freed block contents across calls. It obtains more memory via sbrk (or equivalent GETCORE), aligns allocations to word boundaries, and handles non-contiguous arenas when necessary. This decompiled im...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The IRIX libc malloc family (malloc, free, realloc, etc.) implements a classic System V-style dynamic memory allocator using a splay tree for managing free blocks of varying sizes, separate linked lists for small blocks, aggressive coalescing, and delayed freeing to preserve freed block contents across calls. It obtains more memory via sbrk (or equivalent GETCORE), aligns allocations to word boundaries, and handles non-contiguous arenas when necessary.&lt;br /&gt;
This decompiled implementation reveals MIPS-specific details (e.g., word size alignment, conditional segmented memory handling), a unique delayed free mechanism using flist and Lfree to avoid disturbing freed data until the next allocation, and optimizations like small-block lists and history-based batch allocation.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
The allocator centers on a splay tree of free blocks with supporting structures and routines for coalescing, tree maintenance, and arena growth.&lt;br /&gt;
&lt;br /&gt;
Core Allocation (_malloc / __malloc)&lt;br /&gt;
&lt;br /&gt;
Rounds size to word alignment (WORDSIZE, typically 8 on 64-bit MIPS). Checks last freed block (Lfree) for reuse. Performs pending frees via cleanfree(). Handles small requests (&amp;lt; MINSIZE) via _smalloc. Searches splay tree for best-fit (approximated via splaying). Falls back to Bottom chunk or _morecore() for new memory. Coalesces leftovers if large enough.&lt;br /&gt;
&lt;br /&gt;
Deallocation (free / __free / realfree)&lt;br /&gt;
free delays actual deallocation by placing pointer in circular flist buffer (size FREESIZE=32) and sets Lfree. Actual freeing occurs in next malloc/realloc via cleanfree() or when buffer fills. realfree coalesces with adjacent blocks, inserts into small lists or splay tree (leaf insertion without immediate splay), updates neighbor busy/free bits.&lt;br /&gt;
&lt;br /&gt;
Reallocation (realloc / _realloc)&lt;br /&gt;
&lt;br /&gt;
Attempts in-place expansion by forward merging. Extends via _morecore if at arena end. Falls back to new allocation + copy + free. Handles special recovery cases when allocation fails (shrink, small-block fallback, backward merge with copy).&lt;br /&gt;
&lt;br /&gt;
Small Block Allocation (_smalloc)&lt;br /&gt;
Maintains per-size linked lists (List[]) for sizes &amp;lt; MINSIZE. Batch-allocates multiples (powers of 2 based on history bits) from large blocks to reduce calls to main allocator.&lt;br /&gt;
&lt;br /&gt;
Arena Extension (_morecore)&lt;br /&gt;
&lt;br /&gt;
Requests memory via GETCORE (sbrk wrapper), aligns to page boundaries, doubles request size after threshold calls, handles contiguous/non-contiguous cases, creates new Bottom block.&lt;br /&gt;
&lt;br /&gt;
Tree Maintenance (t_splay, t_delete)&lt;br /&gt;
&lt;br /&gt;
Bottom-up splaying on access (in search/delete). Macro-based rotations for zig/zig-zig cases. Supports lists of equal-sized blocks within tree nodes (via LINKFOR/LINKBAK).&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
&lt;br /&gt;
=== Critical Structures for ABI Compatibility (from mallint.h) ===&lt;br /&gt;
Exact layout must match for binary compatibility; block headers overlap user data minimally.&lt;br /&gt;
&lt;br /&gt;
TREE (block header, placed before user data):&lt;br /&gt;
&lt;br /&gt;
size_t SIZE field in low bits: actual size + flags (BIT0 busy, BIT1 previous free).&lt;br /&gt;
&lt;br /&gt;
Tree fields: TREE *LEFT, RIGHT, PARENT.&lt;br /&gt;
List fields: TREE *LINKFOR, LINKBAK (for equal-size doubly-linked lists).&lt;br /&gt;
&lt;br /&gt;
Self-pointer at end of block for validation.&lt;br /&gt;
Macros: DATA(tp) (user pointer), BLOCK(p) (header from user), NEXT(tp), LAST(tp), BOTTOM(tp), etc.&lt;br /&gt;
&lt;br /&gt;
=== Global state: ===&lt;br /&gt;
TREE *Root — splay tree root.&lt;br /&gt;
&lt;br /&gt;
TREE *Bottom — last chunk at arena end.&lt;br /&gt;
&lt;br /&gt;
char *Baddr — current break address.&lt;br /&gt;
&lt;br /&gt;
char *Lfree — last freed pointer (data intact).&lt;br /&gt;
&lt;br /&gt;
VOID *flist[FREESIZE] + int freeidx — delayed free ring buffer.&lt;br /&gt;
&lt;br /&gt;
TREE *List[MINSIZE/WORDSIZE-1] — small block free lists.&lt;br /&gt;
&lt;br /&gt;
History vars: coresizemask, corecalls.&lt;br /&gt;
&lt;br /&gt;
Constants/macros:&lt;br /&gt;
WORDSIZE — typically 8 (64-bit) or 4.&lt;br /&gt;
&lt;br /&gt;
ALIGN — same as WORDSIZE.&lt;br /&gt;
MINSIZE — threshold for small lists (often 40-48 bytes).&lt;br /&gt;
&lt;br /&gt;
BIT0 (busy), BIT1 (prev free), BITS01.&lt;br /&gt;
&lt;br /&gt;
=== Delayed Free Mechanism ===&lt;br /&gt;
Unique to this implementation: free rarely calls realfree immediately. Instead buffers pointers in flist (preserves data in freed blocks). Next allocation frees buffered blocks (except possibly current realloc target). Enables optimizations assuming freed data undisturbed briefly.&lt;br /&gt;
&lt;br /&gt;
Splay Tree with Equal-Size Lists&lt;br /&gt;
&lt;br /&gt;
Free blocks ordered by size in splay tree. Equal-size blocks form doubly-linked lists within tree nodes (using extra fields). Insertion leaf-only; splaying on search/delete for amortization.&lt;br /&gt;
&lt;br /&gt;
=== Other Behaviors ===&lt;br /&gt;
malloc(0) returns unique pointer (size WORDSIZE).&lt;br /&gt;
&lt;br /&gt;
Aggressive coalescing forward/backward on free.&lt;br /&gt;
&lt;br /&gt;
No mmap for large blocks (pure sbrk).&lt;br /&gt;
&lt;br /&gt;
Thread-safe via optional locks (__LOCK_MALLOC).&lt;br /&gt;
&lt;br /&gt;
Special sgi page-end allocation adjustment.&lt;br /&gt;
&lt;br /&gt;
== Similarities to illumos and BSD libc Implementations ==&lt;br /&gt;
To enable reimplementation via modified illumos/BSD sources:&lt;br /&gt;
&lt;br /&gt;
illumos libc (malloc.c in libc or watchmalloc)&lt;br /&gt;
&lt;br /&gt;
Extremely close — IRIX derived from same SVR4 lineage as Solaris/illumos:&lt;br /&gt;
&lt;br /&gt;
Nearly identical structure: splay tree + small lists + coalescing + delayed free via flist/Lfree.&lt;br /&gt;
&lt;br /&gt;
Same functions: realfree, t_splay, t_delete, _morecore.&lt;br /&gt;
&lt;br /&gt;
Identical delayed free ring buffer and cleanfree.&lt;br /&gt;
&lt;br /&gt;
Same small-block batching with history bits.&lt;br /&gt;
&lt;br /&gt;
Minor differences: illumos evolved (better thread support, umem alternative); may use mmap for large allocs.&lt;br /&gt;
&lt;br /&gt;
For reimplementation: illumos malloc.c is virtually the same base. Adjust MIPS alignment/constants, ensure exact header layout/macros, preserve delayed free and splay details.&lt;br /&gt;
&lt;br /&gt;
BSD libc (jemalloc or legacy)&lt;br /&gt;
&lt;br /&gt;
More divergent:&lt;br /&gt;
&lt;br /&gt;
Modern FreeBSD/NetBSD use jemalloc (arena-per-thread, red-black trees, extensive caching).&lt;br /&gt;
&lt;br /&gt;
Older BSD had simpler first-fit or dlmalloc-derived.&lt;br /&gt;
&lt;br /&gt;
No splay trees, no delayed free ring, different coalescing.&lt;br /&gt;
&lt;br /&gt;
jemalloc highly tuned for multi-thread, low fragmentation.&lt;br /&gt;
&lt;br /&gt;
For reimplementation: BSD sources less suitable as base; useful for ideas on thread arenas or modern features, but require major rewrite to match IRIX splay/delayed behavior.&lt;br /&gt;
&lt;br /&gt;
Overall, illumos/Solaris-derived malloc is the closest match for direct porting due to shared System V heritage and near-identical internals. Combine with IRIX specifics for exact ABI/behavior replication. Verify against mallint.h equivalents and test with IRIX binaries.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Libc:_doscan&amp;diff=451</id>
		<title>Libc: doscan</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Libc:_doscan&amp;diff=451"/>
		<updated>2025-12-30T18:41:45Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;The _doscan function is the core implementation of formatted input in IRIX libc, serving as the internal routine for the entire scanf family (scanf, fscanf, sscanf, vscanf, etc.). It parses the format string, reads from a FILE * stream (or string via dummy stream for sscanf), matches input against specifiers, skips whitespace as required, and stores converted values via va_list. This decompiled version shows MIPS-specific handling (e.g., conditional long double support i...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The _doscan function is the core implementation of formatted input in IRIX libc, serving as the internal routine for the entire scanf family (scanf, fscanf, sscanf, vscanf, etc.). It parses the format string, reads from a FILE * stream (or string via dummy stream for sscanf), matches input against specifiers, skips whitespace as required, and stores converted values via va_list.&lt;br /&gt;
This decompiled version shows MIPS-specific handling (e.g., conditional long double support in 32-bit ABI), full POSIX positional parameter support, wide-character conversions (%C/%S), and careful stream handling with macros like locgetc/locungetc. It uses a dynamic scratch buffer for numeric parsing, character class tables for %[], and multibyte-to-wide conversion for wide specifiers.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
The implementation features a main parsing loop with helper routines for different conversion types.&lt;br /&gt;
=== Main Entry Point (_doscan) ===&lt;br /&gt;
_doscan validates the stream for readability, initializes positional argument handling if needed, and loops through the format:&lt;br /&gt;
&lt;br /&gt;
Skips whitespace in format and input.&lt;br /&gt;
Handles literal &#039;%&#039; (%%) matching.&lt;br /&gt;
Parses suppression (*), field width, positional ($), length modifiers (h,l,ll,L).&lt;br /&gt;
Dispatches to conversion-specific handlers.&lt;br /&gt;
Returns the number of successful assignments or EOF on error/end-of-input with no matches.&lt;br /&gt;
&lt;br /&gt;
=== Format Parsing and Positional Parameters ===&lt;br /&gt;
Uses charswitch for incremental parsing. Full support for POSIX %n$ positional parameters with fast path via _mkarglst (pre-scans for first 30 args) and fallback va_arg skipping. Same stva_list wrapper as in _doprnt.&lt;br /&gt;
=== String and Character Handling (c, s, [, C, S) ===&lt;br /&gt;
&lt;br /&gt;
string(): Reads characters until whitespace (for %s) or mismatch (for %c/%[). Respects field width; no null-termination for %c.&lt;br /&gt;
wstring(): Wide version using nextwc() for multibyte-to-wide conversion.&lt;br /&gt;
setup(): Builds character class table for %[] (handles ^ negation, ranges like a-z).&lt;br /&gt;
&lt;br /&gt;
=== Integer and Pointer Conversion (d, i, o, u, x, p) ===&lt;br /&gt;
Handled in number(): Collects digits into dynamic scratch buffer, detects base (including 0x auto for %i/%x), handles sign. Uses strtol-like accumulation with careful overflow avoidance. %p treated as hex long.&lt;br /&gt;
=== Floating-Point Conversion (e, E, f, F, g, G) ===&lt;br /&gt;
Collects full numeric string (sign, digits, decimal, exponent) into scratch buffer, then calls atof/atold for conversion. Handles locale decimal point (_numeric[0]). Long double conditional on ABI.&lt;br /&gt;
=== Assignment Count (%n) ===&lt;br /&gt;
Stores characters consumed so far (with h/l/ll modifiers).&lt;br /&gt;
=== Auxiliary and Internal Utilities ===&lt;br /&gt;
&lt;br /&gt;
locgetc/locungetc: Stream-aware get/unget (handles sscanf dummy streams).&lt;br /&gt;
readchar(): Direct read() fallback when buffer empty (non-sscanf).&lt;br /&gt;
nextwc(): Multibyte-to-wide conversion with mbtowc.&lt;br /&gt;
Dynamic scratch buffer (initial 128 bytes, grows by 128) for numeric strings.&lt;br /&gt;
_mkarglst: Pre-scans format to build positional va_list array (assumes uniform pointer size).&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
=== Critical Structures for Compatibility ===&lt;br /&gt;
&lt;br /&gt;
stva_list: Same wrapper as in _doprnt for positional args.&lt;br /&gt;
No special FP union needed (unlike output).&lt;br /&gt;
&lt;br /&gt;
=== Extended Format Specifiers ===&lt;br /&gt;
&lt;br /&gt;
%C / %S: Wide character/string (uppercase, similar to glibc %lc/%ls).&lt;br /&gt;
Full POSIX positional parameters (%n$).&lt;br /&gt;
&lt;br /&gt;
=== Length Modifier Handling ===&lt;br /&gt;
&lt;br /&gt;
In 32-bit ABI, &#039;L&#039; for floating-point defaults to &#039;l&#039; (no quad FP support).&lt;br /&gt;
Uppercase specifiers (E,G,X) converted to lowercase (except C/S); non-floating uppercase treated as &#039;l&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Stream and Locale Integration ===&lt;br /&gt;
&lt;br /&gt;
Uses _numeric[0] for decimal point in floats.&lt;br /&gt;
Multibyte-aware wide conversions.&lt;br /&gt;
Robust EOF handling and character count tracking.&lt;br /&gt;
&lt;br /&gt;
These extend standard scanf with wide support, positional args, and careful sscanf integration while maintaining System V-style internals.&lt;br /&gt;
== Similarities to illumos and BSD libc Implementations ==&lt;br /&gt;
To aid reimplementation using modified illumos or BSD sources, note the strong System V heritage shared with illumos.&lt;br /&gt;
=== illumos libc (__doscan_u / doscan.c) ===&lt;br /&gt;
Very close match (IRIX likely derived from earlier SVR4):&lt;br /&gt;
&lt;br /&gt;
Core function often named _doscan or __doscan_u.&lt;br /&gt;
Identical macros locgetc/locungetc for sscanf handling.&lt;br /&gt;
Dynamic scratch buffer for numbers.&lt;br /&gt;
Character class table (NCHARS) for %[].&lt;br /&gt;
Positional parameter support with similar fast/slow paths.&lt;br /&gt;
Wide handling separate.&lt;br /&gt;
Floating uses atof/strtod family.&lt;br /&gt;
Minor differences: illumos may use strtoll/strtoull directly; locale handling evolved.&lt;br /&gt;
&lt;br /&gt;
For reimplementation: Start with illumos doscan.c (or Solaris-derived forks), add IRIX-specific wide handling (%C/%S via nextwc), match exact positional logic and scratch buffer growth. ABI conditionals for long double easy to adapt.&lt;br /&gt;
=== BSD libc (vfscanf.c / __svfscanf) ===&lt;br /&gt;
More divergent (BSD heritage):&lt;br /&gt;
&lt;br /&gt;
Core is vfscanf or __svfscanf; no _doscan.&lt;br /&gt;
State-machine parsing with explicit conversion types (CT_INT, CT_FLOAT, etc.).&lt;br /&gt;
Fixed-size buffer for floats (often 513); no dynamic scratch.&lt;br /&gt;
No native positional parameters (%n$).&lt;br /&gt;
Advanced locale/xlocale support.&lt;br /&gt;
Floating via custom parsefloat (not atof).&lt;br /&gt;
Wide via %lc/%ls (not %C/%S).&lt;br /&gt;
&lt;br /&gt;
For reimplementation: BSD code is portable and modern but requires adding positional support (port from illumos/IRIX), changing to dynamic buffer, adapting wide specifiers. Less direct match than illumos.&lt;br /&gt;
Overall, illumos/Solaris-derived _doscan is the closest base for porting; combine with IRIX specifics for wide/positional/ABI handling. Verify against sources (e.g., illumos-gate doscan.c equivalents, FreeBSD vfscanf.c).&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Libc:_doprnt&amp;diff=450</id>
		<title>Libc: doprnt</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Libc:_doprnt&amp;diff=450"/>
		<updated>2025-12-30T18:40:45Z</updated>

		<summary type="html">&lt;p&gt;Raion: Initial Commit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The _doprnt function forms the core of the formatted output routines in IRIX libc, serving as the internal implementation for the entire printf family (printf, fprintf, sprintf, vprintf, etc.). It parses the format string, retrieves variable arguments via va_list, converts values according to specifiers, and writes formatted output to a FILE * stream or buffer (with dummy streams used for string variants).&lt;br /&gt;
This decompiled implementation reveals MIPS-specific adaptations for 32-bit and 64-bit ABIs (controlled by _MIPS_SIM macros), support for ANSI C specifiers, POSIX extensions (positional parameters, thousands grouping), and IRIX-specific behaviors (human-readable size formats, detailed NaN printing). It coordinates buffer management, locale-aware grouping, floating-point bit manipulation, and wide-character handling while ensuring efficient output through macros like PUT and PAD.&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
The implementation consists of a main loop with supporting utilities that handle parsing, conversion, and output. Below is a detailed overview of the primary operations and structures.&lt;br /&gt;
=== Main Entry Point (_doprnt) ===&lt;br /&gt;
_doprnt processes the format string in a loop, copying literal text directly and handling &#039;%&#039; specifiers through flag parsing, width/precision extraction, modifier application, and conversion-specific logic. It maintains output count, manages stream buffering via _dowrite, and constructs output components (prefix, padding, value, suffix) before emission. Special handling exists for dummy streams (sprintf family) and flushing on newline or unbuffered/line-buffered modes.&lt;br /&gt;
=== Format Parsing and Flag Management ===&lt;br /&gt;
Flags, width, precision, and modifiers are parsed incrementally using a charswitch loop. Supports standard flags (+, -, space, #, 0), precision (.), width, length modifiers (h, l, ll, L), positional parameters (n$), and dynamic width/precision (*). The apostrophe (&#039;) flag enables thousands grouping via __do_group. Bitmask flagword tracks state for padding, justification, and suffixes.&lt;br /&gt;
=== Integer Conversion (d, i, u, o, x, X, p) ===&lt;br /&gt;
Signed conversions handle negative values with careful overflow avoidance using _lowdigit for minimum integer cases. Digit generation uses table-based division (powers of 10) or bit shifting for non-decimal bases. Optional thousands grouping applies for decimal with &#039; flag. # flag adds prefixes (0 for octal, 0x/0X for hex). Pointers (%p) are treated as hex with length modifier in 64-bit.&lt;br /&gt;
=== Floating-Point Conversion (e, E, f, F, g, G, a/A absent) ===&lt;br /&gt;
Uses ecvt_r/fcvt_r (or quad variants for long double) to obtain mantissa and exponent. Special detection and formatting for Inf (&amp;quot;inf&amp;quot;/&amp;quot;INF&amp;quot;) and NaN (&amp;quot;nan0x&amp;lt;hex&amp;gt;&amp;quot;/&amp;quot;NAN0X&amp;lt;hex&amp;gt;&amp;quot;) via _dval bit fields. Supports # flag for trailing decimal, precision defaults, and exponent formatting. Grouping applies to integral part in fixed formats.&lt;br /&gt;
=== Human-Readable Size Formats (b, B – IRIX-specific) ===&lt;br /&gt;
Divides floating value repeatedly by 1024 (%b) or 1000 (%B), appending suffix (k,m,g,t,p,e,z,y or uppercase). Falls through to %f logic for the numeric part.&lt;br /&gt;
=== String and Character Handling (s, S, c, C) ===&lt;br /&gt;
Narrow strings copy with precision limit; NULL renders as &amp;quot;(null)&amp;quot;. Wide characters/strings use wctomb conversion. Uppercase specifiers handle wide types.&lt;br /&gt;
=== Auxiliary and Internal Utilities ===&lt;br /&gt;
&lt;br /&gt;
_dowrite: Flushes buffer when full, handling read-mode quirks.&lt;br /&gt;
_lowdigit / _lowdigit_l: Safe digit extraction for negative extremes.&lt;br /&gt;
&lt;br /&gt;
decimal_digits_ll / decimal_digits_l: Fast digit count via binary search on power-of-10 tables.&lt;br /&gt;
&lt;br /&gt;
_mkarglst / _getarg: Enable positional parameters with fast path for up to 30 arguments.&lt;br /&gt;
&lt;br /&gt;
__do_group: External locale-aware thousands separator insertion.&lt;br /&gt;
&lt;br /&gt;
==== Macros ====&lt;br /&gt;
&lt;br /&gt;
IsZero(x): Checks if a _dval double is zero, ABI-aware.&lt;br /&gt;
&lt;br /&gt;
PUT(p, n): Writes n bytes from p to the buffer/stream, handling overflow via _dowrite.&lt;br /&gt;
&lt;br /&gt;
PAD(s, n): Pads with string s repeated n times, using _dowrite for large n.&lt;br /&gt;
&lt;br /&gt;
SNLEN = 5: Length for NaN strings (&amp;quot;nan0x&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
NDIG = 82: Buffer size from ecvt.c.&lt;br /&gt;
&lt;br /&gt;
MAXARGS = 30: Max fast positional arguments.&lt;br /&gt;
&lt;br /&gt;
==== Constants and Tables ====&lt;br /&gt;
&lt;br /&gt;
table10_ll[18], table10_l[9]: Powers of 10 for decimal digit counting.&lt;br /&gt;
&lt;br /&gt;
_blanks, _zeroes: Padding strings.&lt;br /&gt;
&lt;br /&gt;
uc_digs, lc_digs: Hex digit tables.&lt;br /&gt;
&lt;br /&gt;
lc_nan = &amp;quot;nan0x&amp;quot;, uc_nan = &amp;quot;NAN0X&amp;quot;: NaN prefixes (IRIX-specific with &amp;quot;0x&amp;quot; for hex payload).&lt;br /&gt;
&lt;br /&gt;
lc_inf = &amp;quot;inf&amp;quot;, uc_inf = &amp;quot;INF&amp;quot;: Infinity strings.&lt;br /&gt;
&lt;br /&gt;
wnull_buf: Wide null string for %S NULL handling.&lt;br /&gt;
&lt;br /&gt;
==== Flags (bit positions) ====&lt;br /&gt;
Defined as bitmasks for format parsing:&lt;br /&gt;
&lt;br /&gt;
LENGTH = 1: &#039;l&#039; modifier.&lt;br /&gt;
&lt;br /&gt;
FPLUS = 2: &#039;+&#039; flag.&lt;br /&gt;
&lt;br /&gt;
FMINUS = 4: &#039;-&#039; flag.&lt;br /&gt;
&lt;br /&gt;
FBLANK = 8: &#039; &#039; flag.&lt;br /&gt;
&lt;br /&gt;
FSHARP = 16: &#039;#&#039; flag.&lt;br /&gt;
&lt;br /&gt;
PADZERO = 32: &#039;0&#039; flag.&lt;br /&gt;
&lt;br /&gt;
DOTSEEN = 64: &#039;.&#039; seen (precision).&lt;br /&gt;
&lt;br /&gt;
SUFFIX = 128: Exponent/suffix needed.&lt;br /&gt;
&lt;br /&gt;
RZERO = 256: Trailing zeros.&lt;br /&gt;
&lt;br /&gt;
LZERO = 512: Leading zeros.&lt;br /&gt;
&lt;br /&gt;
SHORT = 1024: &#039;h&#039; modifier.&lt;br /&gt;
&lt;br /&gt;
LLONG = 2048: &#039;ll&#039; modifier.&lt;br /&gt;
&lt;br /&gt;
LDOUBLE = 4096: &#039;L&#039; modifier.&lt;br /&gt;
&lt;br /&gt;
FQUOTE = 0x10000: &#039;&#039;&#039; (apostrophe) flag for thousands grouping (IRIX/POSIX extension).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are stored in flagword and control output formatting.&lt;br /&gt;
==== Structs and Unions ====&lt;br /&gt;
To ensure ABI compatibility, these must match exactly in any replacement:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;_dval&#039;&#039;&#039;: Union for bit-level access to double. Critical for NaN/Inf detection and floating-point manipulation.&lt;br /&gt;
 typedef union {&lt;br /&gt;
 &lt;br /&gt;
    struct {&lt;br /&gt;
        unsigned sign :1;&lt;br /&gt;
        unsigned exp :11;&lt;br /&gt;
        unsigned hi :20;&lt;br /&gt;
        unsigned lo :32;&lt;br /&gt;
    } fparts;&lt;br /&gt;
 if (_MIPS_SIM != _MIPS_SIM_ABI32)&lt;br /&gt;
    struct {&lt;br /&gt;
        unsigned sign :1;&lt;br /&gt;
        unsigned long long rest :63;&lt;br /&gt;
    } dparts;&lt;br /&gt;
 else&lt;br /&gt;
    struct {&lt;br /&gt;
        unsigned sign :1;&lt;br /&gt;
        unsigned hi :31;&lt;br /&gt;
        unsigned lo :32;&lt;br /&gt;
    } dparts;&lt;br /&gt;
 endif&lt;br /&gt;
    struct {&lt;br /&gt;
        unsigned hi;&lt;br /&gt;
        unsigned lo;&lt;br /&gt;
    } fwords;&lt;br /&gt;
    double d;&lt;br /&gt;
 &lt;br /&gt;
 } _dval;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ABI-specific: In 32-bit ABI (_MIPS_SIM_ABI32), double is split into two 32-bit words. In 64-bit, uses 63-bit rest after sign.&lt;br /&gt;
&lt;br /&gt;
Used with IsNANorINF, IsINF, IsNegNAN, GETNaNPC (from nan.h).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;stva_list&#039;&#039;&#039;: Wrapper for va_list to allow assignment (bypasses C array restrictions).&lt;br /&gt;
 typedef struct stva_list {&lt;br /&gt;
 &lt;br /&gt;
    va_list ap;&lt;br /&gt;
 &lt;br /&gt;
 } stva_list;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Used for positional argument handling in _mkarglst and _getarg.&lt;br /&gt;
&lt;br /&gt;
==== Internal Functions ====&lt;br /&gt;
&lt;br /&gt;
_lowdigit(long long *valptr), _lowdigit_l(long *valptr): Compute low-order decimal digit for negative numbers near overflow, divide by 10.&lt;br /&gt;
_dowrite(const char *p, ssize_t n, FILE *iop, unsigned char **ptrptr): Handles buffer flushing/writing when buffer is full.&lt;br /&gt;
decimal_digits_ll(long long), decimal_digits_l(long): Count decimal digits using binary search on power-of-10 tables.&lt;br /&gt;
__do_group(char *str, double val, int prec, int ndigs, int strsize, int maxfsig): Inserts thousands separators (locale-aware) for &#039;&#039;&#039; flag. (External, not defined here.)&lt;br /&gt;
_mkarglst(char *fmt, stva_list args, stva_list arglst[]): Initializes array of va_list for first MAXARGS positional args.&lt;br /&gt;
_getarg(char *fmt, stva_list *pargs, int argno): Advances va_list for args beyond MAXARGS.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
=== Critical Structures for ABI Compatibility ===&lt;br /&gt;
&lt;br /&gt;
_dval: Union providing bit-field access to double representation. Layout differs by ABI (32-bit splits into two words; 64-bit uses 63-bit mantissa). Essential for NaN/Inf detection and payload extraction.&lt;br /&gt;
&lt;br /&gt;
stva_list: Wrapper around va_list to permit assignment, enabling positional argument array.&lt;br /&gt;
&lt;br /&gt;
=== Extended Format Specifiers ===&lt;br /&gt;
&lt;br /&gt;
%b / %B: Human-readable byte sizes with binary (1024) or decimal (1000) scaling and suffixes.&lt;br /&gt;
&lt;br /&gt;
%C / %S: Wide character/string (equivalent to glibc %lc/%ls). &lt;br /&gt;
&lt;br /&gt;
Apostrophe (&#039;) flag: Thousands grouping in decimal integer and fixed float output (POSIX, locale-aware).&lt;br /&gt;
&lt;br /&gt;
=== NaN and Infinity Representation ===&lt;br /&gt;
&lt;br /&gt;
Infinity: &amp;quot;inf&amp;quot; or &amp;quot;INF&amp;quot;.&lt;br /&gt;
NaN: &amp;quot;nan0x&amp;lt;hex-payload&amp;gt;&amp;quot; or &amp;quot;NAN0X&amp;lt;hex-payload&amp;gt;&amp;quot; – includes significand bits as hex (unique to IRIX/MIPS; most systems omit payload).&lt;br /&gt;
&lt;br /&gt;
=== Positional Parameters (%n$) ===&lt;br /&gt;
Full POSIX support with fast path (pre-scanned array for first 30 arguments) and fallback scanning for higher positions.&lt;br /&gt;
=== Long Double Handling ===&lt;br /&gt;
Conditional on 64-bit ABI; uses separate quad conversion routines and extended precision in grouping.&lt;br /&gt;
=== Buffer and Locale Integration ===&lt;br /&gt;
&lt;br /&gt;
Uses _numeric[0] for decimal point.&lt;br /&gt;
Thousands grouping via external __do_group, supporting locale-specific separators.&lt;br /&gt;
Robust NULL string handling and wide-character conversion.&lt;br /&gt;
&lt;br /&gt;
These behaviors extend standard printf semantics with IRIX-specific formatting, hardware-aware floating-point representation, and efficient positional argument handling while maintaining ABI-critical structure layouts. For replacement implementations, exact matching of _dval layout and NaN printing behavior is required for binary compatibility.&lt;br /&gt;
== Similarities to illumos and BSD libc Implementations ==&lt;br /&gt;
To facilitate reimplementation using modified sources from illumos (OpenSolaris descendant) or BSD libc, note the following shared and divergent aspects based on their printf cores (_doprnt in illumos, vfprintf in BSD).&lt;br /&gt;
=== illumos libc (_doprnt) ===&lt;br /&gt;
As a System V derivative like IRIX, illumos shares significant structural similarities:&lt;br /&gt;
&lt;br /&gt;
Core function name and signature (_doprnt(const char *fmt, va_list ap, FILE *iop)).&lt;br /&gt;
Parsing loop with flagword bitmasks for flags (similar positions for FPLUS, FMINUS, etc.).&lt;br /&gt;
Macros like PUT/PAD for buffered output, _lowdigit for overflow-safe digit extraction.&lt;br /&gt;
Integer handling with power-of-10 tables for fast digit count and generation.&lt;br /&gt;
Floating-point uses ecvt/fcvt (with quad for long double), but NaN/Inf as plain &amp;quot;NaN&amp;quot;/&amp;quot;Inf&amp;quot; without hex payload.&lt;br /&gt;
Positional parameters (%n$) with similar _mkarglst/_getarg logic and MAXARGS limit.&lt;br /&gt;
Apostrophe (&#039;) flag for grouping via external function.&lt;br /&gt;
Wide support (%lc/%ls instead of %C/%S).&lt;br /&gt;
No %b/%B; lacks IRIX-specific human-readable sizes.&lt;br /&gt;
FP union (_ieee_double) similar but not MIPS-ABI-specific; no _dval equivalent.&lt;br /&gt;
&lt;br /&gt;
For reimplementation: Start with illumos _doprnt, port _dval for MIPS ABI, add hex NaN printing using GETNaNPC, implement %b/%B by modifying %f case, match IRIX flags/extensions. Buffer utils (_dowrite) are comparable.&lt;br /&gt;
=== BSD libc (vfprintf) ===&lt;br /&gt;
BSD (FreeBSD/OpenBSD/NetBSD) uses vfprintf as the core, with differences in organization but shared ANSI logic:&lt;br /&gt;
&lt;br /&gt;
Main loop parses format, handles specifiers in switch; flag bits similar but differently named (PF_ prefixes).&lt;br /&gt;
Buffered output via __sprint or similar, with padding functions.&lt;br /&gt;
Integer conversion uses custom loops or strtol; some have bitfield %b (different from IRIX %b).&lt;br /&gt;
Floating-point via gdtoa or dragon4, NaN as &amp;quot;nan&amp;quot;/&amp;quot;inf&amp;quot; (case-sensitive); no hex payload.&lt;br /&gt;
No native positional args (BSD extension in some, but not standard).&lt;br /&gt;
No &#039; flag for grouping; locale support via LC_NUMERIC but not auto-grouping.&lt;br /&gt;
Wide support (%lc/%ls); some BSDs have %C as synonym.&lt;br /&gt;
Extensions like %m (strerror), %D (long), %ll (long long).&lt;br /&gt;
Long double via %Lf; FP handling portable, no ABI-specific unions like _dval.&lt;br /&gt;
&lt;br /&gt;
For reimplementation: BSD vfprintf is less similar due to different architecture (no _doprnt), but floating-point (Inf/NaN) and integer logic can be adapted. Add positional support from illumos/IRIX, modify NaN to include hex, implement IRIX extensions. Buffer management differs but portable.&lt;br /&gt;
Overall, illumos is closer for direct porting due to System V heritage; combine with BSD for modern FP precision if needed. Verify against sources (e.g., illumos-gate doprnt.c, FreeBSD vfprintf.c).&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_Introduction&amp;diff=449</id>
		<title>Kernel: Introduction</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_Introduction&amp;diff=449"/>
		<updated>2025-12-30T02:24:36Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;== Introduction ==  The &amp;#039;&amp;#039;Kernel:&amp;#039;&amp;#039; namespace serves as a comprehensive, community-driven repository for detailed technical documentation of the IRIX kernel, derived from reverse engineering efforts on IRIX 6.5 binaries. This initiative focuses on analyzing, decompiling, and annotating kernel object files to produce high-level, functional descriptions of subsystems, data structures, and behaviors. The documentation is intended to preserve and disseminate deep technic...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;Kernel:&#039;&#039; namespace serves as a comprehensive, community-driven repository for detailed technical documentation of the IRIX kernel, derived from reverse engineering efforts on [[IRIX 6.5]] binaries. This initiative focuses on analyzing, decompiling, and annotating kernel object files to produce high-level, functional descriptions of subsystems, data structures, and behaviors. The documentation is intended to preserve and disseminate deep technical knowledge about IRIX&#039;s unique kernel architecture, which remains largely undocumented outside of original Silicon Graphics sources.&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
The primary goal is to create accurate, readable documentation of IRIX kernel components based on decompiled and extensively commented binary code. This effort emerged in response to the challenges encountered during the IRIX-32 project, where direct access to original source code proved impractical. By leveraging modern reverse engineering tools and AI-assisted analysis, the project aims to produce standalone technical articles that describe kernel functionality without relying on or distributing proprietary source code.&lt;br /&gt;
&lt;br /&gt;
A key operational objective is to maintain clear separation between active IRIX development communities and the volunteer reverse engineering team. This isolation ensures compliance with legal and ethical boundaries while allowing independent progress on documentation.&lt;br /&gt;
&lt;br /&gt;
Ultimately, these articles provide a reliable reference for understanding IRIX kernel internals, supporting historical preservation, academic study, and potential future reimplementations.&lt;br /&gt;
&lt;br /&gt;
=== Rationale ===&lt;br /&gt;
&lt;br /&gt;
IRIX represents a sophisticated UNIX variant optimized for high-performance graphics, scientific computing, and real-time applications on MIPS architecture. Many of its kernel innovations—particularly in virtual memory management, NUMA support, ELF loading, and hardware-specific optimizations—remain poorly documented in public sources. This namespace seeks to fill that gap by systematically documenting subsystems as they existed in IRIX 6.5, the final major release.&lt;br /&gt;
&lt;br /&gt;
The documentation serves as groundwork for skilled developers interested in faithfully reimplementing portions of the IRIX kernel. By providing detailed functional overviews, data structure descriptions, and behavioral analyses derived from binary analysis, it enables clean-room reimplementation efforts without exposure to original source code.&lt;br /&gt;
&lt;br /&gt;
=== Methods ===&lt;br /&gt;
&lt;br /&gt;
Documentation is produced through careful reverse engineering of IRIX 6.5 kernel binaries. Primary tools include:&lt;br /&gt;
&lt;br /&gt;
* Ghidra for disassembly, decompilation, and structural analysis&lt;br /&gt;
* mips2c and related projects for improving decompiler output readability&lt;br /&gt;
* decomp.me for collaborative decompilation matching&lt;br /&gt;
&lt;br /&gt;
All articles are written from decompiled output that has been extensively commented and analyzed by engineers. A strict policy is maintained: no original source code is reproduced or distributed within these pages. Descriptions focus on functional behavior, data flows, and algorithmic logic. Where necessary, function prototypes (names, return types, and parameters) may be included for clarity, but only as derived from binary analysis.&lt;br /&gt;
&lt;br /&gt;
Articles emphasize high-level overviews, key data structures, and IRIX-specific behaviors while highlighting deviations from standard UNIX or SVR4 conventions.&lt;br /&gt;
&lt;br /&gt;
=== Personnel ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Młynar&#039;&#039;&#039; – Documenting Engineer from Politechnika Wrocławska: primary decompiler and commenter responsible for detailed analysis and annotation of kernel objects&lt;br /&gt;
* &#039;&#039;&#039;Yura&#039;&#039;&#039; – Engineer from Shenzhen: supporting documentation and verification. MIPS ASM analysis.&lt;br /&gt;
* &#039;&#039;&#039;Raion&#039;&#039;&#039; – Primary documenter and formatter: article structuring, MediaWiki formatting, and coordination&lt;br /&gt;
&lt;br /&gt;
This volunteer effort combines expertise in MIPS architecture, kernel internals, and reverse engineering to produce accurate technical documentation for the broader IRIX preservation community.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:Virtual_Memory&amp;diff=448</id>
		<title>Kernel:Virtual Memory</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:Virtual_Memory&amp;diff=448"/>
		<updated>2025-12-30T02:14:48Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
The IRIX virtual memory system manages physical and virtual memory resources on MIPS-based Silicon Graphics systems, supporting both 32-bit and 64-bit addressing modes with dynamic switching. It is designed for high-performance computing, graphics, and real-time applications, incorporating SVR4 features like demand paging, memory-mapped I/O (mmap, mprotect), and ELF executables. The system handles anonymous memory (e.g., heap, stack) via tree-based structures for copy-on-write efficiency during forks, and file-backed memory through vnode-integrated page caching. It supports large physical memory (up to 16 GB in later versions), virtual address spaces up to 1 TB per 64-bit process, and NUMA-aware allocation for multiprocessor scalability.&lt;br /&gt;
&lt;br /&gt;
Key aspects include page frame management, swapping to disk, variable page sizes for optimization, memory migration for load balancing, and reverse mapping for efficient invalidation. The VM subsystem integrates with IRIX&#039;s filesystem layers (e.g., XFS, EFS) for unified caching and I/O, and includes real-time enhancements like page locking to minimize latencies. It emphasizes multiprocessor efficiency with fine-grained locking, preemption, and hardware-specific optimizations for MIPS processors (e.g., R8000, R10000).&lt;br /&gt;
&lt;br /&gt;
== Key Components and Flow ==&lt;br /&gt;
&lt;br /&gt;
* **Address Space Management**: Processes operate in user or kernel mode, with virtual addresses mapped to physical memory or swap. User space is segmented (e.g., kuseg for 32-bit: 0-2GB), while kernel accesses extended regions.&lt;br /&gt;
* **Page Frame Data (pfdat)**: Tracks physical pages, including flags for states like hashed, queued, recycled, or bad. Supports replication in NUMA environments.&lt;br /&gt;
* **Anonymous Memory Handling**: Uses binary trees of anon structures for copy-on-write sharing post-fork, with caches for pages (pcache) and swap handles (scache).&lt;br /&gt;
* **File-Backed Caching**: Vnode page cache integrates with filesystems for demand-loaded pages, handling flush, invalidate, and toss operations.&lt;br /&gt;
* **Swapping and Paging**: Manages swap devices (up to 255), demand paging, and precomputation of memory needs (availsmem) for resource-constrained environments.&lt;br /&gt;
* **NUMA and Large Pages**: Node-specific data structures (pgdata, nodepda) for free lists and stats; supports multiple page sizes with coalescing and splitting.&lt;br /&gt;
* **Migration and Mapping**: Page migration for balancing; reverse maps (rmap) for quick invalidation during unmap or protection changes.&lt;br /&gt;
* **Real-Time Features**: Page locking, bounded interrupt latencies, and Miser integration for batch scheduling.&lt;br /&gt;
&lt;br /&gt;
Typical flow: On page fault (vfault/pfault), lookup in caches; if missing, allocate or swap in. Forks duplicate anon trees; exits prune and free resources. Memory pressure triggers swapping, coalescing, or migration.&lt;br /&gt;
&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
&lt;br /&gt;
The VM system comprises operations for memory allocation, mapping, fault handling, and resource management. Below is a detailed functional overview, describing roles, logic, and interactions.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous Memory Initialization and Allocation ===&lt;br /&gt;
Initializes global structures like allocation zones and shared anon lists. Creates new anon handles for regions, setting up locks and caches. Allocates and initializes anon nodes with reference counts and depth hints for tree management.&lt;br /&gt;
&lt;br /&gt;
=== Fork Handling (Duplication) ===&lt;br /&gt;
Duplicates anon structures for child processes, forming or extending binary trees to enable copy-on-write sharing. Allocates new leaf nodes for parent and child, linking them to the original root. Checks for tree depth and prunes if necessary. Reserves resources for potential cache growth.&lt;br /&gt;
&lt;br /&gt;
=== Exit or Region Free (Deallocation) ===&lt;br /&gt;
Disassociates regions from anon memory, removing leaf nodes and freeing pages/swap space. Collapses branches with single children recursively toward the root. Releases locks and nodes when reference counts reach zero.&lt;br /&gt;
&lt;br /&gt;
=== Tree Optimization (Collapse and Prune) ===&lt;br /&gt;
Reduces tree depth by merging parent-child pairs when one child is absent, transferring pages and swap handles. Selects survivor based on page count; discards covered pages. Prunes empty intermediate nodes with no pages/swap to prevent unbounded growth in long-lived forking processes.&lt;br /&gt;
&lt;br /&gt;
=== Page Insertion into Anon ===&lt;br /&gt;
Adds pages to leaf node caches, covering lower tree levels if needed. Ensures no duplicates; handles potential cache resizing.&lt;br /&gt;
&lt;br /&gt;
=== Page Modification Handling ===&lt;br /&gt;
Determines copy or steal for writes: Copies for shared or non-top-level pages; steals otherwise, clearing swap info and rehashing to top level. Heuristics for caching swapped pages when memory is abundant.&lt;br /&gt;
&lt;br /&gt;
=== Swap Handle Management ===&lt;br /&gt;
Merges or clears swap handles during collapses; transfers non-covered handles to survivors.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Cache Initialization ===&lt;br /&gt;
Sets up per-vnode caches during allocation or recycling, initializing hash structures and reference counts.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Lookup and Attachment ===&lt;br /&gt;
Searches caches for pages by logical number; attaches by incrementing use counts, resolving races with allocation/recycling.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Insertion ===&lt;br /&gt;
Adds pages to caches, resizing if needed; supports conditional insertion to handle races, freeing duplicates.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Removal and Invalidation ===&lt;br /&gt;
Removes pages from caches, marking bad or requeuing free; flushes/invalidates ranges, tossing to buffers if needed.&lt;br /&gt;
&lt;br /&gt;
=== Page Recycling and Migration ===&lt;br /&gt;
Recycles pages for reuse, removing from caches; migrates by copying state to new frames, updating caches atomically.&lt;br /&gt;
&lt;br /&gt;
=== Memory Requirement Estimation ===&lt;br /&gt;
Precomputes swap/memory needs for operations, caching for runtime linker and batch jobs.&lt;br /&gt;
&lt;br /&gt;
=== Hardware Workaround Checks ===&lt;br /&gt;
Scans for CPU errata indicators, flagging proxy use for instruction rewriting in executable pages.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
&lt;br /&gt;
=== Anonymous Memory Tree Structures ===&lt;br /&gt;
Binary trees of anon nodes for efficient copy-on-write: Leaves represent process-private pages; internal nodes share via parents. Depth hints and pruning thresholds (e.g., PRUNE_THRESHOLD) prevent degradation in forking servers. Covered pages discarded during merges; swap caches (scache) track out-of-memory handles.&lt;br /&gt;
&lt;br /&gt;
=== Shared Anonymous Pages (sanon) ===&lt;br /&gt;
Special lists for unreferenced, dirty, shared anon pages (psanonmem counter). Node-specific free lists with locks; removal macros handle MP races.&lt;br /&gt;
&lt;br /&gt;
=== Page and Swap Caches (pcache/scache) ===&lt;br /&gt;
Dual caches per anon/vnode: pcache hashes in-memory pages; scache manages swap handles for faulted-out pages. Dynamic resizing, preemption during long operations. Undocumented tokens for space reservation.&lt;br /&gt;
&lt;br /&gt;
=== Memory Reservation (availsmem) ===&lt;br /&gt;
Precomputes and reserves physical/swap memory for execs/forks, integrated with Miser for batch retries (EMEMRETRY). Global caching for runtime components.&lt;br /&gt;
&lt;br /&gt;
=== NUMA-Aware Data Structures ===&lt;br /&gt;
Per-node pgdata for free lists, stats, and rotors; nodepda integration for allocation. Large page (lpage) support with coalescing daemons, splitting, and stats (e.g., vfault/pfault retries by size).&lt;br /&gt;
&lt;br /&gt;
=== Page Migration and Reverse Mapping ===&lt;br /&gt;
Migr subsystem for NUMA balancing; rmap for efficient TLB shootdowns and unmaps. Pagemigr transfers states, handling object mutations.&lt;br /&gt;
&lt;br /&gt;
=== Hardware and Real-Time Extensions ===&lt;br /&gt;
Flags for MIPS errata (e.g., R5000 CVT, TFP prefetch); mtext proxies for instruction patching. Page locking for real-time, bounded latencies, and VCE avoidance for cache coloring.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Cache Synchronization ===&lt;br /&gt;
Reference counting (v_pcacheref) with wait bits for reclaim coordination; broadcast on zero refs. Integration with DMAPI, ShareII for extended file ops.&lt;br /&gt;
&lt;br /&gt;
These extend standard UNIX VM with SGI-specific optimizations for MIPS, NUMA, graphics, and HPC, emphasizing scalability and reliability.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:Virtual_Memory&amp;diff=447</id>
		<title>Kernel:Virtual Memory</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:Virtual_Memory&amp;diff=447"/>
		<updated>2025-12-30T02:14:30Z</updated>

		<summary type="html">&lt;p&gt;Raion: Initial Commit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{KernelNav}}&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The IRIX virtual memory system manages physical and virtual memory resources on MIPS-based Silicon Graphics systems, supporting both 32-bit and 64-bit addressing modes with dynamic switching. It is designed for high-performance computing, graphics, and real-time applications, incorporating SVR4 features like demand paging, memory-mapped I/O (mmap, mprotect), and ELF executables. The system handles anonymous memory (e.g., heap, stack) via tree-based structures for copy-on-write efficiency during forks, and file-backed memory through vnode-integrated page caching. It supports large physical memory (up to 16 GB in later versions), virtual address spaces up to 1 TB per 64-bit process, and NUMA-aware allocation for multiprocessor scalability.&lt;br /&gt;
&lt;br /&gt;
Key aspects include page frame management, swapping to disk, variable page sizes for optimization, memory migration for load balancing, and reverse mapping for efficient invalidation. The VM subsystem integrates with IRIX&#039;s filesystem layers (e.g., XFS, EFS) for unified caching and I/O, and includes real-time enhancements like page locking to minimize latencies. It emphasizes multiprocessor efficiency with fine-grained locking, preemption, and hardware-specific optimizations for MIPS processors (e.g., R8000, R10000).&lt;br /&gt;
&lt;br /&gt;
== Key Components and Flow ==&lt;br /&gt;
&lt;br /&gt;
* **Address Space Management**: Processes operate in user or kernel mode, with virtual addresses mapped to physical memory or swap. User space is segmented (e.g., kuseg for 32-bit: 0-2GB), while kernel accesses extended regions.&lt;br /&gt;
* **Page Frame Data (pfdat)**: Tracks physical pages, including flags for states like hashed, queued, recycled, or bad. Supports replication in NUMA environments.&lt;br /&gt;
* **Anonymous Memory Handling**: Uses binary trees of anon structures for copy-on-write sharing post-fork, with caches for pages (pcache) and swap handles (scache).&lt;br /&gt;
* **File-Backed Caching**: Vnode page cache integrates with filesystems for demand-loaded pages, handling flush, invalidate, and toss operations.&lt;br /&gt;
* **Swapping and Paging**: Manages swap devices (up to 255), demand paging, and precomputation of memory needs (availsmem) for resource-constrained environments.&lt;br /&gt;
* **NUMA and Large Pages**: Node-specific data structures (pgdata, nodepda) for free lists and stats; supports multiple page sizes with coalescing and splitting.&lt;br /&gt;
* **Migration and Mapping**: Page migration for balancing; reverse maps (rmap) for quick invalidation during unmap or protection changes.&lt;br /&gt;
* **Real-Time Features**: Page locking, bounded interrupt latencies, and Miser integration for batch scheduling.&lt;br /&gt;
&lt;br /&gt;
Typical flow: On page fault (vfault/pfault), lookup in caches; if missing, allocate or swap in. Forks duplicate anon trees; exits prune and free resources. Memory pressure triggers swapping, coalescing, or migration.&lt;br /&gt;
&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
&lt;br /&gt;
The VM system comprises operations for memory allocation, mapping, fault handling, and resource management. Below is a detailed functional overview, describing roles, logic, and interactions.&lt;br /&gt;
&lt;br /&gt;
=== Anonymous Memory Initialization and Allocation ===&lt;br /&gt;
Initializes global structures like allocation zones and shared anon lists. Creates new anon handles for regions, setting up locks and caches. Allocates and initializes anon nodes with reference counts and depth hints for tree management.&lt;br /&gt;
&lt;br /&gt;
=== Fork Handling (Duplication) ===&lt;br /&gt;
Duplicates anon structures for child processes, forming or extending binary trees to enable copy-on-write sharing. Allocates new leaf nodes for parent and child, linking them to the original root. Checks for tree depth and prunes if necessary. Reserves resources for potential cache growth.&lt;br /&gt;
&lt;br /&gt;
=== Exit or Region Free (Deallocation) ===&lt;br /&gt;
Disassociates regions from anon memory, removing leaf nodes and freeing pages/swap space. Collapses branches with single children recursively toward the root. Releases locks and nodes when reference counts reach zero.&lt;br /&gt;
&lt;br /&gt;
=== Tree Optimization (Collapse and Prune) ===&lt;br /&gt;
Reduces tree depth by merging parent-child pairs when one child is absent, transferring pages and swap handles. Selects survivor based on page count; discards covered pages. Prunes empty intermediate nodes with no pages/swap to prevent unbounded growth in long-lived forking processes.&lt;br /&gt;
&lt;br /&gt;
=== Page Insertion into Anon ===&lt;br /&gt;
Adds pages to leaf node caches, covering lower tree levels if needed. Ensures no duplicates; handles potential cache resizing.&lt;br /&gt;
&lt;br /&gt;
=== Page Modification Handling ===&lt;br /&gt;
Determines copy or steal for writes: Copies for shared or non-top-level pages; steals otherwise, clearing swap info and rehashing to top level. Heuristics for caching swapped pages when memory is abundant.&lt;br /&gt;
&lt;br /&gt;
=== Swap Handle Management ===&lt;br /&gt;
Merges or clears swap handles during collapses; transfers non-covered handles to survivors.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Cache Initialization ===&lt;br /&gt;
Sets up per-vnode caches during allocation or recycling, initializing hash structures and reference counts.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Lookup and Attachment ===&lt;br /&gt;
Searches caches for pages by logical number; attaches by incrementing use counts, resolving races with allocation/recycling.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Insertion ===&lt;br /&gt;
Adds pages to caches, resizing if needed; supports conditional insertion to handle races, freeing duplicates.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Page Removal and Invalidation ===&lt;br /&gt;
Removes pages from caches, marking bad or requeuing free; flushes/invalidates ranges, tossing to buffers if needed.&lt;br /&gt;
&lt;br /&gt;
=== Page Recycling and Migration ===&lt;br /&gt;
Recycles pages for reuse, removing from caches; migrates by copying state to new frames, updating caches atomically.&lt;br /&gt;
&lt;br /&gt;
=== Memory Requirement Estimation ===&lt;br /&gt;
Precomputes swap/memory needs for operations, caching for runtime linker and batch jobs.&lt;br /&gt;
&lt;br /&gt;
=== Hardware Workaround Checks ===&lt;br /&gt;
Scans for CPU errata indicators, flagging proxy use for instruction rewriting in executable pages.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
&lt;br /&gt;
=== Anonymous Memory Tree Structures ===&lt;br /&gt;
Binary trees of anon nodes for efficient copy-on-write: Leaves represent process-private pages; internal nodes share via parents. Depth hints and pruning thresholds (e.g., PRUNE_THRESHOLD) prevent degradation in forking servers. Covered pages discarded during merges; swap caches (scache) track out-of-memory handles.&lt;br /&gt;
&lt;br /&gt;
=== Shared Anonymous Pages (sanon) ===&lt;br /&gt;
Special lists for unreferenced, dirty, shared anon pages (psanonmem counter). Node-specific free lists with locks; removal macros handle MP races.&lt;br /&gt;
&lt;br /&gt;
=== Page and Swap Caches (pcache/scache) ===&lt;br /&gt;
Dual caches per anon/vnode: pcache hashes in-memory pages; scache manages swap handles for faulted-out pages. Dynamic resizing, preemption during long operations. Undocumented tokens for space reservation.&lt;br /&gt;
&lt;br /&gt;
=== Memory Reservation (availsmem) ===&lt;br /&gt;
Precomputes and reserves physical/swap memory for execs/forks, integrated with Miser for batch retries (EMEMRETRY). Global caching for runtime components.&lt;br /&gt;
&lt;br /&gt;
=== NUMA-Aware Data Structures ===&lt;br /&gt;
Per-node pgdata for free lists, stats, and rotors; nodepda integration for allocation. Large page (lpage) support with coalescing daemons, splitting, and stats (e.g., vfault/pfault retries by size).&lt;br /&gt;
&lt;br /&gt;
=== Page Migration and Reverse Mapping ===&lt;br /&gt;
Migr subsystem for NUMA balancing; rmap for efficient TLB shootdowns and unmaps. Pagemigr transfers states, handling object mutations.&lt;br /&gt;
&lt;br /&gt;
=== Hardware and Real-Time Extensions ===&lt;br /&gt;
Flags for MIPS errata (e.g., R5000 CVT, TFP prefetch); mtext proxies for instruction patching. Page locking for real-time, bounded latencies, and VCE avoidance for cache coloring.&lt;br /&gt;
&lt;br /&gt;
=== Vnode Cache Synchronization ===&lt;br /&gt;
Reference counting (v_pcacheref) with wait bits for reclaim coordination; broadcast on zero refs. Integration with DMAPI, ShareII for extended file ops.&lt;br /&gt;
&lt;br /&gt;
These extend standard UNIX VM with SGI-specific optimizations for MIPS, NUMA, graphics, and HPC, emphasizing scalability and reliability.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_ELF_Loader&amp;diff=446</id>
		<title>Kernel: ELF Loader</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_ELF_Loader&amp;diff=446"/>
		<updated>2025-12-30T01:59:54Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Overview ==&lt;br /&gt;
&lt;br /&gt;
The IRIX kernel&#039;s ELF loader manages the execution of ELF-format binaries on MIPS-based systems, accommodating 32-bit and 64-bit architectures along with multiple ABIs. It performs tasks such as validating file headers, preparing the user stack and arguments, mapping memory segments, handling dynamic linking, and applying hardware-specific adjustments. Integration with kernel components like address space handling, virtual memory allocation, process control, and resource management ensures efficient and reliable execution.&lt;br /&gt;
&lt;br /&gt;
The loader supports ABI transitions during execution, resource pre-allocation for constrained environments, and extensions for MIPS hardware errata. It processes both static and dynamic executables, coordinating with the runtime linker for shared libraries.&lt;br /&gt;
&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
&lt;br /&gt;
The loader comprises several core operations that orchestrate the execution process. Below is a detailed functional overview of these operations, describing their roles, inputs, logic, and outputs.&lt;br /&gt;
&lt;br /&gt;
=== Header Retrieval and Validation ===&lt;br /&gt;
&lt;br /&gt;
This function reads the ELF header and program headers from the executable file. It validates essential fields such as the magic number, class (32-bit or 64-bit), data encoding, file type (executable or dynamic), and MIPS-specific architecture flags. It determines the ABI version based on machine type and flags, ensuring compatibility with the system&#039;s capabilities. On success, it provides the parsed headers for further processing; failures result in errors like invalid executable format or bad request due to unsupported architecture.&lt;br /&gt;
&lt;br /&gt;
=== ELF Execution Dispatch ===&lt;br /&gt;
&lt;br /&gt;
The primary entry point for ELF binary execution dispatches based on the file&#039;s class to handle 32-bit or 64-bit specifics. It retrieves headers, scans program headers for dynamic linking indicators, auxiliary setup needs, and hardware options. It calculates auxiliary vector size, allocates kernel space for argument building, constructs the user stack, and reserves memory resources if required for batch processing. The process splits to manage stack usage, proceeding to image removal and new address space creation. Errors lead to cleanup and restoration of original state.&lt;br /&gt;
&lt;br /&gt;
=== Execution Completion ===&lt;br /&gt;
&lt;br /&gt;
Continuing from the dispatch, this phase removes the existing process image, creates a new address space with affinity considerations, and maps segments. For dynamic binaries, it loads the runtime linker, builds extended auxiliary vectors, and sets up the stack with execution parameters. It configures registers, including floating-point unit settings based on architecture, and transfers control to the entry point. Failures trigger process termination with detailed logging.&lt;br /&gt;
&lt;br /&gt;
=== Segment Mapping ===&lt;br /&gt;
&lt;br /&gt;
This operation maps ELF segments into the address space, focusing on loadable sections. It computes protections (read, write, execute) and flags (local mapping, heap consideration), handles zero-fill regions, and applies workarounds for hardware issues in executable pages. It identifies special program headers for dynamic linking, shared libraries, and options. Mapping occurs with file-backed regions, supporting checkpointing. Errors include memory shortages or invalid segment orders.&lt;br /&gt;
&lt;br /&gt;
=== Dynamic Shared Object Mapping ===&lt;br /&gt;
&lt;br /&gt;
Accessible from user space, this function maps segments for shared objects, typically invoked by the runtime linker. It validates file descriptors and permissions, copies program headers from user space, and performs mappings with potential workarounds. On memory errors, it attempts relocation to an alternate address range. Success returns the base address; failures unmap partial allocations.&lt;br /&gt;
&lt;br /&gt;
=== Memory Requirement Calculation ===&lt;br /&gt;
&lt;br /&gt;
These utilities estimate the physical memory needed for execution, summing requirements for writable segments, the user stack, and the runtime linker. Computations account for page alignments and cache results for repeated use, updating on file changes. This supports early reservation in resource-managed environments, preventing failures during critical phases.&lt;br /&gt;
&lt;br /&gt;
=== Hardware Workaround Check ===&lt;br /&gt;
&lt;br /&gt;
For specific CPU errata, this checks program headers for cleanliness indicators regarding problematic instructions. If needed, it flags the use of proxy mechanisms during mapping to mitigate issues in read-only executable regions.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
&lt;br /&gt;
=== MIPS Hardware Workarounds in PT_MIPS_OPTIONS ===&lt;br /&gt;
&lt;br /&gt;
IRIX scans PT_MIPS_OPTIONS sections for hardware patch flags:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;OHW_R5KCVTL&#039;&#039;&#039; (0x8): Indicates the binary is clean of the R5000 cvt.[ds].l bug. If absent on affected CPUs (with &#039;&#039;R5000_cvt_war&#039;&#039; enabled, typically n32/n64 ABIs), the kernel uses the &#039;&#039;mtext&#039;&#039; subsystem (proxy vnodes) to rewrite problematic instructions in read-only executable pages during mapping.&lt;br /&gt;
* &#039;&#039;&#039;OHW_R8KPFETCH&#039;&#039;&#039; (TFP_PREFETCH_WAR): On TFP (R8000) CPUs, non-dynamic MIPS4 binaries with prefetch instructions are rejected (EBADRQC) unless &#039;&#039;chk_ohw_r8kpfetch&#039;&#039; is non-zero. For dynamic binaries, the kernel sets a flag to add &#039;&#039;&#039;AT_PFETCHFD&#039;&#039;&#039; to auxv (see below).&lt;br /&gt;
&lt;br /&gt;
These flags trigger kernel-level instruction patching or rejection, not documented in public ELF ABI supplements.&lt;br /&gt;
&lt;br /&gt;
=== Extended Auxiliary Vector Entries ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;AT_PFETCHFD&#039;&#039;&#039;: Provides an open file descriptor to the executable for the runtime linker (rld) to apply prefetch instruction patches (no-ops) on TFP systems. Added when a dynamic binary requires the prefetch workaround.&lt;br /&gt;
&lt;br /&gt;
Standard auxv entries (AT_PHDR, AT_BASE, etc.) are used, but AT_PFETCHFD is an IRIX-specific extension.&lt;br /&gt;
&lt;br /&gt;
=== Memory Reservation (availsmem) for Exec ===&lt;br /&gt;
&lt;br /&gt;
* Functions &#039;&#039;elf_compute_availsmem&#039;&#039; and &#039;&#039;elf_get_availsmem&#039;&#039; precompute physical memory needs for writable segments (PF_W in PT_LOAD), user stack, and the runtime linker.&lt;br /&gt;
* Cached globally in &#039;&#039;runtime_loader_availsmem&#039;&#039; (recomputed if the runtime linker&#039;s vnode changes).&lt;br /&gt;
* For Miser batch jobs, reserves memory early via &#039;&#039;vm_pool_exec_reservemem&#039;&#039;; failure returns EMEMRETRY for retry.&lt;br /&gt;
&lt;br /&gt;
This mechanism prevents mid-exec failures in memory-constrained environments.&lt;br /&gt;
&lt;br /&gt;
=== Mapping Interfaces ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;execmap&#039;&#039; / &#039;&#039;mtext_execmap_vnode&#039;&#039;: Low-level mapping of file-backed regions with ZFOD, protections, and flags (e.g., MAP_LOCAL, MAP_BRK, MAP_PRIMARY).&lt;br /&gt;
* &#039;&#039;elfmap&#039;&#039;: User-called (from rld) to map DSO PT_LOAD segments. Supports alternate address relocation on ENOMEM by finding a free range and adjusting vaddrs.&lt;br /&gt;
* Integration with checkpointing (ckpt handles passed to mapping calls).&lt;br /&gt;
&lt;br /&gt;
=== Other Internal Behaviors ===&lt;br /&gt;
&lt;br /&gt;
* ABI transition handling: Temporarily sets process ABI proxy during exec; resets on failure.&lt;br /&gt;
* NUMA/affinity: New address space creation via &#039;&#039;aspm_exec_create&#039;&#039; and affinity link setup.&lt;br /&gt;
* FPU flags from PT_MIPS_OPTIONS (ODK_EXCEPTIONS): Sets precise exceptions or speculative mode in process FP flags.&lt;br /&gt;
* Runtime linker loading: Caches availsmem needs; sticky bit (VSVTX) on rld allows saving pregions.&lt;br /&gt;
* Error reporting: Detailed kill messages with reason codes for failed execs.&lt;br /&gt;
&lt;br /&gt;
These features extend standard ELF handling with IRIX-specific resource management, hardware errata mitigation, and kernel-runtime linker coordination.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_ELF_Loader&amp;diff=445</id>
		<title>Kernel: ELF Loader</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_ELF_Loader&amp;diff=445"/>
		<updated>2025-12-30T01:59:35Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;{{KernelNav}}  == Overview ==  The IRIX kernel&amp;#039;s ELF loader manages the execution of ELF-format binaries on MIPS-based systems, accommodating 32-bit and 64-bit architectures along with multiple ABIs. It performs tasks such as validating file headers, preparing the user stack and arguments, mapping memory segments, handling dynamic linking, and applying hardware-specific adjustments. Integration with kernel components like address space handling, virtual memory allocation...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{KernelNav}}&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The IRIX kernel&#039;s ELF loader manages the execution of ELF-format binaries on MIPS-based systems, accommodating 32-bit and 64-bit architectures along with multiple ABIs. It performs tasks such as validating file headers, preparing the user stack and arguments, mapping memory segments, handling dynamic linking, and applying hardware-specific adjustments. Integration with kernel components like address space handling, virtual memory allocation, process control, and resource management ensures efficient and reliable execution.&lt;br /&gt;
&lt;br /&gt;
The loader supports ABI transitions during execution, resource pre-allocation for constrained environments, and extensions for MIPS hardware errata. It processes both static and dynamic executables, coordinating with the runtime linker for shared libraries.&lt;br /&gt;
&lt;br /&gt;
== Key Functions ==&lt;br /&gt;
&lt;br /&gt;
The loader comprises several core operations that orchestrate the execution process. Below is a detailed functional overview of these operations, describing their roles, inputs, logic, and outputs.&lt;br /&gt;
&lt;br /&gt;
=== Header Retrieval and Validation ===&lt;br /&gt;
&lt;br /&gt;
This function reads the ELF header and program headers from the executable file. It validates essential fields such as the magic number, class (32-bit or 64-bit), data encoding, file type (executable or dynamic), and MIPS-specific architecture flags. It determines the ABI version based on machine type and flags, ensuring compatibility with the system&#039;s capabilities. On success, it provides the parsed headers for further processing; failures result in errors like invalid executable format or bad request due to unsupported architecture.&lt;br /&gt;
&lt;br /&gt;
=== ELF Execution Dispatch ===&lt;br /&gt;
&lt;br /&gt;
The primary entry point for ELF binary execution dispatches based on the file&#039;s class to handle 32-bit or 64-bit specifics. It retrieves headers, scans program headers for dynamic linking indicators, auxiliary setup needs, and hardware options. It calculates auxiliary vector size, allocates kernel space for argument building, constructs the user stack, and reserves memory resources if required for batch processing. The process splits to manage stack usage, proceeding to image removal and new address space creation. Errors lead to cleanup and restoration of original state.&lt;br /&gt;
&lt;br /&gt;
=== Execution Completion ===&lt;br /&gt;
&lt;br /&gt;
Continuing from the dispatch, this phase removes the existing process image, creates a new address space with affinity considerations, and maps segments. For dynamic binaries, it loads the runtime linker, builds extended auxiliary vectors, and sets up the stack with execution parameters. It configures registers, including floating-point unit settings based on architecture, and transfers control to the entry point. Failures trigger process termination with detailed logging.&lt;br /&gt;
&lt;br /&gt;
=== Segment Mapping ===&lt;br /&gt;
&lt;br /&gt;
This operation maps ELF segments into the address space, focusing on loadable sections. It computes protections (read, write, execute) and flags (local mapping, heap consideration), handles zero-fill regions, and applies workarounds for hardware issues in executable pages. It identifies special program headers for dynamic linking, shared libraries, and options. Mapping occurs with file-backed regions, supporting checkpointing. Errors include memory shortages or invalid segment orders.&lt;br /&gt;
&lt;br /&gt;
=== Dynamic Shared Object Mapping ===&lt;br /&gt;
&lt;br /&gt;
Accessible from user space, this function maps segments for shared objects, typically invoked by the runtime linker. It validates file descriptors and permissions, copies program headers from user space, and performs mappings with potential workarounds. On memory errors, it attempts relocation to an alternate address range. Success returns the base address; failures unmap partial allocations.&lt;br /&gt;
&lt;br /&gt;
=== Memory Requirement Calculation ===&lt;br /&gt;
&lt;br /&gt;
These utilities estimate the physical memory needed for execution, summing requirements for writable segments, the user stack, and the runtime linker. Computations account for page alignments and cache results for repeated use, updating on file changes. This supports early reservation in resource-managed environments, preventing failures during critical phases.&lt;br /&gt;
&lt;br /&gt;
=== Hardware Workaround Check ===&lt;br /&gt;
&lt;br /&gt;
For specific CPU errata, this checks program headers for cleanliness indicators regarding problematic instructions. If needed, it flags the use of proxy mechanisms during mapping to mitigate issues in read-only executable regions.&lt;br /&gt;
&lt;br /&gt;
== Undocumented or IRIX-Specific Interfaces and Behaviors ==&lt;br /&gt;
&lt;br /&gt;
=== MIPS Hardware Workarounds in PT_MIPS_OPTIONS ===&lt;br /&gt;
&lt;br /&gt;
IRIX scans PT_MIPS_OPTIONS sections for hardware patch flags:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;OHW_R5KCVTL&#039;&#039;&#039; (0x8): Indicates the binary is clean of the R5000 cvt.[ds].l bug. If absent on affected CPUs (with &#039;&#039;R5000_cvt_war&#039;&#039; enabled, typically n32/n64 ABIs), the kernel uses the &#039;&#039;mtext&#039;&#039; subsystem (proxy vnodes) to rewrite problematic instructions in read-only executable pages during mapping.&lt;br /&gt;
* &#039;&#039;&#039;OHW_R8KPFETCH&#039;&#039;&#039; (TFP_PREFETCH_WAR): On TFP (R8000) CPUs, non-dynamic MIPS4 binaries with prefetch instructions are rejected (EBADRQC) unless &#039;&#039;chk_ohw_r8kpfetch&#039;&#039; is non-zero. For dynamic binaries, the kernel sets a flag to add &#039;&#039;&#039;AT_PFETCHFD&#039;&#039;&#039; to auxv (see below).&lt;br /&gt;
&lt;br /&gt;
These flags trigger kernel-level instruction patching or rejection, not documented in public ELF ABI supplements.&lt;br /&gt;
&lt;br /&gt;
=== Extended Auxiliary Vector Entries ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;AT_PFETCHFD&#039;&#039;&#039;: Provides an open file descriptor to the executable for the runtime linker (rld) to apply prefetch instruction patches (no-ops) on TFP systems. Added when a dynamic binary requires the prefetch workaround.&lt;br /&gt;
&lt;br /&gt;
Standard auxv entries (AT_PHDR, AT_BASE, etc.) are used, but AT_PFETCHFD is an IRIX-specific extension.&lt;br /&gt;
&lt;br /&gt;
=== Memory Reservation (availsmem) for Exec ===&lt;br /&gt;
&lt;br /&gt;
* Functions &#039;&#039;elf_compute_availsmem&#039;&#039; and &#039;&#039;elf_get_availsmem&#039;&#039; precompute physical memory needs for writable segments (PF_W in PT_LOAD), user stack, and the runtime linker.&lt;br /&gt;
* Cached globally in &#039;&#039;runtime_loader_availsmem&#039;&#039; (recomputed if the runtime linker&#039;s vnode changes).&lt;br /&gt;
* For Miser batch jobs, reserves memory early via &#039;&#039;vm_pool_exec_reservemem&#039;&#039;; failure returns EMEMRETRY for retry.&lt;br /&gt;
&lt;br /&gt;
This mechanism prevents mid-exec failures in memory-constrained environments.&lt;br /&gt;
&lt;br /&gt;
=== Mapping Interfaces ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;execmap&#039;&#039; / &#039;&#039;mtext_execmap_vnode&#039;&#039;: Low-level mapping of file-backed regions with ZFOD, protections, and flags (e.g., MAP_LOCAL, MAP_BRK, MAP_PRIMARY).&lt;br /&gt;
* &#039;&#039;elfmap&#039;&#039;: User-called (from rld) to map DSO PT_LOAD segments. Supports alternate address relocation on ENOMEM by finding a free range and adjusting vaddrs.&lt;br /&gt;
* Integration with checkpointing (ckpt handles passed to mapping calls).&lt;br /&gt;
&lt;br /&gt;
=== Other Internal Behaviors ===&lt;br /&gt;
&lt;br /&gt;
* ABI transition handling: Temporarily sets process ABI proxy during exec; resets on failure.&lt;br /&gt;
* NUMA/affinity: New address space creation via &#039;&#039;aspm_exec_create&#039;&#039; and affinity link setup.&lt;br /&gt;
* FPU flags from PT_MIPS_OPTIONS (ODK_EXCEPTIONS): Sets precise exceptions or speculative mode in process FP flags.&lt;br /&gt;
* Runtime linker loading: Caches availsmem needs; sticky bit (VSVTX) on rld allows saving pregions.&lt;br /&gt;
* Error reporting: Detailed kill messages with reason codes for failed execs.&lt;br /&gt;
&lt;br /&gt;
These features extend standard ELF handling with IRIX-specific resource management, hardware errata mitigation, and kernel-runtime linker coordination.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_malloc&amp;diff=444</id>
		<title>Kernel: malloc</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_malloc&amp;diff=444"/>
		<updated>2025-12-29T20:54:11Z</updated>

		<summary type="html">&lt;p&gt;Raion: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page documents the memory allocation subsystem of the IRIX kernel (`malloc`, `rmalloc`, and related functions) as implemented in the IRIX kernel. It is intended as a functional reference for reimplementation in other kernels (e.g., Illumos).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The IRIX memory allocation system provides:&lt;br /&gt;
&lt;br /&gt;
* Map-based memory management (`struct map`) for contiguous resource allocation.&lt;br /&gt;
* Page-aligned and color-aware allocations for cache efficiency (R4000-specific).&lt;br /&gt;
* Bitmap-based system page table (SPT) management.&lt;br /&gt;
* Waiting and non-waiting allocation paths (`VM_NOSLEEP` flag).&lt;br /&gt;
* Synchronization primitives using spinlocks and semaphores.&lt;br /&gt;
&lt;br /&gt;
Memory management in IRIX is based on two concepts:&lt;br /&gt;
&lt;br /&gt;
# **Maps** – contiguous resources tracked as a list of free/allocated blocks.&lt;br /&gt;
# **Bitmaps** – finer-grained allocation (e.g., pages, cache-colored pages) with alignment support.&lt;br /&gt;
&lt;br /&gt;
== Map Allocation API ==&lt;br /&gt;
&lt;br /&gt;
=== rmallocmap() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate and initialize a `struct map` for tracking resources.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039; `mapsiz` – number of entries in the map.  &lt;br /&gt;
&#039;&#039;&#039;Outputs:&#039;&#039;&#039; Pointer to newly allocated map, or NULL on failure.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Allocates memory for `mapsiz + 2` map entries.&lt;br /&gt;
* Allocates and initializes a synchronization structure (`lock + semaphore`).&lt;br /&gt;
* Stores pointers to synchronization primitives in the second map entry.&lt;br /&gt;
* Returns a fully initialized map ready for allocations.&lt;br /&gt;
&lt;br /&gt;
=== rmfreemap() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free a previously allocated map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039; Pointer to map.  &lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Waits for any threads currently blocked on the map.&lt;br /&gt;
* Destroys associated semaphore and spinlock.&lt;br /&gt;
* Frees both the map memory and the synchronization structure.&lt;br /&gt;
&lt;br /&gt;
=== malloc / malloc_wait / rmalloc / rmalloc_wait ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate contiguous units from a map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `mp` – pointer to map&lt;br /&gt;
* `size` – number of units&lt;br /&gt;
* Optional `flags` (`VM_NOSLEEP` for non-blocking)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Uses **first-fit allocation**.&lt;br /&gt;
* Non-blocking (`VM_NOSLEEP`) returns `0` if allocation fails.&lt;br /&gt;
* Blocking waits on the map’s semaphore until space becomes available.&lt;br /&gt;
* Returns the starting address of allocated space.&lt;br /&gt;
&lt;br /&gt;
=== mfree / rmfree ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free previously allocated space in a map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `mp` – pointer to map&lt;br /&gt;
* `size` – units to free&lt;br /&gt;
* `a` – base address&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Sorts the freed block into the map.&lt;br /&gt;
* Merges with adjacent free blocks if possible.&lt;br /&gt;
* Updates map’s size and count.&lt;br /&gt;
* Broadcasts to any waiting threads if space becomes available.&lt;br /&gt;
* Logs warnings if map overflow or invalid free occurs.&lt;br /&gt;
&lt;br /&gt;
== Bitmap-Based Page Table Management ==&lt;br /&gt;
&lt;br /&gt;
The IRIX kernel uses **bitmap structures** to manage system page tables (`spt`). This allows fine-grained allocation with support for color and alignment.&lt;br /&gt;
&lt;br /&gt;
=== sptalloc() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate pages from the system page table bitmap.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – pointer to system bitmap structure&lt;br /&gt;
* `want` – number of pages&lt;br /&gt;
* `flags` – allocation flags (`VM_NOSLEEP`, `VM_VACOLOR`, `VM_BREAKABLE`)&lt;br /&gt;
* `color` – desired cache color (for R4000)&lt;br /&gt;
* `alignment` – page boundary alignment (power of 2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Selects a bitmap (clean, stale, aged) for allocation.&lt;br /&gt;
* If color-specific allocation is requested, attempts color map first.&lt;br /&gt;
* Uses rotors to track possible starting positions for efficiency.&lt;br /&gt;
* Supports alignment constraints.&lt;br /&gt;
* Will optionally wait (blocking) if pages are unavailable.&lt;br /&gt;
* Updates bitmap counters and rotors on allocation.&lt;br /&gt;
&lt;br /&gt;
=== sptfree() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free pages back to the system page table bitmap.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – pointer to system bitmap&lt;br /&gt;
* `size` – number of pages&lt;br /&gt;
* `mapaddr` – base address of pages to free&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Updates `m_lowbit`, `m_highbit`, and `m_count` in the bitmap.&lt;br /&gt;
* Sets freed bits in the bitmap.&lt;br /&gt;
* Broadcasts to waiting threads.&lt;br /&gt;
&lt;br /&gt;
=== mergebitmaps() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Merge one bitmap into another (e.g., stale pages back into main SPT map).  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – system bitmap&lt;br /&gt;
* `to` – destination bitmap&lt;br /&gt;
* `from` – source bitmap&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Copies set bits from source to destination.&lt;br /&gt;
* Updates rotor information for SPT allocation.&lt;br /&gt;
* Clears source bitmap.&lt;br /&gt;
&lt;br /&gt;
=== bmapswtch() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Swap contents of two bitmaps.  &lt;br /&gt;
&#039;&#039;&#039;Use case:&#039;&#039;&#039; Replace an old bitmap with a new one without modifying allocation state.&lt;br /&gt;
&lt;br /&gt;
=== sptgetsizes() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Get counts of pages in different states (clean, stale, aged, in-transit).&lt;br /&gt;
&lt;br /&gt;
== Synchronization and Multi-Processor Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Spinlocks (`mutex_spinlock`) protect map structures during allocation.&lt;br /&gt;
* Bitmaps have a hierarchy of locks:&lt;br /&gt;
** Normal allocation lock (`MAP_ALLOCLOCK`)**&lt;br /&gt;
** Urgent lock (`MAP_URGENTLOCK`)** – signals to other threads to back off during replenishment.&lt;br /&gt;
* Wait queues (semaphores) are used for threads blocked on resources.&lt;br /&gt;
&lt;br /&gt;
== R4000-Specific Enhancements ==&lt;br /&gt;
&lt;br /&gt;
* **Cache-colored allocation:** ensures pages allocated from a bitmap minimize cache conflicts.&lt;br /&gt;
* **sptvctst()** – tests for a free bit in a specific cache color.&lt;br /&gt;
* **color_alloc()** – allocates a page of a specific color.&lt;br /&gt;
* **sptaligntst()** – ensures alignment in allocations.&lt;br /&gt;
&lt;br /&gt;
== Fault Checking ==&lt;br /&gt;
&lt;br /&gt;
* `kvfaultcheck()` inspects which CPUs have references to aged or temporary pages.&lt;br /&gt;
* Returns a CPU mask indicating CPUs that need TLB flushes.&lt;br /&gt;
* Integration with isolate debugging on multi-CPU systems (EVEREST/SN0).&lt;br /&gt;
&lt;br /&gt;
== Notes for Reimplementation ==&lt;br /&gt;
&lt;br /&gt;
* Map-based allocations are generic and can be adapted to other OS kernels.&lt;br /&gt;
* Bitmap-based page allocations depend on low-level page tables; rotors and color optimizations can be implemented optionally.&lt;br /&gt;
* Careful handling of spinlocks, semaphores, and wait queues is required in multi-processor environments.&lt;br /&gt;
* Ensure that alignment and cache color are power-of-two values for correctness.&lt;br /&gt;
* Debug assertions (`ASSERT`) in IRIX should be converted to runtime checks or kernel asserts in the new environment.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:_malloc&amp;diff=443</id>
		<title>Kernel: malloc</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:_malloc&amp;diff=443"/>
		<updated>2025-12-29T20:53:44Z</updated>

		<summary type="html">&lt;p&gt;Raion: Initial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= IRIX Kernel Memory Allocation: Functional Documentation =&lt;br /&gt;
&lt;br /&gt;
This page documents the memory allocation subsystem of the IRIX kernel (`malloc`, `rmalloc`, and related functions) as implemented in the IRIX kernel. It is intended as a functional reference for reimplementation in other kernels (e.g., Illumos).&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
The IRIX memory allocation system provides:&lt;br /&gt;
&lt;br /&gt;
* Map-based memory management (`struct map`) for contiguous resource allocation.&lt;br /&gt;
* Page-aligned and color-aware allocations for cache efficiency (R4000-specific).&lt;br /&gt;
* Bitmap-based system page table (SPT) management.&lt;br /&gt;
* Waiting and non-waiting allocation paths (`VM_NOSLEEP` flag).&lt;br /&gt;
* Synchronization primitives using spinlocks and semaphores.&lt;br /&gt;
&lt;br /&gt;
Memory management in IRIX is based on two concepts:&lt;br /&gt;
&lt;br /&gt;
# **Maps** – contiguous resources tracked as a list of free/allocated blocks.&lt;br /&gt;
# **Bitmaps** – finer-grained allocation (e.g., pages, cache-colored pages) with alignment support.&lt;br /&gt;
&lt;br /&gt;
== Map Allocation API ==&lt;br /&gt;
&lt;br /&gt;
=== rmallocmap() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate and initialize a `struct map` for tracking resources.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039; `mapsiz` – number of entries in the map.  &lt;br /&gt;
&#039;&#039;&#039;Outputs:&#039;&#039;&#039; Pointer to newly allocated map, or NULL on failure.  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Allocates memory for `mapsiz + 2` map entries.&lt;br /&gt;
* Allocates and initializes a synchronization structure (`lock + semaphore`).&lt;br /&gt;
* Stores pointers to synchronization primitives in the second map entry.&lt;br /&gt;
* Returns a fully initialized map ready for allocations.&lt;br /&gt;
&lt;br /&gt;
=== rmfreemap() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free a previously allocated map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039; Pointer to map.  &lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Waits for any threads currently blocked on the map.&lt;br /&gt;
* Destroys associated semaphore and spinlock.&lt;br /&gt;
* Frees both the map memory and the synchronization structure.&lt;br /&gt;
&lt;br /&gt;
=== malloc / malloc_wait / rmalloc / rmalloc_wait ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate contiguous units from a map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `mp` – pointer to map&lt;br /&gt;
* `size` – number of units&lt;br /&gt;
* Optional `flags` (`VM_NOSLEEP` for non-blocking)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Uses **first-fit allocation**.&lt;br /&gt;
* Non-blocking (`VM_NOSLEEP`) returns `0` if allocation fails.&lt;br /&gt;
* Blocking waits on the map’s semaphore until space becomes available.&lt;br /&gt;
* Returns the starting address of allocated space.&lt;br /&gt;
&lt;br /&gt;
=== mfree / rmfree ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free previously allocated space in a map.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `mp` – pointer to map&lt;br /&gt;
* `size` – units to free&lt;br /&gt;
* `a` – base address&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Sorts the freed block into the map.&lt;br /&gt;
* Merges with adjacent free blocks if possible.&lt;br /&gt;
* Updates map’s size and count.&lt;br /&gt;
* Broadcasts to any waiting threads if space becomes available.&lt;br /&gt;
* Logs warnings if map overflow or invalid free occurs.&lt;br /&gt;
&lt;br /&gt;
== Bitmap-Based Page Table Management ==&lt;br /&gt;
&lt;br /&gt;
The IRIX kernel uses **bitmap structures** to manage system page tables (`spt`). This allows fine-grained allocation with support for color and alignment.&lt;br /&gt;
&lt;br /&gt;
=== sptalloc() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Allocate pages from the system page table bitmap.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – pointer to system bitmap structure&lt;br /&gt;
* `want` – number of pages&lt;br /&gt;
* `flags` – allocation flags (`VM_NOSLEEP`, `VM_VACOLOR`, `VM_BREAKABLE`)&lt;br /&gt;
* `color` – desired cache color (for R4000)&lt;br /&gt;
* `alignment` – page boundary alignment (power of 2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Selects a bitmap (clean, stale, aged) for allocation.&lt;br /&gt;
* If color-specific allocation is requested, attempts color map first.&lt;br /&gt;
* Uses rotors to track possible starting positions for efficiency.&lt;br /&gt;
* Supports alignment constraints.&lt;br /&gt;
* Will optionally wait (blocking) if pages are unavailable.&lt;br /&gt;
* Updates bitmap counters and rotors on allocation.&lt;br /&gt;
&lt;br /&gt;
=== sptfree() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Free pages back to the system page table bitmap.  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – pointer to system bitmap&lt;br /&gt;
* `size` – number of pages&lt;br /&gt;
* `mapaddr` – base address of pages to free&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Updates `m_lowbit`, `m_highbit`, and `m_count` in the bitmap.&lt;br /&gt;
* Sets freed bits in the bitmap.&lt;br /&gt;
* Broadcasts to waiting threads.&lt;br /&gt;
&lt;br /&gt;
=== mergebitmaps() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Merge one bitmap into another (e.g., stale pages back into main SPT map).  &lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* `bm` – system bitmap&lt;br /&gt;
* `to` – destination bitmap&lt;br /&gt;
* `from` – source bitmap&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Behavior:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Copies set bits from source to destination.&lt;br /&gt;
* Updates rotor information for SPT allocation.&lt;br /&gt;
* Clears source bitmap.&lt;br /&gt;
&lt;br /&gt;
=== bmapswtch() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Swap contents of two bitmaps.  &lt;br /&gt;
&#039;&#039;&#039;Use case:&#039;&#039;&#039; Replace an old bitmap with a new one without modifying allocation state.&lt;br /&gt;
&lt;br /&gt;
=== sptgetsizes() ===&lt;br /&gt;
&#039;&#039;&#039;Purpose:&#039;&#039;&#039; Get counts of pages in different states (clean, stale, aged, in-transit).&lt;br /&gt;
&lt;br /&gt;
== Synchronization and Multi-Processor Considerations ==&lt;br /&gt;
&lt;br /&gt;
* Spinlocks (`mutex_spinlock`) protect map structures during allocation.&lt;br /&gt;
* Bitmaps have a hierarchy of locks:&lt;br /&gt;
** Normal allocation lock (`MAP_ALLOCLOCK`)**&lt;br /&gt;
** Urgent lock (`MAP_URGENTLOCK`)** – signals to other threads to back off during replenishment.&lt;br /&gt;
* Wait queues (semaphores) are used for threads blocked on resources.&lt;br /&gt;
&lt;br /&gt;
== R4000-Specific Enhancements ==&lt;br /&gt;
&lt;br /&gt;
* **Cache-colored allocation:** ensures pages allocated from a bitmap minimize cache conflicts.&lt;br /&gt;
* **sptvctst()** – tests for a free bit in a specific cache color.&lt;br /&gt;
* **color_alloc()** – allocates a page of a specific color.&lt;br /&gt;
* **sptaligntst()** – ensures alignment in allocations.&lt;br /&gt;
&lt;br /&gt;
== Fault Checking ==&lt;br /&gt;
&lt;br /&gt;
* `kvfaultcheck()` inspects which CPUs have references to aged or temporary pages.&lt;br /&gt;
* Returns a CPU mask indicating CPUs that need TLB flushes.&lt;br /&gt;
* Integration with isolate debugging on multi-CPU systems (EVEREST/SN0).&lt;br /&gt;
&lt;br /&gt;
== Notes for Reimplementation ==&lt;br /&gt;
&lt;br /&gt;
* Map-based allocations are generic and can be adapted to other OS kernels.&lt;br /&gt;
* Bitmap-based page allocations depend on low-level page tables; rotors and color optimizations can be implemented optionally.&lt;br /&gt;
* Careful handling of spinlocks, semaphores, and wait queues is required in multi-processor environments.&lt;br /&gt;
* Ensure that alignment and cache color are power-of-two values for correctness.&lt;br /&gt;
* Debug assertions (`ASSERT`) in IRIX should be converted to runtime checks or kernel asserts in the new environment.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=Kernel:Kernel_Timers&amp;diff=442</id>
		<title>Kernel:Kernel Timers</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=Kernel:Kernel_Timers&amp;diff=442"/>
		<updated>2025-12-29T20:49:16Z</updated>

		<summary type="html">&lt;p&gt;Raion: Initial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# IRIX Kernel Timers&lt;br /&gt;
&lt;br /&gt;
The IRIX kernel implements a **high-resolution, per-thread timer subsystem** designed to track the time threads spend in various modes (user, system, interrupt, etc.) with hardware-specific accuracy. This subsystem differs from Illumos/OpenSolaris in several notable ways due to differences in hardware assumptions and kernel design.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Overview&lt;br /&gt;
&lt;br /&gt;
IRIX kernel timers are responsible for:&lt;br /&gt;
&lt;br /&gt;
* Maintaining **accumulated time** for individual threads across multiple timer modes.&lt;br /&gt;
* Providing **high-resolution snapshots** of thread execution time.&lt;br /&gt;
* Handling **timer switching** and accumulation safely in SMP or multi-threaded contexts.&lt;br /&gt;
* Measuring proportional **thread sleep/wait times**.&lt;br /&gt;
* Converting low-level hardware ticks into standard time units (seconds and nanoseconds).&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Key Concepts&lt;br /&gt;
&lt;br /&gt;
### Snapshots&lt;br /&gt;
&lt;br /&gt;
* Each thread maintains a **timer snapshot**, representing its current time state.&lt;br /&gt;
* Snapshots may consist of:&lt;br /&gt;
&lt;br /&gt;
  * A single high-resolution counter (if the platform supports absolute, monotonic timers), or&lt;br /&gt;
  * A combination of seconds and hardware-specific ticks to handle short-wrap timers.&lt;br /&gt;
* Snapshots are used to compute deltas between timer updates and to detect timer wrap-around.&lt;br /&gt;
&lt;br /&gt;
### Timer Accumulation&lt;br /&gt;
&lt;br /&gt;
* Each thread has a **per-thread timer package** that tracks:&lt;br /&gt;
&lt;br /&gt;
  * The currently active timer mode.&lt;br /&gt;
  * Accumulated time for all supported timers.&lt;br /&gt;
  * The last snapshot for delta calculations.&lt;br /&gt;
* When switching timers, IRIX computes the delta between the last snapshot and the current time, adding it to the accumulator for the previous timer mode.&lt;br /&gt;
&lt;br /&gt;
### Timer Switching&lt;br /&gt;
&lt;br /&gt;
* Threads can switch between different timer modes explicitly.&lt;br /&gt;
* Timer switching involves:&lt;br /&gt;
&lt;br /&gt;
  * Snapshotting the current timer.&lt;br /&gt;
  * Updating the accumulator of the previously active timer.&lt;br /&gt;
  * Setting the new timer as active.&lt;br /&gt;
* Race conditions are carefully handled by verifying that snapshots are consistent during the update.&lt;br /&gt;
&lt;br /&gt;
### Reading Timers&lt;br /&gt;
&lt;br /&gt;
* Timer reads return the accumulated time for a specific thread and timer mode.&lt;br /&gt;
* If the requested timer is currently active, IRIX computes the time since the last snapshot and adds it to the accumulator.&lt;br /&gt;
* Reading is designed to be **race-resilient**, looping until a consistent snapshot is obtained.&lt;br /&gt;
&lt;br /&gt;
### Sleep Time Measurement&lt;br /&gt;
&lt;br /&gt;
* IRIX provides a measure of **thread sleep/wait time**, representing how long a thread has been idle.&lt;br /&gt;
* This measure is proportional to real time but does not guarantee absolute accuracy.&lt;br /&gt;
* Threads in active timer modes (user, system, or interrupt) report zero sleep time.&lt;br /&gt;
&lt;br /&gt;
### Conversion to Standard Time&lt;br /&gt;
&lt;br /&gt;
* Low-level hardware ticks are converted into **seconds and nanoseconds** for user-facing APIs.&lt;br /&gt;
* Conversion uses hardware-specific frequency and unit scaling, reflecting differences in RTC or high-resolution counters.&lt;br /&gt;
&lt;br /&gt;
### SMP and Atomic Operations&lt;br /&gt;
&lt;br /&gt;
* On multi-processor systems, atomic operations ensure correct accumulation of timers.&lt;br /&gt;
* IRIX distinguishes **CELL IRIX** systems, which use specific atomic add instructions for timer updates.&lt;br /&gt;
* Non-CELL SMP systems rely on standard atomic or interrupt-safe mechanisms.&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Differences from Illumos/OpenSolaris&lt;br /&gt;
&lt;br /&gt;
| Feature              | IRIX                                       | Illumos/OpenSolaris                     | Notes                                                                           |&lt;br /&gt;
| -------------------- | ------------------------------------------ | --------------------------------------- | ------------------------------------------------------------------------------- |&lt;br /&gt;
| Timer representation | Hardware-specific ticks, may wrap          | 64-bit monotonic nanoseconds (`hrtime`) | IRIX handles wrap-around; Solaris simpler                                       |&lt;br /&gt;
| Snapshots            | Stored as ticks or [seconds + ticks]       | Stored as cumulative `hrtime`           | IRIX explicitly tracks dual-field snapshots for wrap detection                  |&lt;br /&gt;
| Timer switching      | Explicit per-thread function               | Handled by scheduler/context switch     | IRIX exposes manual switching, Solaris hides it internally                      |&lt;br /&gt;
| Sleep time           | Computed dynamically from snapshots        | Maintained in thread scheduler counters | IRIX calculates on-demand; Solaris updates in scheduler                         |&lt;br /&gt;
| SMP safety           | Explicit atomic operations (CELL-specific) | Generic atomic operations               | IRIX has platform-specific atomic paths; Solaris uses uniform atomic ops        |&lt;br /&gt;
| Time conversion      | Scaled using hardware frequency            | Division of nanoseconds                 | IRIX converts hardware ticks; Solaris works directly with `hrtime`              |&lt;br /&gt;
| Race handling        | Looping snapshot checks                    | Scheduler guarantees consistency        | IRIX implements explicit consistency checks; Solaris relies on locks/atomic ops |&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
## Key Takeaways&lt;br /&gt;
&lt;br /&gt;
* IRIX kernel timers are **hardware-conscious**, designed for platforms with wrapping high-resolution counters.&lt;br /&gt;
* The subsystem provides **manual control** over timer modes and accumulators.&lt;br /&gt;
* It carefully manages **race conditions and SMP safety**, including platform-specific atomic operations.&lt;br /&gt;
* Unlike Illumos/OpenSolaris, IRIX must scale raw hardware ticks into standard time units and detect timer wrap-around.&lt;br /&gt;
* Sleep time and deltas are **computed dynamically** rather than tracked in scheduler-maintained counters.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
	<entry>
		<id>https://tech-pubs.net/wiki/index.php?title=SGIfetch&amp;diff=441</id>
		<title>SGIfetch</title>
		<link rel="alternate" type="text/html" href="https://tech-pubs.net/wiki/index.php?title=SGIfetch&amp;diff=441"/>
		<updated>2025-12-28T03:25:57Z</updated>

		<summary type="html">&lt;p&gt;Raion: Created page with &amp;quot;&amp;#039;&amp;#039;&amp;#039;sgifetch&amp;#039;&amp;#039;&amp;#039; is a neofetch-like tool that displays system information for SGI MIPS hardware running IRIX.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;sgifetch&#039;&#039;&#039; is a neofetch-like tool that displays system information for SGI MIPS hardware running IRIX.&lt;/div&gt;</summary>
		<author><name>Raion</name></author>
	</entry>
</feed>