diff options
Diffstat (limited to 'src/arch/i386')
-rw-r--r-- | src/arch/i386/include/pxe_call.h | 19 | ||||
-rw-r--r-- | src/arch/i386/interface/pxe/pxe_call.c | 12 | ||||
-rw-r--r-- | src/arch/i386/interface/syslinux/comboot_call.c | 6 | ||||
-rw-r--r-- | src/arch/i386/prefix/romprefix.S | 47 | ||||
-rw-r--r-- | src/arch/i386/prefix/undiloader.S | 49 |
5 files changed, 87 insertions, 46 deletions
diff --git a/src/arch/i386/include/pxe_call.h b/src/arch/i386/include/pxe_call.h index 50667e62..4d245616 100644 --- a/src/arch/i386/include/pxe_call.h +++ b/src/arch/i386/include/pxe_call.h @@ -34,5 +34,24 @@ extern void pxe_activate ( struct net_device *netdev ); extern int pxe_deactivate ( void ); extern int pxe_start_nbp ( void ); extern __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ); +extern int _pxe_api_call_weak ( struct i386_all_regs *ix86 ) + __attribute__ (( weak )); + +/** + * Dispatch PXE API call weakly + * + * @v ix86 Registers for PXE call + * @ret present Zero if the PXE stack is present, nonzero if not + * + * A successful return only indicates that the PXE stack was available + * for dispatching the call; it says nothing about the success of + * whatever the call asked for. + */ +static inline int pxe_api_call_weak ( struct i386_all_regs *ix86 ) +{ + if ( _pxe_api_call_weak != NULL ) + return _pxe_api_call_weak ( ix86 ); + return -1; +} #endif /* _PXE_CALL_H */ diff --git a/src/arch/i386/interface/pxe/pxe_call.c b/src/arch/i386/interface/pxe/pxe_call.c index 705afcab..a50d6437 100644 --- a/src/arch/i386/interface/pxe/pxe_call.c +++ b/src/arch/i386/interface/pxe/pxe_call.c @@ -340,6 +340,18 @@ __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) { } /** + * Dispatch weak PXE API call with PXE stack available + * + * @v ix86 Registers for PXE call + * @ret present Zero (PXE stack present) + */ +int _pxe_api_call_weak ( struct i386_all_regs *ix86 ) +{ + pxe_api_call ( ix86 ); + return 0; +} + +/** * Dispatch PXE loader call * * @v es:di Address of PXE parameter block diff --git a/src/arch/i386/interface/syslinux/comboot_call.c b/src/arch/i386/interface/syslinux/comboot_call.c index 08fd1736..0a17bf13 100644 --- a/src/arch/i386/interface/syslinux/comboot_call.c +++ b/src/arch/i386/interface/syslinux/comboot_call.c @@ -445,8 +445,10 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) { break; case 0x0009: /* Call PXE Stack */ - pxe_api_call ( ix86 ); - ix86->flags &= ~CF; + if ( pxe_api_call_weak ( ix86 ) != 0 ) + ix86->flags |= CF; + else + ix86->flags &= ~CF; break; case 0x000A: /* Get Derivative-Specific Information */ diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S index d695fd92..952eccdd 100644 --- a/src/arch/i386/prefix/romprefix.S +++ b/src/arch/i386/prefix/romprefix.S @@ -126,6 +126,7 @@ prodstr_pci_id: .size prodstr, . - prodstr .globl undiheader + .weak undiloader undiheader: .ascii "UNDI" /* Signature */ .byte undiheader_len /* Length of structure */ @@ -495,6 +496,7 @@ init_message_done: * * May be either within option ROM space, or within PMM-allocated block. */ + .globl image_source image_source: .long 0 .size image_source, . - image_source @@ -503,6 +505,7 @@ image_source: * * May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block. */ + .globl decompress_to decompress_to: .long HIGHMEM_LOADPOINT .size decompress_to, . - decompress_to @@ -644,50 +647,6 @@ exec_message: .asciz " starting execution\n" .size exec_message, . - exec_message -/* UNDI loader - * - * Called by an external program to load our PXE stack. - */ -undiloader: - /* Save registers */ - pushl %esi - pushl %edi - pushw %ds - pushw %es - pushw %bx - /* ROM segment address to %ds */ - pushw %cs - popw %ds - /* UNDI loader parameter structure address into %es:%di */ - movw %sp, %bx - movw %ss:18(%bx), %di - movw %ss:20(%bx), %es - /* Install to specified real-mode addresses */ - pushw %di - movw %es:12(%di), %bx - movw %es:14(%di), %ax - movl image_source, %esi - movl decompress_to, %edi - call install_prealloc - popw %di - /* Call UNDI loader C code */ - pushl $pxe_loader_call - pushw %cs - pushw $1f - pushw %ax - pushw $prot_call - lret -1: popw %bx /* discard */ - popw %bx /* discard */ - /* Restore registers and return */ - popw %bx - popw %es - popw %ds - popl %edi - popl %esi - lret - .size undiloader, . - undiloader - /* Wait for key press specified by %bl (masked by %bh) * * Used by init and INT19 code when prompting user. If the specified diff --git a/src/arch/i386/prefix/undiloader.S b/src/arch/i386/prefix/undiloader.S new file mode 100644 index 00000000..36c1bef3 --- /dev/null +++ b/src/arch/i386/prefix/undiloader.S @@ -0,0 +1,49 @@ + .text + .code16 + .arch i386 + .section ".prefix", "ax", @progbits + +/* UNDI loader + * + * Called by an external program to load our PXE stack. + */ + .globl undiloader +undiloader: + /* Save registers */ + pushl %esi + pushl %edi + pushw %ds + pushw %es + pushw %bx + /* ROM segment address to %ds */ + pushw %cs + popw %ds + /* UNDI loader parameter structure address into %es:%di */ + movw %sp, %bx + movw %ss:18(%bx), %di + movw %ss:20(%bx), %es + /* Install to specified real-mode addresses */ + pushw %di + movw %es:12(%di), %bx + movw %es:14(%di), %ax + movl image_source, %esi + movl decompress_to, %edi + call install_prealloc + popw %di + /* Call UNDI loader C code */ + pushl $pxe_loader_call + pushw %cs + pushw $1f + pushw %ax + pushw $prot_call + lret +1: popw %bx /* discard */ + popw %bx /* discard */ + /* Restore registers and return */ + popw %bx + popw %es + popw %ds + popl %edi + popl %esi + lret + .size undiloader, . - undiloader |