1241675Suqs/** 2241675Suqs * \file 3241675Suqs * \brief Test program for large page code 4241675Suqs */ 5241675Suqs 6241675Suqs/* 7241675Suqs * Copyright (c) 2013, ETH Zurich. 8241675Suqs * All rights reserved. 9241675Suqs * 10241675Suqs * This file is distributed under the terms in the attached LICENSE file. 11241675Suqs * If you do not find this file, copies can be found by writing to: 12241675Suqs * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13241675Suqs */ 14241675Suqs 15241675Suqs#include <barrelfish/barrelfish.h> 16241675Suqs#include <stdio.h> 17241675Suqs#include <stdlib.h> 18241675Suqs#include <string.h> 19241675Suqs#include <assert.h> 20241675Suqs#include <inttypes.h> 21241675Suqs#include <barrelfish/nameservice_client.h> 22241675Suqs#include <barrelfish/sys_debug.h> 23241675Suqs#include <bench/bench.h> 24241675Suqs 25241675Suqs#define SAFE_VADDR (genvaddr_t)(8ULL<<39) 26241675Suqs#define SAFE_PMAP_ADDR (genvaddr_t)(9ULL<<39) 27241675Suqs//0b 0000 0000 0000 0000 0000 0100 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 28241675Suqs#define SAFE_PMAP_ADDR_L ((genvaddr_t) (12ULL<<39)) 29241675Suqs// 40M 30241675Suqs#define DEFAULT_SIZE (30 * LARGE_PAGE_SIZE) 31241675Suqs 32241675Suqs 33241675Suqs#define RUN_COUNT 50 34241675Suqs 35241675Suqsunsigned long mean4k; 36241675Suqsunsigned long mean2m; 37241675Suqsunsigned long min4k; 38241675Suqsunsigned long min2m; 39241675Suqsunsigned long mean4krand; 40241675Suqsunsigned long mean2mrand; 41241675Suqsunsigned long min4krand; 42241675Suqsunsigned long min2mrand; 43241675Suqsunsigned long max4krand; 44241675Suqsunsigned long max2mrand; 45241675Suqsunsigned long max4k; 46241675Suqsunsigned long max2m; 47241675Suqs 48241675Suqsunsigned long mean4kshort; 49241675Suqsunsigned long mean2mshort; 50241675Suqsunsigned long mean4kshortrand; 51241675Suqsunsigned long mean2mshortrand; 52241675Suqsunsigned long min4kshort; 53241675Suqsunsigned long min2mshort; 54241675Suqsunsigned long min4kshortrand; 55241675Suqsunsigned long min2mshortrand; 56241675Suqsunsigned long max4kshort; 57241675Suqsunsigned long max2mshort; 58241675Suqsunsigned long max4kshortrand; 59241675Suqsunsigned long max2mshortrand; 60241675Suqs/*static paging_x86_64_flags_t PAGE_DEFAULT_ACCESS = 61241675Suqs PTABLE_USER_SUPERVISOR | 62241675Suqs PTABLE_EXECUTE_DISABLE | 63241675Suqs PTABLE_READ_WRITE; 64241675Suqs */ 65241675Suqsstatic vregion_flags_t PMAP_DEFAULT_ACCESS = 66241675Suqs VREGION_FLAGS_READ_WRITE; 67241675Suqs 68241675Suqsstatic void test_region(uint32_t *buf, size_t size, bool large, bool area) 69241675Suqs{ 70241675Suqs cycles_t runs[RUN_COUNT]; 71241675Suqs cycles_t start, end; 72241675Suqs uint64_t mean = 0; 73241675Suqs unsigned long min = 0; 74241675Suqs unsigned long max = 0; 75241675Suqs printf("base address: %lx\n", (uint64_t) buf); 76241675Suqs 77241675Suqs //sequential access 78241675Suqs for (int j = 0; j < RUN_COUNT; j++) { 79241675Suqs 80241675Suqs start = bench_tsc()/1000; 81241675Suqs for (unsigned long i = 0; i < size; i+=4) { 82241675Suqs 83241675Suqs buf[i/4] = i; 84241675Suqs } 85241675Suqs for (unsigned long i = 0; i < size; i+=4) { 86241675Suqs assert(buf[i/4] == i); 87241675Suqs } 88241675Suqs end = bench_tsc()/1000; 89241675Suqs runs[j] = end-start; 90241675Suqs mean += (unsigned int) runs[j]; 91241675Suqs if (runs[j] < min || j == 0) {min = runs[j];} 92241675Suqs if (runs[j] > max) {max = runs[j];} 93241675Suqs printf("run: %u, cycles: %u\n", j, (unsigned int) runs[j]); 94241675Suqs } 95241675Suqs mean = mean/RUN_COUNT; 96241675Suqs printf("\naverage cycles to write the whole area: %u\n", (unsigned int) mean); 97241675Suqs if(!large && !area) { 98241675Suqs mean4k = mean; 99241675Suqs min4k = min; 100241675Suqs max4k = max; 101241675Suqs } 102241675Suqs else if (large && !area) { 103241675Suqs mean2m = mean; 104241675Suqs min2m = min; 105241675Suqs max2m = max; 106241675Suqs } 107241675Suqs else if (!large && area) { 108241675Suqs mean4kshort = mean; 109241675Suqs min4kshort = min; 110241675Suqs max4kshort = max; 111241675Suqs } else { 112241675Suqs mean2mshort = mean; 113241675Suqs min2mshort = min; 114241675Suqs max2mshort = max; 115241675Suqs } 116241675Suqs 117241675Suqs //random access 118241675Suqs //generate 1M random number array 119241675Suqs unsigned int* addrs; 120241675Suqs min = 0; 121241675Suqs max = 0; 122241675Suqs mean = 0; 123241675Suqs addrs = malloc(2000000*sizeof(unsigned int)); 124241675Suqs printf("malloc'd\n"); 125241675Suqs for (int i = 0; i<2000000; i++) 126241675Suqs { 127241675Suqs addrs[i] = (rand() % (size/4)); 128241675Suqs } 129241675Suqs printf("randomised\n"); 130241675Suqs for (int j = 0; j < RUN_COUNT; j++) { 131241675Suqs 132241675Suqs start = bench_tsc()/1000; 133241675Suqs for (int i = 0; i < 2000000; i++) { 134241675Suqs buf[addrs[i]] = addrs[i]; 135241675Suqs } 136241675Suqs for (unsigned long i = 0; i < 2000000; i++) { 137241675Suqs assert(buf[addrs[i]] == addrs[i]); 138241675Suqs } 139241675Suqs end = bench_tsc()/1000; 140241675Suqs runs[j] = end-start; 141241675Suqs mean += (unsigned int) runs[j]; 142241675Suqs if (runs[j] < min || j == 0) {min = runs[j];} 143241675Suqs if (runs[j] > max) {max = runs[j];} 144241675Suqs printf("run: %u, cycles: %u\n", j, (unsigned int) runs[j]); 145241675Suqs } 146241675Suqs mean = mean/RUN_COUNT; 147241675Suqs printf("\naverage cycles to write the whole area randomly: %u\n", (unsigned int) mean); 148241675Suqs if(!large && !area) { 149241675Suqs mean4krand = mean; 150241675Suqs min4krand = min; 151241675Suqs max4krand = max; 152241675Suqs } 153241675Suqs else if (large && !area){ 154241675Suqs mean2mrand = mean; 155241675Suqs min2mrand = min; 156241675Suqs max2mrand = max; 157241675Suqs }else if (!large && area) { 158241675Suqs mean4kshortrand = mean; 159241675Suqs min4kshortrand = min; 160241675Suqs max4kshortrand = max; 161241675Suqs } else { 162241675Suqs mean2mshortrand = mean; 163241675Suqs min2mshortrand = min; 164241675Suqs max2mshortrand = max; 165241675Suqs } 166241675Suqs 167241675Suqs} 168241675Suqs 169241675Suqsint main(void) 170241675Suqs{ 171241675Suqs struct capref frame; 172241675Suqs size_t bytes = DEFAULT_SIZE; 173241675Suqs errval_t err; 174241675Suqs mean4k = 0; 175241675Suqs mean2m = 0; 176241675Suqs genvaddr_t address; 177241675Suqs 178241675Suqs 179241675Suqs //normal pages via pmap interface 180241675Suqs printf("\nstart 4k map with pmap\n"); 181241675Suqs err = frame_alloc(&frame, bytes, &bytes); 182241675Suqs if (err_is_fail(err)) 183241675Suqs { 184241675Suqs printf("error in frame_alloc: %s\n", err_getstring(err)); 185241675Suqs exit(1); 186241675Suqs } 187241675Suqs assert(bytes >= DEFAULT_SIZE); 188241675Suqs printf(" get pmap\n"); 189241675Suqs struct pmap *pmap = get_current_pmap(); 190241675Suqs 191241675Suqs printf(" obtain address\n"); 192241675Suqs err = pmap->f.determine_addr_raw(pmap, bytes, BASE_PAGE_SIZE, &address); 193241675Suqs if (err_is_fail(err)) 194241675Suqs { 195241675Suqs printf("error in determine_addr_raw: %s\n", err_getstring(err)); 196241675Suqs exit(1); 197241675Suqs } 198241675Suqs 199241675Suqs printf(" map\n"); 200241675Suqs err = pmap->f.map(pmap, address, frame, 0, bytes, PMAP_DEFAULT_ACCESS, NULL, &bytes); 201241675Suqs if (err_is_fail(err)) 202241675Suqs { 203241675Suqs printf("error in pmap: %s\n", err_getstring(err)); 204241675Suqs exit(1); 205241675Suqs } 206241675Suqs printf("addr: %lx\n", address); 207241675Suqs test_region((uint32_t*)address, DEFAULT_SIZE, false, false); 208241675Suqs 209241675Suqs printf("\tunmap\n"); 210241675Suqs err = pmap->f.unmap(pmap, address, bytes, NULL); 211241675Suqs if (err_is_fail(err)) 212241675Suqs { 213241675Suqs printf("error in unmap: %s\n", err_getstring(err)); 214241675Suqs exit(1); 215241675Suqs } 216241675Suqs 217241675Suqs //large page via pmap interface 218241675Suqs printf("start 2m map with pmap\n"); 219241675Suqs bytes = DEFAULT_SIZE; 220241675Suqs struct capref frame2; 221241675Suqs err = frame_alloc(&frame2, bytes, &bytes); 222241675Suqs if (err_is_fail(err)) 223241675Suqs { 224241675Suqs printf("error in frame_alloc: %s\n", err_getstring(err)); 225241675Suqs exit(1); 226241675Suqs } 227241675Suqs assert(bytes >= DEFAULT_SIZE); 228241675Suqs pmap = get_current_pmap(); 229241675Suqs 230241675Suqs printf("determine address\n"); 231241675Suqs err = pmap->f.determine_addr_raw(pmap, bytes, LARGE_PAGE_SIZE, &address); 232241675Suqs if (err_is_fail(err)) 233241675Suqs { 234241675Suqs printf("error in determine_addr_raw: %s\n", err_getstring(err)); 235241675Suqs exit(1); 236241675Suqs } 237241675Suqs 238241675Suqs printf("map\n"); 239241675Suqs err = pmap->f.map(pmap, address, frame, 0, bytes, PMAP_DEFAULT_ACCESS | 0x0100, NULL, &bytes); 240241675Suqs if (err_is_fail(err)) 241241675Suqs { 242241675Suqs printf("error in pmap: %s\n", err_getstring(err)); 243241675Suqs exit(1); 244241675Suqs } 245241675Suqs printf("addr: %lx\n", address); 246241675Suqs test_region((uint32_t*)address, DEFAULT_SIZE, true, false); 247241675Suqs 248241675Suqs err = pmap->f.unmap(pmap, address, bytes, NULL); 249241675Suqs if (err_is_fail(err)) 250241675Suqs { 251241675Suqs printf("error in unmap: %s\n", err_getstring(err)); 252241675Suqs exit(1); 253241675Suqs } 254241675Suqs //small area 4k 255241675Suqs bytes = LARGE_PAGE_SIZE; 256241675Suqs err = frame_alloc(&frame, bytes, &bytes); 257241675Suqs if (err_is_fail(err)) 258241675Suqs { 259241675Suqs printf("error in frame_alloc: %s\n", err_getstring(err)); 260241675Suqs exit(1); 261241675Suqs } 262241675Suqs assert(bytes >= LARGE_PAGE_SIZE); 263241675Suqs pmap = get_current_pmap(); 264241675Suqs err = pmap->f.map(pmap, SAFE_PMAP_ADDR, frame, 0, bytes, PMAP_DEFAULT_ACCESS, NULL, &bytes); 265241675Suqs if (err_is_fail(err)) 266241675Suqs { 267241675Suqs printf("error in pmap small 4k\n"); 268241675Suqs exit(1); 269241675Suqs } 270241675Suqs test_region((uint32_t*) SAFE_PMAP_ADDR, LARGE_PAGE_SIZE, false, true); 271241675Suqs 272241675Suqs //small area 2m 273241675Suqs bytes = LARGE_PAGE_SIZE; 274241675Suqs err = frame_alloc(&frame, bytes, &bytes); 275241675Suqs if (err_is_fail(err)) 276241675Suqs { 277241675Suqs printf("error in frame_alloc: %s\n", err_getstring(err)); 278241675Suqs exit(1); 279241675Suqs } 280241675Suqs assert(bytes >= LARGE_PAGE_SIZE); 281241675Suqs pmap = get_current_pmap(); 282241675Suqs 283241675Suqs printf("map\n"); 284241675Suqs err = pmap->f.map(pmap, SAFE_PMAP_ADDR_L, frame, 0, bytes, PMAP_DEFAULT_ACCESS | 0x0100, NULL, &bytes); 285241675Suqs if (err_is_fail(err)) 286241675Suqs { 287241675Suqs printf("error in pmap: %s\n", err_getstring(err)); 288241675Suqs exit(1); 289241675Suqs } 290241675Suqs printf("addr: %lx\n", SAFE_PMAP_ADDR_L); 291241675Suqs test_region((uint32_t*)SAFE_PMAP_ADDR_L, LARGE_PAGE_SIZE, true, true); 292241675Suqs 293241675Suqs 294241675Suqs 295241675Suqs printf("large area\n"); 296241675Suqs printf("average 4k: %lu, average 2m: %lu\n", mean4k, mean2m); 297241675Suqs printf("minimal 4k: %lu, minimal 2m: %lu\n", min4k, min2m); 298241675Suqs printf("maximal 4k: %lu, maximal 2m: %lu\n", max4k, max2m); 299241675Suqs printf("random: average 4k: %lu, average 2m: %lu\n", mean4krand, mean2mrand); 300241675Suqs printf("random:minimal 4k: %lu, minimal 2m: %lu\n", min4krand, min2mrand); 301241675Suqs printf("random:maximal 4k: %lu, maximal 2m: %lu\n\n", max4krand, max2mrand); 302241675Suqs printf("short area\n"); 303241675Suqs printf("average 4k: %lu, average 2m: %lu\n", mean4kshort, mean2mshort); 304241675Suqs printf("minimal 4k: %lu, minimal 2m: %lu\n", min4kshort, min2mshort); 305241675Suqs printf("maximal 4k: %lu, maximal 2m: %lu\n", max4kshort, max2mshort); 306241675Suqs printf("random: average 4k: %lu, average 2m: %lu\n", mean4kshortrand, mean2mshortrand); 307241675Suqs printf("random:minimal 4k: %lu, minimal 2m: %lu\n", min4kshortrand, min2mshortrand); 308241675Suqs printf("random:maximal 4k: %lu, maximal 2m: %lu\n", max4kshortrand, max2mshortrand); 309241675Suqs printf("exited successfully\n"); 310241675Suqs return 0; 311241675Suqs} 312241675Suqs