aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/boot/main.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-07-11 15:18:54 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-12 13:55:55 -0400
commit626073132b381684c4983e0d911e9aceb32e2cbc (patch)
tree2960cbd6e7ef45e476c5679bbff01d8446702615 /arch/i386/boot/main.c
parent7052fdd890bda0b3904674b69a1d24aec0a10d67 (diff)
Assembly header and main routine for new x86 setup code
The assembly header and initialization code, and the main() routine. main.c also contains some miscellaneous very short routines. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/i386/boot/main.c')
-rw-r--r--arch/i386/boot/main.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/arch/i386/boot/main.c b/arch/i386/boot/main.c
new file mode 100644
index 000000000000..7f01f96c4fb8
--- /dev/null
+++ b/arch/i386/boot/main.c
@@ -0,0 +1,161 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * 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 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/main.c
13 *
14 * Main module for the real-mode kernel code
15 */
16
17#include "boot.h"
18
19struct boot_params boot_params __attribute__((aligned(16)));
20
21char *HEAP = _end;
22char *heap_end = _end; /* Default end of heap = no heap */
23
24/*
25 * Copy the header into the boot parameter block. Since this
26 * screws up the old-style command line protocol, adjust by
27 * filling in the new-style command line pointer instead.
28 */
29#define OLD_CL_MAGIC 0xA33F
30#define OLD_CL_ADDRESS 0x20
31
32static void copy_boot_params(void)
33{
34 struct old_cmdline {
35 u16 cl_magic;
36 u16 cl_offset;
37 };
38 const struct old_cmdline * const oldcmd =
39 (const struct old_cmdline *)OLD_CL_ADDRESS;
40
41 BUILD_BUG_ON(sizeof boot_params != 4096);
42 memcpy(&boot_params.hdr, &hdr, sizeof hdr);
43
44 if (!boot_params.hdr.cmd_line_ptr &&
45 oldcmd->cl_magic == OLD_CL_MAGIC) {
46 /* Old-style command line protocol. */
47 u16 cmdline_seg;
48
49 /* Figure out if the command line falls in the region
50 of memory that an old kernel would have copied up
51 to 0x90000... */
52 if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
53 cmdline_seg = ds();
54 else
55 cmdline_seg = 0x9000;
56
57 boot_params.hdr.cmd_line_ptr =
58 (cmdline_seg << 4) + oldcmd->cl_offset;
59 }
60}
61
62/*
63 * Set the keyboard repeat rate to maximum. Unclear why this
64 * is done here; this might be possible to kill off as stale code.
65 */
66static void keyboard_set_repeat(void)
67{
68 u16 ax = 0x0305;
69 u16 bx = 0;
70 asm volatile("int $0x16"
71 : "+a" (ax), "+b" (bx)
72 : : "ecx", "edx", "esi", "edi");
73}
74
75/*
76 * Get Intel SpeedStep IST information.
77 */
78static void query_speedstep_ist(void)
79{
80 asm("int $0x15"
81 : "=a" (boot_params.speedstep_info[0]),
82 "=b" (boot_params.speedstep_info[1]),
83 "=c" (boot_params.speedstep_info[2]),
84 "=d" (boot_params.speedstep_info[3])
85 : "a" (0x0000e980), /* IST Support */
86 "d" (0x47534943)); /* Request value */
87}
88
89/*
90 * Tell the BIOS what CPU mode we intend to run in.
91 */
92static void set_bios_mode(void)
93{
94#ifdef CONFIG_X86_64
95 u32 eax, ebx;
96
97 eax = 0xec00;
98 ebx = 2;
99 asm volatile("int $0x15"
100 : "+a" (eax), "+b" (ebx)
101 : : "ecx", "edx", "esi", "edi");
102#endif
103}
104
105void main(void)
106{
107 /* First, copy the boot header into the "zeropage" */
108 copy_boot_params();
109
110 /* End of heap check */
111 if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
112 heap_end = (char *)(boot_params.hdr.heap_end_ptr
113 +0x200-STACK_SIZE);
114 } else {
115 /* Boot protocol 2.00 only, no heap available */
116 puts("WARNING: Ancient bootloader, some functionality "
117 "may be limited!\n");
118 }
119
120 /* Make sure we have all the proper CPU support */
121 if (validate_cpu()) {
122 puts("Unable to boot - please use a kernel appropriate "
123 "for your CPU.\n");
124 die();
125 }
126
127 /* Tell the BIOS what CPU mode we intend to run in. */
128 set_bios_mode();
129
130 /* Detect memory layout */
131 detect_memory();
132
133 /* Set keyboard repeat rate (why?) */
134 keyboard_set_repeat();
135
136 /* Set the video mode */
137 set_video();
138
139 /* Query MCA information */
140 query_mca();
141
142 /* Voyager */
143#ifdef CONFIG_X86_VOYAGER
144 query_voyager();
145#endif
146
147 /* Query SpeedStep IST information */
148 query_speedstep_ist();
149
150 /* Query APM information */
151#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
152 query_apm_bios();
153#endif
154
155 /* Query EDD information */
156#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
157 query_edd();
158#endif
159 /* Do the last things and invoke protected mode */
160 go_to_protected_mode();
161}