![]() Acrobat file (149K) | ![]() ClarisWorks 4 file (41K) | ![]() QuickView file (473K) |
Technote 1001 | OCTOBER 1995 |
This Note is written for driver writers developing drivers of type 'ndrv' for PCI Macintosh computers and for any developer whose code makes calls to the Device Manager as a client of these drivers.
Contents
For those few who choose to port parts of 68K 'DRVR'driver to a native PowerPC code, 68K non-interrupt code can be ported, but the interrupt handling code must remain emulated because a native interrupt handler would not be able to access the PowerPC status register to block interrupts. If you were to use any PowerPC assembly language instructions dealing with that status register, you would cause a fatal supervisory exception. By leaving the interrupt handler as 68K code, that code could continue to "access" the 68K status register because the emulator provides these services to drivers. The native portions of these drivers will have to use UPPs to interface correctly with the 68K Device Manager. Even though the PowerPC code will have to go through a mixed mode switch for interrupt handling, the developer may choose to go this way because the bulk of the remaining code is PowerPC and could increase performance. This Note, however, does not address the details of using the Mixed Mode Manager.
See Inside Macintosh: PowerPC System Software for using 68K code with PowerPC code via the Mixed Mode Manager.
In this new I/O model, there are multiple levels of executions, including application, secondary, and primary execution levels that replace the old method of using interrupts to protect data. The primary and secondary execution levels are specifically for drivers and cannot use Toolbox services. Note that not a single Toolbox Manager is available. The services supplied at these primary and secondary levels via the Driver Services Library (DSL) include interrupt services. Other services, which replace the need to turn off interrupts that protect your data, include:
Again, there is no way to turn off the one and only interrupt on the PowerPC. If you are writing a driver, you may need to deal with a hardware-generated interrupts, assuming your device generates one. For example, a video driver may not generate one while a network driver most likely would. Also, there are new mechanisms and assumptions on how to deal with hardware generated interrupts.
The following example is one type of transactions between an application and a 'ndrv'driver. There are other transactions at present and there will be more types defined with future releases of the Mac OS.
By choosing to write this kind of driver and following all of the guidelines in the above manual, you guarantee compatibility with future releases of the MacOS.
When the driver is loaded into memory by the Mac OS, the driver installs its interrupt routines and data in the Interrupt Source Tree (IST). It does so by using the Driver Services Library (DSL) routine InstallInterruptFunctions
. The routines are used to disable, enable, and service device interrupts.
At some point, code running at the task level makes a PBRead asynchronous call to the driver via the Device Manager using a data structure called an I/O Parameter Block (IOPB)
. Of special note here is that in the past, calls such as this one may have had private pointers contained in the parameter block that was passed to the driver. This will not work in future releases of the Mac OS because of the pending implementation of multiple address spaces. Publicly-documented buffer pointers and IOPB structures will continue to be supported.
The Device Manager makes a call to DoDriverIO
with a read selector. The driver does what is necessary to set up its device for an asynchronous read and returns to the Device Manager with no return error and no indication that the read has been completed. The driver has completed its first task. The Device Manager returns to the caller. When the read has completed, the hardware generates an interrupt which is detected by the Mac OS. Using the interrupt structure which contains the address of the interrupt service routine (ISR) for the device, control is passed to the ISR.
The ISR is allowed to complete its function uninterrupted, which is why an ISR must make every effort to spend as little time as possible servicing its device at the primary interrupt level. The driver should then queue a secondary interrupt handler to do any remaining work to service the device and/or the data using the DSL function QueueSecondaryInterruptHandler
. This ensures that interrupt latency for the system is kept to a minimum.
IOCommandISComplete
passing a completion status, in this case, "read was successful." The IOPB is updated by the Device Manager and control is passed back to the caller's I/O completion routine.And the point of this example? Interrupts are not available to applications, but there are ways for applications and interrupt handlers to exchange information.