Merge branch 'master' into master-into-distops
[barrelfish] / lib / barrelfish / arch / arm / sys_debug.c
1 /**
2  * \file
3  * \brief Debug system calls, user-side
4  */
5
6 /*
7  * Copyright (c) 2007, 2008, 2009, 2010, 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, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 #include <barrelfish/barrelfish.h>
16 #include <barrelfish/dispatch.h>
17 #include <barrelfish/syscall_arch.h>
18 #include <barrelfish_kpi/sys_debug.h>
19 #include <barrelfish/sys_debug.h>
20 #include <stdio.h>
21 #include <inttypes.h>
22
23 errval_t sys_nop(void)
24 {
25     return syscall1(SYSCALL_NOP).error;
26 }
27
28 errval_t sys_reboot(void)
29 {
30     return syscall1(SYSCALL_REBOOT).error;
31 }
32
33 errval_t sys_debug_context_counter_reset(void)
34 {
35     return syscall2(SYSCALL_DEBUG, DEBUG_CONTEXT_COUNTER_RESET).error;
36 }
37
38 errval_t sys_debug_context_counter_read(uint64_t *ret)
39 {
40     struct sysret sr = syscall2(SYSCALL_DEBUG, DEBUG_CONTEXT_COUNTER_READ);
41     *ret = sr.value;
42     return sr.error;
43 }
44
45 errval_t sys_debug_print_context_counter(void)
46 {
47     uint64_t val;
48     errval_t err = sys_debug_context_counter_read(&val);
49     if (err_is_ok(err)) {
50         printf("core %d: csc = %" PRIu64 "\n", disp_get_core_id(), val);
51     }
52     return err;
53 }
54
55 errval_t sys_debug_timeslice_counter_read(uint64_t *ret)
56 {
57     struct sysret sr = syscall2(SYSCALL_DEBUG, DEBUG_TIMESLICE_COUNTER_READ);
58     *ret = sr.value;
59     return sr.error;
60 }
61
62 errval_t sys_debug_print_timeslice(void)
63 {
64     uint64_t val;
65     errval_t err = sys_debug_timeslice_counter_read(&val);
66     if (err_is_ok(err)) {
67         printf("core %d: kernel_now = %" PRIu64 "\n", disp_get_core_id(), val);
68     }
69     return err;
70 }
71
72 errval_t sys_debug_flush_cache(void)
73 {
74     return syscall2(SYSCALL_DEBUG, DEBUG_FLUSH_CACHE).error;
75 }
76
77 errval_t sys_debug_send_ipi(uint8_t destination, uint8_t shorthand, uint8_t vector)
78 {
79     return syscall5(SYSCALL_DEBUG,
80                    DEBUG_SEND_IPI, destination, shorthand, vector).error;
81 }
82
83 errval_t sys_debug_set_breakpoint(uintptr_t addr, uint8_t mode, uint8_t length)
84 {
85     return syscall5(SYSCALL_DEBUG,
86                     DEBUG_SET_BREAKPOINT, addr, mode, length).error;
87 }
88
89 errval_t sys_debug_cap_trace_ctrl(bool enable, genpaddr_t start, gensize_t size)
90 {
91     return syscall5(SYSCALL_DEBUG,
92                     DEBUG_TRACE_PMEM_CTRL, enable, start, size).error;
93 }
94
95 errval_t sys_debug_hardware_timer_read(uintptr_t* v)
96 {
97     struct sysret sr
98         = syscall2(SYSCALL_DEBUG, DEBUG_HARDWARE_TIMER_READ);
99     *v = sr.value;
100     return sr.error;
101 }
102
103 errval_t sys_debug_hardware_timer_hertz_read(uintptr_t* v)
104 {
105     struct sysret sr
106         = syscall2(SYSCALL_DEBUG, DEBUG_HARDWARE_TIMER_HERTZ_READ);
107     *v = sr.value;
108     return sr.error;
109 }
110
111 errval_t sys_debug_hardware_global_timer_read(uint64_t *ret)
112 {
113     struct sysret sr;
114
115     uint32_t l, h;
116
117     do {
118         h = syscall2(SYSCALL_DEBUG, DEBUG_HARDWARE_GLOBAL_TIMER_HIGH).value;
119         l = syscall2(SYSCALL_DEBUG, DEBUG_HARDWARE_GLOBAL_TIMER_LOW).value;
120         // read high again, in case it changed
121         sr = syscall2(SYSCALL_DEBUG, DEBUG_HARDWARE_GLOBAL_TIMER_HIGH);
122     } while(h != sr.value && err_is_ok(sr.error));
123
124     if(err_is_ok(sr.error) && ret) {
125         *ret = (((uint64_t) h) << 32) | ((uint32_t) l);
126     }
127
128     return sr.error;
129 }