diff --git a/cMIPS/bin/edMemory.sh b/cMIPS/bin/edMemory.sh index 1d19288588415dd32e393b7f9761cab0545d2c7d..1fa7f2e375b8d99a9e6ab9e7efb895363e35bb7c 100755 --- a/cMIPS/bin/edMemory.sh +++ b/cMIPS/bin/edMemory.sh @@ -58,7 +58,7 @@ asm="${include}"/cMIPS.s VARIABLES="x_INST_BASE_ADDR x_INST_MEM_SZ x_DATA_BASE_ADDR x_DATA_MEM_SZ x_IO_BASE_ADDR x_IO_MEM_SZ x_IO_ADDR_RANGE" -EXCEPTION_VECTORS="x_EXCEPTION_0000 x_EXCEPTION_0180 x_EXCEPTION_0200 x_ENTRY_POINT" +EXCEPTION_VECTORS="x_EXCEPTION_0000 x_EXCEPTION_0100 x_EXCEPTION_0180 x_EXCEPTION_0200 x_ENTRY_POINT" if [ "${dfn}" -nt "${lnk}" ] || [ "${dfn}" -nt "${asm}" ] || [ "${dfn}" -nt "${hdr}" ] ; then diff --git a/cMIPS/include/handlers.s b/cMIPS/include/handlers.s index 2ecddca025c27a98bbde443e2c067905dc58afd7..f6442251fbf4ac5b849afb990b311a9b52f148cc 100644 --- a/cMIPS/include/handlers.s +++ b/cMIPS/include/handlers.s @@ -8,7 +8,7 @@ #---------------------------------------------------------------- # interrupt handler for external counter attached to IP5=HW3 - # for extCounter address -- see vhdl/packageMemory.vhd + # for extCounter address see vhdl/packageMemory.vhd .bss .align 2 diff --git a/cMIPS/include/start.s b/cMIPS/include/start.s index 9adb13c8e0eb92079380d6e14783ae338fb898e5..146e571275ec5212440a323071d05327f0258ffa 100644 --- a/cMIPS/include/start.s +++ b/cMIPS/include/start.s @@ -15,38 +15,71 @@ ## _start: - # set STATUS, cop0, hw interrupt IRQ7,IRQ6,IRQ5 enabled, user mode - li $k0, 0x1000e001 - mtc0 $k0, cop0_STATUS + # get physical page number for 2 pages at the bottom of RAM, for .data + # needed so simulations without a page table will not break + # read TLB[4] and write it to TLB[2] + li $k0, 4 + mtc0 $k0, cop0_Index + ehb + tlbr + li $k1, 2 + mtc0 $k1, cop0_Index + ehb + tlbwi + + # then set another mapping onto TLB[4], to avoid replicated entries + li $a0, ( (x_DATA_BASE_ADDR + 8*4096) >>12 ) + sll $a2, $a0, 12 # tag for RAM[0,1] double-page + mtc0 $a2, cop0_EntryHi + + li $a0, ((x_DATA_BASE_ADDR + 8*4096) >>12 ) + sll $a1, $a0, 6 # RAM[8] (even) + ori $a1, $a1, 0b00000000000000000000000000000111 # ccc=0, d,v,g1 + mtc0 $a1, cop0_EntryLo0 + + li $a0, ( (x_DATA_BASE_ADDR + 9*4096) >>12 ) + sll $a1, $a0, 6 # RAM[9] (odd) + ori $a1, $a1, 0b00000000000000000000000000000111 # ccc=0, d,v,g1 + mtc0 $a1, cop0_EntryLo1 + + # and write it to TLB[4] + li $k0, 4 + mtc0 $k0, cop0_Index + tlbwi + + # get physical page number for two pages at the top of RAM, for stack - li $a0, ( (x_DATA_BASE_ADDR+x_DATA_MEM_SZ - 2*4096) >>12) + li $a0, ( (x_DATA_BASE_ADDR+x_DATA_MEM_SZ - 2*4096) >>12 ) sll $a2, $a0, 12 # tag for top double-page mtc0 $a2, cop0_EntryHi - li $a0, ( (x_DATA_BASE_ADDR+x_DATA_MEM_SZ - 2*4096) >>12) - sll $a1, $a0, 6 # top page - 1 (even) + li $a0, ( (x_DATA_BASE_ADDR+x_DATA_MEM_SZ - 2*4096) >>12 ) + sll $a1, $a0, 6 # top page - 2 (even) ori $a1, $a1, 0b00000000000000000000000000000111 # ccc=0, d,v,g1 mtc0 $a1, cop0_EntryLo0 - li $a0, ( (x_DATA_BASE_ADDR+x_DATA_MEM_SZ - 1*4096) >>12) - sll $a1, $a0, 6 # top page - 1 (even) + li $a0, ( (x_DATA_BASE_ADDR+x_DATA_MEM_SZ - 1*4096) >>12 ) + sll $a1, $a0, 6 # top page - 1 (odd) ori $a1, $a1, 0b00000000000000000000000000000111 # ccc=0, d,v,g1 mtc0 $a1, cop0_EntryLo1 - # and write it to TLB(2) -- third mapping + # and write it to TLB[3] li $k0, 3 mtc0 $k0, cop0_Index tlbwi - # pin down first three MMU entries: ROM[0], stack and I/O - li $k0, 3 + # pin down first four TLB entries: ROM[0], RAM[0], stack and I/O + li $k0, 4 mtc0 $k0, cop0_Wired # initialize SP: ramTop-8 li $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) - nop + # set STATUS, cop0, hw interrupt IRQ7,IRQ6,IRQ5 enabled, user mode + li $k0, 0x1000e011 + mtc0 $k0, cop0_STATUS + jal main # on returning from main(), MUST go into exit() nop # to stop the simulation. exit: @@ -83,12 +116,11 @@ _excp_0000: #---------------------------------------------------------------- # handler for NMI or soft-reset -- simply abort simulation -nmi_reset_handler: mfc0 $k1,cop0_CAUSE # read CAUSE nop wait 0x38 # abort simulation, no code in Table 8-25 - nop - # j excp_0000ret # OR do something else! + nop # + # j excp_0000ret # OR do something else .end _excp_0000 ## diff --git a/cMIPS/vhdl/packageMemory.vhd b/cMIPS/vhdl/packageMemory.vhd index da8c7e8ed668f8a92803b68add24488a418b3a6a..7f9d45d7a876bf8ce5bb6ea52b04e7810d40ffa7 100644 --- a/cMIPS/vhdl/packageMemory.vhd +++ b/cMIPS/vhdl/packageMemory.vhd @@ -24,9 +24,10 @@ package p_MEMORY is -- To simplify (and accelerate) the RAM address decoding, -- the BASE of the RAM addresses MUST be allocated at an - -- address that is above/larger the the RAM capacity. Otherwise, - -- the base must be subtracted from the address on every reference, - -- which means having an adder in the critical path. Not good. + -- address which is at a different power of two than the ROM base. + -- Otherwise, the base must be subtracted from the address on every + -- reference, which means having an adder in the critical path. + -- Not good at all. -- The address ranges for ROM, RAM and I/O must be distinct in the -- uppermost 16 bits of the address (bits 31..16). @@ -47,10 +48,10 @@ package p_MEMORY is constant x_IO_BASE_ADDR : reg32 := x"0F000000"; constant x_IO_MEM_SZ : reg32 := x"00002000"; constant x_IO_ADDR_RANGE : reg32 := x"00000020"; - constant x_EXCEPTION_0000 : reg32 := x"00000080"; + constant x_EXCEPTION_0000 : reg32 := x"000000E0"; constant x_EXCEPTION_0100 : reg32 := x"00000100"; constant x_EXCEPTION_0180 : reg32 := x"00000180"; - constant x_EXCEPTION_0200 : reg32 := x"00000280"; + constant x_EXCEPTION_0200 : reg32 := x"00000300"; constant x_ENTRY_POINT : reg32 := x"00000400"; -- end DO NOT change these names --