Track when entering via call32() and use the same mode for stack_hop_back()

If 32bit mode is entered directly via transition32, then use a simple
call16() when hopping back to 16bit mode.  Use only call16big() during
post and when entering 32bit mode via call32().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Simplify farcall16 code

With this change, farcall16() is only used for external API calls and
is only invoked from a 32bit mode entered directly via transition32.
farcall16big() is also only used for external API calls and is only
invoked from a 32bit mode entered directly via transition32.

call16_int() now calls _farcall16() directly, and it will use normal
16bit mode or big real mode as required.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Update reset() to use call16_back()

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
build: Support declaring 32bit C functions that must reside in the f-segment

Add support for a FUNCFSEG macro that will force a "32bit flat" C
function to be located in the f-segment.  This is useful for 32bit
code with inline assembler that thunks to 16bit mode.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move call16() functions from romlayout.S to inline assembler in stacks.c

Use inline assembler in call16 type functions instead of using
__call16() in romlayout.S.

Since call16() and call16big() are now only called with %ss==0 they do
not need to update the stack pointer.  Only call16_sloppy() requires
the stack manipulation code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Break up call32() into call32() and call32_sloppy()

This separates call32() into two functions.  It also moves the
call16_sloppy() code next to the call32_sloppy() code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Fully restore 16bit state during call16_sloppy()

When transitioning back to 16bit mode from within call32(), restore
the full state (cmos index, gdt, fs/gs) in addition to restoring the
original stack.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Implement call32 mechanism using SMIs.

Add support for jumping into 32bit mode using a System Management Mode
(SMM) handler.  When available, this allows SeaBIOS to transition to
32bit mode even when called in vm86 mode.  It will also prevent the
clobbering of the segment registers.

Currently, the SMM mode is only supported in QEMU when running in TCG
mode.  Also, QEMU v2.1 (or later) is needed for it to work when in
vm86 mode.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Move a20 code from system.c and ps2port.h to x86.h

Although the a20 functionality was originally implemented in the ps2
controller, that is just a historical artifact.  It's a core feature
of modern x86 cpus and the code is better located in the x86.h header.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Backup and restore a20 on call32_sloppy()

Previously, the a20 line would always be enabled and left on after
call32_sloppy().  The setting should really be backed up and restored
on each call.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>