Files
xv6-labs/user/pgtbltest.c
2025-05-06 11:20:36 +08:00

165 lines
3.0 KiB
C

#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");
}