1/** 2 * \file 3 * \brief Test program for large page code 4 */ 5 6/* 7 * Copyright (c) 2014, HP Labs. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <barrelfish/barrelfish.h> 16#include <barrelfish/sys_debug.h> 17 18#define RUNS 2 19 20int main(void) 21{ 22 errval_t err; 23 struct capref frame; 24 size_t retsize; 25 void *vbuf; 26 struct vregion *vregion; 27 uint8_t *buf; 28 int errors; 29 30 // get frame 31 err = frame_alloc(&frame, X86_64_HUGE_PAGE_SIZE, &retsize); 32 assert(retsize >= X86_64_HUGE_PAGE_SIZE); 33 if (err_is_fail(err)) { 34 debug_printf("frame_alloc: %s\n", err_getstring(err)); 35 return 1; 36 } 37 38 for (int k = 0; k < RUNS; k++) { 39 debug_printf("Running 2M/1G test\n"); 40 // map with alignment and large flag (don't need memobj) 41 err = vspace_map_one_frame_attr_aligned(&vbuf, retsize, frame, 42 VREGION_FLAGS_READ_WRITE | VREGION_FLAGS_LARGE, 43 X86_64_HUGE_PAGE_SIZE, NULL, &vregion); 44 if (err_is_fail(err)) { 45 debug_printf("vspace_map: %s\n", err_getstring(err)); 46 return 1; 47 } 48 49 debug_printf("vaddr: %p\n", vbuf); 50 51 // touch every 4k page in region 52 buf = vbuf; 53 for (int i = 0; i < X86_64_HUGE_PAGE_SIZE / X86_64_BASE_PAGE_SIZE; i++) { 54 buf[i*BASE_PAGE_SIZE] = i % 256; 55 } 56 // clear out caches 57 sys_debug_flush_cache(); 58 errors = 0; 59 for (int i = 0; i < X86_64_HUGE_PAGE_SIZE / X86_64_BASE_PAGE_SIZE; i++) { 60 if (buf[i*BASE_PAGE_SIZE] != i % 256) { 61 debug_printf("mismatch in page %d: expected %d, was %d\n", 62 i, i % 256, buf[i*BASE_PAGE_SIZE]); 63 errors++; 64 } 65 } 66 debug_printf("2M/1G test %s\n", errors ? "FAILED" : "PASSED"); 67 if (errors) { 68 debug_printf(" %d errors\n", errors); 69 } 70 71 vregion_destroy(vregion); 72 } 73 for (int k = 0; k < RUNS; k++) { 74 debug_printf("Running 2M/2M test\n"); 75 // map with large flag 76 err = vspace_map_one_frame_attr_aligned(&vbuf, retsize, frame, 77 VREGION_FLAGS_READ_WRITE | VREGION_FLAGS_LARGE, 78 X86_64_LARGE_PAGE_SIZE, NULL, &vregion); 79 if (err_is_fail(err)) { 80 debug_printf("vspace_map: %s\n", err_getstring(err)); 81 return 1; 82 } 83 84 debug_printf("vaddr: %p\n", vbuf); 85 86 // touch every 4k page in region 87 buf = vbuf; 88 for (int i = 0; i < X86_64_HUGE_PAGE_SIZE / X86_64_BASE_PAGE_SIZE; i++) { 89 buf[i*BASE_PAGE_SIZE] = i % 256; 90 } 91 // clear out caches 92 sys_debug_flush_cache(); 93 errors = 0; 94 for (int i = 0; i < X86_64_HUGE_PAGE_SIZE / X86_64_BASE_PAGE_SIZE; i++) { 95 if (buf[i*BASE_PAGE_SIZE] != i % 256) { 96 debug_printf("mismatch in page %d: expected %d, was %d\n", 97 i, i % 256, buf[i*BASE_PAGE_SIZE]); 98 errors++; 99 } 100 } 101 debug_printf("2M/2M test %s\n", errors ? "FAILED" : "PASSED"); 102 if (errors) { 103 debug_printf(" %d errors\n", errors); 104 } 105 106 vregion_destroy(vregion); 107 } 108 109 uint32_t eax, ebx, ecx, edx; 110 cpuid(0x80000001, &eax, &ebx, &ecx, &edx); 111 if ((edx >> 26) & 1) { 112 debug_printf("Running 1G/1G test\n"); 113 err = vspace_map_one_frame_attr_aligned(&vbuf, retsize, frame, 114 VREGION_FLAGS_READ_WRITE | VREGION_FLAGS_HUGE, 115 X86_64_HUGE_PAGE_SIZE, NULL, &vregion); 116 if (err_is_fail(err)) { 117 debug_printf("vspace_map: %s\n", err_getstring(err)); 118 return 1; 119 } 120 121 // touch every 4k page in region 122 buf = vbuf; 123 for (int i = 0; i < X86_64_HUGE_PAGE_SIZE / X86_64_BASE_PAGE_SIZE; i++) { 124 buf[i*BASE_PAGE_SIZE] = i % 256; 125 } 126 // clear out caches 127 sys_debug_flush_cache(); 128 errors = 0; 129 for (int i = 0; i < X86_64_HUGE_PAGE_SIZE / X86_64_BASE_PAGE_SIZE; i++) { 130 if (buf[i*BASE_PAGE_SIZE] != i % 256) { 131 debug_printf("mismatch in page %d: expected %d, was %d\n", 132 i, i % 256, buf[i*BASE_PAGE_SIZE]); 133 errors++; 134 } 135 } 136 debug_printf("1G/1G test %s\n", errors ? "FAILED" : "PASSED"); 137 if (errors) { 138 debug_printf(" %d errors\n", errors); 139 } 140 } 141 return 0; 142} 143