[pxeprefix] Add .kkpxe image type and ability to return via PXE stack
Certain combinations of PXE stack and BIOS result in a broken INT 18
call, which will leave the system displaying a "PRESS ANY KEY TO
REBOOT" message instead of proceeding to the next boot device. On
these systems, returning via the PXE stack is the only way to continue
to the next boot device. Returning via the PXE stack works only if we
haven't already blown away the PXE base code in pxeprefix.S.
In most circumstances, we do want to blow away the PXE base code.
Base memory is a limited resource, and it is desirable to reclaim as
much as possible. When we perform an iSCSI boot, we need to place the
iBFT above the 512kB mark, because otherwise it may not be detected by
the loaded OS; this may not be possible if the PXE base code is still
occupying that memory.
Introduce a new prefix type .kkpxe which will preserve both the PXE
base code and the UNDI driver (as compared to .kpxe, which preserves
the UNDI driver but uninstalls the PXE base code). This prefix type
can be used on systems that are known to experience the specific
problem of INT 18 being broken, or in builds (such as gpxelinux.0) for
which it is particularly important to know that returning to the BIOS
will work.
Written by H. Peter Anvin <hpa@zytor.com> and Stefan Hajnoczi
<stefanha@gmail.com>, minor structural alterations by Michael Brown
<mcb30@etherboot.org>.
[iobuf] Add iob_disown() and use it where it simplifies code
There are many functions that take ownership of the I/O buffer they
are passed as a parameter. The caller should not retain a pointer to
the I/O buffer. Use iob_disown() to automatically nullify the
caller's pointer, e.g.:
xfer_deliver_iob ( xfer, iob_disown ( iobuf ) );
This will ensure that iobuf is set to NULL for any code after the call
to xfer_deliver_iob().
iob_disown() is currently used only in places where it simplifies the
code, by avoiding an extra line explicitly setting the I/O buffer
pointer to NULL. It should ideally be used with each call to any
function that takes ownership of an I/O buffer. (The SSA
optimisations will ensure that use of iob_disown() gets optimised away
in cases where the caller makes no further use of the I/O buffer
pointer anyway.)
If gcc ever introduces an __attribute__((free)), indicating that use
of a function argument after a function call should generate a
warning, then we should use this to identify all applicable function
call sites, and add iob_disown() as necessary.
[i386] Change [u]int32_t to [unsigned] int, rather than [unsigned] long
This brings us in to line with Linux definitions, and also simplifies
adding x86_64 support since both platforms have 2-byte shorts, 4-byte
ints and 8-byte long longs.
The userptr_t is now the fundamental type that gets used for conversions.
For example, virt_to_phys() is implemented in terms of virt_to_user() and
user_to_phys().
[undi] Scan for UNDI ROMs on 512-byte boundaries rather than 2kB boundaries
Apparently some BIOSes will place option ROMs on 512-byte boundaries.
While this is against specification, it doesn't actually hurt
anything, so we may as well increase our scan granularity to 512
bytes.
Contributed by Luca <lucarx76@gmail.com>
[i386] Change semantics of __from_data16 and __from_text16
__from_data16 and __from_text16 now take a pointer to a
.data16/.text16 variable, and return the real-mode offset within the
appropriate segment. This matches the use case for every occurrence
of these macros, and prevents potential future bugs such as that fixed
in commit d51d80f. (The bug arose essentially because "&pointer" is
still syntactically valid.)
[undi] Ask for promiscuous packet reception when using UNDI driver
We never set up specific multicast filters; native drivers will ask
the card to receive all multicast packets. The only way to achieve
this via the UNDI API is to enable promiscuous mode.
Add ability for network devices to flag link up/down state to the
networking core.
Autobooting code will now wait for link-up before attempting DHCP.
IPoIB reflects the Infiniband link state as the network device link state
(which is not strictly correct; we also need a succesful IPoIB IPv4
broadcast group join), but is probably more informative.
As written, if the if the UNDI ISR call clobbers the upper halves of
any of the GPRs (which by convention it is permitted to do, and by
paranoia should be expected to do) then nothing in the interrupt
handler will recover the state.
Additionally, save/restore %fs and %gs out of sheer paranoia - it's a
cheap enough operation, and may prevent problems due to poorly written
UNDI stacks.
Since we don't know what the UNDI code does, it is safest to
save/restore %eflags even though the lower half of %eflags is
automatically saved by the interrupt itself.
As written, if the if the UNDI ISR call clobbers the upper halves of
any of the GPRs (which by convention it is permitted to do, and by
paranoia should be expected to do) then nothing in the interrupt
handler will recover the state.
Additionally, save/restore %fs and %gs out of sheer paranoia - it's a
cheap enough operation, and may prevent problems due to poorly written
UNDI stacks.
Improve error reporting for strange length combinations reported by
the UNDI stack.
Ignore obviously invalid length combinations (as returned by
e.g. VMWare's PXE stack).
Limit to one packet per poll to avoid memory exhaustion.
Set up %ds *before* testing a value in our data segment (d'oh!).
Always send EOI; do not chain to BIOS's default interrupt handler.
They are just too unpredictable; at least VMware's seems to kill the
machine if you go anywhere near it.
Disable interrupts after return from PXENV_UNDI_ISR, just in case some
dumb PXE stack enables them.
Use net_device_operations structure and netdev_nullify() to allow for
safe dropping of the netdev ref by the driver while other refs still
exist.
Add netdev_irq() method. Net device open()/close() methods should no
longer enable or disable IRQs.
Remove rx_quota; it wasn't used anywhere and added too much complexity
to implementing correct interrupt-masking behaviour in pxe_undi.c.
Always send EOI. We can't feasibly share interrupts (since we have no
clue what the "previous" interrupt handler will do, which could range
from "just an iret" to "disable the interrupt"), and that means that
we have to take responsibility for ACKing all interrupts. Joy.
Add "name" field to struct device to allow human-readable hardware device
names.
Add "dev" pointer in struct net_device to tie network interfaces back to a
hardware device.
Force natural alignment of data types in __table() macros. This seems to
prevent gcc from taking the unilateral decision to occasionally increase
their alignment (which screws up the table packing).