next up previous contents
Next: 4.1.3 Event tables Up: 4.1 Input/Output Previous: 4.1.1.2 Freezing IO banks

4.1.2 Input/Output for plain users

Users may access IO ports using these wrappers.

<Off IO bank for users. >= (U->)
ENTRY class off_uIOBank : public off_uHWCompResource {
public:
};
Defines off_uIOBank (links are to index).

<Off IO port for users. >= (U->)
ENTRY class off_uIOPort: public off_uHWResUnit {
public:
};
Defines off_uIOPort (links are to index).

<Off IO bank dependencies. >+= (U->) [<-D]
#include <prtl/ex.h>            // for ENTRY

<Off IO port dependencies. >+= (U->) [<-D]
#include <prtl/ex.h>            // for ENTRY

\subsection{Input/Output \cpp{} source files}

I/O bank code is kept in hw/IOBank.h and hw/IOBank.C.

<IOBank.h*>=
<Read the literate code instead warning. >
#ifndef __OFF_IOBANK_H
#define __OFF_IOBANK_H 1

<Off IO bank dependencies. >

#ifdef __KERNEL__
<Off IO bank. >
#endif // __KERNEL__
<Off IO bank for users. >
#endif // __OFF_IOBANK_H

<IOBank.C*>=
<Read the literate code instead warning. >

#include <hw/IOBank.h>           // Exported interface
<Off IO bank implementation dependencies. >

<Off IO bank static members. >

<off_IOBank::alloc and free implementation. >
<off_IOBank::start implementation. >
<off_IOBank::get_iosize implementation. >
<off_IOBank::get_url implementation. >
<off_IOBank::nameof implementation. >
<off_IOBank::cleanup implementation. >
<off_IOBank::copy_state implementation. >
<off_IOBank::restore_state implementation. >
<off_IOBank::operator= implementation. >
<off_IOBank::can_melt implementation. >
<off_IOBank::freeze_state implementation. >
<off_IOBank::melt_state implementation. >
<off_IOBank::get_navigator implementation. >
<off_IOBank::get_inspector implementation. >
<off_IOBank::operator<< implementation. >

I/O port code is found at hw/IOPort.h and hw/IOPort.C

<IOPort.h*>=
<Read the literate code instead warning. >
#ifndef __OFF_IOPORT_H
#define __OFF_IOPORT_H 1

<Off IO port dependencies. >

#ifdef __KERNEL__
<Off IO port. >
#endif // __KERNEL__
<Off IO port for users. >

#endif // __OFF_IOPORT_H

<IOPort.C*>=
<Read the literate code instead warning. >

#include <hw/IOPort.h>          // Exported interface.
<Off IO port implementation dependencies. >

<Off IO port static members. >

<off_IOPort::off_IOPort implementation. >
<off_IOPort::operator new/delete implementation. >
<off_IOPort::copy_state implementation. >
<off_IOPort::restore_state implementation. >
<off_IOPort::get_url_holder implementation. >
<off_IOPort::get_inspector implementation. >

The IO port allocator can be found in hw/IOAllocator.h and hw/IOAllocator.C.

<IOAllocator.h*>=
<Read the literate code instead warning. >
#ifndef __OFF_IO_ALLOCATOR_H
#define __OFF_IO_ALLOCATOR_H 1

<Off IO port allocator dependencies. >

#ifdef __KERNEL__

<Off linkable IO port. >
<Off IO port allocator. >
#endif // __KERNEL__

#endif // __OFF_IO_ALLOCATOR_H

<IOAllocator.C*>=
<Read the literate code instead warning. >

#include <hw/IOAllocator.h>     // exported interface

<Off IO port allocator static members. >

\subsection{IO banks for ix86 based architectures}

Machine dependent IO banks are simpler than, although similar to, machine dependent memory banks.

<Off machine dependent IO bank. >= (U->)
class off_mdepIOBank {
private:
  // Things known by the boot procedure about this IO bank
  //
  unsigned8_t  io_flags;        // capabilities (IF_IOM,IF_USR)
  unsigned8_t  io_mat;          // Mean IO time. (not very useful).
  vm_size_t    io_iosz[OFF_NIOSZ_MAX]; // IO port sizes. 
public:
  unsigned8_t get_flags(void) const { return io_flags; }
  vm_offset_t get_first(void) const { return 0; }
  vm_offset_t get_last(void)  const { return OFF_MDEP_NIOP_MAX; }
  vm_offset_t get_nports(void)const { return OFF_MDEP_NIOP_MAX; }
  vm_offset_t get_mat(void)   const { return io_mat; }
  vm_size_t   get_iosz(natural_t llimit) const {return io_iosz[llimit]; }
  static vm_size_t get_iosz(void)         { return 1; }
  
  <Other public methods of off_mdepIOBank. >
 };
Defines off_mdepIOBank (links are to index).

<Off machine dependent IO bank dependencies. >= (U-> U->) [D->]
#include <klib/limits.h>        // for OFF_NIOSZ_MAX
#include <flux/types.h>         // for boolean_t natural_t et al.

On Intels, we have support for just a single IO bank.

<Other public methods of off_mdepIOBank. >= (<-U) [D->]
static natural_t how_many(void)         { return 1; }

The number of IO ports and allocatable IO ports are also fixed for Intel machines.

<Off machine dependent IO bank size. >= (U->)
const vm_offset_t OFF_MDEP_NIOP_MAX=65535;
const vm_offset_t OFF_MDEP_NAIOP_MAX=32;

Nowadays, the constructor of off_mdepIOBank will set predefined values no matter the bank number.

<Other public methods of off_mdepIOBank. >+= (<-U) [<-D->]
off_mdepIOBank(natural_t number);

<off_mdepIOBank::off_mdepIOBank implementation. >= (U->)
// Returns machine dependent information about the IO bank #n
off_mdepIOBank::off_mdepIOBank(natural_t number)
{
  (void)number;
  io_flags=OFF_IF_IOM|OFF_IF_USR;
  io_mat=128;
  io_iosz[0]=1;
  io_iosz[1]=2;
  io_iosz[3]=4;
  io_iosz[4]=0;
}

We have to define the flags used before.

<Off machine dependent IO bank flag bits. >= (U->)
// flag bits for off_mdepIOBanks.
// They are compatible with resource flag bits. 
const unsigned8_t OFF_IF_USR    = 0x10; // User-level io?
const unsigned8_t OFF_IF_IOM    = 0x20; // Supports IO mapping?

Defines OFF_IF_IOM, OFF_IF_USR (links are to index).

There are a couple of static routine which must still be implemented, those doing actual I/O.

<Other public methods of off_mdepIOBank. >+= (<-U) [<-D]
static unsigned8_t  in_b(const vm_size_t p)    { return inb(p); }
static void         out_b(const vm_size_t p, 
                          const unsigned8_t b) { outb(p,b); }
static unsigned16_t in_w(const vm_size_t p)    { return inw(p); }
static void         out_w(const vm_size_t p,
                          const unsigned16_t b){ outw(p,b); }
static unsigned32_t in_l(const vm_size_t p)    { return inl(p); }
static void         out_l(const vm_size_t p,
                          const unsigned32_t b){ outl(p,b); }
static unsigned64_t in_q(const vm_size_t p)    { return inq(p); }
static void         out_q(const vm_size_t p,
                          const unsigned64_t b){ outq(p,b); }

<Off machine dependent IO bank dependencies. >+= (U-> U->) [<-D]
#include <flux/machine/pio.h>   // for inb, outb, et al.

\subsubsection{Machine dependent IO banks \cpp{} source files }

Machine dependent IO banks are kept in hw/mdep/mIOBank.h and hw/mdep/mIOBank.C.

<mdep mIOBank.h*>=
<Read the literate code instead warning. >
#ifndef __OFF_MDEP_IOBANK_H
#define __OFF_MDEP_IOBANK_H 1

<Off machine dependent IO bank dependencies. >

<Off machine dependent IO bank flag bits. >
<Off machine dependent IO bank size. >
#ifdef __KERNEL__
<Off machine dependent IO bank. >
#endif

#endif // __OFF_MDEP_IOBANK_H

<mdep mIOBank.C*>=
<Read the literate code instead warning. >

#include <hw/mdep/mIOBank.h>      // Exported interface.
<Off machine dependent IO bank dependencies. >

<off_mdepIOBank::off_mdepIOBank implementation. >

%% --------------------------------------------------------------

\section{Traps and interrupts}  


Francisco J. Ballesteros
1998-05-25