File:  [Apple Darwin 0.x] / driverkit / doc / OLD_NRW / chalkTalk.wn / WNDocument.wn
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:37:51 2018 UTC (8 years, 3 months ago) by root
Branches: MAIN, Apple
CVS tags: HEAD, Darwin03, Darwin02
Darwin 0.2 Driver Kit

�W�"$e�e�e|e�e�	���5,7�d99�dHHd�/dUG�6�JUG�6�JDd��X�X�X���TO"$e�e�e|e�e�	��#%�d99�dHHd�/dR��#�2R��#�2DdUGUGUG��







88xHH�/d[(�HHdd'�@��Z
Z�0���

Driverkit 
12 August, 1992

�Z
Z�@�`���0�P��


Agenda:

� Architecture Discussion

� Current Status

� Schedule and Priorities

�Z
Z�@�`���0�P��
�	libIO Timer and Sleep Support Functions

	
�m
X�@�`���0�P����/*
 * Sleep for indicated number of milliseconds.
 */
void ��IOSleep��(unsigned milliseconds);

/*
 * Spin for indicated number of microseconds.
 */
void ��IODelay��(unsigned microseconds);

/*
 * Call function fcn with argument arg in specified number 
 * of seconds.
 */
void �� IOTimeout��(IOThreadFcn fcn, void *arg, int seconds);

/*
 * Cancel callout requested in IOTimeout().
 */
void ��IOUntimeout��(IOThreadFcn fcn, void *arg);

/*
 * Obtain current time in ns.
 */
void ��IOTimeStamp��(ns_time_t *nsp);

�m
X�@�`���0�P����
�	libIO Standard Thread Functions

�m
X�@�`���0�P����/*
 * These are opaque to the user.
 */
typedef void  *��IOThread��;
typedef void (*��IOThreadFcn��)(void *arg);

/*
 * Start a new thread starting execution at fcn with 
 * argument arg.
 */
IOThread ��IOForkThread��(IOThreadFcn fcn, void *arg);

/*
 * Suspend a thread started with IOThreadFork().
 */
void ��IOSuspendThread��(IOThread thread);

/*
 * Resume a thread started by IOThreadFork().
 */
void ��IOResumeThread��(IOThread thread);

volatile void ��IOExitThread��();

�m
X�@�`���0�P����

�#ifdef	KERNEL
	IODevToIdMap	*_idMap;		// provides dev_t to id 
							// mapping for this instance.
#endif	KERNEL
	id		_LogicalDiskLock;	// NXLock. Serializes
							// operations whcih change 
							// LogicalDisks attached to 
							// this device.
	char		_driveName[MAXDNMLEN];	// for Unix 'drive_info'
							// requests 
						
	/*
	 * The lastReadyState variable is initialized by device-specific
	 * subclass, but is subsequently only changed by the 
      * volCheck module.
	 */
	DiskReadyState	_lastReadyState;	
	
	/*
	 * Statistics. Accessed en masse via 
	 * getParameterInt(DISK_STATS_ARRAY).
	 * All times in ms.
	 */
	unsigned	_readOps;
	unsigned	_bytesRead;
�Z
Z�@�`���0�P������IODiskDevice Class
��
�Z
Z�@�`���0�P����@interface IODiskDevice: IODevic
{
@private
	id		_logicalDisk;		// first LogicalDisk object
							// attached to this raw disk.
							// May be nil. 
	unsigned	_blockSize;			// in bytes 
	unsigned	_deviceSize;		// in blockSize's
	unsigned	_removable    	: 1,	// removable media device 
			_formatted		: 1,	// disk is formatted
			_diskIsOpen  	: 1,
			_isPhysDevice 	: 1;	// this is NOT a logical disk
huser_driver Server
����


�m
X�@�`���0�P����� 	Kernel-level server providing:

	�	Device ownership and driver 
			authentication	

	�	Mapping of device registers into driver's 
			VM space

	�	Interrupt notification via Mach messages

	�	DMA functions (enqueue, dequeue)

�	Same RPC interface for User- and Kernel-level
	drivers 


� *  channelNumber of the device represented by devicePort.
 */
IODeviceReturn ��IOAttachChannel��(
	IODevicePort devicePort, 
	int channelNumber,
	BOOL streamMode,
	int bufferSize);
	
/*
 *  Disassociate the dma channel channelNumber from the 
 *  device represented by devicePort. Frees up all resources
 *  associated with specified DMA channel.
 */
IODeviceReturn ��IODetachChannel��(
	IODevicePort devicePort, 
	int channelNumber);
���Z
Z�@�`���0�P��
��Z
Z�@�`���0�P����/*
 *  Build and enqueue a list of dma descriptors. The memory
 *  referenced by the descriptor will be locked. This returns
 *  IO_CR_ALIGNMENT if the channel has been configured as 
 *  a streaming mode channel, rw is IO_DMA_DIR_READ, and
 *  the specified frame crosses a page boundary.
 */
IODeviceReturn ��IOEnqueueDma��(
	IODevicePort devicePort,
	int channelNumber,
	vm_task_t taskId,
	vm_offset_t addr,
	vm_size_t len,
	IODmaDirection rw,
	IODescriptorCommand cmd,	// descriptor command (m88k only)
	unsigned char index,		// descriptor command region/index  
						//    (m88k only)
	IOChannelEnqueueOption opts,
	unsigned dmaId,			// must be non-zero
	BOOL *running);			// returned 
�

/*
 *  Dequeue a dma frame enqueued via chan_dma_enqueue.  
 *  A dma_id of DMA_ID_NULL indicates that no descriptors 
 *  are available; IO_CR_SUCCESS is returned in that case.
 *  IO_CR_BUSY is returned if the channel is still enabled 
 *  and no completed descriptors are available.
 */
IODeviceReturn ��IODequeueDma��(
	IODevicePort devicePort,
	int channelNumber,
	IOChannelDequeueOption opts,
	vm_size_t *bcount,		// RETURNED (except on 
						//  m88k output  devices)
	IOUserStatus *userStatus,	// RETURNED, m88k only
	IODmaStatus *dmaStatus,	// RETURNED
	BOOL *eor,			// RETURNED
	unsigned *dmaId);		// RETURNED
���Z
Z�@�`���0�P��
�Driverkit Architecture
�Z
Z�@�`���0�P��


� 	Class Hierarchy

�	Thread-based model of I/O

� 	libIO

� 	user_driver Server

� 	Autoconfiguration

� 	UXPR tracing
����
� */
- (int)registerDevice;
- (void)unregisterDevice;

/*
 * Get/Set instance variables. 
 */
- (void)��setDeviceName��		: (const char *)name;	
- (const char *)��deviceName��;	
- (void)��setDeviceType��		: (const char *)type;	
- (const char *)��deviceType��;	
- (void)��setLocation��			: (const char *)location;	
- (const char *)��location��;	
- (void)��setUnit��			: (unsigned)Unit;
- (unsigned)��unit��;����

)��/*
 * Obtain device parameters.
 */
- (IODeviceReturn)��getParameterInt�� : 
				   (IOParameterName)parameterName
				   maxCount : (unsigned int)maxCount
				   parameterArray : 
				   	(unsigned int *)parameterArray
				   returnedCount : 
				   	(unsigned int *)returnedCount;
�
- (IODeviceReturn)��getParameterChar�� :
				   (IOParameterName)parameterName
				   maxCount : (unsigned int)maxCount
				   parameterArray : 
				   	(unsigned char *)parameterArray
				   returnedCount : 
				   	(unsigned int *)returnedCount;
			
- (IODeviceReturn)��setParameterInt�� :
				    (IOParameterName)parameterName
				    count : (unsigned int)count
				    parameterArray : 
				   	(unsigned int *)parameterArray;

- (IODeviceReturn)��setParameterChar�� :
				     (IOParameterName)parameterName
				     count : (unsigned int)count
				     parameterArray : 
				   	(unsigned char *)parameterArray;

�	libIO - Miscellaneous Functions
�m
X�@�`���0�P����

�Z
Z�@�`���0�P����/*
 * Log a printf-style string to console.
 */
void ��IOLog��(const char *format, ...);

/*
 * Obtain environment-independent 'task_self' for Mach calls.
 */
task_t ��IOTaskSelf��();

/*
 * Panic (if in the kernel) or dump core (if user space).
 */
void ��IOPanic��(const char *reason);

/*
 * Convert a integer constant (typically a #define or enum) 
 * to a string.
 */
typedef struct {
		int 			rvValue;
		const char 	*rvName;
} ��regValues��;

const char *��IOIntToString��(int value, 
		const regValues *regValueArray);
�Z
Z�@�`���0�P����
�Z
Z�@�`���0�P����/*
 * Memory allocation functions. Both may block.
 */
void *��IOMalloc��(int size);
void ��IOFree��(void *p, int size);
���Z
Z�@�`���0�P��
!�m
X�@�`���0�P��user_driver Server:	
Device ownership and driver authentication	
�m
X�@�`���0�P��


� 	Capability of accessing a hardware device is represented by a ��Device Port��. 

�	All RPCs between a driver and the user_driver server are via Device Port.

�	Device Ports are created by the user_driver server at boot time. 

� 	Device ports given to kernel-level drivers directly (drivers are trusted)

�	Device ports are given to user-level drivers by Config program, which runs at rc time. 


�m
X�@�`���0�P��user_driver Server:
	Mapping of device registers into driver's VM space
�m
X�@�`���0�P��
����/*
 * Map the device register page of the device associated with
 * devicePort into the target task at addr.
 */
IODeviceReturn ��IOMapDevicePage��(
	IODevicePort devicePort,
	task_t targetTask,
	vm_offset_t *addr,		/* in/out */
	BOOL anywhere,
	IOCacheSpec cache);		/* DEV_CACHE_OFF,
							 * DEV_CACHE_WRITE_THRU, etc.
						 	 */

/*
 * Unmap the device register page of the device associated with 
 * devicePort.
 */
IODeviceReturn ��IOUnmapDevicePage��(
	IODevicePort devicePort,
	task_t target_task,
	vm_offset_t addr);
��
�m
X�@�`���0�P��
�m
X�@�`���0�P��

4���m
X�@�`���0�P��user_driver Server:
DMA functions 
�m
X�@�`���0�P��

� 	NRW DMA channels are dynamically allocated to devices - 32 total channels available.
�Z
Z�@�`���0�P��
�m
X�@�`���0�P���	Enqueue/dequeue memory as source/destination of DMA in quanta called 'frames'.

�	One frame can cross page boundaries, but must (currently) follow hardware alignment restrictions (NRW only).

���Z
Z�@�`���0�P��/*
 *  Associate a hardware dma channel with the channel
 Autoconfiguration of NRW Kernel drivers
�Z
Z�@�`���0�P��

�m
X�@�`���0�P���	No hard-coded list of addresses

�	Hardware device identified by "deviceType"	

�	Kernel contains a table mapping deviceType	to driver Class name
�Z
Z�@�`���0�P��
�	user_driver server:

	�  	scans hardware

	�	calls probe:deviceMaster: on each device
		found, passing in the global device number.

	�	Drivers get their devicePort via
		IOCreateDevicePort().

�m
X�@�`���0�P���	There is also a mechanism for starting up "pseudodevices", device drivers which are not attached to a piece of hardware.

�	Indirect devices attach to another IODevice, not to a piece of hardware. E.g., SCSI Disk attaches to SCSIController.
��Z
Z�@�`���0�P�� Autoconfiguration of User level drivers
�Z
Z�@�`���0�P��

�m
X�@�`���0�P���	Config, a privileged user-level program, is the caller of IOCreateDevicePort() for all devices which are not owned by kernel drivers.

�		Config maps deviceType to a file name in /usr/Devices, execs driver if found, and passes Device Port to driver via bootstrap server. 
	
�	User level driver are NOT privileged

�
�Z
Z�@�`���0�P����Driverkit�� Class Hierarchy
��
�Z
Z�@�`���0�P��
�Z
Z�@�`���0�P��
+���>@ClassHierarchy3.641598.eps�

9IODiskDevice Protocols


�Z
Z�@�`���0�P����/*
 * Standard IODiskDevice read/write protocol. Offsets are in blocks.
 * Lengths are in bytes.
 */
@protocol DiskDeviceRw

- (IOReturn) ��readAt��		: (unsigned)offset 
				   length : (unsigned)length 
				  buffer : (out unsigned char *)buffer
				  actualLength : (out unsigned *)actualLength 
				  client : (vm_task_t)client;

- (IOReturn) ��readAsyncAt��	: (unsigned)offset 
				  length : (unsigned)length 
				  buffer : (out unsigned char *)buffer
				  pending : (unsigned)pending
				  client : (vm_task_t)client;
		
- (IOReturn) ��writeAt��		: (unsigned)offset 
				  length : (unsigned)length 
				  buffer : (in unsigned char *)buffer
				  actualLength : (out unsigned *)actualLength 
				  client : (vm_task_t)client;
		  
- (IOReturn) ��writeAsyncAt��	: (unsigned)offset 
				  length : (unsigned)length 
				  buffer : (in unsigned char *)buffer
				  pending : (unsigned)pending
				  client : (vm_task_t)client;
				  

@end
�Z
Z�@�`���0�P����
A	unsigned	_readTotalTime;
	unsigned	_readLatentTime;
	unsigned	_readRetries;
	unsigned	_readErrors;
	unsigned	_writeOps;
	unsigned 	_bytesWritten;
	unsigned	_writeTotalTime;
	unsigned	_writeLatentTime;
	unsigned	_writeRetries;
	unsigned	_writeErrors;
	unsigned	_otherRetries;
	unsigned	_otherErrors;
}��
���Z
Z�@�`���0�P��

�Z
Z�@�`���0�P����/*
 *  Public methods to get and set disk parameters. These are 
 *  implemented in the DiskObject class. 
 */
- (unsigned)��deviceSize��;
- (unsigned)��blockSize����;
�- (IOReturn)��setFormatted���� 		: (unsigned)formattedFlag;
- (unsigned)��formatted����;
- (unsigned)��removable����;
- (const char *)��driveName����;
- (unsigned)��isPhysDevice����;
- (unsigned)��diskIsOpen����;

/*
 *  Two forms of eject - one for use with logical disks attached 
 *  (devEjectDisk), so that attached NXDisks can be polled for 
 *  open state; this method is in the DiskDeviceSubclass protocol 
 *  (below). The other, supported in IODiskDevice, is for an 
 *  exported interface to the physical disk (which is not normally 
 *  used in the kernel).
 */
- (IOReturn) ��ejectDisk����;

@/*
 * Get/set parameters used only by subclasses.
 */		  	
- (void)��setDeviceSize����			: (unsigned)size;
- (void)��setBlockSize����			: (unsigned)size;
- (void)��setIsPhysDevice����			: (unsigned)isPhysFlag;
- ��logicalDisk����;
- (void)��setRemovable����			: (unsigned)removableFlag;
- (void)��setDriveName����			: (const char *)name;
- (DiskReadyState)��lastReadyState����;
- (void)��setLastReadyState����		: (DiskReadyState)readyState;
- (void)��setDiskIsOpen����			: (unsigned)isOpenFlag;

/*
 *  internal setFormatted - avoids logical disk interaction.
 */
- (void)��setFormattedInt����:(unsigned)formattedFlag��;


/*
 *  Statistics support.
 *
 *  These methods are invoked by subclass during I/O.
 */
- (void)��readStats����	: (unsigned)bytesRead
				  totalTime  : (ns_time_t)totalTime
				  latentTime : (ns_time_t)latentTime;
- (void)��writeStats����	: (unsigned)bytesWritten
				  totalTime  : (ns_time_t)totalTime
				  latentTime : (ns_time_t)latentTime;
- (void)��didReadRetry����;
- (void)��gotReadError����;
- (void)��didWriteRetry����;
- (void)��gotWriteError����;
- (void)��didOtherRetry����;
- (void)��gotOtherError����;

@end

�Z
Z�@�`���0�P����
T�Z
Z�@�`���0�P����/*
 *  The DiskDeviceSubclass protocol must be implemented by each 
 *  bottom-level subclass of IODiskDevice.
 */

@protocol DiskDeviceSubclass

/*
 *  Get physical parameters (dev_size, block_size, etc.) from new 
 *  disk. Called upon disk insertion detection or other transition to 
 *  RS_READY.
 */
- (IOReturn)��getPhysParams����;

/*
 *  Called by volCheck thread when WS has told us that a requested 
 *  disk is not present. Pending I/Os which require a disk to be present 
 *  must be aborted.
 */
- (void)��abortRequest����;
�
/*
 *  Called by the volCheck thread when a transition to "ready" is 
 *  detected. Pending I/Os which require a disk may proceed.
 */
- (void)��diskPresent����;

/*
 *  Inquire if disk is present; if not, and 'prompt' is TRUE, ask for it. 
 *  Returns IO_R_NODISK if:
 *    prompt TRUE, disk not present, and user cancels request for 
 *            disk.
 *    prompt FALSE, disk not present.
 *  Else returns IO_R_SUCCESS.
 */
- (IOReturn)��isDiskPresent����	: (BOOL)prompt;

R/*
 * Device-specific eject method.
 */
- (IOReturn) ��devEjectDisk����;
$
/*
 *  Determine basic state of device. This method should NOT 
 *  implement any retries. It also should not return RS_EJECTING 
 *  (That's only used in the lastReadyState instance variable).
 */
- (DiskReadyState)��checkReady����;

@end
�Z
Z�@�`���0�P����
��m
X�@�`���0�P��user_driver Server:	
Interrupt notification via Mach messages

�m
X�@�`���0�P��
� 	No code in any driver runs at spl.

�	All interrupt notification is via Mach message mechanism. 


��/*
 *  Request that interrupt notification messages for the device
 *  represented by devicePort be sent to the port interruptPort.
 */
IODeviceReturn ��IOAttachInterrupt��(
	IODevicePort devicePort, 
	port_t interruptPort);
	
/*
 *  Disassociate interrupt notification messages for the device
 *  represented by devicePort from being sent to intr_port.
 */
IODeviceReturn ��IODetachInterrupt��(
	IODevicePort devicePort, 
	port_t interruptPort);

�
/*
 * Issue command on the dma channel identified by devicePort and 
 * channelNumber. 
 * 
 *  IO_CHAN_NONE can be specified for channelNumber if no 
 *  channels are attached; in this case the only legal 
 *  IOChannelCommand bits are IO_CC_INTR_ENABLE and 
 *  IO_CC_INTR_DISABLE.
 */
IODeviceReturn ��IOSendChannelCommand��(
	IODevicePort devicePort,
	int channelNumber,
	IOChannelCommand command);

/* 
 * Values for IOChannelCommand.
 */
#define ��IO_CC_INTR_ENABLE��		0x0001	// enable interrrupts
#define ��IO_CC_INTR_DISABLE��	0x0002	// disable interrupts
#define ��IO_CC_LOOP_FRAME��		0x0004	// create DMA frame
										//    loop
#define ��IO_CC_UNLOOP_FRAME��	0x0008	// disconnect DMA
										//    frame loop

�Z
Z�@�`���0�P��UXPR tracing


�m
X�@�`���0�P���	Like the 68k Kernel's xpr function - silent, cheap storing of sprintf strings in a circular buffer, evaluated subsequent to run time

�	XPRViewer App allows displaying uxpr data in a scrollview on a separate machine

�	XPRViewer also allows setting uxpr masks (filter bits) by name instead of by hex value

�	XPRViewer runs on kernel drivers as well as on user-level drivers

�	NRW kernel has multiple words of uxpr masks (m68k only had one word) 

V�Z
Z�@�`���0�P��Current Status
�Z
Z�@�`���0�P��
�m
X�@�`���0�P���	All functionality is present in Alpha baseline release.
�Z
Z�@�`���0�P��
�m
X�@�`���0�P���	m88k Kernel level drivers completed:
�Z
Z�@�`���0�P��	�	SCSIController, SCSIDisk
	�	FloppyController, FloppyDisk
	�	Ethernet
	�	adbDriver, adbDevice, adbKeyboard,
		adbPointer 
	�	kmDevice
	�	EventDriver

�m
X�@�`���0�P���	m88k User level drivers completed:
�Z
Z�@�`���0�P��	�	Laser Printer

�m
X�@�`���0�P���	Config is working and released, but doesn't run from /etc/rc yet.

�	Intend to modify kernloader to run all loaded servers in IOTask context. 
�Z
Z�@�`���0�P��

�Z
Z�@�`���0�P��
�Current Status (continued)
�Z
Z�@�`���0�P��
�	Drivers in development:

	�	zs (Serial) - Mike DeMoney
	�	Token Ring - Joel Greeblatt
	�	Sound - Mike Minnick
	�	ISDN - Morris Meyer and Rich Williamson
	�	SCSI Tape, SCSI Generic - dmitch

�m
X�@�`���0�P���	IONetDevice, the basis for Ethernet and Token Ring, is being extensively modifed. Serial driver will also be a subclass of this device.
IODevice Class
��
�Z
Z�@�`���0�P����@interface IODevice: Object
{
@private
	/* 
	 * these fields must be initialized by the device-specific code prior
	 * calling registerDevice.
	 */
	int			_unit;			// like a minor number. Use
							// is unique per device.
	IOUnitName	_deviceName;	// E.g., "sd0a"
	IOUnitType		_location;		// E.g., "0xf7f04000"
	IOUnitType		_deviceType;	// E.g., "SCSIDisk"
}

/*
 * Register/unregister instance in current namespace. 
 * _deviceName must be valid for both calls.
3libIO

�m
X�@�`���0�P��� 	C library
�Z
Z�@�`���0�P��
�m
X�@�`���0�P��� 	Allows writing driver code which is easily portable between kernel and user

�	Supercedes "Kernel Internal API" specified in Loadable Kernel Server Tech Doc
�Z
Z�@�`���0�P��
�m
X�@�`���0�P���	Provides

	� 	Timer and sleep support
	
	� 	Standard Thread functions

	� 	Error Logging

	�	Memory Allocation

	�	Machkit-compatible NXLock objects in the 
			kernel

�m
X�@�`���0�P��
�Thread-based model of I/O



�m
X�@�`���0�P���	One piece of hardware is associated with one thread. 

�	Interrupts are seen by drivers as Mach messages.

�	Context:

	�	Kernel - all threads are part of one task
			called IOTask. IOTask has:

			�	Kernel's physical memory map.
			�	Its own VM map.	
			�	Its own IPC space.

	�	User - all threads part of driver's task_self().
�Z
Z�@�`���0�P��
�d�et.Nt,ra%-
>-:tNX8$�%��$�PtE���d1]$3�%6_�d8��t-=�d0x�t;�@$>%?�@d@K�TR��TPi�tm�t�t�Ot
J�t 6�t"Y�tAq�%D5�G5t%e[d�e�@d�ET'�7T*�TG8�TIR
TL�Z�m
X�@�`���0�P��user_driver Server:	
Device ownership and driver authentication	
�m
X�@�`���0�P��


� 	Capability of accessing a hardware device is represented by a ��Device Port��. 

�	All RPCs between a driver and the user_driver server are via Device Port.

�	Device Ports are created by the user_driver server at boot time for Kernel drivers and at rc time for User level drivers. 

� 	Device ports given to kernel-level drivers directly (drivers are trusted)

�	Device ports are given to user-level drivers by Config program, which runs at rc time. 

�d�et.Nt,ra%-
>-:tNX8$�%��$�PtE���d1]$3�%6_�d8��t-=�d0x�t;�@$>%?�@d@K�TR��TPi�tm�t�t�Ot
J�tUG�t"Y�tAq�%D5�G5t%e[d�e�@d�ET'�7T*�TG8�TIR
TL�

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.