1/**
2 * \file
3 * \brief Kernel debugging functions
4 */
5
6/*
7 * Copyright (c) 2008, 2016, ETH Zurich.
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, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <kernel.h>
16#include <stdio.h>
17#include <x86.h>
18#include <arch/x86/debug.h>
19#include <paging_kernel_arch.h>
20
21union lin_addr {
22    uint64_t raw;
23    struct {
24        uint64_t  offset       :12;
25        uint64_t  ptable       :9;
26        uint64_t  pdir         :9;
27        uint64_t  pdpt         :9;
28        uint64_t  pml4         :9;
29        uint64_t  sign_extend  :16;
30    } d;
31};
32
33void debug_vaddr_identify(lvaddr_t debug_pml4, lvaddr_t vaddr)
34{
35    int i;
36    printf("cr3 register      %lx\n", debug_pml4);
37    printf("identifying vaddr %lx\n", vaddr);
38
39    volatile uint64_t *temp = (uint64_t*)vaddr;
40
41    for(i = 0; i < 512; i++) {
42        printf("at addr %lx content is %lx\n", (uint64_t)(temp + i), *(temp + i));
43    }
44    printf("\n");
45
46    union lin_addr lin_addr;
47    lin_addr.raw = (uint64_t)vaddr;
48
49    printf("vaddr broken down\n");
50    printf("sign_extend = %x\n", lin_addr.d.sign_extend);
51    printf("pml4        = %x\n", lin_addr.d.pml4);
52    printf("pdpt        = %x\n", lin_addr.d.pdpt);
53    printf("pdir        = %x\n", lin_addr.d.pdir);
54    printf("ptable      = %x\n", lin_addr.d.ptable);
55    printf("offset      = %x\n", lin_addr.d.offset);
56
57    uint64_t *pml4et;
58    pml4et = (uint64_t*)(debug_pml4 +
59                         (lin_addr.d.pml4 * sizeof(union x86_64_pdir_entry)));
60    printf("addr = %lx ", (uint64_t)pml4et);
61    printf("content = %lx\n", *pml4et);
62
63    lvaddr_t pdpt_addr;
64    pdpt_addr = local_phys_to_mem(((union x86_64_pdir_entry*)pml4et)->d.base_addr << 12);
65    uint64_t *pdptet;
66    pdptet = (uint64_t*)(pdpt_addr +
67                         (lin_addr.d.pdpt * sizeof(union x86_64_pdir_entry)));
68    printf("addr = %lx ", (uint64_t)pdptet);
69    printf("content = %lx\n", *pdptet);
70
71    lvaddr_t pdir_addr;
72    pdir_addr = local_phys_to_mem(((union x86_64_pdir_entry*)pdptet)->d.base_addr << 12);
73    uint64_t *pdiret;
74    pdiret = (uint64_t*)(pdir_addr +
75                         (lin_addr.d.pdir * sizeof(union x86_64_pdir_entry)));
76    printf("addr = %lx ", (uint64_t)pdiret);
77    printf("content = %lx\n", *pdiret);
78
79    lvaddr_t ptable_addr;
80    ptable_addr = local_phys_to_mem(((union x86_64_pdir_entry*)pdiret)->d.base_addr << 12);
81    uint64_t *ptableet;
82    ptableet = (uint64_t*)(ptable_addr +
83                         (lin_addr.d.ptable * sizeof(union x86_64_pdir_entry)));
84    printf("addr = %lx ", (uint64_t)ptableet);
85    printf("content = %lx\n", *ptableet);
86
87    lpaddr_t addr = ((union x86_64_ptable_entry*)ptableet)->base.base_addr << 12;
88    printf("addr = %lx\n", addr);
89}
90
91uintptr_t kernel_virt_to_elf_addr(void *addr)
92{
93    return (uintptr_t)addr - (uintptr_t)&_start_kernel + START_KERNEL_PHYS;
94}
95