updated mvme162 code from Misha (mms@eiscathq.irf.se)

This commit is contained in:
Joel Sherrill
1995-08-01 15:33:39 +00:00
parent 4a6e64d276
commit c6fb8e9096
8 changed files with 628 additions and 629 deletions

View File

@@ -36,7 +36,7 @@ standard release.
Port Description Port Description
---------------- ----------------
The port was done using already existing ports to the M68020 boards, The port was done using already existing ports to the M68020 boards,
DMV152 and MVME136. DMV152 and MVME136.
The host system was SUN/Solaris 2.3, and the cross-development The host system was SUN/Solaris 2.3, and the cross-development
environment consisted of Free Software Foundation (FSF)'s GNU C environment consisted of Free Software Foundation (FSF)'s GNU C
@@ -74,8 +74,8 @@ configured for the board in use
monitors_vector_table = (m68k_isr *)0xFFE00000; monitors_vector_table = (m68k_isr *)0xFFE00000;
was made to point to the power-up location of MVME162 interrupt vector was made to point to the power-up location of MVME162 interrupt vector
table. table.
- The shutdown is a temporary solution. To exit cleanly, it has to disable - The shutdown is a temporary solution. To exit cleanly, it has to disable
all enabled interrupts and restore the board to its power-up status. all enabled interrupts and restore the board to its power-up status.
Presently this is not done satisfactorily, as a result, the board needs Presently this is not done satisfactorily, as a result, the board needs
@@ -112,7 +112,15 @@ parser;
crossgcc mailing list crossgcc mailing list
- to FSF and Cygnus Support for great free software; - to FSF and Cygnus Support for great free software;
What's new
----------
- 28.07.95 BSP adjusted to rtems-3.2.0.
- Now console driver uses interrupts on receive (ring buffer
code lifted with thanks from the IDP BSP next door (../idp))
- both front-panel serial interfaces are supported
- serious bug in timer interrupts fixed
- interrupt test tm27 now supported
+----------------------------------+-------------------------------+ +----------------------------------+-------------------------------+
| Dr. Mikhail (Misha) Savitski | Voice : +46-980-79162 | | Dr. Mikhail (Misha) Savitski | Voice : +46-980-79162 |
| Software Systems Engineer | Fax : +46-980-79161 | | Software Systems Engineer | Fax : +46-980-79161 |

View File

@@ -32,14 +32,13 @@
#include <clockdrv.h> #include <clockdrv.h>
#define MS_COUNT 1000 /* T2's countdown constant (1 ms) */ #define MS_COUNT 1000 /* T2's countdown constant (1 ms) */
#define CLOCK_INT_LEVEL 6 /* T2's interrupt level */ #define CLOCK_INT_LEVEL 6 /* T2's interrupt level */
rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ rtems_unsigned32 Clock_isrs; /* ISRs until next tick */
volatile rtems_unsigned32 Clock_driver_ticks; volatile rtems_unsigned32 Clock_driver_ticks; /* ticks since initialization */
/* ticks since initialization */
rtems_isr_entry Old_ticker; rtems_isr_entry Old_ticker;
rtems_device_driver Clock_initialize( rtems_device_driver Clock_initialize(
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
void *pargp, void *pargp,
@@ -50,38 +49,36 @@ rtems_device_driver Clock_initialize(
Install_clock( Clock_isr ); Install_clock( Clock_isr );
} }
void ReInstall_clock( clock_isr ) void ReInstall_clock(rtems_isr_entry clock_isr)
rtems_isr_entry clock_isr;
{ {
rtems_unsigned32 isrlevel; rtems_unsigned32 isrlevel;
rtems_interrupt_disable( isrlevel ); rtems_interrupt_disable( isrlevel );
(void) set_vector( clock_isr, (VECTOR_BASE >> 28) * 0x10 + 0x9, 1 ); (void) set_vector( clock_isr, VBR0 * 0x10 + 0x9, 1 );
rtems_interrupt_enable( isrlevel ); rtems_interrupt_enable( isrlevel );
} }
void Install_clock( clock_isr ) void Install_clock(rtems_isr_entry clock_isr )
rtems_isr_entry clock_isr;
{ {
Clock_driver_ticks = 0; Clock_driver_ticks = 0;
Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000; Clock_isrs = BSP_Configuration.microseconds_per_tick / 1000;
if ( BSP_Configuration.ticks_per_timeslice ) { if ( BSP_Configuration.ticks_per_timeslice ) {
Old_ticker = (rtems_isr_entry) Old_ticker =
set_vector( clock_isr, (VECTOR_BASE >> 28) * 0x10 + 0x9, 1 ); (rtems_isr_entry) set_vector( clock_isr, VBR0 * 0x10 + 0x9, 1 );
lcsr->vector_base |= MASK_INT; /* unmask VMEchip2 interrupts */
lcsr->vector_base = 0x67800000; /* set vb, enable interrupts */ lcsr->to_ctl = 0xE7; /* prescaler to 1 MHz (see Appendix A1) */
lcsr->to_ctl = 0xE7; /* prescaler to 1 MHz (see Appendix A1) */
lcsr->timer_cmp_2 = MS_COUNT; lcsr->timer_cmp_2 = MS_COUNT;
lcsr->timer_cnt_2 = 0; /* clear counter */ lcsr->timer_cnt_2 = 0; /* clear counter */
lcsr->board_ctl |= 0x700; /* increment, reset-on-compare, clear-ovfl-cnt */ lcsr->board_ctl |= 0x700; /* increment, reset-on-compare, and */
/* clear-overflow-cnt */
lcsr->intr_level[0] |= CLOCK_INT_LEVEL * 0x10; /* set int level */ lcsr->intr_level[0] |= CLOCK_INT_LEVEL * 0x10; /* set int level */
lcsr->intr_ena |= 0x02000000; /* enable tick timer 2 interrupt */ lcsr->intr_ena |= 0x02000000; /* enable tick timer 2 interrupt */
atexit( Clock_exit ); atexit( Clock_exit );
} }
} }

View File

@@ -24,18 +24,33 @@
#include <rtems.h> #include <rtems.h>
#include "console.h" #include "console.h"
#include "bsp.h" #include "bsp.h"
#include "ringbuf.h"
/* console_initialize Ring_buffer_t Buffer[2];
*
* This routine initializes the console IO driver. /*
* * Interrupt handler for receiver interrupts
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
*/ */
rtems_isr C_Receive_ISR(rtems_vector_number vector)
{
register int ipend, port;
ZWRITE0(1, 0x38); /* reset highest IUS */
ipend = ZREAD(1, 3); /* read int pending from A side */
if (ipend == 0x04) port = 0; /* channel B intr pending */
else if (ipend == 0x20) port = 1; /* channel A intr pending */
else return;
Ring_buffer_Add_character(&Buffer[port], ZREADD(port));
if (ZREAD(port, 1) & 0x70) { /* check error stat */
ZWRITE0(port, 0x30); /* reset error */
}
}
rtems_device_driver console_initialize( rtems_device_driver console_initialize(
rtems_device_major_number major, rtems_device_major_number major,
rtems_device_minor_number minor, rtems_device_minor_number minor,
@@ -44,122 +59,82 @@ rtems_device_driver console_initialize(
rtems_unsigned32 *status rtems_unsigned32 *status
) )
{ {
int i;
/*
* Initialise receiver interrupts on both ports
*/
for (i = 0; i <= 1; i++) {
Ring_buffer_Initialize( &Buffer[i] );
ZWRITE(i, 2, SCC_VECTOR);
ZWRITE(i, 10, 0);
ZWRITE(i, 1, 0x10); /* int on all Rx chars or special condition */
ZWRITE(i, 9, 8); /* master interrupt enable */
}
set_vector(C_Receive_ISR, SCC_VECTOR, 1); /* install ISR for ports A and B */
mcchip->vector_base = 0;
mcchip->gen_control = 2; /* MIEN */
mcchip->SCC_int_ctl = 0x13; /* SCC IEN, IPL3 */
*status = RTEMS_SUCCESSFUL; *status = RTEMS_SUCCESSFUL;
} }
/*
/* is_character_ready * Non-blocking char input
*
* This routine returns TRUE if a character is available.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
*/ */
rtems_boolean is_character_ready( rtems_boolean char_ready(int port, char *ch)
char *ch
)
{ {
rtems_unsigned8 rr_0; if ( Ring_buffer_Is_empty( &Buffer[port] ) )
return FALSE;
Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 ); Ring_buffer_Remove_character( &Buffer[port], *ch );
if ( !(rr_0 & RR_0_RX_DATA_AVAILABLE) )
return( FALSE ); return TRUE;
Z8x30_READ_DATA( CONSOLE_DATA, *ch );
return(TRUE);
}
/* inbyte
*
* This routine reads a character from the SCC.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* Return values:
* character read from SCC
*/
char inbyte( void )
{
rtems_unsigned8 rr_0;
char ch;
while ( 1 ) {
Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 );
if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) != 0 )
break;
}
Z8x30_READ_DATA( CONSOLE_DATA, ch );
return ch;
}
/* outbyte
*
* This routine transmits a character out the SCC. It supports
* XON/XOFF flow control.
*
* Input parameters:
* ch - character to be transmitted
*
* Output parameters: NONE
*/
void outbyte(
char ch
)
{
rtems_unsigned8 rr_0;
char flow_control;
while ( 1 ) {
Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 );
if ( (rr_0 & RR_0_TX_BUFFER_EMPTY) != 0 )
break;
}
while ( 1 ) {
Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 );
if ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 )
break;
Z8x30_READ_DATA( CONSOLE_DATA, flow_control );
if ( flow_control == XOFF )
do {
do {
Z8x30_READ_CONTROL( CONSOLE_CONTROL, RR_0, rr_0 );
} while ( (rr_0 & RR_0_RX_DATA_AVAILABLE) == 0 );
Z8x30_READ_DATA( CONSOLE_DATA, flow_control );
} while ( flow_control != XON );
}
Z8x30_WRITE_DATA( CONSOLE_DATA, ch );
} }
/* /*
* __read -- read bytes from the serial port. Ignore fd, since * Block on char input
* we only have stdin.
*/ */
int __read( char char_wait(int port)
int fd,
char *buf,
int nbytes
)
{ {
int i = 0; unsigned char tmp_char;
while ( !char_ready(port, &tmp_char) );
return tmp_char;
}
/*
* This routine transmits a character out the SCC. It no longer supports
* XON/XOFF flow control.
*/
void char_put(int port, char ch)
{
while (1) {
if (ZREAD0(port) & TX_BUFFER_EMPTY) break;
}
ZWRITED(port, ch);
}
/*
* Map port A (1) to stdin, stdout, and stderr.
* Map everything else to port B (0).
*/
int __read(int fd, char *buf, int nbytes)
{
int i, port;
if ( fd <= 2 ) port = 1;
else port = 0;
for (i = 0; i < nbytes; i++) { for (i = 0; i < nbytes; i++) {
*(buf + i) = inbyte(); *(buf + i) = char_wait(port);
if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) { if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
(*(buf + i++)) = '\n'; (*(buf + i++)) = '\n';
(*(buf + i)) = 0; (*(buf + i)) = 0;
@@ -170,24 +145,22 @@ int __read(
} }
/* /*
* __write -- write bytes to the serial port. Ignore fd, since * Map port A (1) to stdin, stdout, and stderr.
* stdout and stderr are the same. Since we have no filesystem, * Map everything else to port B (0).
* open will only return an error.
*/ */
int __write( int __write(int fd, char *buf, int nbytes)
int fd,
char *buf,
int nbytes
)
{ {
int i; int i, port;
if ( fd <= 2 ) port = 1;
else port = 0;
for (i = 0; i < nbytes; i++) { for (i = 0; i < nbytes; i++) {
if (*(buf + i) == '\n') { if (*(buf + i) == '\n') {
outbyte ('\r'); char_put (port, '\r');
} }
outbyte (*(buf + i)); char_put (port, *(buf + i));
} }
return (nbytes); return (nbytes);
} }

View File

@@ -29,23 +29,30 @@ extern "C" {
#include <rtems.h> #include <rtems.h>
#include <iosupp.h> #include <iosupp.h>
#include <z8530.h>
/* /*
// Following defines must reflect the setup of the particular MVME162 * Following defines must reflect the setup of the particular MVME162
//----------------------------------- */
*/
#define GROUP_BASE_ADDRESS 0x0000F200 #define GROUP_BASE_ADDRESS 0x0000F200
#define BOARD_BASE_ADDRESS 0x00000000 #define BOARD_BASE_ADDRESS 0xFFFF0000
/* Base for local interrupters' vectors (with enable bit set) */ /* Base for local interrupters' vectors (with enable bit set) */
#define VECTOR_BASE 0x67800000
#define MASK_INT 0x00800000
#define VBR0 0x6
#define VBR1 0x7
/* RAM limits */ /* RAM limits */
#define RAM_START 0x00100000 #define RAM_START 0x00100000
#define RAM_END 0x00200000 #define RAM_END 0x00200000
/* /*
//----------------------------------- * ----------------------------------
*/ */
static volatile struct lcsr {
typedef volatile struct lcsr_regs {
unsigned long slave_adr[2]; unsigned long slave_adr[2];
unsigned long slave_trn[2]; unsigned long slave_trn[2];
unsigned long slave_ctl; unsigned long slave_ctl;
@@ -73,80 +80,135 @@ static volatile struct lcsr {
unsigned long intr_clear; unsigned long intr_clear;
unsigned long intr_level[4]; unsigned long intr_level[4];
unsigned long vector_base; unsigned long vector_base;
} *lcsr = (void *) 0xFFF40000; } lcsr_regs;
#define USE_CHANNEL_A 1 /* 1 = use channel A for console */ #define lcsr ((lcsr_regs * const) 0xFFF40000)
#define USE_CHANNEL_B 0 /* 1 = use channel B for console */
/* Constants */ typedef volatile struct mcchip_regs {
#if (USE_CHANNEL_A == 1) unsigned char chipID;
#define CONSOLE_CONTROL 0xFFF45005 unsigned char chipREV;
#define CONSOLE_DATA 0xFFF45007 unsigned char gen_control;
#elif (USE_CHANNEL_B == 1) unsigned char vector_base;
#define CONSOLE_CONTROL 0xFFF45001
#define CONSOLE_DATA 0xFFF45003 unsigned long timer_cmp_1;
#endif unsigned long timer_cnt_1;
unsigned long timer_cmp_2;
unsigned long timer_cnt_2;
unsigned char LSB_prescaler_count;
unsigned char prescaler_clock_adjust;
unsigned char time_ctl_2;
unsigned char time_ctl_1;
unsigned char time_int_ctl_4;
unsigned char time_int_ctl_3;
unsigned char time_int_ctl_2;
unsigned char time_int_ctl_1;
unsigned char dram_err_int_ctl;
unsigned char SCC_int_ctl;
unsigned char time_ctl_4;
unsigned char time_ctl_3;
unsigned short DRAM_space_base;
unsigned short SRAM_space_base;
unsigned char DRAM_size;
unsigned char DRAM_SRAM_opt;
unsigned char SRAM_size;
unsigned char reserved;
unsigned char LANC_error;
unsigned char reserved1;
unsigned char LANC_int_ctl;
unsigned char LANC_berr_ctl;
unsigned char SCSI_error;
unsigned char general_inputs;
unsigned char MVME_162_version;
unsigned char SCSI_int_ctl;
unsigned long timer_cmp_3;
unsigned long timer_cnt_3;
unsigned long timer_cmp_4;
unsigned long timer_cnt_4;
unsigned char bus_clk;
unsigned char PROM_acc_time_ctl;
unsigned char FLASH_acc_time_ctl;
unsigned char ABORT_int_ctl;
unsigned char RESET_ctl;
unsigned char watchdog_timer_ctl;
unsigned char acc_watchdog_time_base_sel;
unsigned char reserved2;
unsigned char DRAM_ctl;
unsigned char reserved4;
unsigned char MPU_status;
unsigned char reserved3;
unsigned long prescaler_count;
} mcchip_regs;
#define mcchip ((mcchip_regs * const) 0xFFF42000)
/*----------------------------------------------------------------*/
/*
* SCC Z8523(0) defines and macros
* -------------------------------
* Prototypes for the low-level serial io are also included here,
* because such stuff is bsp-specific (yet). The function bodies
* are in console.c
*/
enum {portB, portA};
rtems_boolean char_ready(int port, char *ch);
char char_wait(int port);
void char_put(int port, char ch);
#define TX_BUFFER_EMPTY 0x04
#define RX_DATA_AVAILABLE 0x01
#define SCC_VECTOR 0x40
typedef volatile struct scc_regs {
unsigned char pad1;
volatile unsigned char csr;
unsigned char pad2;
volatile unsigned char buf;
} scc_regs;
#define scc ((scc_regs * const) 0xFFF45000)
#define ZWRITE0(port, v) (scc[port].csr = (unsigned char)(v))
#define ZREAD0(port) (scc[port].csr)
#define ZREAD(port, n) (ZWRITE0(port, n), (scc[port].csr))
#define ZREADD(port) (scc[port].buf)
#define ZWRITE(port, n, v) (ZWRITE0(port, n), ZWRITE0(port, v))
#define ZWRITED(port, v) (scc[port].buf = (unsigned char)(v))
/*----------------------------------------------------------------*/
/* /*
// The following registers are located in the VMEbus short * The following registers are located in the VMEbus short
// IO space and respond to address modifier codes $29 and $2D. * IO space and respond to address modifier codes $29 and $2D.
// On FORCE SPARC CPU use address gcsr_vme and device /dev/vme16d32. * On FORCE CPU use address gcsr_vme and device /dev/vme16d32.
*/ */
static volatile struct gcsr { typedef volatile struct gcsr_regs {
unsigned char chip_revision; unsigned char chip_revision;
unsigned char chip_id; unsigned char chip_id;
unsigned char lmsig; unsigned char lmsig;
unsigned char board_scr; unsigned char board_scr;
unsigned short gpr[6]; unsigned short gpr[6];
} *gcsr_vme = (void *) (GROUP_BASE_ADDRESS + BOARD_BASE_ADDRESS), } gcsr_regs;
*gcsr = (void *) 0xFFF40100;
static volatile unsigned short *ipio[6] = { (unsigned short *) 0xFFF58000, #define gcsr_vme ((gcsr_regs * const) (GROUP_BASE_ADDRESS + BOARD_BASE_ADDRESS))
(unsigned short *) 0xFFF58100, #define gcsr ((gcsr_regs * const) 0xFFF40100)
(unsigned short *) 0xFFF58200,
(unsigned short *) 0xFFF58300,
(unsigned short *) 0xFFF58400,
(unsigned short *) 0xFFF58500
};
static volatile unsigned short *ipid[6] = { (unsigned short *) 0xFFF58080,
(unsigned short *) 0xFFF58180,
(unsigned short *) 0xFFF58280,
(unsigned short *) 0xFFF58380,
(unsigned short *) 0xFFF58080,
(unsigned short *) 0xFFF58280
};
static volatile struct ipic_space {
struct sing {
unsigned short io_space[64];
unsigned short id_space[32];
unsigned short id_reptd[32];
} single[4];
struct twin {
unsigned short io_space[128];
unsigned short io_reptd[128];
} twin[2];
} *ipic_space = (void *) 0xFFF58000;
static volatile struct ipic_csr {
unsigned char chip_id;
unsigned char chip_rev;
unsigned char res[2];
unsigned short a_31_16_base;
unsigned short b_31_16_base;
unsigned short c_31_16_base;
unsigned short d_31_16_base;
unsigned char a_23_16_size;
unsigned char b_23_16_size;
unsigned char c_23_16_size;
unsigned char d_23_16_size;
unsigned short a_intr_cnt;
unsigned short b_intr_cnt;
unsigned short c_intr_cnt;
unsigned short d_intr_cnt;
} *ipic_csr = (void *) 0xFFFBC000;
/* /*
* Define the time limits for RTEMS Test Suite test durations. * Define the time limits for RTEMS Test Suite test durations.
@@ -160,40 +222,25 @@ static volatile struct ipic_csr {
#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ #define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */
/* /*
* Define the interrupt mechanism for Time Test 27 * Define the interrupt mechanism for Time Test 27
* *
* NOTE: Not implemented * NOTE: We use software interrupt 0
*/ */
#define MUST_WAIT_FOR_INTERRUPT 0 #define MUST_WAIT_FOR_INTERRUPT 0
#define Install_tm27_vector( handler ) #define Install_tm27_vector( handler ) \
set_vector( (handler), VBR1 * 0x10 + 0x8, 1 ); \
lcsr->intr_level[2] |= 3; \
lcsr->intr_ena |= 0x100;
#define Cause_tm27_intr() #define Cause_tm27_intr() lcsr->intr_soft_set |= 0x100
#define Clear_tm27_intr() #define Clear_tm27_intr() lcsr->intr_clear |= 0x100
#define Lower_tm27_intr() #define Lower_tm27_intr()
/* #ifdef M162_INIT
* Simple spin delay in microsecond units for device drivers.
* This is very dependent on the clock speed of the target.
*/
#define delay( microseconds ) \
{ register rtems_unsigned32 _delay=(microseconds); \
register rtems_unsigned32 _tmp=123; \
asm volatile( "0: \
nbcd %0 ; \
nbcd %0 ; \
dbf %1,0b" \
: "=d" (_tmp), "=d" (_delay) \
: "0" (_tmp), "1" (_delay) ); \
}
/* Constants */
#ifdef 1626_INIT
#undef EXTERN #undef EXTERN
#define EXTERN #define EXTERN
#else #else

View File

@@ -103,11 +103,13 @@ int bsp_start(
m68k_set_vbr( &M68Kvec ); m68k_set_vbr( &M68Kvec );
/* /*
* You may wish to make VME access round-robin here, currently * You may wish to make the VME arbitration round-robin here, currently
* we leave it as it is. * we leave it as it is.
*/ */
lcsr->vector_base = VECTOR_BASE; /* set the vector base register */ /* set the Interrupt Base Vectors */
lcsr->vector_base = (VBR0 << 28) | (VBR1 << 24);
m68k_enable_caching(); m68k_enable_caching();

View File

@@ -31,41 +31,42 @@
* $Id$ * $Id$
*/ */
#include <rtems.h> #include <rtems.h>
#include <bsp.h> #include <bsp.h>
/* Periodic tick interval */ /* Periodic tick interval */
#define TICK_INTERVAL 0x10000 #define TICK_INTERVAL 0x10000U
#define TIMER_INT_LEVEL 6 #define TIMER_INT_LEVEL 6
int Ttimer_val; rtems_unsigned32 Ttimer_val;
rtems_boolean Timer_driver_Find_average_overhead; rtems_boolean Timer_driver_Find_average_overhead;
rtems_isr timerisr(); rtems_isr timerisr();
void Timer_initialize() void Timer_initialize()
{ {
(void) set_vector( timerisr, (VECTOR_BASE >> 28) * 0x10 + 0x8, 0 ); (void) set_vector( timerisr, VBR0 * 0x10 + 0x8, 0 );
Ttimer_val = 0; /* clear timer ISR count */ Ttimer_val = 0; /* clear timer ISR count */
lcsr->vector_base = 0x67800000; /* set vb, enable interrupts */ lcsr->vector_base |= MASK_INT; /* unmask VMEchip2 interrupts */
lcsr->intr_clear |= 0x01000000; /* clear pending interrupt */
lcsr->to_ctl = 0xE7; /* prescaler to 1 MHz (see Appendix A1) */ lcsr->to_ctl = 0xE7; /* prescaler to 1 MHz (see Appendix A1) */
lcsr->timer_cmp_1 = TICK_INTERVAL; lcsr->timer_cmp_1 = TICK_INTERVAL;
lcsr->timer_cnt_1 = 0; /* clear counter */ lcsr->timer_cnt_1 = 0; /* clear counter */
lcsr->board_ctl |= 7; /* increment, reset-on-compare, clear-ovfl-cnt */ lcsr->board_ctl |= 7; /* increment, reset-on-compare, */
/* and clear-overflow-cnt */
lcsr->intr_level[0] |= TIMER_INT_LEVEL; /* set int level */ lcsr->intr_level[0] |= TIMER_INT_LEVEL; /* set int level */
lcsr->intr_ena |= 0x01000000; /* enable tick timer 1 interrupt */ lcsr->intr_ena |= 0x01000000; /* enable tick timer 1 interrupt */
} }
#define AVG_OVERHEAD 6 /* It typically takes 3.0 microseconds */ #define AVG_OVERHEAD 3U /* It typically takes 3.0 microseconds */
/* (6 countdowns) to start/stop the timer. */ /* (3 countdowns) to start/stop the timer. */
#define LEAST_VALID 10 /* Don't trust a value lower than this */ #define LEAST_VALID 10U /* Don't trust a value lower than this */
int Read_timer() int Read_timer()
{ {
unsigned long total; rtems_unsigned32 total;
total = (Ttimer_val * TICK_INTERVAL) + lcsr->timer_cnt_1; total = (Ttimer_val * TICK_INTERVAL) + lcsr->timer_cnt_1;
@@ -75,9 +76,10 @@ int Read_timer()
if ( total < LEAST_VALID ) if ( total < LEAST_VALID )
return 0; /* below timer resolution */ return 0; /* below timer resolution */
return (total-AVG_OVERHEAD); /* in musec units */ return (total-AVG_OVERHEAD) >> 1;
} }
rtems_status_code Empty_function( void ) rtems_status_code Empty_function( void )
{ {
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;

View File

@@ -33,6 +33,7 @@ BEGIN_CODE
.set INTR_CLEAR_REG, 0xfff40074 | interrupt clear register .set INTR_CLEAR_REG, 0xfff40074 | interrupt clear register
.set RELOAD, 0x01000000 | clear tick 1 interrupt .set RELOAD, 0x01000000 | clear tick 1 interrupt
PUBLIC (Ttimer_val)
PUBLIC (timerisr) PUBLIC (timerisr)
SYM (timerisr): SYM (timerisr):
move.l a0, -(a7) | save a0 move.l a0, -(a7) | save a0

View File

@@ -53,255 +53,248 @@ void usage (void);
int MVMEControl(u_long entry, int reset, int go); int MVMEControl(u_long entry, int reset, int go);
unsigned int ahdtoi(unsigned char digit) unsigned int ahdtoi(unsigned char digit)
/* converts a hexadecimal char to an integer /* converts a hexadecimal char to an integer
* *
* entry : digit = character to convert * entry : digit = character to convert
* : 0..15 = result * : 0..15 = result
* : -1 = char is not a digit * : -1 = char is not a digit
*/ */
{ {
/* check digit */ /* check digit */
if (!isxdigit(digit)) if (!isxdigit(digit))
return(-1); return(-1);
switch (toupper(digit)) { switch (toupper(digit)) {
case 'A' : return(0xA); case 'A' : return(0xA);
case 'B' : return(0xB); case 'B' : return(0xB);
case 'C' : return(0xC); case 'C' : return(0xC);
case 'D' : return(0xD); case 'D' : return(0xD);
case 'E' : return(0xE); case 'E' : return(0xE);
case 'F' : return(0xF); case 'F' : return(0xF);
default : return(digit - 0x30); default : return(digit - 0x30);
} }
} }
int issrec(char *str) int issrec(char *str)
/* attempts to identify the type of Srecord string passed /* attempts to identify the type of Srecord string passed
* *
* entry : str = pointer to null terminated string * entry : str = pointer to null terminated string
* returns : 0,1,2,3,5,7,8,9 for S0..S9 except S6 & S4 * returns : 0,1,2,3,5,7,8,9 for S0..S9 except S6 & S4
* : -1 = invalid header or header not found * : -1 = invalid header or header not found
* : -2 = invalid header number * : -2 = invalid header number
*/ */
{ {
/* Check first character for S */ /* Check first character for S */
if ((isupper(str[0]) && (str[0] == 'S')) || if ((isupper(str[0]) && (str[0] == 'S')) || (islower(str[0]) && (str[0] == 's')))
(islower(str[0]) && (str[0] == 's'))) {
{ /* check for valid header number */
/* check for valid header number */ switch (str[1]) {
switch (str[1]) { case '0' : return 0; /* header record */
case '0' : return 0; /* header record */ case '1' : return 1; /* data record, 2byte addr */
case '1' : return 1; /* data record, 2byte addr */ case '2' : return 2; /* " " , 3byte addr */
case '2' : return 2; /* " " , 3byte addr */ case '3' : return 3; /* " " , 4byte addr */
case '3' : return 3; /* " " , 4byte addr */ case '5' : return 5; /* number of S1,S2,S3 blocks */
case '5' : return 5; /* number of S1,S2,S3 blocks */ case '7' : return 7; /* S3 terminator */
case '7' : return 7; /* S3 terminator */ case '8' : return 8; /* S2 terminator */
case '8' : return 8; /* S2 terminator */ case '9' : return 9; /* S1 terminator */
case '9' : return 9; /* S1 terminator */ default : return -2; /* all others are invalid */
default : return -2; /* all others are invalid */ }
} }
} return(-1);
return(-1);
} }
int validrec(char *str) int validrec(char *str)
/* Tests for a valid srecord. tests checksum & for nondigit characters /* Tests for a valid srecord. tests checksum & for nondigit characters
* doesn't rely on any other srecord routines. * doesn't rely on any other srecord routines.
* *
* entry : str = pointer to null terminated string * entry : str = pointer to null terminated string
* returns : -1 = srecord contains invalid characters * returns : -1 = srecord contains invalid characters
* : -2 = srecord checksum is invalid * : -2 = srecord checksum is invalid
* : -3 = srecord record length is invalid * : -3 = srecord record length is invalid
* : 0 = srecord is valid * : 0 = srecord is valid
*/ */
{ {
int cn = 1, rlen=0; int cn = 1, rlen=0;
int mchksum=0, rchksum=0; int mchksum=0, rchksum=0;
/* first check if there are any non-digit characters except S */ /* first check if there are any non-digit characters except S */
while (str[cn]!=0) while (str[cn]!=0)
if (!isxdigit(str[cn++])) if (!isxdigit(str[cn++]))
return(-1); return(-1);
/* test number of data bytes */ /* test number of data bytes */
rlen = ahdtoi(str[2])* 0x10 + ahdtoi(str[3]); rlen = ahdtoi(str[2])* 0x10 + ahdtoi(str[3]);
if (((strlen(str)-4)/2U) != rlen) return(-3); if (((strlen(str)-4)/2U) != rlen) return(-3);
/* get checksum from string */ /* get checksum from string */
rchksum = ahdtoi(str[rlen*2+2])*0x10 + ahdtoi(str[rlen*2+3]); rchksum = ahdtoi(str[rlen*2+2])*0x10 + ahdtoi(str[rlen*2+3]); /* string chksum */
/* string chksum */
/* now calculate my own checksum */ /* now calculate my own checksum */
for (cn=2; cn <= rlen*2; ) for (cn=2; cn <= rlen*2; )
mchksum += ahdtoi(str[cn++])*0x10 + ahdtoi(str[cn++]); mchksum += ahdtoi(str[cn++])*0x10 + ahdtoi(str[cn++]);
mchksum = ~mchksum & 0xFF; mchksum = ~mchksum & 0xFF;
if (mchksum != rchksum) return(-2); /* return -2 in not equal */ if (mchksum != rchksum) return(-2); /* return -2 in not equal */
/* return OK if we didn't fail any of these tests */ /* return OK if we didn't fail any of these tests */
return(0); return(0);
} }
void hdr2str(char *sstr, char *pstr) void hdr2str(char *sstr, char *pstr)
/* converts header record (S0) string into a plain string /* converts header record (S0) string into a plain string
* *
* entry : sstr = pointer to S0 string record * entry : sstr = pointer to S0 string record
* exit : pstr = pointer to string long enough to hold string * exit : pstr = pointer to string long enough to hold string
* (caller must allocate enough space for string) * (caller must allocate enough space for string)
*/ */
{ {
int rlen, cn, pn=0; int rlen, cn, pn=0;
rlen = ahdtoi(sstr[2])*0x10 + ahdtoi(sstr[3]); rlen = ahdtoi(sstr[2])*0x10 + ahdtoi(sstr[3]);
for (cn=8; cn <= rlen*2; ) for (cn=8; cn <= rlen*2; )
pstr[pn++] = ahdtoi(sstr[cn++])*0x10 + ahdtoi(sstr[cn++]); pstr[pn++] = ahdtoi(sstr[cn++])*0x10 + ahdtoi(sstr[cn++]);
pstr[pn]=0; pstr[pn]=0;
} }
unsigned long getaddr(char *str) unsigned long getaddr(char *str)
/* returns the address of the srecord in str. assumes record is valid. /* returns the address of the srecord in str. assumes record is valid.
* *
* entry : str = pointer to srecord string * entry : str = pointer to srecord string
* exit : address of data, word or long. * exit : address of data, word or long.
*/ */
{ {
unsigned long addr=0; unsigned long addr=0;
switch (issrec(str)) { switch (issrec(str)) {
case 0 : case 0 :
case 1 : case 1 :
case 5 : case 5 :
case 9 : case 9 : addr = ahdtoi(str[4])*0x1000 + ahdtoi(str[5])*0x100
addr = ahdtoi(str[4])*0x1000 + ahdtoi(str[5])*0x100 + ahdtoi(str[6])*0x10 + ahdtoi(str[7]);
+ ahdtoi(str[6])*0x10 + ahdtoi(str[7]); return(addr);
return(addr); case 2 :
case 2 : case 8 : addr = ahdtoi(str[4])*0x100000 + ahdtoi(str[5])*0x10000
case 8 : + ahdtoi(str[6])*0x1000 + ahdtoi(str[7])*0x100
addr = ahdtoi(str[4])*0x100000 + ahdtoi(str[5])*0x10000 + ahdtoi(str[8])*0x10 + ahdtoi(str[9]);
+ ahdtoi(str[6])*0x1000 + ahdtoi(str[7])*0x100 return(addr);
+ ahdtoi(str[8])*0x10 + ahdtoi(str[9]); case 3 :
return(addr); case 7 : addr = ahdtoi(str[4])*0x10000000 + ahdtoi(str[5])*0x1000000
case 3 : + ahdtoi(str[6])*0x100000 + ahdtoi(str[7])*0x10000
case 7 : + ahdtoi(str[8])*0x1000 + ahdtoi(str[9])*0x100
addr = ahdtoi(str[4])*0x10000000 + ahdtoi(str[5])*0x1000000 + ahdtoi(str[10])*0x10 + ahdtoi(str[11]);
+ ahdtoi(str[6])*0x100000 + ahdtoi(str[7])*0x10000 return(addr);
+ ahdtoi(str[8])*0x1000 + ahdtoi(str[9])*0x100 default : return(-1);
+ ahdtoi(str[10])*0x10 + ahdtoi(str[11]); }
return(addr);
default : return(-1);
}
} }
unsigned int datasize(char *str) unsigned int datasize(char *str)
/* /*
* returns the number of data bytes in the srecord. assumes record is valid. * returns the number of data bytes in the srecord. assumes record is valid.
* *
* entry : str = pointer to srecord string * entry : str = pointer to srecord string
* exit : number of bytes of data in the data field. * exit : number of bytes of data in the data field.
*/ */
{ {
unsigned int size=0; unsigned int size=0;
switch (issrec(str)) { switch (issrec(str)) {
case 0 : case 0 :
case 1 : case 1 :
case 5 : case 5 :
case 7 : case 7 :
case 8 : case 8 :
case 9 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); case 9 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]);
return(size-3); return(size-3);
case 2 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); case 2 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]);
return(size-4); return(size-4);
case 3 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]); case 3 : size = ahdtoi(str[2])*0x10 + ahdtoi(str[3]);
return(size-5); return(size-5);
default : return(-1); default : return(-1);
} }
} }
void usage (void) void usage (void)
/* /*
* prints correct usage on stdout * prints correct usage on stdout
*/ */
{ {
printf("\nUSAGE : sload [-v][-g][-r] [file]\n"); printf("\nUSAGE : sload [-v][-g][-r] [file]\n");
printf(" file is an s-record file\n"); printf(" file is an s-record file\n");
printf(" -v for verbose summary of s-records loaded\n"); printf(" -v for verbose summary of s-records loaded\n");
printf(" -g to start execution\n"); printf(" -g to start execution\n");
printf(" -r to reset MVME162\n\n"); printf(" -r to reset MVME162\n\n");
} }
int MVMEControl(u_long entry, int reset, int go) int MVMEControl(u_long entry, int reset, int go)
/* Controls MVME-162 from other VME master: /* Controls MVME-162 from other VME master:
* if entry != 0, loads it as start address * if entry != 0, loads it as start address
* if go != 0, starts program execution from entry * if go != 0, starts program execution from entry
* if reset != 0, resets mvme162's local bus * if reset != 0, resets mvme162's local bus
* Depends upon #define'ed GROUP_BASE_ADDRESS and BOARD_BASE_ADDRESS * Depends upon #define'ed GROUP_BASE_ADDRESS and BOARD_BASE_ADDRESS
* which in turn are set by the 162-BUG's ENV command. * which in turn are set by the 162-BUG's ENV command.
*/ */
{ {
int vme; int vme;
char vmedev[32] = "/dev/vme16d32"; /* d32 is important !!! */ char vmedev[32] = "/dev/vme16d32"; /* d32 is important !!! */
u_long pagesize; u_long pagesize;
struct gcsr *gcsr_map; struct gcsr *gcsr_map;
pagesize = sysconf(_SC_PAGESIZE); /* mmap likes to be page-aligned */ pagesize = sysconf(_SC_PAGESIZE); /* mmap likes to be page-aligned */
if ((vme = open(vmedev, O_RDWR)) == -1) { if ((vme = open(vmedev, O_RDWR)) == -1) {
perror("open"); perror("open");
fprintf(stderr, "Cannot open vme as %s to access GCSR\n", vmedev); fprintf(stderr, "Cannot open vme as %s to access GCSR\n", vmedev);
return 1; return 1;
} }
/* "MAP_SHARED" is important here */ /* "MAP_SHARED" is important here */
gcsr_map = (struct gcsr *) gcsr_map = (struct gcsr *) mmap(0, 0x1000, PROT_WRITE|PROT_READ, MAP_SHARED,
mmap(0, 0x1000, PROT_WRITE|PROT_READ, MAP_SHARED, vme, (u_long)gcsr_vme / pagesize * pagesize);
vme, (u_long)gcsr_vme / pagesize * pagesize); if (gcsr_map == (struct gcsr *) - 1) {
if (gcsr_map == (struct gcsr *) - 1) { perror("mmap");
perror("mmap"); fprintf(stderr, "Cannot mmap() to remote bus address 0x%08X\n",
fprintf(stderr, "Cannot mmap() to remote bus address 0x%08X\n", (u_long)gcsr_vme / pagesize * pagesize);
(u_long)gcsr_vme / pagesize * pagesize); return 1;
return 1; }
}
/* /*
* use GCSR to start execution in MVME162 * use GCSR to start execution in MVME162
* adjust pointer to compensate for page alignement * adjust pointer to compensate for page alignement
*/ */
gcsr_map = (struct gcsr *)((u_long)gcsr_map + gcsr_map = (struct gcsr *)((u_long)gcsr_map + (u_long)gcsr_vme % pagesize);
(u_long)gcsr_vme % pagesize);
if (reset) { /* reset the local bus... */ if (reset) { /* reset the local bus... */
gcsr_map->board_scr |= 0x80; gcsr_map->board_scr |= 0x80;
} }
if (entry) { /* ...load start address... */ if (entry) { /* ...load start address... */
gcsr_map->gpr[0] = entry >> 16U; gcsr_map->gpr[0] = entry >> 16U;
gcsr_map->gpr[1] = entry & 0x0000FFFF; gcsr_map->gpr[1] = entry & 0x0000FFFF;
} }
if (go) { /* ... and kick it in the ass! */ if (go) { /* ... and kick it in the ass! */
gcsr_map->lmsig = 0x1; gcsr_map->lmsig = 0x1;
} }
} }
/*=================================================================== */ /*=================================================================== */
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char inpstr[256]; char inpstr[256];
u_char image[256]; u_char image[256];
char hdrstr[64]; char hdrstr[64];
int i, j, k, result, size, line=0, lastrec=0; int i, j, k, result, size, line=0, lastrec=0;
long addr, tsize=0, naddr=0, blksize=0, blknum=1; long addr, tsize=0, naddr=0, blksize=0, blknum=1;
FILE *in; FILE *in;
char infile[256] = ""; char infile[256] = "";
char vmedev[32] = "/dev/vme32d32"; /* Assume "/dev/vme32d32" */ char vmedev[32] = "/dev/vme32d32"; /* Assume "/dev/vme32d32" */
int vme, verbose = 0, go = 0, reset = 0, havefile = 0; int vme, verbose = 0, go = 0, reset = 0, havefile = 0;
/* Parse the command line */ /* Parse the command line */
--argc; --argc;
while (argv++, argc--) { while (argv++, argc--) {
if (**argv != '-') { if (**argv != '-') {
strcpy(infile, *argv); strcpy(infile, *argv);
havefile = 1; havefile = 1;
} else if (!strcmp(*argv, "-v")) { } else if (!strcmp(*argv, "-v")) {
verbose = 1; verbose = 1;
} else if (!strcmp(*argv, "-g")) { } else if (!strcmp(*argv, "-g")) {
@@ -325,18 +318,18 @@ main(int argc, char *argv[])
if (!havefile) { if (!havefile) {
if (!reset && !go) { if (!reset && !go) {
usage(); usage();
} }
else { else {
MVMEControl(0, reset, go); MVMEControl(0, reset, go);
} }
exit(0); exit(0);
} }
if ((in = fopen(infile, "r")) == NULL) { if ((in = fopen(infile, "r")) == NULL) {
perror("open"); perror("open");
fprintf(stderr, "Cannot open input file %s\n", infile); fprintf(stderr, "Cannot open input file %s\n", infile);
exit(1); exit(1);
} }
if ((vme = open(vmedev, O_RDWR)) == -1) { if ((vme = open(vmedev, O_RDWR)) == -1) {
@@ -347,196 +340,172 @@ main(int argc, char *argv[])
line++; line++;
if (validrec(inpstr) == 0) { if (validrec(inpstr) == 0) {
switch (issrec(inpstr)) { switch (issrec(inpstr)) {
case 0 : case 0 :
hdr2str(inpstr, hdrstr); hdr2str(inpstr, hdrstr);
if (verbose) printf("HEADER string = `%s'\n", hdrstr); if (verbose) printf("HEADER string = `%s'\n", hdrstr);
lastrec=HEADER; lastrec=HEADER;
break; break;
case 1 : case 1 :
addr = getaddr(inpstr); addr = getaddr(inpstr);
size = datasize(inpstr); size = datasize(inpstr);
if (blksize == 0) { if (blksize == 0) {
blksize+=size; blksize+=size;
naddr=addr+size; naddr=addr+size;
if (verbose) printf("DATA\tS19\t$%04lX", addr); if (verbose) printf("DATA\tS19\t$%04lX", addr);
lastrec=DATA19; lastrec=DATA19;
}
else if ((blksize!=0) && (addr==naddr)) {
blksize+=size;
naddr=addr+size;
}
else {
if (verbose) printf("\t$%04lX\t%lu", naddr-1, blksize);
if (verbose) printf("\t%d\n", blknum);
blknum+=1;
naddr=addr+size;
blksize=size;
if (verbose) printf("DATA\tS19\t$%04lX", addr);
lastrec=DATA19;
}
tsize += size;
if (vme == -1) break;
for (i = 0, j = 8, k = size; k-- > 0; i += 1, j += 2) {
image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
}
if (lseek(vme, addr, SEEK_SET) == -1) {
fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
}
else {
if (write(vme, (u_char *)image, size) != size) {
fprintf(stderr, "Write to vme address %08X failed\n", addr);
}
}
break;
case 2 :
addr = getaddr(inpstr);
size = datasize(inpstr);
if (blksize == 0) {
blksize+=size;
naddr=addr+size;
if (verbose) printf("DATA\tS28\t$%06lX",addr);
lastrec=DATA28;
}
else if ((blksize!=0) && (addr==naddr)) {
blksize+=size;
naddr=addr+size;
}
else {
if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);
if (verbose) printf("\t%d\n",blknum);
blknum+=1;
naddr=addr+size;
blksize=size;
if (verbose) printf("DATA\tS28\t$%06lX",addr);
lastrec=DATA28;
}
tsize += size;
if (vme == -1) break;
for (i = 0, j = 10, k = size; k-- > 0; i += 1, j += 2) {
image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
}
if (lseek(vme, addr, SEEK_SET) == -1) {
fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
}
else {
if (write(vme, (u_char *)image, size) != size) {
fprintf(stderr, "Write to vme address %08X failed\n", addr);
}
}
break;
case 3 :
addr = getaddr(inpstr);
size = datasize(inpstr);
if (blksize == 0) {
blksize+=size;
naddr=addr+size;
if (verbose) printf("DATA\tS37\t$%08lX",addr);
lastrec=DATA37;
}
else if ((blksize!=0) && (addr==naddr)) {
blksize+=size;
naddr=addr+size;
}
else {
if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);
if (verbose) printf("\t%d\n",blknum);
blknum+=1;
naddr=addr+size;
blksize=size;
if (verbose) printf("DATA\tS37\t$%08lX",addr);
lastrec=DATA37;
}
tsize += size;
if (vme == -1) break;
for (i = 0, j = 12, k = size; k-- > 0; i += 1, j += 2) {
image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
}
if (lseek(vme, addr, SEEK_SET) == -1) {
fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
}
else {
if (write(vme, (u_char *)image, size) != size) {
fprintf(stderr, "Write to vme address %08X failed\n", addr);
}
}
break;
case 7 :
if (lastrec==DATA19){
if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);
}
if (lastrec==DATA28){
if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);
}
if (lastrec==DATA37){
if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);
}
if (verbose) printf("\t%d\n",blknum);
addr = getaddr(inpstr);
if (verbose) printf("TERM\tS37");
printf("\nExecution address = $%08lX\n", addr);
lastrec=TERMINATOR;
break;
case 8 :
if (lastrec==DATA19){
if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);
}
if (lastrec==DATA28){
if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);
}
if (lastrec==DATA37){
if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);
}
if (verbose) printf("\t%d\n",blknum);
addr = getaddr(inpstr);
if (verbose) printf("TERM\tS28");
printf("\nExecution address = $%06lX\n", addr);
lastrec=TERMINATOR;
break;
case 9 :
if (lastrec==DATA19){
if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);
}
if (lastrec==DATA28){
if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);
}
if (lastrec==DATA37){
if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);
}
if (verbose) printf("\t%d\n",blknum);
addr = getaddr(inpstr);
if (verbose) printf("TERM\tS19");
printf("\nExecution address = $%04lX\n", addr);
lastrec=TERMINATOR;
break;
} }
else if ((blksize!=0) && (addr==naddr)) {
blksize+=size;
naddr=addr+size;
}
else {
if (verbose) printf("\t$%04lX\t%lu", naddr-1, blksize);
if (verbose) printf("\t%d\n", blknum);
blknum+=1;
naddr=addr+size;
blksize=size;
if (verbose) printf("DATA\tS19\t$%04lX", addr);
lastrec=DATA19;
}
tsize += size;
if (vme == -1) break;
for (i = 0, j = 8, k = size; k-- > 0; i += 1, j += 2) {
image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
}
if (lseek(vme, addr, SEEK_SET) == -1) {
fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
}
else {
if (write(vme, (u_char *)image, size) != size) {
fprintf(stderr, "Write to vme address %08X failed\n", addr);
}
}
break;
case 2 :
addr = getaddr(inpstr);
size = datasize(inpstr);
if (blksize == 0) {
blksize+=size;
naddr=addr+size;
if (verbose) printf("DATA\tS28\t$%06lX",addr);
lastrec=DATA28;
}
else if ((blksize!=0) && (addr==naddr)) {
blksize+=size;
naddr=addr+size;
}
else {
if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);
if (verbose) printf("\t%d\n",blknum);
blknum+=1;
naddr=addr+size;
blksize=size;
if (verbose) printf("DATA\tS28\t$%06lX",addr);
lastrec=DATA28;
}
tsize += size;
if (vme == -1) break;
for (i = 0, j = 10, k = size; k-- > 0; i += 1, j += 2) {
image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
}
if (lseek(vme, addr, SEEK_SET) == -1) {
fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
}
else {
if (write(vme, (u_char *)image, size) != size) {
fprintf(stderr, "Write to vme address %08X failed\n", addr);
}
}
break;
case 3 :
addr = getaddr(inpstr);
size = datasize(inpstr);
if (blksize == 0) {
blksize+=size;
naddr=addr+size;
if (verbose) printf("DATA\tS37\t$%08lX",addr);
lastrec=DATA37;
}
else if ((blksize!=0) && (addr==naddr)) {
blksize+=size;
naddr=addr+size;
}
else {
if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);
if (verbose) printf("\t%d\n",blknum);
blknum+=1;
naddr=addr+size;
blksize=size;
if (verbose) printf("DATA\tS37\t$%08lX",addr);
lastrec=DATA37;
}
tsize += size;
if (vme == -1) break;
for (i = 0, j = 12, k = size; k-- > 0; i += 1, j += 2) {
image[i] = ahdtoi(inpstr[j])*0x10 + ahdtoi(inpstr[j+1]);
}
if (lseek(vme, addr, SEEK_SET) == -1) {
fprintf(stderr, "lseek() to vme address %08X failed\n", addr);
}
else {
if (write(vme, (u_char *)image, size) != size) {
fprintf(stderr, "Write to vme address %08X failed\n", addr);
}
}
break;
case 7 :
if (lastrec==DATA19){if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);}
if (lastrec==DATA28){if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);}
if (lastrec==DATA37){if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);}
if (verbose) printf("\t%d\n",blknum);
addr = getaddr(inpstr);
if (verbose) printf("TERM\tS37");
printf("\nExecution address = $%08lX\n", addr);
lastrec=TERMINATOR;
break;
case 8 :
if (lastrec==DATA19){if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);}
if (lastrec==DATA28){if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);}
if (lastrec==DATA37){if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);}
if (verbose) printf("\t%d\n",blknum);
addr = getaddr(inpstr);
if (verbose) printf("TERM\tS28");
printf("\nExecution address = $%06lX\n", addr);
lastrec=TERMINATOR;
break;
case 9 :
if (lastrec==DATA19){if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);}
if (lastrec==DATA28){if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);}
if (lastrec==DATA37){if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);}
if (verbose) printf("\t%d\n",blknum);
addr = getaddr(inpstr);
if (verbose) printf("TERM\tS19");
printf("\nExecution address = $%04lX\n", addr);
lastrec=TERMINATOR;
break;
} }
else { }
printf("\nError on line %d. ",line); else {
switch (validrec(inpstr)) { printf("\nError on line %d. ",line);
case -1 : {printf("SRecord contains invalid characters.\n"); break; } switch (validrec(inpstr)) {
case -2 : {printf("SRecord checksum is invalid.\n"); break;} case -1 : {printf("SRecord contains invalid characters.\n"); break; }
case -3 : {printf("SRecord length is invalid.\n"); break;} case -2 : {printf("SRecord checksum is invalid.\n"); break;}
} case -3 : {printf("SRecord length is invalid.\n"); break;}
exit(1); }
} exit(1);
} }
}
if ((lastrec==DATA19) || (lastrec==DATA28) || (lastrec==DATA37)) { if ((lastrec==DATA19) || (lastrec==DATA28) || (lastrec==DATA37)) {
if (lastrec==DATA19){ if (lastrec==DATA19){if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize);}
if (verbose) printf("\t$%04lX\t%lu",naddr-1,blksize); if (lastrec==DATA28){if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize);}
} if (lastrec==DATA37){if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize);}
if (lastrec==DATA28){ if (verbose) printf("\t%d\n",blknum);
if (verbose) printf("\t$%06lX\t%lu",naddr-1,blksize); printf("ERROR: terminator record not found.\n");
} }
if (lastrec==DATA37){ else {
if (verbose) printf("\t$%08lX\t%lu",naddr-1,blksize); for (i = 0x000FFFF; i-- > 0;) ; /* mystique delay... */
} MVMEControl(addr, reset, go);
if (verbose) printf("\t%d\n",blknum); }
printf("ERROR: terminator record not found.\n"); if (verbose) printf("total data size = %lu bytes\n", tsize);
}
else {
for (i = 0x000FFFF; i-- > 0;) ; /* mystique delay... */
MVMEControl(addr, reset, go);
}
if (verbose) printf("total data size = %lu bytes\n", tsize);
} }