diff --git a/src/include/support/liburiscv/liburiscv.h b/src/include/support/liburiscv/liburiscv.h index a57ece5..ecb20c3 100644 --- a/src/include/support/liburiscv/liburiscv.h +++ b/src/include/support/liburiscv/liburiscv.h @@ -168,4 +168,8 @@ extern void INITCPU(unsigned int cpuid, STATE_PTR start_state); extern int CAS(volatile unsigned int *atomic, unsigned int oldval, unsigned int newval); +extern int ACQUIRE_LOCK(volatile unsigned int *atomic); + +extern int RELEASE_LOCK(volatile unsigned int *atomic); + #endif /* !defined(URISCV_LIBURISCV_H) */ diff --git a/src/include/uriscv/processor_defs.h b/src/include/uriscv/processor_defs.h index 725ad63..e35dbee 100644 --- a/src/include/uriscv/processor_defs.h +++ b/src/include/uriscv/processor_defs.h @@ -293,6 +293,7 @@ #define OP_CSRRSI 0x6 #define OP_CSRRCI 0x7 #define R_TYPE 0x33 +#define A_TYPE 0x2F #define OP_MUL_FUNC7 0x1 #define OP_MUL_FUNC3 0x0 @@ -311,6 +312,12 @@ #define OP_REMU_FUNC3 0x7 #define OP_REMU_FUNC7 0x1 +#define OP_AMOSWAP_FUNC3 0x2 +#define OP_AMOSWAP_FUNC7 0x4 +#define OP_AMOSWAP_RL_FUNC7 0x5 +#define OP_AMOSWAP_AQ_FUNC7 0x6 +#define OP_AMOSWAP_RL_AQ_FUNC7 0x7 + #define OP_ADD_FUNC3 0x0 #define OP_ADD_FUNC7 0x0 #define OP_SUB_FUNC3 0x0 diff --git a/src/support/liburiscv/CMakeLists.txt b/src/support/liburiscv/CMakeLists.txt index c8c3cb8..fcb0036 100644 --- a/src/support/liburiscv/CMakeLists.txt +++ b/src/support/liburiscv/CMakeLists.txt @@ -1,7 +1,7 @@ set(URISCV_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/uriscv) set(LIBURISCV_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include/support/liburiscv) -set(LIBURISCV_CFLAGS -ffreestanding -ansi -Wall -c -static -g -march=rv32imfd -mabi=ilp32d -fno-pic) +set(LIBURISCV_CFLAGS -ffreestanding -ansi -Wall -c -static -g -march=rv32imafd -mabi=ilp32d -fno-pic) set(LIBURISCV_CPPFLAGS -I${PROJECT_SOURCE_DIR}/include) add_custom_target(liburiscv.o ALL diff --git a/src/support/liburiscv/liburiscv.S b/src/support/liburiscv/liburiscv.S index aca3a23..8dca7bc 100644 --- a/src/support/liburiscv/liburiscv.S +++ b/src/support/liburiscv/liburiscv.S @@ -317,3 +317,45 @@ LEAF_FUNC(PANIC) nop jr ra +/* + * INITCPU + * + * SYNOPSIS: + * void INITCPU(u32 cpu_id, state t *start_state) + */ +LEAF_FUNC(INITCPU) + li t0, MCTL_BOOT_PC + li t1, 0x00000100 + sw t1, 0(t0) + + /* Compute starting address for this CPUs stored exception vector */ + li t0, 140 /* 140 is the size of a state_t vector */ + mul t0, t0, a0 + li t1, BIOS_DATA_PAGE_BASE + add t0, t1, t0 + + /* store start_state at start of this CPU's stored exception vector */ + sw a1, 0(t0) + + /*.set noreorder*/ + li t0, MCTL_RESET_CPU + sw a0, 0(t0) + /*.set reorder*/ + + jr ra + +/* + * CAS instruction wrapper + */ +LEAF_FUNC(ACQUIRE_LOCK) + li a1, 0 + li a2, 0 + retry: + amoswap.w a1, a1, 0(a0) + bne a1, a2, retry # if a1 != 0 then goto retry + jr ra + +LEAF_FUNC(RELEASE_LOCK) + li a1, 0 + amoswap.w a1, a1, 0(a0) + jr ra diff --git a/src/uriscv/disassemble.cc b/src/uriscv/disassemble.cc index a01ae68..d07afea 100644 --- a/src/uriscv/disassemble.cc +++ b/src/uriscv/disassemble.cc @@ -211,7 +211,7 @@ HIDDEN void StrRInstr(Word instr) { uint8_t func3 = FUNC3(instr); uint8_t func7 = FUNC7(instr); - if (func7 == 0x20) + if (func7 == 0x20) // sub, sra func7 = 2; if (func7 > 2) { sprintf(strbuf, "unknown instruction"); @@ -223,6 +223,24 @@ HIDDEN void StrRInstr(Word instr) { regName[RS2(instr)]); } +HIDDEN const char *const AInstrName[] = {"amoswap.w", "amoswap.w", "amoswap.w", "amoswap.w"}; + +HIDDEN void StrAInstr(Word instr) { + uint8_t func3 = FUNC3(instr); + uint8_t func7 = FUNC7(instr); + + if (0x4 <= func7 && func7 <= 0x7) { // amoswap.w + func7 -= 4; + } else { + sprintf(strbuf, "unknown instruction A-type %x %x", func3, func7); + return; + } + + sprintf(strbuf, "%s\t%s,%s%s,%s0(%s)", AInstrName[func7], regName[RD(instr)], sep, regName[RS2(instr)], + sep, regName[RS1(instr)]); +} + + HIDDEN const char *const loadInstrName[] = {"lb", "lh", "lw", "", "lbu", "lhu"}; HIDDEN void StrLoadInstr(Word instr) { @@ -559,6 +577,10 @@ const char *StrInstr(Word instr) { StrSInstr(instr); } break; + case A_TYPE: { + StrAInstr(instr); + } break; + case OP_AUIPC: case OP_LUI: { sprintf(strbuf, "%s\t%s,%s0x%x", opcode == OP_LUI ? "lui" : "auipc", diff --git a/src/uriscv/processor.cc b/src/uriscv/processor.cc index dcaaea7..1e61600 100644 --- a/src/uriscv/processor.cc +++ b/src/uriscv/processor.cc @@ -922,7 +922,7 @@ bool Processor::execInstrR(Word instr) { break; } default: { - ERRORMSG("R-type not recognized (%x)\n", FUNC7); + ERRORMSG("R-type not recognized (%x, %x)\n", FUNC3, FUNC7); SignalExc(EXC_II, 0); e = true; break; @@ -931,7 +931,7 @@ bool Processor::execInstrR(Word instr) { break; } /* 0x2 */ - case OP_MULHSU_FUNC3 | OP_SLT_FUNC3: { + case OP_MULHSU_FUNC3 | OP_SLT_FUNC3 | OP_AMOSWAP_FUNC3: { switch (FUNC7) { case OP_MULHSU_FUNC7: { SWord high = 0, low = 0; @@ -946,9 +946,21 @@ bool Processor::execInstrR(Word instr) { regName[rs1], regRead(rs1), regRead(rs2)); regWrite(rd, SWord(regRead(rs1)) < SWord(regRead(rs2)) ? 1 : 0); break; + } + case OP_AMOSWAP_FUNC7: + case OP_AMOSWAP_RL_FUNC7: + case OP_AMOSWAP_AQ_FUNC7: + case OP_AMOSWAP_RL_AQ_FUNC7: { + DISASSMSG("AMOSWAP %d,%d,%s(%x)\n", regRead(rd), regRead(rs2), regName[rs1], regRead(rs1)); + regWrite(rd, regRead(rs1)); + Word datap; + this->bus->DataRead(regRead(rs1), &datap, this); + regWrite(rd, datap); + this->bus->DataWrite(regRead(rs1), regRead(rs2), this); + break; } default: { - ERRORMSG("R-type not recognized (%x)\n", FUNC7); + ERRORMSG("R-type not recognized (%x, %x)\n", FUNC3, FUNC7); SignalExc(EXC_II, 0); e = true; break; @@ -974,7 +986,7 @@ bool Processor::execInstrR(Word instr) { break; } default: { - ERRORMSG("R-type not recognized (%x)\n", FUNC7); + ERRORMSG("R-type not recognized (%x, %x)\n", FUNC3, FUNC7); SignalExc(EXC_II, 0); e = true; break; @@ -1002,7 +1014,7 @@ bool Processor::execInstrR(Word instr) { break; } default: { - ERRORMSG("R-type not recognized (%x)\n", FUNC7); + ERRORMSG("R-type not recognized (%x, %x)\n", FUNC3, FUNC7); SignalExc(EXC_II, 0); e = true; break; @@ -1034,7 +1046,7 @@ bool Processor::execInstrR(Word instr) { break; } default: { - ERRORMSG("R-type not recognized (%x)\n", FUNC7); + ERRORMSG("R-type not recognized (%x, %x)\n", FUNC3, FUNC7); SignalExc(EXC_II, 0); e = true; break; @@ -1060,7 +1072,7 @@ bool Processor::execInstrR(Word instr) { break; } default: { - ERRORMSG("R-type not recognized (%x)\n", FUNC7); + ERRORMSG("R-type not recognized (%x, %x)\n", FUNC3, FUNC7); SignalExc(EXC_II, 0); e = true; break; @@ -1086,7 +1098,7 @@ bool Processor::execInstrR(Word instr) { break; } default: { - ERRORMSG("R-type not recognized (%x)\n", FUNC7); + ERRORMSG("R-type not recognized (%x, %x)\n", FUNC3, FUNC7); SignalExc(EXC_II, 0); e = true; break; @@ -1541,6 +1553,10 @@ bool Processor::execInstr(Word instr) { e = execInstrS(instr); break; } + case A_TYPE: { + e = execInstrR(instr); + break; + } case OP_AUIPC: { DISASSMSG("\tU-type | AUIPC\n"); uint8_t rd = RD(instr);