/* -*- linux-c -*- ------------------------------------------------------- *1*2* Copyright (C) 1991, 1992 Linus Torvalds3* Copyright 2007 rPath, Inc. - All Rights Reserved4* Copyright 2009 Intel Corporation; author H. Peter Anvin5*6* This file is part of the Linux kernel, and is made available under7* the terms of the GNU General Public License version 2.8*9* ----------------------------------------------------------------------- */1011/*12* Main module for the real-mode kernel code13*/1415#include "boot.h"1617struct boot_params boot_params __attribute__((aligned(16)));1819char *HEAP = _end;20char *heap_end = _end; /* Default end of heap = no heap */2122/*23* Copy the header into the boot parameter block. Since this24* screws up the old-style command line protocol, adjust by25* filling in the new-style command line pointer instead.26*/2728static void copy_boot_params(void)29{30struct old_cmdline {31u16 cl_magic;32u16 cl_offset;33};34const struct old_cmdline * const oldcmd =35(const struct old_cmdline *)OLD_CL_ADDRESS;3637BUILD_BUG_ON(sizeof boot_params != 4096);38memcpy(&boot_params.hdr, &hdr, sizeof hdr);3940if (!boot_params.hdr.cmd_line_ptr &&41oldcmd->cl_magic == OLD_CL_MAGIC) {42/* Old-style command line protocol. */43u16 cmdline_seg;4445/* Figure out if the command line falls in the region46of memory that an old kernel would have copied up47to 0x90000... */48if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)49cmdline_seg = ds();50else51cmdline_seg = 0x9000;5253boot_params.hdr.cmd_line_ptr =54(cmdline_seg << 4) + oldcmd->cl_offset;55}56}5758/*59* Set the keyboard repeat rate to maximum. Unclear why this60* is done here; this might be possible to kill off as stale code.61*/62static void keyboard_set_repeat(void)63{64struct biosregs ireg;65initregs(&ireg);66ireg.ax = 0x0305;67intcall(0x16, &ireg, NULL);68}6970/*71* Get Intel SpeedStep (IST) information.72*/73static void query_ist(void)74{75struct biosregs ireg, oreg;7677/* Some older BIOSes apparently crash on this call, so filter78it from machines too old to have SpeedStep at all. */79if (cpu.level < 6)80return;8182initregs(&ireg);83ireg.ax = 0xe980; /* IST Support */84ireg.edx = 0x47534943; /* Request value */85intcall(0x15, &ireg, &oreg);8687boot_params.ist_info.signature = oreg.eax;88boot_params.ist_info.command = oreg.ebx;89boot_params.ist_info.event = oreg.ecx;90boot_params.ist_info.perf_level = oreg.edx;91}9293/*94* Tell the BIOS what CPU mode we intend to run in.95*/96static void set_bios_mode(void)97{98#ifdef CONFIG_X86_6499struct biosregs ireg;100101initregs(&ireg);102ireg.ax = 0xec00;103ireg.bx = 2;104intcall(0x15, &ireg, NULL);105#endif106}107108static void init_heap(void)109{110char *stack_end;111112if (boot_params.hdr.loadflags & CAN_USE_HEAP) {113asm("leal %P1(%%esp),%0"114: "=r" (stack_end) : "i" (-STACK_SIZE));115116heap_end = (char *)117((size_t)boot_params.hdr.heap_end_ptr + 0x200);118if (heap_end > stack_end)119heap_end = stack_end;120} else {121/* Boot protocol 2.00 only, no heap available */122puts("WARNING: Ancient bootloader, some functionality "123"may be limited!\n");124}125}126127void main(void)128{129/* First, copy the boot header into the "zeropage" */130copy_boot_params();131132/* Initialize the early-boot console */133console_init();134if (cmdline_find_option_bool("debug"))135puts("early console in setup code\n");136137/* End of heap check */138init_heap();139140/* Make sure we have all the proper CPU support */141if (validate_cpu()) {142puts("Unable to boot - please use a kernel appropriate "143"for your CPU.\n");144die();145}146147/* Tell the BIOS what CPU mode we intend to run in. */148set_bios_mode();149150/* Detect memory layout */151detect_memory();152153/* Set keyboard repeat rate (why?) */154keyboard_set_repeat();155156/* Query MCA information */157query_mca();158159/* Query Intel SpeedStep (IST) information */160query_ist();161162/* Query APM information */163#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)164query_apm_bios();165#endif166167/* Query EDD information */168#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)169query_edd();170#endif171172/* Set the video mode */173set_video();174175/* Do the last things and invoke protected mode */176go_to_protected_mode();177}178179180