diff --git a/.gitignore b/.gitignore index 8a75bc71a..51dda9031 100644 --- a/.gitignore +++ b/.gitignore @@ -229,4 +229,7 @@ examples/verilog/fulladder/profileReport/ examples/verilog/fulladder/simprofile_dir/ examples/verilog/fulladder/simv.daidir/ examples/verilog/fulladder/ucli.key -examples/verilog/fulladder/verdi_config_file \ No newline at end of file +examples/verilog/fulladder/verdi_config_file +tests/functcov +tests/functcov/* +tests/functcov/*/* diff --git a/bin/wally-tool-chain-install.sh b/bin/wally-tool-chain-install.sh index 96834b735..78c31459e 100755 --- a/bin/wally-tool-chain-install.sh +++ b/bin/wally-tool-chain-install.sh @@ -48,7 +48,7 @@ sudo apt update -y sudo apt upgrade -y sudo apt install -y git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev libglib2.0-dev python3-pip pkg-config opam z3 zlib1g-dev automake autotools-dev libmpc-dev libmpfr-dev gperf libtool patchutils bc mutt ssmtp # Other python libraries used through the book. -sudo pip3 install sphinx sphinx_rtd_theme matplotlib scipy scikit-learn adjustText lief markdown +sudo -H pip3 install sphinx sphinx_rtd_theme matplotlib scipy scikit-learn adjustText lief markdown # needed for Ubuntu 22.04, gcc cross compiler expects python not python2 or python3. if ! command -v python &> /dev/null @@ -183,8 +183,8 @@ sudo ln -sf $RISCV/sail-riscv/c_emulator/riscv_sim_RV64 /usr/bin/riscv_sim_RV64 sudo ln -sf $RISCV/sail-riscv/c_emulator/riscv_sim_RV32 /usr/bin/riscv_sim_RV32 # riscof -sudo pip3 install -U testresources riscv_config -sudo pip3 install git+https://github.com/riscv/riscof.git +sudo -H pip3 install -U testresources riscv_config +sudo -H pip3 install git+https://github.com/riscv/riscof.git # Download OSU Skywater 130 cell library sudo mkdir -p $RISCV/cad/lib diff --git a/tests/testgen/Makefile b/tests/testgen/Makefile index b9c07d22f..0e10048af 100644 --- a/tests/testgen/Makefile +++ b/tests/testgen/Makefile @@ -1,4 +1,39 @@ -all: +#all: +# ./covergen.py +# cd ../riscof; make wally-riscv-arch-test +# cd ../../sim; make memfiles + +CEXT := c +CPPEXT := cpp +AEXT := s +SEXT := S +SRCEXT := \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\) +#SRCS = $(wildcard *.S) +#PROGS = $(patsubst %.S,%,$(SRCS)) +SRCDIR = ${WALLY}/tests/functcov/rv64/I +SRCEXT = S +SOURCES ?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort) +OBJEXT = elf +OBJECTS := $(SOURCES:.$(SEXT)=.$(OBJEXT)) + +all: ./covergen.py - cd ../riscof; make wally-riscv-arch-test - cd ../../sim; make memfiles + make build + +build: $(OBJECTS) + +%.elf.objdump: %.elf + +# Change many things if bit width isn't 64 +$(SRCDIR)/%.elf: $(SRCDIR)/%.$(SEXT) + riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zfa_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64 -mcmodel=medany \ + -nostartfiles -T${WALLY}/examples/link/link.ld $< + riscv64-unknown-elf-objdump -S -D $@ > $@.objdump + riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile + extractFunctionRadix.sh $@.objdump + +clean: + rm -f ${SRCDIR}/*.elf ${SRCDIR}/*.objdump ${SRCDIR}/*.addr *${SRCDIR}/.lab ${SRCDIR}/*.memfile + + + diff --git a/tests/testgen/covergen.py b/tests/testgen/covergen.py index 2b9cbbe2d..d2170e476 100755 --- a/tests/testgen/covergen.py +++ b/tests/testgen/covergen.py @@ -14,7 +14,7 @@ from datetime import datetime from random import randint from random import seed from random import getrandbits -from os import getenv +import os import re ################################## @@ -33,16 +33,16 @@ def signedImm12(imm): def writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen): lines = "\n# Testcase " + str(desc) + "\n" - lines = lines + "li x" + str(rd) + ", MASK_XLEN(" + formatstr.format(rdval) + ") # initialize rd to a random value that should get changed\n" + lines = lines + "li x" + str(rd) + ", " + formatstr.format(rdval) + " # initialize rd to a random value that should get changed\n" if (test in rtype): - lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n" - lines = lines + "li x" + str(rs2) + ", MASK_XLEN(" + formatstr.format(rs2val) + ") # initialize rs2 to a random value\n" + lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" + lines = lines + "li x" + str(rs2) + ", " + formatstr.format(rs2val) + " # initialize rs2 to a random value\n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", x" + str(rs2) + " # perform operation\n" elif (test in shiftitype): - lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n" + lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + shiftImm(immval, xlen) + " # perform operation\n" elif (test in itype): - lines = lines + "li x" + str(rs1) + ", MASK_XLEN(" + formatstr.format(rs1val) + ") # initialize rs1 to a random value \n" + lines = lines + "li x" + str(rs1) + ", " + formatstr.format(rs1val) + " # initialize rs1 to a random value \n" lines = lines + test + " x" + str(rd) + ", x" + str(rs1) + ", " + signedImm12(immval) + " # perform operation\n" else: pass @@ -79,22 +79,28 @@ def make_rs2(test, storecmd, xlen): def make_rd_rs1(test, storecmd, xlen): for r in range(32): - [rs1, rs1, rd, rs1val, rs2val, immval, rdval] = randomize() + [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() desc = "cp_rd_rs1 (Test rd = rs1 = x" + str(r) + ")" writeCovVector(desc, r, rs2, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen) def make_rd_rs2(test, storecmd, xlen): for r in range(32): - [rs1, rs1, rd, rs1val, rs2val, immval, rdval] = randomize() + [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() desc = "cp_rd_rs2 (Test rd = rs1 = x" + str(r) + ")" writeCovVector(desc, rs1, r, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen) def make_rd_rs1_rs2(test, storecmd, xlen): for r in range(32): - [rs1, rs1, rd, rs1val, rs2val, immval, rdval] = randomize() + [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() desc = "cp_rd_rs1_rs2 (Test rd = rs1 = rs2 = x" + str(r) + ")" writeCovVector(desc, r, r, r, rs1val, rs2val, immval, rdval, test, storecmd, xlen) +def make_rs1_rs2(test, storecmd, xlen): + for r in range(32): + [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() + desc = "cp_rd_rs1_rs2 (Test rs1 = rs2 = x" + str(r) + ")" + writeCovVector(desc, r, r, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) + def make_rs1_maxvals(test, storecmd, xlen): for v in [0, 2**(xlen-1), 2**(xlen-1)-1, 2**xlen-1, 1, 2**(xlen-1)+1]: [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() @@ -131,6 +137,29 @@ def make_rs1_rs2_eqval(test, storecmd, xlen): #def make_cp_gpr_hazard(test, storecmd, xlen): # pass # *** to be implemented *** +def make_rs1_sign(test, storecmd, xlen): + for v in [1, -1]: + [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() + rs1val = abs(rs1val) * v; + desc = "cp_rs1_sign (Test source rs1 value = " + hex(rs1val) + ")" + writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) + +def make_rs2_sign(test, storecmd, xlen): + for v in [1, -1]: + [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() + rs2val = abs(rs2val) * v; + desc = "cp_rs2_sign (Test source rs2 value = " + hex(rs2val) + ")" + writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) + +def make_cr_rs1_rs2_sign(test, storecmd, xlen): + for v1 in [1, -1]: + for v2 in [1, -1]: + [rs1, rs2, rd, rs1val, rs2val, immval, rdval] = randomize() + rs1val = abs(rs1val) * v1; + rs2val = abs(rs2val) * v2; + desc = "cr_rs1_rs2 (Test source rs1 = " + hex(rs1val) + " rs2 = " + hex(rs2val) + ")" + writeCovVector(desc, rs1, rs2, rd, rs1val, rs2val, immval, rdval, test, storecmd, xlen) + def write_tests(coverpoints, test, storecmd, xlen): for coverpoint in coverpoints: if (coverpoint == "cp_asm_count"): @@ -141,12 +170,18 @@ def write_tests(coverpoints, test, storecmd, xlen): make_rs1(test, storecmd, xlen) elif (coverpoint == "cp_rs2"): make_rs2(test, storecmd, xlen) - elif (coverpoint == "cp_rd_rs1"): + elif (coverpoint == "cmp_rd_rs1"): make_rd_rs1(test, storecmd, xlen) - elif (coverpoint == "cp_rd_rs2"): + elif (coverpoint == "cmp_rd_rs2"): make_rd_rs2(test, storecmd, xlen) - elif (coverpoint == "cp_rd_rs1_rs2"): + elif (coverpoint == "cmp_rd_rs1_rs2"): make_rd_rs1_rs2(test, storecmd, xlen) + elif (coverpoint == "cmp_rd_rs1_eq"): + pass # duplicate of cmp_rd_rs1 + elif (coverpoint == "cmp_rd_rs2_eq"): + pass # duplicate of cmp_rd_rs2 + elif (coverpoint == "cmp_rs1_rs2_eq"): + make_rs1_rs2(test, storecmd, xlen) elif (coverpoint == "cp_rs1_maxvals"): make_rs1_maxvals(test, storecmd, xlen) elif (coverpoint == "cp_rs2_maxvals"): @@ -159,8 +194,22 @@ def write_tests(coverpoints, test, storecmd, xlen): make_rd_rs2_eqval(test, storecmd, xlen) elif (coverpoint == "cmp_rs1_rs2_eqval"): make_rs1_rs2_eqval(test, storecmd, xlen) -# elif (coverpoint == "cp_gpr_hazard"): -# make_cp_gpr_hazard(test, storecmd, xlen) + elif (coverpoint == "cp_rs1_sign"): + make_rs1_sign(test, storecmd, xlen) + elif (coverpoint == "cp_rs2_sign"): + make_rs2_sign(test, storecmd, xlen) + elif (coverpoint == "cp_rd_sign"): + pass # hope already covered by rd_maxvals + elif (coverpoint == "cr_rs1_rs2"): + make_cr_rs1_rs2_sign(test, storecmd, xlen) + elif (coverpoint == "cp_rs1_toggle"): + pass # toggle not needed and seems to be covered by other things + elif (coverpoint == "cp_rs2_toggle"): + pass # toggle not needed and seems to be covered by other things + elif (coverpoint == "cp_rd_toggle"): + pass # toggle not needed and seems to be covered by other things + elif (coverpoint == "cp_gpr_hazard"): + pass # not yet implemented else: print("Error: " + coverpoint + " not implemented yet for " + test) @@ -188,7 +237,7 @@ def getcovergroups(coverdefdir, coverfiles): ################################## # change these to suite your tests -riscv = getenv("RISCV") +riscv = os.environ.get("RISCV") coverdefdir = riscv+"/ImperasDV-OpenHW/Imperas/ImpProprietary/source/host/riscvISACOV/source/coverage"; #coverfiles = ["RV64I", "RV64M", "RV64A", "RV64C", "RV64F", "RV64D"] # add more later coverfiles = ["RV64I"] # add more later @@ -222,13 +271,13 @@ for xlen in xlens: storecmd = "sd" wordsize = 8 for test in coverpoints.keys(): -# for test in tests: -# corners = [0, 1, 2, 0xFF, 0x624B3E976C52DD14 % 2**xlen, 2**(xlen-1)-2, 2**(xlen-1)-1, -# 2**(xlen-1), 2**(xlen-1)+1, 0xC365DDEB9173AB42 % 2**xlen, 2**(xlen)-2, 2**(xlen)-1] - corners = [0, 1, 2**(xlen)-1] - pathname = "../wally-riscv-arch-test/riscv-test-suite/rv" + str(xlen) + "i_m/I/" +# pathname = "../wally-riscv-arch-test/riscv-test-suite/rv" + str(xlen) + "i_m/I/" + WALLY = os.environ.get('WALLY') + pathname = WALLY+"/tests/functcov/rv" + str(xlen) + "/I/" + cmd = "mkdir -p " + pathname + os.system(cmd) basename = "WALLY-COV-" + test - fname = pathname + "src/" + basename + ".S" + fname = pathname + "/" + basename + ".S" # print custom header part f = open(fname, "w") diff --git a/tests/testgen/covergen_footer.S b/tests/testgen/covergen_footer.S index 108119436..597a00f2a 100644 --- a/tests/testgen/covergen_footer.S +++ b/tests/testgen/covergen_footer.S @@ -1,30 +1,2 @@ -RVTEST_CODE_END -RVMODEL_HALT -RVTEST_DATA_BEGIN -.align 4 -rvtest_data: -.word 0x98765432 -RVTEST_DATA_END - -RVMODEL_DATA_BEGIN - - -wally_signature: - .fill NUMTESTS*(XLEN/32),4,0xdeadbeef - -#ifdef rvtest_mtrap_routine - -mtrap_sigptr: - .fill 64*(XLEN/32),4,0xdeadbeef - -#endif - -#ifdef rvtest_gpr_save - -gpr_save: - .fill 32*(XLEN/32),4,0xdeadbeef - -#endif - -RVMODEL_DATA_END +.end diff --git a/tests/testgen/covergen_header.S b/tests/testgen/covergen_header.S index 461f47694..90be86381 100644 --- a/tests/testgen/covergen_header.S +++ b/tests/testgen/covergen_header.S @@ -4,18 +4,9 @@ // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 /////////////////////////////////////////// -#include "model_test.h" -#include "arch_test.h" -RVTEST_ISA("RV64I") - .section .text.init .globl rvtest_entry_point + rvtest_entry_point: -RVMODEL_BOOT -RVTEST_CODE_BEGIN -RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",temp) - - la x6, wally_signature - sd x0, 0(x6) \ No newline at end of file diff --git a/tests/testgen/virtual_memory_util.py b/tests/testgen/virtual_memory_util.py deleted file mode 100644 index 0aafb3a12..000000000 --- a/tests/testgen/virtual_memory_util.py +++ /dev/null @@ -1,292 +0,0 @@ -#!/usr/bin/python3 -################################## -# virtual_memory_util.py -# -# Jessica Torrey 01 March 2021 -# Thomas Fleming 01 March 2021 -# -# Modified kmacsaigoren@hmc.edu 2 June 2021 -# file now reflects actual use to generate assembly code pagetable. -# file now also includes small guide on how it can be used. -# -# Utility for generating the pagetable for any test assembly code where virtual memory is needed. -################################## - -###################################################### -""" HOW TO USE THIS FILE - -This is all assuming you are writing code very similar to the WALLY-VIRTUALMEMORY tests and would like your own virtual memory map. -This guide is also stored in the WALLY-VIRTUALMEMORY.S file as well. - -Begin by copying an existing page directory over to your test and running make (it'll be wrong, but we'll fix it in a second). - Make may hang or give you an error because the reference outputs may be wrong, but all we're trying to do is get an elf file. -Simulate the test code on your favorite riscv processor simulator with a debugger that will show you internal state/register values. - I used OVPsimPlus with the command 'riscvOVPsimPlus.exe --variant --program --gdbconsole' -Run through the simulation until it has written to satp and read the bottom 60 bits of it. - Assuming you're a test with the same setup code, this should be the value of the base ppn. - -Near the top of the python file you're reading right now, edit the value of 'INITIAL_PPN' to be the base PPN you just found in hex. - -Now find the mappings at the very bottom of the python file. -Each of these loops is adding a mapping from each virtual page in the loop to a physical page somewhere in RAM. - -add or remove mappings as you see fit. the first loop maps VPNs of 0x80000 to 0x80014 onto PPNs of 0x80000 to 0x80014 - you can map single pages or ranges of pages. you can also map multiple VPNs onto the same PPN. - Make sure NOT to include the final VPN that causes the page fault in your test or your program will hang on the j loop instruction (unless you change the end condition). - -double check that you're using the right architecture/svmode in the 'arch' variable - -then run this python file and paste its output at the bottom of your assembly code. Be sure not to delete the signature fills. - -email kmacsaigoren@hmc.edu if you have any questions and he might be able to remember the answers. - -*** Currently doesn't work: mapping something with nonzeros in the VPN[3] feild onto any physical aderss. - It'll produce a page table, but writing to those virtual adresses will not correspond to the correctly mapped physical adresses. - - additionally, the expected behaviour doesn't really work when we try to map to a ram afress that starts with something larger than 000000008 - This could be ebcause of the 32 bit adress space for physical memory. - - remember that these things are broken with this program that generates page tables for test code. it does not say whether the test or module - itself works or not. -*/ - -""" -###################################################### - -################################## -# libraries -################################## -from datetime import datetime -from random import randint, seed, getrandbits -from textwrap import dedent - -################################## -# global structures -################################## -PTE_D = 1 << 7 -PTE_A = 1 << 6 -PTE_G = 1 << 5 -PTE_U = 1 << 4 -PTE_X = 1 << 3 -PTE_W = 1 << 2 -PTE_R = 1 << 1 -PTE_V = 1 << 0 - -PTE_PTR_MASK = ~(PTE_W | PTE_R | PTE_X) - -pgdir = [] - -pages = {} - - -testcase_num = 0 -signature_len = 2000 -signature = [0xff for _ in range(signature_len)] - -# Base PPN, comes after 2 pages of test code and 2 pages of filler signature output space. -# depending on your test however, this value may be different. You can use OVPsimPlus or QEMU with your testcode to find it. -INITIAL_PPN = 0x80005 - - -################################## -# classes -################################## -class Architecture: - def __init__(self, xlen, svMode): - if (xlen == 32): - self.PTESIZE = 4 # bytes - self.PTE_BITS = 32 - - self.VPN_BITS = 20 - self.VPN_SEGMENT_BITS = 10 - - self.PPN_BITS = 22 - - self.LEVELS = 2 - elif (xlen == 64): - if (svMode == 39): - self.PTESIZE = 8 - self.PTE_BITS = 54 - - self.VPN_BITS = 27 - self.VPN_SEGMENT_BITS = 9 - - self.PPN_BITS = 44 - - self.LEVELS = 3 - elif (svMode == 48): - self.PTESIZE = 8 - self.PTE_BITS = 54 - - self.VPN_BITS = 36 - self.VPN_SEGMENT_BITS = 9 - - self.PPN_BITS = 44 - - self.LEVELS = 4 - else: - raise ValueError('Only Sv39 and Sv48 are implemented') - else: - raise ValueError('Only rv32 and rv64 are allowed.') - - self.PGSIZE = 2**12 - self.NPTENTRIES = self.PGSIZE // self.PTESIZE - self.OFFSET_BITS = 12 - self.FLAG_BITS = 8 - self.VA_BITS = self.VPN_BITS + self.OFFSET_BITS - -class PageTableEntry: - def __init__(self, ppn, flags, arch): - assert 0 <= ppn and ppn < 2**arch.PPN_BITS, "Invalid physical page number for PTE" - assert 0 <= flags and flags < 2**arch.FLAG_BITS, "Invalid flags for PTE" - self.ppn = ppn - self.flags = flags - self.arch = arch - - def entry(self): - return (self.ppn << (self.arch.PTE_BITS - self.arch.PPN_BITS)) | self.flags - - def __str__(self): - return "0x{0:0{1}x}".format(self.entry(), self.arch.PTESIZE*2) - - def __repr__(self): - return f"" - -class PageTable: - """ - Represents a single level of the page table, located at some physical page - number `ppn` with symbol `name`, using a specified architecture `arch`. - """ - def __init__(self, name, ppn, arch): - self.table = {} - self.name = name - self.ppn = ppn - self.arch = arch - - self.children = 0 - - pages[ppn] = self - - def add_entry(self, vpn_segment, ppn, flags): - if not (0 <= vpn_segment < 2**self.arch.VPN_SEGMENT_BITS): - raise ValueError("Invalid virtual page segment number") - self.table[vpn_segment] = PageTableEntry(ppn, flags, self.arch) - - def add_mapping(self, va, pa, flags): - """ - Maps a virtual address `va` to a physical address `pa` with given `flags`, - creating missing page table levels as needed. - """ - if not (0 <= va < 2**self.arch.VA_BITS): - raise ValueError("Invalid virtual page number") - - vpn = virtual_to_vpn(va, self.arch) - ppn = pa >> self.arch.OFFSET_BITS - current_level = self - - pathname = self.name - - for level in range(self.arch.LEVELS - 1, -1, -1): - if level == 0: - current_level.add_entry(vpn[level], ppn, flags) - elif vpn[level] in current_level.table: - current_level = pages[current_level.table[vpn[level]].ppn] - pathname += f"_{current_level.name}" - else: - next_level_ppn = next_ppn() - current_level.add_entry(vpn[level], next_level_ppn, flags & PTE_PTR_MASK) - pathname += f"_t{current_level.children}" - current_level.children += 1 - pages[next_level_ppn] = PageTable(pathname, next_level_ppn, self.arch) - current_level = pages[next_level_ppn] - - def assembly(self): - # Sort the page table - entries = list(sorted(self.table.items(), key=lambda item: item[0])) - current_index = 0 - - # Align the table - asm = f".balign {self.arch.PGSIZE}\n{self.name}:\n" - for entry in entries: - vpn_index, pte = entry - if current_index < vpn_index: - asm += f" .fill {vpn_index - current_index}, {self.arch.PTESIZE}, 0\n" - asm += f" .{self.arch.PTESIZE}byte {str(pte)}\n" - current_index = vpn_index + 1 - if current_index < self.arch.NPTENTRIES: - asm += f" .fill {self.arch.NPTENTRIES - current_index}, {self.arch.PTESIZE}, 0\n" - return asm - - def __str__(self): - return self.assembly() - - def __repr__(self): - return f"" - - -################################## -# functions -################################## - -def virtual_to_vpn(vaddr, arch): - if not (0 <= vaddr < 2**arch.VA_BITS): - raise ValueError("Invalid physical address") - - page_number = [0 for _ in range(arch.LEVELS)] - - vaddr = vaddr >> arch.OFFSET_BITS - mask = 2**arch.VPN_SEGMENT_BITS - 1 - for level in range(arch.LEVELS): - page_number[level] = vaddr & mask - vaddr = vaddr >> arch.VPN_SEGMENT_BITS - - return page_number - -next_free_ppn = INITIAL_PPN -def next_ppn(): - global next_free_ppn - ppn = next_free_ppn - next_free_ppn += 1 - return ppn - -def print_pages(): - for page in pages: - print(pages[page]) - -################################## -# helper variables -################################## -sv32 = Architecture(32, 32) -sv39 = Architecture(64, 39) -sv48 = Architecture(64, 48) - -if __name__ == "__main__": - arch = sv39 - pgdir = PageTable("page_directory", next_ppn(), arch) - - # Directly map the first 20 pages of RAM - for page in range(20): - vaddr = 0x80000000 + (arch.PGSIZE * page) - paddr = 0x80000000 + (arch.PGSIZE * page) - pgdir.add_mapping(vaddr, paddr, PTE_D | PTE_A | PTE_R | PTE_W | PTE_U | PTE_X | PTE_V) - - # Map Vpn of of the offset below and the 20 pages after it mapped onto the same 20 pages of ram. - # the first two of these are also the location of the output for each test. - for page in range(40): - vaddr = 0x00000000 + (arch.PGSIZE * page) - paddr = 0x80000000 + (arch.PGSIZE * page) - if page >= 20: - pgdir.add_mapping(vaddr, paddr, PTE_D | PTE_A | PTE_R | PTE_W | PTE_U | PTE_X | 0) # gives me an invalid mapping where I can try to store/read to force a page fault. - else: - pgdir.add_mapping(vaddr, paddr, PTE_D | PTE_A | PTE_R | PTE_W | PTE_U | PTE_X | PTE_V) - - - """ - supervisor_pgdir = PageTable("sdir", next_ppn(), rv64) - supervisor_pgdir.add_mapping(0x80000000, 0x80000000, PTE_R | PTE_W | PTE_X) - supervisor_pgdir.add_mapping(0x80000001, 0x80000001, PTE_R | PTE_W | PTE_X) - supervisor_pgdir.add_mapping(0x80001000, 0x80000000, PTE_R | PTE_W | PTE_X) - supervisor_pgdir.add_mapping(0xffff0000, 0x80000000, PTE_R | PTE_W | PTE_X) - """ - - print_pages()