![]() |
![]() |
![]() |
<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.
![]() |
![]() |
![]() |