Writing Device Drivers
只搜寻这本书
以 PDF 格式下载本书

Hardware Overview

2

This chapter discusses some general issues about the hardware that SunOS 5.x runs on. This includes issues related to the processor, bus architectures, and memory models supported by Solaris 2.x, various device issues, and the PROM used in Sun platforms.

Note - The information presented here is for informational purposes only and may be of help during driver debugging. However, the Solaris 2.x DDI/DKI hides many of these implementation details from device drivers.

SPARC Processor Issues

This section describes a number of SPARC processor-specific topics including data alignment, byte ordering, register windows, and availability of floating point instructions.

Data Alignment

All quantities must be aligned on their natural boundaries. Using standard C data types:
  • short integers are aligned on 16-bit boundaries.
  • long integers are aligned on 32-bit boundaries.
  • long long integers are aligned on 64-bit boundaries.
Usually, alignment issues are handled by the compiler. Driver writers are more likely to be concerned about alignment as they must use the proper data types to access their device. Since device registers are commonly accessed through a pointer reference, drivers must ensure that pointers are properly aligned when accessing the device. See "Device Issues" on page 44 for more information about accessing device registers.

Structure Member Alignment

Because of the data alignment restrictions imposed by the SPARC processor, C structures also have alignment requirements. Structure alignment requirements are imposed by the most strictly-aligned structure component. For example, a structure containing only characters has no alignment restrictions, while a structure containing a long long member must be constructed to guarantee that this member falls on a 64-bit boundary. See "Structure Padding" on page 47 for more information on how this relates to device drivers.

Byte Ordering

The SPARC processor uses big endian byte ordering; in other words, the most significant byte of an integer is stored at the lowest address of the integer.

Imported image(369x72)

Register Windows

SPARC processors use register windows. Each register window is comprised of 8 in registers, 8 local registers, and 8 out registers (which are the in registers of the next window). There are also 8 global registers. The number of register windows ranges from 2 to 32 depending on the processor implementation.
Because drivers are normally written in C, the fact that register windows are used is usually hidden by the compiler. However, it may be necessary to use them when debugging the driver. See "Debugging Tools" on page 243 for more information on how register windows are used when debugging. Also see the SPARC Assembly Language Reference Manual for more information.

Floating Point Operations

Drivers should not perform floating point operations, since they are not supported in the kernel.

Multiply and Divide Instructions

The Version 7 SPARC processors do not have multiply or divide instructions. These instructions are emulated in software and should be avoided. Since a driver cannot tell whether it is running on a Version 7 or Version 8 processor, intensive integer multiplication and division should be avoided if possible. Instead, use bitwise left and right shifts to multiply and divide by powers of two.

SPARC Architecture Manual

The SPARC Architecture Manual, Version 8, contains more specific information on the SPARC CPU.

x86 Processor Issues

This section describes a number of x86 processor-specific topics including data alignment, byte ordering and floating point instructions.

Data Alignment

There are no alignment restrictions on data types. However, extra memory cycles may be required for the x86 processor to properly handle misaligned data transfers.

Structure Member Alignment

See "Structure Padding" on page 47 for more information on how this relates to device drivers.

Byte Ordering

The x86 processor uses little endian byte ordering. The least significant byte of an integer is stored at the lowest address of the integer.

Imported image(377x66)

Floating Point Operations

Drivers should not perform floating point operations, since they are not supported in the kernel.

x86 Architecture Manuals

Intel Corporation publishes a number of books on the x86 family of processors.
80386 Programmer's Reference Manual, Intel Corporation, 1986. ISBN 1-55512- 022-9.
i486 Microprocessor Hardware Reference Manual, Intel Corporation, 1990. ISBN 1- 55512-112-8.
Pentium Processor User's Manual - Volume 3: Architecture and Programming Manual, Intel corporation, 1993. ISBN 1-55512-195-0.

System Memory Model

This section describes memory model implications for device drivers.

Store Buffers

To improve performance, the system hardware may buffer data written to device memory. This may affect the synchronization of device I/O operations. Writes to device registers may pass through several system I/O buffers before reaching the registers. The driver needs to take explicit steps to make sure that writes to registers complete at the proper time.
For example, when acknowledging an interrupt, the driver usually sets or clears a bit in a device control register. The driver must ensure that the write to the control register has reached the device before the interrupt handler returns. Similarly, if the device requires a delay (the driver busy-waits) after writing a command to the control register, the driver must ensure that the write has reached the device before delaying.
If the device registers can be read without undesirable side effects, verification of a write can be as simple as reading the register immediately after writing to it. If that particular register cannot be read without undesirable side effects, another device register in the same register set can be used (see ddi_map_regs(9F)).
If no device register in the set can be read without undesirable side effects, one of the ddi_poke(9F) routines may be used, as a last resort, to write to the registers. When these routines return, they guarantee that the write has reached the device.

Note - Future hardware platform implementations may not permit the ddi_poke(9F) routines to guarantee that a write has reached a device. Drivers should avoid the use of ddi_poke(9F) for this purpose whenever possible.

SPARC Memory Model

The SPARC memory model defines the semantics of memory operations such as load and store and specifies how the order in which these operations are issued by a processor is related to the order in which they reach memory. The memory model applies to both uniprocessors and shared-memory multiprocessors. Two memory models are supported by the SPARC processor: Total Store Ordering (TSO) and Partial Store Ordering (PSO). All SPARC processors must support TSO.
TSO guarantees that the store, FLUSH, and atomic load-store instructions of all processors appear to be executed by memory serially in a single order called the memory order. Furthermore, the sequence of store, FLUSH, and atomic load-store instructions in the memory order for a given processor is identical to the sequence in which they were issued by the processor.
Like the TSO memory model, PSO guarantees that the store, FLUSH, and atomic load-store instructions of all processors appear to be executed by memory serially in a single order called the memory order. However, the memory order of store, FLUSH, and atomic load-store instructions for a given processor is, in general, not the same as the order in which the instructions were issued by that processor. Conformance between issuing order and memory order is provided by the STBAR instruction: if two of the above instructions are separated by an STBAR in the issuing order of a processor, or if they reference the same location, then the memory order of the two instructions is the same as the issuing order.
See Chapter 6, Appendix J, and Appendix K of The SPARC Architecture Manual, Version 8 for more details on the SPARC memory model.

Bus Architectures

This section describes a number of bus-specific topics including device identification, device addressing, and interrupts.

Device Identification

Device identification is the process of determining which devices are present in the system.

Self-Identifying Devices

Some devices are self-identifying--the device itself provides information to the system so that it can identify the device driver that needs to be used. The device usually provides additional information to the system in the form of name-value pairs that can be retrieved using the property interfaces. See "Properties" on page 57 for more information on properties.
SBus devices are examples of self-identifying devices. The information is usually derived from a small FORTH program stored in the FCode PROM on the device. See sbus(4) for more information.

Non-Self-Identifying Devices

Devices that do not provide information to the system to identify themselves are called non-self-identifying devices. Drivers for these devices must have a probe(9E) routine which determines whether the device is really there. In addition, information about the device must be provided in a hardware configuration file (see driver.conf(4)), so that the system can provide probe(9E) with the information it needs to contact the device. See "probe( )" on page 93 for more information.
VMEbus, ISA, EISA, and MicroChannel devices are examples of non-self-identifying devices. SCSI target devices and pseudo devices are also non-self-identifying devices. See vme(4), isa(4), scsi(4), and pseudo(4) for more information.

Device Addressing

Device addressing is different on the buses that SunOS currently supports.
The SBus is geographically addressed; each SBus slot exists at a fixed physical address in the system. An SBus card has a different address depending on which slot it is plugged into. Moving an SBus device to a new slot causes the system to treat it as a new device. See "Persistent Instances" on page 93 for more information.
On other buses, such as the VMEbus, each card has its own address, possibly configurable by jumpers. A VMEbus card has the same address no matter which slot it is plugged into. Changing the address of a VME card causes the system to treat it as a new device.

Interrupts

SunOS supports polling interrupts and vectored interrupts.
The SBus uses polling interrupts. When an SBus device interrupts, the system only knows which of several devices might have issued the interrupt. The system interrupt handler must ask the driver for each device whether it is responsible for the interrupt.
The VMEbus uses vectored interrupts. When a VMEbus device interrupts, the system can identify which device is interrupting and call the correct device driver directly.
The Solaris 2.x DDI/DKI interrupt model is the same for both types of devices. See Chapter 6, "Interrupt Handlers," for more information about interrupt handling.

Bus Specifics

This section covers addressing and device configuration issues specific to the buses that SunOS supports.

SBus

Typical SBus systems consist of a motherboard (containing the CPU and SBus interface logic), a number of SBus devices on the motherboard itself, and a number of SBus expansion slots. An SBus can also be connected to other types of buses through an appropriate bus bridge.
Following is a discussion of how the SBus is implemented in the SPARCstation(TM) 1 and SPARCstation(TM) 1+.

Physical Address Space

The physical address space layout of the SPARCstation 1 and SPARCstation 1+ is shown in Table 2-1.
Table 2-1
SpaceRangeUsage
Main Memory0x00000000 - 0xEFFFFFFFMain Memory
I/O Devices0xF0000000 - 0xF7FFFFFF
0xF8000000 - 0xF9FFFFFF
0xFA000000 - 0XFBFFFFFF
0xFC000000 - 0xFDFFFFFF
0xFE000000 - 0xFFFFFFFF
Sun I/O Devices
SBus Slot 0
SBus Slot 1
SBus Slot 2
SBus Slot 3

Physical SBus Addresses

The address bus of the SPARC CPU has 32 bits. The SBus has 28 address bits, as described in the SBus Specification.
In the SPARCstation 1, the address bits are used as described in Table 2-2:
Table 2-2
BitsDescription
0 - 24These bits are the SBus address lines used by a SBus card to address the contents of the card.
25 - 26Used by the CPU to select one of the SBus slots. These bits generate the SlaveSelect lines.
27Used by the CPU to distinguish between SBus devices and
devices resident on the CPU board. A one (1) indicates an SBus
device, and a zero (0) indicates an on-board device.
28 - 31Not used. For compatibility with Sun-4 architecture conventions, these bits are assumed to be all ones.
This addressing scheme yields the SPARCstation 1 and SPARCstation 1+ addresses shown earlier in Table 2-1. Other implementations may use a different number of address bits.

SBus Slots

SBus systems have several SBus slots. The number of slots is system-specific.
The SPARCstation 1 has four SBus slots, numbered 0 through 3. Slot 0 is reserved; slots 1, 2 and 3 are available for SBus cards. The slots are used in the following way:
  • Slot 0 is not a physical slot, but refers to the on-board DMA, SCSI, and Ethernet controllers. For convenience, these are viewed as being plugged into Slot 0.
  • Slots 1 and 2 are physical slots that have DMA-master capability.
  • Slot 3 is a slave-only physical slot that does not support boards that operate as DMA masters.
On other systems, for example the SPARCstation 10, slot 15 (slot 0xf) is the on-board slot, and slots 0-3 are available for SBus cards. Slots 4-14 are reserved.
Because some SBus systems (such as the SPARCstation 1) may not allow some slots to perform DMA, drivers that require DMA capability should use ddi_slaveonly(9F) to determine if their device is in a DMA-capable slot. For an example use of this function, see "attach( )" on page 95.

Hardware Configuration Files

Hardware configuration files should be unnecessary for SBus devices. However, on some occasions drivers for SBus devices may need to use hardware configuration files to augment the information provided by the SBus card. See driver.conf(4) and sbus(4) for further details.

VMEbus

The VMEbus supports multiple address spaces. An appropriate entry in the driver.conf(4) file should be made for the address space used by the device (generally, this is not under control of the driver). For DMA devices, the address space that the board uses for its DMA transfers must be known by the driver (this is usually a 32- or 24-bit space).

Address Spaces

Sun-4 architecture machines that use a VMEbus are all based on the full 32-bit VMEbus. Table 2-3 contains a listing of the VMEbus address types supported by the generic VMEbus.
Table 2-3
VMEbus Space NameAddress SizeData Transfer SizePhysical Address Range
vme32d1632 bits16 bits0x0 - 0xFFFFFFFF
vme24d1624 bits16 bits0x0 - 0xFFFFFF
vme16d1616 bits16 bits0x0 - 0xFFFF
Table 2-3
VMEbus Space NameAddress SizeData Transfer SizePhysical Address Range
vme32d3232 bits32 bits0x0 - 0xFFFFFFFF
vme24d3224 bits32 bits0x0 - 0xFFFFFF
vme16d3216 bits32 bits0x0 - 0xFFFF
Not all of these address spaces are commonly used; nevertheless, they are all supported on Sun-4 architecture systems. Table 2-4 indicates their sizes and physical address mappings.
Table 2-4
TypeAddress Space NameAddress Range
0On-board Memory0x0 - 0xFFFFFFFF
1On-board I/O0x0 - 0xFFFFFF
2vme32d160x0 - 0xFEFFFFFF
3vme32d320x0 - 0xFEFFFFFF
2vme24d16--Stolen from top 16M of vme32d160x0 - 0xFEFFFF
2vme16d16--Stolen from top 64K of vme24d160x0 - 0xFFFF
3vme24d32--Stolen from top 16M of vme32d320x0 - 0xFEFFFF
3vme16d32--Stolen from top 64K of vme24d320x0 - 0xFFFF
The type is a field in the page table entry used by the Sun4 MMU to implement the virtual memory subsystem. It indicates the type of memory referenced:
  • Type 0 - main memory
  • Type 1 - on-board I/O
  • Type 2 - VMEbus memory, 16 bit data
  • Type 3 - VMEbus memory, 32 bit data
Other Sun machines, such as the SPARCServer 600 series, have a different format for page table entries.
When a smaller VME space overlays a larger VME space, it steals memory from the larger space and is considered by the MMU to be part of the larger address space. There is no way to physically access VMEbus addresses above 0xFF000000 in 32-bit VMEbus space, or above 0x00FF0000 in 24-bit VMEbus space.
Figure 2-1 illustrates the overlaying of VMEbus address apaces.

图形

Figure 2-1


Caution - There are restrictions on device addressing. The lower ranges of the 32-bit and 24-bit VME space are reserved for DMA. For example, on the Sun-4 architecture, devices must not be present in the low megabyte of VME address
space or the system will not boot. In addition, there may be devices on the bus with addresses that conflict. These can be determined by examining the hardware configuration files.

Hardware Configuration Files

Most VME devices require hardware configuration files to inform the system that the device hardware may be present. The configuration file must specify the device addresses on the VMEbus and any interrupt capabilities that the device has.
Configuration files for VMEbus devices should identify the parent bus driver implicitly using the class key word and specifying class "vme." This removes the dependency on the name of the particular bus driver involved since the driver may be named differently on different platforms. See driver.conf(4) and vme(4) for further details.

x86 Buses

Currently, there are three buses supported on the x86 platform:
  • ISA - Industry Standard Architecture
  • EISA - Extended Industry Standard Architecture
  • MCA - MicroChannel Architecture

ISA Bus

Memory and I/O Space

Two address spaces are provided: memory address space and I/O address space. Depending on the device, registers may appear in one or both of these address spaces.
Table 2-5
ISA Space
Name
Address
Size
Data Transfer
Size
Physical Address
Range
Main Memory24160x0-0xffffff
I/O--8/160x0-0xfff
Registers can be mapped in memory address space and used by the driver as normal memory (see "Memory-mapped Access" on page 44).
Registers in I/O space are accessed through I/O port numbers using separate kernel routines. See "I/O Port Access" on page 45 for more information.

Hardware Configuration Files

ISA bus devices require hardware configuration files to inform the system that the hardware may be present. The configuration file must specify any device I/O port addresses, any interrupt capabilities that the device may have, and any memory-mapped addresses it may occupy.
Configuration files for these devices should normally identify the parent bus driver as "isa". However, since the EISA bus is a super set of the ISA bus, all ISA devices can also be configured to run in the EISA bus slot. In this case, instead of implicitly specifying a particular parent in the configuration file, driver writers can use the class key word and specify the class as "sysbus." This removes the dependency on the name of a particular bus driver. See driver.conf(4) and isa(4) for further details.

EISA Bus

Memory and I/O Space

Two address spaces are provided: memory address space and I/O address space. Depending on the device, registers may appear in one or both of these address spaces.
Table 2-6
EISA Space
Name
Address
Size
Data Transfer
Size
Physical Address
Range
Main Memory32320x0-0xffffffff
I/O--8/16/320x0-0xffff
Registers can be mapped in memory address space and used by the driver as normal memory (see "Memory-mapped Access" on page 44).
Registers in I/O space are accessed through I/O port numbers using separate kernel routines. See "I/O Port Access" on page 45) for more information.

Hardware Configuration Files

EISA bus devices require hardware configuration files to inform the system that the hardware may be present. The configuration file must specify any device I/O port addresses, any interrupt capabilities that the device may have, and any memory-mapped addresses it may occupy.
Configuration files for these devices should normally identify the parent bus driver as "eisa". See driver.conf(4) and eisa(4) for further details.

MCA Bus

Memory and I/O Space

Two address spaces are provided: memory address space and I/O address space. Depending on the device, registers may appear in one or both of these address spaces.
Table 2-7
MCA Space
Name
Address
Size
Data Transfer
Size
Physical Address
Range
Main Memory32320x0-0xffffffff
I/O--8/16/320x0-0xfff
Registers can be mapped in memory address space and used by the driver as normal memory (see "Memory-mapped Access" on page 44).
Registers in I/O space are accessed through I/O port numbers using separate kernel routines. See "I/O Port Access" on page 45) for more information.

Hardware Configuration Files

MCA bus devices require hardware configuration files to inform the system that the hardware may be present. The configuration file must specify any device I/O port addresses, any interrupt capabilities that the device may have, and any memory-mapped addresses it may occupy.
Configuration files for these devices should normally identify the parent bus driver as "mca". See driver.conf(4) and mca(4) for further details.

Device Issues

Timing-Critical Sections

While most driver operations can be performed without synchronization and protection mechanisms beyond those provided by the locking primitives described in "Locking Primitives" on page 74, some devices require that a sequence of events happen in order without interruption. In conjunction with
the locking primitives, the function ddi_enter_critical(9F) asks the system to guarantee, to the best of its ability, that the current thread will neither be preempted nor interrupted. This stays in effect until a closing call to ddi_exit_critical(9F) is made. See ddi_enter_critical(9F) for details.

Delays

Many chips specify that they can be accessed only at specified intervals. For example, the Zilog Z8530 SCC has a "write recovery time" of 1.6 microseconds. This means that a delay must be enforced with drv_usecwait(9F) when writing characters with an 8530. In some instances, it is unclear what delays are needed; in such cases, they must be determined empirically.

Internal Sequencing Logic

Devices with internal sequencing logic map multiple internal registers to the same external address. There are various kinds of internal sequencing logic:
  • The Intel 8251A and the Signetics 2651 alternate the same external register between two internal mode registers. Writing to the first internal register is accomplished by writing to the external register. This write, however, has the side effect of setting up the sequencing logic in the chip so that the next read/write operation refers to the second internal register.
  • The NEC PD7201 PCC has multiple internal data registers. To write a byte into a particular register, two steps must be performed. The first step is to write into register zero the number of the register into which the following byte of data will go. The data is then written to the specified data register. The sequencing logic automatically sets up the chip so that the next byte sent will go into data register zero.
  • The AMD 9513 timer has a data pointer register that points at the data register into which a data byte will go. When sending a byte to the data register, the pointer is incremented. The current value of the pointer register cannot be read.

Interrupt Issues

The following are some common interrupt-related issues:
  • A controller interrupt does not necessarily indicate that both the controller and one of its slave devices are ready. For some controllers, an interrupt may indicate that either the controller is ready or one of its devices is ready, but not both.
  • Not all devices power up with interrupts disabled and then start interrupting only when told to do so.
  • Some devices do not provide a way to determine that the board has generated an interrupt.
  • Not all interrupting boards shut off interrupts when told to do so or after a bus reset.

Byte Ordering

Peripheral devices can contain chips that use a byte-ordering convention different from that used by the system on which they are installed. The Intel 82586, for example, supports little-endian byte-ordering conventions, making it compatible with Multibus-based, but not VMEbus-based, machines. Drivers for such peripheral devices must swap bytes without inadvertently reordering the bits in any control fields greater than 16 bits in length. See swab(9F) for more information.

The PROM on SPARC Machines

Some platforms have a PROM monitor that provides support for debugging a device without an operating system. This section describes how to use the PROM on SPARC machines to map device registers so that they can be accessed. Usually, the device can be exercised enough with PROM commands to determine if the device is working correctly.
Two separate boot PROMs are briefly discussed here: the Open Boot PROM version 2 (OBP), used on machines with an SBus, and the PROM Monitor (SunMon) available on Sun-4 machines.
The PROM has several purposes; it serves to:
  • Bring the machine up from power on, or from a hard reset (OBP reset command, or SunMon k2 command).
  • Provide an interactive tool for examining and setting memory, device registers, and memory mappings.
  • Boot SunOS or the kernel debugger kadb(1M).
Simply powering up the computer and attempting to use its PROM to examine device registers will likely fail. While the device may be correctly installed, those mappings are SunOS specific and do not become active until SunOS is booted. Upon power up, the PROM maps essential system devices, such as the keyboard.
Examples in this section use a bwtwo (monochrome) frame buffer on a SPARCstation IPC. Using PROM commands to modify video memory on this frame buffer provides a visual indication that something is happening when PROM commands are executed.

Open Boot PROM 2.x

For complete documentation on the Open Boot PROM, see the Open Boot PROM Toolkit User's Guide and monitor(1M). The examples in this section refer to a Sun-4c; other architectures may require new commands to map memory, among other things.
The Open Boot PROM is currently used on Sun machines with an SBus. It is more powerful than the older SunMon ("The Sun Monitor" on page 34). The Open Boot PROM uses an "ok" prompt rather than the ">" prompt used by SunMon. However, many Open Boot PROM machines present the old-style interface by default. The 'n' command switches an OBP from the old mode to the new mode.

  Type b (boot), c (continue), or n (new command mode)  
  >n  
  Type help for more information  
  ok  


Note - If the PROM is in secure mode (the security-mode parameter is not set to none) the PROM password may be required (set in the security-password parameter).

To make the machine come up in new mode by default, set the environment variable sunmon-compat? to false.

  ok setenv sunmon-compat? false  
  sunmon-compat? =      false  

The printenv command displays all parameters and their values.

Help

Help is available with the help command.

History

EMACS-style command-line history is available. Use Control-N (next) and Control-P (previous) to walk the history list.

Forth Commands

The Open Boot PROM uses the Forth programming language. This is a stack-based language; arguments must be pushed on the stack before running the desired command (called a word), and the result is left on the stack.
To place a number on the stack, type its value.

  ok 57  
  ok 68  

To add the two top values on the stack, use the + operator.

  ok +  

The result is left on the stack. The stack is shown with the .s word.

  ok .s  
  bf  

The default base is hexadecimal. The hex and decimal words can be used to switch bases.

  ok decimal  
  ok .s  
  191  

See the Forth User's Guide for more information.

Walking the PROMs Device Tree

The SunOS-like commands pwd, cd, and ls walk the PROM device tree to get to the device. The cd command must be used to establish a position in the tree before pwd will work. This example is from a SPARCstation IPC.

  ok cd /  

To see the devices attached to the current node in the tree, use ls.

  ok ls  
  ffec8760 options  
  ffec5ce0 fd@1,f7200000  
  ffebab64 virtual-memory@0,0  
  ffeba958 memory@0,0  
  ffeb9084 sbus@1,f8000000  
  ffeb9020 auxiliary-io@1,f7400003  
  ffeb8fb8 interrupt-enable@1,f5000000  
  ffeb8f54 memory-error@1,f4000000  
  ffeb8ed0 counter-timer@1,f3000000  
  ffeb8e5c eeprom@1,f2000000  
  ffeb8de8 audio@1,f7201000  
  ffeb8cf8 zs@1,f0000000  
  ffeb8c54 zs@1,f1000000  
  ffeb8c04 openprom  
  ffeb7b5c packages  

The full node name can be used:

  ok cd sbus@1,f8000000  
  ok ls  
  ffecd450 bwtwo@3,0  
  ffecc2f0 le@0,c00000  
  ffec9b38 esp@0,800000  
  ffec9af4 dma@0,400000  

Rather than using the full node name in the previous example, you could have used an abbreviation. The abbreviated command line entry looks like this:

  ok cd sbus  

The name is actually device@slot,offset (for SBus devices). The bwtwo device is in slot 3 and starts at offset 0. If an SBus device shows up in this tree, the device has been recognized by the PROM.
The .attributes command displays the PROM properties of a device. These can be examined to determine what properties the device exports (this is useful later to ensure that the driver is looking for the correct hardware properties). These are the same properties that can be retrieved with ddi_getprop(9F). See sbus(4) and "Properties" on page 57 for related information.

  ok cd bwtwo  
  ok .attributes  
  monitor-sense            00 00 00 03  
  intr                     00 00 00 07 00 00 00 00  
  reg                      00 00 00 03 00 00 00 00 01 00 00 00  
  device_type              display  
  model                    SUNW,501-1561  
  ...  

The reg property defines an array of register description structures, containing the following fields:
u_int   bustype;               /* cookie for related bus type*/
u_int   addr;                  /* address of reg relative to bus */
u_int   size;                  /* size of this register set */

For the bwtwo example, the address is 0.

Mapping the Device

To test the device, it must be mapped into memory. The PROM can then be used to verify proper operation of the device by using data-transfer commands to transfer bytes, words, and long words. If the device can be operated from the PROM, even in a limited way, the driver should also be able to operate the device.
To set up the device for initial testing perform the following three steps:
  1. Determine the physical address of the SBus slot the device is in. Table 2-8 displays the physical addresses of various SBus slots on a SPARCstation 1 and SPARCstation 1+:

Table 2-8
SBus Slot NumberPhysical Address Space
SBus slot #00 (internal slot)
SBus slot #10x2000000
SBus slot #20x4000000
SBus slot #30x6000000
In this example, the bwtwo device is located in slot 3. Consequently, the physical address space for the device is 0x6000000.
  1. Determine the offset within the physical address space used by the device.

    The offset used is specific to the device. In the bwtwo example, the video memory happens to start at offset 0x800000 within the bwtwo space. As a result, the actual offset to be mapped is 0x6800000.

  2. Use the map-sbus word to map the device in.

    The map-sbus word takes an offset and a size as arguments to map. Like the offset, the size of the byte transfer is specific to the device. In the bwtwo example, the size is set to 20000 bytes.

In the code example below, the offset and size values for the frame buffer are displayed as arguments to the map-sbus word. Notice that the virtual address to use is left on top of the stack. The stack is then shown using the .s word. It can be assigned a name with the constant operation.

  ok 6800000 20000 map-sbus  
  ok .s  
  ffe7f000  
  ok constant fb  

Reading and Writing

The PROM provides a variety of 8-bit, 16-bit, and 32-bit operations. In general, a c (character) prefix indicates an 8-bit (one byte) operation; a w (word) prefix indicates a 16-bit (two byte) operation; and an L (longword) prefix indicates a 32-bit (four byte) operation.
A suffix of ! is used to indicate a write operation. The write operation takes the first two items off the stack; the first item is the address, and the second item is the value.

  ok 55 ffe8000 c!  

A suffix of @ is used to indicate a read operation. The read operation takes one argument (the address) the off the stack. .

  ok ffe80000 c@  
  ok .s  
  77  

A suffix of ? is used to display the value, without affecting the stack.

  ok ffe80000 c?  
  77  

Be careful when trying to query the device. If the mappings are not set up correctly, trying to read or write could cause errors. There are special words provided to handle these cases. cprobe, wprobe, and lprobe, for example, read from the given address but return zero if the location does not respond, or nonzero if it does.

  ok ffee0000 c@  
  Data Access Exception  
  ok ffee0000 cprobe  
  ok .s  
  0  
  ok ffe80000 cprobe  
  ok .s  
  0 ffffffff  

A region of memory can be shown with the dump word. This takes an address and a length, and displays the contents of the memory region in bytes.
In the following example the fill word is used to fill video memory with a pattern. fill takes the address, the number of bytes to fill, and the byte to use (there is also a wfill and an Lfill for words and longwords). This causes the bwtwo to display simple patterns based on the byte passed.

  ok 6800000 20000 map-sbus  
  ok constant fb  
  ok fb 20000 ff fill  
  ok fb 20000 0 fill  
  ok fb 18000 55 fill  
  ok fb 15000 3 fill  
  ok fb 10000 5 fill  
  ok fb 5000 f9 fill  

Interrupts

Certain machine-specific interrupt levels are ignored when the Open Boot PROM controls the machine.

The Sun Monitor

Normally, the Sun Monitor is used on Sun-4 architectures with a VMEbus. For complete documentation on SunMon, see the PROM User's Guide.

Mapping the Device

To test the device, it must be mapped into memory. The PROM can then be used to verify proper operation by using data-transfer commands to transfer bytes, words, and long words. If the device can be made to operate from the PROM, even in a limited way, the driver should also be able to operate the device.
To set up the device for initial testing:
  1. Select an appropriate virtual address for the testing of the device.

  2. Determine the physical address of the device, as well as the address space that it occupies.

  3. Use the monitor to map the system's virtual address to the device's physical address.

Selecting a Virtual Address When mapping a virtual address to a physical address, the MMU is actually mapping to a page of physical memory and an offset within that page. The low-order bits of a virtual address, those that specify the offset, are not mapped. See Figure 2-2 on page 35.
The mapping mechanism is essentially the same for all systems, though the details of the address size and page mapping differ.

图形

Figure 2-2

The easiest way to select a virtual address for testing is to use one between 0x4000 and 0x100000. Addresses in this range are unused by the PROM in Sun- 4 architecture machines and are available. Be aware that these addresses, while convenient for testing, are not those that the kernel chooses when the driver is finally installed.
It is most convenient to select a virtual address that has only zeros in its low-order bits. This way, the first address in a virtual page is selected. The low-order bits in the chosen address remain unchanged. With 'X' representing the unmapped low-order bits (13 on an 8K page Sun-4) the test address 0x4000 is, in binary:
0000 0000 0000 0000 010X XXXX XXXX XXXX

Finding a Physical Address The device may be preconfigured to some address. If it is, then that address should be used unless it conflicts with the address of an already installed device. If it conflicts, an unused physical address must be found. To do so, examine the hardware configuration files in /kernel/drv and /usr/kernel/drv on the test system. See driver.conf(4) for more information on hardware configuration files and vme(4) for specific information on configuration files for VMEbus devices.
Creating a Page Table Entry The link between the virtual and physical address is the MMU. The MMU contains a page table to keep track of which virtual pages map to which physical pages. Entries in this table are called page table entries (PTE). To create a mapping, a page table entry must be constructed. On a Sun-4, PTEs are 32-bit numbers with the following structure:

Imported image(484x80)


Note - This discussion is for informational and debugging use only. Device drivers must not manipulate page table entries.

The following is a "template" bit mask that can be used to construct standard PTEs. An acceptable mask assumes values as follows:
V (valid) = 1 w/s (write ok/supervisor only) = 11 c (don't cache) = 1
(a/m) accessed/modified = 00 unused = 00000
A one in the don't cache position only disables caching if the type is zero, since other types of pages are never cached. Substituting the above values, the template looks like this:

Imported image(401x82)

This results in a mask of 0xF0000000 (assuming that the type field is 00). Thus, the four masks for the four types of memory are:
Table 2-9
TypeDescriptionMask
0On Board Memory0xF0000000
1On Board I/O Space0xF4000000
2vme16d160xF8000000
2vme24d160xF8000000
2vme32d160xF8000000
3vme16d320xFC000000
3vme24d320xFC000000
3vme32d320xFC000000
To determine the value to be plugged into the PTE, the appropriate mask is added to the physical page number, resulting in the full 32-bit PTE. Following are some rules for generating PTEs with the correct template, based on the address space the device is in and assuming an 8K page size:
If the device is in vme16d16, vme24d16, or vme32d16 Use Type-2 Template
If the device is in vme16d32, vme24d32, or vme32d16 Use Type-3 Template
If the device is in vme32d16 or vme32d32 Physical Page Number = Physical Address >> 13
If the device is in vme24d16 or vme24d32 Physical Page Number = (Physical Address + 0xFF000000) >> 13
If the device is in vme16d16 or vme16d32 Physical Page Number = (Physical Address + 0xFFFF0000) >> 13
Example One A device is attached at physical address 0x280008 in bus type vme24d16, which will be mapped into virtual memory at address 0xE000000. What is the corresponding PTE?
Answer: 0xF807F940
Explanation: Because the device is being mapped into vme24d16, 0xF8000000 is used as the template. Adding the physical address to 0xFF000000 yields 0xFF280008. In binary, this is:
    1111 1111 0010 1000 0000 0000 0000 1000

Shifting this right by 13 yields:
    XXXX XXXX XXXX X111 1111 1001 0100 0000

Adding the 0xF8000000 template results in values for the 13 bits that are undefined from the shift. The PTE is:
1111 1000 0000 0111 1111 1001 0100 0000

In hexadecimal, this is 0xF807F940.
The resulting PTE maps the virtual page beginning at 0xE000000 to the physical page containing 0x280008. To get the virtual address to access the device, it is necessary to take the lower 13 bits of the physical installation address--the bits that are just passed through the MMU-- and add them to virtual address 0xE000000. The lower 13 bits of physical address 0x280008 are 0008; adding them to 0xE000000 yields 0xE000008, the virtual address by which the device can be accessed.
Example Two A device at physical address 0xEE48 on bus type vme16d32 will be mapped to virtual address 0xE000000. What is the PTE?
Answer: 0xFC07FFFF
Explanation: Because the device is being mapped into vme16d32, 0xFC000000 is used as the template. Adding the physical address to 0xFFFF0000 yields 0xFFFFEE48. In binary, this is:
    1111 1111 1111 1111 1110 1110 0100 1000

Shifting this right by 13 yields:
    XXXX XXXX XXXX X111 1111 1111 1111 1111

Adding the 0xFC000000 template results in values for the 13 bits that are undefined from the shift. The PTE is:
1111 1100 0000 0111 1111 1111 1111 1111

This is 0xFC07FFFF in hexadecimal.
To get the virtual address to access the device at physical address 0xEE48, add its lower 13 bits, 0xE48, to 0xE000000. This yields 0xE000E48.
Sun 4/110 Considerations The Sun-4/110 MMU does not store bits 28-31. For the VMEbus, which uses 32 bits of physical addressing, bits 28-31 are generated by sign-extending bit 27. When the PTE is read back, these upper bits are always set to zero. This essentially creates a hole in the address space that is not addressable.
When entering page table entries on a Sun-4/110 to test hardware from the PROM, use a virtual address less than 0x800000. Virtual addresses at or above 0x800000 are not set up by the PROM for use.
When mapping the device to vme16, vme24, or the top half of the vme32 address space, after entering the PTE the top five bits of the physical page number are zero because the Sun-4/110 physical address space is split with 128 megabytes at the bottom and 128 megabytes at the top. Whenever the physical address goes above 128 megabytes, the high bit is sign extended so that the address lies within the top 128 megabytes. Sign extending the high bit into the next five bits should result in the previously calculated physical page number.
In this example, instead of using 0xE000000 as the starting address, the value 0xE0000 could be used successfully.

Mapping Commands

  1. Issue the PROM command that puts the CPU into supervisor data state:

    > s B

  2. Calculate the PTE appropriate to the chosen physical address.

  3. Map the virtual address to the device. The PROM p command will do this, given a virtual address:

    > p F32000

This command takes the virtual address 0xF32000 as its argument and displays the PTE for it. It also displays a ?, which indicates that a new value may be typed in to replace the one displayed. Note that all virtual addresses within a page select the same PTE. Type any non-hexadecimal character to stop.
  1. Repeat step 3 for each page to map.

Reading and Writing

The format of the data transfer commands are
command [address] [value]
Valid commands are:
o open a byte e open a word (4 bytes) l open a longword (4 bytes)
When using the o, e, or l commands to open a location, the monitor reads the present contents of that location and displays it before giving the option to rewrite it. To do the write without the read (because the device does something else when the read occurs), pass a value after the address argument; this is known as a blind write.