aboutsummaryrefslogtreecommitdiff
path: root/src/platforms/dev2/platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/platforms/dev2/platform.c')
-rw-r--r--src/platforms/dev2/platform.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/platforms/dev2/platform.c b/src/platforms/dev2/platform.c
new file mode 100644
index 0000000..3d5929b
--- /dev/null
+++ b/src/platforms/dev2/platform.c
@@ -0,0 +1,171 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2011 Black Sphere Technologies Ltd.
+ * Written by Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include "platform.h"
+#include "gdb_if.h"
+#include "jtag_scan.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+#include <termios.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static int serial_fd = -1;
+static int debug;
+
+#define BUF_SIZE 4096
+static uint8_t outbuf[BUF_SIZE];
+static uint16_t bufptr = 0;
+
+int serial_open(const char *name)
+{
+ int fd;
+ /* Open. */
+ fd = open(name, O_RDWR | O_NOCTTY);
+ if (fd == -1)
+ return -1;
+ /* Setup raw. */
+ struct termios tc;
+ if(tcgetattr(fd, &tc) == -1) {
+ close(fd);
+ return -1;
+ }
+ tc.c_iflag &= ~(IGNPAR | PARMRK | ISTRIP | IGNBRK | BRKINT | IGNCR |
+ ICRNL | INLCR | IXON | IXOFF | IXANY | IMAXBEL);
+ tc.c_oflag &= ~(OPOST);
+ tc.c_cflag &= ~(HUPCL | CSTOPB | PARENB | PARODD | CSIZE);
+ tc.c_cflag |= CS8 | CLOCAL | CREAD;
+ tc.c_lflag &= ~(ICANON | ECHO | ISIG | IEXTEN | NOFLSH | TOSTOP);
+ tc.c_cc[VTIME] = 0;
+ tc.c_cc[VMIN] = 1;
+ tcflush(fd, TCIFLUSH);
+ if(tcsetattr(fd, TCSANOW, &tc) == -1) {
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int platform_init(int argc, char **argv)
+{
+ int c;
+ char *serial = NULL;
+
+ while((c = getopt(argc, argv, "ds:")) != -1) {
+ switch(c) {
+ case 'd':
+ debug = 1;
+ break;
+ case 's':
+ serial = optarg;
+ break;
+ }
+ }
+ if(optind != argc) {
+ fprintf(stderr, "too many arguments\n");
+ abort();
+ }
+
+ serial_fd = serial_open(serial);
+ if(serial_fd == -1) {
+ fprintf(stderr, "unable to open serial device: %s\n",
+ strerror(errno));
+ abort();
+ }
+
+ uint8_t init_str[] = {
+ DEV2_OP_RESET_SYNC, DEV2_OP_RESET_SYNC, DEV2_OP_RESET_SYNC,
+ DEV2_OP_RESET_SYNC, DEV2_OP_RESET_SYNC, DEV2_OP_RESET_SYNC,
+ DEV2_OP_RESET_SYNC, DEV2_OP_RESET_SYNC, DEV2_OP_RESET_SYNC,
+ DEV2_OP_RESET_SYNC, DEV2_OP_RESET_SYNC, DEV2_OP_RESET_SYNC,
+ DEV2_OP_SETUP, 8, 0, 0, 0, 0,
+ DEV2_OP_DIR, TMS_PIN | TCK_PIN | TDI_PIN
+ };
+ platform_buffer_write (init_str, sizeof (init_str));
+
+ assert(gdb_if_init() == 0);
+
+ jtag_scan(NULL);
+
+ return 0;
+}
+
+void platform_buffer_flush(void)
+{
+ if(bufptr) {
+ assert(write(serial_fd, outbuf, bufptr) == bufptr);
+ bufptr = 0;
+ }
+}
+
+int platform_buffer_write(const uint8_t *data, int size)
+{
+ if((bufptr + size) / BUF_SIZE > 0) platform_buffer_flush();
+ memcpy(outbuf + bufptr, data, size);
+ bufptr += size;
+ return size;
+}
+
+int platform_buffer_read(uint8_t *data, int size)
+{
+ int index = 0;
+ platform_buffer_flush();
+ while((index += read(serial_fd, data + index, size - index)) != size);
+ return size;
+}
+
+#ifdef WIN32
+#warning "This vasprintf() is dubious!"
+int vasprintf(char **strp, const char *fmt, va_list ap)
+{
+ int size = 128, ret = 0;
+
+ *strp = malloc(size);
+ while(*strp && ((ret = vsnprintf(*strp, size, fmt, ap)) == size))
+ *strp = realloc(*strp, size <<= 1);
+
+ return ret;
+}
+#endif
+
+const char *platform_target_voltage(void)
+{
+ return "not supported";
+}
+
+void platform_delay(uint32_t delay)
+{
+ usleep(delay * 100000);
+}
+
+void platform_debug(const char *fmt, ...)
+{
+ if(debug) {
+ va_list ap;
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ }
+}