![]() |
![]() |
![]() |
<hardware>[added with TR18015]
dynamic_address
· hw_base
· platform_traits
· register_access
· register_buffer
· register_traits
· static_address
Include the added header <hardware>
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 any additions to the C++ language, as none are mandated by TR18015.
#include <iohw.h>
namespace std {
namespace hardware {
class hw_base
{ // define hardware address type
public:
enum access_mode
{ // access modes
random,
read,
read_write,
write
};
enum device_bus
{ // device register widths
device8,
device16,
device32,
device64
};
enum byte_order
{ // endianness
msb_low,
msb_high
};
enum processor_bus
{ // processor bus widths
bus8,
bus16,
bus32,
bus64
};
enum data_bus
{ // type name for data bus
};
enum io_bus
{ // type name for I/O bus
};
enum address_kind
{ // addressing model
is_static,
is_dynamic
};
typedef ::ioreg address_type; // HARDWARE DEPENDENT
};
// TEMPLATE CLASS static_address
template<hw_base::address_type Val>
class static_address
{ // specialization for value of type hw_base::address_type
public:
enum
{ // define value from template parameter
value_ = Val
};
hw_base::address_type value() const
{ // get value of this static address
return (Val);
}
};
// CLASS dynamic_address
class dynamic_address
{ // store dynamic address
public:
dynamic_address(hw_base::address_type address);
: value_(address)
{ // construct from address
}
hw_base::address_type value() const
{ // get value of stored address
return (value_);
}
hw_base::address_type value_;
};
// CLASS platform_traits
class platform_traits
{ // default platform traits (ALL CONTENTS OPTIONAL)
public:
typedef hw_base::address_type address_holder;
typedef hw_base::address_type processor_bus;
enum
{ // platform traits
address_mode,
processor_endianness,
processor_bus_width
};
};
// CLASS register_traits
class register_traits
{ // default register traits (ALL CONTENTS OPTIONAL)
public:
typedef unsigned int value_type;
typedef hw_base::address_type address_holder;
enum
{ // platform traits
address_mode,
access_mode,
endianness,
device_bus_width
};
};
// TEMPLATE CLASS register_access
template<class Reg_traits = register_traits,
class Platform_traits = platform_traits>
class register_access
{ // access wrapper for a hardware I/O register
typedef typename Platform_traits::address_holder Plat_t;
typedef typename Reg_traits::address_holder Reg_t;
public:
typedef typename Reg_traits::value_type value_type;
register_access();
register_access(const Plat_t& plat_addr);
register_access(const Reg_t& reg_addr,
const Plat_t& plat_addr);
// access operators
operator value_type() const;
void operator=(value_type val);
void operator|=(value_type val);
void operator&=(value_type val);
void operator^=(value_type val);
// access functions
value_type read() const;
void write(value_type val);
void or_with(value_type val);
void and_with(value_type val);
void xor_with(value_type val);
};
// TEMPLATE CLASS register_buffer
template<class Reg_traits = register_traits,
class Platform_traits = platform_traits>
class register_buffer
{ // access wrapper for a hardware I/O register
typedef typename Platform_traits::address_holder Plat_t;
typedef typename Reg_traits::address_holder Reg_t;
public:
typedef register_access<Reg_traits, Platform_traits> ref_type;
typedef typename Reg_traits::value_type value_type;
register_buffer();
register_buffer(const Plat_t& plat_addr);
register_buffer(const Reg_t& reg_addr,
const Plat_t& plat_addr);
// access operators
ref_type operator[](ioindex_t idx) const;
// access functions
ref_type get_buffer_element(ioindex_t idx) const;
};
} // namespace hardware
} // namespace std
The header <hardware> defines a number of classes
and templates. You should view
this header as a prototype for defining the C++ interface
to the atomic operations needed to
express a low-level I/O hardware driver.
It supplements the C header <iohw.h>.
The facilities in this header are structured around a few basic concepts:
access_mode supplies the enumeration
constants needed to describes the properties of I/O addresses.
The member type address_type is used in other classes as the type
of I/O addresses.platform_traits supplies the enumeration
constants needed to describes the properties of an I/O bus in general.
The member type address_holder is used in other classes as the type
of I/O addresses. Class register_traits performs
a similar role for specific ports on an I/O bus.static_address wraps an I/O
address whose value is known at translation time,
while class dynamic_address
waps one that might nit be known until program execution.register_access supplies the member
functions that call actual drivers to perform I/O operations. Similarly,
class register_buffer supplies register_access
objects for different elements of a hardware buffer.In this
implementation, all operations
are performed by calling one of the five low-level functions
(defined in <iohw.h>):
iordbuf(_IOHW_NAME, idx)
iowrbuf(_IOHW_NAME, idx, val)
ioorbuf(_IOHW_NAME, idx, val)
ioandbuf(_IOHW_NAME, idx, val)
ioxorbuf(_IOHW_NAME, idx, val)
If the macro _IOHW_NAME is not defined when the header
<hardware> is first included, the macro is defined
as hardware. Further, the code assumes that all I/O
occurs within a flat address space, where the effective port address
is simply the sum of the platform address, the register address, and
the index into a specific buffer.
So you can write code such as:
#define KBD 0xffe0 // base address of keyboard ports
#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 hardware_brd(ioindex_t idx); // actual driver
typedef std::hardware::register_buffer<> buffer_t;
buffer_t::value_type getkbd()
{ // read keyboard when ready
buffer_t status(KBD, KBD_STATUS);
buffer_t data(KBD, KBD_DATA);
while ((status.read() & KBD_DONE) == 0)
; // wait until character is present
return (data); // read character and clear DONE
}
All actual driver calls will be to the function
(or macro) hardware_brd.
See also the Table of Contents and the Index.
Copyright © 1992-2006 by P.J. Plauger. All rights reserved.
![]() |
![]() |
![]() |