iPXE
Macros | Functions | Variables
librm_test.c File Reference

Real mode transition self-tests. More...

#include <ipxe/test.h>
#include <ipxe/profile.h>
#include <realmode.h>

Go to the source code of this file.

Macros

#define PROFILE_COUNT   4096
 Number of sample iterations for profiling. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static __asmcall __used void librm_test_call (struct i386_all_regs *ix86 __unused)
 Dummy function for profiling tests. More...
 
static void librm_test_exec (void)
 Perform real mode transition self-tests. More...
 
 REQUIRING_SYMBOL (librm_test)
 
 REQUIRE_OBJECT (test)
 

Variables

static struct profiler p2r_profiler __profiler = { .name = "p2r" }
 Protected-to-real mode transition profiler. More...
 
struct self_test librm_test __self_test
 Real mode transition self-test. More...
 

Detailed Description

Real mode transition self-tests.

This file allows for easy measurement of the time taken to perform real mode transitions, which may have a substantial overhead when running under a hypervisor.

Definition in file librm_test.c.

Macro Definition Documentation

◆ PROFILE_COUNT

#define PROFILE_COUNT   4096

Number of sample iterations for profiling.

Definition at line 44 of file librm_test.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ librm_test_call()

static __asmcall __used void librm_test_call ( struct i386_all_regs *ix86  __unused)
static

Dummy function for profiling tests.

Definition at line 62 of file librm_test.c.

62  {
63  /* Do nothing */
64 }

Referenced by librm_test_exec().

◆ librm_test_exec()

static void librm_test_exec ( void  )
static

Perform real mode transition self-tests.

Definition at line 70 of file librm_test.c.

70  {
71  unsigned int i;
72  unsigned long timestamp;
73  uint32_t timestamp_lo;
74  uint32_t timestamp_hi;
76  uint32_t stopped;
77  uint32_t discard_d;
78 
79  /* Profile mode transitions. We want to profile each
80  * direction of the transition separately, so perform an RDTSC
81  * while in real mode and tweak the profilers' start/stop
82  * times appropriately.
83  */
84  for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
85  profile_start ( &p2r_profiler );
86  __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t" )
87  : "=a" ( timestamp_lo ),
88  "=d" ( timestamp_hi )
89  : );
90  timestamp = timestamp_lo;
91  if ( sizeof ( timestamp ) > sizeof ( timestamp_lo ) )
92  timestamp |= ( ( ( uint64_t ) timestamp_hi ) << 32 );
93  profile_start_at ( &r2p_profiler, timestamp );
94  profile_stop ( &r2p_profiler );
95  profile_stop_at ( &p2r_profiler, timestamp );
96  }
97 
98  /* Profile complete real-mode call cycle */
99  for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
100  profile_start ( &real_call_profiler );
101  __asm__ __volatile__ ( REAL_CODE ( "" ) : );
102  profile_stop ( &real_call_profiler );
103  }
104 
105  /* Profile complete virtual call cycle */
106  for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
107  __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t"
108  "movl %k0, %k2\n\t"
110  "rdtsc\n\t" )
111  : "=a" ( stopped ), "=d" ( discard_d ),
112  "=R" ( started ) : );
113  profile_start_at ( &virt_call_profiler, started );
114  profile_stop_at ( &virt_call_profiler, stopped );
115  }
116 }
#define VIRT_CALL(function)
Call C function from real-mode code.
Definition: librm.h:78
unsigned long long uint64_t
Definition: stdint.h:13
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:173
static void profile_stop_at(struct profiler *profiler, unsigned long stopped)
Stop profiling.
Definition: profile.h:145
static int started
"startup() has been called" flag
Definition: init.c:37
static __asmcall __used void librm_test_call(struct i386_all_regs *ix86 __unused)
Dummy function for profiling tests.
Definition: librm_test.c:62
#define PROFILE_COUNT
Number of sample iterations for profiling.
Definition: librm_test.c:44
uint64_t timestamp
Timestamp.
Definition: ena.h:20
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:160
__asm__ __volatile__("call *%9" :"=a"(result), "=c"(discard_ecx), "=d"(discard_edx) :"d"(0), "a"(code), "b"(0), "c"(in_phys), "D"(0), "S"(out_phys), "m"(hypercall))
unsigned int uint32_t
Definition: stdint.h:12
static void profile_start_at(struct profiler *profiler, unsigned long started)
Start profiling.
Definition: profile.h:131
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

References __asm__(), __volatile__(), librm_test_call(), PROFILE_COUNT, profile_start(), profile_start_at(), profile_stop(), profile_stop_at(), REAL_CODE, started, profiler::stopped, timestamp, and VIRT_CALL.

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( librm_test  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( test  )

Variable Documentation

◆ __profiler

struct profiler virt_call_profiler __profiler = { .name = "p2r" }
static

Protected-to-real mode transition profiler.

Virtual call profiler.

Real-mode call profiler.

Real-to-protected mode transition profiler.

Definition at line 47 of file librm_test.c.

◆ __self_test

struct self_test librm_test __self_test
Initial value:
= {
.name = "librm",
.exec = librm_test_exec,
}
static void librm_test_exec(void)
Perform real mode transition self-tests.
Definition: librm_test.c:70

Real mode transition self-test.

Definition at line 119 of file librm_test.c.