TABLE OF CONTENTS

mmu.library/--Background--
mmu.library/CreateMMUContext
mmu.library/DeleteMMUContext
mmu.library/EnterMMUContext
mmu.library/LeaveMMUContext
mmu.library/CurrentContext
mmu.library/ProtectMMUContext		
mmu.library/UnprotectMMUContext
mmu.library/AddContextHook
mmu.library/RemContextHook
mmu.library/AddMessageHook
mmu.library/RemMessageHook
mmu.library/ActivateException
mmu.library/DeactivateException
mmu.library/GetPageSize	
mmu.library/RemapSize
mmu.library/SetPropertiesA
mmu.library/SetPagePropertiesA
mmu.library/RebuildTree
mmu.library/GetPropertiesA
mmu.library/GetPagePropertiesA
mmu.library/AllocAligned
mmu.library/LockMMUContext
mmu.library/UnlockMMUContext
mmu.library/AttemptLockMMUContext
mmu.library/LockContextList
mmu.library/UnlockContextList
mmu.library/AttemptLockContextList
mmu.library/AllocLineVec
mmu.library/PhysicalPageLocation
mmu.library/PhysicalLocation
mmu.library/DMAInitiate
mmu.library/DMATerminate
mmu.library/GetMapping
mmu.library/ReleaseMapping
mmu.library/SetPropertyList
mmu.library/LockContext
mmu.library/UnlockContext
mmu.library/GetMMUType
mmu.library/SuperContext
mmu.library/DefaultContext
mmu.library/WithoutMMU
mmu.library/--Background--							mmu.library/--Background--

	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 trees are managed on two levels, a "software abstraction level"
		which is comfortable and easy to use. Memory "properties" of large
		regions of memory can be redefined quite easely with one single
		call, but rebuilding the MMU table tree from this abstraction layer
		is a lengthly operation and requires quite a lot of CPU power
		not available in critical applications.
		Therefore, a more "hardware based" approach is available which
		modifies the existing MMU table "on the fly" and is therefore
		rather fast. However, memory pages to be handled like this must
		be marked with the MAPP_SINGLE property to tell the library to
		build the MMU table in a special way to allow fast modification
		and to bypass some possible optimizations (e.g. "early page
		terminators" and "invalid descriptors not at page level").
		Modifications on this level are never seen by the abstraction
		level above and should be used only once the MMU tree is complete.

		If that is, too, not fast enough, the MMU library allows building
		pages using "indirect descriptors". That is, the page property
		flags are given by a true hardware descriptor you provide. This
		makes code CPU specific, obviously, but has the advantage that
		page properties can be modified by a single long word "poke" in
		your program, and the proper ATC flush. This is almost "hardware
		banging", with some support.

		This method has one important drawback, namely that the library
		is no longer able to disable caching for DMA transfer to and from
		this page. Hence, NEVER EVER access an indirect page by DMA.

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

	NAME
		CreateMMUContext - Build a new MMU context.

	SYNOPSIS
		context = CreateMMUContextA ( tags );
		d0							  a0

		context = CreateMMUContext ( tag1, ... ); 


		struct MMUContext * CreateMMUContextA ( struct TagItem *);

		struct MMUContext * CreateMMUContext ( Tag tag1, ... );
		
	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
		tags	-	Tag items for the context to be created. 

		Currently defined tags are:


		MCXTAG_COPY		-	build a copy of the context * passed in,
							if the pointer is NULL, build a copy of
							the global default context.

							If this tag item is not given, all context
							addresses will be marked as MAPP_BLANK. Most
							likely not what you want.
							
		MCXTAG_EXECBASE	-	filter out accesses of AbsExecBase, even if
							page 0 is marked as invalid.
							boolean, defaults to TRUE

	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 EnterMMUContext() explicitly for that purpose.

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

	BUGS

	SEE ALSO
		DeleteMMUContext()

	BUGS

mmu.library/DeleteMMUContext					mmu.library/DeleteMMUContext
	
	NAME
		DeleteMMUContext - delete an MMU context build with CreateMMUContext.

	SYNOPSIS
		DeleteMMUContext ( context );
							a0

		void DeleteMMUContext ( struct MMUContext * );

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


	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
		LeaveMMUContext() before.

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

	BUGS

	SEE ALSO
		CreateMMUContext()

mmu.library/EnterMMUContext						mmu.library/EnterMMUContext

	NAME
		EnterMMUContext - let a task enter a specific context.

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

		struct MMUContext * EnterMMUContext( struct MMUContext * , 
					
									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().

		This function can be used to change the context of a task by
		adding it to a new context. The task specific context switch and
		launch hooks will be "carried over" to the new context, but all
		other MMU specific exceptions are now the matter of the new context.

	BUGS

	SEE ALSO
		LeaveMMUContext(),ProtectMMUContext(), exec/tasks.h

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

	SYNOPSIS
		context = LeaveMMUContext( task );
		d0						a1

		struct MMUContext * LeaveMMUContext( 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 EnterMMUContext(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 or if switch and launch exceptions are in use.

	BUGS

	SEE ALSO
		EnterMMUContext(), DeleteMMUContext(), ProtectMMUContext(), 
		RemContextHook(), exec/tasks.h

mmu.library/CurrentContext							mmu.library/CurrentContext

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

	SYNOPSIS
		context = CurrentMMUContext( task );
		d0						  a1

		struct MMUContext * CurrentMMUContext( struct Task * );

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

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

	RETURNS
		a handle to the context the given task is added to, the global
		context if the task is not attached to any context or the
		currently active context if the argument is NULL. 

	NOTES
		This call fails only if the given task is part of a protected
		context which is not shared by the current task. The NULL
		argument is always safe.

	BUGS
		Protected contexts are not yet implemented.

	SEE ALSO
		ProtectMMUContext(), FindTask()

mmu.library/ProtectMMUContext					mmu.library/ProtectMMUContext

	NAME
		ProtectMMUContext - protect a context from being investigated.

	SYNOPSIS
		ProtectMMUContext( context );
							a0

		void ProtectMMUContext( struct MMUContext * );

	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 
		CreateMMUContext() 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.

	BUGS
		currently not implemented.

	SEE ALSO
		UnprotectMMUContext()

mmu.library/UnprotectMMUContext				mmu.library/UnprotectMMUContext

	NAME
		UnprotectMMUContext - open a context to the public.

	SYNOPSIS

		UnprotectMMUContext( context );
						  a0

		void UnprotectMMUContext ( struct MMUContext * );

	FUNCTION
		This call removes the protection from a given context and, thus, 
		makes it available to be modified by all tasks.

	BUGS
		currently not implemented.

	SEE ALSO
		ProtectMMUContext()

mmu.library/AddContextHook							mmu.library/AddContextHook

	NAME
		AddContextHook - set an exception handler to a Context

	SYNOPSIS
		hook = AddContextHookA ( tags );
								  a0

		hook = AddContextHook ( tag1, ... );

		
		struct ExceptionHook * AddContextHookA ( struct TagItem * );

		struct ExceptionHook * AddContextHook ( Tag tag1, ... );

	FUNCTION
	    This call installs an exception hook for a given context for
	    various exception types the MMU library can provide.

	INPUTS
		tags 	-	A taglist defining the type of the exception hook
					to be added.

		Currently defined are:

		MADTAG_CONTEXT		-	The context to which this exception hook
								should be added. This MUST be given for
								segmentation fault or swapped handlers.

		MADTAG_TASK			-	If the hook should be called only if a
								specific task is running, specify a pointer
								to the task structure here. 
								Warning! Adding too many task specific
								hooks slows things down unnecessary.
								Remember that a MMU Context may hold more
								than one task.
								This MUST be given for the switch and launch
								hooks.

		MADTAG_TYPE			-	Type of the exception hook to build. The
								following types are available:

			MMUEH_SEGFAULT	-	Called on segmentation fault, i.e. write to
								a write protected page or access of an
								invalid page. Most useful for "Enforcer"
								like tools.

			MMUEH_SWAPPED	-	Called on access for a "swapped out" page.
								Most useful to implement virtual memory.

			MMUEH_SWITCH	-	Called when the task looses the CPU.
			MMUEH_LAUNCH	-	Called when the task gains the CPU.
								Remember that the tc_Switch() and tc_Launch()
								function pointers are no longer available
								if the task has been added to a MMUContext.

		MADTAG_CODE			-	A function pointer to the code to be called.
								This should be an assembly language function.
								It is called like this:

		Register a0			-	Pointer to the ExceptionData structure.
		Register a1			-	loaded with the MADTAG_DATA provided data.
		Register a4			-	Ditto.
		Register a5			-	Pointer to the code itself.
		Register a6			-	MMUBase. NOT A SCRATCH.

		Registers d0-d1/a0-a1/a4-a5 are scratches and are available for the
		Exception handler. You *MUST* set the "Z" condition code and
		clear d0 on exit in case you handled the exception. Details on
		how to write an exception handler are in the "Exception.doc" file.

		MADTAG_DATA			-	Data to be loaded for the hook function.
		MADTAG_NAME			-	A name for the hook. Currently unused.
		MADTAG_PRI			-	A priority, ranging from -128...+127.
								Hooks of higher priorities are called first.

	RESULTS
		A handle to the exception hook. Do not interpret this handle.
		Or NULL on failure.

	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.

		The exception will not be activated, you need to call 
		ActivateException() to make the library call it.

		Much more needs to be said about this function, see Exception.doc
		for details about the exception handlers.

	BUGS

	SEE ALSO
		RemContextHook(), AddMessageHook(), ActivateException(),
		exec/interrupts.h, Exception.doc

mmu.library/RemContextHook							mmu.library/RemContextHook

	NAME
		RemContextHook - remove an exception handler from a Context

	SYNOPSIS
		RemContextHook( hook )
						 a1

		void RemContextHook( struct ExceptionHook * );

	FUNCTION
		This function removes a previously installed context hook
		from the hook list.

	INPUTS
		The handle of the hook, as obtained by AddContextHook().

	RESULTS
		none.

	NOTES
		You should call DeactivateException() on your hook before you
		remove it.
		Be aware that removing all exception hooks will cause the
		default exec.library exception hook function to be called, i.e.
		the system will guru in case of a failure.

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

	NAME
		AddMessageHook - install a high-level hook function.

	SYNOPSIS
		hook = AddMessageHookA ( tags );
								  a0

		hook = AddMessageHook ( tag1, ... );


		struct ExceptionHook * AddMessageHookA ( struct TagItem * );

		struct ExceptionHook * AddMessageHook ( Tag tag1, ... );

	FUNCTION
		Installs a high-level hook of the tag-given properties.
		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 and the code failed in
		User mode. They will just "drop thru" to the next handler if this 
		is not the case.

	INPUTS
		tags 	-	A taglist defining the type of the exception hook
					to be added.

		Currently defined are:

		MADTAG_CONTEXT		-	The context to which this exception hook
								should be added. This MUST be given.

		MADTAG_TASK			-	If the hook should be called only if a
								specific task is running, specify a pointer
								to the task structure here. 
								Warning! Adding too many task specific
								hooks slows things down unnecessary.
								Remember that a MMU Context may hold more
								than one task.
								This MUST be given for the switch and launch
								hooks.

		MADTAG_TYPE			-	Type of the exception hook to build. The
								following types are available:

			MMUEH_SEGFAULT	-	Called on segmentation fault, i.e. write to
								a write protected page or access of an
								invalid page. Most useful for "Enforcer"
								like tools.

			MMUEH_SWAPPED	-	Called on access for a "swapped out" page.
								Most useful to implement virtual memory.

		MADTAG_CATCHERPORT	-	The port to sent the data to.
		MADTAG_NAME			-	A name for the hook. Currently unused.
		MADTAG_PRI			-	A priority, ranging from -128...+127.
								Hooks of higher priorities are called first.

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

		struct ExceptionMessage {
			struct Message			exm_msg;
			struct ExceptionData 	exm_Data;
		};

		For details about the ExceptionData structure, see Exception.doc.

		Once the message gets replied, the faulted task is restarted.

	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
		The handler must have been added to a context with EnterMMUContext()
		before this function can be used. Unlike the AddContextHook() 
		function, this DOES NOT work for "plain" tasks without a context.

		The hook must be activated with ActivateException() before it 
		gets called.

		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.

	BUGS
		
	SEE ALSO
		AddContextHook(), RemContextHook(), RemMessageHook(), 
		ActivateException(), Exception.doc

mmu.library/RemMessageHook							mmu.library/RemMessageHook

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

	SYNOPSIS
		RemMessageHook( handle );
						 a1

		void RemMessageHook( struct ExceptionHook * );


	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
		To remove a message hook safely, deactivate it first with
		DeactivateException(), then tell the daemon to reply all 
		exceptions of this hook, then remove it. 

		Not following these rules may cause deadlocks.
	
	BUGS
		
	SEE ALSO
		AddMessageHook(), AddContextHook(), RemContextHook(),
		DeactivateException(), Exception.doc

mmu.library/ActivateException					mmu.library/ActivateException

	NAME
		ActivateException	-	enable an exception hook.

	SYNOPSIS
		ActivateException( hook );
							a1

		void ActivateException( struct ExceptionHook * );

	FUNCTION
		Activates a formerly installed exception hook, either a low
		level context hook or a high-level message hook.
	
	RETURNS
		
	NOTES
		Hooks of either kind must be activated before the mmu.library
		will call them. Hooks are deactivated after creation and must
		be deactivated before they get removed.
		This call can be safely used within interrupts and from super-
		visor mode.

	BUGS

	SEE ALSO
		DeactivateException(), AddContextHook(), AddMessageHook(),
		Exception.doc

mmu.library/DeactivateException				mmu.library/DeactivateException

	NAME
		DeactivateException	-	enable an exception hook.

	SYNOPSIS
		DeactivateException( hook );
							a1

		void DeactivateException( struct ExceptionHook * );

	FUNCTION
		Deactivates a formerly installed exception hook, either a low
		level context hook or a high-level message hook, i.e. disables
		it from being called.
	
	RETURNS
		
	NOTES
		Hooks of either kind must be activated before the mmu.library
		will call them. Hooks are deactivated after creation and must
		be deactivated before they get removed.
		This call can be safely used within interrupts and from super-
		visor mode.

	BUGS

	SEE ALSO
		ActivateException(), RemContextHook(), RemMessageHook(),
		Exception.doc

mmu.library/GetPageSize								mmu.library/GetPageSize

	NAME
		GetPageSize - return the page size of a context.

	SYNOPSIS
		pagesz = GetPageSize( context );
		d0					  a0

		ULONG GetPageSize( struct MMUContext * );

	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 active context.

	RESULTS
		the page size in bytes or zero for failure.

	NOTES
		The call will fail if the given context is protected, the result
		will be zero in this case.

	BUGS
		Context protection is currently unsupported.

	SEE ALSO
		ProtectContext()

mmu.library/RemapSize								mmu.library/RemapSize

	NAME
		RemapSize - return the block size for memory remapping.

	SYNOPSIS
		remapsize = RemapSize( context );
		d0					     a0

		ULONG RemapSize( struct MMUContext * );

	FUNCTION
		This function returns the smallest possible block size, and
		therefore the alignment restrictions, for remapping of memory that
		should be added to the exec memory pool. Since the MMU tables have
		to be placed in non-fragmented memory, certain alignment 
		restrictions for the memory blocks the MMU tables are placed in
		arise. 
		This harder aligment condition is only required for memory
		that is put into the exec free list, but as long as remapped
		memory is never returned from AllocMem, the page size is good 
		enough.

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

	RESULTS
		the smallest admissable block size for memory returned by 
		AllocMem().

	NOTES
		The call will fail if the given context is protected, the result
		will be zero in this case.

		Even though the mmu.library does support memory remapping, this
		does not mean all other programs do. For example, remember that
		the inputs to the "MAPP_REMAPPED" pages is a physical page size,
		hence your program has to translate the logical address obtained
		by AllocMem() to a physical address at first. This can be done 
		with the PhysicalLocation() function.
		
		Additionally, DMA devices might or might not support memory
		remapping, just for the same reason: They require physical, not
		logical addresses. The MMU library provides a translation mechanism
		in form of the ChachePreDMA() and CachePostDMA() functions of
		ExecBase, but not all DMA device drivers call these functions
		properly. Certain patches might be made available for devices
		not following this rule.

	BUGS
		Context protection is currently unsupported.
		Adding remapped memory to the freelist is highly untested and
		not recommended because of the quirks of this mechanism.

	SEE ALSO
		PhysicalLocation(), GetPageSize(), exec/CachePreDMA(),
		DMAInitiate()

mmu.library/SetPropertiesA						mmu.library/SetPropertiesA

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

	SYNOPSIS

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

		BOOL SetPropertiesA( sruct MMUContext *, ULONG, ULONG, ULONG, ULONG,
							 struct TagItem *);


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

		BOOL SetProperties( struct MMUContext *, ULONG, ULONG, ULONG, ULONG,
							Tag tag1, ...);

	FUNCTION
		This call sets attributes of a certain memory range of the
		software abstraction layer of the MMU tree, aligned to page 
		boundaries.

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

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

				MAPP_WRITEPROTECTED	 -	The page will be write 
					protected. Writes to this area will cause a segmentation
					fault.

				MAPP_ROM				- Read only memory, writes tolerated.
					This is almost identically to MAPP_READONLY except that
					writes into this area will not cause a call of the
					segmentation fault handler. The library will filter them
					out.
					This property can be used to simulate a ROM in RAM and
					might be useful for kickstart remappers.

				MAPP_USED				-	The "used" bit of the pages
					will be set. The CPU will set this bit automatically
					as soon as the pages are accessed.

					This flag will turn on the "USED" bit in the hard-
					ware MMU bit. NOT setting this flag means that the
					USED bit in the hardware tree is preserved, regard-
					less of the mask value.

				MAPP_MODIFIED			-	The "modified" bit of the pages
					will be set. The CPU will set this bit automatically
					as soon as a write is performed to the page in question.
					DO NOT SET THIS BIT TOGETHER WITH MAPP_WRITEPROTECTED
					or the CPU might hang. 

					This flag will turn on the "MODIFIED" bit in the hard-
					ware MMU bit. NOT setting this flag means that the
					MODIFIED bit in the hardware tree is preserved, regard-
					less of the mask value.

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

				MAPP_INVALID			-	The page will be marked as 
					invalid. Accessing it will invoke the bus error hook.
					User data can be provided for this property mode,
					provided you don't select MAPP_SINGLEPAGE or 
					MAPP_REPAIRABLE as well.

				MAPP_SWAPPED			-	The page will be marked as
					swapped out.
					A block ID *MUST* be provided for this property mode.

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

				MAPP_IMPRECISEEXECPTION	-	The page will be marked as 
					"imprecise exception". MAPP_CACHEINHIBIT is mandatory
					in this case or this flag does nothing.
					Only available for the 68060, but does not harm for
					other MMUs.

				MAPP_NONSERIALIZED		-	The page will be marked as
					serialized. MAPP_CACHEINHIBIT is mandatory if this
					property is selected. 
					Only available for the 68040, but does not harm for
					other MMUs.

				MAPP_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 for 68040 and 68060, but does not harm
					if selected for other MMUs. MAPP_CACHINHIBIT MUST NOT
					be selected.
	
				MAPP_REMAPPED				-	Map the page to a different
					memory location. Parameters are given in the tag items.

					Even though this seems simple, remapping memory is
					full of quirks. Obviously, DMA devices and the MMU
					itself see the true physical addresses and not the
					logical addresses as filtered by the MMU. Therefore,
					adding remapped memory to the exec.library freelist
					will cause nothing than trouble and hard to trace
					disk faults and crashes as soon as this memory is
					used by a DMA device or the mmu.library itself.
					(Note that even though the library is supposed to
					 support this, this is currently untested)
					Even though there *are* documented methods how to
					prepare a DMA transfer for remapped memory, USING
					these exec function calls is unfortunately the 
					exceptions. Therefore, this method is currently un-
					supported, by most (!really!) DMA device drivers. 
					Amongst the broken devices are the gvpscsi.device 
					and the cybscsi.device, to give just two examples.

					The omniscsi.device (the "Guru ROM") can be fixed
					with the MuOmniScsiPatch.

					If you really *MUST* remap public memory, then align
					it *AT LEAST* to the border given by RemapSize().	
					Just page alignment WILL NOT BE ENOUGH due to the way
					how the library works internally.	

					YOU HAVE BEEN WARNED!
					
				MAPP_SUPERVISORONLY		-	The page will be not available
					for user programs.

					NOTE: This mode is currently implemented using invalid 
					page descriptors for the user pages and is ignored
					when building supervisor tables. This method saves some
					space for the 68040 and 68060 and was the only way how
					it could be done for the 68030 and 68851 without using
					MMU tables twice as large.

				MAPP_USERPAGE0			-	Set user page attribute 0.
					This selects the user page attribute 0 for the 68040
					and 68060. "USER" DOES NOT MEAN YOU!
					The status of this bit appears on special pins of the
					CPU and might be required by some hardware, so don't 	
					play with this. You should not change this bit, by no
					means.

				MAPP_USERPAGE1			-	Set user page attribute 1.
					This selects the user page attribute 0 for the 68040
					and 68060. See above for warnings.

				MAPP_GLOBAL				-	The pages are part of the
					global (public) memory. 
					You should not set this bit manually, it is under
					control of the library to optimize table flushes.

				MAPP_BLANK				-	Blank memory.
					The pages are mapped to one special area in RAM so
					erraneous reads and writes to these pages won't harm. 
					MAPP_BLANK should ONLY be used to mark special memory
					areas as "non-available" and un-handled by the hardware,
					nothing else. 

				MAPP_SHARED				- 	Properties are identically to
					the public context.
					This tells the library to use the same properties as
					for the global context. However, MAPP_SHARED pages
					are not automatically updated when the global context
					changes, it's just a convenient way of saying "I want
					to uninstall my settings".

				MAPP_TRANSLATED			-	Under control of the TTx 
					registers.
					NEVER SET THIS BIT YOURSELF.
					Pages with the "MAPP_TRANSLATED" bit set are under
					control of the "transparent translation registers" of
					the MMU and are "out of scope" for the mmu.library.
					Defining any properties for this domain will do nothing
					(or little, dependent on the TTx register configuration).
					A virtual memory program MUST NOT use virtual addresses
					which are transparently translated, this won't work.
					The mmu.library tries to be smart about the TTx registers
					and disables "unuseful" TTx settings itself.

				MAPP_INDIRECT			- 	Map to a user provided page
					descriptor.
					The provided pages(s) are mapped by a user provided
					page descriptor. This page descriptor MUST BE aligned
					to a long word address, and it MUST BE a valid page
					descriptor for the MMU used.

					NEVER EVER attempt DMA, such as harddisk reads or
					writes to a memory domain marked as MAPP_INDIRECT.

					Due to some cache peculatities, the data might be
					incorrect and the result would be corrupt data.

					The library will be able to mark pages as non-cacheable
					if this is required for the DMA transfer, but this
					magic does not work for indirect pages.

					JUST DON'T DO THAT, MAPP_INIDIRECT is definitely an
					advanced feature.

				MAPP_BUNDLED			-	Map all pages in range to
					a single page in RAM.

					The main purpose of this function is to provide a
					MAPP_BLANK property with a user-selectable target
					page.

				MAPP_SINGLEPAGE			-	Make this page available for
					SetPagePropertiesA().

					WARNING! Setting this bit shortcuts some optimizations
					the library might perform on the MMU table. The system
					may easely run out of memory if you select this
					property for "too many" pages. Use it with care, you
					have been warned!

				MAPP_REPAIRABLE			-	Inform the exception handler
					to provide write data and to allow pipeline fill.

					If this bit is set, the exception handler gets informed
					that you want to know the write data in case writes
					fail, or you want to provide the read data in case
					reads fail. The read/write data is available in the
					ExceptionData structure, read the exception handler
					documentation.

					This flag should be combined with MAPP_INVALID,
					MAPP_WRITEPROTECTED, MAPP_SWAPPED or 
					MAPP_SUPERVISORONLY

					However, this technique requires a lot of "trickery"
					and should be expected to be slow and to create
					sub-optimal and over-sized MMU tables. Use it with
					care, on as few pages as possible and only if your
					exception handler is "not on a hurry".

				MAPP_USERATTRIBUTE0		-	This is for your private use.
					This bit does not have any specific function, it is
					for your private use.

				MAPP_USERATTRIBUTE1		-	This is for your private use.
				MAPP_USERATTRIBUTE2
				MAPP_USERATTRIBUTE3


		mask	-	A bit mask of the attributes to be changed.

				Note that the hardware USED and MODIFIED bits will never
				be cleared, even though the properties say so and the
				corresponding bits in the mask are set. However, you can
				force them "ON" if you like, this saves unnecessary write-
				backs of the MMU.
		
		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:

				MAPTAG_DESTINATION	-	the physical destination of the
					logical address. Must be provided for the MAPP_MAPPED
					or MAPP_BUNDLED	bits. 

				MAPTAG_BLOCKID		-	a unique ID the MMU.library doesn't
					care about, for external usage of the memory.library.
					Must be provided for the MAPP_SWAPPED flag and may be
					used to indicate where on disk the swapped page is
					kept.
				
				MAPTAG_USERDATA		-	a unique cookie you might provide
					for MAPP_INVALID pages and which is passed thru to the
					segmentation fault exception handler.

				MAPTAG_DESCRIPTOR	-	a pointer to a long word aligned
					table descriptor for MAPP_INDIRECT.
				

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

	NOTES
		This call adjusts only the abstraction layer of the MMU table
		and marks the pages as "dirty". An explicit call to 
		RebuildTree() is required to make the changes active.
		You should bundle changes to the MMU table and call RebuildTree()
		once when you're done because rebuilding the MMU tree is a costy
		operation.
		If you need to modify the MMU table "on the fly" then consider
		using "SetPagePropertiesA()", even though its use is restricted
		to single pages. Even faster are MAPP_INDIRECT pages, but - to
		say that again - DO NOT PERFORM DMA ON THESE PAGES.

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

		SUPERVISORONLY, SWAPPED and INVALID memory are 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 
		usually makes sense to mark the memory region as PRIVATE as well, 
		unless you modify the public hook.
		(Note that MAPP_PRIVATE is currently not implemented because it
		 will slow down things considerably.)

		You may freely mark the first memory page as INVALID provided
		the context MCXTAG_EXECBASE flag is set (it usually is).
		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.

	BUGS
		Context protection is currently not available.

	SEE ALSO
		ProtectContext(), GetPropertiesA(), SetContextHook(), 
		GetPageSize(), RemapSize(), RebuildTree(), SetPagePropertiesA()

mmu.library/SetPagePropertiesA				mmu.library/SetPagePropertiesA

	NAME
		SetPagePropertiesA - set hardware memory attributes for a single
		page.

	SYNOPSIS

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

		BOOL SetPagePropertiesA( struct MMUContext *, ULONG, ULONG, ULONG,
							 struct TagItem *);


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

		BOOL SetPageProperties( struct MMUContext *, ULONG, ULONG, ULONG, 
							Tag tag1, ...);

	FUNCTION
		This call sets the hardware attributes of a memory page.

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

		flags	- a binary flags field for the attributes to define. For
					the available attributes, see the SetPropertiesA()
					function.

					Differences:

					MAPP_MODIFIED and MAPP_USED are really set or cleared
					in the true hardware table, the mask is considered
					correctly.

					Note that this function is the only method to clear
					these two hardware flags, SetPropertiesA() or
					RebuildTree() don't do this.

		mask	-	a bit mask of all bits to be changed.

		tags	-	A tag array with additional data. Check 
					SetPropertiesA() for details.

	RESULTS
		A boolean success/failure indicator. Might fail if the context
		is protected or no memory is available for the modification or
		the page is not marked with MAPP_SINGLEPAGE.

	NOTES
		BE WARNED! This function is very restricted in its use. It may well
		return FALSE even if all parameters are valid due to hardware 
		restrictions. This function does never ever rebuild an MMU tree,
		it just modifies "what is there". If the library choose to optimize
		the MMU library tree and to map a couple of pages by one descriptor,
		for what reasons ever, this call will fail. The details when this
		happens depends not only on the MMU, but on the general system
		layout.

		The ONLY documented way to get a mapping for a page that can be
		adjusted using this call is to set the page to MAPP_SINGLEPAGE using
		SetPropertiesA() before.

		This call adjusts the hardware level of the MMU table if a descriptor 
		is available for a single page. It does not modify more than one
		page at once.

		It might happen that the library does not satisfy a request
		setting a page as "cacheable" if a DMA operation is currently in
		progress and the page must remain "nonacheable". However, the
		function will not fail in this case, but just delay the operation
		until the DMA is complete. The properties will always fall back to
		the next available option.

		This routine is safe to be called from within interrupts, it does
		not break any Forbid() or Disable() and is ideal for 
		quick-and-dirty repair operations within exceptions handlers,
		provided the MAPP_SINGLEPAGE flag has been set. 

	BUGS
		Note that MAPP_SINGLEPAGE is the flag you want here, not 
		MAPP_REPAIRABLE. That's something different!

	SEE ALSO
			ProtectContext(), GetPagePropertiesA(), SetContextHook(), 
			GetPageSize(), RebuildTree(), SetPropertiesA()
mmu.library/RebuildTree							mmu.library/RebuildTree

	NAME	
		RebuildTree - build a MMU hardware tree from the software abstraction
		layer.

	SYNOPSIS
		result = RebuildTree( context );
		d0					  a0

		BOOL RebuildTree ( struct MMUContext * );

	FUNCTION
		This function adjusts the MMU hardware tree to reflect the settings
		of the software abstraction layer defined with SetPropertiesA().

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

	RESULTS
		a boolean success/failure indicator. TRUE if the operation was
		performed successfully.

	NOTES
		This is the big - and admittedly - slow one.

		Rebuilding the MMU tree is a relatively slow operation. The library
		tries to be smart about it and rebuilds only the pages whose
		mappings have been adjusted, but it's still a heavy beast.

		Properties temporarely defined with SetPagePropertiesA() will be
		lost after the rebuild, except for the MAPP_USED and MAPP_MODIFIED
		bits.

		BE WARNED! A consistent use of the two flags is only possible
		if the pages are marked as MAPP_SINGLE. The page building algorithm
		does not guarantee consistent use of these two bits except for
		MAPP_SINGLE pages. Even though it *might* look well most the time,
		it is not documented that these two bits are kept correctly for non-
		SINGLE pages. If you need MODIFIED or USED page information, the only 
		way to get them is to mark these pages as MAPP_SINGLE. There's no 
		consistent use for these flags if early termination descriptors 
		(hence, w/o MAPP_SINGLE) are used by the library. 

		Even though some pages in the abstraction layer might be marked as
		un-USED or un-MODIFIED, this routine NEVER clears the hardware bits.
		It requires a call to SetPagePropertiesA(), and hence the MAPP_SINGLE
		attribute (once again!) to do this.

	BUGS
		The library rebuilds currently more than it has to. This will be
		fixed in the next releases.

		Much more should be said about this function.

	SEE ALSO
		SetPropertiesA(), SetPagePropertiesA(), GetPropertiesA(),
		GetPagePropertiesA()

mmu.library/GetPropertiesA						mmu.library/GetPropertiesA

	NAME
		GetPropertiesA - read memory attributes for a given logical page
		from the MMU table abstraction layer.

	SYNOPSIS

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

		ULONG GetPropertiesA( struct MMUContext *, void *, struct TagItem *);


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

		ULONG GetProperties( struct MMUContext *, void *, Tag tag1, ...);

	FUNCTION
		This call reads the page properties of a certain address in
		memory from the software abstraction layer. It is the counterpart
		of SetPropertiesA().

	INPUTS
		context - a handle to the context to investigate or NULL for the
			active 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:

				MAPTAG_DESTINATION	-	a pointer to a void * where 
					the physical destination of the logical address is
					filled in. Only available if the page is physically
					mapped to somewhere. Not filled in otherwise.

				MAPTAG_BLOCKID		-	read the a unique ID for the 
					MAPP_SWAPPED property. Untouched if the page isn't
					swapped. The tag data points to a long word which will
					be filled in for swapped out pages.
				
				MAPTAG_USERDATA		-	read the unique cookie for 
					INVALID pages, fill in the long word pointed to by
					the tag data field.

				MAPTAG_DESCRIPTOR	-	fill in the location of the
					indirect descriptor which is used to perform the
					mapping. Only used if MAPP_INDIRECT is used.

	RESULTS
		Returns a binary flags field for the attributes to define. See
		SetPropertiesA() for details. Remember that MAPP_USED or 
		MAPP_MODIFIED reflect the bits on the abstraction layer, not the
		true hardware bits. You MUST call GetPagePropertiesA() to read
		them, and hence *MUST* use MAPP_SINGLE pages.

	NOTES
		The page size can be read with GetPageSize(). Check the return	
		code of this call!

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

		WARNING: The flags returned DO NOT reflect the hardware flags
		in the MMU table for the context. They DO reflect the settings
		installed with SetPropertiesA() on the abstraction layer of the
		MMU tables.

		The hardware table might differ for the following reasons:

			- SetPropertiesA() was called, but the changes haven't been
			  made active with RebuildTree() yet.
			- A program modified the hardware layer directly using
			  SetPagePropertiesA().
			- DMA is currently active and the page in question has 
			  therefore been marked as non-cacheable temporarely.

		Additionally, the library might have adjusted the abstraction
		layer itself by allocating non-cacheabe memory for its
		MMU tables.

		This routine is *NOT* safe to be called from within interrupts.

	BUGS

	SEE ALSO
		ProtectContext(), SetPropertiesA(), SetContextHook(), 
		GetPageSize(), SetPagePropertiesA(), RebuildTree()

mmu.library/GetPagePropertiesA					mmu.library/GetPagePropertiesA

	
	NAME
		GetPropertiesA - read memory attributes from the hardware level
		for a given logical page. 

	SYNOPSIS

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

		ULONG GetPagePropertiesA( struct MMUContext *, void *, 

								struct TagItem *);


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

		BOOL GetPageProperties( struct MMUContext *, void *, Tag tag1, ...);

	FUNCTION
		This call reads the page properties of a certain address in
		memory directly from the hardware. It is the counterpart
		of SetPagePropertiesA().

	INPUTS
		context - a handle to the context to investigate or NULL for the
			active context. The library might use the MMU hardware directly
			if NULL is passed in, this call might be faster therefore.

		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. See GetPropertiesA() for details.


	RESULTS
		Returns a binary flags field for the attributes to define. See
		SetPropertiesA() for details.

	NOTES
		The page size can be read with GetPageSize(). 

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

		WARNING: The flags returned reflect the NOT the hardware flags
		in the MMU table for the context except for the MODIFIED and USED
		properties, even though the hardware level is *almost* consistent
		with these flags. 

		The hardware table might differ slightly in the following 
		situations:

			- DMA is currently active and the page in question has 
			  therefore been marked as non-cacheable temporarely.
			  Therefore, the cache settings returned are what will be
			  re-installed here when DMA is finished. The library
			  will "fake" the flags you have installed for the page
			  investigated.
			- The library will use invalid descriptors to implement
			  supervisor only or swapped pages.

		However, even though the flags might differ from the hardware
		flags, you're always safe to re-install the properties with
		SetPageProperties, there's no need to keep track of pecularities
		like cache disabling for DMA pages. The library does this for you.

		MAPP_MODIFIED and MAPP_USED are always read from the hardware
		directly.

		KEEP IN MIND that these two bits are only set and handled
		consistently for MAPP_SINGLE pages. You MUST NOT interpret
		them in all other cases, their values might get lost on a
		RebuildTree() call.

		This routine is safe to be called from within interrupts, most
		useful within exception handlers.

	BUGS

	SEE ALSO
			ProtectContext(), GetPropertiesA(), SetContextHook(), 
			GetPageSize(), SetPagePropertiesA(), RebuildTree()

mmu.library/AllocAligned								mmu.library/AllocAligned

	NAME
		AllocAligned 	-	allocate memory aligned to a memory border.

	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. 

		reqments -	exec style memory attributes

		align	-	the alignment restrictions of the page.
					MUST be a power of two.

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

	NOTES
		Examples of how to use the "align" parameter:

		mem = AllocAligned(123,MEMF_PUBLIC|MEMF_CLEAR,1024);

		will allocate 123 bytes starting at a 1024 byte border, i.e. 
		the address returned will be divisible by 1024. The call will 
		clear the 123 bytes, NOT MORE.

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

		A DOS process will have its pr_Result2 field set to
		ERROR_NO_FREE_STORE if the memory allocation fails.

		The mmu.library calls this function by using its LVO library entry,
		so it can be patched to a smarter implementation if desired.

	BUGS

	SEE ALSO
		GetPageSize(), exec/memory.h

mmu.library/LockMMUContext						mmu.library/LockMMUContext

	NAME
		LockMMUContext		-	lock a MMU context

	SYNOPSIS
		LockMMUContext( context );
						  a0

		void LockMMUContext( struct MMUContext * );

	FUNCTION
		Lock the software abstraction layer of the MMU table against
		modifications from other tasks.

	INPUTS
		A handle to a MMUContext or NULL for the active context.

	RETURNS

	NOTES
	 	This mechanism DOES NOT avoid changes of the MMU table on a lower
		level by SetPageProperties(), only SetProperties() from other
		tasks will be locked.
		Hence, it locks the abstraction layer, but not the hardware
		level.

		DO NOT lock more than one context at once, unless you locked
		also the context list with LockContextList(). Not following 
		this rule might cause deadlocks.

	BUGS

	SEE ALSO
		UnlockContext(), SetPageProperties(), SetProperties(),
		LockContextList().

mmu.library/UnlockMMUContext					mmu.library/UnlockMMUContext

	NAME
		UnlockMMUContext	-	release a MMU context

	SYNOPSIS
		UnlockMMUContext( context );
						  a0

		void UnlockMMUContext( struct MMUContext * );

	FUNCTION
		Release the software abstraction layer of the MMU table, allow
		modifications from other tasks.

	INPUTS
		A handle to a MMUContext or NULL for the active context.

	RETURNS

	NOTES
	 	This mechanism DOES NOT avoid changes of the MMU table on a lower
		level by SetPageProperties(), only SetProperties() from other
		tasks will be locked.
		Hence, it locks the abstraction layer, but not the hardware
		level.

	BUGS

	SEE ALSO
		LockMMUContext(), SetPageProperties(), SetProperties(),
		AttemptLockMMUContext()

mmu.library/AttemptLockMMUContext			mmu.library/AttemptLockMMUContext

	NAME
		AttemptLockMMUContext		-	attempt to lock a MMU context

	SYNOPSIS
		ok = AttemptLockMMUContext( context );
						  			  a0

		LONG AttemptLockMMUContext( struct MMUContext * );

	FUNCTION
		Grants non-blocking access to a MMU context.
		Attempts to lock the software abstraction layer of the MMU 
		table against modifications from other tasks. 

	INPUTS
		A handle to a MMUContext or NULL for the active context.

	RETURNS
		TRUE in case of success - the context is then locked for you
		and this lock must be released with UnlockMMUContext().
		FALSE in case any other task holds a lock.

	NOTES
	 	This mechanism DOES NOT avoid changes of the MMU table on a lower
		level by SetPageProperties(), only SetProperties() from other
		tasks will be locked.
		Hence, it locks the abstraction layer, but not the hardware
		level.

		DO NOT lock more than one context at once, unless you locked
		also the context list with LockContextList(). Not following 
		this rule might cause deadlocks.

	BUGS
		In pre-V39 machines, this call does not lock the context again
		in case you already hold a lock. This is a bug of the pre-V39
		AttemptSemaphore(), read the exec autodocs for a workaround.

	SEE ALSO
		UnlockMMUContext(), SetPageProperties(), SetProperties(),
		LockContextList(), AttemptSemaphore()

mmu.library/LockContextList						mmu.library/LockContextList

	NAME
		LockContextList		-	arbitrate a master lock.

	SYNOPSIS
		LockContextList( );

		void LockContextList( void );

	FUNCTION
		Arbitrates a master lock that allows locking more than one context
		at once to avoid deadlocks.

	INPUTS

	RETURNS

	NOTES
		This lock grants access for locking more than one context at once,
		to avoid deadlocks. I.e. in case you need to lock more than one
		context at a time, get this lock FIRST, then lock the contexts
		in any order you prefer.

		This call DOES NOT avoid modification of the context list or 
		individual contexts at all, i.e. other tasks are still able
		to create and to dispose contexts. To avoid this, you must lock
		the contexts afterwards.

		When you're done with the contexts, unlock the contexts first,
		THEN release this lock with UnlockContextList(). NOTE THE ORDER!
	
	BUGS

	SEE ALSO
		UnlockContextList(), LockContext(), AttemptLockContextList()

mmu.library/UnlockContextList				mmu.library/UnlockContextList

	NAME
		UnlockContextList	-	release the master context lock

	SYNOPSIS
		UnlockContextList( );

		void UnlockContextList( void );

	FUNCTION
		Releases the master lock that allows locking more than one context
		at once to avoid deadlocks.

	INPUTS

	RETURNS

	NOTES
		This lock grants access for locking more than one context at once,
		to avoid deadlocks. I.e. in case you need to lock more than one
		context at a time, get this lock FIRST, then lock the contexts
		in any order you prefer.

		This call DOES NOT avoid modification of the context list or 
		individual contexts at all, i.e. other tasks are still able
		to create and to dispose contexts. To avoid this, you must lock
		the contexts afterwards.

		When you're done with the contexts, unlock the contexts first,
		THEN release this lock with UnlockContextList(). NOTE THE ORDER!

	BUGS

	SEE ALSO
		LockContextList(), LockContext(), AttemptLockContextList()

mmu.library/AttemptLockContextList			mmu.library/AttemptLockContextList

	NAME
		AttemptLockContextList		-	attempt to arbitrate the master lock.

	SYNOPSIS
		ok = AttemptLockContextList( );

		LONG AttemptLockContextList( void );

	FUNCTION
		Attempts granting the context master lock in a non-blocking
		fashion. 

	INPUTS

	RETURNS
		TRUE in case the master lock could be arbitrated. You have then to
		release it with UnlockContextList().
		FALSE in case it is already locked and access could not be granted.

	NOTES
		This lock grants access for locking more than one context at once,
		to avoid deadlocks. I.e. in case you need to lock more than one
		context at a time, get this lock FIRST, then lock the contexts
		in any order you prefer.

		This call DOES NOT avoid modification of the context list or 
		individual contexts at all, i.e. other tasks are still able
		to create and to dispose contexts. To avoid this, you must lock
		the contexts afterwards.

		When you're done with the contexts, unlock the contexts first,
		THEN release this lock with UnlockContextList(). NOTE THE ORDER!

	BUGS
		In pre-V39 machines, this call does not lock the context again
		in case you already hold a lock. This is a bug of the pre-V39
		AttemptSemaphore(), read the exec autodocs for a workaround.

	SEE ALSO
		UnlockContextList(), LockContext(), LockContextList(),
		AttemptLockSemaphore()
	
mmu.library/AllocLineVec							mmu.library/AllocLineVec

	NAME
		AllocLineMem		- 	allocate cache line aligned, keep size

	SYNOPSIS
		AllocLineVec ( bytesize , attributes );
						  d0		d1

		void * AllocLineVec ( ULONG, ULONG );

	FUNCTION
		Allocates memory like AllocVec(), but the memory is guaranteed
		to be aligned to cache lines of the processors in the system,
		even though the pointer returned IS NOT.
		Minimal guaranteed alignment is currently 32 bytes, i.e. a 
		PPC cache line. Future hardware may require stricter alignments.

		AllocLineMem'd memory is released with FreeVec() from the
		exec.library.

	INPUTS
		bytesize 	-	the size of the memory block in bytes.
		attributes	-	memory attributes, see exec.library/AllocMem.

	RETURNS
		a pointer to the memory allocated or NULL on failure.

		A DOS process will have its pr_Result2 field set to
		ERROR_NO_FREE_STORE if the memory allocation fails.

	NOTES
		BIG WARNING: The pointer returned IS NEVER cache line aligned
		itself, but the complete memory block toghether with the
		vector size is kept in a cache line, regardless of the size
		passed in. Due to alignment restrictions, the routine might
		allocate a larger memory block than requested. It is however
		guaranteed that AT LEAST the size requested is returned, and
		that a FreeVec() will, indeed, free all memory.

		If MEMF_CLEAR is requested, the memory is cleared on the
		MC68K side, but the "zeros written" might be still in the
		cache. Hence, it is a good idea to flush the cache if the
		memory is passed over to the PPC.

		However, the vector size itself is always "pushed" to 
		memory, it is therefore guaranteed to be properly written
		back to the memory.

		The memory allocated this way is released by FreeVec() of
		the exec.library.

	BUGS

	SEE ALSO
		exec.library/AllocVec(), exec.library/FreeVec(), AllocLineMem()

mmu.library/PhysicalPageLocation			mmu.library/PhysicalPageLocation

	NAME
		PhysicalPageLocation	-	translate logical address to physical

	SYNOPSIS
		addr = PhysicalPageLocation( context , addr );
		d0					   		a0		 a1

		void * PhysicalPageLocation( struct MMUContext * , void * );

	FUNCTION
		This function finds the physical address for the logical address
		passed in by scanning the MMU hardware table. 
		If the physical address is not available, NULL is returned.

	INPUTS
		context - the context to enter or NULL for the current context.
		addr	- the logical address to be translated.

	RETURNS
		the physical address of the logical address passed in, or NULL
		in case the logical address is not swapped in or otherwise out of
		control of the library.

	NOTES
		This is the low-level function, consider using the high-level
		function PhysicalLocation() when possible.
		This call can be safely used within interrupts.

	BUGS
		The function will also return NULL in case the logical address
		is translated to the address 0L. However, 0L should never be 
		used as physical address anyhow.

	SEE ALSO
		GetPageProperties(), PhysicalLocation()
mmu.library/PhysicalLocation					mmu.library/PhysicalLocation

	NAME
		PhysicalLocation	-	translate logical address to physical

	SYNOPSIS
		props = PhysicalLocation( context, addrptr, lenptr );
		d0					   		d1		 a0		  a1

		ULONG PhysicalLocation( struct MMUContext * , void ** , ULONG * );

	FUNCTION
		This function finds the physical address for the logical address
		passed in by scanning the software abstraction layer.
		If the physical address is not available, NULL is returned.

	INPUTS
		context - the context to enter or NULL for the current context.
		addrptr - points to the logical address to be translated.
				  The physical address is filled in here.
		lenptr 	- Points to the length of the address range to be trans-
				  lated. The function returns the length of the largest 
				  possible continous memory range contained in the memory
				  range passed in. Hence, this function may shorten the
				  memory block for fragmentized memory models.

	RETURNS
		the properties of the memory range.

	NOTES
		This is the high-level function, it is not callable from within
		interrupts.

		In case you've to operate on a range of physical memory, start
		the translation with this call, then compare the size returned
		with the size of the memory block passed in. Because this 
		function may shorten the memory size in case the physical 
		memory is fragmentated, you should be prepared that the size
		returned is smaller than what was passed in. In this case, operate
		on the memory region returned, then add the returned size to
		the original logical address and call this function again to
		get the physical location of the next chunk.

	BUGS
		The function will also return NULL in case the logical address
		is translated to the address 0L. However, 0L should never be 
		used as physical address anyhow.

	SEE ALSO
		GetProperties(), PhysicalPageLocation()
mmu.library/DMAInitiate								mmu.library/DMAInitiate

	NAME
		DMAInitiate		-	start a DMA transport given a logical address.

	SYNOPSIS
		DMAInitiate( context, addrptr, lenptr, write );
						d1		 a0		  a1	d0

		void DMAInitiate( struct MMUContext * , void ** , ULONG * , BOOL );

	FUNCTION
		This function finds the physical address for the logical address
		passed in by scanning a backup of the MMU translation tree.
		It ignores modifications made by the high-level and low-level
		functions unless RebuildTree() is called.

	INPUTS
		context - the context to enter or NULL for the current context.
				  NOTE: This parameter is currently a dummy and should be
				  set to NULL. The mmu.library will always use the public
				  context for translation.
		addrptr - points to the logical address to be translated.
				  The physical address is filled in here.
		lenptr 	- Points to the length of the address range to be trans-
				  lated. The function returns the length of the largest 
				  possible continous memory range contained in the memory
				  range passed in. Hence, this function may shorten the
				  memory block for fragmentized memory models.
		write	- set this to TRUE for transports from a DMA device INTO
				  the memory, i.e. device reads. Set this to FALSE for
				  writes from memory to the device.

	RETURNS

	NOTES
		The function checks whether the memory range passed in is available
		for DMA. It will guru in case it is not, i.e. the page is either
		swapped out, invalid, indirect, or write protected for
		DMA device reads. Reads into ROM addresses are silently tolerated,
		and, hence, are translations to and from blank dummy pages.

		This function is callable from within interrupts, but does only
		use a backup of the high-level table for its translation.
		Changes to the software abstraction level are not visible for
		this function unless RebuildTree() is called. Changes to the
		hardware level are not at all visible to this (and all other
		high-level) functions.

		In case you've to operate on a range of physical memory, start
		the translation with this call, then compare the size returned
		with the size of the memory block passed in. Because this 
		function may shorten the memory size in case the physical 
		memory is fragmentated, you should be prepared that the size
		returned is smaller than what was passed in. With the physical
		address returned, start the DMA and call DMATerminate() when
		done.
		In case the returned size is smaller than the block passed in,
		add the returned size to the original logical address and 
		call this function again to get the physical location of the 
		next chunk.

		EACH CALL TO DMAInitiate() must be matched by ONE AND PRECISELY
		ONE call to DMATerminate().

		Even though this function does not require locking the context,	
		I highly recommend doing so. It won't crash if you don't, but
		someone else could modify the MMU translation table in between.
		The library can deal with that, but the result of the DMA 
		operation might be different than what you expect.

	BUGS
		This function should really use the context passed in, but
		since most (if not all) DMA device drivers do not keep the 
		context of the task that actually initiated the transfer and
		hence would use the wrong context anyhow, DMA is currently limited
		to the public context.

	SEE ALSO
		DMATerminate(), PhysicalPageLocation(), exec/CachePreDMA()
mmu.library/DMATerminate							mmu.library/DMATerminate

	NAME
		DMATerminate	-	end a DMA transfer initiated by DMAInitiate.

	SYNOPSIS
		DMATerminate( context );
						d1		 

		void DMATerminate( struct MMUContext * );

	FUNCTION
		This function ends a DMA transfer initiated by DMAInitate. It
		releases the resources by the first call.

	INPUTS
		context - the context to enter or NULL for the current context.
				  NOTE: This parameter is currently a dummy and should be
				  set to NULL. The mmu.library will always use the public
				  context for translation.

	RETURNS

	NOTES
		This function is callable from within interrupts, but does only
		use a backup of the high-level table for its translation.
		Changes to the software abstraction level are not visible for
		this function unless RebuildTree() is called. Changes to the
		hardware level are not at all visible to this (and all other
		high-level) functions.

		EACH CALL TO DMAInitiate() must be matched by ONE AND PRECISELY
		ONE call to DMATerminate().

		For details, check the DMAInitiate() function.

	BUGS
		This function should really use the context passed in, but
		since most (if not all) DMA device drivers do not keep the 
		context of the task that actually initiated the transfer and
		hence would use the wrong context anyhow, DMA is currently limited
		to the public context.

	SEE ALSO
		DMAInitiate(), PhysicalPageLocation(), exec/CachePostDMA()
mmu.library/GetMapping								mmu.library/GetMapping

	NAME
		GetMapping 	-	get access to the memory map of a MMUContext

	SYNOPSIS
		list = GetMapping( context );
		d0					a0

		struct MinList * GetMapping( struct MMUContext * );

	FUNCTION
		This function makes a copy of the MapNodes for the given context.
		The nodes in this list describe the memory map as seen from tasks
		attached to this context, sorted by logical addresses.
		The list must be released afterwards with ReleaseMapping().

	INPUTS
		context - the context to enter or NULL for the current context.

	RETURNS
		a pointer to a struct MinList which contains the MapNodes for this
		context, sorted by physical address, or NULL in case of failure.

	NOTES
		The nodes are just a copy of the real nodes within the context.
	
		This function is most useful to make a backup of the context
		memory map before altering it. In case any of the modifications
		fail, you are able to undo all modifications completely with
		a call to SetPropertyList() - which can't fail. 

		To give an example:

		/* make a backup of the context how it looks now */

		LockMMUContext(ctx);

		if (list=GetMapping(ctx)) {
			fine=TRUE;

			/* Try to alter it, step by step. */

			if (!SetProperties(...)) 
				fine=FALSE;

			if (!SetProperties(...))
				fine=FALSE;

			/* etc, etc.... */

			/* Oops, we failed! Re-install the old backup. */
			if (!fine) 
				SetPropertyList(ctx,list);
		}
		
		ReleaseMapping(ctx,list);
		UnlockMMUContext(ctx);
		/* and so on... */

		Note that you've still to call ReleaseContextList(), even in
		case of failure when you've already re-installed backup property
		list.

	BUGS

	SEE ALSO
		ReleaseMapping(), SetPropertyList(), mmu/context.h
mmu.library/ReleaseMapping							mmu.library/ReleaseMapping

	NAME
		ReleaseMapping 	-	get access to the memory map

	SYNOPSIS
		ReleaseMapping( context , list );
						 a0

		void ReleaseMapping( struct MMUContext * , struct MinList * );

	FUNCTION
		This function releases the list of MapNodes arbitrated by 
		GetMapping.

	INPUTS
		context - the context the nodes where taken from.
		list	- the backup property list to release.

	RETURNS

	NOTES
		This function *MUST* be called, even in case the property list
		was re-installed with SetPropertyList().

	BUGS

	SEE ALSO
		GetMapping(), SetPropertyList()

mmu.library/SetPropertyList						mmu.library/SetPropertyList

	NAME
		SetPropertyList		-	re-install a backup memory map

	SYNOPSIS
		SetPropertyList ( context, list );
							a0	    a1

		void SetPropertyList ( struct MMUContext * , struct MinList * );

	FUNCTION
		This call re-installes a property list, i.e. a complete memory
		map of a context, obtained from GetMapping() before.
	
	INPUTS
		context		-	the context the list should be installed in.
						This should be the same context the list was
						taken from.
		list		-	the property list to install. 

		This list *MUST* have been obtained with GetMapping() before.

	RESULTS
		Nothing. The big advantage of this call is that it cannot fail.

	NOTES
		The property list will become part of the context and is empty
		after this call. You can't re-use it for that reason. However,
		you still need to call ReleaseMapping() with the list pointer
		you've obtained before.

		For additional tips how this function should be used, see the
		GetMapping() function; especially, you can only un-do changes
		to the software abstraction level of a MMU-tree, and only as
		long as you haven't called RebuildTree() to translate these
		into hardware MMU tables. Trying to un-do these changes with
		SetPropertyList() will fail, and it will even fail if you call
		RebuildTree() afterwards. SetPropertyList() *does not* inform
		the software abstraction level about any changes, it is just a
		quick un-do operation. (For the experts: It even re-installs
		the "dirty" flags).

	BUGS
		
	SEE ALSO
		GetMapping(), ReleaseMapping(), RebuildTree()

mmu.library/LockContext								mmu.library/LockContext

	NAME
		LockContext - arbitrate a MMUContext for exclusive access

	SYNOPSIS
		LockContext( context );
						a0

		void LockContext( struct MMUContext * );

	FUNCTION
		Locks a context from modification by any task except the calling
		task, i.e. implements a semaphore protection for the context
		passed in.

	INPUTS
		context - the context to enter or NULL for the current context.

	RETURNS

	NOTES
		This lock includes locking the memory map by GetMapping(). It is
		therefore safe to call GetMapping() while holding a context lock.

		The lock must be released later on with UnlockContext().

	BUGS

	SEE ALSO
		UnlockContext()
mmu.library/UnlockContext							mmu.library/UnlockContext

	NAME
		UnlockContext - release a MMUContext lock

	SYNOPSIS
		UnlockContext( context );
						a0

		void UnlockContext( struct MMUContext * );

	FUNCTION
		Releases a lock to a MMUContext arbitrated by LockContext().

	INPUTS
		context - the context to enter or NULL for the current context.

	RETURNS

	NOTES

	BUGS

	SEE ALSO
		LockContext()	
mmu.library/GetMMUType									mmu.library/GetMMUType

	NAME
		GetMMUType - return the type of the MMU available in the system.

	SYNOPSIS
		mmu = GetMMUType( );
						

		char GetMMUType( void );

	FUNCTION
		Returns an identifier for the MMU available in the system or
		NUL in case no MMU is installed.

	INPUTS

	RETURNS
		a character identifying the MMU type:

		MUTYPE_NONE					no working MMU detected.
		MUTYPE_68851				a 68020 system with an external 68851
									MMU.
		MUTYPE_68030				a 68030 MMU.
		MUTYPE_68040				the internal 68040 MMU.
		MUTYPE_68060				the 68060 MMU.

	NOTES
		The mmu library is smart enough to detect EC processors without a
		working MMU, but the library does not detect multiple CPUs in the
		system. (How?)

	BUGS
		EC processor detection is currently disabled since the exception
		handler requires still more testing.

	SEE ALSO
		mmu/mmubase.h
mmu.library/SuperContext							mmu.library/SuperContext

	NAME
		SuperContext - find the supervisor context for a given context.

	SYNOPSIS
		super = SuperContext( context );
		d0						a0						

		struct MMUContext * SuperContext( struct MMUContext * );

	FUNCTION
		Returns the context that manages the supervisor mode for the user
		mode context passed in.

	INPUTS
		A user mode context or NULL for the current context.

	RETURNS
		A pointer to the context managing the supervisor type accesses with-
		in the current context.

	NOTES
		All contexts build by CreateMMUContext are by default user mode
		contexts. The current version of the library manages only one
		(global) supervisor mode context at all, hence the result does
		*currently* not depent on the input, but this might well change.
	
		To find the public supervisor mode context in future releases, call
		DefaultContext() first and pass in its return value to this function.

	BUGS
		The parameter passed in is currently ignored since the library
		supports only one supervisor context right now.

	SEE ALSO
		DefaultContext()

mmu.library/DefaultContext							mmu.library/DefaultContext

	NAME
		DefaultContext	-	get the global default context

	SYNOPSIS
		public = DefaultContext( );
		d0

		struct MMUContext * DefaultContext( void );

	FUNCTION
		Returns the global default user mode context which is used for
		tasks that are not attached to any other private context.

	INPUTS

	RETURNS
		A pointer to the context managing the user mode accesses for
		"context less" tasks.

	NOTES
		A task is by default part of this default context unless you
		call EnterMMUContext() and attach it to a different context.

		Note that you might have to enter even the default context
		explicitly to be able to use certain features of the exception
		hook mechanism.

	BUGS

	SEE ALSO
		SuperContext()
mmu.library/WithoutMMU								mmu.library/WithoutMMU

	NAME
		WithoutMMU - execute a short subroutine with the MMU disabled.

	SYNOPSIS
		result = WithoutMMU( userFunc );
		d0					 a5

		ULONG WithoutMMU(void *);

	FUNCTION
		Executes a small assembly language routine pointed to in a5
		in supervisor mode, with all interrupts disabled, and the MMU
		disabled. All registers are preserved by this call.
		The function must end with an RTS instruction.

	INPUTS
		userFunc	-	A pointer to a *short* assembly language routine,
						ending with RTS. The function has full access to
						all registers.

	RETURNS
		whatever was left in register d0 by the called function.

	NOTES
		This is a low-level function. Remember that disabling the MMU
		might or might not be what you want, especially if memory is
		remapped.

	BUGS
		Big trouble if the supervisor stack is in remapped memory.

	SEE ALSO
		exec/Supervisor()
