36 .limit = (
sizeof (
idt32 ) - 1 ),
45 .limit = (
sizeof (
idt64 ) - 1 ),
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 NULL
NULL pointer (VOID *)
typeof(acpi_finder=acpi_find)
ACPI table finder.
#define __asmcall
Declare a function with standard calling conventions.
__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 long long uint64_t
#define assert(condition)
Assert a condition at run-time.
uint16_t offset
Offset to command line.
void x86_features(struct x86_features *features)
Get x86 CPU features.
x86 CPU feature detection
#define CPUID_FEATURES_INTEL_EDX_FXSR
FXSAVE and FXRSTOR are supported.
uint32_t addr
Buffer address.
uint32_t features
Supported features.
uint8_t data[48]
Additional event data.
uint32_t vector
MSI-X vector.
struct ena_llq_option stride
Descriptor strides.
uint8_t intr
Interrupts enabled.
#define DBG(...)
Print a debugging message.
uint32_t start
Starting offset.
uint16_t size
Buffer size.
static unsigned int count
Number of entries.
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
#define PROVIDE_IOMAP(_subsys, _api_func, _func)
Provide an I/O mapping API implementation.
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.
void iounmap(volatile const void *io_addr)
Unmap I/O address.
#define __profiler
Declare a profiler.
static void profile_stop(struct profiler *profiler)
Stop profiling.
static void profile_start(struct profiler *profiler)
Start profiling.
static void profile_exclude(struct profiler *profiler)
Exclude time from other ongoing profiling results.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define fls(x)
Find last (i.e.
#define REAL_CODE(asm_code_str)
#define MOVB_INSN
"movb" instruction
#define NUM_INT
Number of interrupts.
#define IO_BASE
I/O page base address.
uint32_t sipi_handler
Startup IPI protected-mode handler (physical address)
#define IDTE_PRESENT
Interrupt descriptor is present.
#define IDTE_TYPE_IRQ32
Interrupt descriptor 32-bit interrupt gate type.
#define IO_PAGE_COUNT
Maximum number of I/O pages.
#define IO_PAGE_SIZE
I/O page size.
#define IDTE_TYPE_IRQ64
Interrupt descriptor 64-bit interrupt gate type.
@ PAGE_RW
Page is writable.
@ PAGE_PWT
Page-level write-through.
@ PAGE_US
Page is accessible by user code.
@ PAGE_LAST
Page is the last page in an allocation.
@ PAGE_PCD
Page-level cache disable.
@ PAGE_PS
Page is a large page.
struct page_table io_pages
The I/O space page table.
#define PUSH_INSN
"push %eax" instruction
#define JMP_INSN
"jmp" instruction
uint16_t copy_to_rm_stack(const void *data, size_t size)
Allocate space on the real-mode stack and copy data there.
char interrupt_wrapper[]
The interrupt wrapper.
void set_interrupt_vector(unsigned int intr, void *vector)
Set interrupt vector.
static void iounmap_pages(volatile const void *io_addr)
Unmap pages for I/O.
__asmcall void check_fxsr(struct i386_all_regs *regs)
Check for FXSAVE/FXRSTOR instruction support.
void remove_from_rm_stack(void *data, size_t size)
Deallocate space on the real-mode stack, optionally copying back data.
static struct interrupt_vector intr_vec[NUM_INT]
The interrupt vectors.
static void * ioremap_pages(unsigned long bus_addr, size_t len)
Map pages for I/O.
static struct profiler * interrupt_profiler(int intr)
Determine interrupt profiler (for debugging)
static struct interrupt64_descriptor idt64[NUM_INT]
The 64-bit interrupt descriptor table.
void interrupt(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Interrupt handler.
static void interrupt_dump(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Display interrupt stack dump (for debugging)
struct i386_regs sipi_regs
Startup IPI register state.
__asmcall void init_idt(void)
Initialise interrupt descriptor table.
#define STACK_DUMP_LEN
Length of stack dump.
void setup_sipi(unsigned int vector, uint32_t handler, struct i386_regs *regs)
Set up startup IPI handler.
static struct interrupt32_descriptor idt32[NUM_INT]
The 32-bit interrupt descriptor table.
uint32_t first
First block in range.
static __always_inline void unsigned long bus_addr
__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.
int shell(void)
Start command shell.
#define offsetof(type, field)
Get offset of a field within a structure.
A 32-bit general register dump.
A 32-bit interrupt descriptor table register.
A 64-bit interrupt descriptor table register.
A 32-bit interrupt descriptor table entry.
uint16_t low
Low 16 bits of address.
uint16_t segment
Code segment.
uint8_t attr
Type and attributes.
uint16_t high
High 16 bits of address.
A 64-bit interrupt descriptor table entry.
uint8_t attr
Type and attributes.
uint16_t segment
Code segment.
uint32_t high
High 32 bits of address.
uint16_t mid
Middle 16 bits of address.
uint16_t low
Low 16 bits of address.
32-bit interrupt wrapper stack frame
64-bit interrupt wrapper stack frame
uint8_t push
"push" instruction
uint32_t offset
Interrupt wrapper address offset.
uint8_t jmp
"jmp" instruction
uint8_t movb
"movb" instruction
uint8_t intr
Interrupt number.
uint8_t next[0]
Next instruction after jump.
A data structure for storing profiling information.