
			PowerPC KERNEL PROJECT (1994/188)
			=================================

This document describes the interfaces implemented for system calls, traps
and signals.

Signals:
-------

The signal codes are same as Sparc/X86 implementation. A copy of the
uts/ppc/sys/machsig.h is attached. The semantics of implementation for
calling the user signal handler is similar to Sparc.

The user signal handler 'hdlr' is called as:

	hdlr(int signo, siginfo_t *sip, ucontext_t *uc)

The arguments are passed in registers according to the normal linkage
conventions:

	r3 = signal number
	r4 = siginfo pointer or NULL if no siginfo is available
	r5 = ucontext pointer

	LR = -1 (invalid return pc in Link Register)
	0(sp) = old stack pointer

The signal frame created on the user stack looks like:

	^			^	HIGH ADDR (bottom)
	|			|
	:			:
	|-----------------------| <== old sp
	|			|
	| ucontext structure	| size1 = sizeof(ucontext_t)
	|			|
	|-----------------------| <== r5
	|			|
	| siginfo structure	| size2 = sizeof(siginfo_t) or 0
	| if it is available	|
	|			|
	|-----------------------| <== r4 (NULL if no siginfo)
	|			|
	| MINFRAME		| size3 = MINFRAME
	|			|
	|-----------------------| <== sp (SA(old_sp-(size1+size2+size3)))
	|			|
	|			|
	v			v	LOW ADDR (top)

System calls:
------------

The list of system calls supported, the system call numbers and the semantics
of the implementation for PPC is same as on Sparc.

	Note: The system call entry table in the kernel is defined in the
	      common file 'common/os/sysent.c' which has no changes for
	      PPC.

Syscall instruction:

	The 'sc' (system-call) instruction is used for trapping into
	the kernel.

Syscall arguments:

	Since the max numbers of arguments to a system call is limited to 8
	(MAXSYSARGS is defined in common/sys/lwp.h) all the arguments to the
	system call are already in the volatile registers (r3 - r10).

	The system call number is passed in the volatile register r0.

Return value(s);

	The return value(s) from the system call are passed in r3 and r4
	as in Sparc (%o0 and %o1).

Error return:

	The error code is returned in r3. The summary overflow bit (CR0_SO)
	in the condition register CR0 indicates error return.

Restartable system calls: (e.g. fcntl, getmsg, getpmsg, ioctl, etc.)

	For restartable system calls we need to save the first argument
	because upon return from the system call r3 is clobbered. For this,
	the system call stub in the library copies r3 into r10 and restores
	it before restarting the system call. The volatile register r10
	is used because none of the restartable system calls have more than
	5 arguments (i.e only r3-r7 are used). If the restartable system
	call has more than 7 arguments then the system call stub in the
	library need to create a stack frame for saving the first argument.

	The list of all the restartable system calls:

	Name		# args
	================================
	fcntl()		2+
	getmsg()	4
	getpmsg()	5
	ioctl()		2+
	lwp_mutex_lock()1
	poll()		3
	pread()		4
	putmsg()	4
	putpmsg()	5
	pwrite()	4
	read()		3
	readv()		3
	lwp_sema_wait()	1
	wait()		1
	waitid()	4
	write()		3
	writev()	3

	Note: The list of restartable system calls are same as on Sparc/X86.

Fast system calls:
-----------------

This is a private interface between the libraries and the kernel.
The current list of fast system calls implemented for PPC:

	fast syscall#s
	--------------
	SC_GETLWPFPU	1	To find out if FPU context is setup for the lwp.
				This is used in the threads library. There are
				no arguments to this system call. It returns
				the value of the pcb_flags (from the kernel
				lwp structure) in r3.
	SC_GETHRTIME	2	Same as on Sparc/x86.
	SC_GETHRESTIME	3	Same as on Sparc/x86.
	SC_GETHRVTIME	4	Same as on Sparc/x86.

Fast system call instruction:

	The regular system call instruction 'sc' is used with the system
	call number as -1 in r0 and fast system call number in r3. The
	system call interrupt handler in the kernel checks for the fast system
	calls. For invalid fast system calls the kernel returns ENOSYS
	error.

Exceptions/Traps:
----------------

Only the breakpoint traps and floating point exceptions are discussed here.
Other exceptions/traps are within the kernel and their interface is not
exported outside the kernel.

Breakpoint traps:

	On PowerPC the trap instruction tw/twi (similar to trap instruction
	't' on Sparc) can be used to generate program exceptions. For Solaris
	port to PPC we are using 'tw 31,0,0' (i.e trap unconditional)
	instruction for breakpoint traps. The kernel trap handler for 'program
	check exception' decodes the trap instruction and it currently
	recognizes only the breakpoint instruction. For other tw/twi
	instructions the kernel generates SIGILL signal.

	Note: On PowerPC hw breakpoints are supported thru the implementation
	      specific HID registers (implemented differently on different
	      CPU architectures) and these are currently not supported in
	      Solaris for PPC.

	The signal code SIGTRAP and fault code TRAP_BKPT is generated for
	breakpoint traps.

Floating point exceptions:

	On PowerPC a 'program check exception' is generated when a floating
	instruction causes an enabled exception. The PowerPC ABI specifies
	the initial value of FPSCR (Floating Point Status and Control Register)
	which enables floating point exceptions. The following are the
	signal codes for different floating enabled exceptions.

		FPE_FLTOVF	For floating point overflow exception.
		FPE_FLTUND	For floating point underflow exception.
		FPE_FLTDIV	For floating point zero divide exception.
		FPE_FLTRES	For floating point inexact result exception.
		FPE_FLTINV	For other floating point exceptions.

	The signal number SIGFPE is generated for any of the floating enabled
	exceptions.

Other interesting traps/exceptions:

	Alignment trap:
		The kernel generates SIGBUS signal with a fault code
		of FLTACCESS.
	Text/Data faults:
		The signal codes and fault codes are similar to Sparc/X86.
	Illegal instruction trap (thru 'program check exception'):
		The signal code (SIGILL) and fault code (ILL_ILLOPC)
		are same as on Sparc/X86.
	Privileged instruction trap (thru 'prgoram check exception'):
		The signal code (SIGILL) and fault code (ILL_PRVOPC)
		are same as on Sparc/X86.
	Single Step trap ('trace trap' on PowerPC, 'run mode trap' on 601):
		The signal code (SIGTRAP) and fault code (TRAP_TRACE)
		are same as on Sparc/X86.
