next up previous contents
Next: 4.1.1.2 Freezing IO banks Up: 4.1.1 IO banks Previous: 4.1.1 IO banks

4.1.1.1 IO Bank navigation

The IO bank navigator gives uniform access to IO banks. It is implemented with the generic bank navigator defined in section [*].

IO bank navigators are created dynamically. Now we can implement this method:

<Other public methods of off_IOBank. >+= (<-U) [<-D->]
// Returns a navigator for IOBanks. 
off_Navigator *get_navigator(void);

<off_IOBank::get_navigator implementation. >= (U->)
// Returns a navigator for IOBanks. 
off_Navigator *off_IOBank::get_navigator(void)
{ 
   assert(valid()); 
   return new off_BankNav<off_IOBank,off_IOPort>(*this); 
}

<Off IO bank navigator dependencies. >= (U->)
#include <hw/IOBank.h>          // for IOBank.
#include <hw/IOPort.h>          // for IOPort.
#include <hw/bnav.h>            // for off_BankNav et al.

<Off IO bank dependencies. >+= (U->) [<-D->]
#include <klib/nav.h>           // for off_Navigator et al.

<Off IO bank implementation dependencies. >+= (U->) [<-D->]
#include <hw/ionav.h>

\subsubsection{IO bank inspection}

The IO bank inspector's attribute array looks like this:

<Off IO bank inspector attribute array initializer. >= (U->)
{{ OFF_STR_ATTR , "name",     &off_IOBank::nameof },
 { OFF_STR_ATTR,  "class",    &off_IOBank::kindof },
 { OFF_ID_ATTR,   "dom",      &off_IOBank::get_domain },
 { OFF_ID_ATTR,   "id",       &off_IOBank::get_id },
 { OFF_STR_ATTR,  "url",      &off_IOBank::get_url },
 { OFF_STR_ATTR,  "provides", &off_IOBank::nameof },
 { OFF_STR_ATTR,  NULL,       NULL    },    // no requeriments. 
 // IO bank specific attributes.
 { OFF_BOOL_ATTR, "doesiomap",  &off_IOBank::is_iomapable },
 { OFF_BOOL_ATTR, "doesuserio", &off_IOBank::is_usrio},

// If this is not commented out it gets an internal gcc compiler error #40
// { OFF_NAT_ATTR,  "nports",     &off_IOBank::get_nports},
// { OFF_NAT_ATTR,  "first",      &off_IOBank::get_first},
// { OFF_NAT_ATTR,  "last",       &off_IOBank::get_last},
// { OFF_NAT_ATTR,  "mat",        &off_IOBank::get_mat},
// { OFF_NAT_ATTR,  "iosize",     &off_IOBank::get_iosize},
 { OFF_NULL_ATTR, NULL,       NULL } } // End of attribute list. 

<Off IO bank inspector attribute array length. >= (U->)
const int OFF_IOINSP_NATTR=9;   // not counting final NULL attr.

We have implemented neither get_url nor nameof yet.

<Other public methods of off_IOBank. >+= (<-U) [<-D->]
// Get the IO bank URL.
const char *get_url(void);
// Returns the IO bank name. 
const char *nameof(void);

Given this attribute list, the IO bank inspector is defined as follows

<Off IO bank inspector. >= (U->)
// An IO bank inspector.
//
class off_IOBankInsp : public off_Inspector {
private:
  static off_attr_t io_attrs[OFF_IOINSP_NATTR+1]; // for final NULL attr.
public:
  off_IOBankInsp(off_IOBank *iobank) : 
     off_Inspector (iobank, io_attrs, OFF_IOINSP_NATTR)
  { assert(iobank && iobank->valid()); }
};

Defines off_IOBankInsp (links are to index).

Where the attribute array is shared.

<Off IO bank inspector static members. >= (U->)
// inspector attributes for iobanks.
off_attr_t off_IOBankInsp::io_attrs[OFF_IOINSP_NATTR+1] =
               <Off IO bank inspector attribute array initializer. > 
;

Every time get_inspector is called, a new inspector is created. The user should delete it whenever it is no longer needed.

<Other public methods of off_IOBank. >+= (<-U) [<-D->]
// Returns an inspector for IOBanks. 
off_Inspector *get_inspector(void);

<off_IOBank::get_inspector implementation. >= (U->)
// Returns an inspector for IOBanks. 
off_Inspector *off_IOBank::get_inspector(void)
{ 
  assert(valid());
  return new off_IOBankInsp(this);
}

The URL for an IO bank is that of its node with io.html appended. We use a new member, a character array initialized the very first time it is needed.

<Other private members of off_IOBank. >+= (<-U) [<-D->]
static char *io_url;             // URL for this IO bank.

Initially it is empty.

<Off IO bank static members. >= (U->)
char *off_IOBank::io_url=NULL;  // URL for this IO bank.

<off_IOBank::get_url implementation. >= (U->)
// Get the IO bank URL.
const char *off_IOBank::get_url(void)
{
  assert(valid());
  if (!io_url){
    io_url=new char[strlen(nd.get_url())+strlen(OFF_IOBANK_URL)+1]; //+1 for \0
    if (io_url){
      strcpy(io_url,nd.get_url());
      strcat(io_url,OFF_IOBANK_URL);
    }
  }
  return io_url;
}

Where he have to define the relative URL for IO banks.

<Off source code urls. >= [D->]
const char OFF_IOBANK_URL[]="/io.html";

<Off IO bank dependencies. >+= (U->) [<-D->]
#include <klib/url.h>           // for OFF_IOBANK_URL

<Off IO bank implementation dependencies. >+= (U->) [<-D->]
#include <string.h>             // for strcat strdup et al
#include <node/Node.h>          // for nd

The name for an IO bank is that of its node complemented with a little suffix. The implementation is almost the same of get_url, however, the name is not shared among IO banks in the same node (i.e. it is not static).

<off_IOBank::nameof implementation. >= (U->)
// Returns the IO bank name. 
const char *off_IOBank::nameof(void)
{
  assert(valid());
  if (!io_name){
    io_name = new char[strlen(nd.nameof())+strlen("/iobank")+9]; // for N...N\0
    if (io_name){
      char number[9];
      strcpy(io_name,nd.nameof());
      strcat(io_name,"/iobank");
      sprintf(number,"%08x",(natural_t)get_id());
      strcat(io_name,number);
    }
  }
  return io_name;
}

<Other private members of off_IOBank. >+= (<-U) [<-D]
char *io_name;                  // name for this IO bank.

<Initialize other aggregate members of off_IOBank. >+= (<-U) [<-D]
io_name(NULL)

\subsubsection{IO port inspection} IO ports cannot be navigated. They can be inspected though. The attribute array of their inspectors is as follows.

<Off IO port inspector attribute array initializer. >= (U->)
{{ OFF_STR_ATTR , "name",     &off_IOPort::nameof },
 { OFF_STR_ATTR,  "class",    &off_IOPort::kindof },
 { OFF_ID_ATTR,   "dom",      &off_IOPort::get_domain },
 { OFF_ID_ATTR,   "id",       &off_IOPort::get_id },
 { OFF_STR_ATTR,  "url",      &off_IOPort::get_url },
 { OFF_STR_ATTR,  "provides", &off_IOPort::nameof },
 { OFF_STR_ATTR,  NULL,       NULL    },    // no requeriments. 
 // Page frame specific attributes.
 { OFF_ID_ATTR,   "container",   &off_IOPort::get_iobank },
 { OFF_NULL_ATTR, NULL,       NULL } } // End of attribute list. 

<Off IO port inspector attribute array length. >= (U->)
const int OFF_IOPINSP_NATTR=8;   // not counting final NULL attr.

We need get_rurl and get_url_holder for ports to support ResUnit::get_url.

<Other protected methods of off_IOPort. >= (<-U) [D->]
// Get the port URL.
virtual const char *get_rurl(void) const { return OFF_IOPORT_URL; }
// Returns the port name. 
virtual char *&get_url_holder(void);

Where we must define the relative URL for ports.

<Off source code urls. >+= [<-D]
const char OFF_IOPORT_URL[]="#IOPort";
Defines OFF_IOPORT_URL (links are to index).

<Off IO port dependencies. >+= (U->) [<-D->]
#include <klib/url.h>           // for OFF_IOPORT_URL

<Off IO port implementation dependencies. >= (U->) [D->]
#include <stdio.h>              // for sprintf et al

URLs are the same for all ports.

<Other private members of off_IOPort. >= (<-U)
static char *io_url;             // URL for this page frame.

<off_IOPort::get_url_holder implementation. >= (U->)
char *&off_IOPort::get_url_holder(void) {  return io_url; }

Initially it is empty.

<Off IO port static members. >= (U->)
char *off_IOPort::io_url=NULL;  // URL for IO ports.

Given the attribute list shown above, a IO port inspector is defined as follows.

<Off IO port inspector. >= (U->)
// A IO port inspector.
//
class off_IOPortInsp : public off_Inspector {
private:
  static off_attr_t io_attrs[OFF_IOPINSP_NATTR+1]; // for final NULL attr.
public:
  off_IOPortInsp(off_IOPort *iop) : 
     off_Inspector(iop, io_attrs, OFF_IOPINSP_NATTR)
  {}
};

Defines off_IOPortInsp (links are to index).

Where the attribute array is shared.

<Off IO port inspector static members. >= (U->)
// inspector attributes for IO ports.
off_attr_t off_IOPortInsp::io_attrs[OFF_IOPINSP_NATTR+1] =
               <Off IO port inspector attribute array initializer. > 
;

Every time get_inspector is called, a new inspector is created. The user should delete it whenever it is no longer needed.

<Other public methods of off_IOPort. >+= (<-U) [<-D]
// Returns an inspector for IOPorts.
off_Inspector *get_inspector(void);

<off_IOPort::get_inspector implementation. >= (U->)
// Returns an inspector for IOPorts.
off_Inspector *off_IOPort::get_inspector(void)
{ 
 return new off_IOPortInsp(this);
}

<Off IO port implementation dependencies. >+= (U->) [<-D]
#include <hw/ionav.h>           // for off_IOPortInsp et al

\subsubsection{IO bank navigation and inspection \cpp{} source files}

The navigation and inspection code for IO banks is kept in hw/ionav.h.

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

<Off IO bank navigator dependencies. >

<Off IO bank inspector attribute array length. >
<Off IO port inspector attribute array length. >
#ifdef __KERNEL__
<Off IO bank inspector. >
<Off IO port inspector. >
#endif

#endif // __OFF_IOBANK_NAV_H

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

#include <hw/ionav.h>           // Exported interface.

<Off IO bank inspector static members. >
<Off IO port inspector static members. >

\subsection{Frozen IO}


next up previous contents
Next: 4.1.1.2 Freezing IO banks Up: 4.1.1 IO banks Previous: 4.1.1 IO banks
Francisco J. Ballesteros
1998-05-25