52 #define STACK_DUMP_LEN 128 141 DBGC ( &
intr_vec[0],
"INTn vector at %p+%zxn (phys %#lx+%zxn)\n",
165 return &timer_irq_profiler;
167 return &other_irq_profiler;
190 sp = ( frame32->
esp +
sizeof ( *frame32 ) -
192 DBGC ( &
intr,
"INT%d at %04x:%08x (stack %04x:%08lx):\n",
194 DBGC ( &
intr,
"cs = %04x ds = %04x es = %04x fs = %04x " 195 "gs = %04x ss = %04x\n", frame32->
cs, frame32->
ds,
196 frame32->
es, frame32->
fs, frame32->
gs, frame32->
ss );
197 DBGC ( &
intr,
"eax = %08x ebx = %08x ecx = %08x " 198 "edx = %08x flg = %08x\n", frame32->
eax, frame32->
ebx,
200 DBGC ( &
intr,
"esi = %08x edi = %08x ebp = %08x " 201 "esp = %08lx eip = %08x\n", frame32->
esi, frame32->
edi,
203 stack = ( ( (
void * ) frame32 ) +
sizeof ( *frame32 ) );
205 DBGC ( &
intr,
"INT%d at %04llx:%016llx (stack " 206 "%04llx:%016llx):\n",
intr,
207 ( (
unsigned long long ) frame64->
cs ),
208 ( (
unsigned long long ) frame64->
rip ),
209 ( (
unsigned long long ) frame64->
ss ),
210 ( (
unsigned long long ) frame64->
rsp ) );
211 DBGC ( &
intr,
"rax = %016llx rbx = %016llx rcx = %016llx\n",
212 ( (
unsigned long long ) frame64->
rax ),
213 ( (
unsigned long long ) frame64->
rbx ),
214 ( (
unsigned long long ) frame64->
rcx ) );
215 DBGC ( &
intr,
"rdx = %016llx rsi = %016llx rdi = %016llx\n",
216 ( (
unsigned long long ) frame64->
rdx ),
217 ( (
unsigned long long ) frame64->
rsi ),
218 ( (
unsigned long long ) frame64->
rdi ) );
219 DBGC ( &
intr,
"rbp = %016llx rsp = %016llx flg = %016llx\n",
220 ( (
unsigned long long ) frame64->
rbp ),
221 ( (
unsigned long long ) frame64->
rsp ),
222 ( (
unsigned long long ) frame64->
rflags ) );
223 DBGC ( &
intr,
"r8 = %016llx r9 = %016llx r10 = %016llx\n",
224 ( (
unsigned long long ) frame64->
r8 ),
225 ( (
unsigned long long ) frame64->
r9 ),
226 ( (
unsigned long long ) frame64->
r10 ) );
227 DBGC ( &
intr,
"r11 = %016llx r12 = %016llx r13 = %016llx\n",
228 ( (
unsigned long long ) frame64->
r11 ),
229 ( (
unsigned long long ) frame64->
r12 ),
230 ( (
unsigned long long ) frame64->
r13 ) );
231 DBGC ( &
intr,
"r14 = %016llx r15 = %016llx\n",
232 ( (
unsigned long long ) frame64->
r14 ),
233 ( (
unsigned long long ) frame64->
r15 ) );
235 stack = phys_to_virt (
sp );
262 DBG (
"CPU exception: dropping to emergency shell\n" );
271 :
"=a" ( discard_eax ) :
"0" (
intr ) );
340 DBGC ( &
io_pages,
"IO mapped %08lx+%zx to %p using PTEs " 356 volatile const void *invalidate = io_addr;
371 for ( i =
first ; ; i++ ) {
391 DBGC ( &
io_pages,
"IO unmapped %p using PTEs [%d-%d]\n",
407 ( (
regs->flags &
CF ) ?
" not" :
"" ) );
#define IO_PAGE_SIZE
I/O page size.
uint16_t mid
Middle 16 bits of address.
uint8_t next[0]
Next instruction after jump.
uint32_t first
First block in range.
uint32_t vector
MSI-X vector.
uint8_t intr
Interrupt number.
#define IDTE_TYPE_IRQ32
Interrupt descriptor 32-bit interrupt gate type.
uint32_t sipi_handler
Startup IPI protected-mode handler (physical address)
struct i386_regs sipi_regs
Startup IPI register state.
uint16_t high
High 16 bits of address.
Page-level write-through.
uint16_t size
Buffer size.
PROVIDE_IOMAP(pages, ioremap, ioremap_pages)
uint8_t attr
Type and attributes.
unsigned long long uint64_t
void x86_features(struct x86_features *features)
Get x86 CPU features.
int shell(void)
Start command shell.
#define offsetof(type, field)
Get offset of a field within a structure.
A data structure for storing profiling information.
unsigned long io_to_bus(volatile const void *io_addr)
Convert I/O address to bus address (for debug only)
static void iounmap_pages(volatile const void *io_addr)
Unmap pages for I/O.
static void interrupt_dump(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Display interrupt stack dump (for debugging)
static void profile_stop(struct profiler *profiler)
Stop profiling.
uint32_t high
High 32 bits of address.
Page-level cache disable.
static __always_inline void unsigned long bus_addr
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
uint32_t start
Starting offset.
#define IDTE_TYPE_IRQ64
Interrupt descriptor 64-bit interrupt gate type.
A 32-bit interrupt descriptor table entry.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define __asmcall
Declare a function with standard calling conventions.
void remove_from_rm_stack(void *data, size_t size)
Deallocate space on the real-mode stack, optionally copying back data.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint8_t intr
Interrupts enabled.
#define IO_BASE
I/O page base address.
uint16_t copy_to_rm_stack(const void *data, size_t size)
Allocate space on the real-mode stack and copy data there.
A 16-bit general register.
static unsigned int count
Number of entries.
uint8_t movb
"movb" instruction
Page is the last page in an allocation.
static struct interrupt_vector intr_vec[NUM_INT]
The interrupt vectors.
static void profile_start(struct profiler *profiler)
Start profiling.
__asmcall void init_idt(void)
Initialise interrupt descriptor table.
#define IO_PAGE_COUNT
Maximum number of I/O pages.
#define CPUID_FEATURES_INTEL_EDX_FXSR
FXSAVE and FXRSTOR are supported.
#define PUSH_INSN
"push %eax" instruction
uint16_t low
Low 16 bits of address.
struct ena_llq_option stride
Descriptor strides.
x86 CPU feature detection
uint32_t features
Supported features.
uint32_t addr
Buffer address.
__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))
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
A 32-bit interrupt descriptor table register.
uint8_t push
"push" instruction
uint16_t low
Low 16 bits of address.
static struct profiler timer_irq_profiler __profiler
Timer interrupt profiler.
#define STACK_DUMP_LEN
Length of stack dump.
A 64-bit interrupt descriptor table entry.
void setup_sipi(unsigned int vector, uint32_t handler, struct i386_regs *regs)
Set up startup IPI handler.
#define MOVB_INSN
"movb" instruction
A 32-bit general register dump.
32-bit interrupt wrapper stack frame
__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 IDTE_PRESENT
Interrupt descriptor is present.
void set_interrupt_vector(unsigned int intr, void *vector)
Set interrupt vector.
uint16_t segment
Code segment.
struct page_table io_pages
The I/O space page table.
void iounmap(volatile const void *io_addr)
Unmap I/O address.
#define JMP_INSN
"jmp" instruction
uint8_t data[48]
Additional event data.
char interrupt_wrapper[]
The interrupt wrapper.
uint32_t offset
Interrupt wrapper address offset.
static void * ioremap_pages(unsigned long bus_addr, size_t len)
Map pages for I/O.
Page is accessible by user code.
static struct profiler * interrupt_profiler(int intr)
Determine interrupt profiler (for debugging)
typeof(acpi_finder=acpi_find)
ACPI table finder.
#define NUM_INT
Number of interrupts.
uint64_t page[512]
Page address and flags.
static void profile_exclude(struct profiler *profiler)
Exclude time from other ongoing profiling results.
uint16_t offset
Offset to command line.
#define DBG(...)
Print a debugging message.
uint8_t jmp
"jmp" instruction
void * ioremap(unsigned long bus_addr, size_t len)
Map bus address as an I/O address.
static struct interrupt64_descriptor idt64[NUM_INT]
The 64-bit interrupt descriptor table.
#define fls(x)
Find last (i.e.
__asmcall void check_fxsr(struct i386_all_regs *regs)
Check for FXSAVE/FXRSTOR instruction support.
#define REAL_CODE(asm_code_str)
#define NULL
NULL pointer (VOID *)
void interrupt(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Interrupt handler.
uint8_t attr
Type and attributes.
64-bit interrupt wrapper stack frame
A 64-bit interrupt descriptor table register.
PROVIDE_IOMAP_INLINE(pages, io_to_bus)
uint16_t segment
Code segment.
static struct interrupt32_descriptor idt32[NUM_INT]
The 32-bit interrupt descriptor table.