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