TABLE OF CONTENTS

mmu.library/--Background--
mmu.library/CreateContext
mmu.library/DeleteContext
mmu.library/EnterContext
mmu.library/LeaveContext
mmu.library/CurrentContext
mmu.library/ProtectContext		
mmu.library/UnprotectContext
mmu.library/AddContextHook
mmu.library/RemContextHook
mmu.library/AddMessageHook
mmu.library/RemMessageHook
mmu.library/GetPageSize	
mmu.library/GetPageSize
mmu.library/SetAttributesA		
mmu.library/GetAttributesA
mmu.library/AllocPage
mmu.library/AllocAligned
mmu.library/--Background--							mmu.library/--Background--
PRELIMINARY PRELIMINARY PRELIMINARY PRELIMINARY PRELIMINARY PRELIMINARY

	PURPOSE
		The mmu.library provides functions for MMU related operations
		as write- or read-protecting certain areas of memory for a
		given set of tasks, or marking memory regions as "swapped"
		virtual memory support. It offers an abstraction level on top
		of the actual MMU and a unified interface for MMU purposes.

		The MMU lib does NOT implement virtual memory, that's the purpose
		of another library - the memory.library. There's no much reason why
		any application except the memory.library and probably some debugging
		tools should call this library directly. The memory.library functions
		on top of this library should suffer for "all day purposes".

		The basic object administrated by this library is the "context". A
		"context" is the software abstraction of a MMU translation tree, it
		keeps the information of the status of memory. The mmu.library 
		provides a "global" context that represents the MMU translation tree
		for all tasks. It is build by the init code of the library either by
		snooping the already existing MMU translation tree or by building an
		own tree by looking at the available memory and expansion devices.

		Programs can build own contexts by using the MMU library functions and
		may enter or leave the contexts generated in this way. Several tasks
		may share one context, as they represent, for example, multiple 
		"threads" of one single program. Thus, the notation used here is some-
		how turned around: A "context" in the amiga world is called "process"
		in unix, and a "task" or "process" in the amiga world is called a
		"thread" usually.

		Tasks that do not enter an own context explicitly share the common
		global context. Even though it is possible to change the global 
		context, this technique should be used only by debugging tools as the
		enforcer. It could, for example, mark unused areas of the memory as
		well as the first 4K as "invalid".

		The MMU library provides two "hooks" for each context, the 
		"bus error hook" and the "segmentation fault" hook. The first hook
		is called if an access to an invalid memory location is detected, or
		a write to a read-only memory area. The second is called if an access
		to a memory page marked as "swapped out" is detected. It's part of
		the service of the MMU library to keep these two access violations
		apart.

		The default hooks call simply the exception handler of the running
		task, which generates by default the well known "guru". It's up to
		programs on top of the MMU library to setup useful hooks. An enforcer
		like tool might set "bus error hook" to print some useful information
		about the access violation, the memory.library will set the 
		"segmentation fault" hook to swap in the memory in question.

		The hooks are really "low-level" routines and are executed in super-
		visor mode, and therefore very limited in power.

		The library provides itself a ready-for-use hook function which
		sends a message to a task to be specified and suspends the task
		that caused the bus error until the message is replied.

mmu.library/CreateContext							mmu.library/CreateContext							mmu.library/CreateContext

	NAME
		CreateContext - Build a new MMU context.

	SYNOPSIS
		context = CreateContext();
		d0		

		Context * CreateContext (void);
		
	FUNCTION
		This function builds a new MMU context.

		The context created will be a copy of the global context, with
		all memory regions marked in the same way and the same hooks
		installed.

	INPUTS
		none.

	RETURNS
		NULL if the new context couldn't be created or a handle to the
		new context, as parameter to all MMU library functions.

	NOTES
		This call makes NOT the current task entering the new context,
		you've to call EnterContext() explicitly for that purpose.

		The context structure is not documented intentionally. It depends
		on the implementation.

	SEE ALSO
		DeleteContext()

	BUGS

mmu.library/DeleteContext							mmu.library/DeleteContext
	
	NAME
		DeleteContext - delete an MMU context build with CreateContext.

	SYNOPSIS
		DeleteContext ( context );
						a0

		VOID DeleteContext ( Context * );

	FUNCTION
		This function deletes a context build with CreateContext().


	INPUTS	 
		A handle to the context to be deleted.

	RETURNS
		nothing.

	NOTES
		This call doesn't remove any task from the context, especially the
		current task is NOT removed from the context. You've to call
		LeaveContext() before.

		Deleting a context with some tasks still in this context will
		cause this function to guru.

	SEE ALSO
		CreateContext()

mmu.library/EnterContext							mmu.library/EnterContext

	NAME
		EnterContext - let a task enter a specific context.

	SYNOPSIS
		context = EnterContext( context , task );
		d0					   a0		 a1

		Context * EnterContext(Context *,struct Task *);

	FUNCTION
		Add a given task to a context. This makes the MMU settings defined
		by the context available for the task in question.

	INPUTS
		context - the context to enter or NULL for the global context.
		task	- a pointer to the task structure that should enter the
				context.

	RETURNS
		a handle to the context the task participated before or NULL if
		this function failed. The task will stay in the last context used
		in this case.

	NOTES
		This call uses the tc_Switch() and tc_Launch() functions of the
		task structure. What basically happens here is that these functions
		are set to internal procedures that swap the context specific
		MMU table or the global MMU in and flush the ATC of the MMU.

		This call may fail, check the return code for NULL - either due to
		lack of memory or because the task is part of a protected context
		the current task hasn't entered.

		If you want to use the tc_Switch() and tc_Launch() functions your-
		self, you should install a task specific context hook, see 
		AddContextHook().

	SEE ALSO
		LeaveContext(),ProtectContext(), exec/tasks.h

mmu.library/LeaveContext							mmu.library/LeaveContext
	
	NAME
		LeaveContext - remove a given task from a context.

	SYNOPSIS
		context = LeaveContext( task );
		d0						a1

		Context * LeaveContext( struct Task *);

	FUNCTION
		The specified task leaves its context and enters the global context.

	INPUTS
		task - the task that should leave a private context and enter the
			global default context.

	RETURNS
		the context the task was added to or NULL on failure.
		Might be the global default context if the task did not enter any 
		context.

	NOTES
		It is safe to call this function even if the task wasn't added to
		any context. The function returns the global context in this case.

		This function must be called to any task participating a given
		context to be able to delete that context.

		This function is equivalent to EnterContext(NULL,task). 

		This function makes use of the tc_Switch() and tc_Launch() functions
		of the task structure to be able to set the MMU root pointer.

		Make sure that you check for failure. This call may return NULL if
		the task entered a protected context the current task does not
		participate.

		You should also remove all task specific context hooks if you
		leave a context because they slow down exception handling, see
		RemContextHook().

	SEE ALSO
		EnterContext(), DeleteContext(), ProtectContext(), 
		RemContextHook(), exec/tasks.h

mmu.library/CurrentContext							mmu.library/CurrentContext

	NAME
		CurrentContext - find out the current context of a task.

	SYNOPSIS
		context = CurrentContext( task );
		d0						  a1

		Context * CurrentContext(struct Task *);

	FUNCTION
		This function is used to get a handle to the context the given
		task is added to, or to return the global context.

	INPUTS
		task - the address of the task structure you like to investigate
		or NULL to get a handle to the global context.

	RETURNS
		a handle to the context the given task is added to, the global
		context if the argument is NULL or NULL on failure.

	NOTES
		This call fails only if the given task is part of a protected
		context which is not shared by the current task. To get the
		context of the current task, use CurrentContext(FindTask(NULL)).

	SEE ALSO
		ProtectContext(), FindTask()

mmu.library/ProtectContext							mmu.library/ProtectContext

	NAME
		ProtectContext - protect a context from being investigated.

	SYNOPSIS
		ProtectContext( context );
						a0

		VOID ProtectContext( Context * );

	FUNCTION
		This function protects a context from getting investigated by any
		task except by those that already entered the context. Modifying or
		scanning this context by any task except except these is prohibited
		by the MMU library and creates a guru.

	INPUTS
		A handle to the context to be protected.

	RESULTS
		none.

	NOTES
		This can be used to protect security relevant data, as a password
		daemon for a multiuser system. Contexts created with CreateContext()
		are by default unprotected.

		Calling this on the global context will create a guru.

		This is a security relevant function and probably the number one
		attack point for "cracking" the system. The MMU library might
		therefore copy its library base and its vector offsets to an
		access restricted area such that the function calls cannot be
		altered by SetFunction(). The Supervisor() function is of course
		a peephole, as it allows direct access to the MMU registers. A
		multi user system build on top of the MMU library is therefore
		very tricky and should probably emulate the supervisor mode by
		patching the Supervisor() and related functions.

	SEE ALSO
		UnprotectContext()

mmu.library/UnprotectContext					mmu.library/UnprotectContext

	NAME
		UnprotectContext - open a context to the public.

	SYNOPSIS

		UnprotectContext( context );
						  a0

		VOID UnprotectContext ( Context * );
		
	FUNCTION
		This call removes the protection from a given context and, thus, 
		makes it available to be modified by all tasks.

	SEE ALSO
		ProtectContext()

mmu.library/AddContextHook							mmu.library/AddContextHook

	NAME
		AddContextHook - set an exception handler to a Context

	SYNOPSIS
		AddContextHook( context, irq, task, type );
						  a0	  a1   a2   d0

		VOID AddContextHook( Context *, 
				 		     struct Interrupt *, struct Task *,
							 ULONG type);
	FUNCTION
	    This call installs an exception hook for a given context for
	    various exception types the MMU library can provide.

	INPUTS
		context - the context the exception hook should be set for.
		irq		- an Interrupt structure that keeps address for the hook.
			Interrupts are sorted by priority in the exception hook list,
			the default hook of the mmu.library, which just throws a
			guru sits at priority -128.
			The interrupt structure MUST stay valid until the hook is
			removed with RemContextHook later. DO NOT try to modify
			the data in the irq structure "on the fly", that won't work.
			To change the hook function, add another hook, then remove
			the old one.

			The hook code MUST be ready for working when this function
			is called, there's nothing that can protect the hook from
			being called as soon as it is installed. You MAY NOT install
			the same interrupt structure twice.
	
			The hook is called in supervisor mode with the data pointer 
			both in a1 and a4 and the type field of this call in d0. 
			Registers d0-d1/a0-a1/a4-a6 can be used as scratch registers.
			Since the supervisor stack is used, stack space is limited
			and the timing is critical. Avoid lenghty operations, try
			to modify the exd_ReturnPC of the structure below to post-
			pone operations to the user mode. Almost NO operating system
			functions may be called in supervisor mode!

			The following structure is passed in in register *a0:

	struct ExceptionData {
		struct Task		*exd_Task;
				/* 	The task that created the hook */
		void			*exd_FailAddress;
				/* 	The address that was accessed */
		void 			**exd_ReturnPC;
				/* 	This can be modified to resume exception
				   	handling at a different address in user mode.
				   	Keep the original PC to restart the instruction
				   	that caused the exception. */
		ULONG			  exd_Flags;
				/* user setable flags. There's currently only
				   one flag documented:
					EXDF_CONTINUE
				   If this is set, the mmu.library will try to
				   emulate the access to the faulty page and
				   return the data in the next field if the faulty	
				   instruction is a read instruction. It will do nothing
				   on a faulty write. This might be very tricky, indeed!
				*/
		ULONG			 exd_ReadPipe;

		ULONG			 exd_BlockID;
				/* the blockID associated to the page the fault occurred */
		ULONG			 exd_ExceptionType;
		struct ExecBase *exd_SysBase;	
				/* Accessing AbsExecBase might be FATAL, use this copy! */
	};
	
			The hook must return a flag value in d0. If this is set to true,
			then the hook CANNOT handle the exception and the data is
			passed to the next hook. If set to false, the exception was
			handled by the hook.

		task	- set this to NULL if the hook should be called for any
			task in the context, or to a struct Task * if the hook
			should be called for a specific task only.

			Be warned! Adding hooks slows down the exception handling,
			so avoid using too many task specific hooks.

		type	- type of the hook to be set. Currently defined are:

				MMUEH_BUSERROR	- set the bus error hook. It is called
					whenever a bus error is generated by something else
					than the MMU.

				MMUEH_SEGFAULT	- set the segmentation fault exception
					hook. Called whenever access is made to a page that
					does not belong to the context, is write protected
					or is accessible in supervisor mode only.

				MMUEH_SWAPPED	- sets the swap-out page fault hook. 
					Called whenever the mmu.library detects access to
					a page that is currently not swapped in.
				
				MMUEH_SWITCH	- sets the switch context hook. Called
					whenever a task of this context loses the CPU.

				MMUEH_LAUNCH	- sets the launch context hook. Called
					whenever a task of the context gains control of the
					CPU. The exd_FailAddress will be NULL for both hooks.

	RESULTS
		none.

	NOTES
		this call will be used by the high-level function AddMessageHook()
		below. 
		The bus error hook may be set by a debugging tool like the enforcer.

	SEE ALSO
		RemContextHook(), exec/interrupts.h

mmu.library/RemContextHook							mmu.library/RemContextHook

	NAME
		RemContextHook - remove an exception handler from a Context

	SYNOPSIS
		RemContextHook( context, irq, type );
						  a0	  a1  d0

		RemContextHook( Context *, 
				 		struct Interrupt *, 
						ULONG type);
	FUNCTION
		This function removes a previously installed context hook
		from the hook list.

	INPUTS
		context - the context the exception hook should be removed from.
		irq		- the same interrupt structure that has been passed in
			for AddContextHook.

			Warning: If you remove your hook, the mmu.lib default hook
			may become active again - which means that whenever an
			exception is generated, the system will guru.

		type	- type of the hook to be removed. Currently defined are:

				MMUEH_BUSERROR	
				MMUEH_SEGFAULT
				MMUEH_SWAPPED
				MMUEH_SWITCH
				MMUEH_LAUNCH

				check AddContextHook() for details.

	RESULTS
		none.

	NOTES

	SEE ALSO
		AddContextHook(), exec/interrupts.h
mmu.library/AddMessageHook							mmu.library/AddMessageHook

	NAME
		AddMessageHook - install a high-level hook function.

	SYNOPSIS
		handle = AddMessageHook( context, port, task, 
								   a0     a1    a2    

								 type, pri, userdata );
								  d0    d1     a3



		MsgHook * AddMessageHook(	Context *,
							  	struct MsgPort *, struct Task *,
								ULONG ,BYTE , void *);

	FUNCTION
		Installs a high-level hook for a given task and context of given
		type. As soon as an exception of the requested type occurs, an
		exception message (see below) will be sent to the port. The task
		that caused the exception will be halted until the message gets
		replied.
		BE WARNED: Message hooks perform only operation if task switching
		is enabled and interrupts are allowed. They will just "drop thru"
		to the next handler if this is not the case.

	INPUTS
		context - the MMU context handle for which the hook should be
			installed.

		port - a pointer to a message port which receives a message as
			soon as the requested exception occurs.

		task - a pointer to the task for which this message hook should
			be installed. MUST BE NON-NULL! Message hooks are always
			task sensitive as they use the message system of the exec.lib.
			for all tasks in the context.

		type - the type of exception which should generate. Currently 
			defined are:

				MMUEH_BUSERROR	
				MMUEH_SEGFAULT
				MMUEH_SWAPPED

			The following types are valid BUT CANNOT be used by
			the message hook system (for obvious reasons):

				MMUEH_SWITCH
				MMUEH_LAUNCH
	
		pri - the priority at which the hook should go. The system handler
			(which just throws a guru) sits at priority -128 and should not
			be replaced.

		userdata - whatever you like to pass in.

		On an exception, the following message will be sent to the port:

		struct ExceptionMessage {
			struct Message			exm_msg;
			UWORD					exm_cludgefill;
			void				   *exm_UserData;
			struct ExceptionData 	exm_Data;
		};

	RESULTS
		a handle for the exception that must be passed back to 
		RemMessageHook() for removal or NULL on failure.
		Do not interpret this handle.
		
	NOTES
		this function is used by the memory.library to install its
		exception handler. The port will be in this case the port of
		the swapper daemon that loads swapped out pages from disk.
		
	SEE ALSO
		AddContextHook(), RemContextHook(), RemMessageHook()

mmu.library/RemMessageHook							mmu.library/RemMessageHook

	NAME
		RemMessageHook	-	remove a high-level hook from a context.

	SYNOPSIS
		RemMessageHook( handle );
						 a1

		VOID RemMessageHook( MessageHook * );


	FUNCTION
		This function removed a previously installed Message hook from
		the hook list of the context.

	INPUTS
		handle - a handle to the message hook as returned by the 
			AddMessageHook function.

	RESULTS
		none.

	NOTES
		This call will first remove the low-level hook function and
		then wait for the return of the sent exception message.
		You should, therefore, not call this function from the same task
		that handles the exception.
		
	SEE ALSO
		AddMessageHook(), AddContextHook(), RemContextHook()

mmu.library/GetPageSize								mmu.library/GetPageSize

	NAME
		GetPageSize - return the page size of a context.

	SYNOPSIS
		pagesz = GetPageSize( context );
		d0					  a0

		ULONG GetPageSize( Context * );

	FUNCTION
		This function returns the page size selected by the MMU library for
		the given context. Possible page sizes are limited by the hardware
		and cannot be adjusted from the outside. 

	INPUTS
		context - a handle to the context to be investigated or NULL for
			the global context.

	RESULT
		the page size in bytes or zero for failure.

	NOTES
		The result will usually not depend on the input, even though the
		library checks whether the input is really valid.

		The call will fail if the given context is protected.

	SEE ALSO
		ProtectContext()

mmu.library/SetAttributesA							mmu.library/SetAttributesA

	
	NAME
		SetAttributesA - set memory attributes for a given logical range.

	SYNOPSIS

		result = SetAttributesA( context, flags, mask, lower, size, tags);
		d0						 a0		  d1	 d2    a1		d0	  a2

		BOOL SetAttributesA( Context *, ULONG, void *, ULONG, ULONG,
							 struct TagItem *);


		result = SetAttributes( context, flags, mask, lower, size, tag1, ...);

		BOOL SetAttributes( Context *, ULONG, void *, ULONG, ULONG,
							Tag tag1, ...);

	FUNCTION
		This call sets attributes of a certain page in memory.

	INPUTS
		context - a handle to the context to modify or NULL for the global
			context.

		flags	- a binary flags field for the attributes to define. The
				following bits have been defined:

				MMUA_WRITE_PROTECTED	-	The page will be write 
					protected. 

				MMUA_PRIVATE			-	The page will be marked invalid
					for all but the given contexts.

				MMUA_INVALID			-	The page will be marked as 
					invalid. Accessing it will invoke the bus error hook.

				MMUA_SWAPPED			-	The page will be marked as
					swapped out.

				MMUA_NOCACHE			-	The page will be marked as non-
					cacheable.

				MMUA_PRECISEEXECPTION	-	The page will be marked as pre-
					for the precise exception model. Only available with
					MMUA_NOCACHE and on special MMUs. 

				MMUA_SERIALIZED			-	The page will be marked as
					serialized. Only available with MMUA_NOCACHE and on
					special MMUs.

				MMUA_COPYBACK			-	The page will be marked as
					"copyback" instead of "writethrough". Generally re-
				 	commended since this is faster for the '40 and '60.
					Only available on special MMUs and without NOCACHE.
	
				MMUA_MAPPED				-	Map the page to a different
					memory location. Parameters are given in the tag items.

		mask	-	A bit mask of the attributes to be changed.
		
		lower	-	The lower boundary of the logical address to be 
				modified. This must be aligned to the page size or this call
				will guru.

		size	-	Size of the region to be modified. Must be a multiple
				of the page size.

		tags	-	A tag array with additional data. Currently defined:

				MMUTAG_DESTINATION	-	the physical destination of the
					logical address. Must be provided for the MMUA_MAPPED
					bit. 

				MMUTAG_BLOCKID		-	a unique ID the MMU.library doesn't
					care about, for external usage of the memory.library.
					Must be provided for the MMUA_SWAPPED flag and may be
					used to indicate where on disk the swapped page is
					kept.

		RETURNS
			A boolean success/failure indicator. Might fail if the context
			is protected or no memory is available for the modification.

		NOTES
			The page size can be read with GetPageSize(). It will be usually
			4K or 8K.

			SWAPPED and INVALID memory might be implemented using the same
			MMU attributes (invalid, namely), but the library exception
			handler will filter them out and call the appropriate hook.

			Write protection goes only for the context specified. It makes
			usually sense to mark the memory region as PRIVATE as well, 
			unless you modify the public hook.

			You may freely mark the first memory page as INVALID. Long word
			read accesses to AbsExecBase will be filtered out by the 
			exception handler of the library and will be satisfied trans-
			parently to the program.

		SEE ALSO
			ProtectContext(), GetAttributesA(), SetContextHook(), 
			GetPageSize()

mmu.library/GetAttributesA							mmu.library/GetAttributesA

	
	NAME
		GetAttributesA - get memory attributes for a given logical page. 

	SYNOPSIS

		flags = GetAttributesA( context, lower, tags);
		d0						 a0		 a1		a2

		BOOL GetAttributesA( Context *, void *, struct TagItem *);


		result = GetAttributes( context, lower, tag1, ...);

		BOOL GetAttributes( Context *, void *, Tag tag1, ...);

	FUNCTION
		This call gets attributes of a certain page in memory.

	INPUTS
		context - a handle to the context to investigate or NULL for the
			public context.

		lower	- the logical address of the page to investigate. The
			size of the page depends on the hardware and is selected by
			the MMU library. The number of bytes in a page is returned
			by GetPageSize().

		tags	- additional tags. Currently defined are:

				MMUTAG_PHYISCAL	-	a pointer to a void * where the
					library should place the physical address the given
					logical address is mapped to.

					The void * is not filled if the page is marked as
					swapped out.

				MMUTAG_READID  -	a pointer to a ULONG * which is filled
					with a unique ID for SWAPPED pages. This ID can be
					used to find the block on disk where the page is kept.

					The ULONG * will not be filled if the page is not marked
					as swapped out.

		RETURNS

			Returns a binary flags field for the attributes to define. The
				following bits have been defined:

				MMUA_WRITE_PROTECTED	-	The page will is write 
					protected for the given context.

				MMUA_PRIVATE			-	The page is marked invalid for
					the context.

				MMUA_SWAPPED			-	The page is swapped out.

				MMUA_NOCACHE			-	The page is non-cacheable.

				MMUA_PRECISEEXECPTION	-	The page is non-cacheable and
					accessed in the precise exception model. Only for
					special MMUs.

				MMUA_COPYBACK			-	The page is in copyback cache
					mode instead of writethrough. Only for special MMUs.

				MMUA_SERIALIZED			-	The page is non-cacheable,
					serialized access.

		NOTES
			The page size can be read with GetPageSize(). It will be usually
			4K or 8K.

			The flags returned are valid for the given context, a different
			context may return a different flag setting and even a different
			physical location.

		SEE ALSO
			ProtectContext(), SetAttributesA(), SetContextHook(), 
			GetPageSize()

mmu.library/AllocAligned								mmu.library/AllocAligned

	NAME
		AllocAligned 	-	allocate memory aligned to a given mask.

	SYNOPSIS
		mem = AllocAligned( bytesize, reqments, align );
		d0				    d0		   d1		 a0

		void * AllocAligned( ULONG, ULONG, ULONG);

	FUNCTION
		Allocate memory aligned to certain boundaries.

	INPUTS
		bytesize - the size of the memory to allocate. Must be a multiple
			of the page size

		reqments -	exec style memory attributes

		align	-	the alignment restrictions of the page.

	RETURNS
		a pointer to the allocated memory, aligned to the given mask or
		NULL if no free physical memory could be found.

	NOTES
		This is a service routine for the memory.library and shouldn't be
		used for all-day purposes.

	SEE ALSO
		GetPageSize(), exec/memory.h

