1/**
2 * \file
3 * \brief Architecture-specific microbenchmarks.
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, 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 <kernel.h>
16#include <microbenchmarks.h>
17#include <arch/x86/apic.h>
18#include <x86.h>
19
20// address space switch (mov to cr3)
21static int asswitch_func(struct microbench *mb)
22{
23    uint64_t start, end;
24    uint64_t asvalue;
25
26    // Put the cr3 value in the asvalue register for now
27    __asm__ __volatile__("mov %%cr3, %0" : "=r" (asvalue));
28
29    start = rdtscp();
30    for (int i = 0; i < MICROBENCH_ITERATIONS; i++) {
31        __asm__ __volatile__(
32            "mov %0, %%cr3"
33            :
34            : "r" (asvalue));
35    }
36    end = rdtscp();
37
38    mb->result = end - start;
39
40    return 0;
41}
42
43static int wrmsr_func(struct microbench *mb)
44{
45    uint64_t start, end;
46
47    start = rdtscp();
48    for (int i = 0; i < MICROBENCH_ITERATIONS; i++) {
49        wrmsr(MSR_IA32_FSBASE, 0);
50    }
51    end = rdtscp();
52
53    mb->result = end - start;
54
55    return 0;
56}
57
58static int init_ipi_func(struct microbench *mb)
59{
60    uint64_t start, end;
61
62    start = rdtscp();
63    for (int i = 0; i < MICROBENCH_ITERATIONS; i++) {
64        apic_send_init_assert(1, xapic_none);
65        apic_send_init_deassert();
66    }
67    end = rdtscp();
68
69    mb->result = end - start;
70
71    return 0;
72}
73
74static int start_ipi_func(struct microbench *mb)
75{
76    uint64_t start, end;
77
78    start = rdtscp();
79    for (int i = 0; i < MICROBENCH_ITERATIONS; i++) {
80        apic_send_start_up(1, xapic_none, 0x6);
81    }
82    end = rdtscp();
83
84    mb->result = end - start;
85
86    return 0;
87}
88
89struct microbench arch_benchmarks[] = {
90    {
91        .name = "wrmsr",
92        .run_func = wrmsr_func
93    },
94    {
95        .name = "address space switch (mov to cr3)",
96        .run_func = asswitch_func
97    },
98    {
99        .name = "Send INIT IPI",
100        .run_func = init_ipi_func
101    },
102    {
103        .name = "Send SIPI",
104        .run_func = start_ipi_func
105    }
106};
107
108size_t arch_benchmarks_size = sizeof(arch_benchmarks) / sizeof(struct microbench);
109