NOTE: This Technical Note has been
retired. Please see the Technical Notes
page for current documentation.|
Everybody Must Get Physical
If you are developing NuBus expansion cards with bus mastership or direct memory access (DMA) capabilities, and if you have ever done development or compatibility testing with Apple's recent machines, like the Macintosh IIci and Macintosh IIsi, you have undoubtedly noticed some strange behavior. You might tell the card to dump data into a buffer at $00300000 and the data instead appears at $006B0000. "What's happening here?" you must ask yourself.
Well, there's a new game in town--it's called a discontiguous physical address space. What that means in simple terms is that there is potentially a big hole in memory. If you have eight megabytes installed in a Macintosh IIci, for instance, that memory appears to the CPU and to NuBus in two separate 4 MB ranges: [$00000000 - $003FFFFF] and [$04000000 - $043FFFFF]. Everything from the end of Bank A to the beginning of Bank B is essentially empty. Bank B memory does not start until at least $04000000.
To compensate for this, the operating system uses the memory management unit (MMU) to map all the physical memory (what the hardware sees) into a single contiguous logical address space (what all Macintosh code sees). The logical address space looks exactly like the memory map you've known for years. The translation is completely transparent to software. If you're an applications developer and you read the low-memory global at $10C, you don't care that the address that the processor actually looks at is $0400010C. When the processor originally put a value in that spot, it went through the same translation. Everything is relative and you always get just what you'd expect.
The sole exception is for software which runs on the Macintosh but communicates
addresses to NuBus master hardware. Say, for instance, that you have developed
a video frame grabber which dumps an image into a handle you've allocated for
that purpose. When you call
The point is, now you must be sure to always convert logical addresses to
corresponding physical addresses before passing them to any alternate bus
master. A new function to support this is
I'm glad you asked, because VM and the memory architecture of the Macintosh
IIci are related topics.
You can call
Holding and Locking Memory Versus Locking Handles
Virtual Memory introduces two new concepts--holding and locking a range of virtual memory. These are not to be confused with locking a handle. Locking a handle prevents the handle from changing its logical address during Memory Manager operations. Holding and locking virtual memory affects how VM deals with arbitrary ranges of memory during paging operations.
Holding and locking memory (as opposed to a handle) are VM functions
exclusively and are accomplished with four new
Holding a range of memory guarantees that the data in that range is actually somewhere in physical Macintosh RAM and that no paging activity is necessary to load it. This is critical for tasks which run at interrupt time, since paging activity should not be initiated at interrupt time. VM is not guaranteed to be reentrant, and because interrupts may occur in the middle of paging, any data accessed by an interrupt handler should reside in a held block of memory. Only hold memory which legitimately needs to be held though, because any memory which is held becomes ineligible for paging. This reduces the space VM has to work with and may significantly impact system performance. Some interrupt-time tasks are deferred by VM until paging is safe, so memory they touch does not always have to be held. These tasks are called out below, in the section "Compatibility With Other Device Drivers and Interrupt-Level Code."
Locking a range of memory is more severe than holding it. This not only forces
the range to be held resident in physical RAM, but also prevents its logical
address from moving with respect to its physical address. This is important
for drivers which initiate DMA transactions, because there must be a known,
static relationship between logical and physical addresses for the duration of
such an operation. Part of the behavior of
In non-VM environments, there is no page swapping activity. This is similar to
all of memory being locked, except that caching is still enabled. Truly locked
memory is neither cached nor paged. If you are running System Software 7.0
with VM, you must explicitly lock a range of memory with
There is one more VM routine of interest,
Apple's primary recommendation regarding
When to Call?
When Not to Call?
What Form Of Address To Pass?
Because its ROM is derived from that of the Macintosh IIci, the Macintosh LC may
appear to have
In order to solve both of these problems as cleanly as possible, the MPW
libraries contain an enhanced version of
(*At this writing, the enhanced
Compatibility With Accelerator Upgrades
The burden of compatibility has long been on the shoulders of accelerator manufacturers. VM may present some additional compatibility challenges for these manufacturers.
Virtual Memory requires services which are not present in the ROMs of 68000-based machines, so VM is not supported by the Macintosh SE, even one with a 68030 accelerator. The same is true of the Macintosh Plus, the Macintosh Classic, and the Macintosh Portable. There is no guarantee that these older machines will ever be able to support VM. For practical reasons, Apple has chosen not to implement VM in a wholly ROM-independent manner. In the foreseeable future, only machines in which Apple intended to include memory management units can support Virtual Memory. Machines never intended to include an MMU do not have all the ROM code required by VM.
Virtual Memory depends on low-memory globals to indicate the presence of a memory management unit at a very early stage of the boot process. In some cases, the low-memory globals are not properly set by the boot code in ROM if the hardware features of an accelerator are significantly different from those of the stock Macintosh. The most likely problems are exhibited by 68000 Macintoshes, 68020 Macintoshes with 68030 accelerators, and Macintoshes with 68040 accelerators. There is third-party virtual memory software which provides much of the VM functionality of System Software 7.0, and which is also compatible with accelerator products. In some cases this software may be bundled with the accelerator.
Apple is not saying that VM does not work with any accelerator, but rather that the System 7.0 implementation of Virtual Memory in general does not support accelerators. Some accelerator products may work or may be modified to work. Apple simply does not guarantee that any particular accelerator product works with VM.
Compatibility With Removable Media
Obviously it would be a disaster if a user ejected the cartridge containing his backing store (paged out memory) and handed it to a co-worker to take home. This would be much worse than giving away a floppy, to be faced with the "Please insert the disk..." alert. Someone would actually have part of the computer's memory in his briefcase--try to type Command-period and get out of that one. To guard against this possibility, ejectable media are not permitted to host the VM backing store. Users of removable cartridge drives are not wholly excluded, however. The driver software for such a drive may impose software interlocks to prevent ejection and indicate in the drive queue that the cartridge is nonejectable. VM accepts any sufficiently large, block oriented device as long as it is not ejectable.
Compatibility With SCSI Code
Virtual Memory introduces new requirements for some SCSI hard disk drivers. Users of Apple hard disks may need to update their drivers with a System Software 7.0-compatible Apple HD SC Setup application. Third-party hard disk drivers may also need to be updated. It is up to these third parties to determine what enhancements, if any, are required for their drivers and to provide updates to their customers if necessary.
For SCSI disk driver developers, one requirement for VM compatibility may be summarized as follows (special thanks to Andy Gong for the detailed analysis):
On System 6.0.x and earlier, all calls to the SCSI disk driver came from the file system. This being true, and the file system being single-threaded, only one SCSI disk driver would be called at any one time. Virtual Memory changes this scenario because it makes calls to the driver directly, avoiding the file system. This implies the possibility of SCSI drivers being reentered.
For a SCSI driver to function correctly in the VM environment, the driver must have complete driver data separation at least on a drive-by-drive basis. Such separation makes the driver reentrant on a drive-by-drive basis. If the driver supports multiple HFS partitions on the same physical drive, the driver must be completely reentrant if any of the HFS partitions are to be used for the VM backing file.
All this means is that a driver which controls multiple drives or partitions must maintain separate driver variables to reference each drive or partition. Otherwise, the state of a transaction to one drive may be lost when the driver is reentered to service another drive. There is no problem with reentrancy for drivers which control only a single drive or partition.
In many cases of SCSI code incompatibility, reentrancy is not the problem. This affects only the small number of SCSI disk drivers which are designed to control multiple drives or partitions from a single driver. A more common problem is caused by a page fault while the SCSI bus is busy. Since VM depends on the SCSI bus to handle a page fault, a page fault is forbidden to happen while the SCSI bus is busy. Code which uses the SCSI Manager needs in general to ensure that all its code, buffers, and data structures (including TIBs) are held in real memory before taking control of the bus.
In the normal course of events, the system heap is held in real memory. Other
critical structures are held for you automatically, like any range of memory passed
to a Device Manager
If your SCSI code is not a standard Device Manager driver or if you reference
In addition to the requirement for reentrancy across drives served by a single driver, the driver for a disk used as a backing store must load at the earliest possible opportunity. Drivers which defer installation until INIT time are too late to be used by VM.
Compatibility With Other Device Drivers and Interrupt-Level Code
The primary concern for device drivers is that they commonly run at interrupt time and it is absolutely essential that interrupt-level code does not cause a page fault. To avoid this, drivers should make certain that any data structures they keep or reference at interrupt time are held in physical memory as described earlier. Locking the structures is typically not necessary except in cases where alternate bus master hardware accesses those structures as well.
To improve performance and compatibility with existing software and drivers, the first release of
System Software 7.0 always holds the entire system heap in physical memory. No special measures need
be taken if your driver and its associated data structures are all installed in the system heap. If your
driver uses memory statically allocated above
The Device Manager deals with
Certain code types are always deferred until times when paging is safe, and as
such don't have to be concerned about whether memory they touch is guaranteed
to be held. Those code types include Device Manager I/O completion routines,
Time Manager tasks, VBL tasks, and slot VBL tasks. The trade-off is in real-time
performance. Clearly, since these tasks may be deferred, there is an increased
possibility of latency which may be unacceptable for some pseudo-real-time
applications. (The Macintosh has never supported true real-time processing.)
An arbitrary function which might cause a page fault at interrupt time can be
deferred explicitly by calling it via the trap
Apple Desktop Bus I/O requests are deferred until a time when paging is safe unless VM is certain that all code and associated data structures are located in the system heap. This is required because the ADB Manager normally processes incoming data at interrupt time and there is a potential for page faults if the service routine code or other data structures are not held in real memory. The only problem with this strategy is reduced performance for specialized ADB drivers which require most of the ADB bandwidth and don't live in the system heap. Nonetheless, it's worth mentioning.
One final note of interest pertains to a longstanding anomaly in the Device
Manager. As it turns out, when you make an asynchronous
Compatibility With the BufPtr Method of Static Allocation
Inside Macintosh, Volume IV describes, on page 257, a method of static allocation for resident drivers or other data structures. This method has been very popular with a number of developers. The main thing for developers to remember about this method in conjunction with VM is that memory allocated in this way is not held in physical memory by default. It must be explicitly held, unlike memory in the system heap which the operating system automatically holds, at least in the first release of System Software 7.0.
When allocating memory above
Due to the way memory is organized with VM in 24-bit addressing, you may not be
able to achieve nearly as much memory above
Compatibility With 32-Bit Addressing
To make the most valuable use of Virtual Memory, 32-bit addressing is extremely
important. Needless to say, it is critical that all developers test their
applications, drivers, and all other types of code extensively under System 7.0
while running 32-bit addressing--both with and without VM. Four megabit SIMMs
are becoming less and less expensive, and the day is not far off when machines
with at least 16 MB will be common. Correct behavior with 32-bit addressing is
critical to the acceptance of both System 7.0 and developer applications. It
is not acceptable to ask users to reboot with 24-bit addressing in order to use
your hardware or software. For a few classes of applications it may be necessary
to turn VM off in order to run efficiently, but VM should not prevent an
application from running at all. Be sure to include a
User Tips and Helpful Hints for Living With VM
Apple suggests that Virtual Memory runs more efficiently with at least four megabytes of physical RAM. Although System Software 7.0 runs on two-megabyte systems, using VM on such a system may result in unacceptable paging performance and hard disk thrashing. After holding the system heap and other RAM which must remain resident, there is simply not enough room left for efficient paging. Fortunately, with the recommended four or five megabytes, most users should be able to run arbitrarily large virtual memory environments, with little or no annoyance from paging delays and limited primarily by the sacrifice in disk space.
Virtual Memory trades virtual RAM size for some degree of performance. VM users should be aware that VM is not always a viable alternative to physical RAM. For example, an application which makes heavy use of an entire 8 MB partition for image processing may execute very sluggishly on a machine with only 4 MB of real RAM. (The benefit of VM in this case that such an application runs at all on a machine with limited RAM.) On the other hand, the same machine may concurrently run six or seven different megabyte-plus applications with little or no appreciable performance degradation except when switching among them. (This is where VM really shines.) Performance is determined by virtual RAM size versus physical RAM size with the memory access dynamics of each application thrown in as a wild card. Each VM user will find a combination of settings which he or she finds most comfortable.
A Special Note Regarding 24-Bit VM
Some machines in the installed base are capable of running VM, but do not have 32-bit clean ROMs and must run with 24-bit addressing. What this means to users who want to run VM is that they can only take advantage of 14 MB of virtual memory. That's all there is room for in a 24-bit address map. More likely the limit is 12 or 13 MB because every installed NuBus card eliminates 1 MB of virtual RAM address space. (The way VM increases RAM size with 24-bit addressing is--more or less--by making each unused NuBus slot look like a 1 MB RAM card and making ROM and each installed NuBus card look like a non-relocatable 1 MB application partition.)
You can be a real friend to the Process Manager (formerly known as MultiFinder) by taking care in which slots you install NuBus expansion cards: ROM always occupies one megabyte at $800000, limiting the largest contiguous block of virtual memory to somewhat less than eight megabytes. The balance may be in a contiguous block as large as four or five megabytes unless it is fragmented by a poor selection of slots for expansion cards. Best results are achieved by placing all expansion cards in consecutive slots at either end of the bus--this has the effect of collecting all the immovable one megabyte rocks into a single pile where one is less likely to trip over them. Haphazard placement of NuBus cards may generate a number of one or two megabyte islands interspersed throughout the upper portion of the virtual memory space, and that does not help to run more applications or to manipulate larger objects.
In machines with fewer than six NuBus slots, recall that one "end" of the bus is actually in the middle of the slot address space. In a Macintosh IIcx, slots are numbered $9 through $B. Expansion cards should be installed from the lowest-numbered slot up (contiguous with the ROM) to avoid fragmentation. In a Macintosh IIci, slots are numbered $C through $E. This poses a greater problem. Due to the RAM-based video in virtual slot $B, it is nearly impossible to avoid some degree of fragmentation when using the built-in video option. When not using this option, installing NuBus cards from the highest-numbered slot down (at the end of memory) is the best course. Fortunately, the IIci ROM supports 32-bit addressing. In 32-bit addressing VM, none of this discussion applies. Virtual Memory and NuBus do not share space in the 32-bit address map.
A Template for GetPhysical Usage
A great deal of the justification for this code may be inferred from the code itself and the comments within. The basic rules are all covered in the previous text, but the simmered-down algorithm sans error handling is this:
See if there is
If there is
If the memory is locked:
Process a physical block;
Until all physical blocks have been processed;
Until all memory is translated;
Process the block of memory the way you used to;
Inside Macintosh, Volume II, Memory Manager
Inside Macintosh, Volume IV, Initialization Resources
Inside Macintosh, Volume VI, Compatibility Guidelines
Inside Macintosh, Volume VI, Memory Management
Technical Note M.HW.Cache -- Cache As Cache Can
NuBus is a trademark of Texas Instruments
THINK is a trademark of Symantec Corporation
Contact ADC | ADC Site Map | ADC Advanced Search
|For information about Apple Products, please visit Apple.com.|
Contact Apple | Privacy Notice
Copyright © 2002 Apple Computer, Inc. All rights reserved.