aboutsummaryrefslogtreecommitdiff
path: root/src/target/smp.c
diff options
context:
space:
mode:
authorMichel Jaouen <michel.jaouen@stericsson.com>2011-04-19 08:43:33 +0200
committerØyvind Harboe <oyvind.harboe@zylin.com>2011-04-28 12:22:10 +0200
commitb778b36f29b74d6d571df85f984ae684672ea162 (patch)
tree774bc2d5f73daa527a6131b0fcb6351f4eb0812f /src/target/smp.c
parent36d60ee6c8d3aa1865dac2378c481954ba402910 (diff)
downloadriscv-openocd-b778b36f29b74d6d571df85f984ae684672ea162.zip
riscv-openocd-b778b36f29b74d6d571df85f984ae684672ea162.tar.gz
riscv-openocd-b778b36f29b74d6d571df85f984ae684672ea162.tar.bz2
smp : infra for smp minimum support
Diffstat (limited to 'src/target/smp.c')
-rw-r--r--src/target/smp.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/target/smp.c b/src/target/smp.c
new file mode 100644
index 0000000..aabfa5b
--- /dev/null
+++ b/src/target/smp.c
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * *
+ * Copyright (C) ST-Ericsson SA 2011 *
+ * Author: Michel Jaouen <michel.jaouen@stericsson.com> for ST-Ericsson. *
+ * 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 2 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "server/server.h"
+#include <helper/types.h>
+
+#include "target/target.h"
+
+#include "server/gdb_server.h"
+#include "smp.h"
+
+
+/* implementation of new packet in gdb interface for smp feature */
+/* */
+/* j : smp status request */
+/* J : smp set request */
+/* */
+/* jc :read core id displayed by gdb connection */
+/* reply XXXXXXXX core id is int32_t , 8 hex digits */
+/* */
+/* Reply ENN error not supported (target not smp) */
+/* */
+/* JcXX set core id displayed at next gdb continue */
+/* maximum 8 bytes described core id int32_t (8 hex digits) */
+/* (core id -1 , reserved for returning to normal continue mode) */
+/* Reply ENN error not supported(target not smp,core id out of range) */
+/* Reply OK : for success */
+/* */
+/* handling of this packet within gdb can be done by the creation */
+/* internal variable by mean of function allocate_computed_value */
+/* set $_core 1 => Jc01 packet is sent */
+/* print $_core => jc packet is sent and result is affected in $ */
+/* Another way to test this packet is the usage of maintenance packet */
+/* maint packet Jc01 */
+/* maint packet jc */
+
+static const char DIGITS[16] = "0123456789abcdef";
+
+
+/* packet j :smp status request */
+int gdb_read_smp_packet(struct connection *connection,
+ struct target *target, char *packet, int packet_size)
+{
+ uint32_t len = sizeof(int32_t);
+ uint8_t *buffer;
+ char *hex_buffer;
+ int retval = ERROR_OK;
+ if (target->smp)
+ {
+ if (strstr(packet, "jc"))
+ {
+ hex_buffer = malloc(len * 2 + 1);
+ buffer = (uint8_t *)&target->gdb_service->core[0];
+ uint32_t i;
+ for (i = 0; i < 4; i++)
+ {
+ uint8_t t = buffer[i];
+ hex_buffer[2 * i] = DIGITS[(t >> 4) & 0xf];
+ hex_buffer[2 * i + 1] = DIGITS[t & 0xf];
+ }
+
+ gdb_put_packet(connection, hex_buffer, len * 2);
+
+ free(hex_buffer);
+ }
+ }
+ else
+ retval = gdb_put_packet(connection,"E01",3);
+ return retval;
+}
+
+/* J : smp set request */
+int gdb_write_smp_packet(struct connection *connection,
+ struct target *target, char *packet, int packet_size)
+{
+ char *separator;
+ int coreid = 0;
+ int retval = ERROR_OK;
+
+ /* skip command character */
+ if (target->smp)
+ {
+ if (strstr(packet, "Jc"))
+ {
+ packet+=2;
+ coreid = strtoul(packet, &separator, 16);
+ target->gdb_service->core[1] = coreid;
+ gdb_put_packet(connection, "OK", 2);
+ }
+ }
+ else
+ {
+ retval = gdb_put_packet(connection,"E01",3);
+ }
+ return ERROR_OK;
+}