~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/ipxe/src/arch/x86/transitions/librm_test.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; either version 2 of the
 
7
 * License, or any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful, but
 
10
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
17
 * 02110-1301, USA.
 
18
 *
 
19
 * You can also choose to distribute this program under the terms of
 
20
 * the Unmodified Binary Distribution Licence (as given in the file
 
21
 * COPYING.UBDL), provided that you have satisfied its requirements.
 
22
 */
 
23
 
 
24
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
25
 
 
26
/** @file
 
27
 *
 
28
 * Real mode transition self-tests
 
29
 *
 
30
 * This file allows for easy measurement of the time taken to perform
 
31
 * real mode transitions, which may have a substantial overhead when
 
32
 * running under a hypervisor.
 
33
 *
 
34
 */
 
35
 
 
36
/* Forcibly enable assertions */
 
37
#undef NDEBUG
 
38
 
 
39
#include <ipxe/test.h>
 
40
#include <ipxe/profile.h>
 
41
#include <realmode.h>
 
42
 
 
43
/** Number of sample iterations for profiling */
 
44
#define PROFILE_COUNT 4096
 
45
 
 
46
/** Protected-to-real mode transition profiler */
 
47
static struct profiler p2r_profiler __profiler = { .name = "p2r" };
 
48
 
 
49
/** Real-to-protected mode transition profiler */
 
50
static struct profiler r2p_profiler __profiler = { .name = "r2p" };
 
51
 
 
52
/** Real-mode call profiler */
 
53
static struct profiler real_call_profiler __profiler = { .name = "real_call" };
 
54
 
 
55
/** Virtual call profiler */
 
56
static struct profiler virt_call_profiler __profiler = { .name = "virt_call" };
 
57
 
 
58
/**
 
59
 * Dummy function for profiling tests
 
60
 */
 
61
static __asmcall void librm_test_call ( struct i386_all_regs *ix86 __unused ) {
 
62
        /* Do nothing */
 
63
}
 
64
 
 
65
/**
 
66
 * Perform real mode transition self-tests
 
67
 *
 
68
 */
 
69
static void librm_test_exec ( void ) {
 
70
        unsigned int i;
 
71
        unsigned long timestamp;
 
72
        uint32_t timestamp_lo;
 
73
        uint32_t timestamp_hi;
 
74
        uint32_t started;
 
75
        uint32_t stopped;
 
76
        uint32_t discard_d;
 
77
 
 
78
        /* Profile mode transitions.  We want to profile each
 
79
         * direction of the transition separately, so perform an RDTSC
 
80
         * while in real mode and tweak the profilers' start/stop
 
81
         * times appropriately.
 
82
         */
 
83
        for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
 
84
                profile_start ( &p2r_profiler );
 
85
                __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t" )
 
86
                                       : "=a" ( timestamp_lo ),
 
87
                                         "=d" ( timestamp_hi )
 
88
                                       : );
 
89
                timestamp = timestamp_lo;
 
90
                if ( sizeof ( timestamp ) > sizeof ( timestamp_lo ) )
 
91
                        timestamp |= ( ( ( uint64_t ) timestamp_hi ) << 32 );
 
92
                profile_start_at ( &r2p_profiler, timestamp );
 
93
                profile_stop ( &r2p_profiler );
 
94
                profile_stop_at ( &p2r_profiler, timestamp );
 
95
        }
 
96
 
 
97
        /* Profile complete real-mode call cycle */
 
98
        for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
 
99
                profile_start ( &real_call_profiler );
 
100
                __asm__ __volatile__ ( REAL_CODE ( "" ) );
 
101
                profile_stop ( &real_call_profiler );
 
102
        }
 
103
 
 
104
        /* Profile complete virtual call cycle */
 
105
        for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
 
106
                __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t"
 
107
                                                   "movl %k0, %k2\n\t"
 
108
                                                   VIRT_CALL ( librm_test_call )
 
109
                                                   "rdtsc\n\t" )
 
110
                                       : "=a" ( stopped ), "=d" ( discard_d ),
 
111
                                         "=R" ( started ) : );
 
112
                profile_start_at ( &virt_call_profiler, started );
 
113
                profile_stop_at ( &virt_call_profiler, stopped );
 
114
        }
 
115
}
 
116
 
 
117
/** Real mode transition self-test */
 
118
struct self_test librm_test __self_test = {
 
119
        .name = "librm",
 
120
        .exec = librm_test_exec,
 
121
};
 
122
 
 
123
REQUIRING_SYMBOL ( librm_test );
 
124
REQUIRE_OBJECT ( test );