Skip to content

Commit 585dccb

Browse files
authored
Merge pull request swiftlang#75427 from kubamracek/embedded-qemu
[embedded] Add QEMU-based testing configs for ARM and AVR for runtime testing
2 parents 49e4e06 + 22e3493 commit 585dccb

File tree

16 files changed

+690
-4
lines changed

16 files changed

+690
-4
lines changed

test/CMakeLists.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,9 @@ foreach(SDK ${SWIFT_SDKS})
286286
set(SWIFT_HAVE_LIBXML2 FALSE)
287287
endif()
288288

289+
set(VARIANT_EXTERNAL_EMBEDDED_PLATFORM FALSE)
290+
set(VARIANT_EXTERNAL_EMBEDDED_DEVICE)
291+
289292
swift_configure_lit_site_cfg(
290293
"${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in"
291294
"${test_bin_dir}/lit.site.cfg"
@@ -524,6 +527,28 @@ foreach(SDK ${SWIFT_SDKS})
524527
endforeach()
525528
endforeach()
526529

530+
if(SWIFT_SHOULD_BUILD_EMBEDDED_STDLIB_CROSS_COMPILING)
531+
set(VARIANT_SUFFIX "-embedded-armv7")
532+
set(VARIANT_TRIPLE "armv7em-none-none-eabi")
533+
set(VARIANT_EXTERNAL_EMBEDDED_PLATFORM TRUE)
534+
set(VARIANT_EXTERNAL_EMBEDDED_DEVICE "arm-qemu-stm32f4")
535+
set(SWIFT_TEST_RESULTS_DIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/swift-test-results/${VARIANT_TRIPLE}")
536+
swift_configure_lit_site_cfg(
537+
"${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in"
538+
"${CMAKE_CURRENT_BINARY_DIR}${VARIANT_SUFFIX}/lit.site.cfg"
539+
"test${VARIANT_SUFFIX}.lit.site.cfg")
540+
541+
set(VARIANT_SUFFIX "-embedded-avr")
542+
set(VARIANT_TRIPLE "avr-none-none-elf")
543+
set(VARIANT_EXTERNAL_EMBEDDED_PLATFORM TRUE)
544+
set(VARIANT_EXTERNAL_EMBEDDED_DEVICE "avr-qemu-atmega2560")
545+
set(SWIFT_TEST_RESULTS_DIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/swift-test-results/${VARIANT_TRIPLE}")
546+
swift_configure_lit_site_cfg(
547+
"${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in"
548+
"${CMAKE_CURRENT_BINARY_DIR}${VARIANT_SUFFIX}/lit.site.cfg"
549+
"test${VARIANT_SUFFIX}.lit.site.cfg")
550+
endif()
551+
527552
# Add shortcuts for the default variant.
528553
foreach(test_mode ${TEST_MODES})
529554
foreach(test_subset ${TEST_SUBSETS})

test/Driver/LegacyDriver/lit.local.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ config.environment = dict(config.environment)
33

44
# Remove the settings that force tests to use the old driver so that tests
55
# in this directory can set `SWIFT_USE_NEW_DRIVER` to test those code paths.
6-
del config.environment['SWIFT_USE_OLD_DRIVER']
7-
del config.environment['SWIFT_AVOID_WARNING_USING_OLD_DRIVER']
6+
if 'SWIFT_USE_OLD_DRIVER' in config.environment: del config.environment['SWIFT_USE_OLD_DRIVER']
7+
if 'SWIFT_AVOID_WARNING_USING_OLD_DRIVER' in config.environment: del config.environment['SWIFT_AVOID_WARNING_USING_OLD_DRIVER']

test/Profiler/lit.local.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
config.environment = dict(config.environment)
33

44
# Prefer the new driver for profiling tests
5-
del config.environment['SWIFT_USE_OLD_DRIVER']
6-
del config.environment['SWIFT_AVOID_WARNING_USING_OLD_DRIVER']
5+
if 'SWIFT_USE_OLD_DRIVER' in config.environment: del config.environment['SWIFT_USE_OLD_DRIVER']
6+
if 'SWIFT_AVOID_WARNING_USING_OLD_DRIVER' in config.environment: del config.environment['SWIFT_AVOID_WARNING_USING_OLD_DRIVER']

test/embedded/hello.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-run-simple-swift(-enable-experimental-feature Embedded -runtime-compatibility-version none -wmo) | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
// REQUIRES: executable_test
5+
// REQUIRES: OS=macosx || OS=linux-gnu || OS=none-eabi || OS=none-elf
6+
7+
print("Hello, Embedded Swift!")
8+
9+
// CHECK: Hello, Embedded Swift!

test/embedded/lit.local.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ if config.target_sdk_name == 'macosx':
1414
if 'embedded_stdlib' not in config.available_features:
1515
config.unsupported = True
1616

17+
config.environment = dict(config.environment)
18+
if 'SWIFT_USE_OLD_DRIVER' in config.environment: del config.environment['SWIFT_USE_OLD_DRIVER']
19+
if 'SWIFT_AVOID_WARNING_USING_OLD_DRIVER' in config.environment: del config.environment['SWIFT_AVOID_WARNING_USING_OLD_DRIVER']

test/lit.cfg

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ config.swift_demangle_yamldump = inferSwiftBinary('swift-demangle-yamldump')
348348
config.swift_demangle = inferSwiftBinary('swift-demangle')
349349
config.benchmark_o = inferSwiftBinary('Benchmark_O')
350350
config.benchmark_driver = inferSwiftBinary('Benchmark_Driver')
351+
config.lld = inferSwiftBinary('lld')
351352
config.wasm_ld = inferSwiftBinary('wasm-ld')
352353
config.swift_plugin_server = inferSwiftBinary('swift-plugin-server')
353354
config.swift_parse_test = inferSwiftBinary('swift-parse-test')
@@ -451,6 +452,8 @@ if run_os == 'openbsd' and run_cpu == 'amd64':
451452
run_ptrsize = '64' if ('64' in run_cpu or run_cpu == "s390x") else '32'
452453
if run_cpu == 'arm64_32':
453454
run_ptrsize = '32'
455+
if run_cpu == 'avr':
456+
run_ptrsize = '16'
454457

455458
run_ptrauth = 'ptrauth' if run_cpu == 'arm64e' else 'noptrauth'
456459
run_endian = 'little' if run_cpu != 's390x' else 'big'
@@ -2052,6 +2055,90 @@ elif run_os == 'wasi':
20522055
# The Swift interpreter is not available when targeting WebAssembly/WASI.
20532056
config.available_features.discard('swift_interpreter')
20542057

2058+
elif config.external_embedded_platform:
2059+
lit_config.note("Testing embedded platform " + config.variant_triple)
2060+
2061+
config.target_object_format = "elf"
2062+
config.target_sdk_name = "embedded"
2063+
config.target_runtime = "native"
2064+
config.target_shared_library_prefix = 'lib'
2065+
config.target_shared_library_suffix = ".so"
2066+
config.target_library_path_var = "LD_LIBRARY_PATH"
2067+
2068+
config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
2069+
2070+
embedded_test_support = os.path.join(config.swift_utils, 'embedded-test-support/embedded-test-support.py')
2071+
PATH = config.environment['PATH']
2072+
2073+
device = config.external_embedded_device
2074+
embedded_swift_flags = subprocess.check_output([embedded_test_support, "--device", device, "print-swift-flags"], env=config.environment).rstrip().decode('utf-8')
2075+
embedded_swift_frontend_flags = subprocess.check_output([embedded_test_support, "--device", device, "print-swift-frontend-flags"], env=config.environment).rstrip().decode('utf-8')
2076+
embedded_clang_flags = subprocess.check_output([embedded_test_support, "--device", device, "print-c-flags"], env=config.environment).rstrip().decode('utf-8')
2077+
2078+
config.target_build_swift = ' '.join([
2079+
config.swiftc,
2080+
'-target', config.variant_triple,
2081+
embedded_swift_flags,
2082+
mcp_opt, config.swift_test_options,
2083+
config.swift_driver_test_options, swift_execution_tests_extra_flags])
2084+
config.target_codesign = "echo"
2085+
config.target_build_swift_dylib = (
2086+
"%s -parse-as-library -emit-library -static -o '\\1'"
2087+
% (config.target_build_swift))
2088+
config.target_add_rpath = ''
2089+
config.target_swift_frontend = ' '.join([
2090+
config.swift_frontend,
2091+
'-target', config.variant_triple, embedded_swift_frontend_flags,
2092+
config.resource_dir_opt, mcp_opt,
2093+
config.swift_test_options, config.swift_frontend_test_options])
2094+
subst_target_swift_frontend_mock_sdk = config.target_swift_frontend
2095+
subst_target_swift_frontend_mock_sdk_after = ""
2096+
config.target_run = embedded_test_support + ' --device %s run --elf-file ' % device
2097+
config.target_env_prefix = ''
2098+
2099+
config.target_sil_opt = (
2100+
'%s -target %s %s %s %s' %
2101+
(config.sil_opt, config.variant_triple, config.resource_dir_opt, mcp_opt, config.sil_test_options))
2102+
subst_target_sil_opt_mock_sdk = config.target_sil_opt
2103+
subst_target_sil_opt_mock_sdk_after = ""
2104+
config.target_swift_symbolgraph_extract = ' '.join([
2105+
config.swift_symbolgraph_extract,
2106+
'-target', config.variant_triple,
2107+
mcp_opt])
2108+
config.target_swift_synthesize_interface = ' '.join([
2109+
config.swift_synthesize_interface,
2110+
'-target', config.variant_triple,
2111+
mcp_opt])
2112+
config.target_swift_ide_test = (
2113+
'%s -target %s %s %s %s %s' %
2114+
(config.swift_ide_test, config.variant_triple, config.resource_dir_opt,
2115+
mcp_opt, ccp_opt, config.swift_ide_test_test_options))
2116+
subst_target_swift_ide_test_mock_sdk = config.target_swift_ide_test
2117+
subst_target_swift_ide_test_mock_sdk_after = ""
2118+
config.target_swiftc_driver = (
2119+
"%s -target %s -toolchain-stdlib-rpath %s %s" %
2120+
(config.swiftc, config.variant_triple, config.resource_dir_opt, mcp_opt))
2121+
config.target_stdlib_swiftc_driver = config.target_swiftc_driver
2122+
config.target_swift_modulewrap = (
2123+
'%s -modulewrap -target %s' %
2124+
(config.swiftc, config.variant_triple))
2125+
config.target_swift_emit_pcm = (
2126+
'%s -emit-pcm -target %s' %
2127+
(config.swiftc, config.variant_triple))
2128+
config.target_clang = (
2129+
"%s -target %s %s %s" %
2130+
(config.clang, config.variant_triple, embedded_clang_flags, clang_mcp_opt))
2131+
config.target_ld = (
2132+
"%s -L%r" %
2133+
(config.lld, make_path(test_resource_dir, config.target_sdk_name)))
2134+
2135+
config.available_features.discard('swift_interpreter')
2136+
2137+
config.excludes += ['Unit']
2138+
2139+
if 'SWIFT_USE_OLD_DRIVER' in config.environment: del config.environment['SWIFT_USE_OLD_DRIVER']
2140+
if 'SWIFT_AVOID_WARNING_USING_OLD_DRIVER' in config.environment: del config.environment['SWIFT_AVOID_WARNING_USING_OLD_DRIVER']
2141+
20552142
else:
20562143
lit_config.fatal("Don't know how to define target_run and "
20572144
"target_build_swift for platform " + config.variant_triple)

test/lit.site.cfg.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ config.target_triple = "@LLVM_TARGET_TRIPLE@"
2929
config.variant_triple = "@VARIANT_TRIPLE@"
3030
config.variant_sdk = "@VARIANT_SDK@"
3131
config.variant_suffix = "@VARIANT_SUFFIX@"
32+
config.external_embedded_platform = "@VARIANT_EXTERNAL_EMBEDDED_PLATFORM@" == "TRUE"
33+
config.external_embedded_device = "@VARIANT_EXTERNAL_EMBEDDED_DEVICE@"
3234
config.swiftlib_dir = "@LIT_SWIFTLIB_DIR@"
3335
config.swift_test_results_dir = \
3436
lit_config.params.get("swift_test_results_dir", "@SWIFT_TEST_RESULTS_DIR@")
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
MEMORY
2+
{
3+
flash : ORIGIN = 0x08000000, LENGTH = 32K
4+
sram : ORIGIN = 0x20000000, LENGTH = 8K
5+
}
6+
7+
SECTIONS
8+
{
9+
.text : { *(.vectors*) ; *(.text*) } > flash
10+
.bss : { *(.bss*) } > sram
11+
.data : { *(.data*) } > sram
12+
/DISCARD/ : { *(.swift_modhash*) }
13+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift project authors.
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include <stddef.h>
14+
#include <stdint.h>
15+
16+
int main(int argc, char *argv[]);
17+
void qemu_exit(void);
18+
int puts(const char *);
19+
20+
__attribute__((noreturn))
21+
void reset(void) {
22+
main(0, NULL);
23+
qemu_exit();
24+
__builtin_trap();
25+
}
26+
27+
void interrupt(void) {
28+
puts("INTERRUPT\n");
29+
qemu_exit();
30+
while (1) {
31+
}
32+
}
33+
34+
__attribute__((aligned(4))) char stack[2048];
35+
36+
__attribute((used))
37+
__attribute((section(".vectors"))) void *vector_table[114] = {
38+
(void *)&stack[2048 - 4], // initial SP
39+
reset, // Reset
40+
41+
interrupt, // NMI
42+
interrupt, // HardFault
43+
interrupt, // MemManage
44+
interrupt, // BusFault
45+
interrupt, // UsageFault
46+
47+
0 // NULL for all the other handlers
48+
};
49+
50+
void qemu_exit() {
51+
__asm__ volatile("mov r0, #0x18");
52+
__asm__ volatile("movw r1, #0x0026");
53+
__asm__ volatile("movt r1, #0x2"); // construct 0x20026 in r1
54+
__asm__ volatile("bkpt #0xab");
55+
}
56+
57+
int putchar(int c) {
58+
// This is only valid in an emulator (QEMU), and it's skipping a proper configuration of the UART device
59+
// and waiting for a "ready to transit" state.
60+
61+
// STM32F1 specific location of USART1 and its DR register
62+
*(volatile uint32_t *)(0x40013800 + 0x04) = c;
63+
return c;
64+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
MEMORY
2+
{
3+
flash : ORIGIN = 0x08000000, LENGTH = 32K
4+
sram : ORIGIN = 0x20000000, LENGTH = 128K
5+
}
6+
7+
SECTIONS
8+
{
9+
.text : { *(.vectors*) ; *(.text*) } > flash
10+
.bss : { *(.bss*) } > sram
11+
.data : { *(.data*) } > sram
12+
/DISCARD/ : { *(.swift_modhash*) }
13+
}

0 commit comments

Comments
 (0)