iPXE
Macros | Functions
com32_call.c File Reference
#include <stdint.h>
#include <realmode.h>
#include <comboot.h>
#include <assert.h>
#include <ipxe/uaccess.h>

Go to the source code of this file.

Macros

#define com32_regs   __use_data16 ( com32_regs )
 
#define com32_int_vector   __use_data16 ( com32_int_vector )
 
#define com32_farcall_proc   __use_data16 ( com32_farcall_proc )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
static com32sys_t __bss16 (com32_regs)
 
static uint8_t __bss16 (com32_int_vector)
 
static uint32_t __bss16 (com32_farcall_proc)
 
uint16_t __bss16 (com32_saved_sp)
 
void __asmcall com32_intcall (uint8_t interrupt, physaddr_t inregs_phys, physaddr_t outregs_phys)
 Interrupt call helper. More...
 
void __asmcall com32_farcall (uint32_t proc, physaddr_t inregs_phys, physaddr_t outregs_phys)
 Farcall helper. More...
 
int __asmcall com32_cfarcall (uint32_t proc, physaddr_t stack, size_t stacksz)
 CDECL farcall helper. More...
 

Macro Definition Documentation

◆ com32_regs

#define com32_regs   __use_data16 ( com32_regs )

Definition at line 34 of file com32_call.c.

◆ com32_int_vector

#define com32_int_vector   __use_data16 ( com32_int_vector )

Definition at line 37 of file com32_call.c.

◆ com32_farcall_proc

#define com32_farcall_proc   __use_data16 ( com32_farcall_proc )

Definition at line 40 of file com32_call.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ __bss16() [1/4]

static com32sys_t __bss16 ( com32_regs  )
static

◆ __bss16() [2/4]

static uint8_t __bss16 ( com32_int_vector  )
static

◆ __bss16() [3/4]

static uint32_t __bss16 ( com32_farcall_proc  )
static

◆ __bss16() [4/4]

uint16_t __bss16 ( com32_saved_sp  )

◆ com32_intcall()

void __asmcall com32_intcall ( uint8_t  interrupt,
physaddr_t  inregs_phys,
physaddr_t  outregs_phys 
)

Interrupt call helper.

Definition at line 47 of file com32_call.c.

47  {
48 
49  DBGC ( &com32_regs, "COM32 INT%x in %#08lx out %#08lx\n",
50  interrupt, inregs_phys, outregs_phys );
51 
53  phys_to_user ( inregs_phys ), 0,
54  sizeof(com32sys_t) );
55 
57 
59  REAL_CODE ( /* Save all registers */
60  "pushal\n\t"
61  "pushw %%ds\n\t"
62  "pushw %%es\n\t"
63  "pushw %%fs\n\t"
64  "pushw %%gs\n\t"
65  /* Mask off unsafe flags */
66  "movl (com32_regs + 40), %%eax\n\t"
67  "andl $0x200cd7, %%eax\n\t"
68  "movl %%eax, (com32_regs + 40)\n\t"
69  /* Load com32_regs into the actual registers */
70  "movw %%sp, %%ss:(com32_saved_sp)\n\t"
71  "movw $com32_regs, %%sp\n\t"
72  "popw %%gs\n\t"
73  "popw %%fs\n\t"
74  "popw %%es\n\t"
75  "popw %%ds\n\t"
76  "popal\n\t"
77  "popfl\n\t"
78  "movw %%ss:(com32_saved_sp), %%sp\n\t"
79  /* patch INT instruction */
80  "pushw %%ax\n\t"
81  "movb %%ss:(com32_int_vector), %%al\n\t"
82  "movb %%al, %%cs:(com32_intcall_instr + 1)\n\t"
83  /* perform a jump to avoid problems with cache
84  * consistency in self-modifying code on some CPUs (486)
85  */
86  "jmp 1f\n"
87  "1:\n\t"
88  "popw %%ax\n\t"
89  "com32_intcall_instr:\n\t"
90  /* INT instruction to be patched */
91  "int $0xFF\n\t"
92  /* Copy regs back to com32_regs */
93  "movw %%sp, %%ss:(com32_saved_sp)\n\t"
94  "movw $(com32_regs + 44), %%sp\n\t"
95  "pushfl\n\t"
96  "pushal\n\t"
97  "pushw %%ds\n\t"
98  "pushw %%es\n\t"
99  "pushw %%fs\n\t"
100  "pushw %%gs\n\t"
101  "movw %%ss:(com32_saved_sp), %%sp\n\t"
102  /* Restore registers */
103  "popw %%gs\n\t"
104  "popw %%fs\n\t"
105  "popw %%es\n\t"
106  "popw %%ds\n\t"
107  "popal\n\t")
108  : : );
109 
110  if ( outregs_phys ) {
111  memcpy_user ( phys_to_user ( outregs_phys ), 0,
112  virt_to_user( &com32_regs ), 0,
113  sizeof(com32sys_t) );
114  }
115 }
#define com32_regs
Definition: com32_call.c:34
#define DBGC(...)
Definition: compiler.h:505
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
__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")
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226
#define com32_int_vector
Definition: com32_call.c:37
void interrupt(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Interrupt handler.
Definition: librm_mgmt.c:250
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.

References __asm__(), __volatile__(), com32_int_vector, com32_regs, DBGC, interrupt(), memcpy_user(), phys_to_user(), REAL_CODE, and virt_to_user().

◆ com32_farcall()

void __asmcall com32_farcall ( uint32_t  proc,
physaddr_t  inregs_phys,
physaddr_t  outregs_phys 
)

Farcall helper.

Definition at line 120 of file com32_call.c.

120  {
121 
122  DBGC ( &com32_regs, "COM32 farcall %04x:%04x in %#08lx out %#08lx\n",
123  ( proc >> 16 ), ( proc & 0xffff ), inregs_phys, outregs_phys );
124 
126  phys_to_user ( inregs_phys ), 0,
127  sizeof(com32sys_t) );
128 
129  com32_farcall_proc = proc;
130 
132  REAL_CODE ( /* Save all registers */
133  "pushal\n\t"
134  "pushw %%ds\n\t"
135  "pushw %%es\n\t"
136  "pushw %%fs\n\t"
137  "pushw %%gs\n\t"
138  /* Mask off unsafe flags */
139  "movl (com32_regs + 40), %%eax\n\t"
140  "andl $0x200cd7, %%eax\n\t"
141  "movl %%eax, (com32_regs + 40)\n\t"
142  /* Load com32_regs into the actual registers */
143  "movw %%sp, %%ss:(com32_saved_sp)\n\t"
144  "movw $com32_regs, %%sp\n\t"
145  "popw %%gs\n\t"
146  "popw %%fs\n\t"
147  "popw %%es\n\t"
148  "popw %%ds\n\t"
149  "popal\n\t"
150  "popfl\n\t"
151  "movw %%ss:(com32_saved_sp), %%sp\n\t"
152  /* Call procedure */
153  "lcall *%%ss:(com32_farcall_proc)\n\t"
154  /* Copy regs back to com32_regs */
155  "movw %%sp, %%ss:(com32_saved_sp)\n\t"
156  "movw $(com32_regs + 44), %%sp\n\t"
157  "pushfl\n\t"
158  "pushal\n\t"
159  "pushw %%ds\n\t"
160  "pushw %%es\n\t"
161  "pushw %%fs\n\t"
162  "pushw %%gs\n\t"
163  "movw %%ss:(com32_saved_sp), %%sp\n\t"
164  /* Restore registers */
165  "popw %%gs\n\t"
166  "popw %%fs\n\t"
167  "popw %%es\n\t"
168  "popw %%ds\n\t"
169  "popal\n\t")
170  : : );
171 
172  if ( outregs_phys ) {
173  memcpy_user ( phys_to_user ( outregs_phys ), 0,
174  virt_to_user( &com32_regs ), 0,
175  sizeof(com32sys_t) );
176  }
177 }
#define com32_regs
Definition: com32_call.c:34
#define DBGC(...)
Definition: compiler.h:505
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
#define com32_farcall_proc
Definition: com32_call.c:40
__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")
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226
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.

References __asm__(), __volatile__(), com32_farcall_proc, com32_regs, DBGC, memcpy_user(), phys_to_user(), REAL_CODE, and virt_to_user().

◆ com32_cfarcall()

int __asmcall com32_cfarcall ( uint32_t  proc,
physaddr_t  stack,
size_t  stacksz 
)

CDECL farcall helper.

Definition at line 182 of file com32_call.c.

182  {
183  int32_t eax;
184 
185  DBGC ( &com32_regs, "COM32 cfarcall %04x:%04x params %#08lx+%#zx\n",
186  ( proc >> 16 ), ( proc & 0xffff ), stack, stacksz );
187 
188  copy_user_to_rm_stack ( phys_to_user ( stack ), stacksz );
189  com32_farcall_proc = proc;
190 
192  REAL_CODE ( "lcall *%%ss:(com32_farcall_proc)\n\t" )
193  : "=a" (eax)
194  :
195  : "ecx", "edx" );
196 
197  remove_user_from_rm_stack ( 0, stacksz );
198 
199  return eax;
200 }
#define com32_regs
Definition: com32_call.c:34
#define DBGC(...)
Definition: compiler.h:505
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
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.
Definition: librm_mgmt.c:68
#define com32_farcall_proc
Definition: com32_call.c:40
uint32_t eax
Definition: string.h:234
__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")
signed int int32_t
Definition: stdint.h:17
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.
Definition: librm_mgmt.c:83
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

References __asm__(), __volatile__(), com32_farcall_proc, com32_regs, copy_user_to_rm_stack(), DBGC, eax, phys_to_user(), REAL_CODE, and remove_user_from_rm_stack().