Move boot_params definitions into separate header file.

This commit is contained in:
Martin Whitaker 2020-06-29 12:09:13 +01:00
parent 955886b48e
commit 9492c086fe
4 changed files with 113 additions and 102 deletions

100
boot/bootparams.h Normal file
View File

@ -0,0 +1,100 @@
// SPDX-License-Identifier: GPL-2.0
#ifndef BOOTPARAMS_H
#define BOOTPARAMS_H
/*
* Provides definitions for the boot params structure passed to us by
* intermediate bootloaders when using the Linux boot protocol. This matches
* the Linux boot_params struct, although we only define the fields we are
* interested in.
*
* Copyright (C) 2020 Martin Whitaker.
*/
#include <stdint.h>
typedef struct {
uint8_t orig_x;
uint8_t orig_y;
uint16_t ext_mem_k;
uint16_t orig_video_page;
uint8_t orig_video_mode;
uint8_t orig_video_cols;
uint8_t flags;
uint8_t unused2;
uint16_t orig_video_ega_bx;
uint16_t unused3;
uint8_t orig_video_lines;
uint8_t orig_video_isVGA;
uint16_t orig_video_points;
uint16_t lfb_width;
uint16_t lfb_height;
uint16_t lfb_depth;
uint32_t lfb_base;
uint32_t lfb_size;
uint16_t cl_magic, cl_offset;
uint16_t lfb_linelength;
uint8_t red_size;
uint8_t red_pos;
uint8_t green_size;
uint8_t green_pos;
uint8_t blue_size;
uint8_t blue_pos;
uint8_t rsvd_size;
uint8_t rsvd_pos;
uint16_t vesapm_seg;
uint16_t vesapm_off;
uint16_t pages;
uint16_t vesa_attributes;
uint32_t capabilities;
uint32_t ext_lfb_base;
uint8_t _reserved[2];
} __attribute__((packed)) screen_info_t;
#define VIDEO_TYPE_VLFB 0x23 // VESA VGA in graphic mode
#define VIDEO_TYPE_EFI 0x70 // EFI graphic mode
#define LFB_CAPABILITY_64BIT_BASE (1 << 1)
typedef struct {
uint32_t loader_signature;
uint32_t sys_tab;
uint32_t mem_desc_size;
uint32_t mem_desc_version;
uint32_t mem_map;
uint32_t mem_map_size;
uint32_t sys_tab_hi;
uint32_t mem_map_hi;
} __attribute__((packed)) efi_info_t;
#define EFI32_LOADER_SIGNATURE ('E' | ('L' << 8) | ('3' << 16) | ('2' << 24))
#define EFI64_LOADER_SIGNATURE ('E' | ('L' << 8) | ('6' << 16) | ('4' << 24))
typedef enum {
E820_NONE = 0,
E820_RAM = 1,
E820_RESERVED = 2,
E820_ACPI = 3, // usable as RAM once ACPI tables have been read
E820_NVS = 4
} e820_type_t;
typedef struct {
uint64_t addr;
uint64_t size;
uint32_t type;
} __attribute__((packed)) e820_entry_t;
typedef struct {
screen_info_t screen_info;
uint8_t unused1[0x1c0 - 0x040];
efi_info_t efi_info;
uint8_t unused2[0x1e8 - 0x1e0];
uint8_t e820_entries;
uint8_t unused3[0x214 - 0x1e9];
uint32_t code32_start;
uint8_t unused4[0x2d0 - 0x218];
e820_entry_t e820_map[E820_MAP_SIZE];
uint8_t unused5[0xeec - 0xd00];
} __attribute__((packed)) boot_params_t;
#endif /* BOOTPARAMS_H */

View File

@ -12,6 +12,7 @@
#include <stdint.h>
#include "boot.h"
#include "bootparams.h"
#include "memsize.h"
@ -28,28 +29,6 @@
#define RES_START 0x0a0000
#define RES_END 0x100000
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// The following definition must match the Linux e820_type enum.
typedef enum {
E820_NONE = 0,
E820_RAM = 1,
E820_RESERVED = 2,
E820_ACPI = 3, // usable as RAM once ACPI tables have been read
E820_NVS = 4
} e820_type_t;
// The following definition must match the Linux e820_entry struct.
typedef struct {
uint64_t addr;
uint64_t size;
uint32_t type;
} __attribute__((packed)) e820_entry_t;
//------------------------------------------------------------------------------
// Public Variables
//------------------------------------------------------------------------------
@ -277,12 +256,10 @@ void pmem_init(void)
e820_entry_t sanitized_map[E820_MAP_SIZE];
num_pm_pages = 0;
const e820_entry_t *e820_map = (e820_entry_t *)(boot_params_addr + E820_MAP);
int e820_entries = *(uint8_t *)(boot_params_addr + E820_ENTRIES);
const boot_params_t *boot_params = (boot_params_t *)boot_params_addr;
int sanitized_entries = sanitize_e820_map(sanitized_map, e820_map, e820_entries);
int sanitized_entries = sanitize_e820_map(sanitized_map, boot_params->e820_map, boot_params->e820_entries);
init_pm_map(sanitized_map, sanitized_entries);
sort_pm_map();

View File

@ -5,70 +5,17 @@
#include <stdint.h>
#include "boot.h"
#include "bootparams.h"
#include "font.h"
#include "vmem.h"
#include "screen.h"
//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------
// screen_info.orig_video_isVGA values.
#define VIDEO_TYPE_VLFB 0x23 // VESA VGA in graphic mode
#define VIDEO_TYPE_EFI 0x70 // EFI graphic mode
// screen_info.capabilities values.
#define LFB_CAPABILITY_64BIT_BASE (1 << 1)
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// The following definition must match the Linux screen_info struct.
typedef struct {
uint8_t orig_x;
uint8_t orig_y;
uint16_t ext_mem_k;
uint16_t orig_video_page;
uint8_t orig_video_mode;
uint8_t orig_video_cols;
uint8_t flags;
uint8_t unused2;
uint16_t orig_video_ega_bx;
uint16_t unused3;
uint8_t orig_video_lines;
uint8_t orig_video_isVGA;
uint16_t orig_video_points;
uint16_t lfb_width;
uint16_t lfb_height;
uint16_t lfb_depth;
uint32_t lfb_base;
uint32_t lfb_size;
uint16_t cl_magic, cl_offset;
uint16_t lfb_linelength;
uint8_t red_size;
uint8_t red_pos;
uint8_t green_size;
uint8_t green_pos;
uint8_t blue_size;
uint8_t blue_pos;
uint8_t rsvd_size;
uint8_t rsvd_pos;
uint16_t vesapm_seg;
uint16_t vesapm_off;
uint16_t pages;
uint16_t vesa_attributes;
uint32_t capabilities;
uint32_t ext_lfb_base;
uint8_t _reserved[2];
} __attribute__((packed)) screen_info_t;
typedef struct {
uint8_t r;
uint8_t g;
@ -206,7 +153,9 @@ static void put_value(int row, int col, uint16_t value)
void screen_init(void)
{
const screen_info_t *screen_info = (screen_info_t *)boot_params_addr;
const boot_params_t *boot_params = (boot_params_t *)boot_params_addr;
const screen_info_t *screen_info = &boot_params->screen_info;
bool use_lfb = screen_info->orig_video_isVGA == VIDEO_TYPE_VLFB
|| screen_info->orig_video_isVGA == VIDEO_TYPE_EFI;

View File

@ -16,6 +16,7 @@
#include <stdint.h>
#include "boot.h"
#include "bootparams.h"
#include "memsize.h"
#include "pmem.h"
@ -113,11 +114,6 @@
#define MADT_PF_ENABLED 0x1
#define MADT_PF_ONLINE_CAPABLE 0x2
// Linux EFI loader signatures
#define EL32Signature ('E' | ('L' << 8) | ('3' << 16) | ('2' << 24))
#define EL64Signature ('E' | ('L' << 8) | ('6' << 16) | ('4' << 24))
// Private memory heap used for AP trampoline and synchronisation objects
#define HEAP_BASE_ADDR (smp_page << PAGE_SHIFT)
@ -288,19 +284,6 @@ typedef struct {
uint64_t table;
} efi64_config_table_t;
// The following definition must match the Linux efi_info struct.
typedef struct {
uint32_t loader_signature;
uint32_t sys_tab;
uint32_t mem_desc_size;
uint32_t mem_desc_version;
uint32_t mem_map;
uint32_t mem_map_size;
uint32_t sys_tab_hi;
uint32_t mem_map_hi;
} efi_info_t;
//------------------------------------------------------------------------------
// Private Variables
//------------------------------------------------------------------------------
@ -574,16 +557,18 @@ static rsdp_t *find_rsdp_in_efi64_system_table(efi64_system_table_t *system_tabl
static bool find_cpus_in_rsdp(void)
{
efi_info_t *efi_info = (efi_info_t *)(boot_params_addr + 0x1c0);
const boot_params_t *boot_params = (boot_params_t *)boot_params_addr;
const efi_info_t *efi_info = &boot_params->efi_info;
// Search for the RSDP
rsdp_t *rp = NULL;
if (efi_info->loader_signature == EL32Signature) {
if (efi_info->loader_signature == EFI32_LOADER_SIGNATURE) {
uintptr_t system_table_addr = (uintptr_t)efi_info->sys_tab;
rp = find_rsdp_in_efi32_system_table((efi32_system_table_t *)system_table_addr);
}
#ifdef __x86_64__
if (efi_info->loader_signature == EL64Signature) {
if (efi_info->loader_signature == EFI64_LOADER_SIGNATURE) {
uintptr_t system_table_addr = (uintptr_t)efi_info->sys_tab_hi << 32 | (uintptr_t)efi_info->sys_tab;
rp = find_rsdp_in_efi64_system_table((efi64_system_table_t *)system_table_addr);
}