<iohw.h>

[added with TR18015 and TR18037]


ioindex_t · ioreg

ioand · ioandbuf · ioandbufl · ioandl · iogroup_acquire · iogroup_map · iogroup_release · ioor · ioorbuf · ioorbufl · ioorl · iord · iordbuf · iordbufl · iordl · iowr · iowrbuf · iowrbufl · iowrl · ioxor · ioxorbuf · ioxorbufl · ioxorl


Include the added header <iohw.h> so that you can write low-level I/O hardware drivers in C that are easier to port to different architectures.

Note that the use of this header does not require the additions to the C language mandated by TR18037, which include fixed-point arithmetic and named address spaces.

    /* TYPES */
typedef i-type ioindex_t;
typedef i-type ioreg;

    /* FUNCTIONS (all masked by macros) */
unsigned int iord(ioreg dev);
unsigned long iordl(ioreg dev);
unsigned int iordbuf(ioreg dev, ioindex_t idx);
unsigned long iordbufl(ioreg dev, ioindex_t idx);

void iowr(ioreg dev, unsigned int val);
void iowrl(ioreg dev, unsigned int val);
void iowrbuf(ioreg dev, ioindex_t idx, unsigned int val);
void iowrbufl(ioreg dev, ioindex_t idx, unsigned int val);

void ioor(ioreg dev, unsigned int val);
void ioorl(ioreg dev, unsigned int val);
void ioorbuf(ioreg dev, ioindex_t idx, unsigned int val);
void ioorbufl(ioreg dev, ioindex_t idx, unsigned int val);

void ioand(ioreg dev, unsigned int val);
void ioandl(ioreg dev, unsigned int val);
void ioandbuf(ioreg dev, ioindex_t idx, unsigned int val);
void ioandbufl(ioreg dev, ioindex_t idx, unsigned int val);

void ioxor(ioreg dev, unsigned int val);
void ioxorl(ioreg dev, unsigned int val);
void ioxorbuf(ioreg dev, ioindex_t idx, unsigned int val);
void ioxorbufl(ioreg dev, ioindex_t idx, unsigned int val);

void iogroup_acquire(int group);
void iogroup_release(int group);
void iogroup_map(int group, int direct);

The header <iohw.h> defines two types and a number of functions, all of which are typically masked as macros. You should view this header as a prototype for defining the atomic operations needed to express a low-level I/O hardware driver (thus the root name iohw) that is intended to be reasonably portable C. The facilities in this header are structured around a few basic concepts:

The function names are thus suggestive of specific I/O operations, though they have no required semantics:

Moreover:

Similarly, functions whose name begins with iogroup_ operate on hardware groups:

In this implementation, all functions are masked by macros that follow the pattern:

#define _IOHW_CAT(x, y)    x##_##y   /* expand arguments and paste */
#define iordbuf(dev, idx)  _IOHW_CAT(dev, brd)(idx)

Thus, the first argument (after macro expansion) is pasted onto a suitable suffix to produce the name of the actual function to call. So you can write code such as:

#define KBD         kbd   /* root name of keyboard functions */
#define KBD_STATUS  0     /* first of two adjacent ports */
#define KBD_DATA    1     /* second of two adjacent ports */
#define KBD_DONE    0x80  /* DONE status bit */

extern unsigned int kbd_brd(ioindex_t idx);  /* actual driver */

unsigned int getkbd()
    {   /* read keyboard when ready */
    while ((iordbuf(KBD, KBD_STATUS) & KBD_DONE) == 0)
        ;   /* wait until character is present */
    return (iordbuf(KBD, KBD_DATA));  /* read character and clear DONE */
    }

All actual driver calls will be to the function (or macro) kbd_brd.


See also the Table of Contents and the Index.

Copyright © 1992-2013 by P.J. Plauger. All rights reserved.