Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/arch/i386/measure.c need to be fixed.

0001 /*                    The Quest Operating System
0002  *  Copyright (C) 2005-2010  Richard West, Boston University
0003  *
0004  *  This program is free software: you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation, either version 3 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 /* Timing and measurement code */
0019 
0020 #include "kernel.h"
0021 #include "util/debug.h"
0022 
0023 #define ITER 10
0024 
0025 extern u32 tick;
0026 
0027 #define TIMING_ASM(var, insrs, edi)                                     \
0028   asm volatile ("xorl %%eax, %%eax\n"                                   \
0029                 "lldt %%ax\n"                                           \
0030                 "rdtsc\n"                                               \
0031                 "movl %%eax, %%esi\n"                                   \
0032                                                                         \
0033                 insrs                                                   \
0034                                                                         \
0035                 "xorl %%eax, %%eax\n"                                   \
0036                 "lldt %%ax\n"                                           \
0037                 "rdtsc\n"                                               \
0038                 "subl %%esi, %%eax\n"                                   \
0039                 :"=a" (diff):"D" (edi): "ebx", "ecx", "edx", "esi")
0040 
0041 void
0042 measure_LAPIC_read (void)
0043 {
0044   u32 diff, i;
0045   if ((tick & 0xFF) == 0) {
0046     for (i=0; i<ITER; i++){
0047       TIMING_ASM (diff,                             \
0048                   "movl 0xFEE00020, %%ecx\n"        \
0049                   "movl 0xFEE00020, %%ecx\n"        \
0050                   "movl 0xFEE00020, %%ecx\n"        \
0051                   "movl 0xFEE00020, %%ecx\n"        \
0052                   "movl 0xFEE00020, %%ecx\n"        \
0053                   "movl 0xFEE00020, %%ecx\n"        \
0054                   "movl 0xFEE00020, %%ecx\n"        \
0055                   "movl 0xFEE00020, %%ecx\n"        \
0056                   "movl 0xFEE00020, %%ecx\n"        \
0057                   "movl 0xFEE00020, %%ecx\n"        \
0058                   , 0);
0059     }
0060     logger_printf ("measure_LAPIC_read: %u\n", diff);
0061   }
0062 }
0063 
0064 void
0065 measure_DR3_write (void)
0066 {
0067   u32 diff;
0068   if ((tick & 0xFF) == 0) {
0069     TIMING_ASM (diff,                           \
0070                   "movl %%ecx, %%dr3\n"         \
0071                   "movl %%ecx, %%dr3\n"         \
0072                   "movl %%ecx, %%dr3\n"         \
0073                   "movl %%ecx, %%dr3\n"         \
0074                   "movl %%ecx, %%dr3\n"         \
0075                   "movl %%ecx, %%dr3\n"         \
0076                   "movl %%ecx, %%dr3\n"         \
0077                   "movl %%ecx, %%dr3\n"         \
0078                   "movl %%ecx, %%dr3\n"         \
0079                   "movl %%ecx, %%dr3\n"
0080                 , 0);
0081     logger_printf ("measure_DR3_write: %u\n", diff);
0082   }
0083 }
0084 
0085 void
0086 measure_DR3_read (void)
0087 {
0088   u32 diff;
0089   if ((tick & 0xFF) == 0) {
0090     TIMING_ASM (diff,                           \
0091                   "movl %%dr3, %%ecx\n"         \
0092                   "movl %%dr3, %%ecx\n"         \
0093                   "movl %%dr3, %%ecx\n"         \
0094                   "movl %%dr3, %%ecx\n"         \
0095                   "movl %%dr3, %%ecx\n"         \
0096                   "movl %%dr3, %%ecx\n"         \
0097                   "movl %%dr3, %%ecx\n"         \
0098                   "movl %%dr3, %%ecx\n"         \
0099                   "movl %%dr3, %%ecx\n"         \
0100                   "movl %%dr3, %%ecx\n"
0101                 , 0);
0102     logger_printf ("measure_DR3_read: %u\n", diff);
0103   }
0104 }
0105 
0106 void
0107 measure_FS_read (void)
0108 {
0109   u32 diff;
0110   static u32 idx = 0;
0111   descriptor seg = {
0112     .pBase0 = 0x1000,
0113     .pBase1 = 0xFF,
0114     .pBase2 = 0xFF,
0115     .uLimit0 = 0x1000,
0116     .uType  = 0x12,             /* writeable */
0117     .uDPL   = 0,
0118     .fPresent = 1,
0119     .uLimit1 = 0,
0120     .f = 0,
0121     .f0 = 0,
0122     .fX = 1,
0123     .fGranularity = 0
0124   };
0125   descriptor *ad = (descriptor *) KERN_GDT;
0126   if ((tick & 0xFF) == 0) {
0127     if (idx == 0) {
0128       for (idx=1;idx<256;idx++) {
0129         if (!(ad[idx].fPresent)) {
0130           memcpy (&ad[idx], &seg, sizeof (seg));
0131           idx <<= 3;
0132           break;
0133         }
0134       }
0135     }
0136 
0137     TIMING_ASM (diff,
0138                 "movw %%di, %%fs\n"           \
0139                 "movl %%fs:0, %%ecx\n"        \
0140                 "movl %%fs:0, %%ecx\n"        \
0141                 "movl %%fs:0, %%ecx\n"        \
0142                 "movl %%fs:0, %%ecx\n"        \
0143                 "movl %%fs:0, %%ecx\n"        \
0144                 "movl %%fs:0, %%ecx\n"        \
0145                 "movl %%fs:0, %%ecx\n"        \
0146                 "movl %%fs:0, %%ecx\n"        \
0147                 "movl %%fs:0, %%ecx\n"        \
0148                 "movl %%fs:0, %%ecx\n"
0149                 , idx);
0150 
0151     logger_printf ("measure_FS_read: %u\n", diff);
0152   }
0153 }
0154 
0155 void
0156 measure_FS_load (void)
0157 {
0158   u32 i, diff, fs;
0159   if ((tick & 0xFF) == 0) {
0160     asm volatile ("movl %%fs, %0":"=r" (fs));
0161     for (i=0; i<ITER; i++) {
0162       TIMING_ASM (diff,
0163                   "movw $0x10, %%dx\n"          \
0164                   "movw %%dx, %%fs\n"           \
0165                   "movw %%dx, %%fs\n"           \
0166                   "movw %%dx, %%fs\n"           \
0167                   "movw %%dx, %%fs\n"           \
0168                   "movw %%dx, %%fs\n"           \
0169                   "movw %%dx, %%fs\n"           \
0170                   "movw %%dx, %%fs\n"           \
0171                   "movw %%dx, %%fs\n"           \
0172                   "movw %%dx, %%fs\n"           \
0173                   "movw %%dx, %%fs\n"           \
0174                   , 0);
0175     }
0176     asm volatile ("movl %0, %%fs"::"r" (fs));
0177     logger_printf ("measure_FS_load: %u\n", diff);
0178   }
0179 }
0180 
0181 void
0182 measure_outport_overhead (void)
0183 {
0184   u32 i, diff;
0185   if ((tick & 0xFF) == 0) {
0186     for (i=0; i<ITER; i++) {
0187       TIMING_ASM (diff,
0188                   "movw $0x8A00, %%ax\n"         \
0189                   "movw $0x8A00, %%dx\n"         \
0190                   "outw %%ax, (%%dx)\n"           \
0191                   "outw %%ax, (%%dx)\n"           \
0192                   "outw %%ax, (%%dx)\n"           \
0193                   "outw %%ax, (%%dx)\n"           \
0194                   "outw %%ax, (%%dx)\n"           \
0195                   "outw %%ax, (%%dx)\n"           \
0196                   "outw %%ax, (%%dx)\n"           \
0197                   "outw %%ax, (%%dx)\n"           \
0198                   "outw %%ax, (%%dx)\n"           \
0199                   "outw %%ax, (%%dx)\n"           \
0200                   , 0);
0201     }
0202     logger_printf ("measure_outport_overhead: %u\n", diff);
0203   }
0204 }
0205 
0206 void
0207 measure_timing_overhead (void)
0208 {
0209   u32 diff;
0210   if ((tick & 0xFF) == 0) {
0211     TIMING_ASM (diff, , 0);
0212     TIMING_ASM (diff, , 0);
0213     TIMING_ASM (diff, , 0);
0214     TIMING_ASM (diff, , 0);
0215     TIMING_ASM (diff, , 0);
0216     logger_printf ("measure_timing_overhead: %u\n", diff);
0217   }
0218 }
0219 
0220 void
0221 measure_run (void)
0222 {
0223   measure_timing_overhead ();
0224   measure_LAPIC_read ();
0225   measure_FS_load ();
0226   measure_outport_overhead ();
0227 }
0228 
0229 /*
0230  * Local Variables:
0231  * indent-tabs-mode: nil
0232  * mode: C
0233  * c-file-style: "gnu"
0234  * c-basic-offset: 2
0235  * End:
0236  */
0237 
0238 /* vi: set et sw=2 sts=2: */