Skip to content

Commit

Permalink
Merge branch 'x86-setup-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/tip/linux-2.6-tip

* 'x86-setup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, setup: fix comment in the "glove box" code
  x86, setup: "glove box" BIOS interrupts in the video code
  x86, setup: "glove box" BIOS interrupts in the MCA code
  x86, setup: "glove box" BIOS interrupts in the EDD code
  x86, setup: "glove box" BIOS interrupts in the APM code
  x86, setup: "glove box" BIOS interrupts in the core boot code
  x86, setup: "glove box" BIOS calls -- infrastructure
  • Loading branch information
Linus Torvalds committed Jun 10, 2009
2 parents bb77629 + ee07366 commit bec7068
Show file tree
Hide file tree
Showing 21 changed files with 489 additions and 355 deletions.
5 changes: 3 additions & 2 deletions arch/x86/boot/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ targets := vmlinux.bin setup.bin setup.elf bzImage
targets += fdimage fdimage144 fdimage288 image.iso mtools.conf
subdir- := compressed

setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
setup-y += a20.o bioscall.o cmdline.o copy.o cpu.o cpucheck.o edd.o
setup-y += header.o main.o mca.o memory.o pm.o pmjump.o
setup-y += printf.o string.o tty.o video.o video-mode.o version.o
setup-y += printf.o regs.o string.o tty.o video.o video-mode.o
setup-y += version.o
setup-$(CONFIG_X86_APM_BOOT) += apm.o

# The link order of the video-*.o modules can matter. In particular,
Expand Down
9 changes: 6 additions & 3 deletions arch/x86/boot/a20.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007-2008 rPath, Inc. - All Rights Reserved
* Copyright 2009 Intel Corporation
* Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
Expand Down Expand Up @@ -90,8 +90,11 @@ static int a20_test_long(void)

static void enable_a20_bios(void)
{
asm volatile("pushfl; int $0x15; popfl"
: : "a" ((u16)0x2401));
struct biosregs ireg;

initregs(&ireg);
ireg.ax = 0x2401;
intcall(0x15, &ireg, NULL);
}

static void enable_a20_kbc(void)
Expand Down
76 changes: 29 additions & 47 deletions arch/x86/boot/apm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
* Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* Original APM BIOS checking by Stephen Rothwell, May 1994
* (sfr@canb.auug.org.au)
Expand All @@ -19,75 +20,56 @@

int query_apm_bios(void)
{
u16 ax, bx, cx, dx, di;
u32 ebx, esi;
u8 err;
struct biosregs ireg, oreg;

/* APM BIOS installation check */
ax = 0x5300;
bx = cx = 0;
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
: "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
: : "esi", "edi");
initregs(&ireg);
ireg.ah = 0x53;
intcall(0x15, &ireg, &oreg);

if (err)
if (oreg.flags & X86_EFLAGS_CF)
return -1; /* No APM BIOS */

if (bx != 0x504d) /* "PM" signature */
if (oreg.bx != 0x504d) /* "PM" signature */
return -1;

if (!(cx & 0x02)) /* 32 bits supported? */
if (!(oreg.cx & 0x02)) /* 32 bits supported? */
return -1;

/* Disconnect first, just in case */
ax = 0x5304;
bx = 0;
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
: "+a" (ax), "+b" (bx)
: : "ecx", "edx", "esi", "edi");

/* Paranoia */
ebx = esi = 0;
cx = dx = di = 0;
ireg.al = 0x04;
intcall(0x15, &ireg, NULL);

/* 32-bit connect */
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
: "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
"+S" (esi), "+D" (di), "=m" (err)
: "a" (0x5303));

boot_params.apm_bios_info.cseg = ax;
boot_params.apm_bios_info.offset = ebx;
boot_params.apm_bios_info.cseg_16 = cx;
boot_params.apm_bios_info.dseg = dx;
boot_params.apm_bios_info.cseg_len = (u16)esi;
boot_params.apm_bios_info.cseg_16_len = esi >> 16;
boot_params.apm_bios_info.dseg_len = di;

if (err)
ireg.al = 0x03;
intcall(0x15, &ireg, &oreg);

boot_params.apm_bios_info.cseg = oreg.ax;
boot_params.apm_bios_info.offset = oreg.ebx;
boot_params.apm_bios_info.cseg_16 = oreg.cx;
boot_params.apm_bios_info.dseg = oreg.dx;
boot_params.apm_bios_info.cseg_len = oreg.si;
boot_params.apm_bios_info.cseg_16_len = oreg.hsi;
boot_params.apm_bios_info.dseg_len = oreg.di;

if (oreg.flags & X86_EFLAGS_CF)
return -1;

/* Redo the installation check as the 32-bit connect;
some BIOSes return different flags this way... */

ax = 0x5300;
bx = cx = 0;
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
: "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
: : "esi", "edi");
ireg.al = 0x00;
intcall(0x15, &ireg, &oreg);

if (err || bx != 0x504d) {
if ((oreg.eflags & X86_EFLAGS_CF) || oreg.bx != 0x504d) {
/* Failure with 32-bit connect, try to disconect and ignore */
ax = 0x5304;
bx = 0;
asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
: "+a" (ax), "+b" (bx)
: : "ecx", "edx", "esi", "edi");
ireg.al = 0x04;
intcall(0x15, &ireg, NULL);
return -1;
}

boot_params.apm_bios_info.version = ax;
boot_params.apm_bios_info.flags = cx;
boot_params.apm_bios_info.version = oreg.ax;
boot_params.apm_bios_info.flags = oreg.cx;
return 0;
}

82 changes: 82 additions & 0 deletions arch/x86/boot/bioscall.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* -----------------------------------------------------------------------
*
* Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2 or (at your
* option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */

/*
* "Glove box" for BIOS calls. Avoids the constant problems with BIOSes
* touching registers they shouldn't be.
*/

.code16
.text
.globl intcall
.type intcall, @function
intcall:
/* Self-modify the INT instruction. Ugly, but works. */
cmpb %al, 3f
je 1f
movb %al, 3f
jmp 1f /* Synchronize pipeline */
1:
/* Save state */
pushfl
pushw %fs
pushw %gs
pushal

/* Copy input state to stack frame */
subw $44, %sp
movw %dx, %si
movw %sp, %di
movw $11, %cx
rep; movsd

/* Pop full state from the stack */
popal
popw %gs
popw %fs
popw %es
popw %ds
popfl

/* Actual INT */
.byte 0xcd /* INT opcode */
3: .byte 0

/* Push full state to the stack */
pushfl
pushw %ds
pushw %es
pushw %fs
pushw %gs
pushal

/* Re-establish C environment invariants */
cld
movzwl %sp, %esp
movw %cs, %ax
movw %ax, %ds
movw %ax, %es

/* Copy output state from stack frame */
movw 68(%esp), %di /* Original %cx == 3rd argument */
andw %di, %di
jz 4f
movw %sp, %si
movw $11, %cx
rep; movsd
4: addw $44, %sp

/* Restore state and return */
popal
popw %gs
popw %fs
popfl
retl
.size intcall, .-intcall
48 changes: 48 additions & 0 deletions arch/x86/boot/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
* Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
Expand All @@ -26,6 +27,7 @@
#include <asm/setup.h>
#include "bitops.h"
#include <asm/cpufeature.h>
#include <asm/processor-flags.h>

/* Useful macros */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
Expand Down Expand Up @@ -241,6 +243,49 @@ int enable_a20(void);
/* apm.c */
int query_apm_bios(void);

/* bioscall.c */
struct biosregs {
union {
struct {
u32 edi;
u32 esi;
u32 ebp;
u32 _esp;
u32 ebx;
u32 edx;
u32 ecx;
u32 eax;
u32 _fsgs;
u32 _dses;
u32 eflags;
};
struct {
u16 di, hdi;
u16 si, hsi;
u16 bp, hbp;
u16 _sp, _hsp;
u16 bx, hbx;
u16 dx, hdx;
u16 cx, hcx;
u16 ax, hax;
u16 gs, fs;
u16 es, ds;
u16 flags, hflags;
};
struct {
u8 dil, dih, edi2, edi3;
u8 sil, sih, esi2, esi3;
u8 bpl, bph, ebp2, ebp3;
u8 _spl, _sph, _esp2, _esp3;
u8 bl, bh, ebx2, ebx3;
u8 dl, dh, edx2, edx3;
u8 cl, ch, ecx2, ecx3;
u8 al, ah, eax2, eax3;
};
};
};
void intcall(u8 int_no, const struct biosregs *ireg, struct biosregs *oreg);

/* cmdline.c */
int cmdline_find_option(const char *option, char *buffer, int bufsize);
int cmdline_find_option_bool(const char *option);
Expand Down Expand Up @@ -279,6 +324,9 @@ int sprintf(char *buf, const char *fmt, ...);
int vsprintf(char *buf, const char *fmt, va_list args);
int printf(const char *fmt, ...);

/* regs.c */
void initregs(struct biosregs *regs);

/* string.c */
int strcmp(const char *str1, const char *str2);
size_t strnlen(const char *s, size_t maxlen);
Expand Down
Loading

0 comments on commit bec7068

Please sign in to comment.