File indexing completed on 2025-05-11 08:24:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <bsp.h>
0037
0038 #include <efi.h>
0039
0040 #include <rtems/bspIo.h>
0041
0042 #include <stdio.h>
0043 #include <string.h>
0044
0045 #include <efistop.h>
0046 #include <efigop.h>
0047
0048 #include <multiboot2impl.h>
0049
0050 #ifdef BSP_USE_EFI_BOOT_SERVICES
0051
0052 extern EFI_HANDLE IH;
0053 extern EFI_SYSTEM_TABLE *ST;
0054 extern EFI_BOOT_SERVICES *BS;
0055 extern EFI_RUNTIME_SERVICES *RS;
0056
0057 extern void uart0_output_char(char c);
0058
0059 static bool is_efi_console_initialized = false;
0060
0061 static char output_buffer[4096];
0062 static int output_buffer_index = 0;
0063
0064 void
0065 efi_console_initialize(void);
0066
0067 EFI_STATUS
0068 print_gop_info(EFI_GRAPHICS_OUTPUT *gop);
0069
0070 EFI_STATUS
0071 check_gop(BOOLEAN verbose);
0072
0073 static void
0074 both_output_char(char c);
0075
0076 static void
0077 sync_output(void);
0078
0079 void
0080 print_ccm_info(EFI_CONSOLE_CONTROL_SCREEN_MODE, BOOLEAN, BOOLEAN);
0081
0082 void
0083 print_ccm_info(EFI_CONSOLE_CONTROL_SCREEN_MODE mode, BOOLEAN graphics, BOOLEAN locked)
0084 {
0085 printf("RTEMS: EFI console default mode: ");
0086 switch (mode) {
0087 case EfiConsoleControlScreenText:
0088 printf("text");
0089 break;
0090 case EfiConsoleControlScreenGraphics:
0091 printf("graphics");
0092 break;
0093 case EfiConsoleControlScreenMaxValue:
0094 printf("max value");
0095 break;
0096 }
0097 if (graphics) {
0098 printf(", graphics is available");
0099 }
0100 if (locked) {
0101 printf(", stdin is locked");
0102 }
0103 printf("\n");
0104 }
0105
0106 void
0107 efi_console_initialize( void )
0108 {
0109 EFI_STATUS status;
0110 EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
0111 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
0112 EFI_HANDLE *HandleBuffer = NULL;
0113 UINTN HandleCount = 0;
0114 BOOLEAN graphics_exists;
0115 BOOLEAN locked_stdin;
0116 EFI_CONSOLE_CONTROL_SCREEN_MODE mode;
0117 BOOLEAN use_text = false;
0118 BOOLEAN use_graphic = false;
0119 BOOLEAN use_auto = false;
0120 int text_mode = -1;
0121 int graphic_mode = -1;
0122
0123 if (is_efi_console_initialized)
0124 return;
0125 if (ST == NULL)
0126 return;
0127
0128
0129 status = ST->BootServices->LocateProtocol(&ConsoleControlGUID, NULL,
0130 (VOID **)&ConsoleControl);
0131 if (EFI_ERROR(status)) {
0132 status = ST->BootServices->HandleProtocol( ST->ConsoleOutHandle,
0133 &ConsoleControlGUID,
0134 (VOID **)&ConsoleControl);
0135 if (EFI_ERROR(status)) {
0136 status = ST->BootServices->LocateHandleBuffer( ByProtocol,
0137 &ConsoleControlGUID,
0138 NULL,
0139 &HandleCount,
0140 &HandleBuffer);
0141 if (status == EFI_SUCCESS) {
0142 for (int i = 0; i < HandleCount; i++) {
0143 status = ST->BootServices->HandleProtocol( HandleBuffer[i],
0144 &ConsoleControlGUID,
0145 (VOID*)&ConsoleControl);
0146 if (!EFI_ERROR (status)) {
0147 break;
0148 }
0149 }
0150 ST->BootServices->FreePool(HandleBuffer);
0151 }
0152 }
0153 }
0154 if (strcmp(BSP_EFI_CONSOLE_KIND, "TEXT") == 0) {
0155 use_text = true;
0156 }
0157 if (strcmp(BSP_EFI_CONSOLE_KIND, "GRAPHIC") == 0) {
0158 use_graphic = true;
0159 }
0160 if (strcmp(BSP_EFI_CONSOLE_KIND, "BOTH") == 0) {
0161 use_text = true;
0162 use_graphic = true;
0163 }
0164 if (strcmp(BSP_EFI_CONSOLE_KIND, "AUTO") == 0) {
0165 use_auto = true;
0166 }
0167 if (ConsoleControl != NULL) {
0168 status = ConsoleControl->GetMode(ConsoleControl, &mode, &graphics_exists, &locked_stdin);
0169 if (!EFI_ERROR(status)) {
0170 print_ccm_info(mode, graphics_exists, locked_stdin);
0171 if (mode == EfiConsoleControlScreenText && use_auto) {
0172 use_text = true;
0173 }
0174 if (mode == EfiConsoleControlScreenGraphics && use_auto) {
0175 use_graphic = true;
0176 }
0177 }
0178 else {
0179
0180 use_text = true;
0181 use_graphic = true;
0182 }
0183 }
0184 else {
0185
0186 use_text = true;
0187 use_graphic = true;
0188 }
0189 if (get_boot_arg_int_value(boot_args(), "text_mode", &text_mode) == 0
0190 || get_boot_arg_int_value(boot_args(), "graphic_mode", &graphic_mode) == 0) {
0191
0192
0193 use_text = false;
0194 use_graphic = false;
0195 }
0196 if (get_boot_arg_int_value(boot_args(), "text_mode", &text_mode) == 0) {
0197 use_text = true;
0198 }
0199 if (get_boot_arg_int_value(boot_args(), "graphic_mode", &graphic_mode) == 0) {
0200 use_graphic = true;
0201 }
0202 if (use_text)
0203 efi_init_text_output(text_mode);
0204 if (use_graphic) {
0205 efi_init_graphic_output(graphic_mode);
0206 }
0207 if (use_text && use_graphic) {
0208 BSP_output_char = both_output_char;
0209 }
0210 else if (use_text) {
0211 BSP_output_char = efi_text_output_char;
0212 }
0213 else if (use_graphic) {
0214 BSP_output_char = efi_graphic_output_char;
0215 }
0216 sync_output();
0217 is_efi_console_initialized = true;
0218 }
0219
0220 void
0221 buffered_output( char c );
0222
0223 void
0224 buffered_output( char c )
0225 {
0226 if (output_buffer_index < (4096 - 1)) {
0227 output_buffer[output_buffer_index] = c;
0228 output_buffer_index++;
0229 }
0230 }
0231
0232 static void
0233 both_output_char( char c )
0234 {
0235 efi_text_output_char(c);
0236 efi_graphic_output_char(c);
0237 }
0238
0239 void
0240 sync_output()
0241 {
0242 printf("EFI: console sync_output(): there are %d characters in the buffer.\n", output_buffer_index);
0243 for (int i = 0; i < output_buffer_index; i++) {
0244 BSP_output_char(output_buffer[i]);
0245 }
0246 printf("EFI: console sync_output() done.\n");
0247 }
0248
0249 #if (BSP_EFI_EARLY_CONSOLE_KIND == BUFFER)
0250 BSP_output_char_function_type BSP_output_char = buffered_output;
0251 #elif (BSP_EFI_EARLY_CONSOLE_KIND == SERIAL)
0252 BSP_output_char_function_type BSP_output_char = uart0_output_char;
0253 #endif
0254
0255 BSP_polling_getchar_function_type BSP_poll_char = NULL;
0256
0257 #endif
0258