wiki:ioc_device_api

Version 5 (modified by alain, 4 years ago) (diff)

--

IOC device API

A) General principles

This device allows the kernel to access various external mass storage peripherals such as a magnetic hard disk or a SD card, that can store blocks of data in a linear array of sectors indexed by a simple lba (logic block address).

The block size is supposed to be 512 bytes.

It supports a first user API, used by the user-level system calls, implementing two command types : the READ and WRITE operations move a given number of contiguous blocks between the block device and a kernel memory buffer.

The I/O operation is blocking for the calling thread, but it is not done by the client thread itself. The general scenario is detailed below:

  1. When a client thread request an I/O operation, the request is registered in the ioc_command_t structure embedded in the client thread descriptor, and the client thread registers itself in the waiting queue rooted in the IOC chdev. Then the client thread blocks on the THREAD_BLOCKED_IO condition, and deschedules.
  2. The DEV server thread attached to the IOC device descriptor handles all commands registered in the IOC device waiting queue. For each pending request, it calls the IOC driver CMD (command) function to ask the hardware device to do the transfer. Then, the server thread blocks on the THREAD_BLOCKED_ISR condition, and deschedules.
  3. When the I/O operation completed, the IOC driver ISR (Interrupt Service Routine) signaling completion reactivates the server thread.
  4. The server thread reactivates the client thread, and handle the next request in the IOC waiting queue, or reschedules if the queue is empty.

Note : According to the scheduling policy, the DEV thread has an higher priority than any user thread, but it is not selected when the associated waiting queue is empty.

  • it get a free WTI mailbox from the client cluster WTI allocator.
  • it enables the WTI IRQ on the client cluster ICU and update the WTI interrupt vector.
  • it access the PIC to link the WTI mailbox to the IOC IRQ.
  • it builds the command descriptor stored in the thread descriptor.
  • it access the PIC to unlink the IOC IRQ.
  • it disables the WTI IRQ in the client cluster ICU and reset the interrupt vector entry.
  • it releases the WTI mailbox to the client cluster WTI allocator.

Most IOC device implementation have a DMA capability, but some implementations, such as the RDK (Ram Disk) implementation does not use DMA, and don't use an IRQ, as the data transfers are directly executed by the driver CMD function.

To access the various drivers, this FBF device defines a lower-level driver API, that must be implemented by all drivers.

All IOC access functions are defined in the dev_ioc.c et dev_ioc.h files.

B) Initialisation

C) User API

1) void dev_ioc_init( xptr_t xp_dev )

The void dev_ioc_init() function makes two initializations :

  • it initialises the IOC specific fields of the chdev descriptor.
  • it initialises the implementation specific IOC hardware device and associated data structures if required.

It can be executed in another cluster than the cluster containing the IOC device descriptor or the IOC hardware device itself. The <xp_dev> argument is an extended pointer on the IOC device descriptor.

1) void dev_ioc_read( char * buffer , uint32_t lba , uint32_t count )

This blocking function try to tranfer one or several contiguous blocks of data from the block device to a memory buffer. The calling thread is registered in the device pending request queue, and descheduled, waiting on transfer completion. It is re-activared by the IRQ signaling completion. It must be called in the client cluster. The <buffer> argument is... The <lba> argument is the first block index in block device. The <count> argument is the number of blocks to move.

2) void dev_ioc_write( char * buffer , uint32_t lba , uint32_t count )

This blocking function try to tranfer one or several contiguous blocks of data from a memory buffer to the block device. The calling thread is actually registered in the device pending request queue, and descheduled, waiting on transfer completion. It is re-activared by the IRQ signaling completion. It must be called in the client cluster. The <buffer> argument is... The <lba> argument is the first block index in block device. The <count> argument is the number of blocks to move.