mirror of https://github.com/ipxe/ipxe.git
[pxe] Profile all PXE API calls
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/19/head
parent
be7f35d9c0
commit
579337c368
|
@ -21,6 +21,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
|
|
||||||
#include <ipxe/uaccess.h>
|
#include <ipxe/uaccess.h>
|
||||||
#include <ipxe/init.h>
|
#include <ipxe/init.h>
|
||||||
|
#include <ipxe/profile.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <registers.h>
|
#include <registers.h>
|
||||||
#include <biosint.h>
|
#include <biosint.h>
|
||||||
|
@ -48,6 +49,26 @@ extern void pxe_int_1a ( void );
|
||||||
/** INT 1A hooked flag */
|
/** INT 1A hooked flag */
|
||||||
static int int_1a_hooked = 0;
|
static int int_1a_hooked = 0;
|
||||||
|
|
||||||
|
/** PXENV_UNDI_TRANSMIT API call profiler */
|
||||||
|
static struct profiler pxe_api_tx_profiler __profiler =
|
||||||
|
{ .name = "pxeapi.tx" };
|
||||||
|
|
||||||
|
/** PXENV_UNDI_ISR API call profiler */
|
||||||
|
static struct profiler pxe_api_isr_profiler __profiler =
|
||||||
|
{ .name = "pxeapi.isr" };
|
||||||
|
|
||||||
|
/** PXE unknown API call profiler
|
||||||
|
*
|
||||||
|
* This profiler can be used to measure the overhead of a dummy PXE
|
||||||
|
* API call.
|
||||||
|
*/
|
||||||
|
static struct profiler pxe_api_unknown_profiler __profiler =
|
||||||
|
{ .name = "pxeapi.unknown" };
|
||||||
|
|
||||||
|
/** Miscellaneous PXE API call profiler */
|
||||||
|
static struct profiler pxe_api_misc_profiler __profiler =
|
||||||
|
{ .name = "pxeapi.misc" };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle an unknown PXE API call
|
* Handle an unknown PXE API call
|
||||||
*
|
*
|
||||||
|
@ -80,6 +101,27 @@ static struct pxe_api_call * find_pxe_api_call ( uint16_t opcode ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine applicable profiler (for debugging)
|
||||||
|
*
|
||||||
|
* @v opcode PXE opcode
|
||||||
|
* @ret profiler Profiler
|
||||||
|
*/
|
||||||
|
static struct profiler * pxe_api_profiler ( unsigned int opcode ) {
|
||||||
|
|
||||||
|
/* Determine applicable profiler */
|
||||||
|
switch ( opcode ) {
|
||||||
|
case PXENV_UNDI_TRANSMIT:
|
||||||
|
return &pxe_api_tx_profiler;
|
||||||
|
case PXENV_UNDI_ISR:
|
||||||
|
return &pxe_api_isr_profiler;
|
||||||
|
case PXENV_UNKNOWN:
|
||||||
|
return &pxe_api_unknown_profiler;
|
||||||
|
default:
|
||||||
|
return &pxe_api_misc_profiler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch PXE API call
|
* Dispatch PXE API call
|
||||||
*
|
*
|
||||||
|
@ -90,10 +132,14 @@ static struct pxe_api_call * find_pxe_api_call ( uint16_t opcode ) {
|
||||||
__asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) {
|
__asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) {
|
||||||
uint16_t opcode = ix86->regs.bx;
|
uint16_t opcode = ix86->regs.bx;
|
||||||
userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di );
|
userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di );
|
||||||
|
struct profiler *profiler = pxe_api_profiler ( opcode );
|
||||||
struct pxe_api_call *call;
|
struct pxe_api_call *call;
|
||||||
union u_PXENV_ANY params;
|
union u_PXENV_ANY params;
|
||||||
PXENV_EXIT_t ret;
|
PXENV_EXIT_t ret;
|
||||||
|
|
||||||
|
/* Start profiling */
|
||||||
|
profile_start ( profiler );
|
||||||
|
|
||||||
/* Locate API call */
|
/* Locate API call */
|
||||||
call = find_pxe_api_call ( opcode );
|
call = find_pxe_api_call ( opcode );
|
||||||
if ( ! call ) {
|
if ( ! call ) {
|
||||||
|
@ -113,6 +159,9 @@ __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) {
|
||||||
/* Copy modified parameter block back to caller and return */
|
/* Copy modified parameter block back to caller and return */
|
||||||
copy_to_user ( uparams, 0, ¶ms, call->params_len );
|
copy_to_user ( uparams, 0, ¶ms, call->params_len );
|
||||||
ix86->regs.ax = ret;
|
ix86->regs.ax = ret;
|
||||||
|
|
||||||
|
/* Stop profiling, if applicable */
|
||||||
|
profile_stop ( profiler );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue