Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  pci_io.h   Sprache: C

 
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_S390_PCI_IO_H
#define _ASM_S390_PCI_IO_H

#ifdef CONFIG_PCI

#include <linux/kernel.h>
#include <linux/slab.h>
#include <asm/pci_insn.h>

/* I/O size constraints */
#define ZPCI_MAX_READ_SIZE 8
#define ZPCI_MAX_WRITE_SIZE 128
#define ZPCI_BOUNDARY_SIZE (1 << 12)
#define ZPCI_BOUNDARY_MASK (ZPCI_BOUNDARY_SIZE - 1)

/* I/O Map */
#define ZPCI_IOMAP_SHIFT  48
#define ZPCI_IOMAP_ADDR_SHIFT  62
#define ZPCI_IOMAP_ADDR_BASE  (1UL << ZPCI_IOMAP_ADDR_SHIFT)
#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1)
#define ZPCI_IOMAP_MAX_ENTRIES       \
 (1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT))
#define ZPCI_IOMAP_ADDR_IDX_MASK      \
 ((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK)

struct zpci_iomap_entry {
 u32 fh;
 u8 bar;
 u16 count;
};

extern struct zpci_iomap_entry *zpci_iomap_start;

#define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT))
#define ZPCI_IDX(addr)        \
 (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT)
#define ZPCI_OFFSET(addr)       \
 ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK)

#define ZPCI_CREATE_REQ(handle, space, len)     \
 ((u64) handle << 32 | space << 16 | len)

#define zpci_read(LENGTH, RETTYPE)      \
static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr) \
{          \
 u64 data;        \
 int rc;         \
          \
 rc = zpci_load(&data, addr, LENGTH);     \
 if (rc)         \
  data = -1ULL;       \
 return (RETTYPE) data;       \
}

#define zpci_write(LENGTH, VALTYPE)      \
static inline void zpci_write_##VALTYPE(VALTYPE val,    \
     const volatile void __iomem *addr) \
{          \
 u64 data = (VALTYPE) val;      \
          \
 zpci_store(addr, data, LENGTH);      \
}

zpci_read(8, u64)
zpci_read(4, u32)
zpci_read(2, u16)
zpci_read(1, u8)
zpci_write(8, u64)
zpci_write(4, u32)
zpci_write(2, u16)
zpci_write(1, u8)

static inline int zpci_write_single(volatile void __iomem *dst, const void *src,
        unsigned long len)
{
 u64 val;

 switch (len) {
 case 1:
  val = (u64) *((u8 *) src);
  break;
 case 2:
  val = (u64) *((u16 *) src);
  break;
 case 4:
  val = (u64) *((u32 *) src);
  break;
 case 8:
  val = (u64) *((u64 *) src);
  break;
 default:
  val = 0;  /* let FW report error */
  break;
 }
 return zpci_store(dst, val, len);
}

static inline int zpci_read_single(void *dst, const volatile void __iomem *src,
       unsigned long len)
{
 u64 data;
 int cc;

 cc = zpci_load(&data, src, len);
 if (cc)
  goto out;

 switch (len) {
 case 1:
  *((u8 *) dst) = (u8) data;
  break;
 case 2:
  *((u16 *) dst) = (u16) data;
  break;
 case 4:
  *((u32 *) dst) = (u32) data;
  break;
 case 8:
  *((u64 *) dst) = (u64) data;
  break;
 }
out:
 return cc;
}

int zpci_write_block(volatile void __iomem *dst, const void *src,
       unsigned long len);

static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max)
{
 int offset = dst & ZPCI_BOUNDARY_MASK;
 int size;

 size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max);
 if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8))
  return size;

 if (size >= 8)
  return 8;
 return rounddown_pow_of_two(size);
}

static inline int zpci_memcpy_fromio(void *dst,
         const volatile void __iomem *src,
         size_t n)
{
 int size, rc = 0;

 while (n > 0) {
  size = zpci_get_max_io_size((u64 __force) src,
         (u64) dst, n,
         ZPCI_MAX_READ_SIZE);
  rc = zpci_read_single(dst, src, size);
  if (rc)
   break;
  src += size;
  dst += size;
  n -= size;
 }
 return rc;
}

static inline int zpci_memcpy_toio(volatile void __iomem *dst,
       const void *src, size_t n)
{
 int size, rc = 0;

 if (!src)
  return -EINVAL;

 while (n > 0) {
  size = zpci_get_max_io_size((u64 __force) dst,
         (u64) src, n,
         ZPCI_MAX_WRITE_SIZE);
  if (size > 8) /* main path */
   rc = zpci_write_block(dst, src, size);
  else
   rc = zpci_write_single(dst, src, size);
  if (rc)
   break;
  src += size;
  dst += size;
  n -= size;
 }
 return rc;
}

static inline int zpci_memset_io(volatile void __iomem *dst,
     int val, size_t count)
{
 u8 *src = kmalloc(count, GFP_KERNEL);
 int rc;

 if (src == NULL)
  return -ENOMEM;
 memset(src, val, count);

 rc = zpci_memcpy_toio(dst, src, count);
 kfree(src);
 return rc;
}

#endif /* CONFIG_PCI */

#endif /* _ASM_S390_PCI_IO_H */

Messung V0.5
C=97 H=94 G=95

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge