Sun Java Solaris Communities My SDN Account Join SDN
 
Documentation

Device Properties

PCI devices are identified by a set of up to 64, 32-bit "configuration registers." The purpose of these registers is to provide a standard set of information in a known place. The driver can retrieve the value of the configuration registers either through mapping to device address space (see "Device Address Mapping") or through properties associated with the device.

IEEE 1275 uses properties to describe characteristics of a hardware device or its associated devices. Examples of properties for the PCI bus node and its child PCI SCSI device node are shown below. The section "Child Node Properties" gives a detailed explanation of some of the PCI child node properties and their implication to driver development.

ok dev /pci@1f,4000

ok .properties

bus-range 00000080

00000080

no-probe-list 0

scsi-initiator-id 00000007

clock-frequency 03ef1480

version# 00 00 00 01

implementation# 00 00 00 00

address fffd8000

fffd2000

fffc4000

slot-name 00 00 00 06 36 34 2d 62 69 74 20 66 61 73 74 20

upa-portid 0000001f

66mhz-capable

interrupts 000007f0

000007ee

000007ef

000007e5

000007e8

000007f2

ranges 00800000 00000000 00000000 000001fe 01800000 00000000 00000800

00800800 00000000 00000000 000001fe 01800800 00000000 00000800

00801000 00000000 00000000 000001fe 01801000 00000000 00000800

01000000 00000000 00000000 000001fe 02000000 00000000 00010000

02000000 00000000 00000000 000001ff 00000000 00000000 80000000

reg 000001fe 00002000 00000000 00002000

000001fe 01800000 00000000 00000100

000001fe 00000000 00000000 0000d000

compatible pci108e,8000

thermal-interrupt

bus-parity-generated

#size-cells 00000002

#address-cells 00 00 00 03

device-type pci

name pci
 


ok dev /pci@1f,4000/scsi@3

ok .prp

interrupts 000007e0

assigned-addresses 81001810 00000000 00000400 00000000 00000100

82001814 00000000 00018000 00000000 00000100

82001818 00000000 00019000 00000000 00001000

device-type scsi-2

clock-frequency 02625a00

reg 00001800 00000000 00000000 00000000 00000000

01001810 00000000 00000000 00000000 00000100

02001814 00000000 00000000 00000000 00000100

02001818 00000000 00000000 00000000 00001000

model Symbios,53C875

compatible glm

name scsi

66mhz-capable 00000000

udf-supported 00000000

fast-back-to-back 00000000

devsel-speed 00000001

class-code 00010000

max-latency 00000040

min-grant 00000008

revision-id 00000001

device-id 0000000f

vendor-id 00001000
 

IEEE 1275 PCI Bus Binding1 is a complement to IEEE 1275 for PCI devices and defines a set of properties for the fields in the configuration registers. During boot, the bus node of PCI devices reads the configuration registers of the device and constructs properties for the device. In addition to these IEEE 1275 specifications, the IEEE 1275 working group recommends a practice for naming the device. Solaris 2.5 supports the recommended practice in device driver binding and device driver loading.

IEEE 1275

IEEE 1275 defines an architecture for the firmware that controls a computer before the operating system has begun execution. OpenBoot is Sun's implementation of IEEE 1275. OpenBoot mainly tests machine hardware, constructs a device tree for the system, and boots the operating system.

IEEE 1275 specifies a data structure known as the device tree to describe the set of devices attached to the system. The device tree is a hierarchical data structure that describes the system hardware and its associated configuration information and support routines. The device tree is also the main interface between OpenBoot and the operating system. Devices are attached to a system on a set of interconnected buses. OpenBoot represents the interconnected buses and their attached devices as a tree of nodes. The root of the device tree is a representation of the machine's main physical bus. An example of the Sun4u PROM device tree is shown here.

ok show-devs

/SUNW,ffb@1e,0

/SUNW,UltraSPARC@0,0

/pci@1f,2000

/pci@1f,4000

/counter-timer@1f,1c00

/virtual-memory

/memory@0,0

/aliases

/options

/openprom

/chosen

/packages

/pci@1f,4000/scsi@3

/pci@1f,4000/network@1,1

/pci@1f,4000/ebus@1

/pci@1f,4000/scsi@3/tape

/pci@1f,4000/scsi@3/disk

/pci@1f,4000/ebus@1/flashprom@10,0

/pci@1f,4000/ebus@1/eeprom@14,0

/pci@1f,4000/ebus@1/SUNW,CS4231@14,200000

/pci@1f,4000/ebus@1/fdthree@14,3023f0

/pci@1f,4000/ebus@1/ecpp@14,3043bc

/pci@1f,4000/ebus@1/su@14,3062f8

/pci@1f,4000/ebus@1/su@14,3083f8

/pci@1f,4000/ebus@1/se@14,400000

/pci@1f,4000/ebus@1/sc@14,500000

/pci@1f,4000/ebus@1/SUNW,pll@14,504000

/pci@1f,4000/ebus@1/power@14,724000

/pci@1f,4000/ebus@1/auxio@14,726000

/openprom/client-services

/packages/ufs-file-system

/packages/disk-label

/packages/obp-tftp

/packages/deblocker

/packages/terminal-emulator
 

Each device node may have properties, methods, and data. Properties describe characteristics of hardware devices, software, and user choices. Properties are externally visible to both OpenBoot procedures and client programs (for example, the Solaris operating system) for determining the characteristics of hardware devices. Methods are named software procedures that control hardware devices or provide other services. Data is used by named software procedures (methods) to maintain internal information. Unlike properties, which can be accessed by external software, data cannot be directly accessed from outside the device node package.

A PCI device used for booting or message display is required to have its own plug-in driver, usually located in a ROM on the device itself. Plug-in drivers are written in a byte-coded machine-independent interpreted language called FCode. FCode is based on Forth semantics. Writing FCode programs is described in Writing FCode Programs for PCI, Firmworks, Rev. H, October 1995.

IEEE 1275 PCI Binding

PCI Bus Binding to IEEE Std 1275: 1994 Standard for Boot Firmware, Rev. 1.7 augments the standard Boot Firmware to specify the application of Open Firmware to PCI Local Bus Specification, Rev. 2.1, June 1, 1995; in particular, it defines a set of properties specifically for PCI devices and specifies the address formats and representations for these properties.

Address Formats and Representations

The numerical representation of the PCI address and the size for PCI devices, as defined in PCI Bus Binding to IEEE Std 1275: 1994 Standard for Boot Firmware, Rev. 1.7, consists of three cells and two cells, respectively. Applying the address formats to the "reg" property allows device drivers to retrieve device information such as:

  • Type of address space (I/O, memory, configuration)
  • Bus number
  • Device number (slot number)
  • Function number
  • Register number

Bit# 33222222 22221111 11111100 00000000

The address format:

phys-hi cell npt000ss bbbbbbbb dddddfff rrrrrrrr
phys-mid cell hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
phys-lo cell llllllll llllllll llllllll llllllll
 

The size format:

size-hi cell hhhhhhhh hhhhhhhh hhhhhhhh hhhhhhhh
size-lo cell llllllll llllllll llllllll llllllll
 

where:

n is 0 if the address is relocatable
p is 1 if the addressable region is "prefetchable"
t is 1 if the address region is aliased
ss is the type code, denoting the address space:



00 - configuration space n, p, t must be 0

01 - I/O space p must be 0

10 - 32-bit address memory space

11 - 64-bit address memory space
bbbbbbbb is the 8-bit bus number
ddddd is the 5-bit device number
fff is the 3-bit function number
rrrrrrrr is the 8-bit register number
hhhhhhhh is the 32-bit unsigned number
llllllll is the 32-bit unsigned number
 

For example, the "reg" property shown in the example of the PCI SCSI device node properties has four phys-addr, size pairs, as shown here.

reg 00001800 00000000 00000000 00000000 00000000 <--register 0

01001810 00000000 00000000 00000000 00000100 <--register 1

02001814 00000000 00000000 00000000 00000100 <--register 2

02001818 00000000 00000000 00000000 00001000 <--register 3
 

In the preceding example, register 0 is in configuration space. Register 1 is in I/O space and has size 0x100. Registers 2 and 3 are in memory space and have size 0x100 and 0x1000, respectively. This device is in slot number 2 of bus number 0 and has only one function, function number 0. The n bits in phys-hi for registers 1, 2, and 3 are 0, which indicates that the address of each of these registers is relative to the base register address. To get the absolute address of each of these registers, drivers have to use the "assigned-addresses" property. The p and t bits are 0, which indicate that these address spaces are not "prefetchable" and are not aliased.

Child Node Properties

  • "name" - This property defines the device's name. In accordance with the Generic Names Recommended Practice2, it should represent the general nature of the device (for more information about the "name" property, see the IEEE 1275 PCI Binding document). For devices with FCode, the name is defined by the FCode program. For devices without FCode, this property is derived from the PCI "class-code". See Table 1 in PCI Bus Binding to IEEE Std 1275: 1994 Standard for Boot Firmware, Rev. 1.7 for the generic name based on the PCI "class-code." If none apply, the bus node should generate a name of the form pcivvvv,dddd as described below under "compatible."
  • "compatible" - This property defines devices with which the device is compatible and has the form pcivvvv,dddd. If the SubsystemID field in the configuration registers for this device is nonzero, vvvv,dddd should be the SubsystemVendorID and SubsystemID, respectively; otherwise vvvv,dddd should be the value of the VendorID and DeviceID fields.
  • "reg" - This property is used by the device to export its memory to the operating system for mapping. For devices without FCode, this property is generated by the bus node by reading the base address registers in the configuration space. For devices with FCode, this property is generated by the FCode of the device. This property is mandatory for PCI child nodes. The property value consists of a sequence of phys-addr, size pairs. In the first such pair, the phys-addr component is the configuration space address of the beginning of the function's set of configuration registers, and the size component is 0. Note that there is no particular relationship between PCI base registers and the "reg" property. A particular base register may or may not be represented in the "reg" property, and the "reg" property may contain entries referring to addresses not controlled by any base register. If the n bit is 0, the address is relative to the value of the associated base register, and device drivers should read the "assign-addresses" property to get the absolute address.
  • "assigned-addresses" - Each entry in this property corresponds to either one or two (in the case of 64-bit address memory space) of the function's configuration space base address registers. The n bit is 1, indicating that the address is absolute (within the PCI domain address space).
  • "interrupts" - The value of this property represents the interrupt line to which this function's interrupt is connected: INTA=1, INTB=2, INTC=3, INTD=4. This property is present if the Configuration Interrupt Pin Register is nonzero, and is absent otherwise.
  • "fcode-rom-offset" - This property indicates the offset of the PCI Expansion ROM image within the device's Expansion ROM in which the FCode image was found. This value is generated before the FCode is evaluated.

The following properties represent the values of standard PCI configuration registers. They are created during the probing process after the device node has been created by OpenBoot, but before evaluating the device's FCode (if any). The property is absent if the value of the property is 0.

  • "vendor-id"
  • "device-id"
  • "revision-id"
  • "class-code"
  • "min-grant"
  • "max-latency"
  • "devsel-speed"
  • "cache-line-size"
  • "fast-back-to-back"
  • "subsystem-id"
  • "subsystem-vendor-id"
  • "66mhz-capable"
  • "udf-supported"

Generic Device Name

The Open Firmware working group recommends using the generic value for the "name" property and using an explicit, unique name for the "compatible" property3 to achieve these objectives:

  • Providing a human-readable identifier for use in constructing device paths
  • Providing a unique identification of the device's detailed programming model to enable operating systems to determine which driver to use

The "name" property reflects the device's function. The "compatible" property infers the detailed programming model from that name. Beginning with the 2.5.1 release, Solaris software supports the generic name practice as recommended by the IEEE 1275 working group.

In following the recommendation, a SCSI controller has "name" and "compatible" properties such as:

  • "name" scsi
  • "compatible" glm

and a network device has properties such as:

  • "name" network
  • "compatible" SUNW,hme

The system uses this naming convention to derive the name of the device driver to attach.

Device Driver Configuration

During boot, the system constructs a kernel-resident device information tree (dev_info tree). This is a hierarchical list of the devices available to the system. Each node in the dev_info tree (dev_info node) contains device-specific information, and includes properties retrieved from a self-identifying device's FCode PROM or a non-self-identifying device's hardware configuration file. The structure of the dev_info tree (see /usr/include/sys/dev_info.h) follows the hierarchy of the physical devices; nexus drivers such as glm (Sun's on-board SCSI controller) have pointers to their children (for example, disk drives), and are pointed to by their parent (the on-board PCI nexus driver, pci).

In the dev_info data structure, the devi_binding_name field is used to store the binding driver name. If the "compatible" property of the device exists, the system uses the first element of the "compatible" property for devi_binding_name. Otherwise, the system uses the "name" property of the device for devi_binding_name.

When the system boots, in addition to the dev_info tree, it builds a table of driver name vs. major number based on the entries in /etc/name_to_major and /etc/driver_aliases. When a driver module is loaded, the system binds the driver module with the dev_info node when devi_binding_name matches the name of the driver module.

The Solaris kernel is self-configuring. The only drivers present immediately after normal booting are those that were required to boot (for example, the disk driver, the frame buffer driver, and the terminal driver for the keyboard). Other drivers are loaded when the device is accessed by an open(2) call on its special file entries in the /dev or /devices directories. (See "/devices and /dev".)

You can use add_drv(1M) to add a new driver to the system. add_drv(1M) determines the devices that are managed by the driver being added by examining the contents of the "name" property and the "compatible" property (if it exists) on each device. If the value in the "name" property does not match the driver being added, each entry in the "compatible" property is tried, in order, until either a match occurs or there are no more entries in the "compatible" property. add_drv(1M) updates system files (/etc/name_to_major and /etc/driver_aliases) for the newly added driver. A reconfiguration boot is required if the driver is for a device already being managed by a different driver and the driver being added appears before the current driver in the device's compatible list.

The -i option of add_drv(1M) allows driver developers to specify a different name for the driver. Use this option when the device name (in its FCode PROM or hardware configuration file) is not the same as the driver module name. add_drv(1M) looks for a device with the same name as the driver module. If the names are different, add_drv(1M) fails. For add_drv(1M) to work in this case, you must use the device's PROM name as an alias (-i PROMname). For example, Sun's on-board network device is called SUNW,hme in its FCode PROM (the "compatible" property), but the driver is called hme. To install this driver in the system, you run add_drv(1M) like this:

add_drv -m "* 0666 root root" -i "SUNW,hme" hme
 

/devices and /dev

The /devices directory contains hardware device nodes for the system. Devices are normally accessed through the logical entries in the /dev directory; however, instead of being special files, the entries in the /dev directory are now symbolic links to the special files in /devices.

The entries in /devices are created by the drvconfig(lM) utility during a reconfiguration boot or when add_drv(lM) is run. drvconfig(1M) traverses the system's dev_info tree and creates an entry for each device found. The structure of /devices mirrors the dev_info tree; that is, nexus drivers are directories and leaf drivers are special files appearing in their parent's directory. The format of all entries in /devices is name@address, where name is the device's name in its dev_info node, and address is its address on its parent. For example, the full name of a SCSI disk might be:

/devices/pci@1f,4000/scsi@3/sd@0,0:a
 

The disk driver, sd, is at SCSI target 0, LUN 0 on SCSI, the host adapter driver. The SCSI hardware is in PCI slot 3. The PCI bus is at UPA port ID 1f and is at offset 0x4000 within the HPB address space. The :a appended to the disk device name identifies a particular minor device.

The links in /dev are created by the devlinks(lM), disks(lM), tapes(lM) and ports(lM) utilities, based on the minor number information supplied in the attach(9E) routine. The system runs these utilities to create /devices and /dev during a reconfiguration boot (that is, boot with the -r flag), and also by the add_drv(lM) utility, which is used to install a new driver in the system.

<<Previous |  Contents |  Next>>