iPXE
Macros | Functions | Variables
pxe_call.h File Reference

PXE API entry point. More...

#include <pxe_api.h>
#include <realmode.h>
#include <rmsetjmp.h>

Go to the source code of this file.

Macros

#define PXE_LOAD_SEGMENT   0
 PXE load address segment. More...
 
#define PXE_LOAD_OFFSET   0x7c00
 PXE load address offset. More...
 
#define PXE_LOAD_PHYS   ( ( PXE_LOAD_SEGMENT << 4 ) + PXE_LOAD_OFFSET )
 PXE physical load address. More...
 
#define ppxe   __use_text16 ( ppxe )
 
#define pxenv   __use_text16 ( pxenv )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
struct s_PXE __text16 (ppxe)
 !PXE structure More...
 
struct s_PXENV __text16 (pxenv)
 PXENV+ structure. More...
 
void pxe_activate (struct net_device *netdev)
 Activate PXE stack. More...
 
int pxe_deactivate (void)
 Deactivate PXE stack. More...
 
int pxe_start_nbp (void)
 Start PXE NBP at 0000:7c00. More...
 
__asmcall void pxe_api_call (struct i386_all_regs *ix86)
 Dispatch PXE API call. More...
 
int pxe_api_call_weak (struct i386_all_regs *ix86)
 Dispatch weak PXE API call with PXE stack available. More...
 

Variables

rmjmp_buf pxe_restart_nbp
 PXENV_RESTART_TFTP jump buffer. More...
 

Detailed Description

PXE API entry point.

Definition in file pxe_call.h.

Macro Definition Documentation

◆ PXE_LOAD_SEGMENT

#define PXE_LOAD_SEGMENT   0

PXE load address segment.

Definition at line 18 of file pxe_call.h.

◆ PXE_LOAD_OFFSET

#define PXE_LOAD_OFFSET   0x7c00

PXE load address offset.

Definition at line 21 of file pxe_call.h.

◆ PXE_LOAD_PHYS

#define PXE_LOAD_PHYS   ( ( PXE_LOAD_SEGMENT << 4 ) + PXE_LOAD_OFFSET )

PXE physical load address.

Definition at line 24 of file pxe_call.h.

◆ ppxe

#define ppxe   __use_text16 ( ppxe )

Definition at line 28 of file pxe_call.h.

◆ pxenv

#define pxenv   __use_text16 ( pxenv )

Definition at line 32 of file pxe_call.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __text16() [1/2]

struct s_PXE __text16 ( ppxe  )

!PXE structure

◆ __text16() [2/2]

struct s_PXENV __text16 ( pxenv  )

PXENV+ structure.

◆ pxe_activate()

void pxe_activate ( struct net_device netdev)

Activate PXE stack.

Parameters
netdevNet device to use as PXE net device

Definition at line 269 of file pxe_call.c.

269  {
270  uint32_t discard_a;
271  uint32_t discard_b;
272  uint32_t discard_d;
273 
274  /* Ensure INT 1A is hooked */
275  if ( ! int_1a_hooked ) {
278  devices_get();
279  int_1a_hooked = 1;
280  }
281 
282  /* Set PXE network device */
284 
285  /* Notify BIOS of installation */
286  __asm__ __volatile__ ( REAL_CODE ( "pushw %%cs\n\t"
287  "popw %%es\n\t"
288  "int $0x1a\n\t" )
289  : "=a" ( discard_a ), "=b" ( discard_b ),
290  "=d" ( discard_d )
291  : "0" ( 0x564e ),
292  "1" ( __from_text16 ( &pxenv ) ) );
293 }
#define __from_text16(pointer)
Definition: libkir.h:23
void pxe_int_1a(void)
INT 1A handler.
unsigned long intptr_t
Definition: stdint.h:21
void hook_bios_interrupt(unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
Hook INT vector.
Definition: biosint.c:25
static int int_1a_hooked
INT 1A hooked flag.
Definition: pxe_call.c:55
static void devices_get(void)
Prevent devices from being removed on shutdown.
Definition: device.h:164
#define pxe_int_1a_vector
Definition: pxe_call.c:49
static struct net_device * netdev
Definition: gdbudp.c:52
void pxe_set_netdev(struct net_device *netdev)
Set network device as current PXE network device.
Definition: pxe_undi.c:69
__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 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")
#define pxenv
Definition: pxe_call.h:32
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

References __asm__(), __from_text16, __volatile__(), devices_get(), hook_bios_interrupt(), int_1a_hooked, netdev, pxe_int_1a(), pxe_int_1a_vector, pxe_set_netdev(), pxenv, and REAL_CODE.

Referenced by pxe_exec(), pxe_notify(), pxenv_start_undi(), and startpxe_payload().

◆ pxe_deactivate()

int pxe_deactivate ( void  )

Deactivate PXE stack.

Return values
rcReturn status code

Definition at line 300 of file pxe_call.c.

300  {
301  int rc;
302 
303  /* Clear PXE network device */
304  pxe_set_netdev ( NULL );
305 
306  /* Ensure INT 1A is unhooked, if possible */
307  if ( int_1a_hooked ) {
308  if ( ( rc = unhook_bios_interrupt ( 0x1a,
309  ( intptr_t ) pxe_int_1a,
310  &pxe_int_1a_vector ))!= 0){
311  DBGC ( &pxe_netdev, "PXE could not unhook INT 1A: %s\n",
312  strerror ( rc ) );
313  return rc;
314  }
315  devices_put();
316  int_1a_hooked = 0;
317  }
318 
319  return 0;
320 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void devices_put(void)
Allow devices to be removed on shutdown.
Definition: device.h:172
void pxe_int_1a(void)
INT 1A handler.
#define DBGC(...)
Definition: compiler.h:505
unsigned long intptr_t
Definition: stdint.h:21
int unhook_bios_interrupt(unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
Unhook INT vector.
Definition: biosint.c:70
static int int_1a_hooked
INT 1A hooked flag.
Definition: pxe_call.c:55
#define pxe_int_1a_vector
Definition: pxe_call.c:49
void pxe_set_netdev(struct net_device *netdev)
Set network device as current PXE network device.
Definition: pxe_undi.c:69
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct net_device * pxe_netdev
Definition: pxe_undi.c:59
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References DBGC, devices_put(), int_1a_hooked, NULL, pxe_int_1a(), pxe_int_1a_vector, pxe_netdev, pxe_set_netdev(), rc, strerror(), and unhook_bios_interrupt().

Referenced by pxe_exec(), pxe_notify(), pxenv_stop_undi(), and stoppxe_exec().

◆ pxe_start_nbp()

int pxe_start_nbp ( void  )

Start PXE NBP at 0000:7c00.

Return values
rcReturn status code

Definition at line 330 of file pxe_call.c.

330  {
331  int jmp;
332  int discard_b, discard_c, discard_d, discard_D;
334 
335  DBGC ( &pxe_netdev, "PXE NBP starting with netdev %s, code %04x:%04zx, "
336  "data %04x:%04zx\n", ( pxe_netdev ? pxe_netdev->name : "<none>"),
338 
339  /* Allow restarting NBP via PXENV_RESTART_TFTP */
341  if ( jmp )
342  DBGC ( &pxe_netdev, "PXE NBP restarting (%x)\n", jmp );
343 
344  /* Far call to PXE NBP */
345  __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
346  "movw %%cx, %%es\n\t"
347  "pushw %%es\n\t"
348  "pushw %%di\n\t"
349  "sti\n\t"
350  "lcall $0, $0x7c00\n\t"
351  "popl %%ebp\n\t" /* discard */
352  "popl %%ebp\n\t" /* gcc bug */ )
353  : "=a" ( status ), "=b" ( discard_b ),
354  "=c" ( discard_c ), "=d" ( discard_d ),
355  "=D" ( discard_D )
356  : "a" ( 0 ), "b" ( __from_text16 ( &pxenv ) ),
357  "c" ( rm_cs ),
358  "d" ( virt_to_phys ( &pxenv ) ),
359  "D" ( __from_text16 ( &ppxe ) )
360  : "esi", "memory" );
361  if ( status )
362  return -EPXENBP ( status );
363 
364  return 0;
365 }
unsigned short uint16_t
Definition: stdint.h:11
uint8_t jmp
"jmp" instruction
Definition: librm.h:142
#define ppxe
Definition: pxe_call.h:28
#define __from_text16(pointer)
Definition: libkir.h:23
#define DBGC(...)
Definition: compiler.h:505
#define rm_ds
Definition: libkir.h:39
#define _data16_memsz
Definition: pxe_call.c:63
#define _text16_memsz
Definition: pxe_call.c:59
struct net_device * pxe_netdev
Definition: pxe_undi.c:59
__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))
void * discard_D
Definition: bigint.h:31
uint8_t status
Status.
Definition: ena.h:16
__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")
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define rmsetjmp(_env)
Definition: rmsetjmp.h:17
#define rm_cs
Definition: libkir.h:38
long discard_c
Definition: bigint.h:32
#define pxenv
Definition: pxe_call.h:32
#define EPXENBP(status)
Definition: pxe_call.c:45
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226
rmjmp_buf pxe_restart_nbp
Jump buffer for PXENV_RESTART_TFTP.
Definition: pxe_call.c:323

References __asm__(), __from_text16, __volatile__(), _data16_memsz, _text16_memsz, DBGC, discard_c, discard_D, EPXENBP, jmp, net_device::name, ppxe, pxe_netdev, pxe_restart_nbp, pxenv, REAL_CODE, rm_cs, rm_ds, rmsetjmp, and status.

Referenced by pxe_exec().

◆ pxe_api_call()

__asmcall void pxe_api_call ( struct i386_all_regs ix86)

Dispatch PXE API call.

Parameters
bxPXE opcode
es:diAddress of PXE parameter block
Return values
axPXE exit code

Definition at line 145 of file pxe_call.c.

145  {
146  uint16_t opcode = ix86->regs.bx;
148  union u_PXENV_ANY *params =
149  real_to_virt ( ix86->segs.es, ix86->regs.di );
150  struct pxe_api_call *call;
151  PXENV_EXIT_t ret;
152 
153  /* Start profiling */
155 
156  /* Locate API call */
157  call = find_pxe_api_call ( opcode );
158  if ( ! call ) {
159  DBGC ( &pxe_netdev, "PXENV_UNKNOWN_%04x\n", opcode );
160  call = &pxenv_unknown_api;
161  }
162 
163  /* Set default status in case child routine fails to do so */
164  params->Status = PXENV_STATUS_FAILURE;
165 
166  /* Hand off to relevant API routine */
167  ret = call->entry ( params );
168 
169  /* Return exit code in %ax */
170  ix86->regs.ax = ret;
171 
172  /* Stop profiling, if applicable */
174 }
unsigned short uint16_t
Definition: stdint.h:11
struct i386_seg_regs segs
Definition: registers.h:175
PXENV_STATUS_t Status
Definition: pxe.h:29
uint8_t opcode
Opcode.
Definition: ena.h:16
uint16_t es
Definition: registers.h:142
#define DBGC(...)
Definition: compiler.h:505
A data structure for storing profiling information.
Definition: profile.h:26
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:173
static __always_inline void * real_to_virt(unsigned int segment, unsigned int offset)
Convert segment:offset address to virtual address.
Definition: realmode.h:77
static struct profiler * pxe_api_profiler(unsigned int opcode)
Determine applicable profiler (for debugging)
Definition: pxe_call.c:123
UINT16_t PXENV_EXIT_t
A PXE exit code.
Definition: pxe_types.h:44
struct i386_regs regs
Definition: registers.h:176
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:160
uint16_t bx
Definition: registers.h:84
struct net_device * pxe_netdev
Definition: pxe_undi.c:59
A PXE API call.
Definition: pxe.h:81
uint16_t di
Definition: registers.h:64
uint16_t ax
Definition: registers.h:108
static struct pxe_api_call * find_pxe_api_call(uint16_t opcode)
Locate PXE API call.
Definition: pxe_call.c:107
PXENV_EXIT_t(* entry)(union u_PXENV_ANY *params)
Entry point.
Definition: pxe.h:87
#define PXENV_STATUS_FAILURE
Definition: pxe_error.h:20

References i386_regs::ax, i386_regs::bx, DBGC, i386_regs::di, pxe_api_call::entry, i386_seg_regs::es, find_pxe_api_call(), opcode, profile_start(), profile_stop(), pxe_api_profiler(), pxe_netdev, PXENV_STATUS_FAILURE, real_to_virt(), i386_all_regs::regs, i386_all_regs::segs, and u_PXENV_ANY::Status.

Referenced by pxe_api_call_weak().

◆ pxe_api_call_weak()

int pxe_api_call_weak ( struct i386_all_regs ix86)

Dispatch weak PXE API call with PXE stack available.

Parameters
ix86Registers for PXE call
Return values
presentZero (PXE stack present)

Definition at line 182 of file pxe_call.c.

182  {
183  pxe_api_call ( ix86 );
184  return 0;
185 }
__asmcall void pxe_api_call(struct i386_all_regs *ix86)
Dispatch PXE API call.
Definition: pxe_call.c:145

References pxe_api_call().

Variable Documentation

◆ pxe_restart_nbp

rmjmp_buf pxe_restart_nbp

PXENV_RESTART_TFTP jump buffer.

PXENV_RESTART_TFTP jump buffer.

Definition at line 323 of file pxe_call.c.

Referenced by pxe_start_nbp(), and pxenv_restart_tftp().