iPXE
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.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
uint16_t copy_to_rm_stack (const void *data, size_t size)
 Allocate space on the real-mode stack and copy data there.
void remove_from_rm_stack (void *data, size_t size)
 Deallocate space on the real-mode stack, optionally copying back data.
void set_interrupt_vector (unsigned int intr, void *vector)
 Set interrupt vector.
__asmcall void init_idt (void)
 Initialise interrupt descriptor table.
static struct profilerinterrupt_profiler (int intr)
 Determine interrupt profiler (for debugging)
static void interrupt_dump (int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
 Display interrupt stack dump (for debugging)
void interrupt (int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
 Interrupt handler.
static void * ioremap_pages (unsigned long bus_addr, size_t len)
 Map pages for I/O.
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 setup_sipi (unsigned int vector, uint32_t handler, struct i386_regs *regs)
 Set up startup IPI handler.
 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.
static struct interrupt_vector intr_vec [NUM_INT]
 The interrupt vectors.
static struct interrupt32_descriptor idt32 [NUM_INT]
 The 32-bit interrupt descriptor table.
struct idtr32 idtr32
 The 32-bit interrupt descriptor table register.
static struct interrupt64_descriptor idt64 [NUM_INT]
 The 64-bit interrupt descriptor table.
struct idtr64 idtr64
 The interrupt descriptor table register.
struct i386_regs sipi_regs
 Startup IPI register state.
static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" }
 Timer interrupt profiler.

Macro Definition Documentation

◆ STACK_DUMP_LEN

#define STACK_DUMP_LEN   128

Length of stack dump.

Definition at line 52 of file librm_mgmt.c.

Referenced by interrupt_dump().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

References interrupt_wrapper.

◆ copy_to_rm_stack()

uint16_t copy_to_rm_stack ( const void * data,
size_t size )

Allocate space on the real-mode stack and copy data there.

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

Definition at line 67 of file librm_mgmt.c.

67 {
68 void *rm_stack;
69
70 rm_sp -= size;
71 rm_stack = real_to_virt ( rm_ss, rm_sp );
72 memcpy ( rm_stack, data, size );
73 return rm_sp;
74}
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint16_t size
Buffer size.
Definition dwmac.h:3
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint16_t rm_ss
uint16_t rm_sp
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
Definition realmode.h:77

References data, memcpy(), real_to_virt(), rm_sp, rm_ss, and size.

Referenced by com32_cfarcall().

◆ remove_from_rm_stack()

void remove_from_rm_stack ( void * data,
size_t size )

Deallocate space on the real-mode stack, optionally copying back data.

Parameters
dataStack data buffer, or NULL
sizeSize of stack data

Definition at line 82 of file librm_mgmt.c.

82 {
83 const void *rm_stack;
84
85 if ( data ) {
86 rm_stack = real_to_virt ( rm_ss, rm_sp );
87 memcpy ( data, rm_stack, size );
88 }
89 rm_sp += size;
90}

References data, memcpy(), real_to_virt(), 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 98 of file librm_mgmt.c.

98 {
99 struct interrupt32_descriptor *idte32;
100 struct interrupt64_descriptor *idte64;
101 intptr_t addr = ( ( intptr_t ) vector );
102
103 /* Populate 32-bit interrupt descriptor */
104 idte32 = &idt32[intr];
105 idte32->segment = VIRTUAL_CS;
106 idte32->attr = ( vector ? ( IDTE_PRESENT | IDTE_TYPE_IRQ32 ) : 0 );
107 idte32->low = ( addr >> 0 );
108 idte32->high = ( addr >> 16 );
109
110 /* Populate 64-bit interrupt descriptor, if applicable */
111 if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {
112 idte64 = &idt64[intr];
113 idte64->segment = LONG_CS;
114 idte64->attr = ( vector ?
115 ( IDTE_PRESENT | IDTE_TYPE_IRQ64 ) : 0 );
116 idte64->low = ( addr >> 0 );
117 idte64->mid = ( addr >> 16 );
118 idte64->high = ( ( ( uint64_t ) addr ) >> 32 );
119 }
120}
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
uint32_t addr
Buffer address.
Definition dwmac.h:9
uint32_t vector
MSI-X vector.
Definition ena.h:9
uint8_t intr
Interrupts enabled.
Definition ena.h:3
#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 IDTE_TYPE_IRQ64
Interrupt descriptor 64-bit interrupt gate type.
Definition librm.h:238
#define VIRTUAL_CS
Definition librm.h:10
#define LONG_CS
Definition librm.h:17
static struct interrupt64_descriptor idt64[NUM_INT]
The 64-bit interrupt descriptor table.
Definition librm_mgmt.c:40
static struct interrupt32_descriptor idt32[NUM_INT]
The 32-bit interrupt descriptor table.
Definition librm_mgmt.c:31
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

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 126 of file librm_mgmt.c.

126 {
127 struct interrupt_vector *vec;
128 unsigned int intr;
129
130 /* Initialise the interrupt descriptor table and interrupt vectors */
131 for ( intr = 0 ; intr < NUM_INT ; intr++ ) {
132 vec = &intr_vec[intr];
133 vec->push = PUSH_INSN;
134 vec->movb = MOVB_INSN;
135 vec->intr = intr;
136 vec->jmp = JMP_INSN;
137 vec->offset = ( ( intptr_t ) interrupt_wrapper -
138 ( intptr_t ) vec->next );
139 set_interrupt_vector ( intr, vec );
140 }
141 DBGC ( &intr_vec[0], "INTn vector at %p+%zxn (phys %#lx+%zxn)\n",
142 intr_vec, sizeof ( intr_vec[0] ),
143 virt_to_phys ( intr_vec ), sizeof ( intr_vec[0] ) );
144
145 /* Initialise the 32-bit interrupt descriptor table register */
146 idtr32.base = virt_to_phys ( idt32 );
147
148 /* Initialise the 64-bit interrupt descriptor table register,
149 * if applicable.
150 */
151 if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
152 idtr64.base = virt_to_phys ( idt64 );
153}
#define DBGC(...)
Definition compiler.h:505
#define MOVB_INSN
"movb" instruction
Definition librm.h:267
#define NUM_INT
Number of interrupts.
Definition librm.h:181
#define PUSH_INSN
"push %eax" instruction
Definition librm.h:264
#define JMP_INSN
"jmp" instruction
Definition librm.h:270
char interrupt_wrapper[]
The interrupt wrapper.
void set_interrupt_vector(unsigned int intr, void *vector)
Set interrupt vector.
Definition librm_mgmt.c:98
static struct interrupt_vector intr_vec[NUM_INT]
The interrupt vectors.
Definition librm_mgmt.c:28
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
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

References __asmcall, idtr32::base, idtr64::base, DBGC, idt32, idt64, interrupt_wrapper, interrupt_vector::intr, 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, and set_interrupt_vector().

◆ interrupt_profiler()

struct profiler * interrupt_profiler ( int intr)
static

Determine interrupt profiler (for debugging)

Parameters
intrInterrupt number
Return values
profilerProfiler

Definition at line 161 of file librm_mgmt.c.

161 {
162
163 switch ( intr ) {
164 case IRQ_INT ( 0 ) :
165 return &timer_irq_profiler;
166 default:
167 return &other_irq_profiler;
168 }
169}
return
Definition natsemi.h:326
#define IRQ_INT(irq)
Definition pic8259.h:57

References intr, and IRQ_INT.

Referenced by interrupt().

◆ interrupt_dump()

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 179 of file librm_mgmt.c.

180 {
181 unsigned long sp;
182 void *stack;
183
184 /* Do nothing unless debugging is enabled */
185 if ( ! DBG_LOG )
186 return;
187
188 /* Print register dump */
189 if ( ( sizeof ( physaddr_t ) <= sizeof ( uint32_t ) ) || frame32 ) {
190 sp = ( frame32->esp + sizeof ( *frame32 ) -
191 offsetof ( typeof ( *frame32 ), esp ) );
192 DBGC ( &intr, "INT%d at %04x:%08x (stack %04x:%08lx):\n",
193 intr, frame32->cs, frame32->eip, frame32->ss, sp );
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,
199 frame32->ecx, frame32->edx, frame32->eflags );
200 DBGC ( &intr, "esi = %08x edi = %08x ebp = %08x "
201 "esp = %08lx eip = %08x\n", frame32->esi, frame32->edi,
202 frame32->ebp, sp, frame32->eip );
203 stack = ( ( ( void * ) frame32 ) + sizeof ( *frame32 ) );
204 } else {
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 ) );
234 sp = frame64->rsp;
235 stack = phys_to_virt ( sp );
236 }
237
238 /* Print stack dump */
239 DBGC_HDA ( &intr, sp, stack, STACK_DUMP_LEN );
240}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
#define DBG_LOG
Definition compiler.h:317
#define DBGC_HDA(...)
Definition compiler.h:506
uint32_t esp
Definition librm.h:0
#define STACK_DUMP_LEN
Length of stack dump.
Definition librm_mgmt.c:52
uint16_t sp
Definition registers.h:13
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
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
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

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, 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 251 of file librm_mgmt.c.

252 {
254 uint32_t discard_eax;
255
256 /* Trap CPU exceptions if debugging is enabled. Note that we
257 * cannot treat INT8+ as exceptions, since we are not
258 * permitted to rebase the PIC.
259 */
260 if ( DBG_LOG && ( intr < IRQ_INT ( 0 ) ) ) {
261 interrupt_dump ( intr, frame32, frame64 );
262 DBG ( "CPU exception: dropping to emergency shell\n" );
263 shell();
264 }
265
266 /* Reissue interrupt in real mode */
268 __asm__ __volatile__ ( REAL_CODE ( "movb %%al, %%cs:(1f + 1)\n\t"
269 "\n1:\n\t"
270 "int $0x00\n\t" )
271 : "=a" ( discard_eax ) : "0" ( intr ) );
274}
__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))
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
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
#define REAL_CODE(asm_code_str)
Definition libkir.h:226
static struct profiler * interrupt_profiler(int intr)
Determine interrupt profiler (for debugging)
Definition librm_mgmt.c:161
static void interrupt_dump(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Display interrupt stack dump (for debugging)
Definition librm_mgmt.c:179
__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")
int shell(void)
Start command shell.
Definition shell.c:82
A data structure for storing profiling information.
Definition profile.h:27

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

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

◆ ioremap_pages()

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 283 of file librm_mgmt.c.

283 {
284 unsigned long start;
285 unsigned int count;
286 unsigned int stride;
287 unsigned int first;
288 unsigned int i;
289 size_t offset;
290 void *io_addr;
291
292 DBGC ( &io_pages, "IO mapping %08lx+%zx\n", bus_addr, len );
293
294 /* Sanity check */
295 if ( ! len )
296 return NULL;
297
298 /* Round down start address to a page boundary */
299 start = ( bus_addr & ~( IO_PAGE_SIZE - 1 ) );
300 offset = ( bus_addr - start );
302
303 /* Calculate number of pages required */
304 count = ( ( offset + len + IO_PAGE_SIZE - 1 ) / IO_PAGE_SIZE );
305 assert ( count != 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 < IO_PAGE_COUNT ; first += stride ) {
314
315 /* Calculate I/O address */
316 io_addr = ( IO_BASE + ( first * IO_PAGE_SIZE ) + offset );
317
318 /* Check that page table entries are available */
319 for ( i = first ; i < ( first + count ) ; i++ ) {
320 if ( io_pages.page[i] & PAGE_P ) {
321 io_addr = NULL;
322 break;
323 }
324 }
325 if ( ! io_addr )
326 continue;
327
328 /* Create page table entries */
329 for ( i = first ; i < ( first + count ) ; i++ ) {
330 io_pages.page[i] = ( start | PAGE_P | PAGE_RW |
332 PAGE_PS );
334 }
335
336 /* Mark last page as being the last in this allocation */
337 io_pages.page[ i - 1 ] |= PAGE_LAST;
338
339 /* Return I/O address */
340 DBGC ( &io_pages, "IO mapped %08lx+%zx to %p using PTEs "
341 "[%d-%d]\n", bus_addr, len, io_addr, first,
342 ( first + count - 1 ) );
343 return io_addr;
344 }
345
346 DBGC ( &io_pages, "IO could not map %08lx+%zx\n", bus_addr, len );
347 return NULL;
348}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint16_t offset
Offset to command line.
Definition bzimage.h:3
ring len
Length.
Definition dwmac.h:226
struct ena_llq_option stride
Descriptor strides.
Definition ena.h:11
uint32_t start
Starting offset.
Definition netvsc.h:1
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define fls(x)
Find last (i.e.
Definition strings.h:167
#define IO_BASE
I/O page base address.
Definition librm.h:365
#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
@ 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
struct page_table io_pages
The I/O space page table.
uint32_t first
First block in range.
Definition pccrr.h:1
static __always_inline void unsigned long bus_addr
Definition pcibios.h:156

References assert, bus_addr, count, DBGC, first, fls, IO_BASE, IO_PAGE_COUNT, IO_PAGE_SIZE, io_pages, len, NULL, offset, PAGE_LAST, PAGE_P, PAGE_PCD, PAGE_PS, PAGE_PWT, PAGE_RW, PAGE_US, start, and stride.

Referenced by PROVIDE_IOMAP().

◆ iounmap_pages()

void iounmap_pages ( volatile const void * io_addr)
static

Unmap pages for I/O.

Parameters
io_addrI/O address

Definition at line 355 of file librm_mgmt.c.

355 {
356 volatile const void *invalidate = io_addr;
357 unsigned int first;
358 unsigned int i;
359 int is_last;
360
361 DBGC ( &io_pages, "IO unmapping %p\n", io_addr );
362
363 /* Calculate first page table entry */
364 first = ( ( io_addr - IO_BASE ) / IO_PAGE_SIZE );
365
366 /* Ignore unmappings outside of the I/O range */
367 if ( first >= IO_PAGE_COUNT )
368 return;
369
370 /* Clear page table entries */
371 for ( i = first ; ; i++ ) {
372
373 /* Sanity check */
374 assert ( io_pages.page[i] & PAGE_P );
375
376 /* Check if this is the last page in this allocation */
377 is_last = ( io_pages.page[i] & PAGE_LAST );
378
379 /* Clear page table entry */
380 io_pages.page[i] = 0;
381
382 /* Invalidate TLB for this page */
383 __asm__ __volatile__ ( "invlpg (%0)" : : "r" ( invalidate ) );
384 invalidate += IO_PAGE_SIZE;
385
386 /* Terminate if this was the last page */
387 if ( is_last )
388 break;
389 }
390
391 DBGC ( &io_pages, "IO unmapped %p using PTEs [%d-%d]\n",
392 io_addr, first, i );
393}

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

Referenced by PROVIDE_IOMAP().

◆ check_fxsr()

__asmcall void check_fxsr ( struct i386_all_regs * regs)

Check for FXSAVE/FXRSTOR instruction support.

Definition at line 399 of file librm_mgmt.c.

399 {
400 struct x86_features features;
401
402 /* Check for FXSR bit */
404 if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_FXSR ) )
405 regs->flags |= CF;
406 DBGC ( &features, "FXSAVE/FXRSTOR is%s supported\n",
407 ( ( regs->flags & CF ) ? " not" : "" ) );
408}
void x86_features(struct x86_features *features)
Get x86 CPU features.
Definition cpuid.c:164
#define CPUID_FEATURES_INTEL_EDX_FXSR
FXSAVE and FXRSTOR are supported.
Definition cpuid.h:56
uint32_t features
Supported features.
Definition ena.h:5
struct i386_regs regs
Definition registers.h:1
#define CF
Definition registers.h:181
x86 CPU features
Definition cpuid.h:24

References __asmcall, 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 417 of file librm_mgmt.c.

418 {
419
420 /* Record protected-mode handler */
421 sipi_handler = handler;
422
423 /* Update copy of rm_ds */
424 sipi_ds = rm_ds;
425
426 /* Save register state */
427 memcpy ( &sipi_regs, regs, sizeof ( sipi_regs ) );
428
429 /* Copy real-mode handler */
430 copy_to_real ( ( vector << 8 ), 0, sipi, sipi_len );
431}
#define rm_ds
Definition libkir.h:39
#define copy_to_real
Definition libkir.h:78
uint32_t sipi_handler
Startup IPI protected-mode handler (physical address)
#define sipi_ds
Definition librm.h:377
#define sipi_len
Definition librm.h:373
#define sipi
Definition librm.h:369
struct i386_regs sipi_regs
Startup IPI register state.
Definition librm_mgmt.c:49

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_IOMAP_INLINE()

PROVIDE_IOMAP_INLINE ( pages ,
io_to_bus  )

References io_to_bus().

◆ PROVIDE_IOMAP() [1/2]

PROVIDE_IOMAP ( pages ,
ioremap ,
ioremap_pages  )

References ioremap(), and ioremap_pages().

◆ PROVIDE_IOMAP() [2/2]

PROVIDE_IOMAP ( pages ,
iounmap ,
iounmap_pages  )

References iounmap(), and iounmap_pages().

Variable Documentation

◆ interrupt_wrapper

char interrupt_wrapper[]
extern

The interrupt wrapper.

Referenced by FILE_LICENCE(), and 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 32 of file librm_mgmt.c.

Referenced by init_idt(), and set_interrupt_vector().

◆ idtr32

struct idtr32 idtr32
Initial value:
= {
.limit = ( sizeof ( idt32 ) - 1 ),
}

The 32-bit interrupt descriptor table register.

Definition at line 35 of file librm_mgmt.c.

35 {
36 .limit = ( sizeof ( idt32 ) - 1 ),
37};

◆ idt64

struct interrupt64_descriptor idt64[NUM_INT]
static

The 64-bit interrupt descriptor table.

Definition at line 41 of file librm_mgmt.c.

Referenced by init_idt(), and set_interrupt_vector().

◆ idtr64

struct idtr64 idtr64
Initial value:
= {
.limit = ( sizeof ( idt64 ) - 1 ),
}

The interrupt descriptor table register.

Definition at line 44 of file librm_mgmt.c.

44 {
45 .limit = ( sizeof ( idt64 ) - 1 ),
46};

◆ 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.

55{ .name = "irq.timer" };