#! /usr/bin/env python import sys from optparse import OptionParser import random import math def convert(size): length = len(size) lastchar = size[length-1] if (lastchar == 'k') or (lastchar == 'K'): m = 1024 nsize = int(size[0:length-1]) * m elif (lastchar == 'm') or (lastchar == 'M'): m = 1024*1024 nsize = int(size[0:length-1]) * m elif (lastchar == 'g') or (lastchar == 'G'): m = 1024*1024*1024 nsize = int(size[0:length-1]) * m else: nsize = int(size) return nsize # # main program # parser = OptionParser() parser.add_option("-s", "--seed", default=0, help="the random seed", action="store", type="int", dest="seed") parser.add_option("-A", "--addresses", default="-1", help="a set of comma-separated pages to access; -1 means randomly generate", action="store", type="string", dest="addresses") parser.add_option("-a", "--asize", default="1k", help="address space size (e.g., 16, 64k, 32m, 1g)", action="store", type="string", dest="asize") parser.add_option("-p", "--physmem", default="16k", help="physical memory size (e.g., 16, 64k, 32m, 1g)", action="store", type="string", dest="psize") parser.add_option("-n", "--numaddrs", default=5, help="number of virtual addresses to generate", action="store", type="int", dest="num") parser.add_option("-b", "--b0", default="-1", help="value of segment 0 base register", action="store", type="string", dest="base0") parser.add_option("-l", "--l0", default="-1", help="value of segment 0 limit register", action="store", type="string", dest="len0") parser.add_option("-B", "--b1", default="-1", help="value of segment 1 base register", action="store", type="string", dest="base1") parser.add_option("-L", "--l1", default="-1", help="value of segment 1 limit register", action="store", type="string", dest="len1") parser.add_option("-c", help="compute answers for me", action="store_true", default=False, dest="solve") (options, args) = parser.parse_args() print "ARG seed", options.seed print "ARG address space size", options.asize print "ARG phys mem size", options.psize print "" random.seed(options.seed) asize = convert(options.asize) psize = convert(options.psize) addresses = str(options.addresses) if psize <= 1: print 'Error: must specify a non-zero physical memory size.' exit(1) if asize == 0: print 'Error: must specify a non-zero address-space size.' exit(1) if psize <= asize: print 'Error: physical memory size must be GREATER than address space size (for this simulation)' exit(1) # # need to generate base, bounds for segment registers # len0 = convert(options.len0) len1 = convert(options.len1) base0 = convert(options.base0) base1 = convert(options.base1) if len0 == -1: len0 = int(asize/4.0 + (asize/4.0 * random.random())) if len1 == -1: len1 = int(asize/4.0 + (asize/4.0 * random.random())) # now have to find room for them if base0 == -1: done = 0 while done == 0: base0 = int(psize * random.random()) if (base0 + len0) < psize: done = 1 # internally, base1 points to the lower address, and base1+len1 the higher address # (this differs from what the user would pass in, for example) if base1 == -1: done = 0 while done == 0: base1 = int(psize * random.random()) if (base1 + len1) < psize: if (base1 > (base0 + len0)) or ((base1 + len1) < base0): done = 1 else: base1 = base1 - len1 if len0 > asize/2.0 or len1 > asize/2.0: print 'Error: length register is too large for this address space' exit(1) print 'Segment register information:' print '' print ' Segment 0 base (grows positive) : 0x%08x (decimal %d)' % (base0, base0) print ' Segment 0 limit : %d' % (len0) print '' print ' Segment 1 base (grows negative) : 0x%08x (decimal %d)' % (base1+len1, base1+len1) print ' Segment 1 limit : %d' % (len1) print '' nbase1 = base1 + len1 if (len0 + base0) > (base1) and (base1 > base0): print 'Error: segments overlap in physical memory' exit(1) addrList = [] if addresses == '-1': # need to generate addresses for i in range(0, options.num): n = int(asize * random.random()) addrList.append(n) else: addrList = addresses.split(',') # # now, need to generate virtual address trace # print 'Virtual Address Trace' i = 0 for vStr in addrList: # vaddr = int(asize * random.random()) vaddr = int(vStr) if vaddr < 0 or vaddr >= asize: print 'Error: virtual address %d cannot be generated in an address space of size %d' % (vaddr, asize) exit(1) if options.solve == False: print ' VA %2d: 0x%08x (decimal: %4d) --> PA or segmentation violation?' % (i, vaddr, vaddr) else: paddr = 0 if (vaddr >= (asize / 2)): # seg 1 paddr = nbase1 + (vaddr - asize) if paddr < base1: print ' VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION (SEG1)' % (i, vaddr, vaddr) else: print ' VA %2d: 0x%08x (decimal: %4d) --> VALID in SEG1: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr) else: # seg 0 if (vaddr >= len0): print ' VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION (SEG0)' % (i, vaddr, vaddr) else: paddr = vaddr + base0 print ' VA %2d: 0x%08x (decimal: %4d) --> VALID in SEG0: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr) i += 1 print '' if options.solve == False: print 'For each virtual address, either write down the physical address it translates to' print 'OR write down that it is an out-of-bounds address (a segmentation violation). For' print 'this problem, you should assume a simple address space with two segments: the top' print 'bit of the virtual address can thus be used to check whether the virtual address' print 'is in segment 0 (topbit=0) or segment 1 (topbit=1). Note that the base/limit pairs' print 'given to you grow in different directions, depending on the segment, i.e., segment 0' print 'grows in the positive direction, whereas segment 1 in the negative. ' print ''