Skip to content

Commit

Permalink
Add multiprocessor support
Browse files Browse the repository at this point in the history
Co-authored-by: Luca Orlandello <[email protected]>
  • Loading branch information
Luca Bassi and llllluca committed Dec 17, 2024
1 parent 87cc141 commit ba2b0d5
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 16 deletions.
4 changes: 4 additions & 0 deletions src/include/support/liburiscv/liburiscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,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) */
1 change: 1 addition & 0 deletions src/include/uriscv/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,6 @@
#define CSR_INDEX 0x802
#define CSR_RANDOM 0x803
#define CSR_BADVADDR 0x804
#define PRID 0x805

#endif
7 changes: 7 additions & 0 deletions src/include/uriscv/processor_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,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
Expand All @@ -295,6 +296,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
Expand Down
43 changes: 41 additions & 2 deletions src/support/bios/exec.S
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#define ASIDSTEP 0x00000040
#define VPNMASK 0xFFFFF000
#define VECTSIZE 140
#define STATE_T_SIZE_IN_BYTES 148

/* NOP padding: 30 nops - string length (32 bytes) */
#define PANIC_PADDING (30 * 4) - 32
Expand Down Expand Up @@ -59,7 +59,7 @@ bios:
* 0x00000000 address
* This is the entry point for UTLB type exceptions.
*/
j LEXCHandler
j LEXCHandler
nop

EndStr:
Expand All @@ -73,6 +73,45 @@ PanicStr:
* 0x00000080: panic()
* Print a message on terminal 0 and loop forever
*/
j LPanic
nop

.space 0x80 - 0x8
/*
* 0x00000100 address
* Secondary processor startup routine
*/
j LInitSecondaryProcessor
nop

/*
* Get a cpu up and runing: initialize BIOS related structures and
* load the supplied processor state.
*/
LInitSecondaryProcessor:
/* Initialize ptr to exception state vector */
li t0, STATE_T_SIZE_IN_BYTES
csrrw t1, PRID, zero
mul t0, t0, t1
li t2, BIOS_DATA_PAGE_BASE
add t0, t0, t2
li t2, BIOS_EXCPT_VECT_BASE
sw t0, 0(t2)

/* Initialize ptr to PC/SP area */
li t0, 16
mul t0, t0, t1
li t1, BIOS_EXEC_HANDLERS_ADDRS
add t0, t0, t1
li t2, BIOS_PC_AREA_BASE
sw t0, 0(t2)

/* Load the new state - address of start_state cached at start of exception vector */
li t0, BIOS_EXCPT_VECT_BASE
lw t2, 0(t0)
lw t2, 0(t2)
WRITEK0(t2)
j LLoadStart

LPanic:
li a0, PANICSTRADDR - 1
Expand Down
2 changes: 1 addition & 1 deletion src/support/liburiscv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,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
Expand Down
44 changes: 43 additions & 1 deletion src/support/liburiscv/liburiscv.S
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include "uriscv/cpu.h"
#include "uriscv/const.h"

#define STATE_T_SIZE_IN_BYTES 148
#define INIT_SECONDARY_PROCESSOR_ROUTINE_ADDRESS 0x00000100

#define LEAF_FUNC(func) \
.globl func; \
.type func, @function; \
Expand Down Expand Up @@ -86,7 +89,7 @@ LEAF_FUNC(getEPC)
jr ra

LEAF_FUNC(getPRID)
addi a0,a0,3
csrrw a0,PRID,zero
jr ra

LEAF_FUNC(getMIE)
Expand Down Expand Up @@ -325,3 +328,42 @@ 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, INIT_SECONDARY_PROCESSOR_ROUTINE_ADDRESS

sw t1, 0(t0)

/* Compute starting address for this CPUs stored exception vector */
li t0, STATE_T_SIZE_IN_BYTES
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)

li t0, MCTL_RESET_CPU
sw a0, 0(t0)

jr ra


LEAF_FUNC(ACQUIRE_LOCK)
li t0, 1
li t1, 0
retry:
amoswap.w t0, t0, 0(a0)
bne t0, t1, retry # if a1 != 0 then goto retry
jr ra

LEAF_FUNC(RELEASE_LOCK)
li t0, 0
amoswap.w t0, t0, 0(a0)
jr ra
23 changes: 22 additions & 1 deletion src/uriscv/disassemble.cc
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,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");
Expand All @@ -207,6 +207,23 @@ 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) {
Expand Down Expand Up @@ -543,6 +560,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",
Expand Down
45 changes: 34 additions & 11 deletions src/uriscv/processor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ void Processor::initCSR() {

csr[TIME].perm = RRR;
csr[TIMEH].perm = RRR;
csr[PRID].perm = RRR;

csr[INSTRET].perm = RRR;
csr[MINSTRET].perm = NNW;
Expand Down Expand Up @@ -270,6 +271,9 @@ void Processor::Reset(Word pc, Word sp) {
csrWrite(MIE, 0);
csrWrite(MCAUSE, 0);
csrWrite(TIME, 0);
csrWrite(PRID, id);
csrWrite(MIP, 0);
csrWrite(MTVEC, 0);
mode = 0x3;

currPC = pc;
Expand Down Expand Up @@ -451,7 +455,9 @@ void Processor::getPrevStatus(Word *pc, Word *instr) {
// exception happened (thanks to excName[] array)
const char *Processor::getExcCauseStr() {
// 0 means no exception
if (excCause)
if (CAUSE_IS_INT(excCause))
return "INT";
else if (excCause)
return excName[excCause];
else
return (EMPTYSTR);
Expand Down Expand Up @@ -618,9 +624,9 @@ void Processor::popKUIEStack() {
// otherwise, and sets CP0 registers if needed
bool Processor::checkForInt() {
// check if interrupts are enabled and pending
if (csrRead(MSTATUS) & MSTATUS_MIE_MASK && (csrRead(MIE) & csrRead(MIP))) {
uint mip = csrRead(MIE) & csrRead(MIP);
if (csrRead(MSTATUS) & MSTATUS_MIE_MASK && mip) {
uint l = 0;
uint mip = csrRead(MIP);
while (mip > 1) {
mip >>= 1;
l++;
Expand Down Expand Up @@ -909,7 +915,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;
Expand All @@ -918,7 +924,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;
Expand All @@ -933,9 +939,22 @@ 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));
Word datap;
Word reg1 = regRead(rs1);
Word reg2 = regRead(rs2);
this->bus->DataRead(reg1, &datap, this);
regWrite(rd, datap);
this->bus->DataWrite(reg1, reg2, 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;
Expand All @@ -961,7 +980,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;
Expand Down Expand Up @@ -989,7 +1008,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;
Expand Down Expand Up @@ -1021,7 +1040,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;
Expand All @@ -1047,7 +1066,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;
Expand All @@ -1073,7 +1092,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;
Expand Down Expand Up @@ -1528,6 +1547,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);
Expand Down

0 comments on commit ba2b0d5

Please sign in to comment.