1111#include < cstring>
1212#include < vector>
1313
14+ #if __has_include(<filesystem>)
15+ #include < filesystem>
16+ namespace fs = std::filesystem;
17+ #elif __has_include(<experimental/filesystem>)
18+ #include < experimental/filesystem>
19+ namespace fs = std::experimental::filesystem;
20+ #else
21+ #error "cannot include the filesystem library"
22+ #endif
23+
1424/*
1525 ET Driver.
1626
@@ -25,6 +35,72 @@ static struct ggml_et_driver {
2535 bool profiling_enabled = false ;
2636} _drv;
2737
38+ // Check at runtime environment variables for paths likely holding ET toolchain with sysemu elf files
39+ std::string ggml_et_get_default_et_path () {
40+ // List of environment variables to check in order of preference
41+ const char * const env_vars[] = {" ET_TOOLCHAIN" , " TOOLCHAIN_ROOT" };
42+
43+ for (const char * var : env_vars) {
44+ if (const char * et_path = std::getenv (var)) {
45+ if (et_path && *et_path != ' \0 ' ) {
46+ return fs::path (et_path).string ();
47+ }
48+ }
49+ }
50+
51+ // Otherwise assume default
52+ return fs::path (" /opt/et" ).string ();
53+ }
54+
55+ // config when using sysemu instead of PCIe hardware device
56+ // adapted from `ainekko/et-platform/esperanto-tools-libs/tools/src/bench.cpp`
57+ inline auto ggml_et_get_default_sysemu_options () {
58+ constexpr uint64_t kSysEmuMaxCycles = std::numeric_limits<uint64_t >::max ();
59+ constexpr uint64_t kSysEmuMinionShiresMask = 0x1FFFFFFFFu ;
60+ const std::string et_path = ggml_et_get_default_et_path () + " /" ;
61+
62+ emu::SysEmuOptions sysEmuOptions;
63+
64+ // Construct all paths
65+ sysEmuOptions.bootromTrampolineToBL2ElfPath = et_path + " lib/esperanto-fw/BootromTrampolineToBL2/BootromTrampolineToBL2.elf" ;
66+ sysEmuOptions.spBL2ElfPath = et_path + " lib/esperanto-fw/ServiceProcessorBL2/fast-boot/ServiceProcessorBL2_fast-boot.elf" ;
67+ sysEmuOptions.machineMinionElfPath = et_path + " lib/esperanto-fw/MachineMinion/MachineMinion.elf" ;
68+ sysEmuOptions.masterMinionElfPath = et_path + " lib/esperanto-fw/MasterMinion/MasterMinion.elf" ;
69+ sysEmuOptions.workerMinionElfPath = et_path + " lib/esperanto-fw/WorkerMinion/WorkerMinion.elf" ;
70+ sysEmuOptions.executablePath = et_path + " bin/sys_emu" ;
71+
72+ // Check that each path has a valid existing non-zero file otherwise emulator just silently hangs
73+ const std::vector<std::string> required_files = {
74+ sysEmuOptions.bootromTrampolineToBL2ElfPath ,
75+ sysEmuOptions.spBL2ElfPath ,
76+ sysEmuOptions.machineMinionElfPath ,
77+ sysEmuOptions.masterMinionElfPath ,
78+ sysEmuOptions.workerMinionElfPath ,
79+ sysEmuOptions.executablePath ,
80+ };
81+
82+ for (const auto & file : required_files) {
83+ if (!fs::exists (file) || fs::file_size (file) == 0 ) {
84+ // Check that each path has a valid existing non-zero file otherwise emulator just silently hangs
85+ GGML_LOG_ERROR (" ET: Unable to find required sysemu file: %s\n " , file.c_str ());
86+ GGML_LOG_ERROR (" ET: Confirm et-platform is correctly installed at configured path.\n " );
87+ exit (1 );
88+ }
89+ }
90+
91+ sysEmuOptions.runDir = (fs::current_path ().string () + " /" );
92+ sysEmuOptions.maxCycles = kSysEmuMaxCycles ;
93+ sysEmuOptions.minionShiresMask = kSysEmuMinionShiresMask ;
94+ sysEmuOptions.puUart0Path = sysEmuOptions.runDir + " pu_uart0_tx.log" ;
95+ sysEmuOptions.puUart1Path = sysEmuOptions.runDir + " pu_uart1_tx.log" ;
96+ sysEmuOptions.spUart0Path = sysEmuOptions.runDir + " spio_uart0_tx.log" ;
97+ sysEmuOptions.spUart1Path = sysEmuOptions.runDir + " spio_uart1_tx.log" ;
98+ sysEmuOptions.startGdb = false ;
99+ sysEmuOptions.memcheck = false ;
100+
101+ return sysEmuOptions;
102+ }
103+
28104// Forward declaration
29105static void ggml_et_driver_cleanup ();
30106
@@ -33,7 +109,16 @@ static bool ggml_et_driver_init() {
33109 assert (_drv.device_layer != nullptr );
34110 } else {
35111 try {
36- _drv.device_layer = dev::IDeviceLayer::createPcieDeviceLayer ();
112+ #if defined GGML_ET_SYSEMU && GGML_ET_SYSEMU
113+ // For emulator device using sysEmuOptions provided by function above enabled compiling with `-DGGML_ET_SYSEMU=ON`
114+ GGML_LOG_INFO (" ET: Attempting to initialize sysemu device loading firmware from %s\n " , ggml_et_get_default_et_path ().c_str ());
115+ _drv.device_layer = dev::IDeviceLayer::createSysEmuDeviceLayer (ggml_et_get_default_sysemu_options ());
116+ #else
117+ // For physical PCIe device
118+ GGML_LOG_INFO (" ET: Attempting to initialize PCIe hardware device\n " );
119+ _drv.device_layer = dev::IDeviceLayer::createPcieDeviceLayer ();
120+ #endif
121+
37122 _drv.runtime = rt::IRuntime::create (_drv.device_layer );
38123 GGML_LOG_INFO (" ET: FOUND %d devices!\n " , _drv.device_layer ->getDevicesCount ());
39124
0 commit comments