1/*
2 * Copyright (c) 2015, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <stdio.h>
11#include <inttypes.h>
12#include <barrelfish/barrelfish.h>
13#include <barrelfish_kpi/paging_target.h>
14#include <barrelfish/sys_debug.h>
15
16#include "nestedpaging.h"
17
18int main(int argc, char *argv[])
19{
20    //const char *sysprint = "Hello world (debug_printf)\n";
21    //sys_print(sysprint, strlen(sysprint));
22    //debug_printf("Hello world (debug_printf)\n");
23    printf("Hello world (normal printf)\n");
24    for (int i = 0;i < argc; i ++) {
25        printf("arg[%d] = %s\n", i, argv[i]);
26    }
27
28    // Check that we're in privileged mode
29    uint16_t cs;
30    __asm volatile("mov %%cs, %[reg]"
31            : [reg] "=r" (cs));
32
33    if((cs & 3) == 0) {
34        printf("We're in privileged mode!\n");
35
36        printf("Trying privileged operation...\n");
37        uintptr_t cr0;
38        __asm volatile("mov %%cr0, %[reg]"
39                : [reg] "=r" (cr0));
40
41        printf("Succeeded! CR0 is %" PRIxPTR "\n", cr0);
42    } else {
43        printf("NO privileged mode enabled\n");
44        return EXIT_FAILURE;
45    }
46
47    genvaddr_t base;
48    void *ptable;
49    errval_t err;
50    err = install_user_managed_pdpt(&base, &ptable);
51    assert(err_is_ok(err));
52
53    union x86_64_ptable_entry *pdpt = ptable;
54    struct capref page;
55    size_t size;
56    err = frame_alloc(&page, 4ull * HUGE_PAGE_SIZE, &size);
57    assert(err_is_ok(err));
58    assert(size == 4ull*HUGE_PAGE_SIZE);
59    struct frame_identity fi;
60    err = frame_identify(page, &fi);
61    assert(err_is_ok(err));
62
63    for (uint64_t i = 0; i < 4; i++) {
64        paging_x86_64_map_huge(&pdpt[i], fi.base + i*HUGE_PAGE_SIZE,
65                vregion_to_pmap(VREGION_FLAGS_READ_WRITE));
66    }
67
68    printf("first entry: 0x%"PRIxGENVADDR"\n", pdpt[0].raw);
69
70    uint8_t *buf = (uint8_t *)base;
71    for (uint64_t i = 0; i < 4ull*HUGE_PAGE_SIZE / BASE_PAGE_SIZE; i++) {
72        buf[i*BASE_PAGE_SIZE] = i % 256;
73    }
74    printf("filled 4G, flushing cache & tlb\n");
75    wbinvd();
76    do_full_tlb_flush();
77    for (uint64_t i = 0; i < 4ull*HUGE_PAGE_SIZE / BASE_PAGE_SIZE; i++) {
78        if (buf[i*BASE_PAGE_SIZE] != i % 256) {
79            debug_printf("value mismatch at page %lu: expected %ld, got %d\n",
80                    i, i % 256, buf[i*BASE_PAGE_SIZE]);
81        }
82    }
83    printf("validated 4G, dumping ptables\n");
84
85    debug_dump_hw_ptables();
86    printf("done!\n\n");
87
88    // make stuff not crash
89    while(true);
90    return EXIT_SUCCESS;
91}
92