Go to the first, previous, next, last section; table of contents; home; full screen; PSIM.

Included Devices

com -- '550 compatible serial device

Description

Models the basics of the 8 register '550 serial device. The model includes an interrupt line, input and output fifos, and status information.

Independent configuration of the devices input and output streams is allowed: use either the console or a file (buffered or unbuffered) as the data source/sink; specify the real-time delay between each character transfer.

When the devices input stream is being taken from a file, the end of file is signaled by a loss of carrier (the loss of carrier may be incorrectly proceeded by a single null character).

Properties

reg = <address> <size> ... (optional - note 1)
List of <address> <size> pairs. Each pair specifies an address for the devices 8 registers. The address should be 8 byte aligned.
alternate-reg = <address> <size> ... (optional - note 1)
Alternative addreses for the registers.
assigned-addresses = <address> <size> ... (optional - note 1)
On a PCI bus, this property specifies the addresses assigned to the device. The values reflect the devices configuration base registers. Note 1: At least one of "assigned-addresses", "reg" or "alternative-reg" must be specified. If "assigned-addresses" is specified the other address specifications are ignored.
input-file = <file-name> (optional)
File to take all serial port input from (instead of the simulation console).
output-file = <file-name> (optional)
File to send all output to (instead of the simulation console).
input-buffering = "unbuffered" (optional)
Reserved for future enhancements. In the future, this option may be used to provide input buffering alternatives.
output-buffering = "unbuffered" (optional)
Specifying "unbuffered" buffering disables buffering on the serial devices output stream (all data is immediatly written). In the future, this option may be extended to include other buffering alternatives.
input-delay = <integer-delay> (optional)
Specify the number of ticks after the current character has been read from the serial port that the next character becomes available.
output-delay = <integer-delay> (optional)
Specify the number of ticks after a character has been written to the empty output fifo that the fifo finishes draining. Any characters written to the output fifo before it has drained will not be lost and will still be displayed.

Examples

  /iobus@0xf0000000/com@0x3000/reg 0x3000 8

Create a simple console device at address 0x3000 within iobus. Since iobus starts at address 0xf0000000 the absolute address of the serial port will be 0xf0003000.

The device will always be ready for I/O (no delay properties specified) and both the input and output streams will use the simulation console (no file properties).

  $ psim \
    -o '/cpus/cpu@0' \
    -o '/iobus@0xf0000000/com@0x4000/reg 0x4000 8' \
    -o '/iobus@0xf0000000/com@0x4000/input-file /etc/passwd' \
    -o '/iobus@0xf0000000/com@0x4000/input-delay 1000' \
    -o '/iobus@0xf0000000/com@0x4000 > 0 int /cpus/cpu@0x0' \
    psim-test/hw-com/cat.be 0xf0004000

The serial port (at address 0xf0004000 is configured so that it takes its input from the file /etc/passwd while its output is allowed to appear on the simulation console. The node /cpus/cpu@0 was explicitly specified to ensure that it had been created before any interrupts were attached to it.

The program psim-test/hw-com/cat copies any characters on the serial port's input (/etc/passwd) to its output (the console). Consequently, the aove program will display the contents of the file /etc/passwd on the screen.

Bugs

IEEE 1275 requires that a device on a PCI bus have, as its first reg entry, the address of its configuration space registers. Currently, this device does not even implement configuration registers. This model does not attempt to model the '550's input and output fifos. Instead, the input fifo is limited to a single character at a time, while the output fifo is effectivly infinite. Consequently, unlike the '550, this device will not discard output characters once a stream of 16 have been written to the data output register.

The input and output can only be taken from a file (or the current terminal device). In the future, the com device should allow the specification of other data streams (such as an xterm or TK window).

The input blocks if no data is available.

Interrupts have not been tested.

core -- root of the device tree

Description

The core device positioned at the root of the device tree appears to its child devices as a normal device just like every other device in the tree.

Internally it is implemented using a core object. Requests to attach (or detach) address spaces are passed to that core object. Requests to transfer (DMA) data are reflected back down the device tree using the core_map data transfer methods.

Properties

None.

cpu -- Interface to a Processor

Description

The CPU device provides the connection between the interrupt net (linking the devices and the interrupt controller) and the simulated model of each processor. This device contains interrupt ports that correspond directly to the external interrupt stimulus that can be sent to a given processor. Sending an interrupt to one of the ports results in an interrupt being delivered to the corresponding processor.

Typically, an interrupt controller would have its inputs connected to device interrupt sources and its outputs (sreset, int, et.al.) connected to this device.

Properties

cpu-nr = <integer> (required)
Specify the processor (1..N) that this cpu device node should control.

Examples

Connect an OpenPIC interrupt controller interrupt ports to processor zero.

 -o '/phb/opic@0 > irq0 int /cpus/cpu@0' \
 -o '/phb/opic@0 > init hreset /cpus/cpu@0' \

cdrom -- read-only removable mass storage device

disk -- mass storage device

floppy -- removable mass storage device

Description

Mass storage devices such as a hard-disk or cdrom-drive are not normally directly connected to the processor. Instead, these devices are attached to a logical bus, such as SCSI or IDE, and then a controller of that bus is made accessible to the processor. Reflecting this, within a device tree, mass storage devices such as a cdrom, disk or floppy are created as children of of a logical bus controller node (such as a SCSI or IDE interface). That controller, in turn, would be made the child of a physical bus node that is directly accessible to the processor. The above mass storage devices provide two interfaces - a logical and a physical. At the physical level the device_io_... functions can be used perform reads and writes of the raw media. The address being interpreted as an offset from the start of the disk. At the logical level, it is possible to create an instance of the disk that provides access to any of the physical media, a disk partition, or even a file within a partition. The disk-label package, which implements this functionality, is described elsewhere. Both the Open Firmware and Moto BUG rom emulations support this interface.

Properties

file = <file-name> (required)
The name of the file that contains an image of the disk. For disk and floppy devices, the image will be opened for both reading and writing.
block-size = <nr-bytes> (optional)
The value is returned by the block-size method. The default value is 512 bytes.
max-transfer = <nr-bytes> (optional)
The value is returned by the max-transfer method. The default value is 512 bytes.
#blocks = <nr-blocks> (optional)
The value is returned by the #blocks method. If no value is present then -1 is returned.

Examples

Enable tracing

 $  psim -t 'disk-device' \

Add a CDROM and disk to an IDE bus. Specify the host operating system's cd drive as the CD-ROM image.

    -o '/pci/ide/disk@0/file "disk-image' \
    -o '/pci/ide/cdrom@1/file "/dev/cd0a' \

As part of the code implementing a logical bus device (for instance the IDE controller), locate the CDROM device and then read block 47.

  device *cdrom = device_tree_find_device(me, "cdrom");
  char block[512];
  device_io_read_buffer(cdrom, buf, 0,

0, 47 * sizeof(block), // space, address sizeof(block), NULL, 0); Use the device instance interface to read block 47 of the file called netbsd.elf on the disks default partition. Similar code would be used in an operating systems pre-boot loader.

  device_instance *netbsd =
    device_create_instance(root, "/pci/ide/disk:,\netbsd.elf");
  char block[512];
  device_instance_seek(netbsd,  0, 47 * sizeof(block));
  device_instance_read(netbsd, block, sizeof(block));

Bugs

The block device specification includes mechanisms for determining the physical device characteristics - such as the disks size. Currently this mechanism is not implemented. The functionality of this device (in particular the device instance interface) depends on the implementation of disk-label package. That package may not be fully implemented.

The disk does not know its size. Hence it relies on the failure of fread(), fwrite() and fseek() calls to detect errors.

The disk size is limited by the addressable range covered by unsigned_word (addr). An extension would be to instead use the concatenated value space:addr.

The method #blocks should `stat' the disk to determine the number of blocks if there is no #blocks property.

eeprom -- JEDEC? compatible electricaly erasable programable device

Description

This device implements a small byte addressable EEPROM. Programming is performed using the same write sequences as used by standard modern EEPROM components. Writes occure in real time, the device returning a progress value until the programing has been completed.

It is based on the AMD 29F040 component.

Properties

reg = <address> <size> (required)
Determine where the device lives in the parents address space.
nr-sectors = <integer> (required)
When erasing an entire sector is cleared at a time. This specifies the number of sectors in the EEPROM component.
sector-size = <integer> (required)
The number of bytes in a sector. When erasing, memory chunks of this size are cleared. NOTE: The product nr-sectors * sector-size does not need to map the size specified in the reg property. If the specified size is smaller part of the eeprom will not be accessible while if it is larger the addresses will wrap.
byte-write-delay = <integer> (required)
Number of clock ticks before the programming of a single byte completes.
sector-start-delay = <integer> (required)
When erasing sectors, the number of clock ticks after the sector has been specified that the actual erase process commences.
erase-delay = <intger> (required)
Number of clock ticks before an erase program completes
manufacture-code = <integer> (required)
The one byte value returned when the auto-select manufacturer code is read.
device-code = <integer> (required)
The one byte value returned when the auto-select device code is read.
input-file = <file-name> (optional)
Initialize the eeprom using the specified binary file.
output-file = <file-name> (optional)
When ever the eeprom is updated, save the modified image into the specified file.

Examples

Enable tracing of the eeprom:

  bash$ psim -t eeprom-device \

Configure something very like the Amd Am29F040 - 512byte EEPROM (but a bit faster):

  -o '/eeprom@0xfff00000/reg 0xfff00000 0x80000' \
  -o '/eeprom@0xfff00000/nr-sectors 8' \
  -o '/eeprom@0xfff00000/sector-size 0x10000' \
  -o '/eeprom@0xfff00000/byte-write-delay 1000' \
  -o '/eeprom@0xfff00000/sector-start-delay 100' \
  -o '/eeprom@0xfff00000/erase-delay 1000' \
  -o '/eeprom@0xfff00000/manufacture-code 0x01' \
  -o '/eeprom@0xfff00000/device-code 0xa4' \

Initialize the eeprom from the file /dev/zero:

  -o '/eeprom@0xfff00000/input-file /dev/zero'

Bugs

glue -- glue to interconnect and test interrupts

Description

The glue device provides two functions. Firstly, it provides a mechanism for inspecting and driving the interrupt net. Secondly, it provides a set of boolean primitives that can be used add combinatorial operations to the interrupt network.

Glue devices have a variable number of big endian output registers. Each host-word size. The registers can be both read and written.

Writing a value to an output register causes an interrupt (of the specified level) to be driven on the devices corresponding output interrupt port.

Reading an output register returns either the last value written or the most recently computed value (for that register) as a result of an interrupt ariving (which ever was computed last).

At present the following sub device types are available:

glue: In addition to driving its output interrupt port with any value written to an interrupt input port is stored in the corresponding output register. Such input interrupts, however, are not propogated to an output interrupt port.

glue-and: The bit-wise AND of the interrupt inputs is computed and then both stored in output register zero and propogated to output interrupt output port zero.

Properties

reg = <address> <size> (required)
Specify the address (within the parent bus) that this device is to live. The address must be 2048 * sizeof(word) (8k in a 32bit simulation) aligned.
interrupt-ranges = <int-number> <range> (optional)
If present, this specifies the number of valid interrupt inputs (up to the maximum of 2048). By default, int-number is zero and range is determined by the reg size.

Examples

Enable tracing of the device:

 -t glue-device \

Create source, bitwize-and, and sink glue devices. Since the device at address 0x10000 is of size 8 it will have two output interrupt ports.

 -o '/iobus@0xf0000000/glue@0x10000/reg 0x10000 8' \
 -o '/iobus@0xf0000000/glue-and@0x20000/reg 0x20000 4' \
 -o '/iobus@0xf0000000/glue-and/interrupt-ranges 0 2' \
 -o '/iobus@0xf0000000/glue@0x30000/reg 0x30000 4' \

Wire the two source interrupts to the AND device:

 -o '/iobus@0xf0000000/glue@0x10000 > 0 0 /iobus/glue-and' \
 -o '/iobus@0xf0000000/glue@0x10000 > 1 1 /iobus/glue-and' \

Wire the AND device up to the sink so that the and's output is not left open.

 -o '/iobus@0xf0000000/glue-and > 0 0 /iobus/glue@0x30000' \

With the above configuration. The client program is able to compute a two bit AND. For instance the C stub below prints 1 AND 0.

  unsigned *input = (void*)0xf0010000;
  unsigned *output = (void*)0xf0030000;
  unsigned ans;
  input[0] = htonl(1);
  input[1] = htonl(0);
  ans = ntohl(*output);
  write_string("AND is ");
  write_int(ans);
  write_line();

Bugs

A future implementation of this device may support multiple interrupt ranges.

Some of the devices listed may not yet be fully implemented.

Additional devices such as a dff, an inverter or a latch may be useful.

htab -- pseudo-device describing a PowerPC hash table

Description

During the initialization of the device tree, the pseudo-device htab, in conjunction with any child pte pseudo-devices, will create a PowerPC hash table in memory. The hash table values are written using dma transfers. The size and address of the hash table are determined by properties of the htab node. By convention, the htab device is made a child of the /openprom/init node. By convention, the real address of the htab is used as the htab nodes unit address.

Properties

real-address = <address> (required)
The physical address of the hash table. The PowerPC architecture places limitations on what is a valid hash table real-address.
nr-bytes = <size> (required)
The size of the hash table (in bytes) that is to be created at real-address. The PowerPC architecture places limitations on what is a valid hash table size.
claim = <anything> (optional)
If this property is present, the memory used to construct the hash table will be claimed from the memory device. The memory device being specified by the /chosen/memory ihandle property.

Examples

Enable tracing.

  $  psim -t htab-device \

Create a htab specifying the base address and minimum size.

    -o '/openprom/init/htab@0x10000/real-address 0x10000' \
    -o '/openprom/init/htab@0x10000/claim 0' \
    -o '/openprom/init/htab@0x10000/nr-bytes 65536' \

Bugs

See the pte device.

pte -- pseudo-device describing a htab entry

Description

The pte pseudo-device, which must be a child of a htabl node, describes a virtual to physical mapping that is to be entered into the parents hash table. Two alternative specifications of the mapping are allowed. Either a section of physical memory can be mapped to a virtual address, or the header of an executible image can be used to define the mapping. By convention, the real address of the map is specified as the pte devices unit address.

Properties

real-address = <address> (required)
The starting physical address that is to be mapped by the hash table.
wimg = <int> (required)
pp = <int> (required)
The value of hash table protection bits that are to be used when creating the virtual to physical address map.
claim = <anything> (optional)
If this property is present, the real memory that is being mapped by the hash table will be claimed from the memory node (specified by the ihandle /chosen/memory).
virtual-address = <integer> [ <integer> ] (option A)
nr-bytes = <size> (option A)
Option A - Virtual virtual address (and size) at which the physical address is to be mapped. If multiple values are specified for the virtual address then they are concatenated to gether to form a longer virtual address.
file-name = <string> (option B)
Option B - An executable image that is to be loaded (starting at the physical address specified above) and then mapped in using informatioin taken from the executables header. information found in the files header.

Examples

Enable tracing (note that both the htab and pte device use the same trace option).

   -t htab-device \

Map a block of physical memory into a specified virtual address:

  -o '/openprom/init/htab/pte@0x0/real-address 0' \
  -o '/openprom/init/htab/pte@0x0/nr-bytes 4096' \
  -o '/openprom/init/htab/pte@0x0/virtual-address 0x1000000' \
  -o '/openprom/init/htab/pte@0x0/claim 0' \
  -o '/openprom/init/htab/pte@0x0/wimg 0x7' \
  -o '/openprom/init/htab/pte@0x0/pp 0x2' \

Map a file into memory.

  -o '/openprom/init/htab/pte@0x10000/real-address 0x10000' \
  -o '/openprom/init/htab/pte@0x10000/file-name "netbsd.elf' \
  -o '/openprom/init/htab/pte@0x10000/wimg 0x7' \
  -o '/openprom/init/htab/pte@0x10000/pp 0x2' \

Bugs

For an ELF executable, the header defines both the virtual and real address at which each file section should be loaded. At present, the real addresses that are specified in the header are ignored, the file instead being loaded in to physical memory in a linear fashion.

ide -- Integrated Disk Electronics

Description

This device models the primary/secondary ide controller described in the [CHRPIO] document.

The controller has separate independant interrupt outputs for each ide bus.

Properties

reg = ... (required)
The reg property is described in the document [CHRPIO].
ready-delay = <integer> (optional)
If present, this specifies the time that the ide device takes to complete an I/O operation.
disk?/ide-byte-count = <integer> (optional)
disk?/ide-sector-count = <integer> (optional)
disk?/ide-head-count = <integer> (optional)
The ide device checks each child (disk device) node to see if it has the above properties. If present, these values will be used to compute the LBA address in CHS addressing mode.

Examples

Enable tracing:

  -t ide-device \

Attach the ide device to the pci bus at slot one. Specify legacy I/O addresses:

  -o '/phb/ide@1/assigned-addresses \
        ni0,0,10,1f0 8 \
        ni0,0,14,3f8 8 \
        ni0,0,18,170 8 \
        ni0,0,1c,378 8 \
        ni0,0,20,200 8' \
  -o '/phb@0x80000000/ide@1/reg \
        1 0 \
        i0,0,10,0 8 \
        i0,0,18,0 8 \
        i0,0,14,6 1 \
        i0,0,1c,6 1 \
        i0,0,20,0 8' \

Note: the fouth and fifth reg entries specify that the register is at an offset into the address specified by the base register (assigned-addresses); Apart from restrictions placed by the pci specification, no restrictions are placed on the number of base registers specified by the assigned-addresses property. Attach a disk to the primary and a cdrom to the secondary ide controller.

  -o '/phb@0x80000000/ide@1/disk@0/file "zero' \
  -o '/phb@0x80000000/ide@1/cdrom@2/file "/dev/cdrom"' \

Connect the two interrupt outputs (a and b) to a glue device to allow testing of the interrupt port. In a real simulation they would be wired to the interrupt controller.

  -o '/phb@0x80000000/glue@2/reg 2 0 ni0,0,0,0 8' \
  -o '/phb@0x80000000/ide@1 > a 0 /phb@0x80000000/glue@2' \
  -o '/phb@0x80000000/ide@1 > b 1 /phb@0x80000000/glue@2' 

Bugs

While the DMA registers are present, DMA support has not yet been implemented.

The number of supported commands is very limited.

The standards documents appear to be vague on how to specify the unit-address of disk devices devices being attached to the ide controller. I've chosen to use integers with devices zero and one going to the primary controller while two and three are connected to the secondary controller.

References

[CHRPIO] PowerPC(tm) Microprocessor Common Hardware Reference Platform: I/O Device Reference. http://chrp.apple.com/???.

[SCHMIDT] The SCSI Bus and IDE Interface - Protocols, Applications and Programming. Friedhelm Schmidt (translated by Michael Schultz). ISBN 0-201-42284-0. Addison-Wesley Publishing Company.

file -- load a file into memory

Description

Loads the entire contents of <file-name> into memory at starting at real-address. Assumes that memory exists for the load.

Properties

file-name = <string>
Name of the file to be loaded into memory
real-address = <integer>

data -- initialize a memory location with specified data

Description

The pseudo device data provides a mechanism specifying the initialization of a small section of memory.

Normally, the data would be written using a dma operation. However, for some addresses this will not result in the desired result. For instance, to initialize an address in an eeprom, instead of a simple dma of the data, a sequence of writes (and then real delays) that program the eeprom would be required.

For dma write initialization, the data device will write the specified data to real-address using a normal dma.

For instance write initialization, the specified instance is opened. Then a seek to the real-address is performed followed by a write of the data.

Integer properties are stored using the target's endian mode.

Properties

data = <any-valid-property> (required)
Data to be loaded into memory. The property type determines how it is loaded.
real-address = <integer> (required)
Start address at which the data is to be stored.
instance = <string> (optional)
Instance specification of the device that is to be opened so that the specified data can be written to it.

Examples

The examples below illustrate the two alternative mechanisms that can be used to store the value 0x12345678 at address 0xfff00c00, which is normally part of the 512k system eeprom.

If the eeprom is being modeled by ram (memory device) then the standard dma initialization can be used. By convention: the data devices are uniquely identified by argumenting them with the destinations real address; and all data devices are put under the node /openprom/init.

 /openprom/memory@0xfff00000/reg 0xfff00000 0x80000
 /openprom/init/data@0x1000/data 0x12345678
 /openprom/init/data@0x1000/real-address 0x1000

If instead a real eeprom was being used the instance write method would instead need to be used (storing just a single byte in an eeprom requires a complex sequence of accesses). The real-address is specified as 0x0c00 which is the offset into the eeprom. For brevity, most of the eeprom properties have been omited.

 /iobus/eeprom@0xfff00000/reg 0xfff00000 0x80000
 /openprom/init/data@0xfff00c00/real-address 0x0c00
 /openprom/init/data@0xfff00c00/data 0x12345667
 /openprom/init/data@0xfff00c00/instance /iobus/eeprom@0xfff00000/reg

Bugs

At present, only integer properties can be specified for an initial data value.

load-binary -- load binary segments into memory

Description

Each loadable segment of the specified binary is loaded into memory at its required address. It is assumed that the memory at those addresses already exists.

This device is normally used to load an executable into memory as part of real mode simulation.

Properties

file-name = <string>
Name of the binary to be loaded.

map-binary -- map the binary into the users address space

Description

Similar to load-binary except that memory for each segment is created before the corresponding data for the segment is loaded.

This device is normally used to load an executable into a user mode simulation.

Properties

file-name = <string>
Name of the binary to be loaded.

stack -- create an initial stack frame in memory

Description

Creates a stack frame of the specified type in memory.

Due to the startup sequence gdb uses when commencing a simulation, it is not possible for the data to be placed on the stack to be specified as part of the device tree. Instead the arguments to be pushed onto the stack are specified using an IOCTL call.

The IOCTL takes the additional arguments:

 unsigned_word stack_end -- where the stack should come down from
 char **argv -- ...
 char **envp -- ...

Properties

stack-type = <string>
The form of the stack frame that is to be created.

iobus -- simple bus for attaching devices

Description

IOBUS provides a simple `local' bus for attaching (hanging) programmed IO devices from. All child devices are directly mapped into this devices parent address space (after checking that the attach address lies within the iobus address range. address).

Properties

None.

memory -- description of system memory

Description

This device describes the size and location of the banks of physical memory within the simulation.

In addition, this device supports the "claim" and "release" methods that can be used by OpenBoot client programs to manage the allocation of physical memory.

Properties

reg = { <address> <size> (required)}
Each pair specify one bank of memory.
available = { <address> <size> (automatic)}
Each pair specifies a block of memory that is currently unallocated.

nvram -- non-volatile memory with clock

Description

This device implements a small byte addressable non-volatile memory. The top 8 bytes of this memory include a real-time clock.

Properties

reg = <address> <size> (required)
Specify the address/size of this device within its parents address space.
timezone = <integer> (optional)
Adjustment to the hosts current GMT (in seconds) that should be applied when updating the NVRAM's clock. If no timezone is specified, zero (GMT or UCT) is assumed.

opic -- Open Programmable Interrupt Controller (OpenPIC)

Description

This device implements the core of the OpenPIC interrupt controller as described in the OpenPIC specification 1.2 and other related documents.

The model includes:

  • Up to 2048 external interrupt sources
  • The four count down timers
  • The four interprocessor multicast interrupts
  • multiprocessor support
  • Full tracing to assist help debugging
  • Support for all variations of edge/level x high/low polarity.

Properties

reg = <address> <size> ... (required)
Determine where the device lives in the parents address space. The first address size pair specifies the address of the interrupt destination unit (which might contain an interrupt source unit) while successive reg entries specify additional interrupt source units. Note that for an opic device attached to a pci bus, the first reg entry may need to be ignored it will be the address of the devices configuration registers.
interrupt-ranges = <int-number> <range> ... (required)
A list of pairs. Each pair corresponds to a block of interrupt source units (the address of which being specified by the corresponding reg tupple). int-number is the number of the first interrupt in the block while range is the number of interrupts in the block.
timer-frequency = <integer> (optional)
If present, specifies the default value of the timer frequency reporting register. By default a value of 1 HZ is used. The value is arbitrary, the timers are always updated once per machine cycle.
vendor-identification = <integer> (optional)
If present, specifies the value to be returned when the vendor identification register is read.

Examples

See the test suite directory:

  psim-test/hw-opic

Bugs

For an OPIC controller attached to a PCI bus, it is not clear what the value of the reg and interrupt-ranges properties should be. In particular, the PCI firmware bindings require the first value of the reg property to specify the devices configuration address while the OpenPIC bindings require that same entry to specify the address of the Interrupt Delivery Unit. This implementation checks for and, if present, ignores any configuration address (and its corresponding interrupt-ranges entry).

The OpenPIC specification requires the controller to be fair when distributing interrupts between processors. At present the algorithm used isn't fair. It is biased towards processor zero.

The OpenPIC specification includes a 8259 pass through mode. This is not supported.

References

PowerPC Multiprocessor Interrupt Controller (MPIC), January 19, 1996. Available from IBM.

The Open Programmable Interrupt Controller (PIC) Register Interface Specification Revision 1.2. Issue Date: Opctober 1995. Available somewhere on AMD's web page (http://www.amd.com/)

PowerPC Microprocessor Common Hardware Reference Platform (CHRP) System bindings to: IEEE Std 1275-1994 Standard for Boot (Initialization, Configuration) Firmware. Revision 1.2b (INTERIM DRAFT). April 22, 1996. Available on the Open Firmware web site http://playground.sun.com/p1275/.

Processor init register

The bits in this register (one per processor) are directly wired to

pal -- glue logic device containing assorted junk

Description

Typical hardware dependant hack. This device allows the firmware to gain access to all the things the firmware needs (but the OS doesn't).

The pal contains the following registers. Except for the interrupt level register, each of the below is 8 bytes in size and must be accessed using correct alignment. For 16 and 32 bit accesses the bytes not directed to the register are ignored: |0 reset register (write) |4 processor id register (read) |8 interrupt port (write) |9 interrupt level (write) |12 processor count register (read) |16 tty input fifo register (read) |20 tty input status register (read) |24 tty output fifo register (write) |28 tty output status register (read)

Reset register (write) halts the simulator exiting with the value written. Processor id register (read) returns the processor number (0 .. N-1) of the processor performing the read. The interrupt registers should be accessed as a pair (using a 16 or 32 bit store). The low byte specifies the interrupt port while the high byte specifies the level to drive that port at. By convention, the pal's interrupt ports (int0, int1, ...) are wired up to the corresponding processor's level sensative external interrupt pin. Eg: A two byte write to address 8 of 0x0102 (big-endian) will result in processor 2's external interrupt pin to be asserted.

Processor count register (read) returns the total number of processors active in the current simulation.

TTY input fifo register (read), if the TTY input status register indicates a character is available by being nonzero, returns the next available character from the pal's tty input port.

Similarly, the TTY output fifo register (write), if the TTY output status register indicates the output fifo is not full by being nonzero, outputs the character written to the tty's output port.

Properties

reg = <address> <size> (required)
Specify the address (within the parent bus) that this device is to live.

phb -- PCI Host Bridge

Description

PHB implements a model of the PCI-host bridge described in the PPCP document.

For bridge devices, Open Firmware specifies that the ranges property be used to specify the mapping of address spaces between a bridges parent and child busses. This PHB model configures itsself according to the information specified in its ranges property. The ranges property is described in detail in the Open Firmware documentation.

For DMA transfers, any access to a PCI address space which falls outside of the mapped memory space is assumed to be a transfer intended for the parent bus.

Properties

ranges = <my-phys-addr> <parent-phys-addr> <my-size> ... (required)
Define a number of mappings from the parent bus to one of this devices PCI busses. The exact format of the parent-phys-addr is parent bus dependant. The format of my-phys-addr is described in the Open Firmware PCI bindings document (note that the address must be non-relocatable).
#address-cells = 3 (required)
Number of cells used by an Open Firmware PCI address. This property must be defined before specifying the ranges property.
#size-cells = 2 (required)
Number of cells used by an Open Firmware PCI size. This property must be defined before specifying the ranges property.

Examples

Enable tracing:

  $ psim \
    -t phb-device \

Since device tree entries that are specified on the command line are added before most of the device tree has been built it is often necessary to explictly add certain device properties and thus ensure they are already present in the device tree. For the phb one such property is parent busses #address-cells.

    -o '/#address-cells 1' \

Create the PHB remembering to include the cell size properties:

    -o '/phb@0x80000000/#address-cells 3' \
    -o '/phb@0x80000000/#size-cells 2' \

Specify that the memory address range 0x80000000 to 0x8fffffff should map directly onto the PCI memory address space while the processor address range 0xc0000000 to 0xc000ffff should map onto the PCI I/O address range starting at location zero:

    -o '/phb@0x80000000/ranges \
                nm0,0,0,80000000 0x80000000 0x10000000 \
                ni0,0,0,0 0xc0000000 0x10000' \

Insert a 4k nvram into slot zero of the PCI bus. Have it directly accessible in both the I/O (address 0x100) and memory (address 0x80001000) spaces:

    -o '/phb@0x80000000/nvram@0/assigned-addresses \
                nm0,0,10,80001000 4096 \
                ni0,0,14,100 4096'
    -o '/phb@0x80000000/nvram@0/reg \
                0 0 \
                i0,0,14,0 4096'
    -o '/phb@0x80000000/nvram@0/alternate-reg \
                0 0 \
                m0,0,10,0 4096'

The assigned-address property corresponding to what (if it were implemented) be found in the config base registers while the reg and alternative-reg properties indicating the location of registers within each address space.

Of the possible addresses, only the non-relocatable versions are used when attaching the device to the bus.

Bugs

The implementation of the PCI configuration space is left as an exercise for the reader. Such a restriction should only impact on systems wanting to dynamically configure devices on the PCI bus.

The CHRP document specfies additional (optional) functionality of the primary PHB. The implementation of such functionality is left as an exercise for the reader.

The Open Firmware PCI bus bindings document (rev 1.6 and 2.0) is unclear on the value of the "ss" bits for a 64bit memory address. The correct value, as used by this module, is 0b11. The Open Firmware PCI bus bindings document (rev 1.6) suggests that the register field of non-relocatable PCI address should be zero. Unfortunatly, PCI addresses specified in the assigned-addresses property must be both non-relocatable and have non-zero register fields.

The unit-decode method is not inserting a bus number into any address that it decodes. Instead the bus-number is left as zero.

Support for aliased memory and I/O addresses is left as an exercise for the reader.

Support for interrupt-ack and special cycles are left as an exercise for the reader. One issue to consider when attempting this exercise is how to specify the address of the int-ack and special cycle register. Hint: /8259-interrupt-ackowledge is the wrong answer.

Children of this node can only use the client callback interface when attaching themselves to the phb.

References

http://playground.sun.com/1275/home.html#OFDbusPCI

register -- dummy device to initialize processor registers

Description

The properties of this device are used, during initialization, to specify the initial value of various processor registers. The property name specifying the register to be initialized with the special form <cpu-nr>.<register> being used to initialize a specific processor's register (eg 0.pc).

Because, when the device tree is created, overriding properties are entered into the tree before any default values, this device must initialize registers in newest (default) to oldest (overriding) property order.

The actual registers (for a given target) are defined in the file registers.c.

This device is normally a child of the /openprom/init node.

Examples

Given a device tree containing the entry:

	/openprom/init/register/pc 0xfff00cf0

then specifying the command line option:

	-o '/openprom/init/register/pc 0x0'

would override the initial value of processor zero's program counter. The resultant device tree tree containing:

	/openprom/init/register/0.pc 0x0
	/openprom/init/register/pc 0xfff00cf0

and would be processed last to first resulting in the sequence: set all program counters to 0xfff00cf0; set processor zero's program counter to zero.

trace -- the properties of this dummy device specify trace options

Description

The properties of this device are used, during initialization, to specify the value various simulation trace options. The initialization can occure implicitly (during device tree init) or explicitly using this devices ioctl method.

The actual options and their default values (for a given target) are defined in the file debug.

This device is normally a child of the /openprom node.

EXAMPLE

The trace option dump-device-tree can be enabled by specifying the option:

	-o '/openprom/trace/dump-device-tree 0x1'

Alternativly the shorthand version:

	-t dump-device-tree

vm -- virtual memory device for user simulation modes

Description

In user mode, mapped text, data and stack addresses are managed by the core. Unmapped addresses are passed onto this device (because it establishes its self as the fallback device) for processing.

During initialization, children of this device will request the mapping of the initial text and data segments. Those requests are passed onto the core device so that that may establish the initial memory regions.

Once the simulation has started (as noted above) any access to an unmapped address range will be passed down to this device as an IO access. This device will then either attach additional memory to the core device or signal the access as being invalid.

The IOCTL function is used to notify this device of any changes to the users `brk' point.

Properties

stack-base = <number>
Specifies the lower address of the stack segment in the users virtual address space. The initial stack page is defined by stack-base + nr-bytes.
nr-bytes = <number>
Specifies the maximum size of the stack segment in the users address space.
Go to the first, previous, next, last section; table of contents; home; full screen.