From 756a121016168251b59dc66626eba1910b1dc520 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Thu, 19 Dec 2024 22:46:44 -0800 Subject: [PATCH 01/23] [libc] init uefi os target --- .../cmake/modules/LLVMLibCArchitectures.cmake | 6 + libc/config/uefi/config.json | 29 ++ libc/config/uefi/entrypoints.txt | 450 ++++++++++++++++++ libc/config/uefi/headers.txt | 20 + libc/include/CMakeLists.txt | 15 + libc/include/Uefi.h.def | 16 + libc/include/Uefi.yaml | 11 + libc/include/llvm-libc-macros/CMakeLists.txt | 6 + libc/include/llvm-libc-macros/EFIAPI-macros.h | 10 + libc/include/llvm-libc-types/CMakeLists.txt | 121 +++++ .../llvm-libc-types/EFI_ALLOCATE_TYPE.h | 19 + .../llvm-libc-types/EFI_BOOT_SERVICES.h | 249 ++++++++++ libc/include/llvm-libc-types/EFI_CAPSULE.h | 26 + .../llvm-libc-types/EFI_CONFIGURATION_TABLE.h | 19 + .../EFI_DEVICE_PATH_PROTOCOL.h | 27 ++ libc/include/llvm-libc-types/EFI_EVENT.h | 21 + libc/include/llvm-libc-types/EFI_GUID.h | 21 + libc/include/llvm-libc-types/EFI_HANDLE.h | 14 + .../llvm-libc-types/EFI_INTERFACE_TYPE.h | 16 + .../llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h | 18 + .../llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h | 43 ++ .../include/llvm-libc-types/EFI_MEMORY_TYPE.h | 32 ++ .../EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h | 22 + .../llvm-libc-types/EFI_PHYSICAL_ADDRESS.h | 16 + .../llvm-libc-types/EFI_RUNTIME_SERVICES.h | 134 ++++++ .../EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h | 41 ++ .../EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h | 68 +++ libc/include/llvm-libc-types/EFI_STATUS.h | 16 + .../llvm-libc-types/EFI_SYSTEM_TABLE.h | 63 +++ .../llvm-libc-types/EFI_TABLE_HEADER.h | 22 + libc/include/llvm-libc-types/EFI_TIME.h | 37 ++ .../include/llvm-libc-types/EFI_TIMER_DELAY.h | 18 + libc/include/llvm-libc-types/EFI_TPL.h | 21 + .../llvm-libc-types/EFI_VIRTUAL_ADDRESS.h | 16 + libc/src/__support/OSUtil/io.h | 2 + libc/src/__support/OSUtil/uefi/CMakeLists.txt | 11 + libc/src/__support/OSUtil/uefi/exit.cpp | 23 + libc/src/__support/OSUtil/uefi/io.cpp | 26 + libc/src/__support/OSUtil/uefi/io.h | 25 + libc/src/stdio/CMakeLists.txt | 2 +- libc/src/stdio/uefi/CMakeLists.txt | 0 libc/startup/uefi/CMakeLists.txt | 56 +++ libc/startup/uefi/crt1.cpp | 24 + libc/test/src/__support/CMakeLists.txt | 4 +- 44 files changed, 1833 insertions(+), 3 deletions(-) create mode 100644 libc/config/uefi/config.json create mode 100644 libc/config/uefi/entrypoints.txt create mode 100644 libc/config/uefi/headers.txt create mode 100644 libc/include/Uefi.h.def create mode 100644 libc/include/Uefi.yaml create mode 100644 libc/include/llvm-libc-macros/EFIAPI-macros.h create mode 100644 libc/include/llvm-libc-types/EFI_ALLOCATE_TYPE.h create mode 100644 libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h create mode 100644 libc/include/llvm-libc-types/EFI_CAPSULE.h create mode 100644 libc/include/llvm-libc-types/EFI_CONFIGURATION_TABLE.h create mode 100644 libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h create mode 100644 libc/include/llvm-libc-types/EFI_EVENT.h create mode 100644 libc/include/llvm-libc-types/EFI_GUID.h create mode 100644 libc/include/llvm-libc-types/EFI_HANDLE.h create mode 100644 libc/include/llvm-libc-types/EFI_INTERFACE_TYPE.h create mode 100644 libc/include/llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h create mode 100644 libc/include/llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h create mode 100644 libc/include/llvm-libc-types/EFI_MEMORY_TYPE.h create mode 100644 libc/include/llvm-libc-types/EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h create mode 100644 libc/include/llvm-libc-types/EFI_PHYSICAL_ADDRESS.h create mode 100644 libc/include/llvm-libc-types/EFI_RUNTIME_SERVICES.h create mode 100644 libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h create mode 100644 libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h create mode 100644 libc/include/llvm-libc-types/EFI_STATUS.h create mode 100644 libc/include/llvm-libc-types/EFI_SYSTEM_TABLE.h create mode 100644 libc/include/llvm-libc-types/EFI_TABLE_HEADER.h create mode 100644 libc/include/llvm-libc-types/EFI_TIME.h create mode 100644 libc/include/llvm-libc-types/EFI_TIMER_DELAY.h create mode 100644 libc/include/llvm-libc-types/EFI_TPL.h create mode 100644 libc/include/llvm-libc-types/EFI_VIRTUAL_ADDRESS.h create mode 100644 libc/src/__support/OSUtil/uefi/CMakeLists.txt create mode 100644 libc/src/__support/OSUtil/uefi/exit.cpp create mode 100644 libc/src/__support/OSUtil/uefi/io.cpp create mode 100644 libc/src/__support/OSUtil/uefi/io.h create mode 100644 libc/src/stdio/uefi/CMakeLists.txt create mode 100644 libc/startup/uefi/CMakeLists.txt create mode 100644 libc/startup/uefi/crt1.cpp diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake index fbb1091ddabab..dd12d1d3ee422 100644 --- a/libc/cmake/modules/LLVMLibCArchitectures.cmake +++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake @@ -69,6 +69,10 @@ function(get_arch_and_system_from_triple triple arch_var sys_var) set(target_sys "darwin") endif() + if(target_sys STREQUAL "unknown") + list(GET triple_comps 2 target_sys) + endif() + # Setting OS name for GPU architectures. list(GET triple_comps -1 gpu_target_sys) if(gpu_target_sys MATCHES "^amdhsa" OR gpu_target_sys MATCHES "^cuda") @@ -187,6 +191,8 @@ elseif(LIBC_TARGET_OS STREQUAL "windows") set(LIBC_TARGET_OS_IS_WINDOWS TRUE) elseif(LIBC_TARGET_OS STREQUAL "gpu") set(LIBC_TARGET_OS_IS_GPU TRUE) +elseif(LIBC_TARGET_OS STREQUAL "uefi") + set(LIBC_TARGET_OS_IS_UEFI TRUE) else() message(FATAL_ERROR "Unsupported libc target operating system ${LIBC_TARGET_OS}") diff --git a/libc/config/uefi/config.json b/libc/config/uefi/config.json new file mode 100644 index 0000000000000..b60dde9ef040a --- /dev/null +++ b/libc/config/uefi/config.json @@ -0,0 +1,29 @@ +{ + "errno": { + "LIBC_CONF_ERRNO_MODE": { + "value": "LIBC_ERRNO_MODE_DEFAULT" + } + }, + "printf": { + "LIBC_CONF_PRINTF_DISABLE_FLOAT": { + "value": true + }, + "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": { + "value": true + }, + "LIBC_CONF_PRINTF_DISABLE_WRITE_INT": { + "value": true + }, + "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": { + "value": false + }, + "LIBC_CONF_PRINTF_DISABLE_STRERROR": { + "value": true + } + }, + "qsort": { + "LIBC_CONF_QSORT_IMPL": { + "value": "LIBC_QSORT_HEAP_SORT" + } + } +} diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt new file mode 100644 index 0000000000000..664a4d2ca4640 --- /dev/null +++ b/libc/config/uefi/entrypoints.txt @@ -0,0 +1,450 @@ +set(TARGET_LIBC_ENTRYPOINTS + # ctype.h entrypoints + libc.src.ctype.isalnum + libc.src.ctype.isalpha + libc.src.ctype.isascii + libc.src.ctype.isblank + libc.src.ctype.iscntrl + libc.src.ctype.isdigit + libc.src.ctype.isgraph + libc.src.ctype.islower + libc.src.ctype.isprint + libc.src.ctype.ispunct + libc.src.ctype.isspace + libc.src.ctype.isupper + libc.src.ctype.isxdigit + libc.src.ctype.toascii + libc.src.ctype.tolower + libc.src.ctype.toupper + + # errno.h entrypoints + libc.src.errno.errno + + # setjmp.h entrypoints + libc.src.setjmp.longjmp + libc.src.setjmp.setjmp + + # string.h entrypoints + libc.src.string.memccpy + libc.src.string.memchr + libc.src.string.memcmp + libc.src.string.memcpy + libc.src.string.memmem + libc.src.string.memmove + libc.src.string.mempcpy + libc.src.string.memrchr + libc.src.string.memset + libc.src.string.memset_explicit + libc.src.string.stpcpy + libc.src.string.stpncpy + libc.src.string.strcasestr + libc.src.string.strcat + libc.src.string.strchr + libc.src.string.strchrnul + libc.src.string.strcmp + libc.src.string.strcoll + libc.src.string.strcpy + libc.src.string.strcspn + libc.src.string.strerror + libc.src.string.strerror_r + libc.src.string.strlcat + libc.src.string.strlcpy + libc.src.string.strlen + libc.src.string.strncat + libc.src.string.strncmp + libc.src.string.strncpy + libc.src.string.strnlen + libc.src.string.strpbrk + libc.src.string.strrchr + libc.src.string.strsep + libc.src.string.strspn + libc.src.string.strstr + libc.src.string.strtok + libc.src.string.strtok_r + libc.src.string.strxfrm + + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + + # inttypes.h entrypoints + libc.src.inttypes.imaxabs + libc.src.inttypes.imaxdiv + libc.src.inttypes.strtoimax + libc.src.inttypes.strtoumax + + # stdbit.h entrypoints + libc.src.stdbit.stdc_bit_ceil_uc + libc.src.stdbit.stdc_bit_ceil_ui + libc.src.stdbit.stdc_bit_ceil_ul + libc.src.stdbit.stdc_bit_ceil_ull + libc.src.stdbit.stdc_bit_ceil_us + libc.src.stdbit.stdc_bit_floor_uc + libc.src.stdbit.stdc_bit_floor_ui + libc.src.stdbit.stdc_bit_floor_ul + libc.src.stdbit.stdc_bit_floor_ull + libc.src.stdbit.stdc_bit_floor_us + libc.src.stdbit.stdc_bit_width_uc + libc.src.stdbit.stdc_bit_width_ui + libc.src.stdbit.stdc_bit_width_ul + libc.src.stdbit.stdc_bit_width_ull + libc.src.stdbit.stdc_bit_width_us + libc.src.stdbit.stdc_count_ones_uc + libc.src.stdbit.stdc_count_ones_ui + libc.src.stdbit.stdc_count_ones_ul + libc.src.stdbit.stdc_count_ones_ull + libc.src.stdbit.stdc_count_ones_us + libc.src.stdbit.stdc_count_zeros_uc + libc.src.stdbit.stdc_count_zeros_ui + libc.src.stdbit.stdc_count_zeros_ul + libc.src.stdbit.stdc_count_zeros_ull + libc.src.stdbit.stdc_count_zeros_us + libc.src.stdbit.stdc_first_leading_one_uc + libc.src.stdbit.stdc_first_leading_one_ui + libc.src.stdbit.stdc_first_leading_one_ul + libc.src.stdbit.stdc_first_leading_one_ull + libc.src.stdbit.stdc_first_leading_one_us + libc.src.stdbit.stdc_first_leading_zero_uc + libc.src.stdbit.stdc_first_leading_zero_ui + libc.src.stdbit.stdc_first_leading_zero_ul + libc.src.stdbit.stdc_first_leading_zero_ull + libc.src.stdbit.stdc_first_leading_zero_us + libc.src.stdbit.stdc_first_trailing_one_uc + libc.src.stdbit.stdc_first_trailing_one_ui + libc.src.stdbit.stdc_first_trailing_one_ul + libc.src.stdbit.stdc_first_trailing_one_ull + libc.src.stdbit.stdc_first_trailing_one_us + libc.src.stdbit.stdc_first_trailing_zero_uc + libc.src.stdbit.stdc_first_trailing_zero_ui + libc.src.stdbit.stdc_first_trailing_zero_ul + libc.src.stdbit.stdc_first_trailing_zero_ull + libc.src.stdbit.stdc_first_trailing_zero_us + libc.src.stdbit.stdc_has_single_bit_uc + libc.src.stdbit.stdc_has_single_bit_ui + libc.src.stdbit.stdc_has_single_bit_ul + libc.src.stdbit.stdc_has_single_bit_ull + libc.src.stdbit.stdc_has_single_bit_us + libc.src.stdbit.stdc_leading_ones_uc + libc.src.stdbit.stdc_leading_ones_ui + libc.src.stdbit.stdc_leading_ones_ul + libc.src.stdbit.stdc_leading_ones_ull + libc.src.stdbit.stdc_leading_ones_us + libc.src.stdbit.stdc_leading_zeros_uc + libc.src.stdbit.stdc_leading_zeros_ui + libc.src.stdbit.stdc_leading_zeros_ul + libc.src.stdbit.stdc_leading_zeros_ull + libc.src.stdbit.stdc_leading_zeros_us + libc.src.stdbit.stdc_trailing_ones_uc + libc.src.stdbit.stdc_trailing_ones_ui + libc.src.stdbit.stdc_trailing_ones_ul + libc.src.stdbit.stdc_trailing_ones_ull + libc.src.stdbit.stdc_trailing_ones_us + libc.src.stdbit.stdc_trailing_zeros_uc + libc.src.stdbit.stdc_trailing_zeros_ui + libc.src.stdbit.stdc_trailing_zeros_ul + libc.src.stdbit.stdc_trailing_zeros_ull + libc.src.stdbit.stdc_trailing_zeros_us + + # stdlib.h entrypoints + libc.src.stdlib._Exit + libc.src.stdlib.abs + libc.src.stdlib.aligned_alloc + libc.src.stdlib.atof + libc.src.stdlib.atoi + libc.src.stdlib.atol + libc.src.stdlib.atoll + libc.src.stdlib.bsearch + libc.src.stdlib.calloc + libc.src.stdlib.div + libc.src.stdlib.free + libc.src.stdlib.labs + libc.src.stdlib.ldiv + libc.src.stdlib.llabs + libc.src.stdlib.lldiv + libc.src.stdlib.malloc + libc.src.stdlib.qsort + libc.src.stdlib.rand + libc.src.stdlib.realloc + libc.src.stdlib.srand + libc.src.stdlib.strtod + libc.src.stdlib.strtof + libc.src.stdlib.strtol + libc.src.stdlib.strtold + libc.src.stdlib.strtoll + libc.src.stdlib.strtoul + libc.src.stdlib.strtoull + + # time.h entrypoints + libc.src.time.asctime + libc.src.time.asctime_r + libc.src.time.ctime + libc.src.time.ctime_r + libc.src.time.difftime + libc.src.time.gmtime + libc.src.time.gmtime_r + libc.src.time.mktime +) + +set(TARGET_LIBM_ENTRYPOINTS + # fenv.h entrypoints + libc.src.fenv.feclearexcept + libc.src.fenv.fedisableexcept + libc.src.fenv.feenableexcept + libc.src.fenv.fegetenv + libc.src.fenv.fegetexcept + libc.src.fenv.fegetexceptflag + libc.src.fenv.fegetround + libc.src.fenv.feholdexcept + libc.src.fenv.feraiseexcept + libc.src.fenv.fesetenv + libc.src.fenv.fesetexcept + libc.src.fenv.fesetexceptflag + libc.src.fenv.fesetround + libc.src.fenv.fetestexcept + libc.src.fenv.fetestexceptflag + libc.src.fenv.feupdateenv + + # math.h entrypoints + libc.src.math.acosf + libc.src.math.acoshf + libc.src.math.asinf + libc.src.math.asinhf + libc.src.math.atan2 + libc.src.math.atan2f + libc.src.math.atanf + libc.src.math.atanhf + libc.src.math.canonicalize + libc.src.math.canonicalizef + libc.src.math.canonicalizel + libc.src.math.cbrt + libc.src.math.cbrtf + libc.src.math.ceil + libc.src.math.ceilf + libc.src.math.ceill + libc.src.math.copysign + libc.src.math.copysignf + libc.src.math.copysignl + libc.src.math.cos + libc.src.math.cosf + libc.src.math.coshf + libc.src.math.erff + libc.src.math.exp + libc.src.math.exp10 + libc.src.math.exp10f + libc.src.math.exp2 + libc.src.math.exp2f + libc.src.math.exp2m1f + libc.src.math.expf + libc.src.math.expm1 + libc.src.math.expm1f + libc.src.math.fabs + libc.src.math.fabsf + libc.src.math.fabsl + libc.src.math.fdim + libc.src.math.fdimf + libc.src.math.fdiml + libc.src.math.floor + libc.src.math.floorf + libc.src.math.floorl + libc.src.math.fma + libc.src.math.fmaf + libc.src.math.fmax + libc.src.math.fmaxf + libc.src.math.fmaximum + libc.src.math.fmaximum_mag + libc.src.math.fmaximum_mag_num + libc.src.math.fmaximum_mag_numf + libc.src.math.fmaximum_mag_numl + libc.src.math.fmaximum_magf + libc.src.math.fmaximum_magl + libc.src.math.fmaximum_num + libc.src.math.fmaximum_numf + libc.src.math.fmaximum_numl + libc.src.math.fmaximumf + libc.src.math.fmaximuml + libc.src.math.fmaxl + libc.src.math.fmin + libc.src.math.fminf + libc.src.math.fminimum + libc.src.math.fminimum_mag + libc.src.math.fminimum_mag_num + libc.src.math.fminimum_mag_numf + libc.src.math.fminimum_mag_numl + libc.src.math.fminimum_magf + libc.src.math.fminimum_magl + libc.src.math.fminimum_num + libc.src.math.fminimum_numf + libc.src.math.fminimum_numl + libc.src.math.fminimumf + libc.src.math.fminimuml + libc.src.math.fminl + libc.src.math.fmod + libc.src.math.fmodf + libc.src.math.fmodl + libc.src.math.fmul + libc.src.math.frexp + libc.src.math.frexpf + libc.src.math.frexpl + libc.src.math.fromfp + libc.src.math.fromfpf + libc.src.math.fromfpl + libc.src.math.fromfpx + libc.src.math.fromfpxf + libc.src.math.fromfpxl + libc.src.math.hypot + libc.src.math.hypotf + libc.src.math.ilogb + libc.src.math.ilogbf + libc.src.math.ilogbl + libc.src.math.isnan + libc.src.math.isnanf + libc.src.math.isnanl + libc.src.math.ldexp + libc.src.math.ldexpf + libc.src.math.ldexpl + libc.src.math.llogb + libc.src.math.llogbf + libc.src.math.llogbl + libc.src.math.llrint + libc.src.math.llrintf + libc.src.math.llrintl + libc.src.math.llround + libc.src.math.llroundf + libc.src.math.llroundl + libc.src.math.log + libc.src.math.log10 + libc.src.math.log10f + libc.src.math.log1p + libc.src.math.log1pf + libc.src.math.log2 + libc.src.math.log2f + libc.src.math.logb + libc.src.math.logbf + libc.src.math.logbl + libc.src.math.logf + libc.src.math.lrint + libc.src.math.lrintf + libc.src.math.lrintl + libc.src.math.lround + libc.src.math.lroundf + libc.src.math.lroundl + libc.src.math.modf + libc.src.math.modff + libc.src.math.modfl + libc.src.math.nan + libc.src.math.nanf + libc.src.math.nanl + libc.src.math.nearbyint + libc.src.math.nearbyintf + libc.src.math.nearbyintl + libc.src.math.nextafter + libc.src.math.nextafterf + libc.src.math.nextafterl + libc.src.math.nextdown + libc.src.math.nextdownf + libc.src.math.nextdownl + libc.src.math.nexttoward + libc.src.math.nexttowardf + libc.src.math.nexttowardl + libc.src.math.nextup + libc.src.math.nextupf + libc.src.math.nextupl + libc.src.math.pow + libc.src.math.powf + libc.src.math.remainder + libc.src.math.remainderf + libc.src.math.remainderl + libc.src.math.remquo + libc.src.math.remquof + libc.src.math.remquol + libc.src.math.rint + libc.src.math.rintf + libc.src.math.rintl + libc.src.math.round + libc.src.math.roundeven + libc.src.math.roundevenf + libc.src.math.roundevenl + libc.src.math.roundf + libc.src.math.roundl + libc.src.math.scalbln + libc.src.math.scalblnf + libc.src.math.scalblnl + libc.src.math.scalbn + libc.src.math.scalbnf + libc.src.math.scalbnl + libc.src.math.sin + libc.src.math.sincos + libc.src.math.sincosf + libc.src.math.sinf + libc.src.math.sinhf + libc.src.math.sqrt + libc.src.math.sqrtf + libc.src.math.sqrtl + libc.src.math.tan + libc.src.math.tanf + libc.src.math.tanhf + libc.src.math.trunc + libc.src.math.truncf + libc.src.math.truncl + libc.src.math.ufromfp + libc.src.math.ufromfpf + libc.src.math.ufromfpl + libc.src.math.ufromfpx + libc.src.math.ufromfpxf + libc.src.math.ufromfpxl +) + +if(LIBC_COMPILER_HAS_FIXED_POINT) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # stdfix.h _Fract and _Accum entrypoints + libc.src.stdfix.abshk + libc.src.stdfix.abshr + libc.src.stdfix.absk + libc.src.stdfix.abslk + libc.src.stdfix.abslr + libc.src.stdfix.absr + libc.src.stdfix.exphk + libc.src.stdfix.expk + libc.src.stdfix.roundhk + libc.src.stdfix.roundhr + libc.src.stdfix.roundk + libc.src.stdfix.roundlk + libc.src.stdfix.roundlr + libc.src.stdfix.roundr + libc.src.stdfix.rounduhk + libc.src.stdfix.rounduhr + libc.src.stdfix.rounduk + libc.src.stdfix.roundulk + libc.src.stdfix.roundulr + libc.src.stdfix.roundur + libc.src.stdfix.sqrtuhk + libc.src.stdfix.sqrtuhr + libc.src.stdfix.sqrtuk + libc.src.stdfix.sqrtur + libc.src.stdfix.sqrtulr + libc.src.stdfix.uhksqrtus + libc.src.stdfix.uksqrtui + libc.src.stdfix.hrbits + libc.src.stdfix.uhrbits + libc.src.stdfix.rbits + libc.src.stdfix.urbits + libc.src.stdfix.lrbits + libc.src.stdfix.ulrbits + libc.src.stdfix.hkbits + libc.src.stdfix.uhkbits + libc.src.stdfix.kbits + libc.src.stdfix.ukbits + libc.src.stdfix.lkbits + libc.src.stdfix.ulkbits + ) +endif() + +set(TARGET_LLVMLIBC_ENTRYPOINTS + ${TARGET_LIBC_ENTRYPOINTS} + ${TARGET_LIBM_ENTRYPOINTS} +) diff --git a/libc/config/uefi/headers.txt b/libc/config/uefi/headers.txt new file mode 100644 index 0000000000000..bf8dee1e6f2a6 --- /dev/null +++ b/libc/config/uefi/headers.txt @@ -0,0 +1,20 @@ +set(TARGET_PUBLIC_HEADERS + libc.include.assert + libc.include.ctype + libc.include.errno + libc.include.features + libc.include.fenv + libc.include.float + libc.include.inttypes + libc.include.math + libc.include.setjmp + libc.include.stdfix + libc.include.stdint + libc.include.stdlib + libc.include.string + libc.include.strings + libc.include.sys_queue + libc.include.time + libc.include.uefi + libc.include.uchar +) diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 867bd1e5ee20f..1811e8f143e6e 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -724,6 +724,21 @@ add_header_macro( .llvm-libc-macros.poll-macros ) +if(LIBC_TARGET_OS_IS_UEFI) + # UEFI spec references "Uefi.h" so we use that name for compatibility + add_header_macro( + uefi + ../libc/include/Uefi.yaml + Uefi.h.def + Uefi.h + DEPENDS + .llvm_libc_common_h + .llvm-libc-types.EFI_GUID + .llvm-libc-types.EFI_STATUS + .llvm-libc-types.EFI_SYSTEM_TABLE + ) +endif() + if(NOT LLVM_LIBC_FULL_BUILD) # We don't install headers in non-fullbuild mode. return() diff --git a/libc/include/Uefi.h.def b/libc/include/Uefi.h.def new file mode 100644 index 0000000000000..6655e13579cd8 --- /dev/null +++ b/libc/include/Uefi.h.def @@ -0,0 +1,16 @@ +//===-- UEFI header uefi.h --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_UEFI_H +#define LLVM_LIBC_UEFI_H + +#include "__llvm-libc-common.h" + +%%public_api() + +#endif // LLVM_LIBC_UEFI_H diff --git a/libc/include/Uefi.yaml b/libc/include/Uefi.yaml new file mode 100644 index 0000000000000..f17e629c87cc7 --- /dev/null +++ b/libc/include/Uefi.yaml @@ -0,0 +1,11 @@ +header: Uefi.h +standards: UEFI +macros: [] +types: + - type_name: EFI_BOOT_SERVICES + - type_name: EFI_GUID + - type_name: EFI_STATUS + - type_name: EFI_SYSTEM_TABLE +enums: [] +functions: [] +objects: [] diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt index ea892a87dbe7a..680909746d39b 100644 --- a/libc/include/llvm-libc-macros/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -333,3 +333,9 @@ add_macro_header( HDR poll-macros.h ) + +add_macro_header( + EFIAPI_macros + HDR + EFIAPI-macros.h +) diff --git a/libc/include/llvm-libc-macros/EFIAPI-macros.h b/libc/include/llvm-libc-macros/EFIAPI-macros.h new file mode 100644 index 0000000000000..d6cc1784bb786 --- /dev/null +++ b/libc/include/llvm-libc-macros/EFIAPI-macros.h @@ -0,0 +1,10 @@ +#ifndef LLVM_LIBC_MACROS_EFIAPI_MACROS_H +#define LLVM_LIBC_MACROS_EFIAPI_MACROS_H + +#if defined(__x86_64__) && !defined(__ILP32__) +#define EFIAPI __attribute__((ms_abi)) +#else +#define EFIAPI +#endif + +#endif // LLVM_LIBC_MACROS_EFIAPI_MACROS_H diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 7ed69ab1af6d9..d31a84b4dc64d 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -157,3 +157,124 @@ DEPENDS add_header(locale_t HDR locale_t.h) add_header(struct_lconv HDR struct_lconv.h) add_header(stdfix-types HDR stdfix-types.h) + +# UEFI +add_header(EFI_GUID HDR EFI_GUID.h DEPENDS libc.include.llvm-libc-macros.stdint_macros) +add_header(EFI_CONFIGURATION_TABLE HDR EFI_CONFIGURATION_TABLE.h DEPENDS .EFI_GUID) + +add_header(EFI_PHYSICAL_ADDRESS HDR EFI_PHYSICAL_ADDRESS.h DEPENDS libc.include.llvm-libc-macros.stdint_macros) +add_header(EFI_VIRTUAL_ADDRESS HDR EFI_VIRTUAL_ADDRESS.h DEPENDS libc.include.llvm-libc-macros.stdint_macros) + +add_header(EFI_MEMORY_DESCRIPTOR + HDR + EFI_MEMORY_DESCRIPTOR.h + DEPENDS + libc.include.llvm-libc-macros.stdint_macros + .EFI_PHYSICAL_ADDRESS + .EFI_VIRTUAL_ADDRESS +) + +add_header(EFI_ALLOCATE_TYPE HDR EFI_ALLOCATE_TYPE.h) +add_header(EFI_EVENT HDR EFI_EVENT.h) +add_header(EFI_INTERFACE_TYPE HDR EFI_INTERFACE_TYPE.h) +add_header(EFI_LOCATE_SEARCH_TYPE HDR EFI_LOCATE_SEARCH_TYPE.h) +add_header(EFI_MEMORY_TYPE HDR EFI_MEMORY_TYPE.h) +add_header(EFI_HANDLE HDR EFI_HANDLE.h) +add_header(EFI_TIME HDR EFI_TIME.h DEPENDS libc.include.llvm-libc-macros.stdint_macros) +add_header(EFI_TIMER_DELAY HDR EFI_TIMER_DELAY.h) +add_header(EFI_TPL HDR EFI_TPL.h DEPENDS .size_t) +add_header(EFI_STATUS HDR EFI_STATUS.h DEPENDS .size_t) + +add_header(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY + HDR + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h + DEPENDS + libc.include.llvm-libc-macros.stdint_macros + .EFI_HANDLE +) + +add_header(EFI_CAPSULE + HDR + EFI_CAPSULE.h + DEPENDS + libc.include.llvm-libc-macros.stdint_macros + .EFI_GUID +) + +add_header(EFI_TABLE_HEADER + HDR + EFI_TABLE_HEADER.h + DEPENDS + libc.include.llvm-libc-macros.stdint_macros +) + +add_header(EFI_DEVICE_PATH_PROTOCOL + HDR + EFI_DEVICE_PATH_PROTOCOL.h + DEPENDS + libc.include.llvm-libc-macros.stdint_macros +) + +add_header(EFI_SIMPLE_TEXT_INPUT_PROTOCOL + HDR + EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h + DEPENDS + libc.include.llvm-libc-macros.stdint_macros + .EFI_STATUS + .char16_t +) + +add_header(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + HDR + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h + DEPENDS + libc.include.llvm-libc-macros.stdint_macros + .EFI_STATUS + .size_t +) + +add_header(EFI_BOOT_SERVICES + HDR + EFI_BOOT_SERVICES.h + DEPENDS + libc.include.llvm-libc-macros.EFIAPI_macros + .EFI_ALLOCATE_TYPE + .EFI_DEVICE_PATH_PROTOCOL + .EFI_EVENT + .EFI_INTERFACE_TYPE + .EFI_LOCATE_SEARCH_TYPE + .EFI_MEMORY_DESCRIPTOR + .EFI_MEMORY_TYPE + .EFI_OPEN_PROTOCOL_INFORMATION_ENTRY + .EFI_PHYSICAL_ADDRESS + .EFI_TABLE_HEADER + .EFI_TIMER_DELAY + .EFI_TPL + .char16_t +) + +add_header(EFI_RUNTIME_SERVICES + HDR + EFI_RUNTIME_SERVICES.h + DEPENDS + .EFI_CAPSULE + .EFI_STATUS + .EFI_TABLE_HEADER + .EFI_TIME + .char16_t +) + +add_header(EFI_SYSTEM_TABLE + HDR + EFI_SYSTEM_TABLE.h + DEPENDS + .EFI_BOOT_SERVICES + .EFI_CONFIGURATION_TABLE + .EFI_HANDLE + .EFI_RUNTIME_SERVICES + .EFI_SIMPLE_TEXT_INPUT_PROTOCOL + .EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + .EFI_STATUS + .EFI_TABLE_HEADER + .char16_t +) diff --git a/libc/include/llvm-libc-types/EFI_ALLOCATE_TYPE.h b/libc/include/llvm-libc-types/EFI_ALLOCATE_TYPE.h new file mode 100644 index 0000000000000..90f23969678f4 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_ALLOCATE_TYPE.h @@ -0,0 +1,19 @@ +//===-- Definition of EFI_ALLOCATE_TYPE type ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_ALLOCATE_TYPE_H +#define LLVM_LIBC_TYPES_EFI_ALLOCATE_TYPE_H + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} EFI_ALLOCATE_TYPE; + +#endif // LLVM_LIBC_TYPES_EFI_ALLOCATE_TYPE_H diff --git a/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h b/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h new file mode 100644 index 0000000000000..362e64846e4fa --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h @@ -0,0 +1,249 @@ +//===-- Definition of EFI_BOOT_SERVICES type ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_BOOT_SERVICES_H +#define LLVM_LIBC_TYPES_EFI_BOOT_SERVICES_H + +#include "../llvm-libc-macros/EFIAPI-macros.h" +#include "EFI_ALLOCATE_TYPE.h" +#include "EFI_DEVICE_PATH_PROTOCOL.h" +#include "EFI_EVENT.h" +#include "EFI_GUID.h" +#include "EFI_INTERFACE_TYPE.h" +#include "EFI_LOCATE_SEARCH_TYPE.h" +#include "EFI_MEMORY_DESCRIPTOR.h" +#include "EFI_MEMORY_TYPE.h" +#include "EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h" +#include "EFI_PHYSICAL_ADDRESS.h" +#include "EFI_TABLE_HEADER.h" +#include "EFI_TIMER_DELAY.h" +#include "EFI_TPL.h" +#include "char16_t.h" +#include "size_t.h" + +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 +#define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION + +typedef EFI_TPL(EFIAPI *EFI_RAISE_TPL)(EFI_TPL NewTpl); +typedef void(EFIAPI *EFI_RESTORE_TPL)(EFI_TPL OldTpl); + +typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_PAGES)(EFI_ALLOCATE_TYPE Type, + EFI_MEMORY_TYPE MemoryType, + size_t Pages, + EFI_PHYSICAL_ADDRESS *Memory); +typedef EFI_STATUS(EFIAPI *EFI_FREE_PAGES)(EFI_PHYSICAL_ADDRESS Memory, + size_t Pages); +typedef EFI_STATUS(EFIAPI *EFI_GET_MEMORY_MAP)(size_t *MemoryMapSize, + EFI_MEMORY_DESCRIPTOR *MemoryMap, + size_t *MapKey, + size_t *DescriptorSize, + uint32_t *DescriptorVersion); + +typedef EFI_STATUS(EFIAPI *EFI_ALLOCATE_POOL)(EFI_MEMORY_TYPE PoolType, + size_t Size, void **Buffer); +typedef EFI_STATUS(EFIAPI *EFI_FREE_POOL)(void *Buffer); + +typedef void(EFIAPI *EFI_EVENT_NOTIFY)(EFI_EVENT Event, void *Context); + +typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT)(uint32_t Type, EFI_TPL NotifyTpl, + EFI_EVENT_NOTIFY NotifyFunction, + void *NotifyContext, + EFI_EVENT *Event); +typedef EFI_STATUS(EFIAPI *EFI_SET_TIMER)(EFI_EVENT Event, EFI_TIMER_DELAY Type, + uint64_t TriggerTime); +typedef EFI_STATUS(EFIAPI *EFI_WAIT_FOR_EVENT)(size_t NumberOfEvents, + EFI_EVENT *Event, size_t *Index); +typedef EFI_STATUS(EFIAPI *EFI_SIGNAL_EVENT)(EFI_EVENT Event); +typedef EFI_STATUS(EFIAPI *EFI_CLOSE_EVENT)(EFI_EVENT Event); +typedef EFI_STATUS(EFIAPI *EFI_CHECK_EVENT)(EFI_EVENT Event); + +typedef EFI_STATUS(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE)( + EFI_HANDLE *Handle, EFI_GUID *Protocol, EFI_INTERFACE_TYPE InterfaceType, + void *Interface); +typedef EFI_STATUS(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE)( + EFI_HANDLE Handle, EFI_GUID *Protocol, void *OldInterface, + void *NewInterface); +typedef EFI_STATUS(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE)(EFI_HANDLE Handle, + EFI_GUID *Protocol, + void *Interface); + +typedef EFI_STATUS(EFIAPI *EFI_HANDLE_PROTOCOL)(EFI_HANDLE Handle, + EFI_GUID *Protocol, + void **Interface); +typedef EFI_STATUS(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY)(EFI_GUID *Protocol, + EFI_EVENT Event, + void **Registration); + +typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE)(EFI_LOCATE_SEARCH_TYPE SearchType, + EFI_GUID *Protocol, + void *SearchKey, + size_t *BufferSize, + EFI_HANDLE *Buffer); +typedef EFI_STATUS(EFIAPI *EFI_LOCATE_DEVICE_PATH)( + EFI_GUID *Protocol, EFI_DEVICE_PATH_PROTOCOL **DevicePath, + EFI_HANDLE *Device); + +typedef EFI_STATUS(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE)(EFI_GUID *Guid, + void *Table); +typedef EFI_STATUS(EFIAPI *EFI_IMAGE_UNLOAD)(EFI_HANDLE ImageHandle); +typedef EFI_STATUS(EFIAPI *EFI_IMAGE_START)(EFI_HANDLE ImageHandle, + size_t *ExitDataSize, + char16_t **ExitData); + +typedef EFI_STATUS(EFIAPI *EFI_EXIT)(EFI_HANDLE ImageHandle, + EFI_STATUS ExitStatus, size_t ExitDataSize, + char16_t *ExitData); +typedef EFI_STATUS(EFIAPI *EFI_EXIT_BOOT_SERVICES)(EFI_HANDLE ImageHandle, + size_t MapKey); +typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT)(uint64_t *Count); +typedef EFI_STATUS(EFIAPI *EFI_STALL)(size_t Microseconds); +typedef EFI_STATUS(EFIAPI *EFI_SET_WATCHDOG_TIMER)(size_t Timeout, + uint64_t WatchdogCode, + size_t DataSize, + char16_t *WatchdogData); + +typedef EFI_STATUS(EFIAPI *EFI_CONNECT_CONTROLLER)( + EFI_HANDLE ControllerHandle, EFI_HANDLE *DriverImageHandle, + EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath, bool Recursive); + +typedef EFI_STATUS(EFIAPI *EFI_DISCONNECT_CONTROLLER)( + EFI_HANDLE ControllerHandle, EFI_HANDLE DriverImageHandle, + EFI_HANDLE ChildHandle); + +typedef EFI_STATUS(EFIAPI *EFI_OPEN_PROTOCOL)( + EFI_HANDLE Handle, EFI_GUID *Protocol, void **Interface, + EFI_HANDLE AgentHandle, EFI_HANDLE ControllerHandle, uint32_t Attributes); + +typedef EFI_STATUS(EFIAPI *EFI_CLOSE_PROTOCOL)(EFI_HANDLE Handle, + EFI_GUID *Protocol, + EFI_HANDLE AgentHandle, + EFI_HANDLE ControllerHandle); + +typedef EFI_STATUS(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION)( + EFI_HANDLE Handle, EFI_GUID *Protocol, + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, size_t *EntryCount); + +typedef EFI_STATUS(EFIAPI *EFI_PROTOCOLS_PER_HANDLE)( + EFI_HANDLE Handle, EFI_GUID ***ProtocolBuffer, size_t *ProtocolBufferCount); + +typedef EFI_STATUS(EFIAPI *EFI_LOCATE_HANDLE_BUFFER)( + EFI_LOCATE_SEARCH_TYPE SearchType, EFI_GUID *Protocol, void *SearchKey, + size_t *NoHandles, EFI_HANDLE **Buffer); + +typedef EFI_STATUS(EFIAPI *EFI_LOCATE_PROTOCOL)(EFI_GUID *Protocol, + void *Registration, + void **Interface); + +typedef EFI_STATUS(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)( + EFI_HANDLE Handle, ...); +typedef EFI_STATUS(EFIAPI *EFI_CALCULATE_CRC32)(void *Data, size_t DataSize, + uint32_t *Crc32); + +typedef void(EFIAPI *EFI_COPY_MEM)(void *Destination, void *Source, + size_t Length); +typedef void(EFIAPI *EFI_SET_MEM)(void *Buffer, size_t Size, uint8_t Value); + +typedef EFI_STATUS(EFIAPI *EFI_CREATE_EVENT_EX)( + uint32_t Type, EFI_TPL NotifyTpl, EFI_EVENT_NOTIFY NotifyFunction, + const void *NotifyContext, const EFI_GUID *EventGroup, EFI_EVENT *Event); + +typedef struct { + EFI_TABLE_HEADER Hdr; + + // + // Task Priority Services + // + EFI_RAISE_TPL RaiseTPL; // EFI 1.0+ + EFI_RESTORE_TPL RestoreTPL; // EFI 1.0+ + + // + // Memory Services + // + EFI_ALLOCATE_PAGES AllocatePages; // EFI 1.0+ + EFI_FREE_PAGES FreePages; // EFI 1.0+ + EFI_GET_MEMORY_MAP GetMemoryMap; // EFI 1.0+ + EFI_ALLOCATE_POOL AllocatePool; // EFI 1.0+ + EFI_FREE_POOL FreePool; // EFI 1.0+ + + // + // Event & Timer Services + // + EFI_CREATE_EVENT CreateEvent; // EFI 1.0+ + EFI_SET_TIMER SetTimer; // EFI 1.0+ + EFI_WAIT_FOR_EVENT WaitForEvent; // EFI 1.0+ + EFI_SIGNAL_EVENT SignalEvent; // EFI 1.0+ + EFI_CLOSE_EVENT CloseEvent; // EFI 1.0+ + EFI_CHECK_EVENT CheckEvent; // EFI 1.0+ + + // + // Protocol Handler Services + // + EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; // EFI 1.0+ + EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; // EFI 1.0+ + EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; // EFI 1.0+ + EFI_HANDLE_PROTOCOL HandleProtocol; // EFI 1.0+ + void *Reserved; // EFI 1.0+ + EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; // EFI 1.0+ + EFI_LOCATE_HANDLE LocateHandle; // EFI 1.+ + EFI_LOCATE_DEVICE_PATH LocateDevicePath; // EFI 1.0+ + EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; // EFI 1.0+ + + // + // Image Services + // + EFI_IMAGE_UNLOAD LoadImage; // EFI 1.0+ + EFI_IMAGE_START StartImage; // EFI 1.0+ + EFI_EXIT Exit; // EFI 1.0+ + EFI_IMAGE_UNLOAD UnloadImage; // EFI 1.0+ + EFI_EXIT_BOOT_SERVICES ExitBootServices; // EFI 1.0+ + + // + // Miscellaneous Services + // + EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; // EFI 1.0+ + EFI_STALL Stall; // EFI 1.0+ + EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; // EFI 1.0+ + + // + // DriverSupport Services + // + EFI_CONNECT_CONTROLLER ConnectController; // EFI 1.1 + EFI_DISCONNECT_CONTROLLER DisconnectController; // EFI 1.1+ + + // + // Open and Close Protocol Services + // + EFI_OPEN_PROTOCOL OpenProtocol; // EFI 1.1+ + EFI_CLOSE_PROTOCOL CloseProtocol; // EFI 1.1+ + EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation; // EFI 1.1+ + + // + // Library Services + // + EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle; // EFI 1.1+ + EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer; // EFI 1.1+ + EFI_LOCATE_PROTOCOL LocateProtocol; // EFI 1.1+ + EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES + InstallMultipleProtocolInterfaces; // EFI 1.1+ + EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES + UninstallMultipleProtocolInterfaces; // EFI 1.1+* + + // + // 32-bit CRC Services + // + EFI_CALCULATE_CRC32 CalculateCrc32; // EFI 1.1+ + + // + // Miscellaneous Services + // + EFI_COPY_MEM CopyMem; // EFI 1.1+ + EFI_SET_MEM SetMem; // EFI 1.1+ + EFI_CREATE_EVENT_EX CreateEventEx; // UEFI 2.0+ +} EFI_BOOT_SERVICES; + +#endif // LLVM_LIBC_TYPES_EFI_BOOT_SERVICES_H diff --git a/libc/include/llvm-libc-types/EFI_CAPSULE.h b/libc/include/llvm-libc-types/EFI_CAPSULE.h new file mode 100644 index 0000000000000..c7440c9b03b75 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_CAPSULE.h @@ -0,0 +1,26 @@ +//===-- Definition of EFI_CAPSULE type ------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_CAPSULE_H +#define LLVM_LIBC_TYPES_EFI_CAPSULE_H + +#include "../llvm-libc-macros/stdint-macros.h" +#include "EFI_GUID.h" + +typedef struct { + EFI_GUID CapsuleGuid; + uint32_t HeaderSize; + uint32_t Flags; + uint32_t CapsuleImageSize; +} EFI_CAPSULE_HEADER; + +#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 +#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 +#define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 + +#endif // LLVM_LIBC_TYPES_EFI_CAPSULE_H diff --git a/libc/include/llvm-libc-types/EFI_CONFIGURATION_TABLE.h b/libc/include/llvm-libc-types/EFI_CONFIGURATION_TABLE.h new file mode 100644 index 0000000000000..56cd3e4fbb587 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_CONFIGURATION_TABLE.h @@ -0,0 +1,19 @@ +//===-- Definition of EFI_CONFIGURATION_TABLE type ------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_CONFIGURATION_TABLE_H +#define LLVM_LIBC_TYPES_EFI_CONFIGURATION_TABLE_H + +#include "EFI_GUID.h" + +typedef struct { + EFI_GUID VendorGuid; + void *VendorTable; +} EFI_CONFIGURATION_TABLE; + +#endif // LLVM_LIBC_TYPES_EFI_CONFIGURATION_TABLE_H diff --git a/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h new file mode 100644 index 0000000000000..3f186cf245d89 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h @@ -0,0 +1,27 @@ +//===-- Definition of EFI_DEVICE_PATH_PROTOCOL type -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_DEVICE_PATH_PROTOCOL_H +#define LLVM_LIBC_TYPES_EFI_DEVICE_PATH_PROTOCOL_H + +#include "../llvm-libc-macros/stdint-macros.h" + +#define EFI_DEVICE_PATH_PROTOCOL_GUID \ + { \ + 0x09576e91, 0x6d3f, 0x11d2, { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ + } + +typedef struct _EFI_DEVICE_PATH_PROTOCOL { + uint8_t Type; + uint8_t SubType; + uint8_t Length[2]; +} EFI_DEVICE_PATH_PROTOCOL; + +#endif // LLVM_LIBC_TYPES_EFI_DEVICE_PATH_PROTOCOL_H diff --git a/libc/include/llvm-libc-types/EFI_EVENT.h b/libc/include/llvm-libc-types/EFI_EVENT.h new file mode 100644 index 0000000000000..938856b8e791e --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_EVENT.h @@ -0,0 +1,21 @@ +//===-- Definition of EFI_EVENT type --------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_EVENT_H +#define LLVM_LIBC_TYPES_EFI_EVENT_H + +typedef void *EFI_EVENT; + +#define EVT_TIMER 0x80000000 +#define EVT_RUNTIME 0x40000000 +#define EVT_NOTIFY_WAIT 0x00000100 +#define EVT_NOTIFY_SIGNAL 0x00000200 +#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#endif // LLVM_LIBC_TYPES_EFI_EVENT_H diff --git a/libc/include/llvm-libc-types/EFI_GUID.h b/libc/include/llvm-libc-types/EFI_GUID.h new file mode 100644 index 0000000000000..b3530008384dd --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_GUID.h @@ -0,0 +1,21 @@ +//===-- Definition of EFI_GUID type -----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_GUID_H +#define LLVM_LIBC_TYPES_EFI_GUID_H + +#include "../llvm-libc-macros/stdint-macros.h" + +typedef struct { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +} EFI_GUID; + +#endif // LLVM_LIBC_TYPES_EFI_GUID_H diff --git a/libc/include/llvm-libc-types/EFI_HANDLE.h b/libc/include/llvm-libc-types/EFI_HANDLE.h new file mode 100644 index 0000000000000..d4376dd247533 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_HANDLE.h @@ -0,0 +1,14 @@ +//===-- Definition of EFI_HANDLE type ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_HANDLE_H +#define LLVM_LIBC_TYPES_EFI_HANDLE_H + +typedef void *EFI_HANDLE; + +#endif // LLVM_LIBC_TYPES_EFI_HANDLE_H diff --git a/libc/include/llvm-libc-types/EFI_INTERFACE_TYPE.h b/libc/include/llvm-libc-types/EFI_INTERFACE_TYPE.h new file mode 100644 index 0000000000000..d463c5381b3f0 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_INTERFACE_TYPE.h @@ -0,0 +1,16 @@ +//===-- Definition of EFI_INTERFACE_TYPE type -----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_INTERFACE_TYPE_H +#define LLVM_LIBC_TYPES_EFI_INTERFACE_TYPE_H + +typedef enum { + EFI_NATIVE_INTERFACE, +} EFI_INTERFACE_TYPE; + +#endif // LLVM_LIBC_TYPES_EFI_INTERFACE_TYPE_H diff --git a/libc/include/llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h b/libc/include/llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h new file mode 100644 index 0000000000000..3a8fd7bc3e776 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_LOCATE_SEARCH_TYPE.h @@ -0,0 +1,18 @@ +//===-- Definition of EFI_LOCATE_SEARCH_TYPE type -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_LOCATE_SEARCH_TYPE_H +#define LLVM_LIBC_TYPES_EFI_LOCATE_SEARCH_TYPE_H + +typedef enum { + AllHandles, + ByRegisterNotify, + ByProtocol, +} EFI_LOCATE_SEARCH_TYPE; + +#endif // LLVM_LIBC_TYPES_EFI_LOCATE_SEARCH_TYPE_H diff --git a/libc/include/llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h b/libc/include/llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h new file mode 100644 index 0000000000000..72d0579aef76c --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_MEMORY_DESCRIPTOR.h @@ -0,0 +1,43 @@ +//===-- Definition of EFI_MEMORY_DESCRIPTOR type --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_MEMORY_DESCRIPTOR_H +#define LLVM_LIBC_TYPES_EFI_MEMORY_DESCRIPTOR_H + +#include "../llvm-libc-macros/stdint-macros.h" +#include "EFI_PHYSICAL_ADDRESS.h" +#include "EFI_VIRTUAL_ADDRESS.h" + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 + +#define EFI_MEMORY_UC 0x0000000000000001 +#define EFI_MEMORY_WC 0x0000000000000002 +#define EFI_MEMORY_WT 0x0000000000000004 +#define EFI_MEMORY_WB 0x0000000000000008 +#define EFI_MEMORY_UCE 0x0000000000000010 +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 +#define EFI_MEMORY_NV 0x0000000000008000 +#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000 +#define EFI_MEMORY_RO 0x0000000000020000 +#define EFI_MEMORY_SP 0x0000000000040000 +#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000 +#define EFI_MEMORY_RUNTIME 0x8000000000000000 +#define EFI_MEMORY_ISA_VALID 0x4000000000000000 +#define EFI_MEMORY_ISA_MASK 0x0FFFF00000000000 + +typedef struct { + uint32_t Type; + EFI_PHYSICAL_ADDRESS PhysicalStart; + EFI_VIRTUAL_ADDRESS VirtualStart; + uint64_t NumberOfPages; + uint64_t Attribute; +} EFI_MEMORY_DESCRIPTOR; + +#endif // LLVM_LIBC_TYPES_EFI_MEMORY_DESCRIPTOR_H diff --git a/libc/include/llvm-libc-types/EFI_MEMORY_TYPE.h b/libc/include/llvm-libc-types/EFI_MEMORY_TYPE.h new file mode 100644 index 0000000000000..c8921cda2c388 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_MEMORY_TYPE.h @@ -0,0 +1,32 @@ +//===-- Definition of EFI_MEMORY_TYPE type --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_MEMORY_TYPE_H +#define LLVM_LIBC_TYPES_EFI_MEMORY_TYPE_H + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiPersistentMemory, + EfiUnacceptedMemoryType, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +#endif // LLVM_LIBC_TYPES_EFI_MEMORY_TYPE_H diff --git a/libc/include/llvm-libc-types/EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h b/libc/include/llvm-libc-types/EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h new file mode 100644 index 0000000000000..de0c59c139efb --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h @@ -0,0 +1,22 @@ +//===-- Definition of EFI_OPEN_PROTOCOL_INFORMATION_ENTRY type ------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_OPEN_PROTOCOL_INFORMATION_ENTRY_H +#define LLVM_LIBC_TYPES_EFI_OPEN_PROTOCOL_INFORMATION_ENTRY_H + +#include "../llvm-libc-macros/stdint-macros.h" +#include "EFI_HANDLE.h" + +typedef struct { + EFI_HANDLE AgentHandle; + EFI_HANDLE ControllerHandle; + uint32_t Attributes; + uint32_t OpenCount; +} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY; + +#endif // LLVM_LIBC_TYPES_EFI_OPEN_PROTOCOL_INFORMATION_ENTRY_H diff --git a/libc/include/llvm-libc-types/EFI_PHYSICAL_ADDRESS.h b/libc/include/llvm-libc-types/EFI_PHYSICAL_ADDRESS.h new file mode 100644 index 0000000000000..8880ee66c0f8d --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_PHYSICAL_ADDRESS.h @@ -0,0 +1,16 @@ +//===-- Definition of EFI_PHYSICAL_ADDRESS type ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_PHYSICAL_ADDRESS_H +#define LLVM_LIBC_TYPES_EFI_PHYSICAL_ADDRESS_H + +#include "../llvm-libc-macros/stdint-macros.h" + +typedef uint64_t EFI_PHYSICAL_ADDRESS; + +#endif // LLVM_LIBC_TYPES_EFI_PHYSICAL_ADDRESS_H diff --git a/libc/include/llvm-libc-types/EFI_RUNTIME_SERVICES.h b/libc/include/llvm-libc-types/EFI_RUNTIME_SERVICES.h new file mode 100644 index 0000000000000..aca1fd6d66297 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_RUNTIME_SERVICES.h @@ -0,0 +1,134 @@ +//===-- Definition of EFI_RUNTIME_SERVICES type ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_RUNTIME_SERVICES_H +#define LLVM_LIBC_TYPES_EFI_RUNTIME_SERVICES_H + +#include "../llvm-libc-macros/EFIAPI-macros.h" +#include "EFI_CAPSULE.h" +#include "EFI_MEMORY_DESCRIPTOR.h" +#include "EFI_PHYSICAL_ADDRESS.h" +#include "EFI_STATUS.h" +#include "EFI_TABLE_HEADER.h" +#include "EFI_TIME.h" +#include "char16_t.h" + +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 +#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION + +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +// This attribute is identified by the mnemonic 'HR' elsewhere +// in this specification. +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +// NOTE: EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated +// and should be considered reserved. +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 +#define EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS 0x00000080 + +typedef enum { + EfiResetCold, + EfiResetWarm, + EfiResetShutdown, + EfiResetPlatformSpecific, +} EFI_RESET_TYPE; + +#define EFI_VARIABLE_AUTHENTICATION_3_CERT_ID_SHA256 1 + +typedef struct { + uint8_t Type; + uint32_t IdSize; + // uint8_t Id[IdSize]; +} EFI_VARIABLE_AUTHENTICATION_3_CERT_ID; + +typedef EFI_STATUS(EFIAPI *EFI_GET_TIME)(EFI_TIME *Time, + EFI_TIME_CAPABILITIES *Capabilities); +typedef EFI_STATUS(EFIAPI *EFI_SET_TIME)(EFI_TIME *Time); +typedef EFI_STATUS(EFIAPI *EFI_GET_WAKEUP_TIME)(bool *Enabled, bool *Pending, + EFI_TIME *Time); +typedef EFI_STATUS(EFIAPI *EFI_SET_WAKEUP_TIME)(bool *Enabled, EFI_TIME *Time); + +typedef EFI_STATUS(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)( + size_t MemoryMapSize, size_t DescriptorSize, uint32_t DescriptorVersion, + EFI_MEMORY_DESCRIPTOR *VirtualMap); +typedef EFI_STATUS(EFIAPI *EFI_CONVERT_POINTER)(size_t DebugDisposition, + void **Address); + +typedef EFI_STATUS(EFIAPI *EFI_GET_VARIABLE)(char16_t *VariableName, + EFI_GUID *VendorGuid, + uint32_t *Attributes, + size_t *DataSize, void *Data); +typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)(size_t *VariableNameSize, + char16_t *VariableName, + EFI_GUID *VendorGuid); +typedef EFI_STATUS(EFIAPI *EFI_SET_VARIABLE)(char16_t *VariableName, + EFI_GUID *VendorGuid, + uint32_t Attributes, + size_t DataSize, void *Data); + +typedef EFI_STATUS(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT)(uint32_t *HighCount); +typedef void(EFIAPI *EFI_RESET_SYSTEM)(EFI_RESET_TYPE ResetType, + EFI_STATUS ResetStatus, size_t DataSize, + void *ResetData); + +typedef EFI_STATUS(EFIAPI *EFI_UPDATE_CAPSULE)( + EFI_CAPSULE_HEADER **CapsuleHeaderArray, size_t CapsuleCount, + EFI_PHYSICAL_ADDRESS ScatterGatherList); +typedef EFI_STATUS(EFIAPI *EFI_QUERY_CAPSULE_CAPABILITIES)( + EFI_CAPSULE_HEADER **CapsuleHeaderArray, size_t CapsuleCount, + uint64_t *MaximumCapsuleSize, EFI_RESET_TYPE ResetType); + +typedef EFI_STATUS(EFIAPI *EFI_QUERY_VARIABLE_INFO)( + uint32_t Attributes, uint64_t *MaximumVariableStorageSize, + uint64_t *RemainingVariableStorageSize, uint64_t *MaximumVariableSize); + +typedef struct { + EFI_TABLE_HEADER Hdr; + + /// + /// Time Services + EFI_GET_TIME GetTime; + EFI_SET_TIME SetTime; + EFI_GET_WAKEUP_TIME GetWakeupTime; + EFI_SET_WAKEUP_TIME SetWakeupTime; + + // + // Virtual Memory Services + // + EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; + EFI_CONVERT_POINTER ConvertPointer; + + // + // Variable Services + // + EFI_GET_VARIABLE GetVariable; + EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; + EFI_SET_VARIABLE SetVariable; + + // + // Miscellaneous Services + // + EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount; + EFI_RESET_SYSTEM ResetSystem; + + // + // UEFI 2.0 Capsule Services + // + EFI_UPDATE_CAPSULE UpdateCapsule; + EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities; + + // + // Miscellaneous UEFI 2.0 Service + // + EFI_QUERY_VARIABLE_INFO QueryVariableInfo; +} EFI_RUNTIME_SERVICES; + +#endif // LLVM_LIBC_TYPES_EFI_RUNTIME_SERVICES_H diff --git a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h new file mode 100644 index 0000000000000..a290c5c7c3095 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h @@ -0,0 +1,41 @@ +//===-- Definition of EFI_SIMPLE_TEXT_INPUT_PROTOCOL type -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H +#define LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H + +#include "../llvm-libc-macros/stdint-macros.h" +#include "EFI_STATUS.h" +#include "char16_t.h" + +#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ + { \ + 0x387477c1, 0x69c7, 0x11d2, { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ + } + +typedef struct { + uint16_t ScanCode; + char16_t UnicodeChar; +} EFI_INPUT_KEY; + +struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL; + +typedef EFI_STATUS(EFIAPI *EFI_INPUT_RESET)( + struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, bool ExtendedVerification); +typedef EFI_STATUS(EFIAPI *EFI_INPUT_READ_KEY)( + struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, EFI_INPUT_KEY *Key); + +typedef struct _EFI_SIMPLE_TEXT_INPUT_PROTOCOL { + EFI_INPUT_RESET Reset; + EFI_INPUT_READ_KEY ReadKeyStroke; + EFI_EVENT WaitForKey; +} EFI_SIMPLE_TEXT_INPUT_PROTOCOL; + +#endif // LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H diff --git a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h new file mode 100644 index 0000000000000..307db79e1b318 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h @@ -0,0 +1,68 @@ +//===-- Definition of EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL type ----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_H +#define LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_H + +#include "../llvm-libc-macros/stdint-macros.h" +#include "EFI_STATUS.h" +#include "size_t.h" + +#define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ + { \ + 0x387477c2, 0x69c7, 0x11d2, { \ + 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ + } \ + } + +struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; + +typedef EFI_STATUS(EFIAPI *EFI_TEXT_RESET)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, bool ExtendedVerification); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_STRING)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, const char16_t *String); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_TEST_STRING)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, const char16_t *String); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_QUERY_MODE)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, size_t ModeNumber, + size_t *Columns, size_t *Rows); + +typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_MODE)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, size_t ModeNumber); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_ATTRIBUTE)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, size_t Attribute); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_CLEAR_SCREEN)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, size_t Column, size_t Row); +typedef EFI_STATUS(EFIAPI *EFI_TEXT_ENABLE_CURSOR)( + struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This, bool Visible); + +typedef struct { + int32_t MaxMode; + int32_t Mode; + int32_t Attribute; + int32_t CursorColumn; + int32_t CursorRow; + bool CursorVisible; +} SIMPLE_TEXT_OUTPUT_MODE; + +typedef struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL { + EFI_TEXT_RESET Reset; + EFI_TEXT_STRING OutputString; + EFI_TEXT_TEST_STRING TestString; + EFI_TEXT_QUERY_MODE QueryMode; + EFI_TEXT_SET_MODE SetMode; + EFI_TEXT_SET_ATTRIBUTE SetAttribute; + EFI_TEXT_CLEAR_SCREEN ClearScreen; + EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; + EFI_TEXT_ENABLE_CURSOR EnableCursor; + SIMPLE_TEXT_OUTPUT_MODE *Mode; +} EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; + +#endif // LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_H diff --git a/libc/include/llvm-libc-types/EFI_STATUS.h b/libc/include/llvm-libc-types/EFI_STATUS.h new file mode 100644 index 0000000000000..f7fa6e52381e1 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_STATUS.h @@ -0,0 +1,16 @@ +//===-- Definition of EFI_STATUS type ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_STATUS_H +#define LLVM_LIBC_TYPES_EFI_STATUS_H + +#include "size_t.h" + +typedef size_t EFI_STATUS; + +#endif // LLVM_LIBC_TYPES_EFI_STATUS_H diff --git a/libc/include/llvm-libc-types/EFI_SYSTEM_TABLE.h b/libc/include/llvm-libc-types/EFI_SYSTEM_TABLE.h new file mode 100644 index 0000000000000..c1fbdf98381db --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_SYSTEM_TABLE.h @@ -0,0 +1,63 @@ +//===-- Definition of EFI_SYSTEM_TABLE type -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_SYSTEM_TABLE_H +#define LLVM_LIBC_TYPES_EFI_SYSTEM_TABLE_H + +#include "EFI_BOOT_SERVICES.h" +#include "EFI_CONFIGURATION_TABLE.h" +#include "EFI_HANDLE.h" +#include "EFI_RUNTIME_SERVICES.h" +#include "EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h" +#include "EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h" +#include "EFI_STATUS.h" +#include "EFI_TABLE_HEADER.h" + +#include "char16_t.h" + +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 +#define EFI_2_100_SYSTEM_TABLE_REVISION ((2 << 16) | (100)) +#define EFI_2_90_SYSTEM_TABLE_REVISION ((2 << 16) | (90)) +#define EFI_2_80_SYSTEM_TABLE_REVISION ((2 << 16) | (80)) +#define EFI_2_70_SYSTEM_TABLE_REVISION ((2 << 16) | (70)) +#define EFI_2_60_SYSTEM_TABLE_REVISION ((2 << 16) | (60)) +#define EFI_2_50_SYSTEM_TABLE_REVISION ((2 << 16) | (50)) +#define EFI_2_40_SYSTEM_TABLE_REVISION ((2 << 16) | (40)) +#define EFI_2_31_SYSTEM_TABLE_REVISION ((2 << 16) | (31)) +#define EFI_2_30_SYSTEM_TABLE_REVISION ((2 << 16) | (30)) +#define EFI_2_20_SYSTEM_TABLE_REVISION ((2 << 16) | (20)) +#define EFI_2_10_SYSTEM_TABLE_REVISION ((2 << 16) | (10)) +#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00)) +#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10)) +#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02)) +#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION +#define EFI_SYSTEM_TABLE_REVISION EFI_2_100_SYSTEM_TABLE_REVISION + +typedef struct { + EFI_TABLE_HEADER Hdr; + + char16_t *FirmwareVendor; + uint32_t FirmwareRevision; + + EFI_HANDLE ConsoleInHandle; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; + + EFI_HANDLE ConsoleOutHandle; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; + + EFI_HANDLE StandardErrorHandle; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr; + + EFI_RUNTIME_SERVICES *RuntimeServices; + EFI_BOOT_SERVICES *BootServices; + + size_t NumberOfTableEntries; + EFI_CONFIGURATION_TABLE *ConfigurationTable; +} EFI_SYSTEM_TABLE; + +#endif // LLVM_LIBC_TYPES_EFI_SYSTEM_TABLE_H diff --git a/libc/include/llvm-libc-types/EFI_TABLE_HEADER.h b/libc/include/llvm-libc-types/EFI_TABLE_HEADER.h new file mode 100644 index 0000000000000..293968ecc4d1b --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_TABLE_HEADER.h @@ -0,0 +1,22 @@ +//===-- Definition of EFI_TABLE_HEADER type -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_TABLE_HEADER_H +#define LLVM_LIBC_TYPES_EFI_TABLE_HEADER_H + +#include "../llvm-libc-macros/stdint-macros.h" + +typedef struct { + uint64_t Signature; + uint32_t Revision; + uint32_t HeaderSize; + uint32_t CRC32; + uint32_t Reserved; +} EFI_TABLE_HEADER; + +#endif // LLVM_LIBC_TYPES_EFI_TABLE_HEADER_H diff --git a/libc/include/llvm-libc-types/EFI_TIME.h b/libc/include/llvm-libc-types/EFI_TIME.h new file mode 100644 index 0000000000000..b0e38b987d44e --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_TIME.h @@ -0,0 +1,37 @@ +//===-- Definition of EFI_TIME type ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_TIME_H +#define LLVM_LIBC_TYPES_EFI_TIME_H + +#include "../llvm-libc-macros/stdint-macros.h" + +typedef struct { + uint16_t Year; // 1900 - 9999 + uint8_t Month; // 1 - 12 + uint8_t Day; // 1 - 31 + uint8_t Hour; // 0 - 23 + uint8_t Minute; // 0 - 59 + uint8_t Second; // 0 - 59 + uint8_t Pad1; + uint32_t Nanosecond; // 0 - 999,999,999 + int16_t TimeZone; // --1440 to 1440 or 2047 +} EFI_TIME; + +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + +typedef struct { + uint32_t Resolution; + uint32_t Accuracy; + bool SetsToZero; +} EFI_TIME_CAPABILITIES; + +#endif // LLVM_LIBC_TYPES_EFI_TIME_H diff --git a/libc/include/llvm-libc-types/EFI_TIMER_DELAY.h b/libc/include/llvm-libc-types/EFI_TIMER_DELAY.h new file mode 100644 index 0000000000000..2a6872c69c8b3 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_TIMER_DELAY.h @@ -0,0 +1,18 @@ +//===-- Definition of EFI_TIMER_DELAY type --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_TIMER_DELAY_H +#define LLVM_LIBC_TYPES_EFI_TIMER_DELAY_H + +typedef enum { + TimerCancel, + TimerPeriodic, + TimerRelative, +} EFI_TIMER_DELAY; + +#endif // LLVM_LIBC_TYPES_EFI_TIMER_DELAY_H diff --git a/libc/include/llvm-libc-types/EFI_TPL.h b/libc/include/llvm-libc-types/EFI_TPL.h new file mode 100644 index 0000000000000..8361ccfacd6f5 --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_TPL.h @@ -0,0 +1,21 @@ +//===-- Definition of EFI_TPL type ----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_TPL_H +#define LLVM_LIBC_TYPES_EFI_TPL_H + +#include "size_t.h" + +typedef size_t EFI_TPL; + +#define TPL_APPLICATION 4 +#define TPL_CALLBACK 8 +#define TPL_NOTIFY 16 +#define TPL_HIGH_LEVEL 31 + +#endif // LLVM_LIBC_TYPES_EFI_TPL_H diff --git a/libc/include/llvm-libc-types/EFI_VIRTUAL_ADDRESS.h b/libc/include/llvm-libc-types/EFI_VIRTUAL_ADDRESS.h new file mode 100644 index 0000000000000..46cbec734dadc --- /dev/null +++ b/libc/include/llvm-libc-types/EFI_VIRTUAL_ADDRESS.h @@ -0,0 +1,16 @@ +//===-- Definition of EFI_VIRTUAL_ADDRESS type ----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_TYPES_EFI_VIRTUAL_ADDRESS_H +#define LLVM_LIBC_TYPES_EFI_VIRTUAL_ADDRESS_H + +#include "../llvm-libc-macros/stdint-macros.h" + +typedef uint64_t EFI_VIRTUAL_ADDRESS; + +#endif // LLVM_LIBC_TYPES_EFI_VIRTUAL_ADDRESS_H diff --git a/libc/src/__support/OSUtil/io.h b/libc/src/__support/OSUtil/io.h index 80119da77fc02..86857da4c30a7 100644 --- a/libc/src/__support/OSUtil/io.h +++ b/libc/src/__support/OSUtil/io.h @@ -24,6 +24,8 @@ #elif defined(__ELF__) // TODO: Ideally we would have LIBC_TARGET_OS_IS_BAREMETAL. #include "baremetal/io.h" +#elif defined(__uefi__) +#include "uefi/io.h" #endif #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_IO_H diff --git a/libc/src/__support/OSUtil/uefi/CMakeLists.txt b/libc/src/__support/OSUtil/uefi/CMakeLists.txt new file mode 100644 index 0000000000000..79ec8ab602456 --- /dev/null +++ b/libc/src/__support/OSUtil/uefi/CMakeLists.txt @@ -0,0 +1,11 @@ +add_object_library( + uefi_util + SRCS + io.cpp + exit.cpp + HDRS + io.h + DEPENDS + libc.src.__support.common + libc.src.__support.CPP.string_view +) diff --git a/libc/src/__support/OSUtil/uefi/exit.cpp b/libc/src/__support/OSUtil/uefi/exit.cpp new file mode 100644 index 0000000000000..ab7530ef88786 --- /dev/null +++ b/libc/src/__support/OSUtil/uefi/exit.cpp @@ -0,0 +1,23 @@ +//===-------- UEFI implementation of an exit function ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/OSUtil/exit.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { +namespace internal { + +[[noreturn]] void exit(int status) { + (void)status; + // TODO: call boot services to exit + while (true) { + } +} + +} // namespace internal +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/OSUtil/uefi/io.cpp b/libc/src/__support/OSUtil/uefi/io.cpp new file mode 100644 index 0000000000000..c80731ea888d3 --- /dev/null +++ b/libc/src/__support/OSUtil/uefi/io.cpp @@ -0,0 +1,26 @@ +//===---------- UEFI implementation of IO utils ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===-----------------------------------------------------------------===// + +#include "io.h" + +#include "src/__support/CPP/string_view.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +ssize_t read_from_stdin(char *buf, size_t size) { + (void)buf; + (void)size; + return 0; +} + +void write_to_stdout(cpp::string_view msg) { (void)msg; } + +void write_to_stderr(cpp::string_view msg) { (void)msg; } + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/OSUtil/uefi/io.h b/libc/src/__support/OSUtil/uefi/io.h new file mode 100644 index 0000000000000..088ae09b8c602 --- /dev/null +++ b/libc/src/__support/OSUtil/uefi/io.h @@ -0,0 +1,25 @@ +//===---------- UEFI implementation of IO utils ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===-----------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_UEFI_IO_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_UEFI_IO_H + +#include "include/llvm-libc-types/size_t.h" +#include "include/llvm-libc-types/ssize_t.h" +#include "src/__support/CPP/string_view.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +ssize_t read_from_stdin(char *buf, size_t size); +void write_to_stderr(cpp::string_view msg); +void write_to_stdout(cpp::string_view msg); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_UEFI_IO_H diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt index b9bc904471df9..776ca103a841f 100644 --- a/libc/src/stdio/CMakeLists.txt +++ b/libc/src/stdio/CMakeLists.txt @@ -22,7 +22,7 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) endif() -if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU) +if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU AND NOT LIBC_TARGET_OS_IS_UEFI) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/generic) endif() diff --git a/libc/src/stdio/uefi/CMakeLists.txt b/libc/src/stdio/uefi/CMakeLists.txt new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/libc/startup/uefi/CMakeLists.txt b/libc/startup/uefi/CMakeLists.txt new file mode 100644 index 0000000000000..01e95f8520c68 --- /dev/null +++ b/libc/startup/uefi/CMakeLists.txt @@ -0,0 +1,56 @@ +function(add_startup_object name) + cmake_parse_arguments( + "ADD_STARTUP_OBJECT" + "ALIAS" # Option argument + "SRC" # Single value arguments + "DEPENDS;COMPILE_OPTIONS" # Multi value arguments + ${ARGN} + ) + + get_fq_target_name(${name} fq_target_name) + if(ADD_STARTUP_OBJECT_ALIAS) + get_fq_deps_list(fq_dep_list ${ADD_STARTUP_OBJECT_DEPENDS}) + add_library(${fq_target_name} ALIAS ${fq_dep_list}) + return() + endif() + + add_object_library( + ${name} + SRCS ${ADD_STARTUP_OBJECT_SRC} + COMPILE_OPTIONS ${ADD_STARTUP_OBJECT_COMPILE_OPTIONS} + ${ADD_STARTUP_OBJECT_UNPARSED_ARGUMENTS} + DEPENDS ${ADD_STARTUP_OBJECT_DEPENDS} + ) + set_target_properties( + ${fq_target_name} + PROPERTIES + OUTPUT_NAME ${name}.o + ) + + # Make an executable target of relocatable bitcode for clang if needed. + if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR) + add_executable(${fq_target_name}.exe $) + set_target_properties(${fq_target_name}.exe PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${LIBC_LIBRARY_DIR} + RUNTIME_OUTPUT_NAME ${name}.o) + target_link_options(${fq_target_name}.exe PRIVATE + "-r" "-nostdlib" "-flto" "-Wl,--lto-emit-llvm") + endif() +endfunction() + +add_startup_object( + crt1 + SRCS + crt1.cpp +) + +add_custom_target(libc-startup) +set(startup_components crt1) +foreach(target IN LISTS startup_components) + set(fq_target_name libc.startup.uefi.${target}) + add_dependencies(libc-startup ${fq_target_name}) + install(FILES $ + DESTINATION ${LIBC_INSTALL_LIBRARY_DIR} + RENAME $ + COMPONENT libc) +endforeach() diff --git a/libc/startup/uefi/crt1.cpp b/libc/startup/uefi/crt1.cpp new file mode 100644 index 0000000000000..c4c5e5fde7d64 --- /dev/null +++ b/libc/startup/uefi/crt1.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of crt for UEFI ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--------------------------------------------------------------------===// + +#include "include/llvm-libc-macros/stdlib-macros.h" +#include "include/llvm-libc-types/EFI_HANDLE.h" +#include "include/llvm-libc-types/EFI_STATUS.h" +#include "include/llvm-libc-types/EFI_SYSTEM_TABLE.h" +#include "src/__support/macros/config.h" + +extern "C" int main(int argc, char **argv, char **envp); + +extern "C" EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, + EFI_SYSTEM_TABLE *SystemTable) { + (void)ImageHandle; + (void)SystemTable; + main(0, NULL, NULL); + // TODO: convert the return value of main to EFI_STATUS + return 0; // TODO: EFI_SUCCESS +} diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt index 8d175e857fcd1..6358f1d14360a 100644 --- a/libc/test/src/__support/CMakeLists.txt +++ b/libc/test/src/__support/CMakeLists.txt @@ -1,6 +1,6 @@ add_custom_target(libc-support-tests) -if(NOT LIBC_TARGET_OS_IS_GPU) +if(NOT LIBC_TARGET_OS_IS_GPU AND NOT LIBC_TARGET_OS_IS_UEFI) add_libc_test( block_test SUITE @@ -251,7 +251,7 @@ add_libc_test( # FIXME: We shouldn't have regular executables created because we could be # cross-compiling the tests and running through an emulator. -if(NOT LIBC_TARGET_OS_IS_GPU) +if(NOT LIBC_TARGET_OS_IS_GPU AND NOT LIBC_TARGET_OS_IS_UEFI) add_executable( libc_str_to_float_comparison_test str_to_float_comparison_test.cpp From 9150a6259d5b9cc46d5a49c4aba6c98d8e8d25fe Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 20 Dec 2024 09:41:01 -0800 Subject: [PATCH 02/23] [libc] save efi image handle and system table in crt1 --- libc/include/Uefi.yaml | 6 +++++- libc/startup/uefi/crt1.cpp | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/libc/include/Uefi.yaml b/libc/include/Uefi.yaml index f17e629c87cc7..28582eb2524b1 100644 --- a/libc/include/Uefi.yaml +++ b/libc/include/Uefi.yaml @@ -8,4 +8,8 @@ types: - type_name: EFI_SYSTEM_TABLE enums: [] functions: [] -objects: [] +objects: + - object_name: efi_system_table + object_type: EFI_SYSTEM_TABLE * + - object_name: efi_image_handle + object_type: EFI_HANDLE diff --git a/libc/startup/uefi/crt1.cpp b/libc/startup/uefi/crt1.cpp index c4c5e5fde7d64..44570cb89010c 100644 --- a/libc/startup/uefi/crt1.cpp +++ b/libc/startup/uefi/crt1.cpp @@ -12,12 +12,16 @@ #include "include/llvm-libc-types/EFI_SYSTEM_TABLE.h" #include "src/__support/macros/config.h" +EFI_HANDLE efi_image_handle; +EFI_SYSTEM_TABLE *efi_system_table; + extern "C" int main(int argc, char **argv, char **envp); extern "C" EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { - (void)ImageHandle; - (void)SystemTable; + efi_image_handle = ImageHandle; + efi_system_table = SystemTable; + main(0, NULL, NULL); // TODO: convert the return value of main to EFI_STATUS return 0; // TODO: EFI_SUCCESS From 52abff6d92b309a89f02eb992b8175fa4659ff5c Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 20 Dec 2024 09:47:11 -0800 Subject: [PATCH 03/23] [libc] implement uefi exit() --- libc/include/llvm-libc-types/CMakeLists.txt | 1 + libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h | 1 + libc/src/__support/OSUtil/uefi/CMakeLists.txt | 1 + libc/src/__support/OSUtil/uefi/exit.cpp | 9 +++++---- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index d31a84b4dc64d..557257c615d1e 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -247,6 +247,7 @@ add_header(EFI_BOOT_SERVICES .EFI_MEMORY_TYPE .EFI_OPEN_PROTOCOL_INFORMATION_ENTRY .EFI_PHYSICAL_ADDRESS + .EFI_STATUS .EFI_TABLE_HEADER .EFI_TIMER_DELAY .EFI_TPL diff --git a/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h b/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h index 362e64846e4fa..8b7a6aadd7a24 100644 --- a/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h +++ b/libc/include/llvm-libc-types/EFI_BOOT_SERVICES.h @@ -20,6 +20,7 @@ #include "EFI_MEMORY_TYPE.h" #include "EFI_OPEN_PROTOCOL_INFORMATION_ENTRY.h" #include "EFI_PHYSICAL_ADDRESS.h" +#include "EFI_STATUS.h" #include "EFI_TABLE_HEADER.h" #include "EFI_TIMER_DELAY.h" #include "EFI_TPL.h" diff --git a/libc/src/__support/OSUtil/uefi/CMakeLists.txt b/libc/src/__support/OSUtil/uefi/CMakeLists.txt index 79ec8ab602456..617c0002f9476 100644 --- a/libc/src/__support/OSUtil/uefi/CMakeLists.txt +++ b/libc/src/__support/OSUtil/uefi/CMakeLists.txt @@ -6,6 +6,7 @@ add_object_library( HDRS io.h DEPENDS + libc.include.uefi libc.src.__support.common libc.src.__support.CPP.string_view ) diff --git a/libc/src/__support/OSUtil/uefi/exit.cpp b/libc/src/__support/OSUtil/uefi/exit.cpp index ab7530ef88786..fc8b9e6549b24 100644 --- a/libc/src/__support/OSUtil/uefi/exit.cpp +++ b/libc/src/__support/OSUtil/uefi/exit.cpp @@ -7,16 +7,17 @@ //===----------------------------------------------------------------------===// #include "src/__support/OSUtil/exit.h" +#include "include/llvm-libc-macros/stdlib-macros.h" #include "src/__support/macros/config.h" +#include namespace LIBC_NAMESPACE_DECL { namespace internal { [[noreturn]] void exit(int status) { - (void)status; - // TODO: call boot services to exit - while (true) { - } + efi_system_table->BootServices->Exit(efi_image_handle, status, 0, NULL); + while (true) + ; } } // namespace internal From d21c9025fe787aa1bd30acac91a523b6ec251fb3 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 20 Dec 2024 10:01:32 -0800 Subject: [PATCH 04/23] [libc] add __stack_chk_fail and abort to uefi --- libc/config/uefi/entrypoints.txt | 3 +++ libc/src/stdlib/uefi/CMakeLists.txt | 7 +++++++ libc/src/stdlib/uefi/abort.cpp | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 libc/src/stdlib/uefi/CMakeLists.txt create mode 100644 libc/src/stdlib/uefi/abort.cpp diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt index 664a4d2ca4640..dec934b38f009 100644 --- a/libc/config/uefi/entrypoints.txt +++ b/libc/config/uefi/entrypoints.txt @@ -1,4 +1,6 @@ set(TARGET_LIBC_ENTRYPOINTS + libc.src.compiler.__stack_chk_fail + # ctype.h entrypoints libc.src.ctype.isalnum libc.src.ctype.isalpha @@ -152,6 +154,7 @@ set(TARGET_LIBC_ENTRYPOINTS # stdlib.h entrypoints libc.src.stdlib._Exit + libc.src.stdlib.abort libc.src.stdlib.abs libc.src.stdlib.aligned_alloc libc.src.stdlib.atof diff --git a/libc/src/stdlib/uefi/CMakeLists.txt b/libc/src/stdlib/uefi/CMakeLists.txt new file mode 100644 index 0000000000000..551a83a36b20e --- /dev/null +++ b/libc/src/stdlib/uefi/CMakeLists.txt @@ -0,0 +1,7 @@ +add_entrypoint_object( + abort + SRCS + abort.cpp + HDRS + ../abort.h +) diff --git a/libc/src/stdlib/uefi/abort.cpp b/libc/src/stdlib/uefi/abort.cpp new file mode 100644 index 0000000000000..98cf71084499a --- /dev/null +++ b/libc/src/stdlib/uefi/abort.cpp @@ -0,0 +1,18 @@ +//===-- Implementation of abort -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +#include "src/stdlib/abort.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(void, abort, ()) { __builtin_trap(); } + +} // namespace LIBC_NAMESPACE_DECL From 6ba52a4dac1344bbd3cc35d94b82558dfdb44c57 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 20 Dec 2024 13:13:34 -0800 Subject: [PATCH 05/23] [libc] support scudo in uefi --- libc/config/uefi/entrypoints.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt index dec934b38f009..1538602f6bd87 100644 --- a/libc/config/uefi/entrypoints.txt +++ b/libc/config/uefi/entrypoints.txt @@ -447,6 +447,13 @@ if(LIBC_COMPILER_HAS_FIXED_POINT) ) endif() +if(LLVM_LIBC_INCLUDE_SCUDO) + list(APPEND TARGET_LIBC_ENTRYPOINTS + # malloc.h external entrypoints + libc.src.stdlib.mallopt + ) +endif() + set(TARGET_LLVMLIBC_ENTRYPOINTS ${TARGET_LIBC_ENTRYPOINTS} ${TARGET_LIBM_ENTRYPOINTS} From 3a72dae70db8760a00f9867ef1c9b4e5318704dc Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 20 Dec 2024 15:47:36 -0800 Subject: [PATCH 06/23] [libc] work on puts in uefi --- libc/config/uefi/entrypoints.txt | 13 ++++ libc/config/uefi/headers.txt | 1 + libc/include/llvm-libc-types/CMakeLists.txt | 2 + .../EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h | 2 + libc/src/__support/CMakeLists.txt | 4 ++ libc/src/__support/UEFI/CMakeLists.txt | 11 +++ libc/src/__support/UEFI/file.cpp | 67 +++++++++++++++++++ libc/src/__support/UEFI/file.h | 46 +++++++++++++ libc/src/stdio/CMakeLists.txt | 38 ++++++----- libc/src/stdio/uefi/CMakeLists.txt | 59 ++++++++++++++++ libc/src/stdio/uefi/getchar.cpp | 26 +++++++ libc/src/stdio/uefi/printf.cpp | 53 +++++++++++++++ libc/src/stdio/uefi/putchar.cpp | 24 +++++++ libc/src/stdio/uefi/puts.cpp | 20 ++++++ libc/src/stdio/uefi/vprintf.cpp | 51 ++++++++++++++ 15 files changed, 399 insertions(+), 18 deletions(-) create mode 100644 libc/src/__support/UEFI/CMakeLists.txt create mode 100644 libc/src/__support/UEFI/file.cpp create mode 100644 libc/src/__support/UEFI/file.h create mode 100644 libc/src/stdio/uefi/getchar.cpp create mode 100644 libc/src/stdio/uefi/printf.cpp create mode 100644 libc/src/stdio/uefi/putchar.cpp create mode 100644 libc/src/stdio/uefi/puts.cpp create mode 100644 libc/src/stdio/uefi/vprintf.cpp diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt index 1538602f6bd87..09ab0da058251 100644 --- a/libc/config/uefi/entrypoints.txt +++ b/libc/config/uefi/entrypoints.txt @@ -152,6 +152,19 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdbit.stdc_trailing_zeros_ull libc.src.stdbit.stdc_trailing_zeros_us + # stdio.h entrypoints + libc.src.stdio.getchar + libc.src.stdio.printf + libc.src.stdio.putchar + libc.src.stdio.puts + libc.src.stdio.snprintf + libc.src.stdio.sprintf + libc.src.stdio.asprintf + libc.src.stdio.vprintf + libc.src.stdio.vsnprintf + libc.src.stdio.vsprintf + libc.src.stdio.vasprintf + # stdlib.h entrypoints libc.src.stdlib._Exit libc.src.stdlib.abort diff --git a/libc/config/uefi/headers.txt b/libc/config/uefi/headers.txt index bf8dee1e6f2a6..642d5a6b2f58b 100644 --- a/libc/config/uefi/headers.txt +++ b/libc/config/uefi/headers.txt @@ -10,6 +10,7 @@ set(TARGET_PUBLIC_HEADERS libc.include.setjmp libc.include.stdfix libc.include.stdint + libc.include.stdio libc.include.stdlib libc.include.string libc.include.strings diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 557257c615d1e..58761ac97d7cf 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -219,7 +219,9 @@ add_header(EFI_SIMPLE_TEXT_INPUT_PROTOCOL HDR EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h DEPENDS + libc.include.llvm-libc-macros.EFIAPI_macros libc.include.llvm-libc-macros.stdint_macros + .EFI_EVENT .EFI_STATUS .char16_t ) diff --git a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h index a290c5c7c3095..0a7384e7de522 100644 --- a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h +++ b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h @@ -9,7 +9,9 @@ #ifndef LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H #define LLVM_LIBC_TYPES_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_H +#include "../llvm-libc-macros/EFIAPI-macros.h" #include "../llvm-libc-macros/stdint-macros.h" +#include "EFI_EVENT.h" #include "EFI_STATUS.h" #include "char16_t.h" diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 17f03a6b6c4a0..5eecbd152f17c 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -370,6 +370,10 @@ add_subdirectory(StringUtil) add_subdirectory(GPU) add_subdirectory(RPC) +if(LIBC_TARGET_OS_IS_UEFI) + add_subdirectory(UEFI) +endif() + # Thread support is used by other "File". So, we add the "threads" # before "File". add_subdirectory(threads) diff --git a/libc/src/__support/UEFI/CMakeLists.txt b/libc/src/__support/UEFI/CMakeLists.txt new file mode 100644 index 0000000000000..46a2d6504b6d8 --- /dev/null +++ b/libc/src/__support/UEFI/CMakeLists.txt @@ -0,0 +1,11 @@ +add_object_library( + file + SRCS + file.cpp + HDRS + file.h + DEPENDS + libc.include.uefi + libc.hdr.types.FILE + libc.src.__support.CPP.new +) diff --git a/libc/src/__support/UEFI/file.cpp b/libc/src/__support/UEFI/file.cpp new file mode 100644 index 0000000000000..73309a46edcfe --- /dev/null +++ b/libc/src/__support/UEFI/file.cpp @@ -0,0 +1,67 @@ +#include "file.h" +#include "hdr/types/FILE.h" +#include "src/__support/macros/config.h" +#include + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +namespace LIBC_NAMESPACE_DECL { +bool File::needsReset() { return handle_type == FileHandleId; } + +void File::reset() { + if (handle_type != FileHandleId) + return; + + if (handle.id == STDIN_FILENO) { + handle = (FileHandle){ + .simple_text_input = efi_system_table->ConIn, + }; + handle_type = FileHandleSimpleTextInput; + } else { + handle = (FileHandle){ + .simple_text_output = handle.id == STDERR_FILENO + ? efi_system_table->StdErr + : efi_system_table->ConOut, + }; + handle_type = FileHandleSimpleTextOutput; + } +} + +size_t File::write(const void *data, size_t data_len) { + if (needsReset()) + reset(); + + if (handle_type == FileHandleSimpleTextOutput) { + handle.simple_text_output->OutputString( + handle.simple_text_output, reinterpret_cast(data)); + return data_len; + } + return 0; +} + +File stdin( + (FileHandle){ + .id = STDIN_FILENO, + }, + FileHandleId); + +File stdout( + (FileHandle){ + .id = STDOUT_FILENO, + }, + FileHandleId); + +File stderr( + (FileHandle){ + .id = STDERR_FILENO, + }, + FileHandleId); +} // namespace LIBC_NAMESPACE_DECL + +extern "C" { +FILE *stdin = reinterpret_cast(&LIBC_NAMESPACE::stdin); +FILE *stdout = reinterpret_cast(&LIBC_NAMESPACE::stdout); +FILE *stderr = reinterpret_cast(&LIBC_NAMESPACE::stderr); +} diff --git a/libc/src/__support/UEFI/file.h b/libc/src/__support/UEFI/file.h new file mode 100644 index 0000000000000..b77c00e903b6c --- /dev/null +++ b/libc/src/__support/UEFI/file.h @@ -0,0 +1,46 @@ +#ifndef LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H +#define LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H + +#include "include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h" +#include "include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h" +#include "src/__support/CPP/new.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +enum FileHandleType { + FileHandleId, + FileHandleSimpleTextInput, + FileHandleSimpleTextOutput, +}; + +union FileHandle { + int id; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *simple_text_input; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *simple_text_output; +}; + +class File { + FileHandle handle; + FileHandleType handle_type; + +private: + bool needsReset(); + +public: + constexpr File(FileHandle handle, FileHandleType handle_type) + : handle(handle), handle_type(handle_type) {} + + void reset(); + + size_t read(void *data, size_t len); + size_t write(const void *data, size_t len); +}; + +extern File stdin; +extern File stdout; +extern File stderr; + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_UEFI_FILE_H diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt index 776ca103a841f..dd3477061c0f4 100644 --- a/libc/src/stdio/CMakeLists.txt +++ b/libc/src/stdio/CMakeLists.txt @@ -240,26 +240,28 @@ add_entrypoint_object( add_subdirectory(printf_core) add_subdirectory(scanf_core) -add_entrypoint_object( - remove - ALIAS - DEPENDS - .${LIBC_TARGET_OS}.remove -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_entrypoint_object( + remove + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.remove + ) -add_entrypoint_object( - rename - ALIAS - DEPENDS - .${LIBC_TARGET_OS}.rename -) + add_entrypoint_object( + rename + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.rename + ) -add_entrypoint_object( - fdopen - ALIAS - DEPENDS - .${LIBC_TARGET_OS}.fdopen -) + add_entrypoint_object( + fdopen + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.fdopen + ) +endif() # These entrypoints have multiple potential implementations. add_stdio_entrypoint_object(feof) diff --git a/libc/src/stdio/uefi/CMakeLists.txt b/libc/src/stdio/uefi/CMakeLists.txt index e69de29bb2d1d..6fe527ea24237 100644 --- a/libc/src/stdio/uefi/CMakeLists.txt +++ b/libc/src/stdio/uefi/CMakeLists.txt @@ -0,0 +1,59 @@ +add_entrypoint_object( + getchar + SRCS + getchar.cpp + HDRS + ../getchar.h + DEPENDS + libc.hdr.stdio_macros + libc.src.__support.UEFI.file +) + +add_entrypoint_object( + printf + SRCS + printf.cpp + HDRS + ../printf.h + DEPENDS + libc.src.stdio.printf_core.printf_main + libc.src.stdio.printf_core.writer + libc.src.__support.arg_list + libc.src.__support.OSUtil.osutil +) + +add_entrypoint_object( + putchar + SRCS + putchar.cpp + HDRS + ../putchar.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.__support.CPP.string_view + libc.src.__support.UEFI.file +) + +add_entrypoint_object( + puts + SRCS + puts.cpp + HDRS + ../puts.h + DEPENDS + libc.src.__support.UEFI.file + libc.src.string.strlen +) + +add_entrypoint_object( + vprintf + SRCS + vprintf.cpp + HDRS + ../vprintf.h + DEPENDS + libc.src.stdio.printf_core.printf_main + libc.src.stdio.printf_core.writer + libc.src.__support.arg_list + libc.src.__support.OSUtil.osutil +) diff --git a/libc/src/stdio/uefi/getchar.cpp b/libc/src/stdio/uefi/getchar.cpp new file mode 100644 index 0000000000000..ecd7a8a54e9ea --- /dev/null +++ b/libc/src/stdio/uefi/getchar.cpp @@ -0,0 +1,26 @@ +//===-- Implementation of getchar -----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/getchar.h" +#include "src/__support/UEFI/file.h" + +#include "hdr/stdio_macros.h" // for EOF. +#include "hdr/types/FILE.h" +#include "src/__support/macros/config.h" +#include "src/errno/libc_errno.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, getchar, ()) { + unsigned char c; + if (stdin.read(&c, 1) != 1) + return EOF; + return c; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdio/uefi/printf.cpp b/libc/src/stdio/uefi/printf.cpp new file mode 100644 index 0000000000000..04aa284ee0839 --- /dev/null +++ b/libc/src/stdio/uefi/printf.cpp @@ -0,0 +1,53 @@ +//===-- Implementation of printf for baremetal ------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/printf.h" +#include "src/__support/OSUtil/io.h" +#include "src/__support/arg_list.h" +#include "src/__support/macros/config.h" +#include "src/stdio/printf_core/core_structs.h" +#include "src/stdio/printf_core/printf_main.h" +#include "src/stdio/printf_core/writer.h" + +#include +#include + +namespace LIBC_NAMESPACE_DECL { + +namespace { + +LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { + write_to_stderr(new_str); + return printf_core::WRITE_OK; +} + +} // namespace + +LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { + va_list vlist; + va_start(vlist, format); + internal::ArgList args(vlist); // This holder class allows for easier copying + // and pointer semantics, as well as handling + // destruction automatically. + va_end(vlist); + constexpr size_t BUFF_SIZE = 1024; + char buffer[BUFF_SIZE]; + + printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr); + printf_core::Writer writer(&wb); + + int retval = printf_core::printf_main(&writer, format, args); + + int flushval = wb.overflow_write(""); + if (flushval != printf_core::WRITE_OK) + retval = flushval; + + return retval; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdio/uefi/putchar.cpp b/libc/src/stdio/uefi/putchar.cpp new file mode 100644 index 0000000000000..0ba46a5ade6c9 --- /dev/null +++ b/libc/src/stdio/uefi/putchar.cpp @@ -0,0 +1,24 @@ +//===-- Baremetal Implementation of putchar -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/putchar.h" +#include "src/__support/CPP/string_view.h" +#include "src/__support/OSUtil/io.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, putchar, (int c)) { + char uc = static_cast(c); + + write_to_stderr(cpp::string_view(&uc, 1)); + + return 0; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdio/uefi/puts.cpp b/libc/src/stdio/uefi/puts.cpp new file mode 100644 index 0000000000000..07a33e49e644a --- /dev/null +++ b/libc/src/stdio/uefi/puts.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of puts for baremetal-------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/puts.h" +#include "src/__support/UEFI/file.h" +#include "src/__support/macros/config.h" +#include "src/string/strlen.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) { + return (int)stdout.write(reinterpret_cast(str), strlen(str)); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdio/uefi/vprintf.cpp b/libc/src/stdio/uefi/vprintf.cpp new file mode 100644 index 0000000000000..617b5f488e772 --- /dev/null +++ b/libc/src/stdio/uefi/vprintf.cpp @@ -0,0 +1,51 @@ +//===-- Implementation of vprintf -------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/vprintf.h" +#include "src/__support/OSUtil/io.h" +#include "src/__support/arg_list.h" +#include "src/__support/macros/config.h" +#include "src/stdio/printf_core/core_structs.h" +#include "src/stdio/printf_core/printf_main.h" +#include "src/stdio/printf_core/writer.h" + +#include +#include + +namespace LIBC_NAMESPACE_DECL { + +namespace { + +LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { + write_to_stderr(new_str); + return printf_core::WRITE_OK; +} + +} // namespace + +LLVM_LIBC_FUNCTION(int, vprintf, + (const char *__restrict format, va_list vlist)) { + internal::ArgList args(vlist); // This holder class allows for easier copying + // and pointer semantics, as well as handling + // destruction automatically. + constexpr size_t BUFF_SIZE = 1024; + char buffer[BUFF_SIZE]; + + printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr); + printf_core::Writer writer(&wb); + + int retval = printf_core::printf_main(&writer, format, args); + + int flushval = wb.overflow_write(""); + if (flushval != printf_core::WRITE_OK) + retval = flushval; + + return retval; +} + +} // namespace LIBC_NAMESPACE_DECL From 91f554dfa5de3071afea21015f7139e766f5adfc Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Fri, 20 Dec 2024 16:12:14 -0800 Subject: [PATCH 07/23] [libc] add os util out and err writes for uefi --- libc/src/__support/OSUtil/uefi/io.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libc/src/__support/OSUtil/uefi/io.cpp b/libc/src/__support/OSUtil/uefi/io.cpp index c80731ea888d3..a4dad03ef1ff1 100644 --- a/libc/src/__support/OSUtil/uefi/io.cpp +++ b/libc/src/__support/OSUtil/uefi/io.cpp @@ -10,6 +10,7 @@ #include "src/__support/CPP/string_view.h" #include "src/__support/macros/config.h" +#include namespace LIBC_NAMESPACE_DECL { @@ -19,8 +20,16 @@ ssize_t read_from_stdin(char *buf, size_t size) { return 0; } -void write_to_stdout(cpp::string_view msg) { (void)msg; } +void write_to_stdout(cpp::string_view msg) { + // TODO: use mbstowcs once implemented + efi_system_table->ConOut->OutputString( + efi_system_table->ConOut, reinterpret_cast(msg.data())); +} -void write_to_stderr(cpp::string_view msg) { (void)msg; } +void write_to_stderr(cpp::string_view msg) { + // TODO: use mbstowcs once implemented + efi_system_table->StdErr->OutputString( + efi_system_table->StdErr, reinterpret_cast(msg.data())); +} } // namespace LIBC_NAMESPACE_DECL From c7093ea2663e02905b6f4b49401fc9075040e7bc Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Mon, 23 Dec 2024 19:11:13 -0800 Subject: [PATCH 08/23] [libc] revert target triple hack --- libc/cmake/modules/LLVMLibCArchitectures.cmake | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libc/cmake/modules/LLVMLibCArchitectures.cmake b/libc/cmake/modules/LLVMLibCArchitectures.cmake index dd12d1d3ee422..f5dd32acc5ee3 100644 --- a/libc/cmake/modules/LLVMLibCArchitectures.cmake +++ b/libc/cmake/modules/LLVMLibCArchitectures.cmake @@ -69,10 +69,6 @@ function(get_arch_and_system_from_triple triple arch_var sys_var) set(target_sys "darwin") endif() - if(target_sys STREQUAL "unknown") - list(GET triple_comps 2 target_sys) - endif() - # Setting OS name for GPU architectures. list(GET triple_comps -1 gpu_target_sys) if(gpu_target_sys MATCHES "^amdhsa" OR gpu_target_sys MATCHES "^cuda") From ac12e60e6d93aeada7a97f7567e4218b717ef380 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Mon, 23 Dec 2024 19:41:47 -0800 Subject: [PATCH 09/23] [libc] add uefi to docs --- libc/docs/index.rst | 1 + libc/docs/platform_support.rst | 2 + libc/docs/uefi/index.rst | 15 +++ libc/docs/uefi/support.rst | 232 +++++++++++++++++++++++++++++++++ libc/docs/uefi/using.rst | 46 +++++++ 5 files changed, 296 insertions(+) create mode 100644 libc/docs/uefi/index.rst create mode 100644 libc/docs/uefi/support.rst create mode 100644 libc/docs/uefi/using.rst diff --git a/libc/docs/index.rst b/libc/docs/index.rst index 12dcba27a906b..a989ef9735a7c 100644 --- a/libc/docs/index.rst +++ b/libc/docs/index.rst @@ -62,6 +62,7 @@ LLVM-libc aspires to a unique place in the software ecosystem. The goals are: full_cross_build overlay_mode gpu/index.rst + uefi/index.rst configure .. toctree:: diff --git a/libc/docs/platform_support.rst b/libc/docs/platform_support.rst index 4643d82e2308b..e798db894b1ab 100644 --- a/libc/docs/platform_support.rst +++ b/libc/docs/platform_support.rst @@ -20,3 +20,5 @@ have reached their EOL. Compatibility patches for obsolete operating systems will not be accepted. For GPU, reference `our GPU docs `__. + +For UEFI, reference `our UEFI docs `__. diff --git a/libc/docs/uefi/index.rst b/libc/docs/uefi/index.rst new file mode 100644 index 0000000000000..31a65cb063aa7 --- /dev/null +++ b/libc/docs/uefi/index.rst @@ -0,0 +1,15 @@ +.. libc_uefi: + +============= +libc for UEFI +============= + +.. note:: This feature is very experimental and may change in the future. + +The *UEFI* support for LLVM's libc project aims to make a subset of the standard +C library available on UEFI systems. + +.. toctree:: + + using + support diff --git a/libc/docs/uefi/support.rst b/libc/docs/uefi/support.rst new file mode 100644 index 0000000000000..c105f0028cfa7 --- /dev/null +++ b/libc/docs/uefi/support.rst @@ -0,0 +1,232 @@ +.. _libc_uefi_support: + +=================== +Supported Functions +=================== + +.. include:: ../check.rst + +.. contents:: Table of Contents + :depth: 4 + :local: + + +The following functions and headers are supported at least partially. +Some functions are implemented fully for UEFI. + +ctype.h +------- + +============= ========= +Function Name Available +============= ========= +isalnum |check| +isalpha |check| +isascii |check| +isblank |check| +iscntrl |check| +isdigit |check| +isgraph |check| +islower |check| +isprint |check| +ispunct |check| +isspace |check| +isupper |check| +isxdigit |check| +toascii |check| +tolower |check| +toupper |check| +============= ========= + +string.h +-------- + +============= ========= +Function Name Available +============= ========= +bcmp |check| +bcopy |check| +bzero |check| +memccpy |check| +memchr |check| +memcmp |check| +memcpy |check| +memmem |check| +memmove |check| +mempcpy |check| +memrchr |check| +memset |check| +stpcpy |check| +stpncpy |check| +strcat |check| +strchr |check| +strchrnul |check| +strcmp |check| +strcoll |check| +strcpy |check| +strcspn |check| +strdup |check| +strerror |check| +strlcat |check| +strlcpy |check| +strlen |check| +strncat |check| +strncmp |check| +strncpy |check| +strndup |check| +strnlen |check| +strpbrk |check| +strrchr |check| +strsep |check| +strspn |check| +strstr |check| +strtok |check| +strtok_r |check| +strxfrm |check| +============= ========= + +strings.h +--------- + +============= ========= +Function Name Available +============= ========= +bcmp |check| +bcopy |check| +bzero |check| +strcasecmp |check| +strcasestr |check| +index |check| +rindex |check| +============= ========= + +stdbit.h +-------- + +============================ ========= +Function Name Available +============================ ========= +stdc_leading_zeros_uc |check| +stdc_leading_zeros_us |check| +stdc_leading_zeros_ui |check| +stdc_leading_zeros_ul |check| +stdc_leading_zeros_ull |check| +stdc_trailing_zeros_uc |check| +stdc_trailing_zeros_us |check| +stdc_trailing_zeros_ui |check| +stdc_trailing_zeros_ul |check| +stdc_trailing_zeros_ull |check| +stdc_trailing_ones_uc |check| +stdc_trailing_ones_us |check| +stdc_trailing_ones_ui |check| +stdc_trailing_ones_ul |check| +stdc_trailing_ones_ull |check| +stdc_first_leading_zero_uc |check| +stdc_first_leading_zero_us |check| +stdc_first_leading_zero_ui |check| +stdc_first_leading_zero_ul |check| +stdc_first_leading_zero_ull |check| +stdc_first_leading_one_uc |check| +stdc_first_leading_one_us |check| +stdc_first_leading_one_ui |check| +stdc_first_leading_one_ul |check| +stdc_first_leading_one_ull |check| +stdc_first_trailing_zero_uc |check| +stdc_first_trailing_zero_us |check| +stdc_first_trailing_zero_ui |check| +stdc_first_trailing_zero_ul |check| +stdc_first_trailing_zero_ull |check| +stdc_first_trailing_one_uc |check| +stdc_first_trailing_one_us |check| +stdc_first_trailing_one_ui |check| +stdc_first_trailing_one_ul |check| +stdc_first_trailing_one_ull |check| +stdc_count_zeros_uc |check| +stdc_count_zeros_us |check| +stdc_count_zeros_ui |check| +stdc_count_zeros_ul |check| +stdc_count_zeros_ull |check| +stdc_count_ones_uc |check| +stdc_count_ones_us |check| +stdc_count_ones_ui |check| +stdc_count_ones_ul |check| +stdc_count_ones_ull |check| +stdc_has_single_bit_uc |check| +stdc_has_single_bit_us |check| +stdc_has_single_bit_ui |check| +stdc_has_single_bit_ul |check| +stdc_has_single_bit_ull |check| +stdc_bit_width_uc |check| +stdc_bit_width_us |check| +stdc_bit_width_ui |check| +stdc_bit_width_ul |check| +stdc_bit_width_ull |check| +stdc_bit_floor_uc |check| +stdc_bit_floor_us |check| +stdc_bit_floor_ui |check| +stdc_bit_floor_ul |check| +stdc_bit_floor_ull |check| +stdc_bit_ceil_uc |check| +stdc_bit_ceil_us |check| +stdc_bit_ceil_ui |check| +stdc_bit_ceil_ul |check| +stdc_bit_ceil_ull |check| +============================ ========= + +stdlib.h +-------- + +============= ========= +Function Name Available +============= ========= +abs |check| +atoi |check| +atof |check| +atol |check| +atoll |check| +exit |check| +abort |check| +system |check| +labs |check| +llabs |check| +div |check| +ldiv |check| +lldiv |check| +bsearch |check| +qsort |check| +qsort_r |check| +strtod |check| +strtof |check| +strtol |check| +strtold |check| +strtoll |check| +strtoul |check| +strtoull |check| +srand |check| +rand |check| +============= ========= + +inttypes.h +---------- + +============= ========= +Function Name Available +============= ========= +imaxabs |check| +imaxdiv |check| +strtoimax |check| +strtoumax |check| +============= ========= + +stdio.h +------- + +============= ========= +Function Name Available +============= ========= +getchar |check| +printf |check| +putchar |check| +puts |check| +vprintf |check| +============= ========= diff --git a/libc/docs/uefi/using.rst b/libc/docs/uefi/using.rst new file mode 100644 index 0000000000000..90d06df773493 --- /dev/null +++ b/libc/docs/uefi/using.rst @@ -0,0 +1,46 @@ +.. libc_uefi_usage: + +=================== +Using libc for UEFI +=================== + +.. contents:: Table of Contents + :depth: 4 + :local: + +Using the UEFI C library +======================== + +Once you have finished building the UEFI C library, it +can be used to run libc or libm functions inside a UEFI +environment. Current, not all C standard functions are +supported in UEFI. Consult the :ref:`list of supported +functions` for a comprehensive list. + +Running a UEFI C library program in QEMU +======================================== + +QEMU is the preferred way to test programs compiled using +the UEFI C library, it only requires OVMF which is based +on EDKII. It is recommended to create a directory which +serves as a fat32 file system but passed through QEMU. +The following flag is capable of doing that: + +.. code-block:: sh + + -drive file=fat:rw:fat32-fs + +This will expose the ``fat32-fs`` directory as a fat32 +partition. Once QEMU starts, press ESQ a few times to +bring up the EDKII menu. Enter the boot manager and +load the option for the UEFI shell. Typically, EDKII +will expose the fat32 filesystem as ``FS0``. From there, +you can run the following command to run your program. +Here, we are using ``a.out`` as the example since clang +outputs to that filename by default. + +.. code-block:: sh + + > FS0: + FS0:> a.out + From 5ae9b03a606a304fea86d23ce631852e81c56eba Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Mon, 23 Dec 2024 19:54:03 -0800 Subject: [PATCH 10/23] [libc] replace __uefi__ macro with __UEFI__ --- libc/src/__support/OSUtil/io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/src/__support/OSUtil/io.h b/libc/src/__support/OSUtil/io.h index 86857da4c30a7..66af31f3cc8c6 100644 --- a/libc/src/__support/OSUtil/io.h +++ b/libc/src/__support/OSUtil/io.h @@ -24,7 +24,7 @@ #elif defined(__ELF__) // TODO: Ideally we would have LIBC_TARGET_OS_IS_BAREMETAL. #include "baremetal/io.h" -#elif defined(__uefi__) +#elif defined(__UEFI__) #include "uefi/io.h" #endif From 2c17e66c6bcb42657143c6b9d9e68ba5ab6939f9 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Mon, 23 Dec 2024 23:12:17 -0800 Subject: [PATCH 11/23] [libc] add uefi timespec --- libc/config/uefi/entrypoints.txt | 1 + libc/src/time/uefi/CMakeLists.txt | 12 +++++++ libc/src/time/uefi/timespec_get.cpp | 52 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 libc/src/time/uefi/CMakeLists.txt create mode 100644 libc/src/time/uefi/timespec_get.cpp diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt index 09ab0da058251..bfc633c6e79c9 100644 --- a/libc/config/uefi/entrypoints.txt +++ b/libc/config/uefi/entrypoints.txt @@ -204,6 +204,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.time.gmtime libc.src.time.gmtime_r libc.src.time.mktime + libc.src.time.timespec_get ) set(TARGET_LIBM_ENTRYPOINTS diff --git a/libc/src/time/uefi/CMakeLists.txt b/libc/src/time/uefi/CMakeLists.txt new file mode 100644 index 0000000000000..5c2b138f5d036 --- /dev/null +++ b/libc/src/time/uefi/CMakeLists.txt @@ -0,0 +1,12 @@ +add_entrypoint_object( + timespec_get + SRCS + timespec_get.cpp + HDRS + ../timespec_get.h + DEPENDS + libc.include.uefi + libc.hdr.time_macros + libc.hdr.types.struct_timespec + libc.src.time.mktime +) diff --git a/libc/src/time/uefi/timespec_get.cpp b/libc/src/time/uefi/timespec_get.cpp new file mode 100644 index 0000000000000..9ba3d2e7dd15f --- /dev/null +++ b/libc/src/time/uefi/timespec_get.cpp @@ -0,0 +1,52 @@ +//===-- Implementation of timespec_get for UEFI ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/time/timespec_get.h" +#include "hdr/time_macros.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/time/mktime.h" +#include + +namespace LIBC_NAMESPACE_DECL { + +extern "C" bool __llvm_libc_timespec_get_utc(struct timespec *ts); + +LLVM_LIBC_FUNCTION(int, timespec_get, (struct timespec * ts, int base)) { + if (base != TIME_UTC) + return 0; + + EFI_TIME efi_time; + EFI_STATUS status = + efi_system_table->RuntimeServices->GetTime(&efi_time, nullptr); + if (status != 0) + return 0; + + struct tm t; + t.tm_year = efi_time.Year - 1900; // tm_year is years since 1900 + t.tm_mon = efi_time.Month - 1; // tm_mon is 0-11 + t.tm_mday = efi_time.Day; + t.tm_hour = efi_time.Hour; + t.tm_min = efi_time.Minute; + t.tm_sec = efi_time.Second; + t.tm_isdst = -1; // Use system timezone settings + + ts->tv_sec = LIBC_NAMESPACE::mktime(&t); + if (ts->tv_sec == -1) + return 0; + + ts->tv_nsec = efi_time.Nanosecond; + + // Handle timezone offset if specified + if (efi_time.TimeZone != 2047) { // 2047 means timezone is unspecified + ts->tv_sec -= efi_time.TimeZone * 60; // EFI_TIME timezone is in minutes + } + return base; +} + +} // namespace LIBC_NAMESPACE_DECL From 99e4e9f63eed44fd3cd95c2816f7d68552cfbf9b Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 24 Dec 2024 10:23:24 -0800 Subject: [PATCH 12/23] [libc] working on uefi tests --- libc/config/uefi/config.json | 2 +- libc/config/uefi/entrypoints.txt | 19 ------------------- libc/config/uefi/headers.txt | 1 - libc/src/__support/UEFI/file.cpp | 10 ++++++++++ libc/src/__support/macros/attributes.h | 3 ++- libc/src/__support/macros/properties/os.h | 4 ++++ 6 files changed, 17 insertions(+), 22 deletions(-) diff --git a/libc/config/uefi/config.json b/libc/config/uefi/config.json index b60dde9ef040a..63f358ba68afb 100644 --- a/libc/config/uefi/config.json +++ b/libc/config/uefi/config.json @@ -1,7 +1,7 @@ { "errno": { "LIBC_CONF_ERRNO_MODE": { - "value": "LIBC_ERRNO_MODE_DEFAULT" + "value": "LIBC_ERRNO_MODE_SHARED" } }, "printf": { diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt index bfc633c6e79c9..8d439ffba496c 100644 --- a/libc/config/uefi/entrypoints.txt +++ b/libc/config/uefi/entrypoints.txt @@ -47,8 +47,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strcoll libc.src.string.strcpy libc.src.string.strcspn - libc.src.string.strerror - libc.src.string.strerror_r libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen @@ -208,23 +206,6 @@ set(TARGET_LIBC_ENTRYPOINTS ) set(TARGET_LIBM_ENTRYPOINTS - # fenv.h entrypoints - libc.src.fenv.feclearexcept - libc.src.fenv.fedisableexcept - libc.src.fenv.feenableexcept - libc.src.fenv.fegetenv - libc.src.fenv.fegetexcept - libc.src.fenv.fegetexceptflag - libc.src.fenv.fegetround - libc.src.fenv.feholdexcept - libc.src.fenv.feraiseexcept - libc.src.fenv.fesetenv - libc.src.fenv.fesetexcept - libc.src.fenv.fesetexceptflag - libc.src.fenv.fesetround - libc.src.fenv.fetestexcept - libc.src.fenv.fetestexceptflag - libc.src.fenv.feupdateenv # math.h entrypoints libc.src.math.acosf diff --git a/libc/config/uefi/headers.txt b/libc/config/uefi/headers.txt index 642d5a6b2f58b..ee201e60de5d5 100644 --- a/libc/config/uefi/headers.txt +++ b/libc/config/uefi/headers.txt @@ -3,7 +3,6 @@ set(TARGET_PUBLIC_HEADERS libc.include.ctype libc.include.errno libc.include.features - libc.include.fenv libc.include.float libc.include.inttypes libc.include.math diff --git a/libc/src/__support/UEFI/file.cpp b/libc/src/__support/UEFI/file.cpp index 73309a46edcfe..f345e9b569c0b 100644 --- a/libc/src/__support/UEFI/file.cpp +++ b/libc/src/__support/UEFI/file.cpp @@ -29,6 +29,16 @@ void File::reset() { } } +size_t File::read(void *data, size_t len) { + (void)data; + (void)len; + if (needsReset()) + reset(); + + // TODO: decode keys from simple text input + return 0; +} + size_t File::write(const void *data, size_t data_len) { if (needsReset()) reset(); diff --git a/libc/src/__support/macros/attributes.h b/libc/src/__support/macros/attributes.h index c6474673de85a..dfdac84407a00 100644 --- a/libc/src/__support/macros/attributes.h +++ b/libc/src/__support/macros/attributes.h @@ -18,6 +18,7 @@ #define LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H #include "properties/architectures.h" +#include "properties/os.h" #ifndef __has_attribute #define __has_attribute(x) 0 @@ -28,7 +29,7 @@ #define LIBC_INLINE_ASM __asm__ __volatile__ #define LIBC_UNUSED __attribute__((unused)) -#ifdef LIBC_TARGET_ARCH_IS_GPU +#if defined(LIBC_TARGET_ARCH_IS_GPU) || defined(LIBC_TARGET_OS_IS_UEFI) #define LIBC_THREAD_LOCAL #else #define LIBC_THREAD_LOCAL thread_local diff --git a/libc/src/__support/macros/properties/os.h b/libc/src/__support/macros/properties/os.h index 807ce1812735c..2e7b88d972cdb 100644 --- a/libc/src/__support/macros/properties/os.h +++ b/libc/src/__support/macros/properties/os.h @@ -29,4 +29,8 @@ #define LIBC_TARGET_OS_IS_FUCHSIA #endif +#if defined(__UEFI__) +#define LIBC_TARGET_OS_IS_UEFI +#endif + #endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_OS_H From e082649af7701ac822d0f70b18ee15c4f6708d06 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 24 Dec 2024 10:29:46 -0800 Subject: [PATCH 13/23] [libc] add ctor and dtor to uefi --- libc/startup/uefi/crt1.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/libc/startup/uefi/crt1.cpp b/libc/startup/uefi/crt1.cpp index 44570cb89010c..5676a47613580 100644 --- a/libc/startup/uefi/crt1.cpp +++ b/libc/startup/uefi/crt1.cpp @@ -12,6 +12,39 @@ #include "include/llvm-libc-types/EFI_SYSTEM_TABLE.h" #include "src/__support/macros/config.h" +namespace LIBC_NAMESPACE_DECL { + +using InitCallback = void(void); +using FiniCallback = void(void); +extern "C" InitCallback *__CTOR_LIST__[]; +extern "C" FiniCallback *__DTOR_LIST__[]; + +static void call_init_array_callbacks() { + unsigned long nptrs = (unsigned long)__CTOR_LIST__[0]; + unsigned long i; + + if (nptrs == (unsigned long)-1) { + for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++) + ; + } + + for (i = nptrs; i >= 1; i--) { + __CTOR_LIST__[i](); + } +} + +static void call_fini_array_callbacks() { + unsigned long nptrs = 0; + + for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++) + ; + + for (unsigned long i = nptrs; i >= 1; i--) { + __DTOR_LIST__[i](); + } +} +} // namespace LIBC_NAMESPACE_DECL + EFI_HANDLE efi_image_handle; EFI_SYSTEM_TABLE *efi_system_table; @@ -22,7 +55,11 @@ extern "C" EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, efi_image_handle = ImageHandle; efi_system_table = SystemTable; + LIBC_NAMESPACE::call_init_array_callbacks(); + main(0, NULL, NULL); + + LIBC_NAMESPACE::call_fini_array_callbacks(); // TODO: convert the return value of main to EFI_STATUS return 0; // TODO: EFI_SUCCESS } From d7cbeeae3727ab04c4e41724ed33d3203368d39a Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 24 Dec 2024 17:52:20 -0800 Subject: [PATCH 14/23] [libc] make uefi tests build --- libc/CMakeLists.txt | 6 +- libc/cmake/modules/LLVMLibCTestRules.cmake | 8 +- libc/config/uefi/config.json | 2 +- libc/config/uefi/entrypoints.txt | 2 +- libc/docs/uefi/support.rst | 1 - libc/include/llvm-libc-macros/signal-macros.h | 2 + .../llvm-libc-macros/uefi/CMakeLists.txt | 5 + .../llvm-libc-macros/uefi/signal-macros.h | 28 ++ libc/src/__support/OSUtil/uefi/io.cpp | 14 +- libc/src/__support/UEFI/file.cpp | 7 +- libc/src/__support/macros/properties/types.h | 4 +- libc/src/__support/threads/mutex.h | 2 + .../src/__support/threads/uefi/CMakeLists.txt | 5 + libc/src/__support/threads/uefi/mutex.h | 32 ++ libc/src/stdio/uefi/puts.cpp | 6 +- libc/test/UnitTest/CMakeLists.txt | 3 +- libc/test/UnitTest/LibcTest.cpp | 7 + libc/test/include/CMakeLists.txt | 4 + libc/test/integration/scudo/CMakeLists.txt | 2 +- libc/test/src/CMakeLists.txt | 6 +- libc/test/src/__support/CMakeLists.txt | 55 +-- libc/test/src/__support/FPUtil/CMakeLists.txt | 4 + libc/test/src/__support/File/CMakeLists.txt | 2 +- libc/test/src/compiler/CMakeLists.txt | 4 + libc/test/src/errno/CMakeLists.txt | 2 +- libc/test/src/math/CMakeLists.txt | 326 +++++++++--------- libc/test/src/math/smoke/CMakeLists.txt | 4 + libc/test/src/stdfix/CMakeLists.txt | 70 ++-- .../test/src/stdio/printf_core/CMakeLists.txt | 4 + libc/test/src/stdio/scanf_core/CMakeLists.txt | 4 + libc/test/src/time/CMakeLists.txt | 4 + libc/test/utils/UnitTest/CMakeLists.txt | 2 +- 32 files changed, 389 insertions(+), 238 deletions(-) create mode 100644 libc/include/llvm-libc-macros/uefi/CMakeLists.txt create mode 100644 libc/include/llvm-libc-macros/uefi/signal-macros.h create mode 100644 libc/src/__support/threads/uefi/CMakeLists.txt create mode 100644 libc/src/__support/threads/uefi/mutex.h diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index 1c4c0cd5aa22b..69b1b3aaccb85 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -257,8 +257,10 @@ else() set(LIBC_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}) endif() -if(LIBC_TARGET_OS_IS_GPU) - include(prepare_libc_gpu_build) +if(LIBC_TARGET_OS_IS_GPU OR LIBC_TARGET_OS_IS_UEFI) + if(LIBC_TARGET_OS_IS_GPU) + include(prepare_libc_gpu_build) + endif() set(LIBC_ENABLE_UNITTESTS OFF) endif() diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index ffbdb40cd5091..b85e75f15a62c 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -673,6 +673,7 @@ function(add_libc_hermetic test_name) libc.src.string.memset libc.src.strings.bcmp libc.src.strings.bzero + libc.src.stdlib.atexit ) if(libc.src.compiler.__stack_chk_fail IN_LIST TARGET_LLVMLIBC_ENTRYPOINTS) @@ -743,6 +744,11 @@ function(add_libc_hermetic test_name) endif() endforeach() + if(LIBC_TARGET_OS_IS_UEFI) + target_link_options(${fq_build_target_name} PRIVATE + ${LIBC_COMPILE_OPTIONS_DEFAULT} "-Wl,/lldmingw") + endif() + if(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU) target_link_options(${fq_build_target_name} PRIVATE ${LIBC_COMPILE_OPTIONS_DEFAULT} -Wno-multi-gpu @@ -778,7 +784,7 @@ function(add_libc_hermetic test_name) ${fq_deps_list}) # TODO: currently the dependency chain is broken such that getauxval cannot properly # propagate to hermetic tests. This is a temporary workaround. - if (LIBC_TARGET_ARCHITECTURE_IS_AARCH64) + if (LIBC_TARGET_ARCHITECTURE_IS_AARCH64 AND NOT LIBC_TARGET_OS_IS_UEFI) target_link_libraries( ${fq_build_target_name} PRIVATE diff --git a/libc/config/uefi/config.json b/libc/config/uefi/config.json index 63f358ba68afb..c874d7bdfab48 100644 --- a/libc/config/uefi/config.json +++ b/libc/config/uefi/config.json @@ -15,7 +15,7 @@ "value": true }, "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": { - "value": false + "value": true }, "LIBC_CONF_PRINTF_DISABLE_STRERROR": { "value": true diff --git a/libc/config/uefi/entrypoints.txt b/libc/config/uefi/entrypoints.txt index 8d439ffba496c..1ca0938d4c824 100644 --- a/libc/config/uefi/entrypoints.txt +++ b/libc/config/uefi/entrypoints.txt @@ -172,6 +172,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdlib.atoi libc.src.stdlib.atol libc.src.stdlib.atoll + libc.src.stdlib.atexit libc.src.stdlib.bsearch libc.src.stdlib.calloc libc.src.stdlib.div @@ -188,7 +189,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdlib.strtod libc.src.stdlib.strtof libc.src.stdlib.strtol - libc.src.stdlib.strtold libc.src.stdlib.strtoll libc.src.stdlib.strtoul libc.src.stdlib.strtoull diff --git a/libc/docs/uefi/support.rst b/libc/docs/uefi/support.rst index c105f0028cfa7..f78e4adbb2953 100644 --- a/libc/docs/uefi/support.rst +++ b/libc/docs/uefi/support.rst @@ -198,7 +198,6 @@ qsort_r |check| strtod |check| strtof |check| strtol |check| -strtold |check| strtoll |check| strtoul |check| strtoull |check| diff --git a/libc/include/llvm-libc-macros/signal-macros.h b/libc/include/llvm-libc-macros/signal-macros.h index fbe929a0fea25..ab9825d9a2492 100644 --- a/libc/include/llvm-libc-macros/signal-macros.h +++ b/libc/include/llvm-libc-macros/signal-macros.h @@ -13,6 +13,8 @@ #include "linux/signal-macros.h" #elif defined(__NVPTX__) || defined(__AMDGPU__) #include "gpu/signal-macros.h" +#elif defined(__UEFI__) +#include "uefi/signal-macros.h" #endif #endif // LLVM_LIBC_MACROS_SIGNAL_MACROS_H diff --git a/libc/include/llvm-libc-macros/uefi/CMakeLists.txt b/libc/include/llvm-libc-macros/uefi/CMakeLists.txt new file mode 100644 index 0000000000000..9ef86a8cb5479 --- /dev/null +++ b/libc/include/llvm-libc-macros/uefi/CMakeLists.txt @@ -0,0 +1,5 @@ +add_header( + signal_macros + HDR + signal-macros.h +) diff --git a/libc/include/llvm-libc-macros/uefi/signal-macros.h b/libc/include/llvm-libc-macros/uefi/signal-macros.h new file mode 100644 index 0000000000000..2d8159240de8b --- /dev/null +++ b/libc/include/llvm-libc-macros/uefi/signal-macros.h @@ -0,0 +1,28 @@ +//===-- Definition of GPU signal number macros ----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_MACROS_GPU_SIGNAL_MACROS_H +#define LLVM_LIBC_MACROS_GPU_SIGNAL_MACROS_H + +#define SIGINT 2 +#define SIGILL 4 +#define SIGABRT 6 +#define SIGFPE 8 +#define SIGSEGV 11 +#define SIGTERM 15 + +#define SIG_DFL ((__sighandler_t)(0)) +#define SIG_IGN ((__sighandler_t)(1)) +#define SIG_ERR ((__sighandler_t)(-1)) + +// Max signal number +#define NSIG 64 + +#define __NSIGSET_WORDS NSIG + +#endif // LLVM_LIBC_MACROS_GPU_SIGNAL_MACROS_H diff --git a/libc/src/__support/OSUtil/uefi/io.cpp b/libc/src/__support/OSUtil/uefi/io.cpp index a4dad03ef1ff1..885bbc690bea8 100644 --- a/libc/src/__support/OSUtil/uefi/io.cpp +++ b/libc/src/__support/OSUtil/uefi/io.cpp @@ -22,14 +22,20 @@ ssize_t read_from_stdin(char *buf, size_t size) { void write_to_stdout(cpp::string_view msg) { // TODO: use mbstowcs once implemented - efi_system_table->ConOut->OutputString( - efi_system_table->ConOut, reinterpret_cast(msg.data())); + for (size_t i = 0; i < msg.size(); i++) { + char16_t e[2] = {msg[i], 0}; + efi_system_table->ConOut->OutputString( + efi_system_table->ConOut, reinterpret_cast(&e)); + } } void write_to_stderr(cpp::string_view msg) { // TODO: use mbstowcs once implemented - efi_system_table->StdErr->OutputString( - efi_system_table->StdErr, reinterpret_cast(msg.data())); + for (size_t i = 0; i < msg.size(); i++) { + char16_t e[2] = {msg[i], 0}; + efi_system_table->StdErr->OutputString( + efi_system_table->StdErr, reinterpret_cast(&e)); + } } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/UEFI/file.cpp b/libc/src/__support/UEFI/file.cpp index f345e9b569c0b..edf1b51e900aa 100644 --- a/libc/src/__support/UEFI/file.cpp +++ b/libc/src/__support/UEFI/file.cpp @@ -44,8 +44,11 @@ size_t File::write(const void *data, size_t data_len) { reset(); if (handle_type == FileHandleSimpleTextOutput) { - handle.simple_text_output->OutputString( - handle.simple_text_output, reinterpret_cast(data)); + for (size_t i = 0; i < data_len; i++) { + char16_t e[2] = {((const char *)data)[i], 0}; + handle.simple_text_output->OutputString( + handle.simple_text_output, reinterpret_cast(&e)); + } return data_len; } return 0; diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h index 6293b9d4d292a..7014cf8dd5c6e 100644 --- a/libc/src/__support/macros/properties/types.h +++ b/libc/src/__support/macros/properties/types.h @@ -10,7 +10,7 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H #define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H -#include "hdr/float_macros.h" // LDBL_MANT_DIG +#include "hdr/float_macros.h" // LDBL_MANT_DIG #include "include/llvm-libc-macros/float16-macros.h" // LIBC_TYPES_HAS_FLOAT16 #include "include/llvm-libc-types/float128.h" // float128 #include "src/__support/macros/properties/architectures.h" @@ -43,7 +43,7 @@ // int128 / uint128 support #if defined(__SIZEOF_INT128__) && !defined(LIBC_TARGET_OS_IS_WINDOWS) -#define LIBC_TYPES_HAS_INT128 +// #define LIBC_TYPES_HAS_INT128 #endif // defined(__SIZEOF_INT128__) // -- float16 support --------------------------------------------------------- diff --git a/libc/src/__support/threads/mutex.h b/libc/src/__support/threads/mutex.h index 392b38984dc0a..36de27ca5655b 100644 --- a/libc/src/__support/threads/mutex.h +++ b/libc/src/__support/threads/mutex.h @@ -41,6 +41,8 @@ #include "src/__support/threads/linux/mutex.h" #elif defined(LIBC_TARGET_ARCH_IS_GPU) #include "src/__support/threads/gpu/mutex.h" +#elif defined(__UEFI__) +#include "src/__support/threads/uefi/mutex.h" #endif // __linux__ #endif // LLVM_LIBC_SRC___SUPPORT_THREADS_MUTEX_H diff --git a/libc/src/__support/threads/uefi/CMakeLists.txt b/libc/src/__support/threads/uefi/CMakeLists.txt new file mode 100644 index 0000000000000..ea89feb0c5c68 --- /dev/null +++ b/libc/src/__support/threads/uefi/CMakeLists.txt @@ -0,0 +1,5 @@ +add_header_library( + mutex + HDRS + mutex.h +) diff --git a/libc/src/__support/threads/uefi/mutex.h b/libc/src/__support/threads/uefi/mutex.h new file mode 100644 index 0000000000000..c76b919f26324 --- /dev/null +++ b/libc/src/__support/threads/uefi/mutex.h @@ -0,0 +1,32 @@ +//===--- Implementation of a UEFI mutex class -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_UEFI_MUTEX_H +#define LLVM_LIBC_SRC___SUPPORT_THREADS_UEFI_MUTEX_H + +#include "src/__support/macros/attributes.h" +#include "src/__support/macros/config.h" +#include "src/__support/threads/mutex_common.h" + +namespace LIBC_NAMESPACE_DECL { + +/// Implementation of a simple passthrough mutex which guards nothing. A +/// complete Mutex locks in general cannot be implemented on the GPU. We simply +/// define the Mutex interface and require that only a single thread executes +/// code requiring a mutex lock. +struct Mutex { + LIBC_INLINE constexpr Mutex(bool, bool, bool, bool) {} + + LIBC_INLINE MutexError lock() { return MutexError::NONE; } + LIBC_INLINE MutexError unlock() { return MutexError::NONE; } + LIBC_INLINE MutexError reset() { return MutexError::NONE; } +}; + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_GPU_MUTEX_H diff --git a/libc/src/stdio/uefi/puts.cpp b/libc/src/stdio/uefi/puts.cpp index 07a33e49e644a..cb4ff40f365d6 100644 --- a/libc/src/stdio/uefi/puts.cpp +++ b/libc/src/stdio/uefi/puts.cpp @@ -14,7 +14,11 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) { - return (int)stdout.write(reinterpret_cast(str), strlen(str)); + int rc = (int)stdout.write(reinterpret_cast(str), strlen(str)); + if (rc < 1) + return rc; + + return (int)stdout.write("\r\n", 2); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt index 570bd600d1a43..c143487daf009 100644 --- a/libc/test/UnitTest/CMakeLists.txt +++ b/libc/test/UnitTest/CMakeLists.txt @@ -25,7 +25,8 @@ function(add_unittest_framework_library name) endif() endforeach() - if(LLVM_LIBC_FULL_BUILD) + # UEFI requires full builds + if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_UEFI) # TODO: Build test framework with LIBC_FULL_BUILD in full build mode after # making LibcFPExceptionHelpers and LibcDeathTestExecutors hermetic. set(LLVM_LIBC_FULL_BUILD "") diff --git a/libc/test/UnitTest/LibcTest.cpp b/libc/test/UnitTest/LibcTest.cpp index afb1368f00905..f2cb62db20d5b 100644 --- a/libc/test/UnitTest/LibcTest.cpp +++ b/libc/test/UnitTest/LibcTest.cpp @@ -13,10 +13,12 @@ #include "src/__support/CPP/string_view.h" #include "src/__support/fixed_point/fx_rep.h" #include "src/__support/macros/config.h" +#include "src/__support/macros/properties/os.h" #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128 #include "src/__support/uint128.h" #include "test/UnitTest/TestLogger.h" +#ifndef LIBC_TARGET_OS_IS_UEFI #if __STDC_HOSTED__ #include #define LIBC_TEST_USE_CLOCK @@ -27,6 +29,7 @@ extern "C" clock_t clock() noexcept { return LIBC_NAMESPACE::clock(); } #define LIBC_TEST_USE_CLOCK #endif +#endif namespace LIBC_NAMESPACE_DECL { namespace testing { @@ -158,13 +161,17 @@ int Test::runTests(const TestOptions &Options) { } tlog << green << "[ RUN ] " << reset << TestName << '\n'; +#ifdef LIBC_TEST_USE_CLOCK [[maybe_unused]] const uint64_t start_time = clock(); +#endif RunContext Ctx; T->SetUp(); T->setContext(&Ctx); T->Run(); T->TearDown(); +#ifdef LIBC_TEST_USE_CLOCK [[maybe_unused]] const uint64_t end_time = clock(); +#endif switch (Ctx.status()) { case RunContext::RunResult::Fail: tlog << red << "[ FAILED ] " << reset << TestName << '\n'; diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt index 24935cec048ba..2ca9c1a966758 100644 --- a/libc/test/include/CMakeLists.txt +++ b/libc/test/include/CMakeLists.txt @@ -1,3 +1,7 @@ +if(LIBC_TARGET_OS_IS_UEFI) + return() +endif() + add_custom_target(libc_include_tests) add_dependencies(check-libc libc_include_tests) diff --git a/libc/test/integration/scudo/CMakeLists.txt b/libc/test/integration/scudo/CMakeLists.txt index b4011e501b96b..8f3b48e55583e 100644 --- a/libc/test/integration/scudo/CMakeLists.txt +++ b/libc/test/integration/scudo/CMakeLists.txt @@ -1,4 +1,4 @@ -if(NOT LLVM_LIBC_INCLUDE_SCUDO) +if(NOT LLVM_LIBC_INCLUDE_SCUDO OR LIBC_TARGET_OS_IS_UEFI) return() endif() diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt index b7c145788c0cd..44071db0172b5 100644 --- a/libc/test/src/CMakeLists.txt +++ b/libc/test/src/CMakeLists.txt @@ -92,7 +92,11 @@ add_subdirectory(assert) add_subdirectory(compiler) add_subdirectory(dirent) add_subdirectory(locale) -add_subdirectory(setjmp) + +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_subdirectory(setjmp) +endif() + add_subdirectory(signal) add_subdirectory(spawn) diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt index 6358f1d14360a..bd8e83130c0cb 100644 --- a/libc/test/src/__support/CMakeLists.txt +++ b/libc/test/src/__support/CMakeLists.txt @@ -116,21 +116,22 @@ add_libc_test( libc.src.__support.uint128 ) -add_libc_test( - str_to_float_test - SUITE - libc-support-tests - SRCS - str_to_float_test.cpp - str_to_double_test.cpp - str_to_long_double_test.cpp - DEPENDS - libc.src.__support.integer_literals - libc.src.__support.str_to_float - libc.src.__support.uint128 - libc.src.errno.errno -) - +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_libc_test( + str_to_float_test + SUITE + libc-support-tests + SRCS + str_to_float_test.cpp + str_to_double_test.cpp + str_to_long_double_test.cpp + DEPENDS + libc.src.__support.integer_literals + libc.src.__support.str_to_float + libc.src.__support.uint128 + libc.src.errno.errno + ) +endif() add_libc_test( str_to_integer_test @@ -159,22 +160,24 @@ add_libc_test( libc.src.__support.uint128 ) -add_libc_test( - arg_list_test - SUITE - libc-support-tests - SRCS - arg_list_test.cpp - DEPENDS - libc.src.__support.arg_list - libc.src.__support.macros.properties.os -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_libc_test( + arg_list_test + SUITE + libc-support-tests + SRCS + arg_list_test.cpp + DEPENDS + libc.src.__support.arg_list + libc.src.__support.macros.properties.os + ) +endif() # TODO: clang-cl generates calls into runtime library functions to # handle 128-bit integer arithmetics and conversions which are not yet # available on Windows. Re-enable 128-bit integer support on Windows once # these functions are ready. -if(NOT LIBC_TARGET_ARCHITECTURE_IS_NVPTX AND NOT LIBC_TARGET_OS_IS_WINDOWS) +if(NOT LIBC_TARGET_ARCHITECTURE_IS_NVPTX AND NOT LIBC_TARGET_OS_IS_WINDOWS AND NOT LIBC_TARGET_OS_IS_UEFI) add_libc_test( big_int_test SUITE diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt index 1e64e9ba425a5..9fe0446f21c76 100644 --- a/libc/test/src/__support/FPUtil/CMakeLists.txt +++ b/libc/test/src/__support/FPUtil/CMakeLists.txt @@ -1,3 +1,7 @@ +if(LIBC_TARGET_OS_IS_UEFI) + return() +endif() + add_custom_target(libc-fputil-tests) add_fp_unittest( diff --git a/libc/test/src/__support/File/CMakeLists.txt b/libc/test/src/__support/File/CMakeLists.txt index a11f52978f35f..f81ada731a222 100644 --- a/libc/test/src/__support/File/CMakeLists.txt +++ b/libc/test/src/__support/File/CMakeLists.txt @@ -1,4 +1,4 @@ -if(NOT (TARGET libc.src.__support.threads.mutex) OR LIBC_TARGET_OS_IS_GPU) +if(NOT (TARGET libc.src.__support.threads.mutex) OR LIBC_TARGET_OS_IS_GPU OR LIBC_TARGET_OS_IS_UEFI) # Not all platforms have a mutex implementation. If mutex is unvailable, # we just skip everything about files. The GPU does not currently support # files as well. diff --git a/libc/test/src/compiler/CMakeLists.txt b/libc/test/src/compiler/CMakeLists.txt index a45fa8c55e512..e091ce7d6b4ce 100644 --- a/libc/test/src/compiler/CMakeLists.txt +++ b/libc/test/src/compiler/CMakeLists.txt @@ -1,3 +1,7 @@ +if(LIBC_TARGET_OS_IS_UEFI) + return() +endif() + add_custom_target(libc_stack_chk_guard_unittests) add_libc_unittest( diff --git a/libc/test/src/errno/CMakeLists.txt b/libc/test/src/errno/CMakeLists.txt index b73962fb4de4d..aa9de129d26fd 100644 --- a/libc/test/src/errno/CMakeLists.txt +++ b/libc/test/src/errno/CMakeLists.txt @@ -1,4 +1,4 @@ -if(NOT LLVM_LIBC_FULL_BUILD OR LIBC_TARGET_OS_IS_GPU) +if(NOT LLVM_LIBC_FULL_BUILD OR LIBC_TARGET_OS_IS_GPU OR LIBC_TARGET_OS_IS_UEFI) return() endif() diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt index f000ff6f3cf47..de3fa0d01302b 100644 --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -1260,100 +1260,102 @@ add_fp_unittest( libc.src.__support.FPUtil.manipulation_functions ) -add_fp_unittest( - ilogbl_test - SUITE - libc-math-unittests - SRCS - ilogbl_test.cpp - HDRS - ILogbTest.h - DEPENDS - libc.src.math.ilogbl - libc.src.__support.CPP.limits - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.manipulation_functions -) - -add_fp_unittest( - ldexp_test - SUITE - libc-math-unittests - SRCS - ldexp_test.cpp - HDRS - LdExpTest.h - DEPENDS - libc.src.math.ldexp - libc.src.__support.CPP.limits - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.normal_float -) - -add_fp_unittest( - ldexpf_test - SUITE - libc-math-unittests - SRCS - ldexpf_test.cpp - HDRS - LdExpTest.h - DEPENDS - libc.src.math.ldexpf - libc.src.__support.CPP.limits - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.normal_float -) - -add_fp_unittest( - ldexpl_test - SUITE - libc-math-unittests - SRCS - ldexpl_test.cpp - HDRS - LdExpTest.h - DEPENDS - libc.src.math.ldexpl - libc.src.__support.CPP.limits - libc.src.__support.FPUtil.fp_bits - libc.src.__support.FPUtil.normal_float -) - -add_fp_unittest( - logb_test - SUITE - libc-math-unittests - SRCS - logb_test.cpp - DEPENDS - libc.src.math.logb - libc.src.__support.FPUtil.manipulation_functions -) - -add_fp_unittest( - logbf_test - SUITE - libc-math-unittests - SRCS - logbf_test.cpp - DEPENDS - libc.src.math.logbf - libc.src.__support.FPUtil.manipulation_functions -) - -add_fp_unittest( - logbl_test - SUITE - libc-math-unittests - SRCS - logbl_test.cpp - HDRS - LogbTest.h - DEPENDS - libc.src.math.logbl - libc.src.__support.FPUtil.manipulation_functions -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_fp_unittest( + ilogbl_test + SUITE + libc-math-unittests + SRCS + ilogbl_test.cpp + HDRS + ILogbTest.h + DEPENDS + libc.src.math.ilogbl + libc.src.__support.CPP.limits + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.manipulation_functions + ) + + add_fp_unittest( + ldexp_test + SUITE + libc-math-unittests + SRCS + ldexp_test.cpp + HDRS + LdExpTest.h + DEPENDS + libc.src.math.ldexp + libc.src.__support.CPP.limits + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.normal_float + ) + + add_fp_unittest( + ldexpf_test + SUITE + libc-math-unittests + SRCS + ldexpf_test.cpp + HDRS + LdExpTest.h + DEPENDS + libc.src.math.ldexpf + libc.src.__support.CPP.limits + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.normal_float + ) + + add_fp_unittest( + ldexpl_test + SUITE + libc-math-unittests + SRCS + ldexpl_test.cpp + HDRS + LdExpTest.h + DEPENDS + libc.src.math.ldexpl + libc.src.__support.CPP.limits + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.normal_float + ) + + add_fp_unittest( + logb_test + SUITE + libc-math-unittests + SRCS + logb_test.cpp + DEPENDS + libc.src.math.logb + libc.src.__support.FPUtil.manipulation_functions + ) + + add_fp_unittest( + logbf_test + SUITE + libc-math-unittests + SRCS + logbf_test.cpp + DEPENDS + libc.src.math.logbf + libc.src.__support.FPUtil.manipulation_functions + ) + + add_fp_unittest( + logbl_test + SUITE + libc-math-unittests + SRCS + logbl_test.cpp + HDRS + LogbTest.h + DEPENDS + libc.src.math.logbl + libc.src.__support.FPUtil.manipulation_functions + ) +endif() add_fp_unittest( modf_test @@ -1387,19 +1389,21 @@ add_fp_unittest( UNIT_TEST_ONLY ) -add_fp_unittest( - modfl_test - SUITE - libc-math-unittests - SRCS - modfl_test.cpp - HDRS - ModfTest.h - DEPENDS - libc.src.math.modfl - libc.src.__support.FPUtil.basic_operations - libc.src.__support.FPUtil.nearest_integer_operations -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_fp_unittest( + modfl_test + SUITE + libc-math-unittests + SRCS + modfl_test.cpp + HDRS + ModfTest.h + DEPENDS + libc.src.math.modfl + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.nearest_integer_operations + ) +endif() add_fp_unittest( fdimf_test @@ -1429,19 +1433,21 @@ add_fp_unittest( libc.src.__support.FPUtil.fp_bits ) -add_fp_unittest( - fdiml_test - SUITE - libc-math-unittests - SRCS - fdiml_test.cpp - HDRS - FDimTest.h - DEPENDS - libc.src.math.fdiml - libc.src.__support.FPUtil.basic_operations - libc.src.__support.FPUtil.fp_bits -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_fp_unittest( + fdiml_test + SUITE + libc-math-unittests + SRCS + fdiml_test.cpp + HDRS + FDimTest.h + DEPENDS + libc.src.math.fdiml + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.fp_bits + ) +endif() add_fp_unittest( fminf_test @@ -1469,18 +1475,20 @@ add_fp_unittest( libc.src.__support.FPUtil.fp_bits ) -add_fp_unittest( - fminl_test - SUITE - libc-math-unittests - SRCS - fminl_test.cpp - HDRS - FMinTest.h - DEPENDS - libc.src.math.fminl - libc.src.__support.FPUtil.fp_bits -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_fp_unittest( + fminl_test + SUITE + libc-math-unittests + SRCS + fminl_test.cpp + HDRS + FMinTest.h + DEPENDS + libc.src.math.fminl + libc.src.__support.FPUtil.fp_bits + ) +endif() add_fp_unittest( fmaxf_test @@ -1508,18 +1516,20 @@ add_fp_unittest( libc.src.__support.FPUtil.fp_bits ) -add_fp_unittest( - fmaxl_test - SUITE - libc-math-unittests - SRCS - fmaxl_test.cpp - HDRS - FMaxTest.h - DEPENDS - libc.src.math.fmaxl - libc.src.__support.FPUtil.fp_bits -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_fp_unittest( + fmaxl_test + SUITE + libc-math-unittests + SRCS + fmaxl_test.cpp + HDRS + FMaxTest.h + DEPENDS + libc.src.math.fmaxl + libc.src.__support.FPUtil.fp_bits + ) +endif() add_fp_unittest( sqrtf_test @@ -1729,19 +1739,21 @@ add_fp_unittest( libc.src.__support.FPUtil.fp_bits ) -add_fp_unittest( - nextafterl_test - SUITE - libc-math-unittests - SRCS - nextafterl_test.cpp - HDRS - NextAfterTest.h - DEPENDS - libc.src.math.nextafterl - libc.src.__support.FPUtil.basic_operations - libc.src.__support.FPUtil.fp_bits -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_fp_unittest( + nextafterl_test + SUITE + libc-math-unittests + SRCS + nextafterl_test.cpp + HDRS + NextAfterTest.h + DEPENDS + libc.src.math.nextafterl + libc.src.__support.FPUtil.basic_operations + libc.src.__support.FPUtil.fp_bits + ) +endif() add_fp_unittest( nextafterf128_test diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index f3ecba3737e38..3d14fb19a97d2 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -1,3 +1,7 @@ +if(LIBC_TARGET_OS_IS_UEFI) + return() +endif() + add_custom_target(libc-math-smoke-tests) add_dependencies(libc-math-unittests libc-math-smoke-tests) diff --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt index e4d4fc5b52558..50256a562f11b 100644 --- a/libc/test/src/stdfix/CMakeLists.txt +++ b/libc/test/src/stdfix/CMakeLists.txt @@ -113,38 +113,40 @@ add_libc_test( libc.src.__support.FPUtil.sqrt ) -add_libc_test( - exphk_test - SUITE - libc-stdfix-tests - HDRS - ExpTest.h - SRCS - exphk_test.cpp - COMPILE_OPTIONS - ${libc_opt_high_flag} - DEPENDS - libc.src.stdfix.exphk - libc.src.math.exp - libc.src.__support.CPP.bit - libc.src.__support.fixed_point.fx_rep - libc.src.__support.FPUtil.basic_operations -) +if(NOT LIBC_TARGET_OS_IS_UEFI) + add_libc_test( + exphk_test + SUITE + libc-stdfix-tests + HDRS + ExpTest.h + SRCS + exphk_test.cpp + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.stdfix.exphk + libc.src.math.exp + libc.src.__support.CPP.bit + libc.src.__support.fixed_point.fx_rep + libc.src.__support.FPUtil.basic_operations + ) -add_libc_test( - expk_test - SUITE - libc-stdfix-tests - HDRS - ExpTest.h - SRCS - expk_test.cpp - COMPILE_OPTIONS - ${libc_opt_high_flag} - DEPENDS - libc.src.stdfix.expk - libc.src.math.exp - libc.src.__support.CPP.bit - libc.src.__support.fixed_point.fx_rep - libc.src.__support.FPUtil.basic_operations -) + add_libc_test( + expk_test + SUITE + libc-stdfix-tests + HDRS + ExpTest.h + SRCS + expk_test.cpp + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.stdfix.expk + libc.src.math.exp + libc.src.__support.CPP.bit + libc.src.__support.fixed_point.fx_rep + libc.src.__support.FPUtil.basic_operations + ) +endif() diff --git a/libc/test/src/stdio/printf_core/CMakeLists.txt b/libc/test/src/stdio/printf_core/CMakeLists.txt index ff7ebbc4f5fd0..a75ad45a3a09a 100644 --- a/libc/test/src/stdio/printf_core/CMakeLists.txt +++ b/libc/test/src/stdio/printf_core/CMakeLists.txt @@ -1,3 +1,7 @@ +if(LIBC_TARGET_OS_IS_UEFI) + return() +endif() + add_libc_unittest( parser_test SUITE diff --git a/libc/test/src/stdio/scanf_core/CMakeLists.txt b/libc/test/src/stdio/scanf_core/CMakeLists.txt index 06735ddb23be7..fe2de3aa2d63a 100644 --- a/libc/test/src/stdio/scanf_core/CMakeLists.txt +++ b/libc/test/src/stdio/scanf_core/CMakeLists.txt @@ -1,3 +1,7 @@ +if(LIBC_TARGET_OS_IS_UEFI) + return() +endif() + add_libc_unittest( parser_test SUITE diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt index 12add224f386a..f0697bc534b95 100644 --- a/libc/test/src/time/CMakeLists.txt +++ b/libc/test/src/time/CMakeLists.txt @@ -1,5 +1,9 @@ add_custom_target(libc_time_unittests) +if(LIBC_TARGET_OS_IS_UEFI) + return() +endif() + add_libc_unittest( asctime_test SUITE diff --git a/libc/test/utils/UnitTest/CMakeLists.txt b/libc/test/utils/UnitTest/CMakeLists.txt index d3af8245515b9..be4db2e2efc19 100644 --- a/libc/test/utils/UnitTest/CMakeLists.txt +++ b/libc/test/utils/UnitTest/CMakeLists.txt @@ -1,4 +1,4 @@ -if(LIBC_TARGET_OS_IS_GPU) +if(LIBC_TARGET_OS_IS_GPU OR LIBC_TARGET_OS_IS_UEFI) return() endif() From 778c66cadc11bc7f8c57dc537285f471e4dc9582 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 24 Dec 2024 20:38:26 -0800 Subject: [PATCH 15/23] [libc] add python test runner for uefi --- libc/cmake/modules/LLVMLibCTestRules.cmake | 4 +- libc/test/scripts/uefi_runner.py | 194 +++++++++++++++++++++ 2 files changed, 197 insertions(+), 1 deletion(-) create mode 100755 libc/test/scripts/uefi_runner.py diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index b85e75f15a62c..a1cda112d6504 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -605,6 +605,7 @@ function(add_integration_test test_name) ${INTEGRATION_TEST_ENV} $<$:${gpu_loader_exe}> ${CMAKE_CROSSCOMPILING_EMULATOR} + $<$:${LIBC_TARGET_TRIPLE}> ${INTEGRATION_TEST_LOADER_ARGS} $ ${INTEGRATION_TEST_ARGS}) add_custom_target( @@ -799,7 +800,8 @@ function(add_libc_hermetic test_name) endif() set(test_cmd ${HERMETIC_TEST_ENV} - $<$:${gpu_loader_exe}> ${CMAKE_CROSSCOMPILING_EMULATOR} ${HERMETIC_TEST_LOADER_ARGS} + $<$:${gpu_loader_exe}> ${CMAKE_CROSSCOMPILING_EMULATOR} + $<$:${LIBC_TARGET_TRIPLE}> ${HERMETIC_TEST_LOADER_ARGS} $ ${HERMETIC_TEST_ARGS}) add_custom_target( ${fq_target_name} diff --git a/libc/test/scripts/uefi_runner.py b/libc/test/scripts/uefi_runner.py new file mode 100755 index 0000000000000..fa8bee4ad63bd --- /dev/null +++ b/libc/test/scripts/uefi_runner.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +# +# ===- UEFI runner for binaries ------------------------------*- python -*--==# +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ==-------------------------------------------------------------------------==# + +import argparse +import os +import platform +import re +import shutil +import subprocess +import tempfile + + +class Target: + def __init__(self, triple: str): + self.triple = triple.split("-") + assert len(self.triple) == 2 or len(self.triple) == 3 + + def arch(self): + return self.triple[0] + + def isNativeArch(self): + return self.arch() == Target.defaultArch() + + def vendor(self): + if len(self.triple) == 2: + return "unknown" + + return self.triple[1] + + def os(self): + if len(self.triple) == 2: + return self.triple[1] + + return self.triple[2] + + def abi(self): + if len(self.triple) < 4: + return "llvm" + + return self.triple[3] + + def qemuBinary(self): + return f"qemu-system-{self.arch()}" + + def qemuArgs(self): + if self.arch() == "aarch64": + args = ["-machine", "virt"] + + if self.isNativeArch(): + args.pop() + args.append("virt,gic-version=max,accel=kvm:tcg") + args.append("-cpu") + args.append("max") + + return args + + if self.arch() == "x86_64" and self.isNativeArch(): + return [ + "-machine", + "accel=kvm:tcg", + "-cpu", + "max", + ] + return [] + + def ovmfPath(self): + if self.arch() == "aarch64": + return "AAVMF_CODE.fd" + + if self.arch() == "x86_64": + return "OVMF_CODE.fd" + + raise Exception(f"{self.arch()} is not a valid architecture") + + def efiArch(self): + if self.arch() == "aarch64": + return "AA64" + + if self.arch() == "x86_64": + return "X64" + + raise Exception(f"{self.arch()} is not a valid architecture") + + def efiFileName(self): + return f"BOOT{self.efiArch()}.EFI" + + def __str__(self): + return f"{self.arch()}-{self.vendor()}-{self.os()}-{self.abi()}" + + def default(): + return Target(f"{Target.defaultArch()}-unknown-{Target.defaultOs()}") + + def defaultArch(): + return platform.machine() + + def defaultOs(): + return platform.system().lower() + + +def main(): + parser = argparse.ArgumentParser(description="UEFI runner for binaries") + parser.add_argument("binary_file", help="Path to the UEFI binary to execute") + parser.add_argument( + "--target", + help="Triplet which specifies what the target is", + ) + parser.add_argument( + "--ovmf-path", + help="Path to the directory where OVMF is located", + ) + args = parser.parse_args() + target = Target.default() if args.target is None else Target(args.target) + + ovmfFile = os.path.join( + args.ovmf_path + or os.getenv("OVMF_PATH") + or f"/usr/share/edk2/{target.efiArch().lower()}", + target.ovmfPath(), + ) + + qemuArgs = [target.qemuBinary()] + qemuArgs.extend(target.qemuArgs()) + + qemuArgs.append("-drive") + qemuArgs.append(f"if=pflash,format=raw,unit=0,readonly=on,file={ovmfFile}") + + qemuArgs.append("-nographic") + qemuArgs.append("-serial") + qemuArgs.append("stdio") + + qemuArgs.append("-monitor") + qemuArgs.append("none") + + with tempfile.TemporaryDirectory() as tempdir: + qemuArgs.append("-drive") + qemuArgs.append(f"file=fat:rw:{tempdir},format=raw,media=disk") + + os.mkdir(os.path.join(tempdir, "EFI")) + os.mkdir(os.path.join(tempdir, "EFI", "BOOT")) + + shutil.copyfile( + args.binary_file, os.path.join(tempdir, "EFI", "BOOT", target.efiFileName()) + ) + + proc = subprocess.Popen( + qemuArgs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True + ) + + num_tests = 0 + num_suites = 0 + + while True: + line = proc.stdout.readline() + if not line: + break + + line = line.rstrip() + + if num_tests > 0: + print(line) + + x = re.search(r"Running ([0-9]+) tests? from ([0-9]+) tests? suite\.", line) + if not x is None: + num_tests = int(x.group(1)) + num_suites = int(x.group(2)) + continue + + x = re.search( + r"Ran ([0-9]+) tests?\. PASS: ([0-9]+) FAIL: ([0-9]+)", line + ) + + if not x is None: + proc.kill() + ran_tests = int(x.group(1)) + passed_tests = int(x.group(2)) + failed_tests = int(x.group(3)) + + assert passed_tests + failed_tests == ran_tests + assert ran_tests == num_tests + + if failed_tests > 0: + raise Exception("A test failed") + break + + +if __name__ == "__main__": + main() From 332c39999edd1c2df9517c82ecb1cb4ab0bd40b0 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 7 Jan 2025 18:21:26 -0800 Subject: [PATCH 16/23] [libc] remove param names from unused uefi functions --- libc/src/__support/OSUtil/uefi/io.cpp | 6 +----- libc/src/__support/UEFI/file.cpp | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/libc/src/__support/OSUtil/uefi/io.cpp b/libc/src/__support/OSUtil/uefi/io.cpp index 885bbc690bea8..d281aee449880 100644 --- a/libc/src/__support/OSUtil/uefi/io.cpp +++ b/libc/src/__support/OSUtil/uefi/io.cpp @@ -14,11 +14,7 @@ namespace LIBC_NAMESPACE_DECL { -ssize_t read_from_stdin(char *buf, size_t size) { - (void)buf; - (void)size; - return 0; -} +ssize_t read_from_stdin(char *, size_t) { return 0; } void write_to_stdout(cpp::string_view msg) { // TODO: use mbstowcs once implemented diff --git a/libc/src/__support/UEFI/file.cpp b/libc/src/__support/UEFI/file.cpp index edf1b51e900aa..bec8610303f46 100644 --- a/libc/src/__support/UEFI/file.cpp +++ b/libc/src/__support/UEFI/file.cpp @@ -29,9 +29,7 @@ void File::reset() { } } -size_t File::read(void *data, size_t len) { - (void)data; - (void)len; +size_t File::read(void *, size_t) { if (needsReset()) reset(); From 0d12108066e9dbd5cfcc41b8a8ec20cd28fddb18 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 7 Jan 2025 18:34:22 -0800 Subject: [PATCH 17/23] [libc] fix uefi code formatting --- libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h | 6 +----- .../llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h | 6 +----- .../llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h | 6 +----- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h index 3f186cf245d89..f6a0b2e1f45c0 100644 --- a/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h +++ b/libc/include/llvm-libc-types/EFI_DEVICE_PATH_PROTOCOL.h @@ -12,11 +12,7 @@ #include "../llvm-libc-macros/stdint-macros.h" #define EFI_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0x09576e91, 0x6d3f, 0x11d2, { \ - 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } + {0x09576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} typedef struct _EFI_DEVICE_PATH_PROTOCOL { uint8_t Type; diff --git a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h index 0a7384e7de522..a6dc0952b6310 100644 --- a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h +++ b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_INPUT_PROTOCOL.h @@ -16,11 +16,7 @@ #include "char16_t.h" #define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ - { \ - 0x387477c1, 0x69c7, 0x11d2, { \ - 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } + {0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} typedef struct { uint16_t ScanCode; diff --git a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h index 307db79e1b318..b5014c46a0722 100644 --- a/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h +++ b/libc/include/llvm-libc-types/EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.h @@ -14,11 +14,7 @@ #include "size_t.h" #define EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ - { \ - 0x387477c2, 0x69c7, 0x11d2, { \ - 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } + {0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} struct _EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; From 89605084d489468138f1a86a7b4516cac8c63006 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 21 Jan 2025 18:54:23 -0800 Subject: [PATCH 18/23] [libc] add copyright to EFIAPI macro --- libc/include/llvm-libc-macros/EFIAPI-macros.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libc/include/llvm-libc-macros/EFIAPI-macros.h b/libc/include/llvm-libc-macros/EFIAPI-macros.h index d6cc1784bb786..cb854928d0ab7 100644 --- a/libc/include/llvm-libc-macros/EFIAPI-macros.h +++ b/libc/include/llvm-libc-macros/EFIAPI-macros.h @@ -1,3 +1,11 @@ +//===-- Definition of EFIAPI macro ------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===------------------------------------------------------------------===// + #ifndef LLVM_LIBC_MACROS_EFIAPI_MACROS_H #define LLVM_LIBC_MACROS_EFIAPI_MACROS_H From c0211ab12598f17c17cccd5a4c802f219adb78be Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Tue, 21 Jan 2025 19:04:23 -0800 Subject: [PATCH 19/23] [libc] fix uefi signal-macros header --- libc/include/llvm-libc-macros/uefi/signal-macros.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libc/include/llvm-libc-macros/uefi/signal-macros.h b/libc/include/llvm-libc-macros/uefi/signal-macros.h index 2d8159240de8b..6ad69421fbd0f 100644 --- a/libc/include/llvm-libc-macros/uefi/signal-macros.h +++ b/libc/include/llvm-libc-macros/uefi/signal-macros.h @@ -1,4 +1,4 @@ -//===-- Definition of GPU signal number macros ----------------------------===// +//===-- Definition of UEFI signal number macros ---------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_MACROS_GPU_SIGNAL_MACROS_H -#define LLVM_LIBC_MACROS_GPU_SIGNAL_MACROS_H +#ifndef LLVM_LIBC_MACROS_UEFI_SIGNAL_MACROS_H +#define LLVM_LIBC_MACROS_UEFI_SIGNAL_MACROS_H #define SIGINT 2 #define SIGILL 4 @@ -25,4 +25,4 @@ #define __NSIGSET_WORDS NSIG -#endif // LLVM_LIBC_MACROS_GPU_SIGNAL_MACROS_H +#endif // LLVM_LIBC_MACROS_UEFI_SIGNAL_MACROS_H From c57b2486e0c778e85581e38a8f6c3ee25114acfd Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Sat, 8 Feb 2025 07:40:21 -0800 Subject: [PATCH 20/23] [libc] fix uefi nitpicks --- libc/CMakeLists.txt | 7 ++++--- libc/src/__support/threads/uefi/mutex.h | 4 ++-- libc/src/stdio/uefi/puts.cpp | 4 ++-- libc/startup/uefi/crt1.cpp | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index 69b1b3aaccb85..11323ac7b0efe 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -257,10 +257,11 @@ else() set(LIBC_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}) endif() +if(LIBC_TARGET_OS_IS_GPU) + include(prepare_libc_gpu_build) +endif() + if(LIBC_TARGET_OS_IS_GPU OR LIBC_TARGET_OS_IS_UEFI) - if(LIBC_TARGET_OS_IS_GPU) - include(prepare_libc_gpu_build) - endif() set(LIBC_ENABLE_UNITTESTS OFF) endif() diff --git a/libc/src/__support/threads/uefi/mutex.h b/libc/src/__support/threads/uefi/mutex.h index c76b919f26324..44e4e8eb5ab84 100644 --- a/libc/src/__support/threads/uefi/mutex.h +++ b/libc/src/__support/threads/uefi/mutex.h @@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL { /// Implementation of a simple passthrough mutex which guards nothing. A -/// complete Mutex locks in general cannot be implemented on the GPU. We simply +/// complete Mutex locks in general cannot be implemented in UEFI. We simply /// define the Mutex interface and require that only a single thread executes /// code requiring a mutex lock. struct Mutex { @@ -29,4 +29,4 @@ struct Mutex { } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_GPU_MUTEX_H +#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_UEFI_MUTEX_H diff --git a/libc/src/stdio/uefi/puts.cpp b/libc/src/stdio/uefi/puts.cpp index cb4ff40f365d6..de9bf61847d2d 100644 --- a/libc/src/stdio/uefi/puts.cpp +++ b/libc/src/stdio/uefi/puts.cpp @@ -14,11 +14,11 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) { - int rc = (int)stdout.write(reinterpret_cast(str), strlen(str)); + int rc = static_cast(stdout.write(reinterpret_cast(str), strlen(str))); if (rc < 1) return rc; - return (int)stdout.write("\r\n", 2); + return static_cast(stdout.write("\r\n", 2)); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/startup/uefi/crt1.cpp b/libc/startup/uefi/crt1.cpp index 5676a47613580..9da8b8c1e9556 100644 --- a/libc/startup/uefi/crt1.cpp +++ b/libc/startup/uefi/crt1.cpp @@ -23,7 +23,7 @@ static void call_init_array_callbacks() { unsigned long nptrs = (unsigned long)__CTOR_LIST__[0]; unsigned long i; - if (nptrs == (unsigned long)-1) { + if (nptrs == ~0ul) { for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++) ; } From 41a17d391485726b34b8cb97977708ce5dad7cd6 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Sat, 8 Feb 2025 07:46:32 -0800 Subject: [PATCH 21/23] [libc] make uefi exit unreachable past exit call --- libc/src/__support/OSUtil/uefi/exit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/src/__support/OSUtil/uefi/exit.cpp b/libc/src/__support/OSUtil/uefi/exit.cpp index fc8b9e6549b24..0d7b6fe70d0c0 100644 --- a/libc/src/__support/OSUtil/uefi/exit.cpp +++ b/libc/src/__support/OSUtil/uefi/exit.cpp @@ -16,8 +16,8 @@ namespace internal { [[noreturn]] void exit(int status) { efi_system_table->BootServices->Exit(efi_image_handle, status, 0, NULL); - while (true) - ; + + __builtin_unreachable(); } } // namespace internal From a6e47ded286310b77acd30eb5a75aa2d48ee77e3 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Sat, 8 Feb 2025 07:47:11 -0800 Subject: [PATCH 22/23] [libc] fix uefi puts formatting --- libc/src/stdio/uefi/puts.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libc/src/stdio/uefi/puts.cpp b/libc/src/stdio/uefi/puts.cpp index de9bf61847d2d..98758183c694e 100644 --- a/libc/src/stdio/uefi/puts.cpp +++ b/libc/src/stdio/uefi/puts.cpp @@ -14,7 +14,8 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) { - int rc = static_cast(stdout.write(reinterpret_cast(str), strlen(str))); + int rc = static_cast( + stdout.write(reinterpret_cast(str), strlen(str))); if (rc < 1) return rc; From 61cad7308a18c66211a3f39868b6482f4ca66c61 Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Sat, 8 Feb 2025 09:00:07 -0800 Subject: [PATCH 23/23] [libc] adjust testing for uefi --- libc/cmake/modules/LLVMLibCTestRules.cmake | 1 + libc/test/UnitTest/CMakeLists.txt | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index a1cda112d6504..cabeba5828262 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -785,6 +785,7 @@ function(add_libc_hermetic test_name) ${fq_deps_list}) # TODO: currently the dependency chain is broken such that getauxval cannot properly # propagate to hermetic tests. This is a temporary workaround. + # getauxval does not exist on UEFI. if (LIBC_TARGET_ARCHITECTURE_IS_AARCH64 AND NOT LIBC_TARGET_OS_IS_UEFI) target_link_libraries( ${fq_build_target_name} diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt index c143487daf009..570bd600d1a43 100644 --- a/libc/test/UnitTest/CMakeLists.txt +++ b/libc/test/UnitTest/CMakeLists.txt @@ -25,8 +25,7 @@ function(add_unittest_framework_library name) endif() endforeach() - # UEFI requires full builds - if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_UEFI) + if(LLVM_LIBC_FULL_BUILD) # TODO: Build test framework with LIBC_FULL_BUILD in full build mode after # making LibcFPExceptionHelpers and LibcDeathTestExecutors hermetic. set(LLVM_LIBC_FULL_BUILD "")