Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:10

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsX8664AMD64EFI
0007  *
0008  * @brief Multiboot2 support routines
0009  */
0010 
0011 /*
0012  * Copyright (C) 2023 Karel Gardas
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #include <acpi/acpi.h>
0037 #include <bsp.h>
0038 #include <inttypes.h>
0039 #include <multiboot2.h>
0040 #include <multiboot2impl.h>
0041 
0042 #include <rtems/score/heap.h>
0043 
0044 #include <efi.h>
0045 
0046 #include <stdio.h>
0047 #include <stdlib.h>
0048 #include <string.h>
0049 
0050 #ifdef BSP_MULTIBOOT_SUPPORT
0051 #ifdef BSP_USE_EFI_BOOT_SERVICES
0052 
0053 extern void
0054 efi_console_initialize( void );
0055 
0056 extern void
0057 efi_memory_heap_extend(void);
0058 
0059 
0060 extern EFI_HANDLE               IH;
0061 extern EFI_SYSTEM_TABLE         *ST;
0062 extern EFI_BOOT_SERVICES        *BS;
0063 extern EFI_RUNTIME_SERVICES     *RS;
0064 #endif
0065 extern int _multiboot2_magic;
0066 extern void* _multiboot2_info_ptr;
0067 static int already_processed = 0;
0068 #endif
0069 
0070 static int bootservices_running = 0;
0071 
0072 static char multiboot_boot_args[256];
0073 
0074 extern Heap_Control *RTEMS_Malloc_Heap;
0075 
0076 #ifdef BSP_MULTIBOOT_SUPPORT
0077 
0078 void
0079 process_multiboot2_info()
0080 {
0081     struct multiboot_tag *tag;
0082     unsigned size;
0083 
0084 #ifdef BSP_USE_EFI_BOOT_SERVICES
0085     ST = 0;
0086     RS = 0;
0087     BS = 0;
0088 #endif
0089     if (already_processed)
0090         return;
0091     if (_multiboot2_magic == MULTIBOOT2_BOOTLOADER_MAGIC) {
0092         if ((*(unsigned*)_multiboot2_info_ptr) & 7) {
0093             printf("Multiboot2 info @ %p, unaligned mbi: 0x%x\n", _multiboot2_info_ptr, *(unsigned*)_multiboot2_info_ptr);
0094         }
0095         else {
0096             size = *(unsigned*)_multiboot2_info_ptr;
0097             printf("Multiboot2 info @ %p, size 0x%x\n", _multiboot2_info_ptr, size);
0098             for (tag = (struct multiboot_tag *) (_multiboot2_info_ptr + 8);
0099                  tag->type != MULTIBOOT_TAG_TYPE_END;
0100                  tag = (struct multiboot_tag *) ((multiboot_uint8_t *) tag + ((tag->size + 7) & ~7))) {
0101                 switch (tag->type) {
0102                 case MULTIBOOT_TAG_TYPE_CMDLINE:
0103                     printf("Multiboot2 booting arguments: `%s', args len: %d\n",
0104                       ((struct multiboot_tag_string *) tag)->string,
0105                       ((struct multiboot_tag_string *) tag)->size);
0106                     strncpy(multiboot_boot_args, ((struct multiboot_tag_string*)tag)->string, ((struct multiboot_tag_string*)tag)->size);
0107                     break;
0108                 case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
0109                     printf("Multiboot2 loader name: `%s'\n", ((struct multiboot_tag_string *) tag)->string);
0110                     break;
0111                 case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
0112                     struct multiboot_tag_framebuffer* fbtag = (struct multiboot_tag_framebuffer*)tag;
0113                     uint64_t fbbase = fbtag->common.framebuffer_addr;
0114             printf("Multiboot2 framebuffer @ %p, resolution: %dx%d, pitch/bpp: %d/%d, type: %d\n",
0115                            (void*)fbbase, fbtag->common.framebuffer_width, fbtag->common.framebuffer_height,
0116                     fbtag->common.framebuffer_pitch, fbtag->common.framebuffer_bpp,
0117                     fbtag->common.framebuffer_type);
0118                     break;
0119                 case MULTIBOOT_TAG_TYPE_ACPI_OLD:
0120                     if (acpi_rsdp_addr != 0) {
0121                         break;
0122                     }
0123                     struct multiboot_tag_new_acpi* rsdp_old_tag = (struct multiboot_tag_new_acpi*) tag;
0124                     printf("Multiboot2: ACPI 1.0 RSDP address: %p\n", rsdp_old_tag->rsdp);
0125                     acpi_rsdp_addr = (uint64_t) rsdp_old_tag->rsdp;
0126                 break;
0127                 case MULTIBOOT_TAG_TYPE_ACPI_NEW:
0128                     struct multiboot_tag_new_acpi* rsdp_new_tag = (struct multiboot_tag_new_acpi*) tag;
0129                     printf("Multiboot2: ACPI 2.0 RSDP address: %p\n", rsdp_new_tag->rsdp);
0130                     acpi_rsdp_addr = (uint64_t) rsdp_new_tag->rsdp;
0131                 break;
0132 #ifdef BSP_USE_EFI_BOOT_SERVICES
0133                 case MULTIBOOT_TAG_TYPE_EFI64:
0134                     printf("EFI64 system table @ 0x%llx\n", ((struct multiboot_tag_efi64 *) tag)->pointer);
0135                     ST = ((EFI_SYSTEM_TABLE*)((struct multiboot_tag_efi64 *) tag)->pointer);
0136                     BS = ST->BootServices;
0137                     RS = ST->RuntimeServices;
0138                     efi_console_initialize();
0139             efi_memory_heap_extend();
0140                     break;
0141                 case MULTIBOOT_TAG_TYPE_EFI_BS:
0142                     printf("GRUB: EFI boot services running.\n");
0143                     bootservices_running = 1;
0144                     break;
0145                 case MULTIBOOT_TAG_TYPE_EFI64_IH:
0146                     printf("EFI: 64bit image handle: 0x%llx\n", ((struct multiboot_tag_efi64_ih *) tag)->pointer);
0147                     IH = (EFI_HANDLE)((struct multiboot_tag_efi64_ih *) tag)->pointer;
0148             break;
0149 #endif
0150                 }
0151             }
0152         }
0153     }
0154     else {
0155         printf("So while not being booted by multiboot2, let's see what's in its magic then?: %dx\n", _multiboot2_magic);
0156     }
0157 }
0158 
0159 #endif /* BSP_MULTIBOOT_SUPPORT */
0160 
0161 int
0162 uefi_bootservices_running()
0163 {
0164     return bootservices_running;
0165 }
0166 
0167 const char*
0168 boot_args()
0169 {
0170     return multiboot_boot_args;
0171 }
0172 
0173 int
0174 get_boot_arg_int_value(const char* boot_args, const char* arg, int* val)
0175 {
0176     int len_arg = strlen(arg);
0177     int len_try = strlen(boot_args) - len_arg;
0178     int len_bootargs = strlen(boot_args);
0179     char num[10];
0180     for (int i = 0; i < len_try; i++) {
0181         if (strncmp(&(boot_args[i]), arg, len_arg) == 0) {
0182             i = i + len_arg + 1;
0183             for (int j = 0; j < 10; j++) {
0184                 if (boot_args[i + j] != ' ' && i + j < len_bootargs)
0185                     num[j] = boot_args[i + j];
0186                 else {
0187                     num[j] = 0;
0188                     *val = atoi(num);
0189                     return 0;
0190                 }
0191             }
0192         }
0193     }
0194     return -1;
0195 }
0196