pagetable lab initialized
This commit is contained in:
164
user/pgtbltest.c
Normal file
164
user/pgtbltest.c
Normal file
@@ -0,0 +1,164 @@
|
||||
#include "kernel/param.h"
|
||||
#include "kernel/fcntl.h"
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/riscv.h"
|
||||
#include "user/user.h"
|
||||
|
||||
#define N (8 * (1 << 20))
|
||||
|
||||
void print_pgtbl();
|
||||
void print_kpgtbl();
|
||||
void ugetpid_test();
|
||||
void pgaccess_test();
|
||||
void superpg_test();
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
print_pgtbl();
|
||||
ugetpid_test();
|
||||
print_kpgtbl();
|
||||
pgaccess_test();
|
||||
superpg_test();
|
||||
printf("pgtbltest: all tests succeeded\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
char *testname = "???";
|
||||
|
||||
void
|
||||
err(char *why)
|
||||
{
|
||||
printf("pgtbltest: %s failed: %s, pid=%d\n", testname, why, getpid());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
print_pte(uint64 va)
|
||||
{
|
||||
pte_t pte = (pte_t) pgpte((void *) va);
|
||||
printf("va 0x%lx pte 0x%lx pa 0x%lx perm 0x%lx\n", va, pte, PTE2PA(pte), PTE_FLAGS(pte));
|
||||
}
|
||||
|
||||
void
|
||||
print_pgtbl()
|
||||
{
|
||||
printf("print_pgtbl starting\n");
|
||||
for (uint64 i = 0; i < 10; i++) {
|
||||
print_pte(i * PGSIZE);
|
||||
}
|
||||
uint64 top = MAXVA/PGSIZE;
|
||||
for (uint64 i = top-10; i < top; i++) {
|
||||
print_pte(i * PGSIZE);
|
||||
}
|
||||
printf("print_pgtbl: OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
ugetpid_test()
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("ugetpid_test starting\n");
|
||||
testname = "ugetpid_test";
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
int ret = fork();
|
||||
if (ret != 0) {
|
||||
wait(&ret);
|
||||
if (ret != 0)
|
||||
exit(1);
|
||||
continue;
|
||||
}
|
||||
if (getpid() != ugetpid())
|
||||
err("missmatched PID");
|
||||
exit(0);
|
||||
}
|
||||
printf("ugetpid_test: OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
print_kpgtbl()
|
||||
{
|
||||
printf("print_kpgtbl starting\n");
|
||||
kpgtbl();
|
||||
printf("print_kpgtbl: OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
pgaccess_test()
|
||||
{
|
||||
char *buf;
|
||||
unsigned int abits;
|
||||
printf("pgaccess_test starting\n");
|
||||
testname = "pgaccess_test";
|
||||
buf = malloc(32 * PGSIZE);
|
||||
if (pgaccess(buf, 32, &abits) < 0)
|
||||
err("pgaccess failed");
|
||||
buf[PGSIZE * 1] += 1;
|
||||
buf[PGSIZE * 2] += 1;
|
||||
buf[PGSIZE * 30] += 1;
|
||||
if (pgaccess(buf, 32, &abits) < 0)
|
||||
err("pgaccess failed");
|
||||
if (abits != ((1 << 1) | (1 << 2) | (1 << 30)))
|
||||
err("incorrect access bits set");
|
||||
free(buf);
|
||||
printf("pgaccess_test: OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
supercheck(uint64 s)
|
||||
{
|
||||
pte_t last_pte = 0;
|
||||
|
||||
for (uint64 p = s; p < s + 512 * PGSIZE; p += PGSIZE) {
|
||||
pte_t pte = (pte_t) pgpte((void *) p);
|
||||
if(pte == 0)
|
||||
err("no pte");
|
||||
if ((uint64) last_pte != 0 && pte != last_pte) {
|
||||
err("pte different");
|
||||
}
|
||||
if((pte & PTE_V) == 0 || (pte & PTE_R) == 0 || (pte & PTE_W) == 0){
|
||||
err("pte wrong");
|
||||
}
|
||||
last_pte = pte;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 512; i += PGSIZE){
|
||||
*(int*)(s+i) = i;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 512; i += PGSIZE){
|
||||
if(*(int*)(s+i) != i)
|
||||
err("wrong value");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
superpg_test()
|
||||
{
|
||||
int pid;
|
||||
|
||||
printf("superpg_test starting\n");
|
||||
testname = "superpg_test";
|
||||
|
||||
char *end = sbrk(N);
|
||||
if (end == 0 || end == (char*)0xffffffffffffffff)
|
||||
err("sbrk failed");
|
||||
|
||||
uint64 s = SUPERPGROUNDUP((uint64) end);
|
||||
supercheck(s);
|
||||
if((pid = fork()) < 0) {
|
||||
err("fork");
|
||||
} else if(pid == 0) {
|
||||
supercheck(s);
|
||||
exit(0);
|
||||
} else {
|
||||
int status;
|
||||
wait(&status);
|
||||
if (status != 0) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
printf("superpg_test: OK\n");
|
||||
}
|
||||
Reference in New Issue
Block a user