Go to main content

Writing Device Drivers in Oracle® Solaris 11.4

Exit Print View

Updated: November 2020
 
 

PROM on SPARC Systems

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 whether the device is working correctly.

See the boot(8) man page for a description of the x86 boot subsystem.

    The PROM has several purposes, including:

  • Bringing the machine up from power on, or from a hard reset PROM reset command

  • Providing an interactive tool for examining and setting memory, device registers, and memory mappings

  • Booting the Oracle Solaris system.

    Simply powering up the computer and attempting to use its PROM to examine device registers can fail. While the device might be correctly installed, those mappings are specific to the Oracle Solaris OS and do not become active until the Oracle Solaris kernel is booted. Upon power up, the PROM maps only essential system devices, such as the keyboard.

  • Taking a system crash dump using the sync command

Open Boot PROM 3

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

The printenv command displays all parameters and their values.

Help is available with the help command.

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

For complete documentation on the Open Boot PROM, see the Open Boot PROM Toolkit User's Guide.

Forth Commands

The Open Boot PROM uses the Forth programming language. Forth is a stack-based language. Arguments must be pushed on the stack before running the correct 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 remains 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 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 workstation with a PCI device.

ok cd /

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

ok ls
f0322ea0 pci@309
f027f158 cpu@4
f027eff8 cpu@3
f027ee98 cpu@2
f027ed38 cpu@1
f027ebd8 cpu@0
f027ab78 reboot-memory@0
f0272108 iscsi-hba
f0241604 virtual-memory
f0240ff8 memory@m0,50000000
f022cecc aliases
f022ce54 options
f022cd0c openprom
f022cc98 chosen
f022cc20 packages

The full node name can be used:

cd pci@309
ok ls
f0332014 pci@1
ok cd pci@1
ok ls
f0334d90 display@0

Rather than using the full node name in the previous example, you could also use an abbreviation. The abbreviated command-line entry looks like the following example:

ok cd pci

The name is actually device@dev,func (for PCI devices). The display device is at dev 0 and function 0. If a PCI device is displayed in this tree, the device has been recognized by the PROM.

The .properties command displays the PROM properties of a device. These properties can be examined to determine which properties the device exports. This information is useful later to ensure that the driver is looking for the correct hardware properties. These properties are the same properties that can be retrieved with ddi_getprop(9F).

ok cd display
ok .properties
assigned-addresses       82010010 00000000 01000000 00000000 01000000 
                         82010014 00000000 00100000 00000000 00004000 
                         82010018 00000000 00800000 00000000 00800000 
                         82010030 00000000 00110000 00000000 00010000 
compatible               pciex102b,522.19a2.102.5
                         pciex102b,522.19a2.102
                         pciex102b,522.5
                         pciex102b,522
                         pciexclass,030000
                         pciexclass,0300
reg                      00010000 00000000 00000000 00000000 00000000 
                         02010010 00000000 00000000 00000000 01000000 
                         02010014 00000000 00000000 00000000 00004000 
                         02010018 00000000 00000000 00000000 00800000 
                         02010030 00000000 00000000 00000000 00010000 
device_type              display
name                     display
port-type                Legacy-PCIE-Endpoint
interrupts               00000001 
cache-line-size          00000010 
class-code               00030000 
subsystem-id             00000102 
subsystem-vendor-id      000019a2 
revision-id              00000005 
device-id                00000522 
vendor-id                0000102b

The reg property defines an array of register description structures containing the following fields:

uint32_t	bus_hi;	/* 3 cells of register address */
uint32_t	bus_mid;
uint32_t 	bus_lo;
uin32_t	size_hi;	/* 2 cells of register size */
uin32_t	size_lo;

Mapping the Device

A device must be mapped into memory to be tested. 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 steps:

  1. Determine the PCI device path.

    In this example, the display device is located at /pci@309/pci@1/display@0.

  2. Determine the offset within the physical address space used by the device.

    The offset used is specific to the device. In the display example, the video memory happens to start at an offset of BAR 18.

  3. Use the begin-select-dev word to select the PCI device and execute the map-in method of the parent to map the device in.

    The begin-select-dev word takes a string of the device path as its argument. The map-in word takes 3-cell address and a size as arguments to map. Like the offset, the size of the byte transfer is specific to the device. In the display example, the size is set to 0x800000 bytes.

    In the following code example, the PCI path is displayed as an argument to the select-dev word, and the offset, slot number, and size values for the frame buffer are displayed as arguments to the map-in word. Notice the space between the opening quote and / in the begin-select-dev argument. The virtual address to use remains on top of the stack. The stack is shown using the .s word. The stack can be assigned a name with the constant operation.

    PCI memory space decoding must eb enabled before a device can be accessed. This can be done by writing 7 to config space offset 4 using config-w! method of the parent device.

    ok pwd
    /pci@309/pci@1/display@0
    ok " /pci@309/pci@1/display@0" begin-select-dev
    
    ok my-address my-space 02010018 or 00800000 " map-in" $call-parent
    ok .s
    fddb0000 
    ok constant fb
    ok 7 my-space 4 +  " config-w!"  $call-parent

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 ! indicates 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 ffe98000 c!

A suffix of @ indicates a read operation. The read operation takes the address off the stack.

ok ffe98000 c@
ok .s
55

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

ok ffe98000 c?
55

Be careful when trying to query the device. If the mappings are not set up correctly, trying to read or write could cause errors. Special words are 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 fffa4000 c@
Data Access Error

ok fffa4000 cprobe
ok .s0

ok ffe98000 cprobe
ok .s
0 ffffffffffffffff

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. Use wfill and an Lfill for words and longwords. This fill example causes the display to display simple patterns based on the byte passed.

ok fb 10000 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