Commit b613259d authored by Roberto Hexsel's avatar Roberto Hexsel

added functions to start/stop/read COUNT and test to ensure COUNT counts

parent 5ca9543a
......@@ -36,6 +36,7 @@ extern void dumpRAM(void);
extern void cmips_delay(int);
// external counter (peripheral)
extern void startCounter(int, int);
extern void stopCounter(void);
extern int readCounter(void);
......@@ -43,6 +44,10 @@ extern int readCounter(void);
extern void enableInterr(void);
extern void disableInterr(void);
// internal counter, CP0 register COUNT
extern int startCount(void);
extern int readCount(void);
extern char *memcpy(char*, const char*, int);
extern char *memset(char*, const int, int);
......
......@@ -28,8 +28,6 @@ SECTIONS
_edata = . ; /* end of data constant (from Xinu) */
} > ram
.data1 : { *(.data1) } > ram
.rodata : { *(.rodata .rodata.*) } > ram
.rodata1 : { *(.rodata1) } > ram
.lit8 : { *(.lit8) } > ram
.lit4 : { *(.lit4) } > ram
.sdata : { *(.sdata .sdata.*) } > ram
......@@ -37,9 +35,14 @@ SECTIONS
.bss :
{
*(.bss .bss.*) *(COMMON)
} > ram
.rodata1 : { *(.rodata1) } > ram
.rodata :
{
*(.rodata .rodata.*)
_end = . ; /* end of image constant (from Xinu) */
} > ram
end_RAM = 0x00020000; /* x_DATA_MEM_SZ */
half_RAM = (end_RAM / 2);
base_PT = ( _bdata + half_RAM );
......
......@@ -133,7 +133,7 @@ UARTret:
mfc0 $k0, c0_status # Read STATUS register
ori $k0, $k0, M_StatusIEn # but do not modify its contents
mtc0 $k0, c0_status
mtc0 $k0, c0_status # except for re-enabling interrupts
eret # Return from interrupt
.end UARTinterr
#----------------------------------------------------------------
......@@ -158,6 +158,40 @@ countCompare:
.end countCompare
#----------------------------------------------------------------
#================================================================
# startCount enables the COUNT register, returns new CAUSE
# CAUSE.dc <= 0 to enable counting
#----------------------------------------------------------------
.text
.set noreorder
.global startCount
.ent startCount
startCount:
mfc0 $v0, c0_cause
lui $v1, 0xf7ff
ori $v1, $v1, 0xffff
and $v0, $v0, $v1
jr $ra
mtc0 $v0, c0_cause
.end startCount
#----------------------------------------------------------------
#================================================================
# readCount returns the value of the COUNT register
#----------------------------------------------------------------
.text
.set noreorder
.global readCount
.ent readCount
readCount:
mfc0 $v0, c0_count
jr $ra
nop
.end readCount
#----------------------------------------------------------------
#================================================================
# functions to enable and disable interrupts, both return STATUS
......@@ -493,7 +527,7 @@ k_for: lbu $a0, 0($a1)
.equ kmsg_interr,0
.equ kmsg_excep,1
.data
.section .rodata
.align 2
_kmsg_interr: .asciiz "\n\t00 - interrupt\n\n"
_kmsg_excep: .asciiz "\n\t01 - exception\n\n"
......@@ -502,7 +536,7 @@ _kmsg_seg_fault: .asciiz "\n\t03 - segmentation fault\n\n"
_kmsg_sec_mem: .asciiz "\n\t04 - in secondary memory\n\n"
.global _kmsg_list
.data
.section .rodata
.align 2
_kmsg_list:
.word _kmsg_interr,_kmsg_excep, _kmsg_prot_viol, _kmsg_seg_fault
......
......@@ -51,7 +51,7 @@ _start:
#
# the page table is located at the middle of the RAM
# bottom half is reserved for "RAM memory", top for page table
# bottom half is reserved for "RAM memory", top half is for PTable
#
.set TOP_OF_RAM, (x_DATA_BASE_ADDR + x_DATA_MEM_SZ)
.set MIDDLE_RAM, (x_DATA_BASE_ADDR + (x_DATA_MEM_SZ/2))
......
//-------------------------------------------------------------------------
// test if COUNT register counts up monotonically
// returns error if the time to compute every 11th element of the Fibonacci
// sequence, as measured by COUNT is not monotonically increasing
//-------------------------------------------------------------------------
#include "cMIPS.h"
#define TRUE (1==1)
#define FALSE (1==0)
//---------------------------------------------------------------------
int fibonacci(int n) {
int i;
int f1 = 0;
int f2 = 1;
int fi = 0;;
if (n == 0)
return 0;
if(n == 1)
return 1;
for(i = 2 ; i <= n ; i++ ) {
fi = f1 + f2;
f1 = f2;
f2 = fi;
}
return fi;
}
//=====================================================================
int main() {
int i, new, old, monotonic;
print( startCount() ); // start COUNT
monotonic = TRUE;
for (i=0; i < 44; i += 11) {
old = readCount(); // COUNT before computing fib(i)
print( fibonacci(i) );
new = readCount(); // COUNT after computing fib(i)
monotonic = monotonic && ( (new - old) > 0 );
if ( monotonic == FALSE ) {
to_stdout('e'); to_stdout('r'); to_stdout('r'); to_stdout('\n');
print(new);
exit(new);
}
// print(new);
}
// print(new);
to_stdout('o'); to_stdout('k'); to_stdout('\n');
// now disable COUNT and make sure that it has stopped
print( stopCount() ); // stop COUNT
old = readCount(); // COUNT before computing fib(i)
print( fibonacci(5) );
new = readCount(); // COUNT after computing fib(i)
monotonic = monotonic && ( (new - old) > 0 );
if ( monotonic == TRUE ) {
to_stdout('e'); to_stdout('r'); to_stdout('r'); to_stdout('\n');
print(new);
exit(new);
} else {
// print(new);
to_stdout('o'); to_stdout('k'); to_stdout('\n');
}
exit(new);
}
//=====================================================================
0080007c
00000000
00000059
0000452f
0035c7e2
ok
0880007c
00000005
ok
......@@ -104,7 +104,7 @@ if [ 0 = 0 ] ; then
fi
c_small="divmul fat fib sieve ccitt16 gcd matrix negcnt reduz rand"
c_small="divmul fat fib count sieve ccitt16 gcd matrix negcnt reduz rand"
c_types="xram sort-byte sort-half sort-int memcpy"
c_sorts="bubble insertion merge quick selection shell"
c_FPU="FPU_m"
......@@ -133,7 +133,7 @@ else
fi
for F in $(echo "$SIMULATE" ) ; do
$bin/compile.sh -O 3 ${F}.c || exit 1
$bin/compile.sh -O3 ${F}.c || exit 1
${simulator} --ieee-asserts=disable --stop-time=$stoptime \
2>/dev/null >$F.simout
diff $ignBLANKS -q $F.expected $F.simout
......
typedef struct control { // control register fields (uses only ls byte)
unsigned int ign : 24, // ignore uppermost 3 bytes
rts : 1, // Request to Send output (bit 7)
ign2 : 2, // bits 6,5 ignored
intTX : 1, // interrupt on TX buffer empty (bit 4)
intRX : 1, // interrupt on RX buffer full (bit 3)
speed : 3; // 4,8,16... {tx,rx}clock data rates (bits 0..2)
} Tcontrol;
typedef struct status { // status register fields (uses only ls byte)
unsigned int ign : 24, // ignore uppermost 3 bytes
cts : 1, // Clear To Send input=1 (bit 7)
txEmpty : 1, // TX register is empty (bit 6)
rxFull : 1, // octet available from RX register (bit 5)
int_TX_empt: 1, // interrupt pending on TX empty (bit 4)
int_RX_full: 1, // interrupt pending on RX full (bit 3)
ign1 : 1, // ignored (bit 2)
framing : 1, // framing error (bit 1)
overun : 1; // overun error (bit 0)
} Tstatus;
typedef union ctlStat { // control + status on same address
Tcontrol ctl; // write-only
Tstatus stat; // read-only
} TctlStat;
typedef union data { // data registers on same address
int tx; // write-only
int rx; // read-only
} Tdata;
typedef struct serial {
TctlStat cs; // address is (int *)IO_UART_ADDR
Tdata d; // address is (int *)(IO_UART_ADDR+1)
} Tserial;
......@@ -11,46 +11,13 @@
#include "cMIPS.h"
typedef struct control { // control register fields (uses only ls byte)
int ign : 24, // ignore uppermost bits
rts : 1, // Request to Send output (bit 7)
ign2 : 2, // bits 6,5 ignored
intTX : 1, // interrupt on TX buffer empty (bit 4)
intRX : 1, // interrupt on RX buffer full (bit 3)
speed : 3; // 4,8,16..256 tx-rx clock data rates (bits 0..2)
} Tcontrol;
typedef struct status { // status register fields (uses only ls byte)
int ign : 24, // ignore uppermost bits
ign7 : 1, // ignored (bit 7)
txEmpty : 1, // TX register is empty (bit 6)
rxFull : 1, // octet available from RX register (bit 5)
int_TX_empt: 1, // interrupt pending on TX empty (bit 4)
int_RX_full: 1, // interrupt pending on RX full (bit 3)
ign2 : 1, // ignored (bit 2)
framing : 1, // framing error (bit 1)
overun : 1; // overun error (bit 0)
} Tstatus;
typedef union ctlStat { // control + status on same address
Tcontrol ctl; // write-only
Tstatus stat; // read-only
} TctlStat;
typedef union data { // data registers on same address
int tx; // write-only
int rx; // read-only
} Tdata;
typedef struct serial {
TctlStat cs; // @ (int *)IO_UART_ADDR
Tdata d; // @ (int *)(IO_UART_ADDR+1)
} Tserial;
#include "uart_defs.c"
extern int _uart_buff[16]; // declared in include/handlers.s
#define SPEED 2 // operate at 1/4 of the highest data rate
int main(void) { // receive a string through the UART serial interface
volatile Tserial *uart; // tell GCC not to optimize away code
......@@ -61,10 +28,10 @@ int main(void) { // receive a string through the UART serial interface
uart = (void *)IO_UART_ADDR; // bottom of UART address range
ctrl.ign = 0;
ctrl.rts = 0; // make RTS=0 to hold remote unit
ctrl.rts = 0; // make RTS=0 to hold remote unit inactive
ctrl.intTX = 0;
ctrl.intRX = 0;
ctrl.speed = 2; // operate at 1/4 of the highest data rate
ctrl.speed = SPEED;
uart->cs.ctl = ctrl; // initizlize UART
// handler sets flag=bfr[3] to 1 after new character is received;
......@@ -72,10 +39,10 @@ int main(void) { // receive a string through the UART serial interface
bfr[3] = 0; // reset flag
ctrl.ign = 0;
ctrl.rts = 1; // make RTS=1 so RemoteUnit starts its transmission
ctrl.rts = 1; // make RTS=1 to activate remote unit
ctrl.intTX = 0;
ctrl.intRX = 1; // do generate interrupts on RXbuffer full
ctrl.speed = 2; // operate at 1/4 of the highest data rate
ctrl.speed = SPEED; // operate at 1/4 of the highest data rate
uart->cs.ctl = ctrl;
do {
......@@ -83,7 +50,7 @@ int main(void) { // receive a string through the UART serial interface
{}; // nothing new
c = (char)bfr[2]; // get new character
bfr[3] = 0; // and reset flag
to_stdout( (int)c );
to_stdout( (int)c ); // and print new char
} while (c != '\0'); // end of string?
return c;
......
//
// Test UART's reception circuit.
//
// Remote unit reads string from file serial.inp and sends it over the
// serial line. This program prints the string to simulator's stdout.
#include "cMIPS.h"
typedef struct control { // control register fields (uses only ls byte)
int ign : 24, // ignore uppermost bits
rts : 1, // Request to Send output (bit 7)
ign2 : 2, // bits 6,5 ignored
intTX : 1, // interrupt on TX buffer empty (bit 4)
intRX : 1, // interrupt on RX buffer full (bit 3)
speed : 3; // 4,8,16..256 tx-rx clock data rates (bits 0..2)
} Tcontrol;
typedef struct status { // status register fields (uses only ls byte)
unsigned int ign : 24, // ignore uppermost 3 bytes
cts : 1, // Clear To Send input=1 (bit 7)
txEmpty : 1, // TX register is empty (bit 6)
rxFull : 1, // octet available from RX register (bit 5)
int_TX_empt: 1, // interrupt pending on TX empty (bit 4)
int_RX_full: 1, // interrupt pending on RX full (bit 3)
ign1 : 1, // ignored (bit 2)
framing : 1, // framing error (bit 1)
overun : 1; // overun error (bit 0)
} Tstatus;
typedef union ctlStat { // control + status on same address
Tcontrol ctl; // write-only
Tstatus stat; // read-only
} TctlStat;
typedef union data { // data registers on same address
int tx; // write-only
int rx; // read-only
} Tdata;
typedef struct serial {
TctlStat cs;
Tdata d;
} Tserial;
#include "uart_defs.c"
#if 0
......@@ -44,6 +17,8 @@ char s[32]; // = "the quick brown fox jumps over the lazy dog";
char s[32]; // = " ";
#endif
#define SPEED 1
int main(void) { // receive a string through the UART serial interface
int i;
volatile int state;
......@@ -53,22 +28,23 @@ int main(void) { // receive a string through the UART serial interface
uart = (void *)IO_UART_ADDR; // bottom of UART address range
// reset all UART's signals
ctrl.ign = 0;
ctrl.rts = 0; // make RTS=0 to hold RemoteUnit
ctrl.rts = 0; // make RTS=0 to keep RemoteUnit inactive
ctrl.ign2 = 0;
ctrl.intTX = 0;
ctrl.intRX = 0;
ctrl.speed = 1; // operate at the second highest data rate
ctrl.speed = SPEED; // operate at the second highest data rate
uart->cs.ctl = ctrl;
i = -1;
ctrl.ign = 0;
ctrl.rts = 1; // make RTS=1 to activate RemoteUnit
ctrl.rts = 1; // make RTS=1 to activate RemoteUnit
ctrl.ign2 = 0;
ctrl.intTX = 0;
ctrl.intRX = 0;
ctrl.speed = 1; // operate at the second highest data rate
ctrl.speed = SPEED; // operate at the second highest data rate
uart->cs.ctl = ctrl;
do {
......
//
// Test UART's transmission circuit.
//
// Remote unit receives a string over the serial line and prints it
// on the simulator's standard output.
//
#include "cMIPS.h"
typedef struct control { // control register fields (uses only ls byte)
int ign : 24, // ignore uppermost bits
rts : 1, // Request to Send output (bit 7)
ign2 : 2, // bits 6,5 ignored
intTX : 1, // interrupt on TX buffer empty (bit 4)
intRX : 1, // interrupt on RX buffer full (bit 3)
speed : 3; // 4,8,16..256 tx-rx clock data rates (bits 0..2)
} Tcontrol;
typedef struct status { // status register fields (uses only ls byte)
unsigned int ign : 24, // ignore uppermost 3 bytes
cts : 1, // Clear To Send input=1 (bit 7)
txEmpty : 1, // TX register is empty (bit 6)
rxFull : 1, // octet available from RX register (bit 5)
int_TX_empt: 1, // interrupt pending on TX empty (bit 4)
int_RX_full: 1, // interrupt pending on RX full (bit 3)
ign1 : 1, // ignored (bit 2)
framing : 1, // framing error (bit 1)
overun : 1; // overun error (bit 0)
} Tstatus;
typedef union ctlStat { // control + status on same address
Tcontrol ctl; // write-only
Tstatus stat; // read-only
} TctlStat;
typedef union data { // data registers on same address
int tx; // write-only
int rx; // read-only
} Tdata;
typedef struct serial {
TctlStat cs;
Tdata d;
} Tserial;
#include "uart_defs.c"
#define LONG_STRING 1
......@@ -60,14 +33,15 @@ int strcopy(const char *y, char *x)
#define SPEED 0 // operate at the highest data rate
#define COUNTING ((SPEED+1)*100) // how long to wait for last bits to be sent out
// how long to wait for last bits to be sent out before ending simulation
#define COUNTING ((SPEED+1)*100)
int main(void) { // send a string through the UART serial interface
int i;
volatile unsigned int state, val;
volatile Tserial *uart; // tell GCC to not optimize away tests
volatile Tserial *uart; // tell GCC to not optimize away any code
Tcontrol ctrl;
volatile int *counter; // address of counter
......@@ -78,9 +52,9 @@ int main(void) { // send a string through the UART serial interface
s[0] = '1'; s[1] = '2'; s[2] = '3'; s[3] = '\0';
#endif
uart = (void *)IO_UART_ADDR; // UART's address
uart = (void *)IO_UART_ADDR; // UART's address
counter = (int *)IO_COUNT_ADDR; // counter's address
counter = (void *)IO_COUNT_ADDR; // counter's address
ctrl.speed = SPEED;
ctrl.intTX = 0; // no interrupts
......
......@@ -1911,10 +1911,8 @@ begin
i_update := '1';
i_stall := '0';
when cop0reg_COUNT | cop0reg_COMPARE | cop0reg_CAUSE |
cop0reg_EntryLo0 | cop0reg_EntryLo1 | cop0reg_EntryHi =>
i_update := '1';
i_stall := '0';
when cop0reg_Index | cop0reg_Context | cop0reg_Wired =>
cop0reg_EntryLo0 | cop0reg_EntryLo1 | cop0reg_EntryHi |
cop0reg_Index | cop0reg_Context | cop0reg_Wired =>
i_update := '1';
i_stall := '0';
when cop0reg_EPC =>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment