Hardware Overview
This appendix discusses general issues about hardware capable of supporting the Solaris 9 operating environment. This includes issues related to the processor, bus architectures, and memory models supported by the Solaris 9 operating environment, various device issues, and the PROM used in Sun platforms.
Note - The information presented here is for informational purposes only and might be of help during driver debugging. However, the DDI/DKI interfaces hide many of these implementation details from device drivers.
This appendix provides information on the following subjects:
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. For information on IA processor-specific topics, see "IA Processor Issues".
Caution - Drivers should never perform floating-point operations, as they are not supported in the kernel.
SPARC Data Alignment
All quantities must be aligned on their natural boundaries. Using standard C data types:
short integers are aligned on 16-bit boundaries.
int integers are aligned on 32-bit boundaries.
long integers are aligned on either 32-bit boundaries or 64-bit boundaries, depending on whether the data model of the kernel is 64-bit or 32-bit. For information on data models, see Appendix C, Making a Device Driver 64-Bit Ready .
long long integers are aligned on 64-bit boundaries.
Usually, the compiler handles alignment issues. However, driver writers are more likely to be concerned about alignment as they must use the proper data types to access their device. Because device registers are commonly accessed through a pointer reference, drivers must ensure that pointers are properly aligned when accessing the device.
SPARC 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.
SPARC Byte Ordering
The SPARC processor uses big-endian byte ordering; in other words, the most significant byte (MSB) of an integer is stored at the lowest address of the integer.
SPARC Register Windows
SPARC processors use register windows. Each register window consists 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 compiler usually hides the fact that register windows are used. However, you might have to use them when debugging the driver.
SPARC 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. Because a driver cannot determine whether it is running on a Version 7, Version 8, or Version 9 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.
The SPARC Architecture Manual, Version 9, contains more specific information on the SPARC CPU. The SPARC Compliance Definition, Version 2.4, contains details of the SPARC V9 application binary interface (ABI). It describes the 32-bit SPARC V8 ABI and the 64-bit SPARC V9 ABI. You can obtain this document from SPARC International at http://www.sparc.com.
IA Processor Issues
There are no alignment restrictions on data types. However, extra memory cycles might be required for the IA processor to properly handle misaligned data transfers.
Caution - Drivers should not perform floating-point operations, as they are not supported in the kernel.
IA Byte Ordering
The IA processor uses little-endian byte ordering. The least significant byte (LSB) of an integer is stored at the lowest address of the integer.
IA Architecture Manuals
Intel Corporation publishes a number of books on the IA family of processors. See http://www.intel.com.
Endianness
To achieve the goal of multiple-platform, multiple-instruction-set architecture portability, host bus dependencies were removed from the drivers. The first dependency issue to be addressed was the endianness (or byte ordering) of the processor. For example, the IA processor family is little-endian while the SPARC architecture is big-endian.
Bus architectures display the same endianness types as processors. The PCI local bus, for example, is little-endian, the SBus is big-endian, the ISA bus is little-endian, and so on.
To maintain portability between processors and buses, DDI-compliant drivers must be endian neutral. Although drivers could conceivably manage their endianness by runtime checks or by preprocessor directives like #ifdef _LITTLE_ENDIAN or _BIG_ENDIAN statements in the source code, long-term maintenance would be troublesome. In some cases, the DDI framework performs the byte swapping using a software approach. In other cases, where byte swapping can be done by hardware (as in memory management unit (MMU) page-level swapping or by special machine instructions), the DDI framework will take advantage of the hardware features to improve performance.
Figure A-1 Byte Ordering Host Bus Dependency
Along with being endian-neutral, portable drivers must also be independent from data ordering of the processor. Under most circumstances, data must be transferred in the sequence instructed by the driver. However, sometimes data can be merged, batched, or reordered to streamline the data transfer, as illustrated in Figure A-2. For example, data merging can be applied to accelerate graphics display on frame buffers. Drivers have the option to advise the DDI framework to use other optimal data transfer mechanisms during the transfer.
Figure A-2 Data Ordering Host Bus Dependency
Store Buffers
To improve performance, the CPU uses internal store buffers to temporarily store data. This can affect the synchronization of device I/O operations. Therefore, the driver needs to take explicit steps to make sure that writes to registers are completed at the proper time.
For example, when access to device space (such as registers or a frame buffer) is synchronized by a lock, the driver needs to check that the store to the device space has actually completed before releasing the lock. Releasing the lock does not guarantee the flushing of I/O buffers.
To give another 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.
System Memory Model
The system 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: total store ordering (TSO) and partial store ordering (PSO).