bsps/amd64: add a new EFI-based variant of AMD64 BSP

The new amd64efi BSP supports:
- multiboot2 boot format. Runs well with GRUB.
- console based on either EFI simple text output or GOP-based framebuffer
- clock based on EFI event/timer API
- early console using either hard-wired PC-AT serial or just memory buffer
- with EFI support disabled the BSP is more or less equivalent to amd64 BSP
  with multiboot2 support
This commit is contained in:
Karel Gardas committed 2023-04-29 20:41:23 +02:00
1 parent 1590df5f9a
commit bf53ff2de2
27 files changed
+7253 -5

No files matched your search

+109
View File
@@ -0,0 +1,109 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2023 Karel Gardas
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bsp.h>
#include <efi.h>
#include <stdio.h>
extern EFI_BOOT_SERVICES *BS;
static EFI_EVENT clock_event = 0;
extern void
Clock_isr( void* );
#ifndef EFIAPI
#error "EFIAPI not defined!"
#endif
/* no-sse attribute helps with enforcing GCC to generate code which does not use
SSE instructions requiring 16 byte alligned access on unaligned data hence
producing perfect GP fault. The code with SSE enabled looks:
EFIAPI void
efi_clock_tick_notify(EFI_EVENT e, VOID* ctx)
{
10b2ba: 55 push rbp
10b2bb: 48 89 e5 mov rbp,rsp
10b2be: 57 push rdi
10b2bf: 56 push rsi
10b2c0: 48 81 ec a0 00 00 00 sub rsp,0xa0
10b2c7: 8b 02 mov eax,DWORD PTR [rdx]
->10b2c9: 0f 29 b5 50 ff ff ff movaps XMMWORD PTR [rbp-0xb0],xmm6
10b2d0: 0f 29 bd 60 ff ff ff movaps XMMWORD PTR [rbp-0xa0],xmm7
10b2d7: 83 c0 01 add eax,0x1
and we get GP @ 10b2c9.
CAVEAT: This function is to be called from the UEFI which means it needs to callable
by using MS ABI!
*/
__attribute__((target("no-sse")))
EFIAPI void
efi_clock_tick_notify(EFI_EVENT e, VOID* ctx);
__attribute__((target("no-sse")))
EFIAPI void
efi_clock_tick_notify(EFI_EVENT e, VOID* ctx)
{
Clock_isr(NULL);
}
static void
efi_clock_initialize( void )
{
EFI_STATUS status = BS->CreateEvent
(EVT_TIMER | EVT_NOTIFY_SIGNAL,
TPL_CALLBACK, (EFI_EVENT_NOTIFY)efi_clock_tick_notify,
(VOID*)NULL, &clock_event);
if (EFI_ERROR(status)) {
printf("EFI: error while creating event in clock initialization!\n");
}
else {
printf("EFI: clock event created.\n");
/* set periodic timer to signal Clock_isr every 10 milisecond. Value provided
here is following UEFI spec in hundred of nanoseconds. */
status = BS->SetTimer(clock_event, TimerPeriodic, (10 * 1000 * 10));
if (EFI_ERROR(status)) {
printf("EFI: error while creating timer in clock initialization!\n");
BS->CloseEvent(clock_event);
}
else {
printf("EFI: timer for clock event is set.\n");
}
}
}
#define Clock_driver_support_initialize_hardware() efi_clock_initialize()
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
/* Include shared source clock driver code */
#include "../../shared/dev/clock/clockimpl.h"
+9 -2
View File
@@ -30,6 +30,9 @@
#include <bsp/console-termios.h>
#include <rtems/score/cpuimpl.h>
void
uart0_output_char(char);
static uint8_t amd64_uart_get_register(uintptr_t addr, uint8_t i)
{
return inport_byte(addr + i);
@@ -61,12 +64,16 @@ const console_device console_device_table[] = {
};
const size_t console_device_count = RTEMS_ARRAY_SIZE(console_device_table);
static void output_char(char c)
void uart0_output_char(char c)
{
rtems_termios_device_context *ctx = console_device_table[0].context;
ns16550_polled_putchar(ctx, c);
}
BSP_output_char_function_type BSP_output_char = output_char;
#ifndef BSP_USE_EFI_BOOT_SERVICES
BSP_output_char_function_type BSP_output_char = uart0_output_char;
BSP_polling_getchar_function_type BSP_poll_char = NULL;
#endif
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+107
View File
@@ -0,0 +1,107 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2023 Karel Gardas
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bsp.h>
#include <efi.h>
#include <efilib.h>
#include <rtems/bspIo.h>
#include <efistop.h>
#include <stdio.h>
#include <string.h>
#ifdef BSP_USE_EFI_BOOT_SERVICES
static void
print_stop_info(SIMPLE_TEXT_OUTPUT_INTERFACE* stop);
void
efi_init_text_output(int hint)
{
int maxval = ST->ConOut->Mode->MaxMode - 1;
int curval = ST->ConOut->Mode->Mode;
ST->ConOut->Reset(ST->ConOut, true);
if (hint != -1) {
/* hint got from command-line does have highest priority */
ST->ConOut->SetMode(ST->ConOut, hint);
}
else if (strcmp(BSP_EFI_SIMPLE_TEXT_OUTPUT_MODE_VALUE, "MAX") == 0) {
ST->ConOut->SetMode(ST->ConOut, maxval);
}
else if (strcmp(BSP_EFI_SIMPLE_TEXT_OUTPUT_MODE_VALUE, "AUTO") == 0) {
ST->ConOut->SetMode(ST->ConOut, curval);
}
else {
ST->ConOut->SetMode(ST->ConOut, atoi(BSP_EFI_SIMPLE_TEXT_OUTPUT_MODE_VALUE));
}
ST->ConOut->EnableCursor(ST->ConOut, TRUE);
print_stop_info(ST->ConOut);
ST->ConOut->ClearScreen(ST->ConOut);
}
void
efi_text_output_char(char c)
{
EFI_STATUS status;
char tocpy[2];
tocpy[0] = c;
tocpy[1] = 0;
CHAR16 str[2];
cpy8to16(tocpy, str, 2);
status = ST->ConOut->TestString(ST->ConOut, str);
if (EFI_ERROR(status))
str[0] = '?';
ST->ConOut->OutputString(ST->ConOut, str);
}
static void
print_stop_info(SIMPLE_TEXT_OUTPUT_INTERFACE* stop)
{
EFI_STATUS status;
int max_mode = stop->Mode->MaxMode;
int current_mode = stop->Mode->Mode;
printf("RTEMS: text output: current mode: %d, max mode: %d\n", current_mode, (max_mode - 1));
UINTN columns = 0;
UINTN rows = 0;
for (int i = 0; i < max_mode; i++) {
if (current_mode == i)
printf(" -> ");
else
printf(" ");
status = stop->QueryMode(stop, i, &columns, &rows);
if (EFI_ERROR(status))
printf("%d. mode: error: can't obtain column x row values.\n", i);
else {
printf("%d. mode: %ld * %ld\n", i, columns, rows);
}
}
}
#endif
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+46
View File
@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2023 Karel Gardas
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <efi.h>
#include <rtems/fb.h>
int
efi_init_graphic_output(int);
void
efi_graphic_output_char(char);
/* to support RPi based character output to framebuffer.
The functions are declared here in open in order to show if they
should not be moved including whole character output to FB somewhere
into bsps/shared. */
void
rpi_get_var_screen_info(struct fb_var_screeninfo*);
void
rpi_get_fix_screen_info(struct fb_fix_screeninfo*);
+35
View File
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2023 Karel Gardas
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <efi.h>
void
efi_init_text_output(int);
void
efi_text_output_char(char);
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,38 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2023 Karel Gardas
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
void
process_multiboot2_info(void);
int
uefi_bootservices_running(void);
const char*
boot_args(void);
int
get_boot_arg_int_value(const char*, const char*, int*);
+14 -2
View File
@@ -28,9 +28,21 @@
#include <bsp/bootcard.h>
#include <libcpu/page.h>
#include <bsp/irq-generic.h>
#include <multiboot2impl.h>
#if defined(BSP_USE_EFI_BOOT_SERVICES) && !defined(BSP_MULTIBOOT_SUPPORT)
#error "RTEMS amd64efi BSP requires multiboot2 support!"
#endif
void bsp_start(void)
{
paging_init();
bsp_interrupt_initialize();
#ifdef BSP_MULTIBOOT_SUPPORT
process_multiboot2_info();
if (!uefi_bootservices_running()) {
#endif
paging_init();
bsp_interrupt_initialize();
#ifdef BSP_MULTIBOOT_SUPPORT
}
#endif
}
File diff suppressed because it is too large. Load diff
+5 -1
View File
@@ -28,13 +28,15 @@ RamBase = DEFINED(RamBase) ? RamBase :
/* XXX: Defaulting to 1GiB.
*/
RamSize = DEFINED(RamSize) ? RamSize :
DEFINED(_RamSize) ? _RamSize : 0x40000000;
/* DEFINED(_RamSize) ? _RamSize : 0x2000000;*/ /* 32MB */
DEFINED(_RamSize) ? _RamSize : 0x1000000; /* 16MB */
RamEnd = RamBase + RamSize;
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x00100000)); . = SEGMENT_START("text-segment", 0x00100000) + SIZEOF_HEADERS;
/* .multiboot2_header : { *(.multiboot2_header) }*/
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
@@ -88,6 +90,7 @@ SECTIONS
.plt.sec : { *(.plt.sec) }
.text :
{
KEEP (*(.multiboot2_header))
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
@@ -236,6 +239,7 @@ SECTIONS
{
*(SORT_BY_NAME (SORT_BY_ALIGNMENT (.noinit*)))
}
. = ALIGN(64);
.rtemsstack (NOLOAD) :
{
*(SORT(.rtemsstack.*))
+174
View File
@@ -0,0 +1,174 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2023 Karel Gardas
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bsp.h>
#include <inttypes.h>
#include <multiboot2.h>
#include <multiboot2impl.h>
#include <rtems/score/heap.h>
#include <efi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef BSP_MULTIBOOT_SUPPORT
#ifdef BSP_USE_EFI_BOOT_SERVICES
extern void
efi_console_initialize( void );
extern void
efi_memory_heap_extend(void);
extern EFI_HANDLE IH;
extern EFI_SYSTEM_TABLE *ST;
extern EFI_BOOT_SERVICES *BS;
extern EFI_RUNTIME_SERVICES *RS;
#endif
extern int _multiboot2_magic;
extern void* _multiboot2_info_ptr;
static int already_processed = 0;
#endif
static int bootservices_running = 0;
static char multiboot_boot_args[256];
extern Heap_Control *RTEMS_Malloc_Heap;
#ifdef BSP_MULTIBOOT_SUPPORT
void
process_multiboot2_info()
{
struct multiboot_tag *tag;
unsigned size;
#ifdef BSP_USE_EFI_BOOT_SERVICES
ST = 0;
RS = 0;
BS = 0;
#endif
if (already_processed)
return;
if (_multiboot2_magic == MULTIBOOT2_BOOTLOADER_MAGIC) {
if ((*(unsigned*)_multiboot2_info_ptr) & 7) {
printf("Multiboot2 info @ %p, unaligned mbi: 0x%x\n", _multiboot2_info_ptr, *(unsigned*)_multiboot2_info_ptr);
}
else {
size = *(unsigned*)_multiboot2_info_ptr;
printf("Multiboot2 info @ %p, size 0x%x\n", _multiboot2_info_ptr, size);
for (tag = (struct multiboot_tag *) (_multiboot2_info_ptr + 8);
tag->type != MULTIBOOT_TAG_TYPE_END;
tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + ((tag->size + 7) & ~7))) {
switch (tag->type) {
case MULTIBOOT_TAG_TYPE_CMDLINE:
printf("Multiboot2 booting arguments: `%s', args len: %d\n",
((struct multiboot_tag_string *) tag)->string,
((struct multiboot_tag_string *) tag)->size);
strncpy(multiboot_boot_args, ((struct multiboot_tag_string*)tag)->string, ((struct multiboot_tag_string*)tag)->size);
break;
case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
printf("Multiboot2 loader name: `%s'\n", ((struct multiboot_tag_string *) tag)->string);
break;
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
struct multiboot_tag_framebuffer* fbtag = (struct multiboot_tag_framebuffer*)tag;
uint64_t fbbase = fbtag->common.framebuffer_addr;
printf("Multiboot2 framebuffer @ %p, resolution: %dx%d, pitch/bpp: %d/%d, type: %d\n",
(void*)fbbase, fbtag->common.framebuffer_width, fbtag->common.framebuffer_height,
fbtag->common.framebuffer_pitch, fbtag->common.framebuffer_bpp,
fbtag->common.framebuffer_type);
break;
#ifdef BSP_USE_EFI_BOOT_SERVICES
case MULTIBOOT_TAG_TYPE_EFI64:
printf("EFI64 system table @ 0x%llx\n", ((struct multiboot_tag_efi64 *) tag)->pointer);
ST = ((EFI_SYSTEM_TABLE*)((struct multiboot_tag_efi64 *) tag)->pointer);
BS = ST->BootServices;
RS = ST->RuntimeServices;
efi_console_initialize();
efi_memory_heap_extend();
break;
case MULTIBOOT_TAG_TYPE_EFI_BS:
printf("GRUB: EFI boot services running.\n");
bootservices_running = 1;
break;
case MULTIBOOT_TAG_TYPE_EFI64_IH:
printf("EFI: 64bit image handle: 0x%llx\n", ((struct multiboot_tag_efi64_ih *) tag)->pointer);
IH = (EFI_HANDLE)((struct multiboot_tag_efi64_ih *) tag)->pointer;
break;
#endif
}
}
}
}
else {
printf("So while not being booted by multiboot2, let's see what's in its magic then?: %dx\n", _multiboot2_magic);
}
}
#endif /* BSP_MULTIBOOT_SUPPORT */
int
uefi_bootservices_running()
{
return bootservices_running;
}
const char*
boot_args()
{
return multiboot_boot_args;
}
int
get_boot_arg_int_value(const char* boot_args, const char* arg, int* val)
{
int len_arg = strlen(arg);
int len_try = strlen(boot_args) - len_arg;
int len_bootargs = strlen(boot_args);
char num[10];
for (int i = 0; i < len_try; i++) {
if (strncmp(&(boot_args[i]), arg, len_arg) == 0) {
i = i + len_arg + 1;
for (int j = 0; j < 10; j++) {
if (boot_args[i + j] != ' ' && i + j < len_bootargs)
num[j] = boot_args[i + j];
else {
num[j] = 0;
*val = atoi(num);
return 0;
}
}
}
}
return -1;
}
+72
View File
@@ -1,6 +1,7 @@
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2023 Karel Gardas
* Copyright (C) 2018 embedded brains GmbH
*
* Redistribution and use in source and binary forms, with or without
@@ -25,6 +26,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <bspopts.h>
#ifdef BSP_MULTIBOOT_SUPPORT
#include <multiboot2.h>
#endif
.text
.section .text._start,"ax",@progbits
.p2align 4,,15
@@ -36,6 +43,71 @@ _start:
subq $8, %rsp
.cfi_def_cfa_offset 16
xorl %edi, %edi
#ifdef BSP_MULTIBOOT_SUPPORT
mov %eax, _multiboot2_magic
mov %rbx, _multiboot2_info_ptr
#endif
movabsq $boot_card, %rax
call *%rax
.cfi_endproc
#ifdef BSP_MULTIBOOT_SUPPORT
multiboot2:
ret
_multiboot2_start:
jmp _start
.text
.section .multiboot2_header
.p2align 4,,15
multiboot2_header_start:
.long MULTIBOOT2_HEADER_MAGIC
.long MULTIBOOT_ARCHITECTURE_I386
.long multiboot2_header_end - multiboot2_header_start
.long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot2_header_end - multiboot2_header_start))
efi_bootservices_start:
.short MULTIBOOT_HEADER_TAG_EFI_BS
.short 0
.long efi_bootservices_end - efi_bootservices_start
efi_bootservices_end:
efi64_entry_start:
.short MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64
.short 0
.long efi64_entry_end - efi64_entry_start
.long _start /* directly copied from resulting ELF */
/* padding to 8 byte tags allignment */
.long 0
efi64_entry_end:
info_requests_start:
.short MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST
.short 0
.long info_requests_end - info_requests_start
.long MULTIBOOT_TAG_TYPE_EFI64
.long MULTIBOOT_TAG_TYPE_CMDLINE
#ifdef BSP_USE_EFI_BOOT_SERVICES
.long MULTIBOOT_TAG_TYPE_EFI_BS
#else
.long 0
#endif
/* padding to 8 byte tags allignment */
.long 0
info_requests_end:
/* header end*/
.short MULTIBOOT_HEADER_TAG_END
.short 0
.long 8
multiboot2_header_end:
.data
.global _multiboot2_magic
_multiboot2_magic:
.long 0
.data
.global _multiboot2_info_ptr
_multiboot2_info_ptr:
.quad 0
#endif
+17
View File
@@ -0,0 +1,17 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
build-type: objects
cflags: []
copyrights:
- Copyright (C) 2023 Karel Gardas
cppflags: []
cxxflags: []
enabled-by: true
includes:
- bsps/shared/freebsd/stand/efi/include
- bsps/shared/freebsd/stand/efi/include/amd64
install: []
links: []
source:
- bsps/shared/freebsd/stand/efi/libefi/libefi.c
- bsps/shared/freebsd/stand/efi/libefi/wchar.c
type: build
+18
View File
@@ -0,0 +1,18 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-boolean: null
- env-assign: null
- define-condition: null
build-type: option
copyrights:
- Copyright (C) 2023 Karel Gardas
default:
- enabled-by: true
value: true
description: |
Enable use of EFI boot services.
enabled-by: true
format: '{}'
links: []
name: BSP_USE_EFI_BOOT_SERVICES
type: build
+29
View File
@@ -0,0 +1,29 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-string: null
- define: null
- script: |
kinds = ["TEXT", "GRAPHIC", "BOTH", "AUTO"]
if value not in kinds:
conf.fatal("Preferred EFI console '{}' is not one of {}".format(value, kinds))
build-type: option
copyrights:
- Copyright (C) 2023 Karel Gardas
default:
- enabled-by: true
value: AUTO
description: |
Select preferred EFI console. Possible values are TEXT, GRAPHIC, BOTH and AUTO. The TEXT here will instruct RTEMS to use EFI simple text output protocol. By default
EFI also forwards such text output to configured serial port. Details depends on the target platform EFI configuration.
The GRAPHIC instructs RTEMS to use EFI graphics output protocol. Advantage of it
in comparison with TEXT is that it is available also in the time when boot services
are already finished. BOTH tells RTEMS to mirror its output to both TEXT and GRAPHIC. This only
applies to platforms where both options are supported. The option which is not supported
on target platform is ignored in the RTEMS runtime and only available option is used. Finally AUTO tells RTEMS to use output console
preferred by the target platform configuration. In case RTEMS is not able to retrieve EFI console control protocol interface, then BOTH
is used instead of AUTO.
enabled-by: true
format: '{}'
links: []
name: BSP_EFI_CONSOLE_KIND
type: build
+27
View File
@@ -0,0 +1,27 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-string: null
- script: |
kinds = ["SERIAL", "BUFFER"]
if value not in kinds:
conf.fatal("Preferred EFI early console '{}' is not one of {}".format(value, kinds))
conf.define("BUFFER", "1", False)
conf.define("SERIAL", "2", False)
- define-unquoted: null
build-type: option
copyrights:
- Copyright (C) 2023 Karel Gardas
default:
- enabled-by: true
value: BUFFER
description: |
Select preferred EFI early printout console. Possible values here
are SERIAL and BUFFER. In case of SERIAL, the tty0/com1 will be used
for early printout. In case of BUFFER, all prints will be buffered
and once real EFI console is initialized, then whole buffer will be
copied to it.
enabled-by: true
format: '{}'
links: []
name: BSP_EFI_EARLY_CONSOLE_KIND
type: build
+20
View File
@@ -0,0 +1,20 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-string: null
- define: null
build-type: option
copyrights:
- Copyright (C) 2023 Karel Gardas
default:
- enabled-by: true
value: AUTO
description: |
Define EFI graphics output protocol mode value. Use MAX to select maximum
available mode or AUTO to allow automatic selection based on the platform
preference. Otherwise use positive integer number to select desired graphics
protocol mode which you can get from graphics protocol mode list.
enabled-by: true
format: '{}'
links: []
name: BSP_EFI_GRAPHICS_OUTPUT_MODE_VALUE
type: build
+18
View File
@@ -0,0 +1,18 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-boolean: null
- env-assign: null
- define-condition: null
build-type: option
copyrights:
- Copyright (C) 2023 Karel Gardas
default:
- enabled-by: true
value: false
description: |
Print EFI memory map on boot.
enabled-by: true
format: '{}'
links: []
name: BSP_EFI_MMAP_PRINTOUT
type: build
+21
View File
@@ -0,0 +1,21 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-string: null
- define: null
build-type: option
copyrights:
- Copyright (C) 2023 Karel Gardas
default:
- enabled-by: true
value: AUTO
description: |
Define EFI simple text output protocol mode value. Use MAX to select maximum
available mode or AUTO to allow automatic selection based on the platform
preference. Otherwise use positive integer number to select desired simple
text output protocol mode which you can get from simple text protocol mode
list.
enabled-by: true
format: '{}'
links: []
name: BSP_EFI_SIMPLE_TEXT_OUTPUT_MODE_VALUE
type: build
+18
View File
@@ -0,0 +1,18 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-boolean: null
- env-assign: null
- define-condition: null
build-type: option
copyrights:
- Copyright (C) 2023 Karel Gardas
default:
- enabled-by: true
value: true
description: |
Enable multiboot2 support in the startup assembly.
enabled-by: true
format: '{}'
links: []
name: BSP_MULTIBOOT_SUPPORT
type: build
@@ -0,0 +1,84 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
arch: x86_64
bsp: amd64efi
build-type: bsp
cflags: []
copyrights:
- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
cppflags: []
enabled-by: true
family: amd64
includes:
- bsps/shared/freebsd/stand/efi/include
- bsps/shared/freebsd/stand/efi/include/amd64
install:
- destination: ${BSP_INCLUDEDIR}
source:
- bsps/x86_64/amd64/include/apic.h
- bsps/x86_64/amd64/include/bsp.h
- bsps/x86_64/amd64/include/clock.h
- bsps/x86_64/amd64/include/pic.h
- bsps/x86_64/amd64/include/start.h
- destination: ${BSP_LIBDIR}
source:
- bsps/x86_64/amd64/start/linkcmds
links:
- role: build-dependency
uid: ../../obj
- role: build-dependency
uid: ../../objirq
- role: build-dependency
uid: ../../objmem
- role: build-dependency
uid: ../../opto2
- role: build-dependency
uid: efiabi
- role: build-dependency
uid: start
- role: build-dependency
uid: ../grp
- role: build-dependency
uid: ../../optmultiboot
- role: build-dependency
uid: ../../opteficonsole
- role: build-dependency
uid: ../../optefiearlyconsole
- role: build-dependency
uid: ../../optefistom
- role: build-dependency
uid: ../../optefigopm
- role: build-dependency
uid: ../../optefimmapprint
- role: build-dependency
uid: ../../optefibs
- role: build-dependency
uid: ../../bspopts
- role: build-dependency
uid: optldpagesize
- role: build-dependency
uid: ../../objefi
source:
- bsps/shared/cache/nocache.c
- bsps/shared/dev/btimer/btimer-cpucounter.c
- bsps/shared/dev/getentropy/getentropy-cpucounter.c
- bsps/shared/dev/serial/console-termios-init.c
- bsps/shared/dev/serial/console-termios.c
- bsps/shared/irq/irq-default-handler.c
- bsps/shared/start/bspfatal-default.c
- bsps/shared/start/bspreset-empty.c
- bsps/shared/start/gettargethash-default.c
- bsps/shared/start/sbrk.c
- bsps/x86_64/amd64/clock/eficlock.c
- bsps/x86_64/amd64/console/eficonsole.c
- bsps/x86_64/amd64/console/efistop.c
- bsps/x86_64/amd64/console/efigop.c
- bsps/x86_64/amd64/console/outch.c
- bsps/x86_64/amd64/console/console.c
- bsps/x86_64/amd64/interrupts/idt.c
- bsps/x86_64/amd64/interrupts/isr_handler.S
- bsps/x86_64/amd64/interrupts/pic.c
- bsps/x86_64/amd64/start/bspstart.c
- bsps/x86_64/amd64/start/multiboot2.c
- bsps/x86_64/amd64/start/efimem.c
- bsps/x86_64/amd64/start/page.c
type: build
+23
View File
@@ -0,0 +1,23 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-string: null
- split: null
- env-append: null
build-type: option
copyrights:
- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
default:
- enabled-by: true
value:
- -fshort-wchar
- -maccumulate-outgoing-args
- -fno-stack-protector
- -fno-stack-check
- -mno-red-zone
- -mcmodel=large
description: |
ABI flags
enabled-by: true
links: []
name: ABI_FLAGS
type: build
@@ -0,0 +1,25 @@
SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
actions:
- get-integer: null
- assert-uint32: null
- env-assign: null
- set-value: -Wl,-z,max-page-size=${LD_MAX_PAGE_SIZE:#010x}
- substitute: null
- env-append: LDFLAGS
- env-append: PKGCONFIG_LDFLAGS
build-type: option
copyrights:
- Copyright (C) 2023 Karel Gardas
default:
- enabled-by: true
value: 4096
description: |
Set the value of max-page-size parameter for the GNU linker.
By default on x86_64 the linker is using 2MB page size which is
too big for creating correctly formed and later recognized multiboot2
binaries. Default value 4k used here is working well for the purpose.
enabled-by: true
format: '{:#010x}'
links: []
name: LD_MAX_PAGE_SIZE
type: build