iPXE
librm_mgmt.c
Go to the documentation of this file.
1/*
2 * librm: a library for interfacing to real-mode code
3 *
4 * Michael Brown <mbrown@fensystems.co.uk>
5 *
6 */
7
8FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
9
10#include <stdint.h>
11#include <strings.h>
12#include <assert.h>
13#include <ipxe/profile.h>
14#include <realmode.h>
15#include <pic8259.h>
16#include <ipxe/shell.h>
17#include <ipxe/cpuid.h>
18
19/*
20 * This file provides functions for managing librm.
21 *
22 */
23
24/* Calling convention used by interrupt wrapper */
25#ifdef __x86_64__
26#define __intrcall
27#else
28#define __intrcall __attribute__ (( regparm ( 3 ) ))
29#endif
30
31/** The interrupt wrapper */
32extern char interrupt_wrapper[];
33
34/** The interrupt vectors */
36
37/** The 32-bit interrupt descriptor table */
38static struct interrupt32_descriptor
39idt32[NUM_INT] __attribute__ (( aligned ( 16 ) ));
40
41/** The 32-bit interrupt descriptor table register */
42struct idtr32 idtr32 = {
43 .limit = ( sizeof ( idt32 ) - 1 ),
44};
45
46/** The 64-bit interrupt descriptor table */
47static struct interrupt64_descriptor
48idt64[NUM_INT] __attribute__ (( aligned ( 16 ) ));
49
50/** The interrupt descriptor table register */
51struct idtr64 idtr64 = {
52 .limit = ( sizeof ( idt64 ) - 1 ),
53};
54
55/** Startup IPI register state */
57
58/** Length of stack dump */
59#define STACK_DUMP_LEN 128
60
61/** Timer interrupt profiler */
62static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" };
63
64/** Other interrupt profiler */
65static struct profiler other_irq_profiler __profiler = { .name = "irq.other" };
66
67/**
68 * Allocate space on the real-mode stack and copy data there
69 *
70 * @v data Stack data
71 * @v size Size of stack data
72 * @ret sp New value of real-mode stack pointer
73 */
74uint16_t copy_to_rm_stack ( const void *data, size_t size ) {
75 void *rm_stack;
76
77 rm_sp -= size;
78 rm_stack = real_to_virt ( rm_ss, rm_sp );
79 memcpy ( rm_stack, data, size );
80 return rm_sp;
81}
82
83/**
84 * Deallocate space on the real-mode stack, optionally copying back data
85 *
86 * @v data Stack data buffer, or NULL
87 * @v size Size of stack data
88 */
89void remove_from_rm_stack ( void *data, size_t size ) {
90 const void *rm_stack;
91
92 if ( data ) {
93 rm_stack = real_to_virt ( rm_ss, rm_sp );
94 memcpy ( data, rm_stack, size );
95 }
96 rm_sp += size;
97}
98
99/**
100 * Set interrupt vector
101 *
102 * @v intr Interrupt number
103 * @v vector Interrupt vector, or NULL to disable
104 */
105void set_interrupt_vector ( unsigned int intr, void *vector ) {
106 struct interrupt32_descriptor *idte32;
107 struct interrupt64_descriptor *idte64;
108 intptr_t addr = ( ( intptr_t ) vector );
109
110 /* Populate 32-bit interrupt descriptor */
111 idte32 = &idt32[intr];
112 idte32->segment = VIRTUAL_CS;
113 idte32->attr = ( vector ? ( IDTE_PRESENT | IDTE_TYPE_IRQ32 ) : 0 );
114 idte32->low = ( addr >> 0 );
115 idte32->high = ( addr >> 16 );
116
117 /* Populate 64-bit interrupt descriptor, if applicable */
118 if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
119 idte64 = &idt64[intr];
120 idte64->segment = LONG_CS;
121 idte64->attr = ( vector ?
122 ( IDTE_PRESENT | IDTE_TYPE_IRQ64 ) : 0 );
123 idte64->low = ( addr >> 0 );
124 idte64->mid = ( addr >> 16 );
125 idte64->high = ( ( ( uint64_t ) addr ) >> 32 );
126 }
127}
128
129/**
130 * Initialise interrupt descriptor table
131 *
132 */
133__asmcall void init_idt ( void ) {
134 struct interrupt_vector *vec;
135 unsigned int intr;
136
137 /* Initialise the interrupt descriptor table and interrupt vectors */
138 for ( intr = 0 ; intr < NUM_INT ; intr++ ) {
139 vec = &intr_vec[intr];
140 vec->push = PUSH_INSN;
141 vec->movb = MOVB_INSN;
142 vec->intr = intr;
143 vec->jmp = JMP_INSN;
144 vec->offset = ( ( intptr_t ) interrupt_wrapper -
145 ( intptr_t ) vec->next );
146 set_interrupt_vector ( intr, vec );
147 }
148 DBGC ( &intr_vec[0], "INTn vector at %p+%zxn (phys %#lx+%zxn)\n",
149 intr_vec, sizeof ( intr_vec[0] ),
150 virt_to_phys ( intr_vec ), sizeof ( intr_vec[0] ) );
151
152 /* Initialise the 32-bit interrupt descriptor table register */
153 idtr32.base = virt_to_phys ( idt32 );
154
155 /* Initialise the 64-bit interrupt descriptor table register,
156 * if applicable.
157 */
158 if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
159 idtr64.base = virt_to_phys ( idt64 );
160}
161
162/**
163 * Determine interrupt profiler (for debugging)
164 *
165 * @v intr Interrupt number
166 * @ret profiler Profiler
167 */
168static struct profiler * interrupt_profiler ( int intr ) {
169
170 switch ( intr ) {
171 case IRQ_INT ( 0 ) :
172 return &timer_irq_profiler;
173 default:
174 return &other_irq_profiler;
175 }
176}
177
178/**
179 * Display interrupt stack dump (for debugging)
180 *
181 * @v intr Interrupt number
182 * @v frame32 32-bit interrupt wrapper stack frame (or NULL)
183 * @v frame64 64-bit interrupt wrapper stack frame (or NULL)
184 */
185static __attribute__ (( unused )) void
186interrupt_dump ( int intr, struct interrupt_frame32 *frame32,
187 struct interrupt_frame64 *frame64 ) {
188 unsigned long sp;
189 void *stack;
190
191 /* Do nothing unless debugging is enabled */
192 if ( ! DBG_LOG )
193 return;
194
195 /* Print register dump */
196 if ( ( sizeof ( physaddr_t ) <= sizeof ( uint32_t ) ) || frame32 ) {
197 sp = ( frame32->esp + sizeof ( *frame32 ) -
198 offsetof ( typeof ( *frame32 ), esp ) );
199 DBGC ( &intr, "INT%d at %04x:%08x (stack %04x:%08lx):\n",
200 intr, frame32->cs, frame32->eip, frame32->ss, sp );
201 DBGC ( &intr, "cs = %04x ds = %04x es = %04x fs = %04x "
202 "gs = %04x ss = %04x\n", frame32->cs, frame32->ds,
203 frame32->es, frame32->fs, frame32->gs, frame32->ss );
204 DBGC ( &intr, "eax = %08x ebx = %08x ecx = %08x "
205 "edx = %08x flg = %08x\n", frame32->eax, frame32->ebx,
206 frame32->ecx, frame32->edx, frame32->eflags );
207 DBGC ( &intr, "esi = %08x edi = %08x ebp = %08x "
208 "esp = %08lx eip = %08x\n", frame32->esi, frame32->edi,
209 frame32->ebp, sp, frame32->eip );
210 stack = ( ( ( void * ) frame32 ) + sizeof ( *frame32 ) );
211 } else {
212 DBGC ( &intr, "INT%d at %04llx:%016llx (stack "
213 "%04llx:%016llx):\n", intr,
214 ( ( unsigned long long ) frame64->cs ),
215 ( ( unsigned long long ) frame64->rip ),
216 ( ( unsigned long long ) frame64->ss ),
217 ( ( unsigned long long ) frame64->rsp ) );
218 DBGC ( &intr, "rax = %016llx rbx = %016llx rcx = %016llx\n",
219 ( ( unsigned long long ) frame64->rax ),
220 ( ( unsigned long long ) frame64->rbx ),
221 ( ( unsigned long long ) frame64->rcx ) );
222 DBGC ( &intr, "rdx = %016llx rsi = %016llx rdi = %016llx\n",
223 ( ( unsigned long long ) frame64->rdx ),
224 ( ( unsigned long long ) frame64->rsi ),
225 ( ( unsigned long long ) frame64->rdi ) );
226 DBGC ( &intr, "rbp = %016llx rsp = %016llx flg = %016llx\n",
227 ( ( unsigned long long ) frame64->rbp ),
228 ( ( unsigned long long ) frame64->rsp ),
229 ( ( unsigned long long ) frame64->rflags ) );
230 DBGC ( &intr, "r8 = %016llx r9 = %016llx r10 = %016llx\n",
231 ( ( unsigned long long ) frame64->r8 ),
232 ( ( unsigned long long ) frame64->r9 ),
233 ( ( unsigned long long ) frame64->r10 ) );
234 DBGC ( &intr, "r11 = %016llx r12 = %016llx r13 = %016llx\n",
235 ( ( unsigned long long ) frame64->r11 ),
236 ( ( unsigned long long ) frame64->r12 ),
237 ( ( unsigned long long ) frame64->r13 ) );
238 DBGC ( &intr, "r14 = %016llx r15 = %016llx\n",
239 ( ( unsigned long long ) frame64->r14 ),
240 ( ( unsigned long long ) frame64->r15 ) );
241 sp = frame64->rsp;
242 stack = phys_to_virt ( sp );
243 }
244
245 /* Print stack dump */
246 DBGC_HDA ( &intr, sp, stack, STACK_DUMP_LEN );
247}
248
249/**
250 * Interrupt handler
251 *
252 * @v intr Interrupt number
253 * @v frame32 32-bit interrupt wrapper stack frame (or NULL)
254 * @v frame64 64-bit interrupt wrapper stack frame (or NULL)
255 * @v frame Interrupt wrapper stack frame
256 */
257__intrcall void interrupt ( int intr, struct interrupt_frame32 *frame32,
258 struct interrupt_frame64 *frame64 ) {
260 uint32_t discard_eax;
261
262 /* Trap CPU exceptions if debugging is enabled. Note that we
263 * cannot treat INT8+ as exceptions, since we are not
264 * permitted to rebase the PIC.
265 */
266 if ( DBG_LOG && ( intr < IRQ_INT ( 0 ) ) ) {
267 interrupt_dump ( intr, frame32, frame64 );
268 DBG ( "CPU exception: dropping to emergency shell\n" );
269 shell();
270 }
271
272 /* Reissue interrupt in real mode */
274 __asm__ __volatile__ ( REAL_CODE ( "movb %%al, %%cs:(1f + 1)\n\t"
275 "\n1:\n\t"
276 "int $0x00\n\t" )
277 : "=a" ( discard_eax ) : "0" ( intr ) );
280}
281
282/**
283 * Map pages for I/O
284 *
285 * @v bus_addr Bus address
286 * @v len Length of region
287 * @ret io_addr I/O address
288 */
289static void * ioremap_pages ( unsigned long bus_addr, size_t len ) {
290 unsigned long start;
291 unsigned int count;
292 unsigned int stride;
293 unsigned int first;
294 unsigned int i;
295 size_t offset;
296 void *io_addr;
297
298 DBGC ( &io_pages, "IO mapping %08lx+%zx\n", bus_addr, len );
299
300 /* Sanity check */
301 if ( ! len )
302 return NULL;
303
304 /* Round down start address to a page boundary */
305 start = ( bus_addr & ~( IO_PAGE_SIZE - 1 ) );
306 offset = ( bus_addr - start );
308
309 /* Calculate number of pages required */
310 count = ( ( offset + len + IO_PAGE_SIZE - 1 ) / IO_PAGE_SIZE );
311 assert ( count != 0 );
313
314 /* Round up number of pages to a power of two */
315 stride = ( 1 << fls ( count - 1 ) );
316 assert ( count <= stride );
317
318 /* Allocate pages */
319 for ( first = 0 ; first < IO_PAGE_COUNT ; first += stride ) {
320
321 /* Calculate I/O address */
322 io_addr = ( IO_BASE + ( first * IO_PAGE_SIZE ) + offset );
323
324 /* Check that page table entries are available */
325 for ( i = first ; i < ( first + count ) ; i++ ) {
326 if ( io_pages.page[i] & PAGE_P ) {
327 io_addr = NULL;
328 break;
329 }
330 }
331 if ( ! io_addr )
332 continue;
333
334 /* Create page table entries */
335 for ( i = first ; i < ( first + count ) ; i++ ) {
336 io_pages.page[i] = ( start | PAGE_P | PAGE_RW |
338 PAGE_PS );
340 }
341
342 /* Mark last page as being the last in this allocation */
343 io_pages.page[ i - 1 ] |= PAGE_LAST;
344
345 /* Return I/O address */
346 DBGC ( &io_pages, "IO mapped %08lx+%zx to %p using PTEs "
347 "[%d-%d]\n", bus_addr, len, io_addr, first,
348 ( first + count - 1 ) );
349 return io_addr;
350 }
351
352 DBGC ( &io_pages, "IO could not map %08lx+%zx\n", bus_addr, len );
353 return NULL;
354}
355
356/**
357 * Unmap pages for I/O
358 *
359 * @v io_addr I/O address
360 */
361static void iounmap_pages ( volatile const void *io_addr ) {
362 volatile const void *invalidate = io_addr;
363 unsigned int first;
364 unsigned int i;
365 int is_last;
366
367 DBGC ( &io_pages, "IO unmapping %p\n", io_addr );
368
369 /* Calculate first page table entry */
370 first = ( ( io_addr - IO_BASE ) / IO_PAGE_SIZE );
371
372 /* Ignore unmappings outside of the I/O range */
373 if ( first >= IO_PAGE_COUNT )
374 return;
375
376 /* Clear page table entries */
377 for ( i = first ; ; i++ ) {
378
379 /* Sanity check */
380 assert ( io_pages.page[i] & PAGE_P );
381
382 /* Check if this is the last page in this allocation */
383 is_last = ( io_pages.page[i] & PAGE_LAST );
384
385 /* Clear page table entry */
386 io_pages.page[i] = 0;
387
388 /* Invalidate TLB for this page */
389 __asm__ __volatile__ ( "invlpg (%0)" : : "r" ( invalidate ) );
390 invalidate += IO_PAGE_SIZE;
391
392 /* Terminate if this was the last page */
393 if ( is_last )
394 break;
395 }
396
397 DBGC ( &io_pages, "IO unmapped %p using PTEs [%d-%d]\n",
398 io_addr, first, i );
399}
400
401/**
402 * Check for FXSAVE/FXRSTOR instruction support
403 *
404 */
406 struct x86_features features;
407
408 /* Check for FXSR bit */
410 if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_FXSR ) )
411 regs->flags |= CF;
412 DBGC ( &features, "FXSAVE/FXRSTOR is%s supported\n",
413 ( ( regs->flags & CF ) ? " not" : "" ) );
414}
415
416/**
417 * Set up startup IPI handler
418 *
419 * @v vector Startup IPI vector
420 * @v handler Protected-mode startup IPI handler physical address
421 * @v regs Initial register state
422 */
423void setup_sipi ( unsigned int vector, uint32_t handler,
424 struct i386_regs *regs ) {
425
426 /* Record protected-mode handler */
427 sipi_handler = handler;
428
429 /* Update copy of rm_ds */
430 sipi_ds = rm_ds;
431
432 /* Save register state */
433 memcpy ( &sipi_regs, regs, sizeof ( sipi_regs ) );
434
435 /* Copy real-mode handler */
436 copy_to_real ( ( vector << 8 ), 0, sipi, sipi_len );
437}
438
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
#define __asmcall
Declare a function with standard calling conventions.
Definition compiler.h:15
__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 short uint16_t
Definition stdint.h:11
unsigned long intptr_t
Definition stdint.h:21
unsigned int uint32_t
Definition stdint.h:12
unsigned long physaddr_t
Definition stdint.h:20
unsigned long long uint64_t
Definition stdint.h:13
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint16_t offset
Offset to command line.
Definition bzimage.h:3
void x86_features(struct x86_features *features)
Get x86 CPU features.
Definition cpuid.c:164
x86 CPU feature detection
#define CPUID_FEATURES_INTEL_EDX_FXSR
FXSAVE and FXRSTOR are supported.
Definition cpuid.h:56
ring len
Length.
Definition dwmac.h:226
uint32_t addr
Buffer address.
Definition dwmac.h:9
uint32_t features
Supported features.
Definition ena.h:5
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint32_t vector
MSI-X vector.
Definition ena.h:9
struct ena_llq_option stride
Descriptor strides.
Definition ena.h:11
uint8_t intr
Interrupts enabled.
Definition ena.h:3
#define DBGC(...)
Definition compiler.h:530
#define DBG_LOG
Definition compiler.h:342
#define DBG(...)
Print a debugging message.
Definition compiler.h:523
#define DBGC_HDA(...)
Definition compiler.h:531
uint32_t start
Starting offset.
Definition netvsc.h:1
uint16_t size
Buffer size.
Definition dwmac.h:3
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define __attribute__(x)
Definition compiler.h:10
#define PROVIDE_IOMAP(_subsys, _api_func, _func)
Provide an I/O mapping API implementation.
Definition iomap.h:36
unsigned long io_to_bus(volatile const void *io_addr)
Convert I/O address to bus address (for debug only).
void * ioremap(unsigned long bus_addr, size_t len)
Map bus address as an I/O address.
#define PROVIDE_IOMAP_INLINE(_subsys, _api_func)
Provide a static inline I/O mapping API implementation.
Definition iomap.h:45
void iounmap(volatile const void *io_addr)
Unmap I/O address.
Profiling.
#define __profiler
Declare a profiler.
Definition profile.h:61
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition profile.h:174
static void profile_start(struct profiler *profiler)
Start profiling.
Definition profile.h:161
static void profile_exclude(struct profiler *profiler)
Exclude time from other ongoing profiling results.
Definition profile.h:187
void * memcpy(void *dest, const void *src, size_t len) __nonnull
String functions.
#define fls(x)
Find last (i.e.
Definition strings.h:167
#define rm_ds
Definition libkir.h:39
#define REAL_CODE(asm_code_str)
Definition libkir.h:226
#define copy_to_real
Definition libkir.h:78
#define MOVB_INSN
"movb" instruction
Definition librm.h:267
uint16_t rm_ss
#define NUM_INT
Number of interrupts.
Definition librm.h:181
#define IO_BASE
I/O page base address.
Definition librm.h:365
uint32_t sipi_handler
Startup IPI protected-mode handler (physical address).
#define IDTE_PRESENT
Interrupt descriptor is present.
Definition librm.h:232
#define IDTE_TYPE_IRQ32
Interrupt descriptor 32-bit interrupt gate type.
Definition librm.h:235
#define sipi_ds
Definition librm.h:377
uint32_t esp
Definition librm.h:0
#define IO_PAGE_COUNT
Maximum number of I/O pages.
Definition librm.h:350
#define IO_PAGE_SIZE
I/O page size.
Definition librm.h:358
#define IDTE_TYPE_IRQ64
Interrupt descriptor 64-bit interrupt gate type.
Definition librm.h:238
@ PAGE_RW
Page is writable.
Definition librm.h:329
@ PAGE_PWT
Page-level write-through.
Definition librm.h:333
@ PAGE_US
Page is accessible by user code.
Definition librm.h:331
@ PAGE_LAST
Page is the last page in an allocation.
Definition librm.h:343
@ PAGE_P
Page is present.
Definition librm.h:327
@ PAGE_PCD
Page-level cache disable.
Definition librm.h:335
@ PAGE_PS
Page is a large page.
Definition librm.h:337
#define sipi_len
Definition librm.h:373
struct page_table io_pages
The I/O space page table.
uint16_t rm_sp
#define VIRTUAL_CS
Definition librm.h:10
#define LONG_CS
Definition librm.h:17
#define PUSH_INSN
"push %eax" instruction
Definition librm.h:264
#define sipi
Definition librm.h:369
#define JMP_INSN
"jmp" instruction
Definition librm.h:270
uint8_t unused
Unused.
Definition librm.h:5
uint16_t copy_to_rm_stack(const void *data, size_t size)
Allocate space on the real-mode stack and copy data there.
Definition librm_mgmt.c:74
char interrupt_wrapper[]
The interrupt wrapper.
void set_interrupt_vector(unsigned int intr, void *vector)
Set interrupt vector.
Definition librm_mgmt.c:105
static void iounmap_pages(volatile const void *io_addr)
Unmap pages for I/O.
Definition librm_mgmt.c:361
__asmcall void check_fxsr(struct i386_all_regs *regs)
Check for FXSAVE/FXRSTOR instruction support.
Definition librm_mgmt.c:405
void remove_from_rm_stack(void *data, size_t size)
Deallocate space on the real-mode stack, optionally copying back data.
Definition librm_mgmt.c:89
static struct interrupt_vector intr_vec[NUM_INT]
The interrupt vectors.
Definition librm_mgmt.c:35
static void * ioremap_pages(unsigned long bus_addr, size_t len)
Map pages for I/O.
Definition librm_mgmt.c:289
static struct profiler * interrupt_profiler(int intr)
Determine interrupt profiler (for debugging).
Definition librm_mgmt.c:168
__intrcall void interrupt(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Interrupt handler.
Definition librm_mgmt.c:257
#define __intrcall
Definition librm_mgmt.c:28
static struct interrupt64_descriptor idt64[NUM_INT]
The 64-bit interrupt descriptor table.
Definition librm_mgmt.c:47
static void interrupt_dump(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Display interrupt stack dump (for debugging).
Definition librm_mgmt.c:186
struct i386_regs sipi_regs
Startup IPI register state.
Definition librm_mgmt.c:56
__asmcall void init_idt(void)
Initialise interrupt descriptor table.
Definition librm_mgmt.c:133
#define STACK_DUMP_LEN
Length of stack dump.
Definition librm_mgmt.c:59
void setup_sipi(unsigned int vector, uint32_t handler, struct i386_regs *regs)
Set up startup IPI handler.
Definition librm_mgmt.c:423
static struct interrupt32_descriptor idt32[NUM_INT]
The 32-bit interrupt descriptor table.
Definition librm_mgmt.c:38
uint32_t first
First block in range.
Definition pccrr.h:1
static __always_inline void unsigned long bus_addr
Definition pcibios.h:156
#define IRQ_INT(irq)
Definition pic8259.h:57
__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")
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
Definition realmode.h:77
uint16_t sp
Definition registers.h:13
struct i386_regs regs
Definition registers.h:1
#define CF
Definition registers.h:181
int shell(void)
Start command shell.
Definition shell.c:82
Minimal command shell.
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
A full register dump.
Definition registers.h:174
A 32-bit general register dump.
Definition registers.h:62
A 32-bit interrupt descriptor table register.
Definition librm.h:184
uint32_t base
Base.
Definition librm.h:188
A 64-bit interrupt descriptor table register.
Definition librm.h:192
uint64_t base
Base.
Definition librm.h:196
A 32-bit interrupt descriptor table entry.
Definition librm.h:200
uint16_t low
Low 16 bits of address.
Definition librm.h:202
uint16_t segment
Code segment.
Definition librm.h:204
uint8_t attr
Type and attributes.
Definition librm.h:208
uint16_t high
High 16 bits of address.
Definition librm.h:210
A 64-bit interrupt descriptor table entry.
Definition librm.h:214
uint8_t attr
Type and attributes.
Definition librm.h:222
uint16_t segment
Code segment.
Definition librm.h:218
uint32_t high
High 32 bits of address.
Definition librm.h:226
uint16_t mid
Middle 16 bits of address.
Definition librm.h:224
uint16_t low
Low 16 bits of address.
Definition librm.h:216
32-bit interrupt wrapper stack frame
Definition librm.h:273
uint32_t edi
Definition librm.h:281
uint32_t esi
Definition librm.h:282
uint32_t cs
Definition librm.h:288
uint32_t ss
Definition librm.h:275
uint32_t ecx
Definition librm.h:284
uint32_t fs
Definition librm.h:277
uint32_t gs
Definition librm.h:276
uint32_t edx
Definition librm.h:283
uint32_t ebx
Definition librm.h:285
uint32_t esp
Definition librm.h:274
uint32_t eflags
Definition librm.h:289
uint32_t eax
Definition librm.h:286
uint32_t es
Definition librm.h:278
uint32_t ds
Definition librm.h:279
uint32_t ebp
Definition librm.h:280
uint32_t eip
Definition librm.h:287
64-bit interrupt wrapper stack frame
Definition librm.h:293
uint64_t rdi
Definition librm.h:303
uint64_t r14
Definition librm.h:295
uint64_t r12
Definition librm.h:297
uint64_t rsi
Definition librm.h:304
uint64_t r11
Definition librm.h:298
uint64_t rip
Definition librm.h:309
uint64_t rdx
Definition librm.h:305
uint64_t rbp
Definition librm.h:302
uint64_t r9
Definition librm.h:300
uint64_t rsp
Definition librm.h:312
uint64_t cs
Definition librm.h:310
uint64_t rflags
Definition librm.h:311
uint64_t ss
Definition librm.h:313
uint64_t rbx
Definition librm.h:307
uint64_t r13
Definition librm.h:296
uint64_t r8
Definition librm.h:301
uint64_t r15
Definition librm.h:294
uint64_t rcx
Definition librm.h:306
uint64_t r10
Definition librm.h:299
uint64_t rax
Definition librm.h:308
An interrupt vector.
Definition librm.h:248
uint8_t push
"push" instruction
Definition librm.h:250
uint32_t offset
Interrupt wrapper address offset.
Definition librm.h:258
uint8_t jmp
"jmp" instruction
Definition librm.h:256
uint8_t movb
"movb" instruction
Definition librm.h:252
uint8_t intr
Interrupt number.
Definition librm.h:254
uint8_t next[0]
Next instruction after jump.
Definition librm.h:260
A data structure for storing profiling information.
Definition profile.h:27
x86 CPU features
Definition cpuid.h:24