summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/transitions/librm_mgmt.c
diff options
context:
space:
mode:
authorMichael Brown2014-05-04 12:45:11 +0200
committerMichael Brown2014-05-04 14:39:42 +0200
commit6f410a16d946d7015eaa11c1b255c28debb0d8b5 (patch)
tree854316bd29bdc637ee09951452c1cb12c7b197a3 /src/arch/i386/transitions/librm_mgmt.c
parent[undi] Place an upper limit on the number of PXENV_UNDI_ISR calls per poll (diff)
downloadipxe-6f410a16d946d7015eaa11c1b255c28debb0d8b5.tar.gz
ipxe-6f410a16d946d7015eaa11c1b255c28debb0d8b5.tar.xz
ipxe-6f410a16d946d7015eaa11c1b255c28debb0d8b5.zip
[profile] Allow interrupts to be excluded from profiling results
Interrupt processing adds noise to profiling results. Allow interrupts (from within protected mode) to be profiled separately, with time spent within the interrupt handler being excluded from any other profiling currently in progress. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/i386/transitions/librm_mgmt.c')
-rw-r--r--src/arch/i386/transitions/librm_mgmt.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/arch/i386/transitions/librm_mgmt.c b/src/arch/i386/transitions/librm_mgmt.c
index f90d49b0..89668978 100644
--- a/src/arch/i386/transitions/librm_mgmt.c
+++ b/src/arch/i386/transitions/librm_mgmt.c
@@ -8,6 +8,7 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <stdint.h>
+#include <ipxe/profile.h>
#include <realmode.h>
#include <pic8259.h>
@@ -30,6 +31,12 @@ struct idtr idtr = {
.limit = ( sizeof ( idt ) - 1 ),
};
+/** Timer interrupt profiler */
+static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" };
+
+/** Other interrupt profiler */
+static struct profiler other_irq_profiler __profiler = { .name = "irq.other" };
+
/**
* Allocate space on the real-mode stack and copy data there from a
* user buffer
@@ -104,18 +111,38 @@ void init_idt ( void ) {
}
/**
+ * Determine interrupt profiler (for debugging)
+ *
+ * @v intr Interrupt number
+ * @ret profiler Profiler
+ */
+static struct profiler * interrupt_profiler ( int intr ) {
+
+ switch ( intr ) {
+ case IRQ_INT ( 0 ) :
+ return &timer_irq_profiler;
+ default:
+ return &other_irq_profiler;
+ }
+}
+
+/**
* Interrupt handler
*
- * @v irq Interrupt number
+ * @v intr Interrupt number
*/
-void __attribute__ (( cdecl, regparm ( 1 ) )) interrupt ( int irq ) {
+void __attribute__ (( cdecl, regparm ( 1 ) )) interrupt ( int intr ) {
+ struct profiler *profiler = interrupt_profiler ( intr );
uint32_t discard_eax;
/* Reissue interrupt in real mode */
+ profile_start ( profiler );
__asm__ __volatile__ ( REAL_CODE ( "movb %%al, %%cs:(1f + 1)\n\t"
"\n1:\n\t"
"int $0x00\n\t" )
- : "=a" ( discard_eax ) : "0" ( irq ) );
+ : "=a" ( discard_eax ) : "0" ( intr ) );
+ profile_stop ( profiler );
+ profile_exclude ( profiler );
}
PROVIDE_UACCESS_INLINE ( librm, phys_to_user );