PCI (wrapper) Module and PCIlib

IO serves PCI requests with it's wrapper module and uses an internal PCIlib extracted from Linux 2.4.x. More...

Find PCI Devices (IPC interface)

Locate PCI devices based on their properties.

We use busno:devfn as PCI device handle.

long l4_io_pci_find_device_component (CORBA_Object _dice_corba_obj, unsigned short vendor_id, unsigned short device_id, l4_io_pdev_t start_at, l4_io_pci_dev_t *pci_dev, CORBA_Server_Environment *_dice_corba_env)
 Locate PCI device according to vendor and device id.
long l4_io_pci_find_slot_component (CORBA_Object _dice_corba_obj, unsigned long bus, unsigned long slot, l4_io_pci_dev_t *pci_dev, CORBA_Server_Environment *_dice_corba_env)
 Locate PCI device according to bus and slot info.
long l4_io_pci_find_class_component (CORBA_Object _dice_corba_obj, unsigned long class_id, l4_io_pdev_t start_at, l4_io_pci_dev_t *pci_dev, CORBA_Server_Environment *_dice_corba_env)
 Locate PCI device according to device class id.

Read PCI Configuration Space (IPC interface)

Read the PCI configuration space portions (byte, word, dword).

long l4_io_pci_read_config_byte_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, long offset, unsigned char *val, CORBA_Server_Environment *_dice_corba_env)
 Read one byte of PCI configuration space.
long l4_io_pci_read_config_word_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, long offset, unsigned short *val, CORBA_Server_Environment *_dice_corba_env)
 Read one word of PCI configuration space.
long l4_io_pci_read_config_dword_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, long offset, l4_uint32_t *val, CORBA_Server_Environment *_dice_corba_env)
 Read one double word of PCI configuration space.

Modify PCI Configuration Space (IPC interface)

Write portions of PCI configuration space (bytes, word, dwords).

Todo:
Maybe check for well-known region that should _not_ be altered. Implementation.


long l4_io_pci_write_config_byte_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, long offset, unsigned char val, CORBA_Server_Environment *_dice_corba_env)
 Write one byte into PCI configuration space.
long l4_io_pci_write_config_word_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, long offset, unsigned short val, CORBA_Server_Environment *_dice_corba_env)
 Write one word into PCI configuration space.
long l4_io_pci_write_config_dword_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, long offset, unsigned long val, CORBA_Server_Environment *_dice_corba_env)
 Write one double word into PCI configuration space.

PCI Device Initialization (IPC interface)

Activation, Busmastering and Power Management (PM).

long l4_io_pci_enable_device_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, CORBA_Server_Environment *_dice_corba_env)
 Initialize device before it's used by a driver.
long l4_io_pci_disable_device_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, CORBA_Server_Environment *_dice_corba_env)
 Finalize device after use.
long l4_io_pci_set_master_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, CORBA_Server_Environment *_dice_corba_env)
 Enable Busmastering for PCI device.
long l4_io_pci_set_power_state_component (CORBA_Object _dice_corba_obj, l4_io_pdev_t pdev, int *state, CORBA_Server_Environment *_dice_corba_env)
 Set power management state for PCI device.

Resource Management Glue for PCIlib

Linux' PCI subsystem _expects_ the new, hierarchical resource management system.

So it has to be mapped to io's flat allocation scheme:

  1. callback requests/releases only for IORESOURCE_BUSY regions
  2. announce top-level I/O memory regions (I/O has to initiate mappings from sigma0 or whomsoever)

Shame: Almost all of this is from Linux 2.4.x.

Test:
krishna: central root resources are essential - io{port,mem}_resource
Test:
krishna: no resources can be released (this only means no HOTPLUGGING is supported)


static struct resource * __request_resource (struct resource *root, struct resource *new)
 Generic resource requests.
struct resource * __request_region (struct resource *parent, unsigned long start, unsigned long n, const char *name)
 Generic region requests.
static int __find_resource (struct resource *root, struct resource *new, unsigned long size, unsigned long min, unsigned long max, unsigned long align, void(*alignf)(void *, struct resource *, unsigned long, unsigned long), void *alignf_data)
 Generic Find empty slot in the resource tree given range and alignment.
int request_resource (struct resource *root, struct resource *new)
 Linux resource requests.
int allocate_resource (struct resource *root, struct resource *new, unsigned long size, unsigned long min, unsigned long max, unsigned long align, void(*alignf)(void *, struct resource *, unsigned long, unsigned long), void *alignf_data)
 Linux resource allocation.

Interrupt Line Request Glue for PCIlib

Mapping of PCIlib interrupt allocation.

int request_irq (unsigned int irq, void(*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *name, void *id)
 Request interrupt.
void free_irq (unsigned int irq, void *id)
 Free Interrupt.

Memory Management Glue for PCIlib

void * kmalloc (size_t size, int gfp)
 Well known kmalloc.
void kfree (const void *obj)
 Well known kfree.
unsigned long FASTCALL (__get_free_pages(unsigned int gfp, unsigned int order))
 Well known __get_free_pages.
void FASTCALL (free_pages(unsigned long addr, unsigned int order))
 Well known free_pages.

PCIlib interface

Todo:
/proc fs has to be optional


int PCI_init (int list)
 PCIlib initialization.
unsigned short PCI_linux_to_io (void *linux_pdev, void *l4io_pdev)
 Info Type Conversion.

Functions

int io_pci_init (int list)
 PCI module initialization.

Detailed Description

IO serves PCI requests with it's wrapper module and uses an internal PCIlib extracted from Linux 2.4.x.

For now I don't know where to draw the red line in the PCI subsystem. Linux drivers make instant use of PCI specific macros/functions. I think many of the structs has to be kept in io and the driver server... we'll see.

Todo:
What about more than 1 PCI bus?

Function Documentation

struct resource* __request_region ( struct resource *  parent,
unsigned long  start,
unsigned long  n,
const char *  name 
) [read]

Generic region requests.

Test:
krishna: As Linux grabs a write_lock(resource_lock), we assume single-threading.

Definition at line 194 of file glue.c.

static struct resource* __request_resource ( struct resource *  root,
struct resource *  new 
) [static, read]

Generic resource requests.

Test:
krishna: it seems as Linux only sorts resources here; exception: PCI conf #1 I/O ports
Test:
krishna: now: top-level announcement and BUSY requests
Todo:
Who is in trouble if region announcement fails (no mapping into io) - we or the driver servers?

Definition at line 135 of file glue.c.

int allocate_resource ( struct resource *  root,
struct resource *  new,
unsigned long  size,
unsigned long  min,
unsigned long  max,
unsigned long  align,
void(*)(void *, struct resource *, unsigned long, unsigned long)  alignf,
void *  alignf_data 
)

Linux resource allocation.

Test:
krishna: As Linux grabs a write_lock(resource_lock), we assume single-threading.

Definition at line 333 of file glue.c.

void FASTCALL ( free_pages(unsigned long addr, unsigned int order)   ) 

Well known free_pages.

Test:
krishna: It's called by pci_free_consistent() and pcibios_get_irq_routing_table() - so do we _really_ need it?
Todo:
implement free_pages using l4rm?! ... for now it's _not_

Definition at line 492 of file glue.c.

unsigned long FASTCALL ( __get_free_pages(unsigned int gfp, unsigned int order)   ) 

Well known __get_free_pages.

Test:
krishna: It's called by pci_alloc_consistent() and pcibios_get_irq_routing_table() - so do we _really_ need it?
Todo:
implement __get_free_pages using l4rm?! ... for now it's _not_

Definition at line 477 of file glue.c.

void free_irq ( unsigned int  irq,
void *  id 
)

Free Interrupt.

It is used to check IRQ availability during pci_enable_device and as we don't really occupy IRQs nothing is done in here.

Definition at line 376 of file glue.c.

int io_pci_init ( int  list  ) 

PCI module initialization.

Returns:
0 on success, negative error code otherwise
Initialize PCIlib and setup base addresses.

Definition at line 307 of file nopci.c.

void* kmalloc ( size_t  size,
int  gfp 
)

Well known kmalloc.

Test:
krishna: Okay, PCIlib never kmallocs with gfp != GFP_KERNEL, so malloc seems sufficient.

Definition at line 454 of file glue.c.

long l4_io_pci_disable_device_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
CORBA_Server_Environment *  _dice_corba_env 
)

Finalize device after use.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device
Return values:
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 254 of file nopci.c.

long l4_io_pci_enable_device_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
CORBA_Server_Environment *  _dice_corba_env 
)

Initialize device before it's used by a driver.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device to be initialized
Return values:
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 236 of file nopci.c.

long l4_io_pci_find_class_component ( CORBA_Object  _dice_corba_obj,
unsigned long  class_id,
l4_io_pdev_t  start_at,
l4_io_pci_dev_t *  pci_dev,
CORBA_Server_Environment *  _dice_corba_env 
)

Locate PCI device according to device class id.

Parameters:
_dice_corba_obj DICE corba object
class_id device class id of PCI device
start_at maybe start at this previously found device
Return values:
pci_dev PCI device found
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 84 of file nopci.c.

long l4_io_pci_find_device_component ( CORBA_Object  _dice_corba_obj,
unsigned short  vendor_id,
unsigned short  device_id,
l4_io_pdev_t  start_at,
l4_io_pci_dev_t *  pci_dev,
CORBA_Server_Environment *  _dice_corba_env 
)

Locate PCI device according to vendor and device id.

Parameters:
_dice_corba_obj DICE corba object
vendor_id vendor id of PCI device
device_id device id of PCI device
start_at maybe start at this previously found device
Return values:
pci_dev PCI device found
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 39 of file nopci.c.

long l4_io_pci_find_slot_component ( CORBA_Object  _dice_corba_obj,
unsigned long  bus,
unsigned long  slot,
l4_io_pci_dev_t *  pci_dev,
CORBA_Server_Environment *  _dice_corba_env 
)

Locate PCI device according to bus and slot info.

Parameters:
_dice_corba_obj DICE corba object
bus bus number
slot slot number
Return values:
pci_dev PCI device found
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 62 of file nopci.c.

long l4_io_pci_read_config_byte_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
long  offset,
unsigned char *  val,
CORBA_Server_Environment *  _dice_corba_env 
)

Read one byte of PCI configuration space.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device
offset configuration register
Return values:
val content of configuration register
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 106 of file nopci.c.

long l4_io_pci_read_config_dword_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
long  offset,
l4_uint32_t *  val,
CORBA_Server_Environment *  _dice_corba_env 
)

Read one double word of PCI configuration space.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device
offset configuration register
Return values:
val content of configuration register
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 150 of file nopci.c.

long l4_io_pci_read_config_word_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
long  offset,
unsigned short *  val,
CORBA_Server_Environment *  _dice_corba_env 
)

Read one word of PCI configuration space.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device
offset configuration register
Return values:
val content of configuration register
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 128 of file nopci.c.

long l4_io_pci_set_master_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
CORBA_Server_Environment *  _dice_corba_env 
)

Enable Busmastering for PCI device.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device to be initialized
Return values:
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 272 of file nopci.c.

long l4_io_pci_set_power_state_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
int *  state,
CORBA_Server_Environment *  _dice_corba_env 
)

Set power management state for PCI device.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device to be initialized
state new PM state (0 == D0, 3 == D3, etc.)
Return values:
state old PM state
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 292 of file nopci.c.

long l4_io_pci_write_config_byte_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
long  offset,
unsigned char  val,
CORBA_Server_Environment *  _dice_corba_env 
)

Write one byte into PCI configuration space.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device
offset configuration register
val configuration register modifier
Return values:
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 172 of file nopci.c.

long l4_io_pci_write_config_dword_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
long  offset,
unsigned long  val,
CORBA_Server_Environment *  _dice_corba_env 
)

Write one double word into PCI configuration space.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device
offset configuration register
val configuration register modifier
Return values:
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 216 of file nopci.c.

long l4_io_pci_write_config_word_component ( CORBA_Object  _dice_corba_obj,
l4_io_pdev_t  pdev,
long  offset,
unsigned short  val,
CORBA_Server_Environment *  _dice_corba_env 
)

Write one word into PCI configuration space.

Parameters:
_dice_corba_obj DICE corba object
pdev PCI device
offset configuration register
val configuration register modifier
Return values:
_dice_corba_env corba environment
Returns:
0 on success, negative error code otherwise

Definition at line 194 of file nopci.c.

unsigned short PCI_linux_to_io ( void *  linux_pdev,
void *  l4io_pdev 
)

Info Type Conversion.

Returns:
concatenated bus number and devfn index

Definition at line 571 of file glue.c.

int request_irq ( unsigned int  irq,
void(*)(int, void *, struct pt_regs *)  handler,
unsigned long  flags,
const char *  name,
void *  id 
)

Request interrupt.

It is used to check IRQ availability during pci_enable_device and will always succeed because is executed on L4IO startup.

Definition at line 363 of file glue.c.

int request_resource ( struct resource *  root,
struct resource *  new 
)

Linux resource requests.

Test:
krishna: As Linux grabs a write_lock(resource_lock), we assume single threading.
Test:
krishna: Try to align MMIO regions before doing real allocation (see also allocate_resource()).

Definition at line 286 of file glue.c.


l4io, written by Christian Helmuth  © 2003 Technische Universitaet Dresden