Version 2 (modified by 5 years ago) (diff) | ,
---|
MMC device API
A) General principles
This device allows the kernel to access L2 caches, seen as internal peripherals distributed in all clusters, and containing addressable registers used for three different purposes:
- instrumentation,
- L2/L3 software cache coherence.
- addressing error signaling.
This device is called the MMC configuration interface.
The "kernel" API contains defines five command to access those three types of registers, details in section C.
As all L2 caches can be accessed by any thread running in any cluster, a calling thread must get exclusive access to this MMC configuration interface. As these operations consume few cycles, and access conflicts are expected to be rare events, the calling threads can use a busy waiting strategy to get the device busy lock. They do not register in the device waiting queue, and do not use any server thread.
These MMC devices can rise an MMC_IRQ when a bad address is detected for a write transaction. In this case, the error is reported by the ioc_driver_isr() function (ISR stand for Interrupt Service Routine).
To access the various drivers, the IOC device defines a lower-level "driver" API, that is detailed in section D below.
All IOC device structures and access functions are defined in the dev_ioc.c et dev_ioc.h files.
B) Initialisation
The dev_mmc_init( chdev_t * chdev ) function makes the following initializations :
- This function initializes the driver specific fields in the generic MMC device descriptor.
- It initialise the implementation specific MMC driver.
- It links the MMC_IRQ to the local core identified by (lpid == 0), and enables this IRQ.
It must be executed once in any cluster containing an L2 cache.
C) The "kernel" API
All these operations are blocking (return only when the transfer is completed), and use all a polling policy.
- The dev_mmc_inval( xptr_t buffer_xp , uint32_t nbytes ) blocking function invalidates all cache lines covering a memory buffer in the physical address space, defined by the <buf_xp> extended pointer and by the <nbytes> argument. It can be executed by any thread in any cluster, because it uses remote accesses to access both the MMC chdev descriptor, and the MMC configuration interface.
- The dev_mmc_sync( xptr_t buffer_xp , uint32_t nbytes ) blocking function forces the L2 cache to synchronize the L3 cache for all cache lines covering a memory buffer in the physical address space, defined by the <buf_xp> extended pointer and by the <nbytes> argument. It can be executed by any thread in any cluster, because it uses remote accesses to access both the MMC chdev descriptor, and the MMC configuration interface.
- The dev_mmc_error_set( cxy_t cxy , uint32_t index , uint32_t wdata ) function set the value <wdata> in one MMC error register identified by the <cxy> cluster identifier, and by the register <index>. It can be executed by any thread in any cluster, because it uses remote accesses to access both the MMC chdev descriptor, and the MMC configuration interface.
- The dev_mmc_error_get( cxy_t cxy , uint32_t index , uint32_t rdata ) function returns in <rdata> the value contained in one MMC error register identified by the <cxy> cluster identifier, and by the register <index>. It can be executed by any thread in any cluster, because it uses remote accesses to access both the MMC chdev descriptor, and the MMC configuration interface.
- The dev_mmc_instru_get( cxy_t cxy , uint32_t index , uint32_t * rdata ) function returns in <rdata> the value contained in one instrumentation MMC register identified by the <cxy> cluster identifier, and by the register <index>. It can be executed by any thread in any cluster, because it uses remote accesses to access both the MMC chdev descriptor, and the MMC cache configuration interface.
D) The "driver" API
All MMC drivers must define three functions :
- void mmc_driver_init( chdev_t *ioc_chdev )
- void mmc_driver_cmd( xptr_t thread_xp )
- void mmc_driver_isr( chdev_t * ioc_chdev )
The mmc_driver_cmd() function arguments are actually defined in the mmc_command_t structure embedded in the client thread descriptor. One command contains four informations:
- type : operation type (defined below).
- buf_ptr : local pointer on buffer in kernel space (for INVAL/SYNC).
- buf_size : number of bytes in buf_ptr buffer.
- reg_index : register index in MMC peripheral.
- reg_ptr : local pointer on source/destination buffer (for GET/SET).
The set of available instrumentation registers depend on the implementation.
The five command types for the MMC driver(s) are the following:
- MMC_CC_INVAL : invalidate all cache lines covering a given buffer in L2 cache.
- MMC_CC_SYNC : synchronize all cache lines covering a given buffer to L3 cache.
- MMC_ERROR_SET : set a given error signaling register.
- MMC_ERROR_GET : return the content of a given error signaling register.
- MMC_INSTRU_GET : return the content of a given instrumentation register.
The mmc_driver_isr() must acknowledge the MMC_IRQ.