-nbproject
-.project
+COPYING
+INSTALL
+Makefile.in
+aclocal.m4
+autom4te.cache
+config.guess
+config.sub
+configure
+depcomp
+install-sh
+ltmain.sh
+missing
+*.bz2
+*.lo
*.o
-*.elf
-doc/tutorial/*.log
-doc/tutorial/*.aux
-libstlink.a
-test_usb
-test_sg
-gdbserver/st-util
-flash/flash
-*.log
-example/*/*.bin
-example/*/*.elf
-example/*/*/*.bin
-example/*/*/*/*.bin
-example/*/*/*.a
-example/*/*/*/*.a
+.libs
+libtool
+*.la
+config.log
+config.status
+compile
+st-flash
+st-util
+*.deps*
+*.dirstamp
+*.a
+Makefile
+*.exe
+example/blink/*.elf
+++ /dev/null
-# make ... for both stlink v1 and stlink v2 support
-##
-VPATH=src
-
-SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c
-OBJS_LIB=$(SOURCES_LIB:.c=.o)
-TEST_PROGRAMS=test_usb test_sg
-LDFLAGS=-L. -lstlink
-
-# libusb location
-LDFLAGS+=`pkg-config --libs libusb-1.0`
-CFLAGS+=`pkg-config --cflags libusb-1.0`
-
-CFLAGS+=-g
-CFLAGS+=-DDEBUG=1
-CFLAGS+=-std=gnu99
-CFLAGS+=-Wall -Wextra
-
-
-LIBRARY=libstlink.a
-
-all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS)
-
-$(LIBRARY): $(OBJS_LIB)
- @echo "objs are $(OBJS_LIB)"
- $(AR) -cr $@ $^
- @echo "done making library"
-
-
-test_sg: test_sg.o $(LIBRARY)
- @echo "building test_sg"
- $(CC) test_sg.o $(LDFLAGS) -o $@
-
-test_usb: test_usb.o $(LIBRARY)
- @echo "building test_usb"
- $(CC) test_usb.o $(LDFLAGS) -o $@
- @echo "done linking"
-
-%.o: %.c
- @echo "building $^ into $@"
- $(CC) $(CFLAGS) -c $^ -o $@
- @echo "done compiling"
-
-clean:
- rm -rf $(OBJS_LIB)
- rm -rf $(LIBRARY)
- rm -rf test_usb*
- rm -rf test_sg*
- $(MAKE) -C flash clean
- $(MAKE) -C gdbserver clean
-
-flash:
- $(MAKE) -C flash
-
-gdbserver:
- $(MAKE) -C gdbserver CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)"
-
-.PHONY: clean all flash gdbserver
--- /dev/null
+# Makefile.am -- Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = subdir-objects
+
+bin_PROGRAMS = st-flash st-util
+
+noinst_LIBRARIES = libstlink.a
+
+st_flash_SOURCES = flash/main.c
+st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h
+
+CFILES = \
+ src/stlink-common.c \
+ src/stlink-usb.c \
+ src/stlink-sg.c \
+ src/uglylogging.c
+
+HFILES = \
+ src/stlink-common.h \
+ src/stlink-usb.h \
+ src/stlink-sg.h \
+ src/uglylogging.h \
+ src/mmap.h
+
+libstlink_a_SOURCES = $(CFILES) $(HFILES)
+
+libstlink_a_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2
+libstlink_a_LIBADD = $(LIBOBJS)
+
+st_flash_LDADD = libstlink.a
+st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
+
+st_util_LDADD = libstlink.a
+st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
+
+EXTRA_DIST = autogen.sh
+
--- /dev/null
+#!/bin/sh
+autoreconf --install --force --verbose
--- /dev/null
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.61)
+AC_INIT([stlink],[0.5.2],[davem@devkitpro.org])
+AC_CONFIG_SRCDIR([src/stlink-common.c])
+AC_CONFIG_LIBOBJ_DIR([src])
+AM_INIT_AUTOMAKE([1.10])
+
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_CANONICAL_HOST
+AC_CANONICAL_BUILD
+AC_PROG_RANLIB
+AM_PROG_CC_C_O
+
+AC_CHECK_HEADERS(sys/mman.h)
+AC_CHECK_HEADERS(sys/poll.h)
+AC_CHECK_FUNCS(mmap)
+AC_REPLACE_FUNCS(mmap pread)
+
+# Checks for libraries.
+PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,,
+ AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***]))
+AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb)
+
+LIBS="$LIBS $USB_LIBS"
+CFLAGS="$CFLAGS $USB_CFLAGS"
+
+case "${host}" in
+ *-mingw32*)
+ LIBS="$LIBS -lws2_32"
+ CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CPPFLAGS"
+ ;;
+esac
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+
/* missing type */
typedef unsigned int uint32_t;
-
+void main(void);
/* hardware configuration */
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
+#ifdef __MINGW32__
+#include "mingw.h"
+#else
#include <sys/poll.h>
+#endif
static const char hex[] = "0123456789abcdef";
int gdb_send_packet(int fd, char* data) {
- unsigned length = strlen(data) + 5;
+ int length = strlen(data) + 5;
char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */
memset(packet, 0, length);
packet[0] = '$';
uint8_t cksum = 0;
- for(int i = 0; i < strlen(data); i++) {
+ for(unsigned int i = 0; i < strlen(data); i++) {
packet[i + 1] = data[i];
cksum += data[i];
}
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
+#ifdef __MINGW32__
+#include "mingw.h"
+#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
+#endif
#include <stlink-common.h>
current_memory_map = make_memory_map(sl);
+#ifdef __MINGW32__
+ WSADATA wsadata;
+ if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) {
+ goto winsock_error;
+ }
+#endif
+
while(serve(sl, state.listen_port) == 0);
+#ifdef __MINGW32__
+winsock_error:
+ WSACleanup();
+#endif
+
/* Switch back to mass storage mode before closing. */
stlink_run(sl);
stlink_exit_debug_mode(sl);
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"
"<memory-map>"
- " <memory type=\"rom\" start=\"0x00000000\" length=\"0x%x\"/>" // code = sram, bootrom or flash; flash is bigger
- " <memory type=\"ram\" start=\"0x20000000\" length=\"0x%x\"/>" // sram 8k
- " <memory type=\"flash\" start=\"0x08000000\" length=\"0x%x\">"
- " <property name=\"blocksize\">0x%x</property>"
+ " <memory type=\"rom\" start=\"0x00000000\" length=\"0x%zx\"/>" // code = sram, bootrom or flash; flash is bigger
+ " <memory type=\"ram\" start=\"0x20000000\" length=\"0x%zx\"/>" // sram 8k
+ " <memory type=\"flash\" start=\"0x08000000\" length=\"0x%zx\">"
+ " <property name=\"blocksize\">0x%zx</property>"
" </memory>"
" <memory type=\"ram\" start=\"0x40000000\" length=\"0x1fffffff\"/>" // peripheral regs
" <memory type=\"ram\" start=\"0xe0000000\" length=\"0x1fffffff\"/>" // cortex regs
- " <memory type=\"rom\" start=\"0x%08x\" length=\"0x%x\"/>" // bootrom
- " <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8\"/>" // option byte area
+ " <memory type=\"rom\" start=\"0x%08x\" length=\"0x%zx\"/>" // bootrom
+ " <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8x\"/>" // option byte area
"</memory-map>";
char* make_memory_map(stlink_t *sl) {
mask++;
}
- if((mask != -1) && (mask < 16)) {
+ if((mask != (uint32_t)-1) && (mask < 16)) {
for(i = 0; i < DATA_WATCH_NUM; i++) {
// is this an empty slot ?
if(data_watches[i].fun == WATCHDISABLED) {
}
static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) {
- int fit_blocks = 0, fit_length = 0;
+ unsigned int fit_blocks = 0, fit_length = 0;
for(struct flash_block* fb = flash_root; fb; fb = fb->next) {
/* Block: ------X------Y--------
}
unsigned int val = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
- struct sockaddr_in serv_addr = {0};
+ struct sockaddr_in serv_addr;
+ memset(&serv_addr,0,sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(port);
printf("Listening at *:%d...\n", port);
int client = accept(sock, NULL, NULL);
- signal (SIGINT, SIG_DFL);
+ //signal (SIGINT, SIG_DFL);
if(client < 0) {
perror("accept");
return 1;
if(!strcmp(queryName, "Supported")) {
reply = strdup("PacketSize=3fff;qXfer:memory-map:read+");
} else if(!strcmp(queryName, "Xfer")) {
- char *type, *op, *s_addr, *s_length;
+ char *type, *op, *__s_addr, *s_length;
char *tok = params;
char *annex __attribute__((unused));
type = strsep(&tok, ":");
op = strsep(&tok, ":");
annex = strsep(&tok, ":");
- s_addr = strsep(&tok, ",");
+ __s_addr = strsep(&tok, ",");
s_length = tok;
- unsigned addr = strtoul(s_addr, NULL, 16),
+ unsigned addr = strtoul(__s_addr, NULL, 16),
length = strtoul(s_length, NULL, 16);
#ifdef DEBUG
cmdName++; // vCommand -> Command
if(!strcmp(cmdName, "FlashErase")) {
- char *s_addr, *s_length;
+ char *__s_addr, *s_length;
char *tok = params;
- s_addr = strsep(&tok, ",");
+ __s_addr = strsep(&tok, ",");
s_length = tok;
- unsigned addr = strtoul(s_addr, NULL, 16),
+ unsigned addr = strtoul(__s_addr, NULL, 16),
length = strtoul(s_length, NULL, 16);
#ifdef DEBUG
reply = strdup("OK");
}
} else if(!strcmp(cmdName, "FlashWrite")) {
- char *s_addr, *data;
+ char *__s_addr, *data;
char *tok = params;
- s_addr = strsep(&tok, ":");
+ __s_addr = strsep(&tok, ":");
data = tok;
- unsigned addr = strtoul(s_addr, NULL, 16);
+ unsigned addr = strtoul(__s_addr, NULL, 16);
unsigned data_length = status - (data - packet);
// Length of decoded data cannot be more than
// Additional byte is reserved for alignment fix.
uint8_t *decoded = calloc(data_length + 1, 1);
unsigned dec_index = 0;
- for(int i = 0; i < data_length; i++) {
+ for(unsigned int i = 0; i < data_length; i++) {
if(data[i] == 0x7d) {
i++;
decoded[dec_index++] = data[i] ^ 0x20;
count : count + 4 - (count % 4));
reply = calloc(count * 2 + 1, 1);
- for(int i = 0; i < count; i++) {
+ for(unsigned int i = 0; i < count; i++) {
reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4];
reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf];
}
stm32_addr_t start = strtoul(s_start, NULL, 16);
unsigned count = strtoul(s_count, NULL, 16);
- for(int i = 0; i < count; i ++) {
+ for(unsigned int i = 0; i < count; i ++) {
char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 };
uint8_t byte = strtoul(hex, NULL, 16);
sl->q_buf[i] = byte;
--- /dev/null
+#ifdef __MINGW32__
+
+#include "mingw.h"
+
+#undef socket
+#undef connect
+#undef accept
+#undef shutdown
+
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
+{
+ struct timeval timeout, *toptr;
+ fd_set ifds, ofds, efds, *ip, *op;
+ unsigned int i, rc;
+
+ /* Set up the file-descriptor sets in ifds, ofds and efds. */
+ FD_ZERO(&ifds);
+ FD_ZERO(&ofds);
+ FD_ZERO(&efds);
+ for (i = 0, op = ip = 0; i < nfds; ++i) {
+ fds[i].revents = 0;
+ if(fds[i].events & (POLLIN|POLLPRI)) {
+ ip = &ifds;
+ FD_SET(fds[i].fd, ip);
+ }
+ if(fds[i].events & POLLOUT) {
+ op = &ofds;
+ FD_SET(fds[i].fd, op);
+ }
+ FD_SET(fds[i].fd, &efds);
+ }
+
+ /* Set up the timeval structure for the timeout parameter */
+ if(timo < 0) {
+ toptr = 0;
+ } else {
+ toptr = &timeout;
+ timeout.tv_sec = timo / 1000;
+ timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000;
+ }
+
+#ifdef DEBUG_POLL
+ printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n",
+ (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op);
+#endif
+ rc = select(0, ip, op, &efds, toptr);
+#ifdef DEBUG_POLL
+ printf("Exiting select rc=%d\n", rc);
+#endif
+
+ if(rc <= 0)
+ return rc;
+
+ if(rc > 0) {
+ for ( i = 0; i < nfds; ++i) {
+ int fd = fds[i].fd;
+ if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds))
+ fds[i].revents |= POLLIN;
+ if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds))
+ fds[i].revents |= POLLOUT;
+ if(FD_ISSET(fd, &efds))
+ /* Some error was detected ... should be some way to know. */
+ fds[i].revents |= POLLHUP;
+#ifdef DEBUG_POLL
+ printf("%d %d %d revent = %x\n",
+ FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds),
+ fds[i].revents
+ );
+#endif
+ }
+ }
+ return rc;
+}
+static void
+set_connect_errno(int winsock_err)
+{
+ switch(winsock_err) {
+ case WSAEINVAL:
+ case WSAEALREADY:
+ case WSAEWOULDBLOCK:
+ errno = EINPROGRESS;
+ break;
+ default:
+ errno = winsock_err;
+ break;
+ }
+}
+
+static void
+set_socket_errno(int winsock_err)
+{
+ switch(winsock_err) {
+ case WSAEWOULDBLOCK:
+ errno = EAGAIN;
+ break;
+ default:
+ errno = winsock_err;
+ break;
+ }
+}
+/*
+ * A wrapper around the socket() function. The purpose of this wrapper
+ * is to ensure that the global errno symbol is set if an error occurs,
+ * even if we are using winsock.
+ */
+SOCKET
+win32_socket(int domain, int type, int protocol)
+{
+ SOCKET fd = socket(domain, type, protocol);
+ if(fd == INVALID_SOCKET) {
+ set_socket_errno(WSAGetLastError());
+ }
+ return fd;
+}
+/*
+ * A wrapper around the connect() function. The purpose of this wrapper
+ * is to ensure that the global errno symbol is set if an error occurs,
+ * even if we are using winsock.
+ */
+int
+win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len)
+{
+ int rc = connect(fd, addr, addr_len);
+ assert(rc == 0 || rc == SOCKET_ERROR);
+ if(rc == SOCKET_ERROR) {
+ set_connect_errno(WSAGetLastError());
+ }
+ return rc;
+}
+
+/*
+ * A wrapper around the accept() function. The purpose of this wrapper
+ * is to ensure that the global errno symbol is set if an error occurs,
+ * even if we are using winsock.
+ */
+SOCKET
+win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len)
+{
+ SOCKET newfd = accept(fd, addr, addr_len);
+ if(newfd == INVALID_SOCKET) {
+ set_socket_errno(WSAGetLastError());
+ newfd = -1;
+ }
+ return newfd;
+}
+
+/*
+ * A wrapper around the shutdown() function. The purpose of this wrapper
+ * is to ensure that the global errno symbol is set if an error occurs,
+ * even if we are using winsock.
+ */
+int
+win32_shutdown(SOCKET fd, int mode)
+{
+ int rc = shutdown(fd, mode);
+ assert(rc == 0 || rc == SOCKET_ERROR);
+ if(rc == SOCKET_ERROR) {
+ set_socket_errno(WSAGetLastError());
+ }
+ return rc;
+}
+int win32_close_socket(SOCKET fd) {
+ int rc;
+
+ rc = closesocket(fd);
+ return rc;
+}
+
+
+ssize_t win32_write_socket(SOCKET fd, void *buf, int n)
+{
+ int rc = send(fd, buf, n, 0);
+ if(rc == SOCKET_ERROR) {
+ set_socket_errno(WSAGetLastError());
+ }
+ return rc;
+}
+
+ssize_t win32_read_socket(SOCKET fd, void *buf, int n)
+{
+ int rc = recv(fd, buf, n, 0);
+ if(rc == SOCKET_ERROR) {
+ set_socket_errno(WSAGetLastError());
+ }
+ return rc;
+}
+
+
+char * win32_strtok_r(char *s, const char *delim, char **lasts)
+{
+ register char *spanp;
+ register int c, sc;
+ char *tok;
+
+
+ if (s == NULL && (s = *lasts) == NULL)
+ return (NULL);
+
+ /*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+cont:
+ c = *s++;
+ for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+ if (c == sc)
+ goto cont;
+ }
+
+ if (c == 0) { /* no non-delimiter characters */
+ *lasts = NULL;
+ return (NULL);
+ }
+ tok = s - 1;
+
+ /*
+ * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+ * Note that delim must have one NUL; we stop if we see that, too.
+ */
+ for (;;) {
+ c = *s++;
+ spanp = (char *)delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *lasts = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+
+char *win32_strsep (char **stringp, const char *delim)
+{
+ register char *s;
+ register const char *spanp;
+ register int c, sc;
+ char *tok;
+
+ if ((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+
+#endif
+
+
--- /dev/null
+#ifdef __MINGW32__
+
+#include <io.h>
+
+#define _USE_W32_SOCKETS 1
+#include <windows.h>
+
+#define ENOTCONN WSAENOTCONN
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#define ENOBUFS WSAENOBUFS
+#define ECONNRESET WSAECONNRESET
+#define ESHUTDOWN WSAESHUTDOWN
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define EINPROGRESS WSAEINPROGRESS
+#define EISCONN WSAEISCONN
+
+/* winsock doesn't feature poll(), so there is a version implemented
+ * in terms of select() in mingw.c. The following definitions
+ * are copied from linux man pages. A poll() macro is defined to
+ * call the version in mingw.c.
+ */
+#define POLLIN 0x0001 /* There is data to read */
+#define POLLPRI 0x0002 /* There is urgent data to read */
+#define POLLOUT 0x0004 /* Writing now will not block */
+#define POLLERR 0x0008 /* Error condition */
+#define POLLHUP 0x0010 /* Hung up */
+#define POLLNVAL 0x0020 /* Invalid request: fd not open */
+struct pollfd {
+ SOCKET fd; /* file descriptor */
+ short events; /* requested events */
+ short revents; /* returned events */
+};
+#define poll(x, y, z) win32_poll(x, y, z)
+
+/* These wrappers do nothing special except set the global errno variable if
+ * an error occurs (winsock doesn't do this by default). They set errno
+ * to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), so code
+ * outside of this file "shouldn't" have to worry about winsock specific error
+ * handling.
+ */
+#define socket(x, y, z) win32_socket(x, y, z)
+#define connect(x, y, z) win32_connect(x, y, z)
+#define accept(x, y, z) win32_accept(x, y, z)
+#define shutdown(x, y) win32_shutdown(x, y)
+#define read(x, y, z) win32_read_socket(x, y, z)
+#define write(x, y, z) win32_write_socket(x, y, z)
+
+/* Winsock uses int instead of the usual socklen_t */
+typedef int socklen_t;
+
+int win32_poll(struct pollfd *, unsigned int, int);
+SOCKET win32_socket(int, int, int);
+int win32_connect(SOCKET, struct sockaddr*, socklen_t);
+SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *);
+int win32_shutdown(SOCKET, int);
+
+#define strtok_r(x, y, z) win32_strtok_r(x, y, z)
+#define strsep(x,y) win32_strsep(x,y)
+
+char *win32_strtok_r(char *s, const char *delim, char **lasts);
+char *win32_strsep(char **stringp, const char *delim);
+
+ssize_t win32_read_socket(SOCKET fd, void *buf, int n);
+ssize_t win32_write_socket(SOCKET fd, void *buf, int n);
+
+
+#endif
--- /dev/null
+/* mmap.c -- version of mmap for gold. */
+
+/* Copyright 2009 Free Software Foundation, Inc.
+ Written by Vladimir Simonov <sv@sw.ru>.
+
+ This file is part of gold.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+//#include "config.h"
+//#include "ansidecl.h"
+
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include "mmap.h"
+
+extern ssize_t pread (int, void *, size_t, off_t);
+
+void *
+mmap (void *__addr, size_t __len, int __prot,
+ int __flags, int __fd, long long __offset)
+{
+ void *ret;
+ ssize_t count;
+
+ if (__addr || (__fd != -1 && (__prot & PROT_WRITE))
+ || (__flags & MAP_SHARED))
+ return MAP_FAILED;
+
+ ret = malloc (__len);
+ if (!ret)
+ return MAP_FAILED;
+
+ if (__fd == -1)
+ return ret;
+
+ count = pread (__fd, ret, __len, __offset);
+ if ((size_t) count != __len)
+ {
+ free (ret);
+ return MAP_FAILED;
+ }
+
+ return ret;
+}
+
+int
+munmap (void *__addr, size_t __len)
+{
+ free (__addr);
+ return 0;
+}
--- /dev/null
+/* mmap.h -- mmap family functions prototypes for gold. */
+
+/* Copyright 2009 Free Software Foundation, Inc.
+ Written by Vladimir Simonov <sv@sw.ru>
+
+ This file is part of gold.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#ifndef GOLD_MMAP_H
+#define GOLD_MMAP_H
+
+#ifdef HAVE_SYS_MMAN_H
+
+#include <sys/mman.h>
+
+/* Some BSD systems still use MAP_ANON instead of MAP_ANONYMOUS. */
+
+#ifndef MAP_ANONYMOUS
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#else
+
+#define PROT_READ 0x1
+#define PROT_WRITE 0x2
+
+#define MAP_SHARED 0x01
+#define MAP_PRIVATE 0x02
+
+#define MAP_ANONYMOUS 0x20
+
+#define MAP_FAILED ((void *) -1)
+#endif /* HAVE_SYS_MMAN_H */
+
+#ifndef HAVE_MMAP
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void *mmap (void *__addr, size_t __len, int __prot,
+ int __flags, int __fd, long long __offset);
+extern int munmap (void *__addr, size_t __len);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAVE_MMAP */
+
+#endif /* GOLD_MMAP_H */
--- /dev/null
+/* pread.c -- version of pread for gold. */
+
+/* Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <iant@google.com>.
+
+ This file is part of gold.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* This file implements pread for systems which don't have it. This
+ file is only compiled if pread is not present on the system. This
+ is not an exact version of pread, as it does not preserve the
+ current file offset. */
+
+//#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+extern ssize_t pread (int, void *, size_t, off_t);
+
+ssize_t
+pread (int fd, void *buf, size_t count, off_t offset)
+{
+ if (lseek(fd, offset, SEEK_SET) != offset)
+ return -1;
+ return read(fd, buf, count);
+}
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/mman.h>
-
+#include "mmap.h"
#include "stlink-common.h"
#include "uglylogging.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/mman.h>
+#include "mmap.h"
#include "stlink-common.h"
#include "stlink-sg.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
-#include <time.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <libusb.h>
#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args)
#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args)
+#ifndef timersub
+/* This is a copy from GNU C Library (GNU LGPL 2.1), sys/time.h. */
+# define timersub(a, b, result) \
+ do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80};
volatile unsigned long flags;
};
-static void on_trans_done(struct libusb_transfer * trans) {
+static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) {
struct trans_ctx * const ctx = trans->user_data;
if (trans->status != LIBUSB_TRANSFER_COMPLETED)