Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added a timerhalt() function #176

Open
wants to merge 1 commit into
base: riscv
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions kernel/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ struct sleeplock;
struct stat;
struct superblock;

// start.c
void timerhalt(void);

// bio.c
void binit(void);
struct buf* bread(uint, uint);
Expand Down
16 changes: 16 additions & 0 deletions kernel/kernelvec.S
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,17 @@ timervec:
# scratch[0,8,16] : register save area.
# scratch[24] : address of CLINT's MTIMECMP register.
# scratch[32] : desired interval between interrupts.
# scratch[40] : halt flag set by timerhalt.

csrrw a0, mscratch, a0
sd a1, 0(a0)
sd a2, 8(a0)
sd a3, 16(a0)

# halt if timerhalt has set halt flag to 1
ld a1, 40(a0)
bne a1, zero, halt

# schedule the next timer interrupt
# by adding interval to mtimecmp.
ld a1, 24(a0) # CLINT_MTIMECMP(hart)
Expand All @@ -122,3 +127,14 @@ timervec:
csrrw a0, mscratch, a0

mret

halt:
# based on qemu's hw/riscv/virt.c:
# qemu halts if FINISHER_PASS(=0x5555) is
# written at address *VIRT_TEST(=0x100000L)
lui a1, 0x100
lui a2, 0x5
addi a2, a2, 0x555
sw a2, 0(a1)
spin:
j spin
1 change: 1 addition & 0 deletions kernel/printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ panic(char *s)
printf(s);
printf("\n");
panicked = 1; // freeze uart output from other CPUs
timerhalt();
for(;;)
;
}
Expand Down
12 changes: 11 additions & 1 deletion kernel/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ void timerinit();
__attribute__ ((aligned (16))) char stack0[4096 * NCPU];

// a scratch area per CPU for machine-mode timer interrupts.
uint64 timer_scratch[NCPU][5];
uint64 timer_scratch[NCPU][6];

// assembly code in kernelvec.S for machine-mode timer interrupt.
extern void timervec();
Expand Down Expand Up @@ -73,9 +73,11 @@ timerinit()
// scratch[0..2] : space for timervec to save registers.
// scratch[3] : address of CLINT MTIMECMP register.
// scratch[4] : desired interval (in cycles) between timer interrupts.
// scratch[5] : halt flag to signal halt to timervec.
uint64 *scratch = &timer_scratch[id][0];
scratch[3] = CLINT_MTIMECMP(id);
scratch[4] = interval;
scratch[5] = 0;
w_mscratch((uint64)scratch);

// set the machine-mode trap handler.
Expand All @@ -87,3 +89,11 @@ timerinit()
// enable machine-mode timer interrupts.
w_mie(r_mie() | MIE_MTIE);
}

// signal halt to timervec.
void
timerhalt()
{
// set halt flag in scratch area for hartid[0] to 1.
timer_scratch[0][5] = 1;
}