diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2009-04-01 21:13:46 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-04-09 19:08:11 -0400 |
commit | df7699c56421c0476704f24a43409ac8c505f3d2 (patch) | |
tree | c8d5935a5bd7dd59b0ce70db1a53999090be938b /arch/x86/boot/tty.c | |
parent | 7a734e7dd93b9aea08ed51036a9a0e2c9dfd8dac (diff) |
x86, setup: "glove box" BIOS interrupts in the core boot code
Impact: BIOS proofing
"Glove box" off BIOS interrupts in the core boot code.
LKML-Reference: <49DE7F79.4030106@zytor.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/boot/tty.c')
-rw-r--r-- | arch/x86/boot/tty.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/arch/x86/boot/tty.c b/arch/x86/boot/tty.c index 7e8e8b25f5f6..01ec69c901c7 100644 --- a/arch/x86/boot/tty.c +++ b/arch/x86/boot/tty.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
4 | * Copyright 2007 rPath, Inc. - All Rights Reserved | 4 | * Copyright 2007 rPath, Inc. - All Rights Reserved |
5 | * Copyright 2009 Intel Corporation; author H. Peter Anvin | ||
5 | * | 6 | * |
6 | * This file is part of the Linux kernel, and is made available under | 7 | * This file is part of the Linux kernel, and is made available under |
7 | * the terms of the GNU General Public License version 2. | 8 | * the terms of the GNU General Public License version 2. |
@@ -22,24 +23,23 @@ | |||
22 | 23 | ||
23 | void __attribute__((section(".inittext"))) putchar(int ch) | 24 | void __attribute__((section(".inittext"))) putchar(int ch) |
24 | { | 25 | { |
25 | unsigned char c = ch; | 26 | struct biosregs ireg; |
26 | 27 | ||
27 | if (c == '\n') | 28 | if (ch == '\n') |
28 | putchar('\r'); /* \n -> \r\n */ | 29 | putchar('\r'); /* \n -> \r\n */ |
29 | 30 | ||
30 | /* int $0x10 is known to have bugs involving touching registers | 31 | initregs(&ireg); |
31 | it shouldn't. Be extra conservative... */ | 32 | ireg.bx = 0x0007; |
32 | asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal" | 33 | ireg.cx = 0x0001; |
33 | : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch)); | 34 | ireg.ah = 0x0e; |
35 | ireg.al = ch; | ||
36 | intcall(0x10, &ireg, NULL); | ||
34 | } | 37 | } |
35 | 38 | ||
36 | void __attribute__((section(".inittext"))) puts(const char *str) | 39 | void __attribute__((section(".inittext"))) puts(const char *str) |
37 | { | 40 | { |
38 | int n = 0; | 41 | while (*str) |
39 | while (*str) { | ||
40 | putchar(*str++); | 42 | putchar(*str++); |
41 | n++; | ||
42 | } | ||
43 | } | 43 | } |
44 | 44 | ||
45 | /* | 45 | /* |
@@ -49,14 +49,13 @@ void __attribute__((section(".inittext"))) puts(const char *str) | |||
49 | 49 | ||
50 | static u8 gettime(void) | 50 | static u8 gettime(void) |
51 | { | 51 | { |
52 | u16 ax = 0x0200; | 52 | struct biosregs ireg, oreg; |
53 | u16 cx, dx; | ||
54 | 53 | ||
55 | asm volatile("int $0x1a" | 54 | initregs(&ireg); |
56 | : "+a" (ax), "=c" (cx), "=d" (dx) | 55 | ireg.ah = 0x02; |
57 | : : "ebx", "esi", "edi"); | 56 | intcall(0x1a, &ireg, &oreg); |
58 | 57 | ||
59 | return dx >> 8; | 58 | return oreg.dh; |
60 | } | 59 | } |
61 | 60 | ||
62 | /* | 61 | /* |
@@ -64,19 +63,24 @@ static u8 gettime(void) | |||
64 | */ | 63 | */ |
65 | int getchar(void) | 64 | int getchar(void) |
66 | { | 65 | { |
67 | u16 ax = 0; | 66 | struct biosregs ireg, oreg; |
68 | asm volatile("int $0x16" : "+a" (ax)); | 67 | |
68 | initregs(&ireg); | ||
69 | /* ireg.ah = 0x00; */ | ||
70 | intcall(0x16, &ireg, &oreg); | ||
69 | 71 | ||
70 | return ax & 0xff; | 72 | return oreg.al; |
71 | } | 73 | } |
72 | 74 | ||
73 | static int kbd_pending(void) | 75 | static int kbd_pending(void) |
74 | { | 76 | { |
75 | u8 pending; | 77 | struct biosregs ireg, oreg; |
76 | asm volatile("int $0x16; setnz %0" | 78 | |
77 | : "=qm" (pending) | 79 | initregs(&ireg); |
78 | : "a" (0x0100)); | 80 | ireg.ah = 0x01; |
79 | return pending; | 81 | intcall(0x16, &ireg, &oreg); |
82 | |||
83 | return !(oreg.eflags & X86_EFLAGS_ZF); | ||
80 | } | 84 | } |
81 | 85 | ||
82 | void kbd_flush(void) | 86 | void kbd_flush(void) |