5.2.5. PVBusSlave component

The PVBusSlave component handles decoding the slave side of the PVBus. Any component that acts as a bus slave must:

By default, the PVBusSlave translates all transactions into read() and write() requests on the device port.

The control port enables you to configure the PVBusSlave for a device. This lets you define the behavior of the different regions of the address space on the device. You can configure regions separately for read and write, at a 4k byte granularity. This permits you to set memory-like, device-like, abort or ignore access address regions.

Transactions to memory-like regions are handled internally by the PVBusSlave subcomponent. Abort and ignore regions are also handled by the PVBusSlave.

Transactions to device-like regions are forwarded to the device port. Your device must implement the read() and write() methods on the device port if any regions are configured as device-like.

Figure 5.5 shows a view of the component in System Canvas.

Figure 5.5. PVBusSlave in System Canvas

PVBusSlave in System Canvas

This component is written in C++.

Ports

Table 5.5 provides a brief description of the ports in the PVBus component.

Table 5.5. PVBus ports

NamePort protocolTypeDescription

pvbus_s

PVBus

Slave

Handles incoming requests from bus masters.

device

PVDevice

Master

Passes on requests for peripheral register accesses to permit the owning component to handle the request.

control

PVBusSlave- Control

Slave

Enables the owning component to control which regions of the device memory are to be handled as RAM/ROM/Device. These settings can be changed dynamically. For example, when a Flash component is being programmed, it can switch to treating reads as Device requests instead of ROM requests.


PVDevice protocol

The PVDevice protocol enables you to implement support for memory-mapped device registers. The two methods are called through the device port on the PVBusSlave to handle bus read/write transactions:

read(pv::ReadTransaction) : pv::Tx_Result

This method permits a device to handle a bus read transaction.

write(pv::WriteTransaction) : pv::Tx_Result

This method permits a device to handle a bus write transaction.

The C++ transaction and Tx_Result classes are described in further detail. See C++ classes.

The PVDevice protocol uses two optional behaviors to differentiate between transaction originating from the processor (loads and stores) and transactions originating from an attached debugger:

optional slave behavior debugRead(pv::ReadTransaction tx) : pv::Tx_Result

If implemented, this method enables the device to handle a debug read transaction.

optional slave behavior debugWrite(pv::WriteTransaction tx) : pv::Tx_Result

If implemented, this method enables the device to handle a debug write transaction.

If the debugRead and debugWrite behaviors are implemented, they are called for all debug transactions. If they are not implemented, debug transactions are handled by the read and write behaviors.

PVBusSlaveControl

setFillPattern(uint32_t fill1, uint32_t fill2)

This sets a two-word alternating fill pattern to be used by uninitialized memory.

setAccess(pv::bus_addr_t base, pv::bus_addr_t top, pv::accessType type, pv::accessMode mode)

This reconfigures handling for a region of memory.

base (inclusive value) and top (exclusive value) specify the address range to configure. Both base and top values must be 4KB page aligned.

type selects what types of bus access must be reconfigured. It can be one of:

  • pv::ACCESSTYPE_READ

  • pv::ACCESSTYPE_WRITE

  • pv::ACCESSTYPE_RW

mode defines how bus accesses must be handled. See pv::accessMode values.

getReadStorage(pv::bus_addr_t address, pv::bus_addr_t *limit) : const uint8_t* getWriteStorage(pv::bus_addr_t address, pv::bus_addr_t *limit) : uint8_t *

These two methods permit you to access the underlying storage that PVBusSlave allocates to implement a region of memory.

The return value is a pointer to the byte that represents the storage corresponding to the address of base.

Memory is stored in blocks of at least 4KB, so the returned pointer can access all memory within a block. If a limit pointer is provided, it is used to return the device address corresponding to the limit of the current block.

The pointer value returned is not guaranteed to remain valid indefinitely. Bus activities, or other calls to the control port, might invalidate the pointer.

provideReadStorage(pv::bus_addr_t base, pv::bus_addr_t limit, const uint8_t * storage), provideReadWriteStorage(pv::bus_addr_t base,pv::bus_addr_t limit, uint8_t * storage)

These methods enable you to allocate blocks of memory that the PVBusSlave can use to manage regions of RAM/ROM. Only use these methods when you require a high degree of control over memory, such as when you require a device to map specific regions of host memory into the simulation.

You must align base (inclusive) and limit (exclusive) values to 4KB page addresses within device address space. The memory region pointed to by storage must be large enough to contain (limit - base) bytes.

After these calls, PVBusSlave controls access to the underlying memory. The owner must call getWriteStorage() before modifying the memory contents and getReadStorage() before reading the memory contents.

pv::accessMode values

The values assigned to pv::accessMode control what happens when an address is accessed. Legal values for the enumeration are:

pv::ACCESSMODE_MEMORY

Act as memory. The PVBusSlave manages the underlying storage to provide 4KB of memory, which can be ROM or RAM, depending on how you configure it to handle bus write transactions.

pv::ACCESSMODE_DEVICE

Act as a device. Requests to the select pages are routed to the PVBusSlave device port, where the necessary behavior can be implemented by the component.

pv::ACCESSMODE_ABORT

Generate bus abort signals for any accesses to this page.

pv::ACCESSMODE_IGNORE

Ignore accesses to this page. Bus read requests return 0.

Parameters

Table 5.6 provides a description of the configuration parameters for the PVBusSlave component.

Table 5.6. PVBusSlave configuration parameters

Parameter nameDescriptionTypeAllowed valueDefault value

size

Addressable size of the device in bytes.

uint64_t

Must be a multiple of 0x1000 (4KB).

0x10000000 (256MB)


Registers

The PVBusSlave component has no registers.

Debug features

The PVBusSlave component has no debug features.

Verification and testing

The PVBusSlave component has been tested as part of the VE example system using VE test suites and by booting operating systems.

Performance

The PVBusSlave component, typically, does not significantly affect the performance of a PV system. However, correct implementation of the PVBusSlave component is critical to the performance of the overall PV system. For example, routing a request to a PVDevice port is slower than letting the PVBusSlave handle the request internally, so you are strongly encouraged to use the PVBusSlave component support for memory-like regions where possible.

Library dependencies

The PVBusSlave component has no dependencies on external libraries.

Copyright © 2008-2013 ARM. All rights reserved.ARM DUI 0423O
Non-ConfidentialID060613