Skip to content

Commit 2f09cde

Browse files
committed
Fix incorrect shift.
1 parent 7c30dc1 commit 2f09cde

File tree

1 file changed

+46
-15
lines changed

1 file changed

+46
-15
lines changed

mini-rv32ima/mini-rv32ima.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct InternalCPUState
3434
uint32_t mcause;
3535
uint32_t reserved[21];
3636
uint8_t uart8250[8]; //@248
37+
uint8_t * image;
3738
};
3839

3940

@@ -136,6 +137,7 @@ int main( int argc, char ** argv )
136137
core.pc = ram_image_offset;
137138
core.registers[10] = 0x00; //hart ID
138139
core.registers[11] = dtb_ptr?(dtb_ptr+0x80000000):0; //dtb_pa (Must be valid pointer) (Should be pointer to dtb)
140+
core.image = ram_image;
139141

140142
// Image is loaded.
141143
int rt;
@@ -180,11 +182,17 @@ int ReadCSR( struct InternalCPUState * state, int csr )
180182
}
181183
}
182184

183-
void WriteCSR( struct InternalCPUState * state, int csr, int value )
185+
void WriteCSR( struct InternalCPUState * state, int csr, uint32_t value )
184186
{
185187
printf( "%04x = %08x\n", csr, value );
186188
switch( csr )
187189
{
190+
case 0x137:
191+
{
192+
// Special, side-channel printf.
193+
printf( "SIDE-CHANNEL-DEBUG: %s\n", state->image + value - 0x80000000 );
194+
break;
195+
}
188196
case 0x340: state->mscratch = value; break;
189197
case 0x305: state->mtvec = value; break;
190198
case 0x304: state->mie = value; break;
@@ -317,9 +325,11 @@ int StepInstruction( struct InternalCPUState * state, uint8_t * image, uint32_t
317325
if( rsval >= 0x90000000 && rsval < 0x90000008 )
318326
{
319327
//Special: UART.
320-
printf( "****************************Read UART: %08x\n", rsval );
321-
rsval = (rsval - 0x90000000) - (intptr_t)image + (intptr_t)state->uart8250;
322-
state->uart8250[5] |= 0x20;
328+
//if(rsval != 0x90000005 ) printf( "****************************Read UART: %08x %08x\n", rsval, pc );
329+
rsval = (rsval - 0x90000000);
330+
state->uart8250[5] |= 0x60;
331+
//printf( "=> %08x\n", *((uint32_t*)(image + rsval)) );
332+
if( rdid ) regs[rdid] = state->uart8250[rsval];
323333
}
324334
else if( rsval >= ram_amt-3 )
325335
{
@@ -356,7 +366,15 @@ int StepInstruction( struct InternalCPUState * state, uint8_t * image, uint32_t
356366
if( addy >= 0x90000000 && addy < 0x90000008 )
357367
{
358368
//Special: UART.
359-
printf( "************************** Write UART: %08x -> %08x\n", addy, rs2 );
369+
if( addy == 0x90000000 )
370+
{
371+
printf( "%c", rs2 );
372+
fflush( stdout );
373+
}
374+
else
375+
{
376+
printf( "************************** Write UART: %08x -> %08x\n", addy, rs2 );
377+
}
360378
addy = (addy - 0x90000000) - (intptr_t)image + (intptr_t)state->uart8250;
361379
}
362380
else if( addy >= ram_amt-3 )
@@ -416,16 +434,25 @@ int StepInstruction( struct InternalCPUState * state, uint8_t * image, uint32_t
416434
{
417435
// RV32M
418436
// XXX TODO: Check MULH/MULHSU/MULHU
419-
switch( (ir>>12)&7 )
437+
438+
if( ( (ir>>12) & 0x100 ) && rs2 == 0 )
439+
{
440+
//Integer division by zero
441+
442+
}
443+
else
420444
{
421-
case 0b000: val = rs1 * rs2; break; // MUL
422-
case 0b001: val = ((int64_t)rs1 * (int64_t)rs2) >> 32; break; // MULH
423-
case 0b010: val = ((int64_t)rs1 * (uint64_t)rs2) >> 32; break; // MULHSU
424-
case 0b011: val = ((uint64_t)rs1 * (uint64_t)rs2) >> 32; break; // MULHU
425-
case 0b100: val = (int32_t)rs1 / (int32_t)rs2; break; // DIV
426-
case 0b101: val = rs1 / rs2; break; // DIVU
427-
case 0b110: val = (int32_t)rs1 % (int32_t)rs2; break; // REM
428-
case 0b111: val = rs1 % rs2; break; // REMU
445+
switch( (ir>>12)&7 )
446+
{
447+
case 0b000: val = rs1 * rs2; break; // MUL
448+
case 0b001: val = ((int64_t)rs1 * (int64_t)rs2) >> 32; break; // MULH
449+
case 0b010: val = ((int64_t)rs1 * (uint64_t)rs2) >> 32; break; // MULHSU
450+
case 0b011: val = ((uint64_t)rs1 * (uint64_t)rs2) >> 32; break; // MULHU
451+
case 0b100: if( rs2 == 0 ) val = -1; else val = (int32_t)rs1 / (int32_t)rs2; break; // DIV
452+
case 0b101: if( rs2 == 0 ) val = 0xffffffff; else val = rs1 / rs2; break; // DIVU
453+
case 0b110: if( rs2 == 0 ) val = rs1; else val = (int32_t)rs1 % (int32_t)rs2; break; // REM
454+
case 0b111: if( rs2 == 0 ) val = rs1; else val = rs1 % rs2; break; // REMU
455+
}
429456
}
430457
}
431458
else
@@ -437,7 +464,7 @@ int StepInstruction( struct InternalCPUState * state, uint8_t * image, uint32_t
437464
case 0b010: val = (int32_t)rs1 < (int32_t)rs2; break;
438465
case 0b011: val = rs1 < rs2; break;
439466
case 0b100: val = rs1 ^ rs2; break;
440-
case 0b101: val = (ir & 0x40000000 ) ? ( ((int32_t)rs1) >> rs2 ) : ( rs1 << rs2 ); break;
467+
case 0b101: val = (ir & 0x40000000 ) ? ( ((int32_t)rs1) >> rs2 ) : ( rs1 >> rs2 ); break;
441468
case 0b110: val = rs1 | rs2; break;
442469
case 0b111: val = rs1 & rs2; break;
443470
}
@@ -478,6 +505,10 @@ int StepInstruction( struct InternalCPUState * state, uint8_t * image, uint32_t
478505
;// WFI, Ignore.
479506
else
480507
{
508+
if( (ir >> 24) == 0xff )
509+
{
510+
exit(1);
511+
}
481512
//retval = -100;
482513
printf( "EBREAK EBREAK EBREAK @ %08x\n", pc );//retval = 1;
483514
}

0 commit comments

Comments
 (0)