shithub: riscv

Download patch

ref: 0b6f0c70dba53c08846299a85d3cddd91c070c53
parent: 37d6ddd8f323224d169b7fa42fa126d5c9b2ffd4
author: Ori Bernstein <[email protected]>
date: Tue Nov 19 07:30:40 EST 2019

add start of section 9 manpages (thanks rgl)

this change adds some of the kernel manpages from 9legacy,
fixed and updated to match the changes in 9front.

--- /dev/null
+++ b/sys/man/9/0intro
@@ -1,0 +1,53 @@
+.TH INTRO 9
+.SH NAME
+intro \- introduction to kernel functions
+.SH DESCRIPTION
+This section of the manual
+describes the functions publicly available to the authors of
+kernel code, particularly device drivers (real and virtual).
+This section will eventually be much expanded, but this makes a start.
+.PP
+The
+.SM SYNOPSIS
+subsections do not show the header files needed for
+the standard kernel declarations.
+The primary combinations summarised below:
+.IP
+.RS
+.ta \w'\fL#include 'u
+.nf
+.B
+#include	"u.h"
+.B
+#include	"../port/lib.h"
+.B
+#include	"mem.h"
+.B
+#include	"dat.h"
+.B
+#include	"fns.h"
+.B
+#include	"../port/error.h"
+.PP
+.I "furthermore, added in IP code:"
+.br
+.B
+#include "../ip/ip.h"
+.PP
+.I "furthermore, in hardware device drivers:"
+.br
+.B
+#include "io.h"
+.br
+.B
+#include "ureg.h"
+.PP
+.I "furthermore, in network interfaces or ether drivers:"
+.B
+#include "../port/netif.h"
+.fi
+.RE
+.PP
+There might also be specific include files needed by
+drivers on particular platforms or to use specialised kernel interfaces.
+The easiest method is to check the source of likely-looking drivers nearby.
--- /dev/null
+++ b/sys/man/9/INDEX
@@ -1,0 +1,67 @@
+0intro 0intro
+intro 0intro
+BALLOC allocb
+BLEN allocb
+adjustblock allocb
+allocb allocb
+blockalloclen allocb
+blocklen allocb
+checkb allocb
+concatblock allocb
+copyblock allocb
+freeb allocb
+freeblist allocb
+iallocb allocb
+packblock allocb
+padblock allocb
+pullblock allocb
+pullupblock allocb
+readblist allocb
+trimblock allocb
+addclock0link delay
+delay delay
+microdelay delay
+error error
+nexterror error
+poperror error
+waserror error
+eve eve
+iseve eve
+intrdisable intrenable
+intrenable intrenable
+kproc kproc
+pexit kproc
+postnote kproc
+free malloc
+getmalloctag malloc
+getrealloctag malloc
+malloc malloc
+mallocz malloc
+msize malloc
+realloc malloc
+secalloc malloc
+secfree malloc
+setmalloctag malloc
+setrealloctag malloc
+smalloc malloc
+panic panic
+canqlock qlock
+qlock qlock
+qunlock qlock
+rlock qlock
+runlock qlock
+wlock qlock
+wunlock qlock
+return0 sleep
+sleep sleep
+tsleep sleep
+wakeup sleep
+islo splhi
+splhi splhi
+spllo splhi
+splx splhi
+xalloc xalloc
+xallocz xalloc
+xfree xalloc
+xspanalloc xalloc
+xsummary xalloc
--- /dev/null
+++ b/sys/man/9/INDEX.html
@@ -1,0 +1,61 @@
+<HEAD>
+<TITLE>plan 9 man section 9</TITLE>
+</HEAD>
+<BODY>
+<B>[<A HREF="/sys/man/index.html">manual index</A>]</B>
+<H2>Plan 9 from Bell Labs - Section 9 - </H2>
+<HR>
+<DL>
+<DT><A HREF="/magic/man2html/9/0intro">0intro</A>
+-  introduction to kernel functions
+<DD><TT> intro</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/allocb">allocb</A>
+-  data block management
+<DD><TT> allocb, iallocb, freeb, freeblist, BLEN, BALLOC, blocklen, blockalloclen, readblist, concatblock, copyblock, trimblock, packblock, padblock, pullblock, pullupblock, adjustblock, checkb</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/delay">delay</A>
+-  small delays, clock interrupts
+<DD><TT> delay, microdelay, addclock0link</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/error">error</A>
+-  error handling functions
+<DD><TT> error, nexterror, poperror, waserror</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/eve">eve</A>
+-  privileged user
+<DD><TT> eve, iseve</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/intrenable">intrenable</A>
+-  enable (disable) an interrupt handler
+<DD><TT> intrenable, intrdisable</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/kproc">kproc</A>
+-  kernel process creation, termination and interruption
+<DD><TT> kproc, pexit, postnote</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/malloc">malloc</A>
+-  kernel memory allocator
+<DD><TT> malloc, mallocz, smalloc, realloc, free, msize, secalloc, secfree, setmalloctag, setrealloctag, getmalloctag, getrealloctag</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/panic">panic</A>
+-  abandon hope, all ye who enter here
+<DD><TT> panic</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/qlock">qlock</A>
+-  serial synchronisation
+<DD><TT> qlock, qunlock, canqlock, rlock, runlock, wlock, wunlock</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/sleep">sleep</A>
+-  process synchronisation
+<DD><TT> sleep, wakeup, tsleep, return0</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/splhi">splhi</A>
+-  enable and disable interrupts
+<DD><TT> splhi, spllo, splx, islo</TT>
+</DT>
+<DT><A HREF="/magic/man2html/9/xalloc">xalloc</A>
+-  basic memory management
+<DD><TT> xalloc, xallocz, xspanalloc, xfree, xsummary</TT>
+</DT>
+</DL>
--- /dev/null
+++ b/sys/man/9/allocb
@@ -1,0 +1,343 @@
+.TH ALLOCB 9
+.SH NAME
+allocb, iallocb, freeb, freeblist, BLEN, BALLOC, blocklen, blockalloclen, readblist, concatblock, copyblock, trimblock, packblock, padblock, pullblock, pullupblock, adjustblock, checkb \- data block management
+.SH SYNOPSIS
+.ta \w'\fLBlock* 'u
+.B
+Block*	allocb(int size)
+.PP
+.B
+Block*	iallocb(int size)
+.PP
+.B
+void	freeb(Block *b)
+.PP
+.B
+void	freeblist(Block *b)
+.PP
+.B
+int	blocklen(Block *b)
+.PP
+.B
+int	blockalloclen(Block *b)
+.PP
+.B
+long	readblist(Block *b, uchar *p, long n, ulong offset)
+.PP
+.B
+Block*	concatblock(Block *b)
+.PP
+.B
+Block*	copyblock(Block *b, int n)
+.PP
+.B
+Block*	trimblock(Block *b, int offset, int n)
+.PP
+.B
+Block*	packblock(Block *b)
+.PP
+.B
+Block*	padblock(Block *b, int n)
+.PP
+.B
+int	pullblock(Block **bph, int n)
+.PP
+.B
+Block*	pullupblock(Block *b, int n)
+.PP
+.B
+Block*	adjustblock(Block *b, int n)
+.PP
+.B
+void	checkb(Block *b, char *msg)
+.sp 0.1
+.PP
+.B
+#define BLEN(s)	((s)->wp - (s)->rp)
+.PP
+.B
+#define BALLOC(s) ((s)->lim - (s)->base)
+.SH DESCRIPTION
+A
+.B Block
+provides a receptacle for data:
+.IP
+.EX
+.DT
+typedef
+struct Block
+{
+	Block*	next;
+	Block*	list;
+	uchar*	rp;		/* first unconsumed byte */
+	uchar*	wp;		/* first empty byte */
+	uchar*	lim;		/* 1 past the end of the buffer */
+	uchar*	base;	/* start of the buffer */
+	void	(*free)(Block*);
+	ushort	flag;
+	ushort	checksum;	/* IP checksum of complete packet */
+} Block;
+.EE
+.PP
+Each
+.B Block
+has an associated buffer, located at
+.BR base ,
+and accessed via
+.B wp
+when filling the buffer, or
+.B rp
+when fetching data from it.
+Each pointer should be incremented to reflect the amount of data written or read.
+A
+.B Block
+is empty when
+.B rp
+reaches
+.BR wp .
+The pointer
+.B lim
+bounds the allocated space.
+Some operations described below accept lists of
+.BR Block s,
+which are
+chained via their
+.B next
+pointers, with a null pointer ending the list.
+.B Blocks
+are usually intended for a
+.B Queue
+(see
+.IR qio (9)),
+but can be used independently.
+.PP
+A
+.B Block
+and its buffer are normally allocated by one call to
+.IR malloc (9)
+and aligned on an 8 byte (\fLBY2V\fP) boundary.
+Some devices with particular allocation constraints
+(eg, requiring certain addresses for DMA) might allocate their own
+.B Block
+and buffer;
+.B free
+must then point to a function that can deallocate the specially allocated
+.BR Block .
+.PP
+Many
+.B Block
+operations cannot be used in interrupt handlers
+because they either
+.IR sleep (9)
+or raise an
+.IR error (9).
+Of operations that allocate blocks, only
+.IR iallocb
+is usable.
+.PP
+.I Allocb
+allocates a
+.B Block
+of at least
+.IR size
+bytes.
+The block
+is initially empty:
+.B rp
+and
+.B wp
+point to the start of the data.
+If it cannot allocate memory,
+.I allocb
+raises an
+.IR error (9);
+it cannot be used by an interrupt handler.
+.PP
+.IR Iallocb
+is similar to
+.IR allocb
+but is intended for use by interrupt handlers,
+and returns a null pointer if no memory is available.
+It also limits its allocation to a quota allocated at system initialisation to interrupt-time buffering.
+.PP
+.I Freeb
+frees a single
+.B Block
+(and its buffer).
+.PP
+.I Freeblist
+frees the whole
+list of blocks headed by
+.IR b .
+.PP
+.I BLEN
+returns the number of unread bytes in a single block.
+.PP
+.I BALLOC
+returns the number of allocated bytes in a single block.
+.PP
+.I Blocklen
+returns the number of bytes of unread data in the whole list of blocks headed by
+.IR b .
+.PP
+.I Blockalloclen
+returns the number of total bytes allocated in the whole list of blocks headed by
+.IR b .
+.PP
+.I Readblist
+copies
+.I n
+bytes of data at offset
+.I offset
+from the list of blocks headed by
+.I b
+into
+.IR p ,
+then returns the amount of bytes copied. It leaves the block list intact.
+.PP
+.I Concatblock
+returns
+.I b
+if it is not a list, and otherwise
+returns a single
+.B Block
+containing all the data in the list of blocks
+.IR b ,
+which it frees.
+.PP
+.I Copyblock
+by contrast returns a single
+.B Block
+containing a copy of the first
+.I n
+bytes of data in the block list
+.IR b ,
+padding with zeroes if the list contained less than
+.I n
+bytes.
+The list
+.I b
+is unchanged.
+.PP
+.I Padblock
+can pad a single
+.B Block
+at either end, to reserve space for protocol headers or trailers.
+If
+.IR n ≥ 0 ,
+it inserts
+.I n
+bytes at the start of the block,
+setting the read pointer
+.B rp
+to point to the new space.
+If
+.IR n < 0 ,
+it adds
+.I n
+bytes at the end of the block,
+leaving the write pointer
+.B wp
+pointing at the new space.
+In both cases, it allocates a new
+.B Block
+if necessary, freeing the old, and
+it always returns a pointer to the resulting
+.BR Block .
+.PP
+.I Trimblock
+trims the list
+.I b
+to contain no more than
+.I n
+bytes starting at
+.I offset
+bytes into the data of the original list.
+It returns a new list, freeing unneeded parts of the old.
+If no data remains, it returns a null pointer.
+.PP
+.I Packblock
+examines each
+.B Block
+in the list
+.IR b ,
+reallocating any block in the list that has four times more available space than actual data.
+It returns a pointer to the revised list.
+.PP
+.I Pullblock
+discards up to
+.I n
+bytes from the start of the list headed by
+.BI * bph \f1.\f0
+Unneeded blocks are freed.
+.I Pullblock
+sets
+.BI * bph
+to point to the new list head
+and returns the number of bytes discarded (which might be less than
+.IR n ).
+It is used by transport protocols to discard ack'd data at
+the head of a retransmission queue.
+.PP
+.I Pullupblock
+rearranges the data in the list of blocks
+.I b
+to ensure that there are at least
+.I n
+bytes of contiguous data in the first block,
+and returns a pointer to the new list head.
+It frees any blocks that it empties.
+It returns a null pointer if there is not enough data in the list.
+.PP
+.I Adjustblock
+ensures that the block
+.I b
+has at least
+.I n
+bytes of data, reallocating or padding with zero if necessary.
+It returns a pointer to the new
+.BR Block .
+(If
+.I n
+is negative, it frees the block and returns a null pointer.)
+.PP
+.I Checkb
+does some consistency checking of
+the state of
+.IR b ;
+a
+.IR panic (9)
+results if things look grim.
+It is intended for internal use by the queue I/O routines (see
+.IR qio (9))
+but could be used elsewhere.
+.PP
+The only functions that can be called at interrupt level are
+.IR iallocb ,
+.IR freeb ,
+.IR freeblist ,
+.IR BLEN ,
+.IR BALLOC ,
+.IR blocklen ,
+.IR blockalloclen ,
+.IR readblist
+and
+.IR trimblock .
+The others allocate memory and can potentially block.
+.SH SOURCE
+.B /sys/src/9/port/allocb.c
+.br
+.B /sys/src/9/port/qio.c
+.SH DIAGNOSTICS
+Many functions directly or indirectly can raise an
+.IR error (9),
+and callers must therefore provide for proper error recovery
+as described therein to prevent memory leaks and other bugs.
+Except for
+.IR iallocb ,
+any functions that allocate new blocks or lists
+are unsuitable for use by interrupt handlers.
+.IR Iallocb
+returns a null pointer when it runs out of memory.
+.SH SEE ALSO
+.IR qio (9)
--- /dev/null
+++ b/sys/man/9/delay
@@ -1,0 +1,46 @@
+.TH DELAY 9
+.SH NAME
+delay, microdelay, addclock0link \- small delays, clock interrupts
+.SH SYNOPSIS
+.ta \w'\fLTimer* 'u
+.B
+void	delay(int ms)
+.PP
+.B
+void	microdelay(int µs)
+.PP
+.B
+Timer*	addclock0link(void(*clockf)(void), int ms)
+.SH DESCRIPTION
+.I Delay
+busy waits for
+.I ms
+milliseconds, forced to be at least one millisecond on some architectures.
+.PP
+.I Microdelay
+works exactly the same as
+.I delay
+but using microseconds instead.
+.PP
+For delays on the order of clock ticks,
+.I tsleep
+(see
+.IR sleep (9))
+provides a better alternative to the busy waiting of these routines.
+.PP
+.I Addclock0link
+adds a new periodic timer to the current processor's timer list, with
+.I clockf
+executing every
+.I ms
+milliseconds. If
+.I ms
+is zero a default clock is used, it will panic otherwise (i.e.
+.I ms
+< 0).
+.SH SOURCE
+.B /sys/src/9/port/portclock.c
+.br
+.B /sys/src/9/*/clock.c
+.SH SEE ALSO
+.IR sleep (9)
--- /dev/null
+++ b/sys/man/9/error
@@ -1,0 +1,171 @@
+.TH ERROR 9
+.SH NAME
+error, nexterror, poperror, waserror \- error handling functions
+.SH SYNOPSIS
+.ta \w'\fL#define 'u
+.B
+void	error(char*)
+.PP
+.B
+void	nexterror(void)
+.sp 0.1
+.PP
+.B
+#define poperror() (up->nerrlab--)
+.PP
+.B
+#define waserror() (setlabel(&up->errlab[up->nerrlab++]))
+.SH DESCRIPTION
+The kernel handles error conditions using non-local gotos,
+similar to
+.IR setjmp (2),
+but using a stack of error labels to implement nested exception handling.
+This simplifies many of the internal interfaces by eliminating the need
+for returning and checking error codes at every level of the call stack,
+at the cost of requiring kernel routines to adhere to a strict discipline.
+.PP
+Each process has in its defining kernel
+.B Proc
+structure a stack of labels,
+.B NERR
+(currently 64)  elements deep.
+A kernel function that must perform a clean up or recovery action on an error
+makes a stylised call to
+.IR waserror ,
+.IR nexterror
+and
+.IR poperror :
+.IP
+.EX
+.DT
+if(waserror()){
+	/* recovery action */
+	nexterror();
+}
+/* normal action */
+poperror();
+.EE
+.PP
+When called in the normal course of events,
+.I waserror
+registers an error handling block by pushing its label onto the stack,
+and returns zero.
+The return value of
+.I waserror
+should be tested as shown above.
+If non-zero (true), the calling function should perform the needed
+error recovery, ended by a call to
+.I nexterror
+to transfer control to the next location on the error stack.
+Typical recovery actions include deallocating memory, unlocking resources, and
+resetting state variables.
+.PP
+Within the recovery block,
+after handling an error condition, there must normally
+be a call to
+.I nexterror
+to transfer control to any error recovery lower down in the stack.
+The main exception is in the outermost function in a process,
+which must not call
+.I nexterror
+(there being nothing further on the stack), but calls
+.I pexit
+(see
+.IR kproc (9))
+instead,
+to terminate the process.
+.PP
+When the need to recover a particular resource has passed,
+a function that has called
+.I waserror
+must
+remove the corresponding label from the stack by calling
+.IR poperror .
+This
+must
+be done before returning from the function; otherwise, a subsequent call to
+.I error
+will return to an obsolete activation record, with unpredictable but unpleasant consequences.
+.PP
+.I Error
+copies the given error message, which is limited to
+.B ERRMAX
+bytes, into the
+.B Proc.errstr
+of the current process,
+enables interrupts by calling
+.I spllo
+.RI ( native
+only),
+and finally calls
+.I nexterror
+to start invoking the recovery procedures currently stacked by
+.IR waserror .
+The file
+.B /sys/src/9/port/error.h
+offers a wide selection of predefined error messages, suitable for almost any occasion.
+The message set by the most recent call to
+.I error
+can be obtained within the kernel by examining
+.B up->error
+and in an application, by using the
+.L %r
+directive of
+.IR print (2).
+.PP
+A complex function can have nested error handlers.
+A
+.I waserror
+block will follow the acquisition of a resource, releasing it
+on error before calling
+.I nexterror,
+and a
+.I poperror
+will precede its release in the normal case.
+For example:
+.IP
+.EX
+.DT
+void
+outer(Thing *t)
+{
+    qlock(t);
+    if(waserror()){      /* A */
+        qunlock(t);
+        nexterror();
+    }
+    m = mallocz(READSTR, 0);
+    if(m == nil)
+        error(Enomem);	/* returns to A */
+    if(waserror()){     /* B */
+        free(m);
+        nexterror();    /* invokes A */
+    }
+    inner(t);
+    poperror();         /* pops B */
+    free(m);
+    poperror();         /* pops A */
+    qunlock(t);
+}
+.sp 1v
+void
+inner(Thing *t)
+{
+    if(t->bad)
+        error(Egreg);   /* returns to B */
+    t->valid++;
+}
+.EE
+.SH SOURCE
+.B /sys/src/9/port/proc.c
+.SH CAVEATS
+The description above has many instances of
+.IR should ,
+.IR will ,
+.I must
+and
+.IR "must not" .
+.SH SEE ALSO
+.IR panic (9),
+.IR kproc (9),
+.IR splhi (9)
--- /dev/null
+++ b/sys/man/9/eve
@@ -1,0 +1,46 @@
+.TH EVE 9
+.SH NAME
+eve, iseve \- privileged user
+.SH SYNOPSIS
+.ta \w'\fLchar* 'u
+.B
+char	*eve;
+.PP
+.B
+int	iseve(void)
+.SH DESCRIPTION
+.I Eve
+is a null-terminated string containing the name of the owner of
+the Plan 9 system (sometimes called the `host owner',
+see
+.IR cons (3)).
+The identity is set on a terminal to the name of the user who logs in.
+It is set on a CPU server to the
+.I authid
+obtained either from NVRAM or by a console prompt.
+The initial process created by system initialisation is given the
+.I eve
+identity.
+.PP
+.I Iseve
+returns true if the current user is
+.IR eve .
+Several drivers use
+.I iseve
+to check the caller's identity
+before granting permission to perform certain actions.
+For example, the console driver allows only the user
+.I eve
+to write a new identity into the
+.B /dev/user
+file.
+The privileges are strictly local and do not extend into the network
+(in particular, to file servers—even ones running on the local machine).
+.SH SOURCE
+.B /sys/src/9/port/auth.c
+.SH SEE ALSO
+.IR auth (2),
+.IR cap (3),
+.IR cons (3),
+.IR authsrv (6),
+.IR auth (8)
--- /dev/null
+++ b/sys/man/9/intrenable
@@ -1,0 +1,106 @@
+.TH INTRENABLE 9
+.SH NAME
+intrenable, intrdisable \- enable (disable) an interrupt handler
+.SH SYNOPSIS
+.ta \w'\fLvoid* 'u
+.B
+void intrenable(int v, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
+.PP
+.B
+void intrdisable(int v, void (*f)(Ureg*, void*), void* a, int tbdf, char *name)
+.SH DESCRIPTION
+.I Intrenable
+registers
+.I f
+to be called by the kernel's interrupt controller driver each time
+an interrupt denoted by
+.I v
+occurs, and unmasks the corresponding interrupt in the interrupt controller.
+The encoding of
+.I v
+is platform-dependent; it is often an interrupt vector number, but
+can be more complex.
+.I Tbdf
+is a platform-dependent value that might further qualify
+.IR v .
+It might for instance
+denote the type of bus, bus instance, device number and function
+(following the PCI device indexing scheme), hence its name,
+but can have platform-dependent meaning.
+.I Name
+is a string that should uniquely identify the corresponding device (eg, \f5"uart0"\fP);
+again it is usually platform-dependent.
+.I Intrenable
+supports sharing of interrupt levels when the hardware does.
+.PP
+Almost invariably
+.I f
+is a function defined in a device driver to carry out the device-specific work associated with a given interrupt.
+The pointer
+.I a
+is passed to
+.IR f ;
+typically it points to the driver's data for a given device or controller.
+It also passes
+.I f
+a
+.B Ureg*
+value that
+contains the registers saved by the interrupt handler (the
+contents are platform specific;
+see the platform's include file
+.BR "ureg.h" ).
+.PP
+.I F
+is invoked by underlying code in the kernel that is invoked directly from the hardware vectors.
+It is therefore not running in any process (see
+.IR kproc (9);
+indeed, on many platforms
+the current process pointer
+.RB ( up )
+will be nil.
+There are many restrictions on kernel functions running outside a process, but a fundamental one is that
+they must not
+.IR sleep (9),
+although they often call
+.B wakeup
+to signal the occurrence of an event associated with the interrupt.
+.IR Qio (9)
+and other manual pages note which functions are safe for
+.I f
+to call.
+.PP
+The interrupt controller driver does whatever is
+required to acknowledge or dismiss the interrupt signal in the interrupt controller,
+before calling
+.IR f ,
+for edge-triggered interrupts,
+and after calling
+.I f
+for level-triggered ones.
+.I F
+is responsible for dealing with the cause of the interrupt in the device, including any
+acknowledgement required in the device, before it returns.
+.PP
+.I Intrdisable
+removes any registration previously made by
+.I intrenable
+with matching parameters, and if no other
+interrupt is active on
+.IR v ,
+it masks the interrupt in the controller.
+Device drivers that are not dynamically configured tend to call
+.I intrenable
+during reset or initialisation (see
+.IR dev (9)),
+but can call it at any appropriate time, and
+instead of calling
+.I intrdisable
+they can simply enable or disable interrupts in the device as required.
+.SH SOURCE
+.B /sys/src/9/*/trap.c
+.SH SEE ALSO
+.IR malloc (9),
+.IR qio (9),
+.IR sleep (9),
+.IR splhi (9)
--- /dev/null
+++ b/sys/man/9/kproc
@@ -1,0 +1,134 @@
+.TH KPROC 9
+.SH NAME
+kproc, pexit, postnote \- kernel process creation, termination and interruption
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+void	kproc(char *name, void (*func)(void*), void *arg)
+.PP
+.B
+void	pexit(char *note, int freemem)
+.PP
+.B
+int	postnote(Proc *p, int dolock, char *n, int flag)
+.SH DESCRIPTION
+.I Kproc
+creates a new kernel process
+to run the function
+.IR func ,
+which is invoked as 
+.BR "(*func)(arg)" .
+The string
+.I name
+is copied into the
+.B text
+field of the
+.B Proc
+structure of the new process; this value is the name of the kproc in
+the output of
+.IR ps (1).
+The process is made runnable; it
+will run when selected by the scheduler
+.IR sched (9).
+The process is created with base and current priorities set to
+.BR PriKproc .
+It shares the kernel process group and thus name space.
+.PP
+A kernel process terminates only when it calls
+.IR pexit ,
+thereby terminating itself.
+There is no mechanism for one process to force the termination of another,
+although it can send a software interrupt using
+.IR postnote .
+.I Note
+is a null string on normal termination, or
+the cause of 
+If
+.I freemem
+is non-zero,
+any memory allocated by the process is discarded;
+it should normally be non-zero for any process created
+by
+.IR kproc .
+Use the following to terminate a kernel process normally:
+.IP
+.EX
+pexit("", 1);
+.EE
+.PP
+to terminate a kernel process normally.
+.PP
+.I Postnote
+sends a software interrupt to process
+.IR p ,
+causing it, if necessary, to wake from
+.IR sleep (9)
+or break out of a
+.IR rendezvous (2)
+or an
+.IR eqlock(9),
+with an
+.IR error (9)
+`interrupted'.
+Up to
+.B NNOTE
+notes can be pending at once (currently 5);
+if more than that arrive, the process is forced
+out of
+.IR sleep ,
+.I rendezvous
+and
+.IR eqlock ,
+but the message itself is discarded.
+.I Postnote
+returns non-zero iff the note has been
+delivered successfully.
+If
+.I dolock
+is non-zero,
+.I postnote
+synchronises delivery of the note with the debugger
+and other operations of
+.IR proc (3).
+.I Flag
+is zero, or one of the following
+.TP
+.B NDebug
+Print the note message on the user's standard error.
+Furthermore, suspend the process in a
+.B Broken
+state, preserving its memory, for later debugging.
+.TP
+.B NExit
+Deliver the note quietly.
+.TP
+.B NUser
+The note comes from another process, not the system.
+.PP
+The kernel uses
+.I postnote
+to signal processes that commit grave faults,
+and to implement the note and kill functions of
+.IR proc (3).
+A device driver should use
+.I postnote
+only to tell a service process,
+previously started by the driver using
+.I kproc ,
+that it should stop;
+the note will cause that process to raise an
+.IR error (9).
+For example, a process started to read packets from a network device could
+be stopped as follows when the interface is unbound:
+.IP
+.EX
+postnote(readp, 1, "unbind", 0);
+.EE
+.PP
+where
+.I readp
+points to the appropriate
+.BR Proc .
+The text of the message is typically irrelevant.
+.SH SOURCE
+.B /sys/src/9/port/proc.c
--- /dev/null
+++ b/sys/man/9/malloc
@@ -1,0 +1,187 @@
+.TH MALLOC 9
+.SH NAME
+malloc, mallocz, smalloc, realloc, free, msize, secalloc, secfree, setmalloctag, setrealloctag, getmalloctag, getrealloctag \- kernel memory allocator
+.SH SYNOPSIS
+.ta \w'\fLvoid* 'u
+.B
+void*	malloc(ulong size)
+.PP
+.B
+void*	mallocalign(ulong size, ulong align, long offset, ulong span)
+.PP
+.B
+void*	mallocz(ulong size, int clr)
+.PP
+.B
+void*	smalloc(ulong size)
+.PP
+.B
+void*	realloc(void *p, ulong size)
+.PP
+.B
+void	free(void *ptr)
+.PP
+.B
+ulong	msize(void *ptr)
+.PP
+.B
+void*	secalloc(ulong size)
+.PP
+.B
+void	secfree(void *ptr)
+.PP
+.B
+void	setmalloctag(void *ptr, ulong tag)
+.PP
+.B
+ulong	getmalloctag(void *ptr)
+.PP
+.B
+void	setrealloctag(void *ptr, ulong tag)
+.PP
+.B
+ulong	getrealloctag(void *ptr)
+.PP
+.SH DESCRIPTION
+These are kernel versions of the functions in
+.IR malloc (2).
+They allocate memory from the
+.B mainmem
+memory pool,
+which is managed by
+the allocator
+.IR pool (2),
+which in turn replenishes the pool as required by calling
+.IR xalloc (9).
+All but
+.I smalloc
+(which calls
+.IR sleep (9))
+may safely be called by interrupt handlers.
+.PP
+.I Malloc
+returns a pointer to a block of at least
+.I size
+bytes, initialised to zero.
+The block is suitably aligned for storage of any type of object.
+The call
+.B malloc(0)
+returns a valid pointer rather than null.
+.I Mallocz
+is similar, but only clears the memory if
+.I clr
+is non-zero.
+.PP
+.I Smalloc
+returns a pointer to a block of
+.I size
+bytes, initialised to zero.
+If the memory is not immediately available,
+.I smalloc
+retries every 100 milliseconds until the memory is acquired.
+.PP
+.I Mallocalign
+allocates a block of at least 
+.I n
+bytes of memory respecting alignment contraints.
+If
+.I align
+is non-zero,
+the returned pointer is aligned to be equal to
+.I offset
+modulo
+.IR align .
+If
+.I span
+is non-zero,
+the
+.I n
+byte block allocated will not span a
+.IR span -byte
+boundary.
+.PP
+.I Realloc
+changes the size of the block pointed to by
+.I p
+to
+.I size
+bytes,
+if possible without moving the data,
+and returns a pointer to the block.
+The contents are unchanged up to the lesser of old and new sizes,
+and any new space allocated is initialised to zero.
+.I Realloc
+takes on special meanings when one or both arguments are zero:
+.TP
+.B "realloc(0,\ size)
+means
+.LR malloc(size) ;
+returns a pointer to the newly-allocated memory
+.TP
+.B "realloc(ptr,\ 0)
+means
+.LR free(ptr) ;
+returns null
+.TP
+.B "realloc(0,\ 0)
+no-op; returns null
+.PD
+.PP
+The argument to
+.I free
+is a pointer to a block of memory allocated by one of the routines above, which
+is returned to the allocation pool, or a null pointer, which is ignored.
+.PP
+When a block is allocated, sometimes there is some extra unused space at the end.
+.I Msize
+grows the block to encompass this unused space and returns the new number
+of bytes that may be used.
+.PP
+.I Secalloc
+and
+.I secfree
+are security-aware functions that use a pool flagged by
+.B POOL_ANTAGONISM
+(see
+.IR pool (2)),
+which fills every allocated block with garbage before and after its
+use, to prevent leakage.
+.PP
+The memory allocator maintains two word-sized fields
+associated with each block, the ``malloc tag'' and the ``realloc tag''.
+By convention, the malloc tag is the PC that allocated the block,
+and the realloc tag the PC that last reallocated the block.
+These may be set or examined with 
+.IR setmalloctag ,
+.IR getmalloctag ,
+.IR setrealloctag ,
+and
+.IR getrealloctag .
+When allocating blocks directly with
+.I malloc
+and
+.IR realloc ,
+these tags will be set properly.
+If a custom allocator wrapper is used,
+the allocator wrapper can set the tags
+itself (usually by passing the result of
+.IR getcallerpc (2) 
+to 
+.IR setmalloctag )
+to provide more useful information about
+the source of allocation.
+.SH SOURCE
+.B /sys/src/9/port/alloc.c
+.SH DIAGNOSTICS
+All functions except
+.I smalloc
+return a null pointer if space is unavailable.
+If the allocated blocks have no malloc or realloc tags,
+.I getmalloctag
+and
+.I getrealloctag
+return
+.BR ~0 .
+.SH SEE ALSO
+.IR pool (2),
+.IR xalloc (9)
--- /dev/null
+++ b/sys/man/9/panic
@@ -1,0 +1,25 @@
+.TH PANIC 9
+.SH NAME
+panic \- abandon hope, all ye who enter here
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+void	panic(char *fmt, ...)
+.SH DESCRIPTION
+.I Panic
+writes a message to the console and
+causes the system to give up the host.
+It enables interrupts, dumps the kernel stack,
+and halts the current processor;
+if more than one, others will gradually come to a halt.
+Depending on configuration settings, the platform-dependent
+.I exit
+might reboot the system.
+The format
+.I fmt
+and associated arguments are the same as those for
+.IR print (9).
+.I Panic
+adds a prefix
+.L "panic: "
+and a trailing newline.
--- /dev/null
+++ b/sys/man/9/qlock
@@ -1,0 +1,138 @@
+.TH QLOCK 9
+.SH NAME
+qlock, qunlock, canqlock, rlock, runlock, wlock, wunlock \- serial synchronisation
+.SH SYNOPSIS
+.de PB
+.PP
+.ft L
+.nf
+..
+.PB
+typedef struct
+{
+	Lock	use;			/* to access Qlock structure */
+	Proc	*head;		/* next process waiting for object */
+	Proc	*tail;		/* last process waiting for object */
+	int	locked;		/* flag */
+} QLock;
+.PB
+typedef struct
+{
+	Lock		use;
+	Proc		*head;	/* list of waiting processes */
+	Proc		*tail;
+	uintptr	wpc;		/* pc of writer */
+	Proc		*wproc;	/* writing proc */
+	int		readers;	/* number of readers */
+	int		writer;	/* number of writers */
+} RWlock;
+.ta \w'\fLvoid 'u
+.PP
+.B
+void	eqlock(QLock *l)
+.PP
+.B
+void	qlock(QLock *l)
+.PP
+.B
+void	qunlock(QLock *l)
+.PP
+.B
+int	canqlock(QLock *l)
+.PP
+.B
+void	rlock(RWlock *l)
+.PP
+.B
+void	runlock(RWlock *l)
+.PP
+.B
+int	canrlock(RWlock *l)
+.PP
+.B
+void	wlock(RWlock *l)
+.PP
+.B
+void	wunlock(RWlock *l)
+.SH DESCRIPTION
+The primitive locking functions described in
+.IR lock (9)
+guarantee mutual exclusion, but they implement spin locks,
+and should not be used if the process might
+.IR sleep (9)
+within a critical section.
+The following functions serialise access to a resource by forming an orderly
+queue of processes.
+.PP
+Each resource to be controlled is given an associated
+.B QLock
+structure; it is usually most straightforward to put the
+.B QLock
+in the structure that represents the resource.
+It must be initialised to zero before use
+(as guaranteed for global variables and for structures allocated by
+.IR malloc ).
+.PP
+On return from
+.IR qlock ,
+the process has acquired the lock
+.IR l ,
+and can assume exclusive access to the associated resource.
+If the lock is not immediately available, the requesting process is placed on a
+FIFO queue of processes that have requested the lock.
+Processes on this list are blocked in the
+.L Queueing
+state.
+.PP
+.I Eqlock
+is an interruptible form of
+.IR qlock.
+.PP
+.I Qunlock
+unlocks
+.I l
+and schedules the first process queued for it (if any).
+.PP
+.I Canqlock
+is a non-blocking form of
+.IR qlock .
+It tries to obtain the lock
+.I l
+and returns true if successful, and 0 otherwise;
+it always returns immediately.
+.PP
+.B RWlock
+is a form of lock for resources that have distinct readers and writers.
+It allows concurrent readers but gives each writer exclusive access.
+A caller announces its read or write intentions by choice of lock (and unlock) function;
+the system assumes the caller will not modify a structure accessed under read lock.
+.PP
+.I Rlock
+acquires
+.I l
+for reading.
+The holder can read but agrees not to modify the resource.
+There may be several concurrent readers.
+.I Canrlock
+is non-blocking: it returns non-zero if it successfully acquired the lock immediately,
+and 0 if the resource was unavailable.
+.PP
+.I Runlock
+returns a read lock;
+the last reader out enables the first writer waiting (if any).
+.PP
+.I Wlock
+acquires a write lock.
+The holder of such a lock may assume exclusive access to the resource,
+and is allowed to modify it.
+.PP
+.I Wunlock
+returns a write lock.
+The next pending process, whether reader or writer, is scheduled.
+.SH SOURCE
+.B /sys/src/9/port/qlock.c
+.br
+.SH SEE ALSO
+.IR lock (9),
+.IR malloc (9),
+.IR splhi (9)
--- /dev/null
+++ b/sys/man/9/sleep
@@ -1,0 +1,125 @@
+.TH SLEEP 9
+.SH NAME
+sleep, wakeup, tsleep, return0 \- process synchronisation
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+void	sleep(Rendez *r, int (*f)(void*), void *arg)
+.PP
+.B
+void	wakeup(Rendez *r)
+.PP
+.B
+void	tsleep(Rendez *r, int (*f)(void*), void *arg, ulong ms)
+.PP
+.B
+int	return0(void *arg)
+.PP
+.SH DESCRIPTION
+A process running in the kernel can use these functions to
+synchronise with an interrupt handler or another kernel process.
+In particular, they are used by device drivers to wait for an event to be signalled on
+receipt of an interrupt.
+(In practice, they are most often used indirectly, through
+.IR qio (9)
+for instance.)
+.PP
+The caller of
+.I sleep
+and a caller of
+.I wakeup
+share a
+.B Rendez
+structure, to provide a rendezvous point between them
+to synchronise on an event.
+.I Sleep
+uses a condition function
+.I f
+that returns true if the event has occurred.
+.PP
+.I Sleep
+evaluates
+.IB f ( arg ).
+If true, the event has happened and
+.I sleep
+returns immediately.
+Otherwise,
+.I sleep
+blocks on the event variable
+.IR r ,
+awaiting
+.IR wakeup .
+.PP
+.I Wakeup
+is called by either a process or an interrupt handler to wake any process
+sleeping at
+.IR r ,
+signifying that the corresponding condition is true (the event has occurred).
+It has no effect if there is no sleeping process.
+.PP
+.I Tsleep
+is similar to
+.IR sleep ,
+except that if the condition
+.IB f ( arg )
+is false and the caller does sleep,
+and nothing else wakes it within
+.I ms
+millliseconds,
+the system will wake it.
+.IR Tsleep 's
+caller must check its environment to decide whether timeout or the event
+occurred.
+The timing provided by
+.I tsleep
+is imprecise, but adequate in practice for the normal use of protecting against
+lost interrupts and otherwise unresponsive devices or software.
+.PP
+.I Return0
+ignores its arguments and returns zero. It is commonly used as
+the predicate
+.I f
+in a call to
+.I tsleep
+to obtain a time delay, using the
+.B Rendez
+variable
+.B sleep
+in the
+.B Proc
+structure, for example:
+.IP
+.B tsleep(&up->sleep, return0, nil, 10);
+.PP
+Both
+.I sleep
+and
+.I tsleep
+can be interrupted by
+.IR swiproc
+(see
+.IR kproc (9)),
+causing a non-local goto through a call to
+.IR error (9).
+.SH SOURCE
+.B /sys/src/9/port/proc.c
+.br
+.B /sys/src/9/port/sysproc.c
+.SH DIAGNOSTICS
+There can be at most one process waiting on a
+.BR Rendez ,
+and if two processes collide, the system will
+.IR panic (9)
+.RB (`` "double sleep" '').
+Access to a
+.B Rendez
+must therefore be serialised by some other mechanism, usually
+.IR qlock (9).
+.SH SEE ALSO
+.IR lock (9),
+.IR qlock (9),
+.IR delay (9)
+.br
+``Process Sleep and Wakeup on a Shared-memory Multiprocessor'',
+in
+.I "Plan 9 Programmer's Manual: Volume 2".
--- /dev/null
+++ b/sys/man/9/splhi
@@ -1,0 +1,56 @@
+.TH SPLHI 9
+.SH NAME
+splhi, spllo, splx, islo \- enable and disable interrupts
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+int	spllo(void)
+.PP
+.B
+int	splhi(void)
+.PP
+.B
+void	splx(int x)
+.PP
+.B
+int	islo(void)
+.SH DESCRIPTION
+These primitives enable and disable maskable interrupts on the current
+processor.
+Generally, device drivers should use
+.I ilock
+(see
+.IR lock (9)),
+.IR sleep (9),
+or the functions in
+.IR qio (9)
+to control interaction between processes and interrupt handlers.
+Those routines (but not these) provide correct synchronisation on multiprocessors.
+.PP
+.I Spllo
+enables interrupts and returns a flag representing the previous interrupt enable state.
+It must not normally be called from interrupt level.
+.PP
+.I Splhi
+disables all maskable interrupts and returns the previous interrupt enable state.
+The period during which interrupts are disabled had best be short,
+or real-time applications will suffer.
+.PP
+.I Splx
+restores the interrupt enable state to
+.IR x ,
+which must be a value returned
+by a previous call to
+.I splhi
+or
+.IR spllo .
+.PP
+.I Islo
+returns true (non-zero) if interrupts are currently enabled, and 0 otherwise.
+.SH SOURCE
+.B /sys/src/9/*/l.s
+.SH SEE ALSO
+.IR lock (9),
+.IR qio (9),
+.IR sleep (9),
+.IR intrenable (9)
--- /dev/null
+++ b/sys/man/9/xalloc
@@ -1,0 +1,81 @@
+.TH XALLOC 9
+.SH NAME
+xalloc, xallocz, xspanalloc, xfree, xsummary \- basic memory management
+.SH SYNOPSIS
+.ta \w'\fLvoid* 'u
+.B
+void*	xalloc(ulong size)
+.PP
+.B
+void*	xallocz(ulong size, int clr)
+.PP
+.B
+void*	xspanalloc(ulong size, int align, ulong span)
+.PP
+.B
+void	xfree(void *p)
+.PP
+.B
+void	xsummary(void)
+.SH DESCRIPTION
+These are primitives used by higher-level memory allocators in the kernel,
+such as
+.IR malloc (9).
+They are not intended for use directly by most kernel routines.
+The main exceptions are routines that permanently allocate large structures,
+or need the special alignment properties guaranteed by
+.IR xspanalloc .
+.PP
+.I Xalloc
+returns a pointer to a range of size bytes of memory. The memory will be zero filled and aligned on a 8 byte
+.RB ( BY2V )
+address. If the memory is not available,
+.B xalloc
+returns a null pointer.
+.PP
+.I Xmallocz
+will clear the memory after allocation if
+.I clr
+is set to a value other than zero. Since it is used by
+.IR xmalloc ,
+the same diagnostics apply.
+.PP
+.I Xspanalloc
+allocates memory given alignment and spanning constraints.
+The block returned will contain
+.I size
+bytes, aligned on a boundary that is
+.BI "0 mod" " align,"
+in such a way that the memory in the block does not
+span an address that is
+.BI "0 mod" " span."
+.I Xspanalloc
+is intended for use
+allocating hardware data structures (eg, page tables) or I/O buffers
+that must satisfy specific alignment restrictions.
+If
+.I xspanalloc
+cannot allocate memory to satisfy the given constraints, it will
+.IR panic (9).
+The technique it uses can sometimes cause memory to be wasted.
+Consequently,
+.I xspanalloc
+should be used sparingly.
+.PP
+.I Xfree
+frees the block of memory at
+.IR p ,
+which must be an address previously returned by
+.I xalloc
+(not
+.IR xspanalloc ).
+.PP
+.I Xsummary
+dumps memory allocation statistics to the console.
+The output includes the total free space, the number of free holes,
+and a summary of active holes.
+Each line shows `address top size'.
+.SH SOURCE
+.B /sys/src/9/port/xalloc.c
+.SH SEE ALSO
+.IR malloc (9)