iPXE
Macros | Functions | Variables
librm_mgmt.c File Reference
#include <stdint.h>
#include <strings.h>
#include <assert.h>
#include <ipxe/profile.h>
#include <realmode.h>
#include <pic8259.h>
#include <ipxe/shell.h>
#include <ipxe/cpuid.h>

Go to the source code of this file.

Macros

#define STACK_DUMP_LEN   128
 Length of stack dump. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
uint16_t copy_user_to_rm_stack (userptr_t data, size_t size)
 Allocate space on the real-mode stack and copy data there from a user buffer. More...
 
void remove_user_from_rm_stack (userptr_t data, size_t size)
 Deallocate space on the real-mode stack, optionally copying back data to a user buffer. More...
 
void set_interrupt_vector (unsigned int intr, void *vector)
 Set interrupt vector. More...
 
__asmcall void init_idt (void)
 Initialise interrupt descriptor table. More...
 
static struct profilerinterrupt_profiler (int intr)
 Determine interrupt profiler (for debugging) More...
 
static void interrupt_dump (int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
 Display interrupt stack dump (for debugging) More...
 
void interrupt (int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
 Interrupt handler. More...
 
static void * ioremap_pages (unsigned long bus_addr, size_t len)
 Map pages for I/O. More...
 
static void iounmap_pages (volatile const void *io_addr)
 Unmap pages for I/O. More...
 
__asmcall void check_fxsr (struct i386_all_regs *regs)
 Check for FXSAVE/FXRSTOR instruction support. More...
 
void setup_sipi (unsigned int vector, uint32_t handler, struct i386_regs *regs)
 Set up startup IPI handler. More...
 
 PROVIDE_UACCESS_INLINE (librm, phys_to_user)
 
 PROVIDE_UACCESS_INLINE (librm, user_to_phys)
 
 PROVIDE_UACCESS_INLINE (librm, virt_to_user)
 
 PROVIDE_UACCESS_INLINE (librm, user_to_virt)
 
 PROVIDE_UACCESS_INLINE (librm, userptr_add)
 
 PROVIDE_UACCESS_INLINE (librm, memcpy_user)
 
 PROVIDE_UACCESS_INLINE (librm, memmove_user)
 
 PROVIDE_UACCESS_INLINE (librm, memset_user)
 
 PROVIDE_UACCESS_INLINE (librm, strlen_user)
 
 PROVIDE_UACCESS_INLINE (librm, memchr_user)
 
 PROVIDE_IOMAP_INLINE (pages, io_to_bus)
 
 PROVIDE_IOMAP (pages, ioremap, ioremap_pages)
 
 PROVIDE_IOMAP (pages, iounmap, iounmap_pages)
 

Variables

char interrupt_wrapper []
 The interrupt wrapper. More...
 
static struct interrupt_vector intr_vec [NUM_INT]
 The interrupt vectors. More...
 
static struct interrupt32_descriptor idt32 [NUM_INT]
 The 32-bit interrupt descriptor table. More...
 
struct idtr32 idtr32
 The 32-bit interrupt descriptor table register. More...
 
static struct interrupt64_descriptor idt64 [NUM_INT]
 The 64-bit interrupt descriptor table. More...
 
struct idtr64 idtr64
 The interrupt descriptor table register. More...
 
struct i386_regs sipi_regs
 Startup IPI register state. More...
 
static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" }
 Timer interrupt profiler. More...
 

Macro Definition Documentation

◆ STACK_DUMP_LEN

#define STACK_DUMP_LEN   128

Length of stack dump.

Definition at line 52 of file librm_mgmt.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ copy_user_to_rm_stack()

uint16_t copy_user_to_rm_stack ( userptr_t  data,
size_t  size 
)

Allocate space on the real-mode stack and copy data there from a user buffer.

Parameters
dataUser buffer
sizeSize of stack data
Return values
spNew value of real-mode stack pointer

Definition at line 68 of file librm_mgmt.c.

68  {
69  userptr_t rm_stack;
70  rm_sp -= size;
71  rm_stack = real_to_user ( rm_ss, rm_sp );
72  memcpy_user ( rm_stack, 0, data, 0, size );
73  return rm_sp;
74 };
uint16_t rm_ss
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint16_t rm_sp
static __always_inline userptr_t real_to_user(unsigned int segment, unsigned int offset)
Convert segment:offset address to user buffer.
Definition: realmode.h:75
void memcpy_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers.
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33

References data, memcpy_user(), real_to_user(), rm_sp, rm_ss, and size.

Referenced by com32_cfarcall().

◆ remove_user_from_rm_stack()

void remove_user_from_rm_stack ( userptr_t  data,
size_t  size 
)

Deallocate space on the real-mode stack, optionally copying back data to a user buffer.

Parameters
dataUser buffer
sizeSize of stack data

Definition at line 83 of file librm_mgmt.c.

83  {
84  if ( data ) {
85  userptr_t rm_stack = real_to_user ( rm_ss, rm_sp );
86  memcpy_user ( rm_stack, 0, data, 0, size );
87  }
88  rm_sp += size;
89 };
uint16_t rm_ss
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint16_t rm_sp
static __always_inline userptr_t real_to_user(unsigned int segment, unsigned int offset)
Convert segment:offset address to user buffer.
Definition: realmode.h:75
void memcpy_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers.
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33

References data, memcpy_user(), real_to_user(), rm_sp, rm_ss, and size.

Referenced by com32_cfarcall().

◆ set_interrupt_vector()

void set_interrupt_vector ( unsigned int  intr,
void *  vector 
)

Set interrupt vector.

Parameters
intrInterrupt number
vectorInterrupt vector, or NULL to disable

Definition at line 97 of file librm_mgmt.c.

97  {
98  struct interrupt32_descriptor *idte32;
99  struct interrupt64_descriptor *idte64;
100  intptr_t addr = ( ( intptr_t ) vector );
101 
102  /* Populate 32-bit interrupt descriptor */
103  idte32 = &idt32[intr];
104  idte32->segment = VIRTUAL_CS;
105  idte32->attr = ( vector ? ( IDTE_PRESENT | IDTE_TYPE_IRQ32 ) : 0 );
106  idte32->low = ( addr >> 0 );
107  idte32->high = ( addr >> 16 );
108 
109  /* Populate 64-bit interrupt descriptor, if applicable */
110  if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
111  idte64 = &idt64[intr];
112  idte64->segment = LONG_CS;
113  idte64->attr = ( vector ?
114  ( IDTE_PRESENT | IDTE_TYPE_IRQ64 ) : 0 );
115  idte64->low = ( addr >> 0 );
116  idte64->mid = ( addr >> 16 );
117  idte64->high = ( ( ( uint64_t ) addr ) >> 32 );
118  }
119 }
uint16_t mid
Middle 16 bits of address.
Definition: librm.h:338
uint32_t vector
MSI-X vector.
Definition: ena.h:20
#define IDTE_TYPE_IRQ32
Interrupt descriptor 32-bit interrupt gate type.
Definition: librm.h:349
uint16_t high
High 16 bits of address.
Definition: librm.h:324
#define LONG_CS
Definition: librm.h:17
uint8_t attr
Type and attributes.
Definition: librm.h:322
unsigned long long uint64_t
Definition: stdint.h:13
unsigned long intptr_t
Definition: stdint.h:21
uint32_t high
High 32 bits of address.
Definition: librm.h:340
#define IDTE_TYPE_IRQ64
Interrupt descriptor 64-bit interrupt gate type.
Definition: librm.h:352
A 32-bit interrupt descriptor table entry.
Definition: librm.h:314
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
uint16_t low
Low 16 bits of address.
Definition: librm.h:316
#define VIRTUAL_CS
Definition: librm.h:10
u32 addr
Definition: sky2.h:8
uint16_t low
Low 16 bits of address.
Definition: librm.h:330
unsigned int uint32_t
Definition: stdint.h:12
A 64-bit interrupt descriptor table entry.
Definition: librm.h:328
unsigned long physaddr_t
Definition: stdint.h:20
#define IDTE_PRESENT
Interrupt descriptor is present.
Definition: librm.h:346
uint16_t segment
Code segment.
Definition: librm.h:332
static struct interrupt64_descriptor idt64[NUM_INT]
The 64-bit interrupt descriptor table.
Definition: librm_mgmt.c:40
uint8_t attr
Type and attributes.
Definition: librm.h:336
uint16_t segment
Code segment.
Definition: librm.h:318
static struct interrupt32_descriptor idt32[NUM_INT]
The 32-bit interrupt descriptor table.
Definition: librm_mgmt.c:31

References addr, interrupt32_descriptor::attr, interrupt64_descriptor::attr, interrupt32_descriptor::high, interrupt64_descriptor::high, idt32, idt64, IDTE_PRESENT, IDTE_TYPE_IRQ32, IDTE_TYPE_IRQ64, intr, LONG_CS, interrupt32_descriptor::low, interrupt64_descriptor::low, interrupt64_descriptor::mid, interrupt32_descriptor::segment, interrupt64_descriptor::segment, vector, and VIRTUAL_CS.

Referenced by gdbmach_init(), and init_idt().

◆ init_idt()

__asmcall void init_idt ( void  )

Initialise interrupt descriptor table.

Definition at line 125 of file librm_mgmt.c.

125  {
126  struct interrupt_vector *vec;
127  unsigned int intr;
128 
129  /* Initialise the interrupt descriptor table and interrupt vectors */
130  for ( intr = 0 ; intr < NUM_INT ; intr++ ) {
131  vec = &intr_vec[intr];
132  vec->push = PUSH_INSN;
133  vec->movb = MOVB_INSN;
134  vec->intr = intr;
135  vec->jmp = JMP_INSN;
136  vec->offset = ( ( intptr_t ) interrupt_wrapper -
137  ( intptr_t ) vec->next );
138  set_interrupt_vector ( intr, vec );
139  }
140  DBGC ( &intr_vec[0], "INTn vector at %p+%zxn (phys %#lx+%zxn)\n",
141  intr_vec, sizeof ( intr_vec[0] ),
142  virt_to_phys ( intr_vec ), sizeof ( intr_vec[0] ) );
143 
144  /* Initialise the 32-bit interrupt descriptor table register */
146 
147  /* Initialise the 64-bit interrupt descriptor table register,
148  * if applicable.
149  */
150  if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
152 }
uint8_t next[0]
Next instruction after jump.
Definition: librm.h:374
uint8_t intr
Interrupt number.
Definition: librm.h:368
#define DBGC(...)
Definition: compiler.h:505
unsigned long intptr_t
Definition: stdint.h:21
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
uint8_t movb
"movb" instruction
Definition: librm.h:366
static struct interrupt_vector intr_vec[NUM_INT]
The interrupt vectors.
Definition: librm_mgmt.c:28
#define PUSH_INSN
"push %eax" instruction
Definition: librm.h:378
An interrupt vector.
Definition: librm.h:362
A 32-bit interrupt descriptor table register.
Definition: librm.h:298
uint8_t push
"push" instruction
Definition: librm.h:364
unsigned int uint32_t
Definition: stdint.h:12
#define MOVB_INSN
"movb" instruction
Definition: librm.h:381
unsigned long physaddr_t
Definition: stdint.h:20
uint64_t base
Base.
Definition: librm.h:310
void set_interrupt_vector(unsigned int intr, void *vector)
Set interrupt vector.
Definition: librm_mgmt.c:97
#define JMP_INSN
"jmp" instruction
Definition: librm.h:384
uint32_t base
Base.
Definition: librm.h:302
char interrupt_wrapper[]
The interrupt wrapper.
uint32_t offset
Interrupt wrapper address offset.
Definition: librm.h:372
#define NUM_INT
Number of interrupts.
Definition: librm.h:295
uint8_t jmp
"jmp" instruction
Definition: librm.h:370
static struct interrupt64_descriptor idt64[NUM_INT]
The 64-bit interrupt descriptor table.
Definition: librm_mgmt.c:40
A 64-bit interrupt descriptor table register.
Definition: librm.h:306
static struct interrupt32_descriptor idt32[NUM_INT]
The 32-bit interrupt descriptor table.
Definition: librm_mgmt.c:31

References idtr32::base, idtr64::base, DBGC, idt32, idt64, interrupt_wrapper, intr, interrupt_vector::intr, intr_vec, interrupt_vector::jmp, JMP_INSN, interrupt_vector::movb, MOVB_INSN, interrupt_vector::next, NUM_INT, interrupt_vector::offset, interrupt_vector::push, PUSH_INSN, set_interrupt_vector(), and virt_to_phys().

◆ interrupt_profiler()

static struct profiler* interrupt_profiler ( int  intr)
static

Determine interrupt profiler (for debugging)

Parameters
intrInterrupt number
Return values
profilerProfiler

Definition at line 160 of file librm_mgmt.c.

160  {
161 
162  switch ( intr ) {
163  case IRQ_INT ( 0 ) :
164  return &timer_irq_profiler;
165  default:
166  return &other_irq_profiler;
167  }
168 }
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
#define IRQ_INT(irq)
Definition: pic8259.h:60
return
Definition: natsemi.h:326

References intr, and IRQ_INT.

Referenced by interrupt().

◆ interrupt_dump()

static void interrupt_dump ( int  intr,
struct interrupt_frame32 frame32,
struct interrupt_frame64 frame64 
)
static

Display interrupt stack dump (for debugging)

Parameters
intrInterrupt number
frame3232-bit interrupt wrapper stack frame (or NULL)
frame6464-bit interrupt wrapper stack frame (or NULL)

Definition at line 178 of file librm_mgmt.c.

179  {
180  unsigned long sp;
181  void *stack;
182 
183  /* Do nothing unless debugging is enabled */
184  if ( ! DBG_LOG )
185  return;
186 
187  /* Print register dump */
188  if ( ( sizeof ( physaddr_t ) <= sizeof ( uint32_t ) ) || frame32 ) {
189  sp = ( frame32->esp + sizeof ( *frame32 ) -
190  offsetof ( typeof ( *frame32 ), esp ) );
191  DBGC ( &intr, "INT%d at %04x:%08x (stack %04x:%08lx):\n",
192  intr, frame32->cs, frame32->eip, frame32->ss, sp );
193  DBGC ( &intr, "cs = %04x ds = %04x es = %04x fs = %04x "
194  "gs = %04x ss = %04x\n", frame32->cs, frame32->ds,
195  frame32->es, frame32->fs, frame32->gs, frame32->ss );
196  DBGC ( &intr, "eax = %08x ebx = %08x ecx = %08x "
197  "edx = %08x flg = %08x\n", frame32->eax, frame32->ebx,
198  frame32->ecx, frame32->edx, frame32->eflags );
199  DBGC ( &intr, "esi = %08x edi = %08x ebp = %08x "
200  "esp = %08lx eip = %08x\n", frame32->esi, frame32->edi,
201  frame32->ebp, sp, frame32->eip );
202  stack = ( ( ( void * ) frame32 ) + sizeof ( *frame32 ) );
203  } else {
204  DBGC ( &intr, "INT%d at %04llx:%016llx (stack "
205  "%04llx:%016llx):\n", intr,
206  ( ( unsigned long long ) frame64->cs ),
207  ( ( unsigned long long ) frame64->rip ),
208  ( ( unsigned long long ) frame64->ss ),
209  ( ( unsigned long long ) frame64->rsp ) );
210  DBGC ( &intr, "rax = %016llx rbx = %016llx rcx = %016llx\n",
211  ( ( unsigned long long ) frame64->rax ),
212  ( ( unsigned long long ) frame64->rbx ),
213  ( ( unsigned long long ) frame64->rcx ) );
214  DBGC ( &intr, "rdx = %016llx rsi = %016llx rdi = %016llx\n",
215  ( ( unsigned long long ) frame64->rdx ),
216  ( ( unsigned long long ) frame64->rsi ),
217  ( ( unsigned long long ) frame64->rdi ) );
218  DBGC ( &intr, "rbp = %016llx rsp = %016llx flg = %016llx\n",
219  ( ( unsigned long long ) frame64->rbp ),
220  ( ( unsigned long long ) frame64->rsp ),
221  ( ( unsigned long long ) frame64->rflags ) );
222  DBGC ( &intr, "r8 = %016llx r9 = %016llx r10 = %016llx\n",
223  ( ( unsigned long long ) frame64->r8 ),
224  ( ( unsigned long long ) frame64->r9 ),
225  ( ( unsigned long long ) frame64->r10 ) );
226  DBGC ( &intr, "r11 = %016llx r12 = %016llx r13 = %016llx\n",
227  ( ( unsigned long long ) frame64->r11 ),
228  ( ( unsigned long long ) frame64->r12 ),
229  ( ( unsigned long long ) frame64->r13 ) );
230  DBGC ( &intr, "r14 = %016llx r15 = %016llx\n",
231  ( ( unsigned long long ) frame64->r14 ),
232  ( ( unsigned long long ) frame64->r15 ) );
233  sp = frame64->rsp;
234  stack = phys_to_virt ( sp );
235  }
236 
237  /* Print stack dump */
238  DBGC_HDA ( &intr, sp, stack, STACK_DUMP_LEN );
239 }
uint32_t cs
Definition: librm.h:402
uint64_t rsp
Definition: librm.h:426
uint32_t esp
Definition: librm.h:249
uint64_t r14
Definition: librm.h:409
uint64_t r12
Definition: librm.h:411
uint32_t es
Definition: librm.h:392
uint64_t rsi
Definition: librm.h:418
#define DBGC(...)
Definition: compiler.h:505
uint64_t r10
Definition: librm.h:413
uint32_t eax
Definition: librm.h:400
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
uint64_t r13
Definition: librm.h:410
uint64_t ss
Definition: librm.h:427
uint64_t rcx
Definition: librm.h:420
uint32_t ds
Definition: librm.h:393
static __always_inline void * phys_to_virt(unsigned long phys_addr)
Convert physical address to a virtual address.
Definition: uaccess.h:299
uint64_t r8
Definition: librm.h:415
uint32_t edx
Definition: librm.h:397
uint64_t rax
Definition: librm.h:422
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
#define DBGC_HDA(...)
Definition: compiler.h:506
uint32_t fs
Definition: librm.h:391
uint64_t r9
Definition: librm.h:414
uint32_t ecx
Definition: librm.h:398
uint32_t eip
Definition: librm.h:401
uint32_t edi
Definition: librm.h:395
uint32_t esp
Definition: librm.h:388
uint64_t rdx
Definition: librm.h:419
uint64_t r15
Definition: librm.h:408
uint32_t ebp
Definition: librm.h:394
uint32_t eflags
Definition: librm.h:403
unsigned int uint32_t
Definition: stdint.h:12
#define STACK_DUMP_LEN
Length of stack dump.
Definition: librm_mgmt.c:52
uint64_t rbp
Definition: librm.h:416
uint32_t ss
Definition: librm.h:389
unsigned long physaddr_t
Definition: stdint.h:20
uint64_t rflags
Definition: librm.h:425
uint32_t esi
Definition: librm.h:396
uint32_t gs
Definition: librm.h:390
uint32_t ebx
Definition: librm.h:399
uint64_t cs
Definition: librm.h:424
uint64_t rbx
Definition: librm.h:421
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
uint64_t rip
Definition: librm.h:423
#define DBG_LOG
Definition: compiler.h:317
uint64_t r11
Definition: librm.h:412
uint16_t sp
Definition: registers.h:27
uint64_t rdi
Definition: librm.h:417

References interrupt_frame32::cs, interrupt_frame64::cs, DBG_LOG, DBGC, DBGC_HDA, interrupt_frame32::ds, interrupt_frame32::eax, interrupt_frame32::ebp, interrupt_frame32::ebx, interrupt_frame32::ecx, interrupt_frame32::edi, interrupt_frame32::edx, interrupt_frame32::eflags, interrupt_frame32::eip, interrupt_frame32::es, interrupt_frame32::esi, esp, interrupt_frame32::esp, interrupt_frame32::fs, interrupt_frame32::gs, intr, offsetof, phys_to_virt(), interrupt_frame64::r10, interrupt_frame64::r11, interrupt_frame64::r12, interrupt_frame64::r13, interrupt_frame64::r14, interrupt_frame64::r15, interrupt_frame64::r8, interrupt_frame64::r9, interrupt_frame64::rax, interrupt_frame64::rbp, interrupt_frame64::rbx, interrupt_frame64::rcx, interrupt_frame64::rdi, interrupt_frame64::rdx, interrupt_frame64::rflags, interrupt_frame64::rip, interrupt_frame64::rsi, interrupt_frame64::rsp, sp, interrupt_frame32::ss, interrupt_frame64::ss, STACK_DUMP_LEN, and typeof().

Referenced by interrupt().

◆ interrupt()

void interrupt ( int  intr,
struct interrupt_frame32 frame32,
struct interrupt_frame64 frame64 
)

Interrupt handler.

Parameters
intrInterrupt number
frame3232-bit interrupt wrapper stack frame (or NULL)
frame6464-bit interrupt wrapper stack frame (or NULL)
frameInterrupt wrapper stack frame

Definition at line 250 of file librm_mgmt.c.

251  {
253  uint32_t discard_eax;
254 
255  /* Trap CPU exceptions if debugging is enabled. Note that we
256  * cannot treat INT8+ as exceptions, since we are not
257  * permitted to rebase the PIC.
258  */
259  if ( DBG_LOG && ( intr < IRQ_INT ( 0 ) ) ) {
260  interrupt_dump ( intr, frame32, frame64 );
261  DBG ( "CPU exception: dropping to emergency shell\n" );
262  shell();
263  }
264 
265  /* Reissue interrupt in real mode */
267  __asm__ __volatile__ ( REAL_CODE ( "movb %%al, %%cs:(1f + 1)\n\t"
268  "\n1:\n\t"
269  "int $0x00\n\t" )
270  : "=a" ( discard_eax ) : "0" ( intr ) );
273 }
int shell(void)
Start command shell.
Definition: shell.c:84
A data structure for storing profiling information.
Definition: profile.h:26
static void interrupt_dump(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Display interrupt stack dump (for debugging)
Definition: librm_mgmt.c:178
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:171
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:158
#define IRQ_INT(irq)
Definition: pic8259.h:60
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
unsigned int uint32_t
Definition: stdint.h:12
__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 struct profiler * interrupt_profiler(int intr)
Determine interrupt profiler (for debugging)
Definition: librm_mgmt.c:160
static void profile_exclude(struct profiler *profiler)
Exclude time from other ongoing profiling results.
Definition: profile.h:184
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define DBG_LOG
Definition: compiler.h:317
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

References __asm__(), __volatile__(), DBG, DBG_LOG, interrupt_dump(), interrupt_profiler(), intr, IRQ_INT, profile_exclude(), profile_start(), profile_stop(), REAL_CODE, and shell().

Referenced by com32_intcall(), hook_bios_interrupt(), and unhook_bios_interrupt().

◆ ioremap_pages()

static void* ioremap_pages ( unsigned long  bus_addr,
size_t  len 
)
static

Map pages for I/O.

Parameters
bus_addrBus address
lenLength of region
Return values
io_addrI/O address

Definition at line 282 of file librm_mgmt.c.

282  {
283  unsigned long start;
284  unsigned int count;
285  unsigned int stride;
286  unsigned int first;
287  unsigned int i;
288  size_t offset;
289  void *io_addr;
290 
291  DBGC ( &io_pages, "IO mapping %08lx+%zx\n", bus_addr, len );
292 
293  /* Sanity check */
294  if ( ! len )
295  return NULL;
296 
297  /* Round down start address to a page boundary */
298  start = ( bus_addr & ~( IO_PAGE_SIZE - 1 ) );
299  offset = ( bus_addr - start );
300  assert ( offset < IO_PAGE_SIZE );
301 
302  /* Calculate number of pages required */
303  count = ( ( offset + len + IO_PAGE_SIZE - 1 ) / IO_PAGE_SIZE );
304  assert ( count != 0 );
305  assert ( count < ( sizeof ( io_pages.page ) /
306  sizeof ( io_pages.page[0] ) ) );
307 
308  /* Round up number of pages to a power of two */
309  stride = ( 1 << ( fls ( count ) - 1 ) );
310  assert ( count <= stride );
311 
312  /* Allocate pages */
313  for ( first = 0 ; first < ( sizeof ( io_pages.page ) /
314  sizeof ( io_pages.page[0] ) ) ;
315  first += stride ) {
316 
317  /* Calculate I/O address */
318  io_addr = ( IO_BASE + ( first * IO_PAGE_SIZE ) + offset );
319 
320  /* Check that page table entries are available */
321  for ( i = first ; i < ( first + count ) ; i++ ) {
322  if ( io_pages.page[i] & PAGE_P ) {
323  io_addr = NULL;
324  break;
325  }
326  }
327  if ( ! io_addr )
328  continue;
329 
330  /* Create page table entries */
331  for ( i = first ; i < ( first + count ) ; i++ ) {
332  io_pages.page[i] = ( start | PAGE_P | PAGE_RW |
334  PAGE_PS );
335  start += IO_PAGE_SIZE;
336  }
337 
338  /* Mark last page as being the last in this allocation */
339  io_pages.page[ i - 1 ] |= PAGE_LAST;
340 
341  /* Return I/O address */
342  DBGC ( &io_pages, "IO mapped %08lx+%zx to %p using PTEs "
343  "[%d-%d]\n", bus_addr, len, io_addr, first,
344  ( first + count - 1 ) );
345  return io_addr;
346  }
347 
348  DBGC ( &io_pages, "IO could not map %08lx+%zx\n", bus_addr, len );
349  return NULL;
350 }
#define IO_PAGE_SIZE
I/O page size.
Definition: librm.h:468
Page-level write-through.
Definition: librm.h:447
#define DBGC(...)
Definition: compiler.h:505
Page-level cache disable.
Definition: librm.h:449
uint32_t start
Starting offset.
Definition: netvsc.h:12
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define IO_BASE
I/O page base address.
Definition: librm.h:475
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
Page is the last page in an allocation.
Definition: librm.h:457
Page is a large page.
Definition: librm.h:451
uint32_t len
Length.
Definition: ena.h:14
uint16_t count
Number of entries.
Definition: ena.h:22
Page is writable.
Definition: librm.h:443
struct page_table io_pages
The I/O space page table.
Page is accessible by user code.
Definition: librm.h:445
uint64_t page[512]
Page address and flags.
Definition: librm.h:435
#define fls(x)
Find last (i.e.
Definition: strings.h:166
static __always_inline void unsigned long bus_addr
Definition: ecam_io.h:135
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23
Page is present.
Definition: librm.h:441

References assert(), bus_addr, count, DBGC, first, fls, IO_BASE, IO_PAGE_SIZE, io_pages, len, NULL, offset, page_table::page, PAGE_LAST, PAGE_P, PAGE_PCD, PAGE_PS, PAGE_PWT, PAGE_RW, PAGE_US, and start.

◆ iounmap_pages()

static void iounmap_pages ( volatile const void *  io_addr)
static

Unmap pages for I/O.

Parameters
io_addrI/O address

Definition at line 357 of file librm_mgmt.c.

357  {
358  volatile const void *invalidate = io_addr;
359  unsigned int first;
360  unsigned int i;
361  int is_last;
362 
363  DBGC ( &io_pages, "IO unmapping %p\n", io_addr );
364 
365  /* Calculate first page table entry */
366  first = ( ( io_addr - IO_BASE ) / IO_PAGE_SIZE );
367 
368  /* Clear page table entries */
369  for ( i = first ; ; i++ ) {
370 
371  /* Sanity check */
372  assert ( io_pages.page[i] & PAGE_P );
373 
374  /* Check if this is the last page in this allocation */
375  is_last = ( io_pages.page[i] & PAGE_LAST );
376 
377  /* Clear page table entry */
378  io_pages.page[i] = 0;
379 
380  /* Invalidate TLB for this page */
381  __asm__ __volatile__ ( "invlpg (%0)" : : "r" ( invalidate ) );
382  invalidate += IO_PAGE_SIZE;
383 
384  /* Terminate if this was the last page */
385  if ( is_last )
386  break;
387  }
388 
389  DBGC ( &io_pages, "IO unmapped %p using PTEs [%d-%d]\n",
390  io_addr, first, i );
391 }
#define IO_PAGE_SIZE
I/O page size.
Definition: librm.h:468
#define DBGC(...)
Definition: compiler.h:505
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define IO_BASE
I/O page base address.
Definition: librm.h:475
Page is the last page in an allocation.
Definition: librm.h:457
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__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")
struct page_table io_pages
The I/O space page table.
uint64_t page[512]
Page address and flags.
Definition: librm.h:435
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23
Page is present.
Definition: librm.h:441

References __asm__(), __volatile__(), assert(), DBGC, first, IO_BASE, IO_PAGE_SIZE, io_pages, page_table::page, PAGE_LAST, and PAGE_P.

◆ check_fxsr()

__asmcall void check_fxsr ( struct i386_all_regs regs)

Check for FXSAVE/FXRSTOR instruction support.

Definition at line 397 of file librm_mgmt.c.

397  {
398  struct x86_features features;
399 
400  /* Check for FXSR bit */
401  x86_features ( &features );
402  if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_FXSR ) )
403  regs->flags |= CF;
404  DBGC ( &features, "FXSAVE/FXRSTOR is%s supported\n",
405  ( ( regs->flags & CF ) ? " not" : "" ) );
406 }
#define CF
Definition: registers.h:181
#define DBGC(...)
Definition: compiler.h:505
void x86_features(struct x86_features *features)
Get x86 CPU features.
Definition: cpuid.c:163
x86 CPU features
Definition: cpuid.h:23
#define CPUID_FEATURES_INTEL_EDX_FXSR
FXSAVE and FXRSTOR are supported.
Definition: cpuid.h:52
uint32_t features
Supported features.
Definition: ena.h:16
struct i386_regs regs
Definition: registers.h:15

References CF, CPUID_FEATURES_INTEL_EDX_FXSR, DBGC, features, regs, and x86_features().

◆ setup_sipi()

void setup_sipi ( unsigned int  vector,
uint32_t  handler,
struct i386_regs regs 
)

Set up startup IPI handler.

Parameters
vectorStartup IPI vector
handlerProtected-mode startup IPI handler physical address
regsInitial register state

Definition at line 415 of file librm_mgmt.c.

416  {
417 
418  /* Record protected-mode handler */
419  sipi_handler = handler;
420 
421  /* Update copy of rm_ds */
422  sipi_ds = rm_ds;
423 
424  /* Save register state */
425  memcpy ( &sipi_regs, regs, sizeof ( sipi_regs ) );
426 
427  /* Copy real-mode handler */
428  copy_to_real ( ( vector << 8 ), 0, sipi, ( ( size_t ) sipi_len ) );
429 }
uint32_t vector
MSI-X vector.
Definition: ena.h:20
uint32_t sipi_handler
Startup IPI protected-mode handler (physical address)
struct i386_regs sipi_regs
Startup IPI register state.
Definition: librm_mgmt.c:49
#define sipi_ds
Definition: librm.h:486
#define rm_ds
Definition: libkir.h:39
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define copy_to_real
Definition: libkir.h:78
char sipi_len[]
Length of startup IPI real-mode handler.
struct i386_regs regs
Definition: registers.h:15
#define sipi
Definition: librm.h:479

References copy_to_real, memcpy(), regs, rm_ds, sipi, sipi_ds, sipi_handler, sipi_len, sipi_regs, and vector.

Referenced by bios_mp_start_all().

◆ PROVIDE_UACCESS_INLINE() [1/10]

PROVIDE_UACCESS_INLINE ( librm  ,
phys_to_user   
)

◆ PROVIDE_UACCESS_INLINE() [2/10]

PROVIDE_UACCESS_INLINE ( librm  ,
user_to_phys   
)

◆ PROVIDE_UACCESS_INLINE() [3/10]

PROVIDE_UACCESS_INLINE ( librm  ,
virt_to_user   
)

◆ PROVIDE_UACCESS_INLINE() [4/10]

PROVIDE_UACCESS_INLINE ( librm  ,
user_to_virt   
)

◆ PROVIDE_UACCESS_INLINE() [5/10]

PROVIDE_UACCESS_INLINE ( librm  ,
userptr_add   
)

◆ PROVIDE_UACCESS_INLINE() [6/10]

PROVIDE_UACCESS_INLINE ( librm  ,
memcpy_user   
)

◆ PROVIDE_UACCESS_INLINE() [7/10]

PROVIDE_UACCESS_INLINE ( librm  ,
memmove_user   
)

◆ PROVIDE_UACCESS_INLINE() [8/10]

PROVIDE_UACCESS_INLINE ( librm  ,
memset_user   
)

◆ PROVIDE_UACCESS_INLINE() [9/10]

PROVIDE_UACCESS_INLINE ( librm  ,
strlen_user   
)

◆ PROVIDE_UACCESS_INLINE() [10/10]

PROVIDE_UACCESS_INLINE ( librm  ,
memchr_user   
)

◆ PROVIDE_IOMAP_INLINE()

PROVIDE_IOMAP_INLINE ( pages  ,
io_to_bus   
)

◆ PROVIDE_IOMAP() [1/2]

PROVIDE_IOMAP ( pages  ,
ioremap  ,
ioremap_pages   
)

◆ PROVIDE_IOMAP() [2/2]

PROVIDE_IOMAP ( pages  ,
iounmap  ,
iounmap_pages   
)

Variable Documentation

◆ interrupt_wrapper

char interrupt_wrapper[]

The interrupt wrapper.

Referenced by init_idt().

◆ intr_vec

struct interrupt_vector intr_vec[NUM_INT]
static

The interrupt vectors.

Definition at line 28 of file librm_mgmt.c.

Referenced by init_idt().

◆ idt32

struct interrupt32_descriptor idt32[NUM_INT]
static

The 32-bit interrupt descriptor table.

Definition at line 31 of file librm_mgmt.c.

Referenced by init_idt(), and set_interrupt_vector().

◆ idtr32

struct idtr32 idtr32
Initial value:
= {
.limit = ( sizeof ( idt32 ) - 1 ),
}
static struct interrupt32_descriptor idt32[NUM_INT]
The 32-bit interrupt descriptor table.
Definition: librm_mgmt.c:31

The 32-bit interrupt descriptor table register.

Definition at line 35 of file librm_mgmt.c.

◆ idt64

struct interrupt64_descriptor idt64[NUM_INT]
static

The 64-bit interrupt descriptor table.

Definition at line 40 of file librm_mgmt.c.

Referenced by init_idt(), and set_interrupt_vector().

◆ idtr64

struct idtr64 idtr64
Initial value:
= {
.limit = ( sizeof ( idt64 ) - 1 ),
}
static struct interrupt64_descriptor idt64[NUM_INT]
The 64-bit interrupt descriptor table.
Definition: librm_mgmt.c:40

The interrupt descriptor table register.

Definition at line 44 of file librm_mgmt.c.

◆ sipi_regs

struct i386_regs sipi_regs

Startup IPI register state.

Definition at line 49 of file librm_mgmt.c.

Referenced by setup_sipi().

◆ __profiler

struct profiler other_irq_profiler __profiler = { .name = "irq.timer" }
static

Timer interrupt profiler.

Other interrupt profiler.

Definition at line 55 of file librm_mgmt.c.