Line 17... |
Line 17... |
more details.
|
more details.
|
|
|
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
with this program. If not, see <http://www.gnu.org/licenses/>. */
|
with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
/* This program is commented throughout in a fashion suitable for processing
|
|
with Doxygen. */
|
|
|
/* This is functional simulation of any external peripheral. It's job is to
|
/* This is functional simulation of any external peripheral. It's job is to
|
* trap accesses in a specific range, so that the simulator can drive an
|
* trap accesses in a specific range, so that the simulator can drive an
|
* external device.
|
* external device.
|
*/
|
*/
|
|
|
#include <stdlib.h>
|
/* Autoconf and/or portability configuration */
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "config.h"
|
#include "config.h"
|
|
|
#ifdef HAVE_INTTYPES_H
|
/* System includes */
|
#include <inttypes.h>
|
#include <stdlib.h>
|
#endif
|
#include <stdio.h>
|
|
|
#include "or1ksim.h"
|
/* Package includes */
|
#include "port.h"
|
|
#include "arch.h"
|
#include "arch.h"
|
#include "abstract.h"
|
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "pic.h"
|
#include "abstract.h"
|
#include "vapi.h"
|
#include "toplevel-support.h"
|
#include "sched.h"
|
#include "sim-cmd.h"
|
#include "channel.h"
|
|
#include "debug.h"
|
|
|
/*! State associated with the generic device. */
|
|
struct dev_generic
|
|
{
|
|
|
|
/* Info about a particular transaction */
|
|
|
|
enum
|
|
{ /* Direction of the access */
|
|
GENERIC_READ,
|
|
GENERIC_WRITE
|
|
} trans_direction;
|
|
|
#include "generic.h"
|
enum
|
|
{ /* Size of the access */
|
|
GENERIC_BYTE,
|
|
GENERIC_HW,
|
|
GENERIC_WORD
|
|
} trans_size;
|
|
|
|
uint32_t value; /* The value to read/write */
|
|
|
DEFAULT_DEBUG_CHANNEL( generic );
|
/* Configuration */
|
|
|
|
int enabled; /* Device enabled */
|
|
int byte_enabled; /* Byte R/W allowed */
|
|
int hw_enabled; /* Half word R/W allowed */
|
|
int word_enabled; /* Full word R/W allowed */
|
|
char *name; /* Name of the device */
|
|
oraddr_t baseaddr; /* Base address of device */
|
|
uint32_t size; /* Address space size (bytes) */
|
|
|
|
};
|
|
|
|
|
/* Generic read and write upcall routines. Note the address here is absolute,
|
/* Generic read and write upcall routines. Note the address here is absolute,
|
not relative to the device. */
|
not relative to the device. */
|
|
|
static unsigned long int ext_read( unsigned long int addr,
|
static unsigned long int
|
unsigned long int mask )
|
ext_read (unsigned long int addr, unsigned long int mask)
|
{
|
{
|
return config.ext.read_up( config.ext.class_ptr, addr, mask );
|
return config.ext.read_up( config.ext.class_ptr, addr, mask );
|
|
|
} /* ext_callback() */
|
} /* ext_callback() */
|
|
|
|
|
/* Generic read and write upcall routines. Note the address here is absolute,
|
/* Generic read and write upcall routines. Note the address here is absolute,
|
not relative to the device. */
|
not relative to the device. */
|
|
|
static void ext_write( unsigned long int addr,
|
static void
|
unsigned long int mask,
|
ext_write (unsigned long int addr,
|
unsigned long int value )
|
unsigned long int mask, unsigned long int value)
|
{
|
{
|
config.ext.write_up( config.ext.class_ptr, addr, mask, value );
|
config.ext.write_up( config.ext.class_ptr, addr, mask, value );
|
|
|
} /* ext_callback() */
|
} /* ext_callback() */
|
|
|
|
|
/* I/O routines. Note that address is relative to start of address space. */
|
/* I/O routines. Note that address is relative to start of address space. */
|
|
|
static uint8_t generic_read_byte( oraddr_t addr,
|
static uint8_t
|
void *dat )
|
generic_read_byte (oraddr_t addr, void *dat)
|
{
|
{
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
|
|
if( !config.ext.class_ptr ) {
|
if (!config.ext.class_ptr)
|
|
{
|
fprintf( stderr, "Byte read from disabled generic device\n" );
|
fprintf( stderr, "Byte read from disabled generic device\n" );
|
return 0;
|
return 0;
|
}
|
}
|
else if( addr >= dev->size ) {
|
else if (addr >= dev->size)
|
TRACE( "Generic device \"%s\": Byte read out of range (addr %"
|
{
|
PRIxADDR ")\n", dev->name, addr );
|
fprintf (stderr, "Byte read out of range for generic device %s "
|
|
"(addr %" PRIxADDR ")\n", dev->name, addr);
|
return 0;
|
return 0;
|
}
|
}
|
else {
|
else
|
|
{
|
unsigned long fulladdr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long fulladdr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long wordaddr = fulladdr & 0xfffffffc;
|
unsigned long wordaddr = fulladdr & 0xfffffffc;
|
unsigned long bitoff = (fulladdr & 0x00000003) << 3;
|
unsigned long bitoff = (fulladdr & 0x00000003) << 3;
|
|
|
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
Line 109... |
Line 136... |
#endif
|
#endif
|
}
|
}
|
} /* generic_read_byte() */
|
} /* generic_read_byte() */
|
|
|
|
|
static void generic_write_byte( oraddr_t addr,
|
static void
|
uint8_t value,
|
generic_write_byte (oraddr_t addr, uint8_t value, void *dat)
|
void *dat )
|
|
{
|
{
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
|
|
if( !config.ext.class_ptr ) {
|
if (!config.ext.class_ptr)
|
|
{
|
fprintf( stderr, "Byte write to disabled generic device\n" );
|
fprintf( stderr, "Byte write to disabled generic device\n" );
|
}
|
}
|
else if( addr >= dev->size ) {
|
else if (addr >= dev->size)
|
TRACE( "Generic device \"%s\": Byte write out of range (addr %"
|
{
|
PRIxADDR ")\n", dev->name, addr );
|
fprintf (stderr, "Byte written out of range for generic device %s "
|
|
"(addr %" PRIxADDR ")\n", dev->name, addr);
|
}
|
}
|
else {
|
else
|
|
{
|
unsigned long fulladdr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long fulladdr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long wordaddr = fulladdr & 0xfffffffc;
|
unsigned long wordaddr = fulladdr & 0xfffffffc;
|
unsigned long bitoff = (fulladdr & 0x00000003) << 3;
|
unsigned long bitoff = (fulladdr & 0x00000003) << 3;
|
|
|
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
Line 140... |
Line 169... |
ext_write( wordaddr, mask, wordval );
|
ext_write( wordaddr, mask, wordval );
|
}
|
}
|
} /* generic_write_byte() */
|
} /* generic_write_byte() */
|
|
|
|
|
static uint16_t generic_read_hw( oraddr_t addr,
|
static uint16_t
|
void *dat )
|
generic_read_hw (oraddr_t addr, void *dat)
|
{
|
{
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
|
|
if( !config.ext.class_ptr ) {
|
if (!config.ext.class_ptr)
|
|
{
|
fprintf( stderr, "Half word read from disabled generic device\n" );
|
fprintf( stderr, "Half word read from disabled generic device\n" );
|
return 0;
|
return 0;
|
}
|
}
|
else if( addr >= dev->size ) {
|
else if (addr >= dev->size)
|
TRACE( "Generic device \"%s\": Half word read out of range (addr %"
|
{
|
PRIxADDR ")\n", dev->name, addr );
|
fprintf (stderr, "Half-word read out of range for generic device %s "
|
|
"(addr %" PRIxADDR ")\n", dev->name, addr);
|
return 0;
|
return 0;
|
}
|
}
|
else if( addr & 0x1 ) {
|
else if (addr & 0x1)
|
fprintf( stderr, "Unaligned half word read from 0x" PRIxADDR " ignored\n",
|
{
|
|
fprintf (stderr,
|
|
"Unaligned half word read from 0x%" PRIxADDR " ignored\n",
|
addr );
|
addr );
|
return 0;
|
return 0;
|
}
|
}
|
else {
|
else
|
|
{
|
unsigned long fulladdr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long fulladdr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long wordaddr = fulladdr & 0xfffffffc;
|
unsigned long wordaddr = fulladdr & 0xfffffffc;
|
unsigned long bitoff = (fulladdr & 0x00000003) << 3;
|
unsigned long bitoff = (fulladdr & 0x00000003) << 3;
|
|
|
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
Line 179... |
Line 213... |
#endif
|
#endif
|
}
|
}
|
} /* generic_read_hw() */
|
} /* generic_read_hw() */
|
|
|
|
|
static void generic_write_hw( oraddr_t addr,
|
static void
|
uint16_t value,
|
generic_write_hw (oraddr_t addr, uint16_t value, void *dat)
|
void *dat )
|
|
{
|
{
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
|
|
if( !config.ext.class_ptr ) {
|
if (!config.ext.class_ptr)
|
|
{
|
fprintf( stderr, "Half word write to disabled generic device\n" );
|
fprintf( stderr, "Half word write to disabled generic device\n" );
|
}
|
}
|
else if( addr >= dev->size ) {
|
else if (addr >= dev->size)
|
TRACE( "Generic device \"%s\": Half word write out of range (addr %"
|
{
|
PRIxADDR ")\n", dev->name, addr );
|
fprintf (stderr, "Half-word written out of range for generic device %s "
|
|
"(addr %" PRIxADDR ")\n", dev->name, addr);
|
}
|
}
|
else if( addr & 0x1 ) {
|
else if (addr & 0x1)
|
fprintf( stderr, "Unaligned half word write to 0x" PRIxADDR " ignored\n",
|
{
|
addr );
|
fprintf (stderr,
|
|
"Unaligned half word write to 0x%" PRIxADDR " ignored\n", addr);
|
}
|
}
|
else{
|
else
|
|
{
|
unsigned long fulladdr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long fulladdr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long wordaddr = fulladdr & 0xfffffffc;
|
unsigned long wordaddr = fulladdr & 0xfffffffc;
|
unsigned long bitoff = (fulladdr & 0x00000003) << 3;
|
unsigned long bitoff = (fulladdr & 0x00000003) << 3;
|
|
|
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
Line 214... |
Line 251... |
ext_write( wordaddr, mask, wordval );
|
ext_write( wordaddr, mask, wordval );
|
}
|
}
|
} /* generic_write_hw() */
|
} /* generic_write_hw() */
|
|
|
|
|
static uint32_t generic_read_word( oraddr_t addr,
|
static uint32_t
|
void *dat )
|
generic_read_word (oraddr_t addr, void *dat)
|
{
|
{
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
|
|
if( !config.ext.class_ptr ) {
|
if (!config.ext.class_ptr)
|
|
{
|
fprintf( stderr, "Full word read from disabled generic device\n" );
|
fprintf( stderr, "Full word read from disabled generic device\n" );
|
return 0;
|
return 0;
|
}
|
}
|
else if( addr >= dev->size ) {
|
else if (addr >= dev->size)
|
TRACE( "Generic device \"%s\": Full word read out of range (addr %"
|
{
|
PRIxADDR ")\n", dev->name, addr );
|
fprintf (stderr, "Full word read out of range for generic device %s "
|
|
"(addr %" PRIxADDR ")\n", dev->name, addr);
|
return 0;
|
return 0;
|
}
|
}
|
else if( 0 != (addr & 0x3) ) {
|
else if (0 != (addr & 0x3))
|
fprintf( stderr, "Unaligned full word read from 0x" PRIxADDR " ignored\n",
|
{
|
|
fprintf (stderr,
|
|
"Unaligned full word read from 0x%" PRIxADDR " ignored\n",
|
addr );
|
addr );
|
return 0;
|
return 0;
|
}
|
}
|
else {
|
else
|
|
{
|
unsigned long wordaddr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long wordaddr = (unsigned long int)(addr + dev->baseaddr);
|
|
|
return (uint32_t) ext_read( wordaddr, 0xffffffff );
|
return (uint32_t) ext_read( wordaddr, 0xffffffff );
|
}
|
}
|
} /* generic_read_word() */
|
} /* generic_read_word() */
|
|
|
|
|
static void generic_write_word( oraddr_t addr,
|
static void
|
uint32_t value,
|
generic_write_word (oraddr_t addr, uint32_t value, void *dat)
|
void *dat )
|
|
{
|
{
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
|
|
if( !config.ext.class_ptr ) {
|
if (!config.ext.class_ptr)
|
|
{
|
fprintf( stderr, "Full word write to disabled generic device\n" );
|
fprintf( stderr, "Full word write to disabled generic device\n" );
|
}
|
}
|
else if( addr >= dev->size ) {
|
else if (addr >= dev->size)
|
TRACE( "Generic device \"%s\": Full word write out of range (addr %"
|
{
|
PRIxADDR ")\n", dev->name, addr );
|
fprintf (stderr, "Full word written out of range for generic device %s "
|
|
"(addr %" PRIxADDR ")\n", dev->name, addr);
|
}
|
}
|
else if( 0 != (addr & 0x3) ) {
|
else if (0 != (addr & 0x3))
|
fprintf( stderr, "Unaligned full word write to 0x" PRIxADDR " ignored\n",
|
{
|
addr );
|
fprintf (stderr,
|
|
"Unaligned full word write to 0x%" PRIxADDR " ignored\n", addr);
|
}
|
}
|
else{
|
else
|
|
{
|
unsigned long wordaddr = (unsigned long int)(addr + dev->baseaddr);
|
unsigned long wordaddr = (unsigned long int)(addr + dev->baseaddr);
|
|
|
ext_write( wordaddr, 0xffffffff, value );
|
ext_write( wordaddr, 0xffffffff, value );
|
}
|
}
|
} /* generic_write_word() */
|
} /* generic_write_word() */
|
|
|
|
|
/* Reset is a null operation */
|
/* Reset is a null operation */
|
|
|
static void generic_reset( void *dat )
|
static void
|
|
generic_reset (void *dat)
|
{
|
{
|
return;
|
return;
|
|
|
} /* generic_reset() */
|
} /* generic_reset() */
|
|
|
|
|
/* Status report can only advise of configuration. */
|
/* Status report can only advise of configuration. */
|
|
|
static void generic_status( void *dat )
|
static void
|
|
generic_status (void *dat)
|
{
|
{
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
struct dev_generic *dev = (struct dev_generic *)dat;
|
|
|
PRINTF( "\nGeneric device \"%s\" at 0x%" PRIxADDR ":\n", dev->name,
|
PRINTF( "\nGeneric device \"%s\" at 0x%" PRIxADDR ":\n", dev->name,
|
dev->baseaddr );
|
dev->baseaddr );
|
PRINTF( " Size 0x%" PRIx32 "\n", dev->size );
|
PRINTF( " Size 0x%" PRIx32 "\n", dev->size );
|
|
|
if( dev->byte_enabled ) {
|
if (dev->byte_enabled)
|
|
{
|
PRINTF( " Byte R/W enabled\n" );
|
PRINTF( " Byte R/W enabled\n" );
|
}
|
}
|
|
|
if( dev->hw_enabled ) {
|
if (dev->hw_enabled)
|
|
{
|
PRINTF( " Half word R/W enabled\n" );
|
PRINTF( " Half word R/W enabled\n" );
|
}
|
}
|
|
|
if( dev->word_enabled ) {
|
if (dev->word_enabled)
|
|
{
|
PRINTF( " Full word R/W enabled\n" );
|
PRINTF( " Full word R/W enabled\n" );
|
}
|
}
|
|
|
PRINTF( "\n" );
|
PRINTF( "\n" );
|
|
|
} /* generic_status() */
|
} /* generic_status() */
|
|
|
|
|
/* Functions to set configuration */
|
/* Functions to set configuration */
|
|
|
static void generic_enabled( union param_val val,
|
static void
|
void *dat )
|
generic_enabled (union param_val val, void *dat)
|
{
|
{
|
((struct dev_generic *)dat)->enabled = val.int_val;
|
((struct dev_generic *)dat)->enabled = val.int_val;
|
|
|
} /* generic_enabled() */
|
} /* generic_enabled() */
|
|
|
|
|
static void generic_byte_enabled( union param_val val,
|
static void
|
void *dat )
|
generic_byte_enabled (union param_val val, void *dat)
|
{
|
{
|
((struct dev_generic *)dat)->byte_enabled = val.int_val;
|
((struct dev_generic *)dat)->byte_enabled = val.int_val;
|
|
|
} /* generic_byte_enabled() */
|
} /* generic_byte_enabled() */
|
|
|
|
|
static void generic_hw_enabled( union param_val val,
|
static void
|
void *dat )
|
generic_hw_enabled (union param_val val, void *dat)
|
{
|
{
|
((struct dev_generic *)dat)->hw_enabled = val.int_val;
|
((struct dev_generic *)dat)->hw_enabled = val.int_val;
|
|
|
} /* generic_hw_enabled() */
|
} /* generic_hw_enabled() */
|
|
|
|
|
static void generic_word_enabled( union param_val val,
|
static void
|
void *dat )
|
generic_word_enabled (union param_val val, void *dat)
|
{
|
{
|
((struct dev_generic *)dat)->word_enabled = val.int_val;
|
((struct dev_generic *)dat)->word_enabled = val.int_val;
|
|
|
} /* generic_word_enabled() */
|
} /* generic_word_enabled() */
|
|
|
|
|
static void generic_name( union param_val val,
|
static void
|
void *dat )
|
generic_name (union param_val val, void *dat)
|
{
|
{
|
((struct dev_generic *)dat)->name = strdup( val.str_val );
|
((struct dev_generic *)dat)->name = strdup( val.str_val );
|
|
|
if( !((struct dev_generic *)dat)->name ) {
|
if (!((struct dev_generic *) dat)->name)
|
|
{
|
fprintf(stderr, "Peripheral 16450: name \"%s\": Run out of memory\n",
|
fprintf(stderr, "Peripheral 16450: name \"%s\": Run out of memory\n",
|
val.str_val );
|
val.str_val );
|
exit(-1);
|
exit(-1);
|
}
|
}
|
} /* generic_name() */
|
} /* generic_name() */
|
|
|
|
|
static void generic_baseaddr( union param_val val,
|
static void
|
void *dat )
|
generic_baseaddr (union param_val val, void *dat)
|
{
|
{
|
((struct dev_generic *)dat)->baseaddr = val.addr_val;
|
((struct dev_generic *)dat)->baseaddr = val.addr_val;
|
|
|
} /* generic_baseaddr() */
|
} /* generic_baseaddr() */
|
|
|
|
|
static void generic_size( union param_val val,
|
static void
|
void *dat )
|
generic_size (union param_val val, void *dat)
|
{
|
{
|
((struct dev_generic *)dat)->size = val.int_val;
|
((struct dev_generic *)dat)->size = val.int_val;
|
|
|
} /* generic_size() */
|
} /* generic_size() */
|
|
|
|
|
/* Start of new generic section */
|
/* Start of new generic section */
|
|
|
static void *generic_sec_start()
|
static void *
|
|
generic_sec_start ()
|
{
|
{
|
struct dev_generic *new =
|
struct dev_generic *new =
|
(struct dev_generic *)malloc( sizeof( struct dev_generic ));
|
(struct dev_generic *)malloc( sizeof( struct dev_generic ));
|
|
|
if( 0 == new) {
|
if (0 == new)
|
|
{
|
fprintf( stderr, "Generic peripheral: Run out of memory\n" );
|
fprintf( stderr, "Generic peripheral: Run out of memory\n" );
|
exit( -1 );
|
exit( -1 );
|
}
|
}
|
|
|
/* Default names */
|
/* Default names */
|
Line 394... |
Line 447... |
} /* generic_sec_start() */
|
} /* generic_sec_start() */
|
|
|
|
|
/* End of new generic section */
|
/* End of new generic section */
|
|
|
static void generic_sec_end( void *dat)
|
static void
|
|
generic_sec_end (void *dat)
|
{
|
{
|
struct dev_generic *generic = (struct dev_generic *)dat;
|
struct dev_generic *generic = (struct dev_generic *)dat;
|
struct mem_ops ops;
|
struct mem_ops ops;
|
|
|
/* Give up if not enabled, or if size is zero, or if no access size is
|
/* Give up if not enabled, or if size is zero, or if no access size is
|
enabled. */
|
enabled. */
|
|
|
if( !generic->enabled ) {
|
if (!generic->enabled)
|
|
{
|
free( dat );
|
free( dat );
|
return;
|
return;
|
}
|
}
|
|
|
if( 0 == generic->size ) {
|
if (0 == generic->size)
|
|
{
|
fprintf( stderr, "Generic peripheral \"%s\" has size 0: ignoring",
|
fprintf( stderr, "Generic peripheral \"%s\" has size 0: ignoring",
|
generic->name );
|
generic->name );
|
free( dat );
|
free( dat );
|
return;
|
return;
|
}
|
}
|
|
|
if( !generic->byte_enabled &&
|
if( !generic->byte_enabled &&
|
!generic->hw_enabled &&
|
!generic->hw_enabled && !generic->word_enabled)
|
!generic->word_enabled ) {
|
{
|
fprintf( stderr, "Generic peripheral \"%s\" has no access: ignoring",
|
fprintf( stderr, "Generic peripheral \"%s\" has no access: ignoring",
|
generic->name );
|
generic->name );
|
free( dat );
|
free( dat );
|
return;
|
return;
|
}
|
}
|
Line 429... |
Line 485... |
* come from the peripheral if desired.
|
* come from the peripheral if desired.
|
*/
|
*/
|
|
|
memset( &ops, 0, sizeof( struct mem_ops ));
|
memset( &ops, 0, sizeof( struct mem_ops ));
|
|
|
if( generic->byte_enabled ) {
|
if (generic->byte_enabled)
|
|
{
|
ops.readfunc8 = generic_read_byte;
|
ops.readfunc8 = generic_read_byte;
|
ops.writefunc8 = generic_write_byte;
|
ops.writefunc8 = generic_write_byte;
|
ops.read_dat8 = dat;
|
ops.read_dat8 = dat;
|
ops.write_dat8 = dat;
|
ops.write_dat8 = dat;
|
}
|
}
|
|
|
if( generic->hw_enabled ) {
|
if (generic->hw_enabled)
|
|
{
|
ops.readfunc16 = generic_read_hw;
|
ops.readfunc16 = generic_read_hw;
|
ops.writefunc16 = generic_write_hw;
|
ops.writefunc16 = generic_write_hw;
|
ops.read_dat16 = dat;
|
ops.read_dat16 = dat;
|
ops.write_dat16 = dat;
|
ops.write_dat16 = dat;
|
}
|
}
|
|
|
if( generic->word_enabled ) {
|
if (generic->word_enabled)
|
|
{
|
ops.readfunc32 = generic_read_word;
|
ops.readfunc32 = generic_read_word;
|
ops.writefunc32 = generic_write_word;
|
ops.writefunc32 = generic_write_word;
|
ops.read_dat32 = dat;
|
ops.read_dat32 = dat;
|
ops.write_dat32 = dat;
|
ops.write_dat32 = dat;
|
}
|
}
|
Line 462... |
Line 521... |
} /* generic_sec_end() */
|
} /* generic_sec_end() */
|
|
|
|
|
/* Register a generic section. */
|
/* Register a generic section. */
|
|
|
void reg_generic_sec(void)
|
void
|
|
reg_generic_sec (void)
|
{
|
{
|
struct config_section *sec = reg_config_sec( "generic",
|
struct config_section *sec = reg_config_sec( "generic",
|
generic_sec_start,
|
generic_sec_start,
|
generic_sec_end );
|
generic_sec_end );
|
|
|