diff options
| -rw-r--r-- | icetime/Makefile | 3 | ||||
| -rw-r--r-- | icetime/icetime.cc | 33 | ||||
| -rw-r--r-- | icetime/iceutil.cc | 179 | 
3 files changed, 190 insertions, 25 deletions
| diff --git a/icetime/Makefile b/icetime/Makefile index d260681..b1cd18d 100644 --- a/icetime/Makefile +++ b/icetime/Makefile @@ -26,10 +26,11 @@ share/$(CHIPDB_SUBDIR)/chipdb-5k.txt: ../icebox/chipdb-5k.txt  override LDFLAGS += --embed-file share  endif -icetime$(EXE): icetime.o +icetime$(EXE): icetime.o iceutil.o  	$(CXX) -o $@ $(LDFLAGS) $^ $(LDLIBS)  icetime.o: icetime.cc timings.inc +iceutil.o: iceutil.cc  timings.inc: timings.py ../icefuzz/timings_*.txt  	python3 timings.py > timings.inc.new diff --git a/icetime/icetime.cc b/icetime/icetime.cc index c49e2e2..a5a27a0 100644 --- a/icetime/icetime.cc +++ b/icetime/icetime.cc @@ -38,6 +38,8 @@  #include <emscripten.h>  #endif +std::string find_chipdb(std::string config_device); +  // add this number of ns as estimate for clock distribution mismatch  #define GLOBAL_CLK_DIST_JITTER 0.1 @@ -322,35 +324,18 @@ void read_config()  void read_chipdb()  {  	char buffer[1024]; +	std::string filepath = chipdbfile; -	if (!chipdbfile.empty()) { -		snprintf(buffer, 1024, "%s", chipdbfile.c_str()); -	} else -	if (PREFIX[0] == '~' && PREFIX[1] == '/') { -		std::string homedir; -#ifdef _WIN32 -		if (getenv("USERPROFILE") != nullptr) { -			homedir += getenv("USERPROFILE"); -		} -		else { -			if (getenv("HOMEDRIVE") != nullptr && -			    getenv("HOMEPATH") != nullptr) { -				homedir += getenv("HOMEDRIVE"); -				homedir += getenv("HOMEPATH"); -			} -		} -#else -		homedir += getenv("HOME"); -#endif -		snprintf(buffer, 1024, "%s%s/share/" CHIPDB_SUBDIR "/chipdb-%s.txt", homedir.c_str(), PREFIX+1, config_device.c_str()); -	} else { -		snprintf(buffer, 1024, PREFIX "/share/" CHIPDB_SUBDIR "/chipdb-%s.txt", config_device.c_str()); +	if (filepath.empty()) +		filepath = find_chipdb(config_device); +	if (filepath.empty()) { +		fprintf(stderr, "Can't find chipdb file for device %s\n", config_device.c_str()); +		exit(1);  	} -	FILE *fdb = fopen(buffer, "r"); +	FILE *fdb = fopen(filepath.c_str(), "r");  	if (fdb == nullptr) {  		perror("Can't open chipdb file"); -		fprintf(stderr, "  %s\n", buffer);  		exit(1);  	} diff --git a/icetime/iceutil.cc b/icetime/iceutil.cc new file mode 100644 index 0000000..ad8d662 --- /dev/null +++ b/icetime/iceutil.cc @@ -0,0 +1,179 @@ +/* + *  yosys -- Yosys Open SYnthesis Suite + * + *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> + * + *  Permission to use, copy, modify, and/or distribute this software for any + *  purpose with or without fee is hereby granted, provided that the above + *  copyright notice and this permission notice appear in all copies. + * + *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include <errno.h> +#include <string> +#include <sstream> +#include <cstring> + +#ifdef _WIN32 +#  include <windows.h> +#  include <io.h> +#elif defined(__APPLE__) +#  include <mach-o/dyld.h> +#  include <unistd.h> +#else +#  include <unistd.h> +#endif + +#ifdef __FreeBSD__ +#  include <sys/sysctl.h> +#endif + +#include <limits.h> + +#if defined(__linux__) || defined(__CYGWIN__) +std::string proc_self_dirname() +{ +	char path[PATH_MAX]; +	ssize_t buflen = readlink("/proc/self/exe", path, sizeof(path)); +	if (buflen < 0) { +		fprintf(stderr, "fatal error: readlink(\"/proc/self/exe\") failed: %s\n", strerror(errno)); +		exit(EXIT_FAILURE); +	} +	while (buflen > 0 && path[buflen-1] != '/') +		buflen--; +	return std::string(path, buflen); +} +#elif defined(__FreeBSD__) +std::string proc_self_dirname() +{ +	int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; +	size_t buflen; +	char *buffer; +	std::string path; +	if (sysctl(mib, 4, NULL, &buflen, NULL, 0) != 0) { +		fprintf(stderr, "fatal error: sysctl failed: %s\n", strerror(errno)); +		exit(EXIT_FAILURE); +	} +	buffer = (char*)malloc(buflen); +	if (buffer == NULL) { +		fprintf(stderr, "fatal error: malloc failed: %s\n", strerror(errno)); +		exit(EXIT_FAILURE); +	} +	if (sysctl(mib, 4, buffer, &buflen, NULL, 0) != 0) { +		fprintf(stderr, "fatal error: sysctl failed: %s\n", strerror(errno)); +		exit(EXIT_FAILURE); +	} +	while (buflen > 0 && buffer[buflen-1] != '/') +		buflen--; +	path.assign(buffer, buflen); +	free(buffer); +	return path; +} +#elif defined(__APPLE__) +std::string proc_self_dirname() +{ +	char *path = NULL; +	uint32_t buflen = 0; +	while (_NSGetExecutablePath(path, &buflen) != 0) +		path = (char *) realloc((void *) path, buflen); +	while (buflen > 0 && path[buflen-1] != '/') +		buflen--; +	return std::string(path, buflen); +} +#elif defined(_WIN32) +std::string proc_self_dirname() +{ +	int i = 0; +#  ifdef __MINGW32__ +	char longpath[MAX_PATH + 1]; +	char shortpath[MAX_PATH + 1]; +#  else +	WCHAR longpath[MAX_PATH + 1]; +	TCHAR shortpath[MAX_PATH + 1]; +#  endif +	if (!GetModuleFileName(0, longpath, MAX_PATH+1)) { +		fprintf(stderr, "fatal error: GetModuleFileName() failed.\n"); +		exit(EXIT_FAILURE); +	} +	if (!GetShortPathName(longpath, shortpath, MAX_PATH+1)) { +		fprintf(stderr, "fatal error: GetShortPathName() failed.\n"); +		exit(EXIT_FAILURE); +	} +	while (shortpath[i] != 0) +		i++; +	while (i > 0 && shortpath[i-1] != '/' && shortpath[i-1] != '\\') +		shortpath[--i] = 0; +	std::string path; +	for (i = 0; shortpath[i]; i++) +		path += char(shortpath[i]); +	return path; +} +#elif defined(EMSCRIPTEN) +std::string proc_self_dirname() +{ +	return "/"; +} +#else +	#error Dont know how to determine process executable base path! +#endif + +bool file_test_open(std::string path) +{ +	FILE *fdb = fopen(path.c_str(), "r"); +	if (fdb == nullptr) { +		return false; +	} +	fclose(fdb); +	return true; +} + +extern bool verbose; + +std::string find_chipdb(std::string config_device) +{ +	if (PREFIX[0] == '~' && PREFIX[1] == '/') { +		std::string homepath; +#ifdef _WIN32 +		if (getenv("USERPROFILE") != nullptr) { +			homepath += getenv("USERPROFILE"); +		} +		else { +			if (getenv("HOMEDRIVE") != nullptr && +			    getenv("HOMEPATH") != nullptr) { +				homepath += getenv("HOMEDRIVE"); +				homepath += getenv("HOMEPATH"); +			} +		} +#else +		homepath += getenv("HOME"); +#endif +		homepath += std::string(PREFIX + 1) + "/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt"; +		if (verbose) +			fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), homepath.c_str()); +		if (file_test_open(homepath)) +			return homepath; +	} + +	std::string prefixpath = PREFIX "/share/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt"; +	if (verbose) +		fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), prefixpath.c_str()); +	if (file_test_open(prefixpath)) +		return prefixpath; + +	std::string relbinarypath = proc_self_dirname() + "../share/" CHIPDB_SUBDIR "/chipdb-" + config_device + ".txt"; +	if (verbose) +		fprintf(stderr, "Looking for chipdb '%s' at %s\n", config_device.c_str(), relbinarypath.c_str()); +	if (file_test_open(relbinarypath)) +		return relbinarypath; + +	return ""; +} + | 
