Commit 791396a2 authored by Roberto Hexsel's avatar Roberto Hexsel

page table walk, several fixes

parent e21ec516
Pipeline #4069 skipped
......@@ -32,6 +32,7 @@ OPTIONS:
-h Show this message
-O n Optimization level, defaults to n=0 {0,1,2,3}
-v Verbose, creates memory map: SOURCE.map
-n when verbose, display register names instead of numbers
-mif Generate output file ROM.mif for Altera's FPGAs
EOF
}
......@@ -54,6 +55,7 @@ if [ $# = 0 ] ; then usage ; exit 1 ; fi
miffile=false
verbose=false
names=false
unset mem_map
level=0
......@@ -82,6 +84,8 @@ while true ; do
;;
-v) verbose=true
;;
-n) names=true
;;
-mif|-m) miffile=true
;;
-x) set -x
......@@ -105,6 +109,12 @@ fi
if [ $verbose = true ] ; then mem_map="-Map ${inp}.map" ; fi
if [ $names = true ] ; then
reg_names="-M reg-names=mips2r2 -M cp0-names=mips2r2"
else
reg_names="-M reg-names=numeric -M cp0-names=numeric"
fi
asm=${inp}.s
obj=${inp}.o
elf=${inp}.elf
......@@ -114,18 +124,15 @@ dat=data.bin
(mips-as -O${level} -EL -mips32r2 -I "${include}" -o $obj $asm || exit 1) &&\
mips-ld -EL ${mem_map} -I "${include}" --script $c_ld -o $elf $obj &&\
mips-objcopy -S -j .text -O binary $elf $bin &&\
mips-objcopy -S -j .data -j .rodata -O binary $elf $dat &&\
mips-objcopy -S -j .data -j .rodata -j .PT -O binary $elf $dat &&\
chmod a-x $bin $dat &&\
if [ $verbose = true ] ; then
mips-objdump -z -D -EL -M reg-names=numeric -M cp0-names=mips2r2 \
--show-raw-insn \
mips-objdump -z -D -EL $reg_names --show-raw-insn \
--section .text --section .data --section .rodata --section .bss $elf
fi &&\
if [ $miffile = true ] ; then
elf2mif.sh "$elf" || exit 1
fi
# -M reg-names=mips2r2 -M cp0-names=mips2r2 reg-names=numeric \
# --section .reginfo
......@@ -33,6 +33,7 @@ OPTIONS:
-h Show this message
-O n Optimization level, defaults to n=1 {0,1,2,3}
-v Verbose, creates memory map: source.map
-n when verbose, display register numbers instead of names
-W Pass -Wall on to GCC
-mif Generate output file ROM.mif for Altera's FPGAs
-syn Compile for synthesis, else for simulation
......@@ -57,6 +58,7 @@ if [ $# = 0 ] ; then usage ; exit 1 ; fi
miffile=false
synth=false
verbose=false
names=true
unset memory_map
level=1
......@@ -80,6 +82,8 @@ while true ; do
;;
-v) verbose=true
;;
-n) names=false
;;
-mif) miffile=true
;;
-syn) synth=true
......@@ -146,15 +150,20 @@ mips-ld -EL -e _start ${memory_map} -I "${include}" --script $c_ld \
mips-objcopy -S -j .text -O binary $elf $bin && \
mips-objcopy -S -j .data -j .rodata -j .rodata1 -j .data1 \
-j .sdata -j .lit8 -j .lit4 -j .sbss -j .bss \
-j .sdata -j .lit8 -j .lit4 -j .sbss -j .bss -j .PT \
-O binary $elf $dat || exit 1
if [ $names = true ] ; then
reg_names="-M reg-names=mips2r2 -M cp0-names=mips2r2"
else
reg_names="-M reg-names=numeric -M cp0-names=numeric"
fi
if [ $? == 0 -a $verbose = true ]; then
mips-objdump -z -D -EL -M reg-names=mips2r2 -M cp0-names=mips2r2 \
--show-raw-insn \
mips-objdump -z -D -EL $reg_names --show-raw-insn \
--section .text --section .data \
--section .rodata --section .sdata --section .sbss \
--section .bss $elf
--section .bss --section .PT $elf
fi
if [ $? == 0 -a $miffile = true ] ; then
......
No preview for this file type
#define x_INST_BASE_ADDR 0x00000000
#define x_DATA_BASE_ADDR 0x00010000
#define x_DATA_BASE_ADDR 0x00040000
#define x_DATA_MEM_SZ 0x00020000
#define x_SDRAM_BASE_ADDR 0x04000000
#define x_SDRAM_MEM_SZ 0x02000000
#define x_IO_BASE_ADDR 0x3c000000
......
......@@ -5,8 +5,8 @@ MEMORY
{
rom (rx) : ORIGIN = 0x00000000, /* x_INST_BASE_ADDR */
LENGTH = 0x00004000, /* x_INST_MEM_SZ */
ram (!rx) : ORIGIN = 0x00010000, /* x_DATA_BASE_ADDR */
LENGTH = 0x00008000, /* x_DATA_MEM_SZ */
ram (!rx) : ORIGIN = 0x00040000, /* x_DATA_BASE_ADDR */
LENGTH = 0x00020000, /* x_DATA_MEM_SZ */
sdram (!rx) : ORIGIN = 0x04000000, /* x_SDRAM_BASE_ADDR */
LENGTH = 0x02000000, /* x_SDRAM_MEM_SZ */
io (!rx) : ORIGIN = 0x3c000000, /* not used, do not remove */
......@@ -40,8 +40,9 @@ SECTIONS
_end = . ; /* end of image constant (from Xinu) */
} > ram
end_RAM = 0x00008000; /* x_DATA_MEM_SZ */
end_RAM = 0x00020000; /* x_DATA_MEM_SZ */
half_RAM = (end_RAM / 2);
base_TP = ( _bdata + half_RAM );
.TP base_TP : { *(.TP) } > ram
base_PT = ( _bdata + half_RAM );
.PT base_PT : { *(.PT) } > ram
}
......@@ -3,8 +3,8 @@
.set x_INST_BASE_ADDR,0x00000000
.set x_INST_MEM_SZ,0x00004000
.set x_DATA_BASE_ADDR,0x00010000
.set x_DATA_MEM_SZ,0x00008000
.set x_DATA_BASE_ADDR,0x00040000
.set x_DATA_MEM_SZ,0x00020000
.set x_IO_BASE_ADDR,0x3c000000
.set x_IO_MEM_SZ,0x00002000
......@@ -71,8 +71,9 @@
# reset: COP0 present, at exception level, all else disabled
.set cop0_STATUS_reset,0x10000002
.set c0_status_reset, cop0_STATUS_reset
# normal state: COP0 present, user mode, all IRQs enabled
.set cop0_STATUS_normal,0x1000ff11
# reset: COUNTER stopped, use special interrVector, no interrupts
.set cop0_CAUSE_reset, 0x0880007c
.set c0_cause_reset, cop0_CAUSE_reset
......@@ -348,10 +348,10 @@ void DSP7SEGput(int MSD, int MSdot, int lsd, int lsdot) {
//=======================================================================
// external counter -- counts down to zero and stops or interrupts
// external counter -- counts up to limit, then stops or interrupts
//=======================================================================
// write an integer with number of pulses to count and start counter
// if interr is not 0, then will interrupt when count reaches zero
// if interr is not 0, then raise an interrupt when count reaches 'n'
void startCounter(int n, int interr) {
int *IO = (int *)IO_COUNT_ADDR;
int interrupt;
......
......@@ -4,7 +4,7 @@
.set noreorder
.align 2
.set M_StatusIEn,0x0000ff09 # STATUS.intEn=1, user mode
.set M_StatusIEn,0x0000ff11 # STATUS.intEn=1, user mode
#----------------------------------------------------------------
# interrupt handler for external counter attached to IP5=HW3
......@@ -57,11 +57,11 @@ extCounter:
# lw $a1, 1*4($k1)
#----------------------------------
mfc0 $k0, cop0_STATUS # Read STATUS register
mfc0 $k0, c0_status # Read STATUS register
ori $k0, $k0, M_StatusIEn # but do not modify its contents
addiu $k1, $zero, -7 # except for re-enabling interrupts
and $k0, $k1, $k0 # -7 = 0xffff.fff9
mtc0 $k0, cop0_STATUS
mtc0 $k0, c0_status
eret # Return from interrupt
.end extCounter
#----------------------------------------------------------------
......@@ -102,10 +102,10 @@ UARTinterr:
lui $k0, %hi(_uart_buff)
ori $k0, $k0, %lo(_uart_buff)
sw $k1, 0($k0) # and save UART status to memory
sw $k1, 0*4($k0) # and save UART status to memory
sw $a0, 12($k0) # save registers $a0,$a1, others?
sw $a1, 16($k0)
sw $a0, 5*4($k0) # save registers $a0,$a1, others?
sw $a1, 6*4($k0)
#----------------------------------
# while you are developing the complete handler,
......@@ -115,7 +115,7 @@ UARTinterr:
andi $a0, $k1, UART_rx_irq # Is this reception?
beq $a0, $zero, UARTret # no, ignore it and return
lui $a0, %hi(HW_uart_addr)
ori $a0, $a0, %lo(HW_uart_addr)
lw $a1, 4($a0) # Read data
......@@ -125,14 +125,14 @@ UARTinterr:
sw $a1, 8($k0) # Signal new arrival
UARTret:
lw $a1, 16($k0) # restore registers $a0,$a1, others?
lw $a0, 12($k0)
lw $a1, 6*4($k0) # restore registers $a0,$a1, others?
lw $a0, 5*4($k0)
mfc0 $k0, cop0_STATUS # Read STATUS register
mfc0 $k0, c0_status # Read STATUS register
ori $k0, $k0, M_StatusIEn # but do not modify its contents
addiu $k1, $zero, -7 # except for re-enabling interrupts
and $k0, $k1, $k0 # -7 = 0xffff.fff9 = user mode
mtc0 $k0, cop0_STATUS
mtc0 $k0, c0_status
eret # Return from interrupt
.end UARTinterr
#----------------------------------------------------------------
......@@ -145,16 +145,16 @@ UARTret:
.global countCompare
.ent countCompare
countCompare:
mfc0 $k1,cop0_COUNT # read COMPARE and clear IRQ
mfc0 $k1,c0_count # read COMPARE and clear IRQ
addiu $k1,$k1,64 # set next interrupt in 64 ticks
mtc0 $k1,cop0_COMPARE
mtc0 $k1,c0_compare
mfc0 $k0, cop0_STATUS # Read STATUS register
mfc0 $k0, c0_status # Read STATUS register
ori $k0, $k0, M_StatusIEn # but do not modify its contents
lui $k1, 0xffff # except for re-enabling interrupts
ori $k1, $k1, 0xfff9 # and going into user mode
and $k0, $k1, $k0
mtc0 $k0, cop0_STATUS
mtc0 $k0, c0_status
eret # Return from interrupt
.end countCompare
#----------------------------------------------------------------
......
This diff is collapsed.
......@@ -13,7 +13,7 @@
extern void exit(int);
extern void print(int);
extern int readInt(int *);
extern int readInt(int *);
extern void writeInt(int);
#else
......
......@@ -5,7 +5,7 @@
#include "cMIPS.h"
#define FALSE (0==1)
#define TRUE ~(FALSE)
#define TRUE !(FALSE)
#define N 4
#define CNT_VALUE 0x40000040 // set count to 64 cycles
......
......@@ -5,7 +5,7 @@
#define MAX 100
#define FALSE (0==1)
#define TRUE ~FALSE
#define TRUE !FALSE
extern int _counter_val;
......
......@@ -11,15 +11,13 @@
.global _start
.global _exit
.set c0_cause_rst, 0x0880007c # disable counter, separate IntVector
_start: nop
li $k0, c0_status_reset # RESET, kernel mode, all else disabled
li $k0, cop0_STATUS_reset # RESET, kernel mode, all else disabled
mtc0 $k0, c0_status
li $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: ramTop-8
li $k0, 0x1000ff01 # RESET_STATUS, kernel mode, interr enabled
mtc0 $k0, c0_status
li $k0, c0_cause_rst # RESET, disable counter
li $k0, cop0_CAUSE_reset # RESET, disable counter
mtc0 $k0, c0_cause
la $15,x_IO_BASE_ADDR
......
......@@ -5,9 +5,10 @@
# 2nd test: lo priority (external cntr) arrives first
# then the two alternate
# Testing the internal counter is difficult because it counts clock cycles
# Testing the counters is difficult because they count clock cycles
# rather than instructions -- if the I/O or memory latencies change then
# the simulation output also changes and comparisons may be impossible.
# the simulation output also changes and comparisons to the expected values
# may/will fail.
.include "cMIPS.s"
......@@ -19,16 +20,15 @@
.global _start
.global _exit
.set c0_cause_rst, 0x0880007c # disable counter, separate IntVector
.set ext_restart, 0xc0000000 # start ext_counter, intrr enable
_start: nop
li $k0, c0_status_reset # RESET, kernel mode, all else disabled
li $k0, cop0_STATUS_reset # RESET, kernel mode, all else disabled
mtc0 $k0, c0_status
li $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: ramTop-8
li $k0, 0x1000ff01 # RESET_STATUS, kernel mode, interr enabled
li $k0, 0x1000ff01 # RESET_STATUS, kernel mode, interr enabled
mtc0 $k0, c0_status
li $k0, c0_cause_rst # RESET, disable counter
li $k0, cop0_CAUSE_reset # RESET, disable counter
mtc0 $k0, c0_cause
la $15,x_IO_BASE_ADDR
......
//
// This program references a wide range of addresses to do a walk over
// several entries of the Page Table (PT).
// As the pages are referenced, the TLB must be refilled with entries from
// the PT.
//
// This program needs a large (simulated) RAM. RAM must be allocated
// so that the bottom half is "usable memory" and the top half is
// allocated to the Page Table. The base address and RAM size must
// be set on file vhdl/packageMemory.vhd.
//
// x_DATA_BASE_ADDR : reg32 := x"00040000";
// x_DATA_MEM_SZ : reg32 := x"00020000";
//
// With this much memory, simulations run slowly. No free lunch.
#include "cMIPS.h"
#define FALSE (0==1)
#define TRUE !FALSE
#define MAX_RAM ( x_DATA_BASE_ADDR + (x_DATA_MEM_SZ / 2) )
#define NUM_RAM_PAGES ( (x_DATA_MEM_SZ / 2) / 4096 )
void main(void) {
int i;
int *walker;
// write to the middle of all pages
walker = (int *)(x_DATA_BASE_ADDR + 1024);
for( i = 0 ; i < NUM_RAM_PAGES; i++){
*walker = i;
walker = (int *)((int)walker + 4096);
}
// and now read what was written
walker = (int *)(x_DATA_BASE_ADDR + 1024);
for( i = 0 ; i < NUM_RAM_PAGES; i++){
print( *walker );
walker = (int *)((int)walker + 4096);
}
to_stdout('\n');
to_stdout('o');
to_stdout('k');
to_stdout('\n');
}
00000000
00000001
00000002
00000003
00000004
00000005
00000006
00000007
00000008
00000009
0000000a
0000000b
0000000c
0000000d
0000000e
0000000f
ok
......@@ -8,8 +8,8 @@
#endif
#define MAX 100
#define FALSE 0
#define TRUE 1
#define FALSE (0==1)
#define TRUE !FALSE
int p[MAX] = {0};
......
#!/bin/bash
# set -x
if [ ! -v tree ] ; then
# you must set the location of the cMIPS root directory in the variable tree
# tree=${HOME}/cmips-code/cMIPS
export tree="$(echo $PWD | sed -e 's:^\(/.*/cMIPS\)/.*:\1:')"
fi
srcVHDL=${tree}/vhdl
pack=$srcVHDL/packageWires.vhd
# for ROM in 0 1 2 3 5 10 13 14; do
for ROM in 0 1 ; do
sed -i -e "/ROM_WAIT_STATES/s/ := \([0-9][0-9]*\);/ := ${ROM};/" $pack
echo -n "rom=$ROM"
# for RAM in 0 1 15 11 10 5 4 3 2; do
for RAM in 0 1 ; do
sed -i -e "/RAM_WAIT_STATES/s/ := \([0-9][0-9]*\);/ := ${RAM};/" $pack
echo " ram=$RAM"
./doTests.sh || exit 1
done
done
sed -i -e "/ROM_WAIT_STATES/s/ := \([0-9][0-9]*\);/ := 0;/" \
-e "/RAM_WAIT_STATES/s/ := \([0-9][0-9]*\);/ := 0;/" $pack
//
// Test interrupts caused by UART's reception circuit.
//
// Remote unit reads string from serial.inp and sends it over the
// serial line.
//
// UARTinterr, in include/handlers.s, reads newly arrived character,
// sets a flag and puts character in a buffer. main() reads from the
// buffer and prints it to the simulator's standard output.
#include "cMIPS.h"
typedef struct control { // control register fields (uses only ls byte)
......@@ -38,7 +49,7 @@ typedef struct serial {
} Tserial;
extern int _uart_buff[16];
extern int _uart_buff[16]; // declared in include/handlers.s
int main(void) { // receive a string through the UART serial interface
......
......@@ -1977,7 +1977,7 @@ begin
end if;
newSTATUS(STATUS_EXL) := '1'; -- at exception level
newSTATUS(STATUS_UM) := '0'; -- enter kernel mode
newSTATUS(STATUS_IE) := '0'; -- disable interrupts
-- newSTATUS(STATUS_IE) := '0'; -- disable interrupts
i_update := '1';
i_update_r := cop0reg_STATUS;
i_stall := '0'; -- do not stall
......@@ -1996,7 +1996,7 @@ begin
ExcCode <= cop0code_Tr;
newSTATUS(STATUS_EXL) := '1'; -- at exception level
newSTATUS(STATUS_UM) := '0'; -- enter kernel mode
newSTATUS(STATUS_IE) := '0'; -- disable interrupts
-- newSTATUS(STATUS_IE) := '0'; -- disable interrupts
i_update := '1';
i_update_r := cop0reg_STATUS;
i_stall := '0';
......@@ -2026,7 +2026,7 @@ begin
when exOvfl => -- OVERFLOW happened one cycle earlier
newSTATUS(STATUS_EXL) := '1'; -- at exception level
newSTATUS(STATUS_IE) := '0'; -- disable interrupts
-- newSTATUS(STATUS_IE) := '0'; -- disable interrupts
exception_taken <= '1';
i_update := '1';
i_update_r := cop0reg_STATUS;
......@@ -2042,8 +2042,7 @@ begin
end if;
when IFaddressError =>
-- fetch from UNALIGNED ADDRESS
when IFaddressError => -- fetch from UNALIGNED ADDRESS
newSTATUS(STATUS_EXL) := '1'; -- at exception level
newSTATUS(STATUS_IE) := '0'; -- disable interrupts
exception_taken <= '1';
......@@ -2097,7 +2096,7 @@ begin
is_delayslot <= '0';
end if;
newSTATUS(STATUS_EXL) := '1'; -- at exception level
newSTATUS(STATUS_IE) := '0'; -- disable interrupts
-- newSTATUS(STATUS_IE) := '0'; -- disable interrupts
i_update := '1';
i_update_r := cop0reg_STATUS;
i_epc_update := '0';
......@@ -2120,7 +2119,7 @@ begin
is_delayslot <= MM_is_delayslot;
end if;
newSTATUS(STATUS_EXL) := '1'; -- at exception level
newSTATUS(STATUS_IE) := '0'; -- disable interrupts
-- newSTATUS(STATUS_IE) := '0'; -- disable interrupts
i_update := '1';
i_update_r := cop0reg_STATUS;
i_epc_update := '0';
......@@ -2136,7 +2135,7 @@ begin
is_delayslot <= '0';
end if;
newSTATUS(STATUS_EXL) := '1'; -- at exception level
newSTATUS(STATUS_IE) := '0'; -- disable interrupts
-- newSTATUS(STATUS_IE) := '0'; -- disable interrupts
i_update := '1';
i_update_r := cop0reg_STATUS;
i_epc_update := '0';
......@@ -2162,7 +2161,7 @@ begin
is_delayslot <= MM_is_delayslot;
end if;
newSTATUS(STATUS_EXL) := '1'; -- at exception level
newSTATUS(STATUS_IE) := '0'; -- disable interrupts
-- newSTATUS(STATUS_IE) := '0'; -- disable interrupts
i_update := '1';
i_update_r := cop0reg_STATUS;
i_epc_update := '0';
......@@ -3011,7 +3010,7 @@ begin
-- TLB entry 6 -- initialized to 1st,2nd pages of SDRAM
-- TLB entry 6 -- initialized to RAM 5th, 6th (1st,2nd pages of SDRAM)
MMU_TAG6: register32 generic map(MMU_ini_tag_RAM4)
port map (clk, rst, tlb_tag6_updt, tlb_tag_inp, tlb_tag6);
......
......@@ -42,8 +42,8 @@ package p_MEMORY is
-- you may change the values, not names neither formatting --
constant x_INST_BASE_ADDR : reg32 := x"00000000";
constant x_INST_MEM_SZ : reg32 := x"00004000";
constant x_DATA_BASE_ADDR : reg32 := x"00010000";
constant x_DATA_MEM_SZ : reg32 := x"00008000";
constant x_DATA_BASE_ADDR : reg32 := x"00040000";
constant x_DATA_MEM_SZ : reg32 := x"00020000";
constant x_IO_BASE_ADDR : reg32 := x"3c000000";
constant x_IO_MEM_SZ : reg32 := x"00002000";
constant x_IO_ADDR_RANGE : reg32 := x"00000020";
......
......@@ -856,7 +856,7 @@ begin
end if;
when st_init => -- 0
outDat <= '1';
tx_run <= '1'; -- start TX clock
tx_run <= '1'; -- start TX clock
tx_next_st <= st_idle;
when st_idle => -- 1
if not endfile(input_stream) then
......@@ -866,7 +866,7 @@ begin
bfr := x"0a"; -- new line
j := 0;
elsif sentence'length = 0 then
bfr := x"0a"; -- send new line for empty line
bfr := x"0a"; -- send new line for empty line
-- assert false report "empty line: " & integer'image(j)&" " & LF;
else
read (sentence, char, good);
......@@ -910,7 +910,7 @@ begin
tx_next_st <= st_idle;
when st_done => -- 13 wait forever
if send_null = FALSE then
bfr := x"00"; -- send out a NULL character
bfr := x"00"; -- send out a NULL character
send_null := TRUE;
tx_next_st <= st_start;
else
......
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