updated alarmtest
This commit is contained in:
parent
78f863f8ae
commit
56583b1402
|
@ -173,7 +173,6 @@ int copyinstr(pagetable_t, char *, uint64, uint64);
|
||||||
// plic.c
|
// plic.c
|
||||||
void plicinit(void);
|
void plicinit(void);
|
||||||
void plicinithart(void);
|
void plicinithart(void);
|
||||||
uint64 plic_pending(void);
|
|
||||||
int plic_claim(void);
|
int plic_claim(void);
|
||||||
void plic_complete(int);
|
void plic_complete(int);
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,7 @@ exec(char *path, char **argv)
|
||||||
p->tf->epc = elf.entry; // initial program counter = main
|
p->tf->epc = elf.entry; // initial program counter = main
|
||||||
p->tf->sp = sp; // initial stack pointer
|
p->tf->sp = sp; // initial stack pointer
|
||||||
proc_freepagetable(oldpagetable, oldsz);
|
proc_freepagetable(oldpagetable, oldsz);
|
||||||
|
|
||||||
return argc; // this ends up in a0, the first argument to main(argc, argv)
|
return argc; // this ends up in a0, the first argument to main(argc, argv)
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
|
|
|
@ -28,20 +28,6 @@ plicinithart(void)
|
||||||
*(uint32*)PLIC_SPRIORITY(hart) = 0;
|
*(uint32*)PLIC_SPRIORITY(hart) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return a bitmap of which IRQs are waiting
|
|
||||||
// to be served.
|
|
||||||
uint64
|
|
||||||
plic_pending(void)
|
|
||||||
{
|
|
||||||
uint64 mask;
|
|
||||||
|
|
||||||
//mask = *(uint32*)(PLIC + 0x1000);
|
|
||||||
//mask |= (uint64)*(uint32*)(PLIC + 0x1004) << 32;
|
|
||||||
mask = *(uint64*)PLIC_PENDING;
|
|
||||||
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ask the PLIC what interrupt we should serve.
|
// ask the PLIC what interrupt we should serve.
|
||||||
int
|
int
|
||||||
plic_claim(void)
|
plic_claim(void)
|
||||||
|
|
|
@ -95,7 +95,7 @@ struct proc {
|
||||||
int pid; // Process ID
|
int pid; // Process ID
|
||||||
|
|
||||||
// these are private to the process, so p->lock need not be held.
|
// these are private to the process, so p->lock need not be held.
|
||||||
uint64 kstack; // Bottom of kernel stack for this process
|
uint64 kstack; // Virtual address of kernel stack
|
||||||
uint64 sz; // Size of process memory (bytes)
|
uint64 sz; // Size of process memory (bytes)
|
||||||
pagetable_t pagetable; // Page table
|
pagetable_t pagetable; // Page table
|
||||||
struct trapframe *tf; // data page for trampoline.S
|
struct trapframe *tf; // data page for trampoline.S
|
||||||
|
|
|
@ -34,7 +34,8 @@ acquire(struct spinlock *lk)
|
||||||
|
|
||||||
// Tell the C compiler and the processor to not move loads or stores
|
// Tell the C compiler and the processor to not move loads or stores
|
||||||
// past this point, to ensure that the critical section's memory
|
// past this point, to ensure that the critical section's memory
|
||||||
// references happen after the lock is acquired.
|
// references happen strictly after the lock is acquired.
|
||||||
|
// On RISC-V, this emits a fence instruction.
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
|
|
||||||
// Record info about lock acquisition for holding() and debugging.
|
// Record info about lock acquisition for holding() and debugging.
|
||||||
|
@ -52,8 +53,10 @@ release(struct spinlock *lk)
|
||||||
|
|
||||||
// Tell the C compiler and the CPU to not move loads or stores
|
// Tell the C compiler and the CPU to not move loads or stores
|
||||||
// past this point, to ensure that all the stores in the critical
|
// past this point, to ensure that all the stores in the critical
|
||||||
// section are visible to other CPUs before the lock is released.
|
// section are visible to other CPUs before the lock is released,
|
||||||
// On RISC-V, this turns into a fence instruction.
|
// and that loads in the critical section occur strictly before
|
||||||
|
// the lock is released.
|
||||||
|
// On RISC-V, this emits a fence instruction.
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
|
|
||||||
// Release the lock, equivalent to lk->locked = 0.
|
// Release the lock, equivalent to lk->locked = 0.
|
||||||
|
|
|
@ -21,7 +21,7 @@ main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
test0();
|
test0();
|
||||||
test1();
|
test1();
|
||||||
exit();
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile static int count;
|
volatile static int count;
|
||||||
|
@ -44,7 +44,7 @@ test0()
|
||||||
count = 0;
|
count = 0;
|
||||||
sigalarm(2, periodic);
|
sigalarm(2, periodic);
|
||||||
for(i = 0; i < 1000*500000; i++){
|
for(i = 0; i < 1000*500000; i++){
|
||||||
if((i % 250000) == 0)
|
if((i % 1000000) == 0)
|
||||||
write(2, ".", 1);
|
write(2, ".", 1);
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
break;
|
break;
|
||||||
|
@ -53,7 +53,7 @@ test0()
|
||||||
if(count > 0){
|
if(count > 0){
|
||||||
printf("test0 passed\n");
|
printf("test0 passed\n");
|
||||||
} else {
|
} else {
|
||||||
printf("test0 failed\n");
|
printf("\ntest0 failed: the kernel never called the alarm handler\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,14 @@ void __attribute__ ((noinline)) foo(int i, int *j) {
|
||||||
*j += 1;
|
*j += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// tests that the kernel calls the handler multiple times.
|
||||||
|
//
|
||||||
|
// tests that, when the handler returns, it returns to
|
||||||
|
// the point in the program where the timer interrupt
|
||||||
|
// occurred, with all registers holding the same values they
|
||||||
|
// held when the interrupt occurred.
|
||||||
|
//
|
||||||
void
|
void
|
||||||
test1()
|
test1()
|
||||||
{
|
{
|
||||||
|
@ -79,9 +87,19 @@ test1()
|
||||||
break;
|
break;
|
||||||
foo(i, &j);
|
foo(i, &j);
|
||||||
}
|
}
|
||||||
if(i != j || count < 10){
|
if(count < 10){
|
||||||
// i should equal j
|
printf("\ntest1 failed: too few calls to the handler\n");
|
||||||
printf("test1 failed\n");
|
exit(1);
|
||||||
|
} else if(i != j){
|
||||||
|
// the loop should have called foo() i times, and foo() should
|
||||||
|
// have incremented j once per call, so j should equal i.
|
||||||
|
// once possible source of errors is that the handler may
|
||||||
|
// return somewhere other than where the timer interrupt
|
||||||
|
// occurred; another is that that registers may not be
|
||||||
|
// restored correctly, causing i or j or the address ofj
|
||||||
|
// to get an incorrect value.
|
||||||
|
printf("\ntest1 failed: foo() executed fewer times than it was called\n");
|
||||||
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
printf("test1 passed\n");
|
printf("test1 passed\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue