root/arch/x86/boot/main.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. copy_boot_params
  2. keyboard_init
  3. query_ist
  4. set_bios_mode
  5. init_heap
  6. main

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* -*- linux-c -*- ------------------------------------------------------- *
   3  *
   4  *   Copyright (C) 1991, 1992 Linus Torvalds
   5  *   Copyright 2007 rPath, Inc. - All Rights Reserved
   6  *   Copyright 2009 Intel Corporation; author H. Peter Anvin
   7  *
   8  * ----------------------------------------------------------------------- */
   9 
  10 /*
  11  * Main module for the real-mode kernel code
  12  */
  13 #include <linux/build_bug.h>
  14 
  15 #include "boot.h"
  16 #include "string.h"
  17 
  18 struct boot_params boot_params __attribute__((aligned(16)));
  19 
  20 char *HEAP = _end;
  21 char *heap_end = _end;          /* Default end of heap = no heap */
  22 
  23 /*
  24  * Copy the header into the boot parameter block.  Since this
  25  * screws up the old-style command line protocol, adjust by
  26  * filling in the new-style command line pointer instead.
  27  */
  28 
  29 static void copy_boot_params(void)
  30 {
  31         struct old_cmdline {
  32                 u16 cl_magic;
  33                 u16 cl_offset;
  34         };
  35         const struct old_cmdline * const oldcmd =
  36                 (const struct old_cmdline *)OLD_CL_ADDRESS;
  37 
  38         BUILD_BUG_ON(sizeof(boot_params) != 4096);
  39         memcpy(&boot_params.hdr, &hdr, sizeof(hdr));
  40 
  41         if (!boot_params.hdr.cmd_line_ptr &&
  42             oldcmd->cl_magic == OLD_CL_MAGIC) {
  43                 /* Old-style command line protocol. */
  44                 u16 cmdline_seg;
  45 
  46                 /* Figure out if the command line falls in the region
  47                    of memory that an old kernel would have copied up
  48                    to 0x90000... */
  49                 if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
  50                         cmdline_seg = ds();
  51                 else
  52                         cmdline_seg = 0x9000;
  53 
  54                 boot_params.hdr.cmd_line_ptr =
  55                         (cmdline_seg << 4) + oldcmd->cl_offset;
  56         }
  57 }
  58 
  59 /*
  60  * Query the keyboard lock status as given by the BIOS, and
  61  * set the keyboard repeat rate to maximum.  Unclear why the latter
  62  * is done here; this might be possible to kill off as stale code.
  63  */
  64 static void keyboard_init(void)
  65 {
  66         struct biosregs ireg, oreg;
  67         initregs(&ireg);
  68 
  69         ireg.ah = 0x02;         /* Get keyboard status */
  70         intcall(0x16, &ireg, &oreg);
  71         boot_params.kbd_status = oreg.al;
  72 
  73         ireg.ax = 0x0305;       /* Set keyboard repeat rate */
  74         intcall(0x16, &ireg, NULL);
  75 }
  76 
  77 /*
  78  * Get Intel SpeedStep (IST) information.
  79  */
  80 static void query_ist(void)
  81 {
  82         struct biosregs ireg, oreg;
  83 
  84         /* Some older BIOSes apparently crash on this call, so filter
  85            it from machines too old to have SpeedStep at all. */
  86         if (cpu.level < 6)
  87                 return;
  88 
  89         initregs(&ireg);
  90         ireg.ax  = 0xe980;       /* IST Support */
  91         ireg.edx = 0x47534943;   /* Request value */
  92         intcall(0x15, &ireg, &oreg);
  93 
  94         boot_params.ist_info.signature  = oreg.eax;
  95         boot_params.ist_info.command    = oreg.ebx;
  96         boot_params.ist_info.event      = oreg.ecx;
  97         boot_params.ist_info.perf_level = oreg.edx;
  98 }
  99 
 100 /*
 101  * Tell the BIOS what CPU mode we intend to run in.
 102  */
 103 static void set_bios_mode(void)
 104 {
 105 #ifdef CONFIG_X86_64
 106         struct biosregs ireg;
 107 
 108         initregs(&ireg);
 109         ireg.ax = 0xec00;
 110         ireg.bx = 2;
 111         intcall(0x15, &ireg, NULL);
 112 #endif
 113 }
 114 
 115 static void init_heap(void)
 116 {
 117         char *stack_end;
 118 
 119         if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
 120                 asm("leal %P1(%%esp),%0"
 121                     : "=r" (stack_end) : "i" (-STACK_SIZE));
 122 
 123                 heap_end = (char *)
 124                         ((size_t)boot_params.hdr.heap_end_ptr + 0x200);
 125                 if (heap_end > stack_end)
 126                         heap_end = stack_end;
 127         } else {
 128                 /* Boot protocol 2.00 only, no heap available */
 129                 puts("WARNING: Ancient bootloader, some functionality "
 130                      "may be limited!\n");
 131         }
 132 }
 133 
 134 void main(void)
 135 {
 136         /* First, copy the boot header into the "zeropage" */
 137         copy_boot_params();
 138 
 139         /* Initialize the early-boot console */
 140         console_init();
 141         if (cmdline_find_option_bool("debug"))
 142                 puts("early console in setup code\n");
 143 
 144         /* End of heap check */
 145         init_heap();
 146 
 147         /* Make sure we have all the proper CPU support */
 148         if (validate_cpu()) {
 149                 puts("Unable to boot - please use a kernel appropriate "
 150                      "for your CPU.\n");
 151                 die();
 152         }
 153 
 154         /* Tell the BIOS what CPU mode we intend to run in. */
 155         set_bios_mode();
 156 
 157         /* Detect memory layout */
 158         detect_memory();
 159 
 160         /* Set keyboard repeat rate (why?) and query the lock flags */
 161         keyboard_init();
 162 
 163         /* Query Intel SpeedStep (IST) information */
 164         query_ist();
 165 
 166         /* Query APM information */
 167 #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
 168         query_apm_bios();
 169 #endif
 170 
 171         /* Query EDD information */
 172 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
 173         query_edd();
 174 #endif
 175 
 176         /* Set the video mode */
 177         set_video();
 178 
 179         /* Do the last things and invoke protected mode */
 180         go_to_protected_mode();
 181 }

/* [<][>][^][v][top][bottom][index][help] */