aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.arch
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2007-06-12 14:35:26 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2007-06-12 14:35:26 +0000
commit23d964e7b6625bec3822bcb9613f65362b9b3026 (patch)
treec9c8d4a9f98b11ad39dc14dddc8f41374747fc33 /gdb/testsuite/gdb.arch
parent374c1d382bcb2271b3a39ee369717f255ca0777a (diff)
downloadgdb-23d964e7b6625bec3822bcb9613f65362b9b3026.zip
gdb-23d964e7b6625bec3822bcb9613f65362b9b3026.tar.gz
gdb-23d964e7b6625bec3822bcb9613f65362b9b3026.tar.bz2
* target.h (enum target_object): Add TARGET_OBJECT_SPU.
* spu-linux-nat.c (spu_xfer_partial): Handle TARGET_OBJECT_SPU. * spu-tdep.h (SPU_NUM_PSEUDO_REGS): Add 5 pseudo registers. (enum spu_regnum): Add SPU_FPSCR_REGNUM, SPU_SRR0_REGNUM, SPU_LSLR_REGNUM, SPU_DECR_REGNUM, SPU_DECR_STATUS_REGNUM. * spu-tdep.c (infospucmdlist): New variable. (spu_register_name): Handle additional pseudo registers. (spu_register_type): Likewise. (spu_pseudo_register_read): Likewise. (spu_pseudo_register_write): Likewise. (spu_pseudo_register_read_spu): New function. (spu_pseudo_register_write_spu): Likewise. (info_spu_event_command): New function. (info_spu_signal_command): Likewise. (info_spu_mailbox_list): Likewise. (info_spu_mailbox_command): Likewise. (spu_mfc_get_bitfield): Likewise. (info_spu_dma_cmdlist): Likewise. (info_spu_dma_command): Likewise. (info_spu_proxydma_command): Likewise. (info_spu_command): Likewise. (_initialize_spu_tdep): Install "info spu" commands. testsuite/ChangeLog: * gdb.arch/spu-info.exp: New testcase. * gdb.arch/spu-info.c: New file. doc/ChangeLog: * gdb.texinfo (Architectures): Add new SPU section to document Cell Broadband Engine SPU architecture specific commands.
Diffstat (limited to 'gdb/testsuite/gdb.arch')
-rw-r--r--gdb/testsuite/gdb.arch/spu-info.c236
-rw-r--r--gdb/testsuite/gdb.arch/spu-info.exp243
2 files changed, 479 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.arch/spu-info.c b/gdb/testsuite/gdb.arch/spu-info.c
new file mode 100644
index 0000000..1fc83ec
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/spu-info.c
@@ -0,0 +1,236 @@
+/* Copyright 2007 Free Software Foundation, Inc.
+
+ 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.
+
+ This file is part of the gdb testsuite.
+
+ Contributed by Markus Deuling <deuling@de.ibm.com>.
+ Tests for 'info spu' commands. */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <spu_mfcio.h>
+
+
+/* PPE-assisted call interface. */
+void
+send_to_ppe (unsigned int signalcode, unsigned int opcode, void *data)
+{
+ __vector unsigned int stopfunc =
+ {
+ signalcode, /* stop */
+ (opcode << 24) | (unsigned int) data,
+ 0x4020007f, /* nop */
+ 0x35000000 /* bi $0 */
+ };
+
+ void (*f) (void) = (void *) &stopfunc;
+ asm ("sync");
+ f ();
+}
+
+/* PPE-assisted call to mmap from SPU. */
+unsigned long long
+mmap_ea (unsigned long long start, size_t length,
+ int prot, int flags, int fd, off_t offset)
+{
+ struct mmap_args
+ {
+ unsigned long long start __attribute__ ((aligned (16)));
+ size_t length __attribute__ ((aligned (16)));
+ int prot __attribute__ ((aligned (16)));
+ int flags __attribute__ ((aligned (16)));
+ int fd __attribute__ ((aligned (16)));
+ off_t offset __attribute__ ((aligned (16)));
+ } args;
+
+ args.start = start;
+ args.length = length;
+ args.prot = prot;
+ args.flags = flags;
+ args.fd = fd;
+ args.offset = offset;
+
+ send_to_ppe (0x2101, 11, &args);
+ return args.start;
+}
+
+/* This works only in a Linux environment with <= 1024 open
+ file descriptors for one process. Result is the file
+ descriptor for the current context if available. */
+int
+find_context_fd (void)
+{
+ int dir_fd = -1;
+ int i;
+
+ for (i = 0; i < 1024; i++)
+ {
+ struct stat stat;
+
+ if (fstat (i, &stat) < 0)
+ break;
+ if (S_ISDIR (stat.st_mode))
+ dir_fd = dir_fd == -1 ? i : -2;
+ }
+ return dir_fd < 0 ? -1 : dir_fd;
+}
+
+/* Open the context file and return the file handler. */
+int
+open_context_file (int context_fd, char *name, int flags)
+{
+ char buf[128];
+
+ if (context_fd < 0)
+ return -1;
+
+ sprintf (buf, "/proc/self/fd/%d/%s", context_fd, name);
+ return open (buf, flags);
+}
+
+
+int
+do_event_test ()
+{
+ spu_write_event_mask (MFC_MULTI_SRC_SYNC_EVENT); /* 0x1000 */ /* Marker Event */
+ spu_write_event_mask (MFC_PRIV_ATTN_EVENT); /* 0x0800 */
+ spu_write_event_mask (MFC_LLR_LOST_EVENT); /* 0x0400 */
+ spu_write_event_mask (MFC_SIGNAL_NOTIFY_1_EVENT); /* 0x0200 */
+ spu_write_event_mask (MFC_SIGNAL_NOTIFY_2_EVENT); /* 0x0100 */
+ spu_write_event_mask (MFC_OUT_MBOX_AVAILABLE_EVENT); /* 0x0080 */
+ spu_write_event_mask (MFC_OUT_INTR_MBOX_AVAILABLE_EVENT); /* 0x0040 */
+ spu_write_event_mask (MFC_DECREMENTER_EVENT); /* 0x0020 */
+ spu_write_event_mask (MFC_IN_MBOX_AVAILABLE_EVENT); /* 0x0010 */
+ spu_write_event_mask (MFC_COMMAND_QUEUE_AVAILABLE_EVENT); /* 0x0008 */
+ spu_write_event_mask (MFC_LIST_STALL_NOTIFY_EVENT); /* 0x0002 */
+ spu_write_event_mask (MFC_TAG_STATUS_UPDATE_EVENT); /* 0x0001 */
+
+ return 0;
+}
+
+int
+do_dma_test ()
+{
+ #define MAP_FAILED (-1ULL)
+ #define PROT_READ 0x1
+ #define MAP_PRIVATE 0x002
+ #define BSIZE 128
+ static char buf[BSIZE] __attribute__ ((aligned (128)));
+ char *file = "/var/tmp/tmp_buf";
+ struct stat fdstat;
+ int fd, cnt;
+ unsigned long long src;
+
+ /* Create a file and fill it with some bytes. */
+ fd = open (file, O_CREAT | O_RDWR | O_TRUNC, 0777);
+ if (fd == -1)
+ return -1;
+ memset ((void *)buf, '1', BSIZE);
+ write (fd, buf, BSIZE);
+ write (fd, buf, BSIZE);
+ memset ((void *)buf, 0, BSIZE);
+
+ if (fstat (fd, &fdstat) != 0
+ || !fdstat.st_size)
+ return -2;
+
+ src = mmap_ea(0ULL, fdstat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (src == MAP_FAILED)
+ return -3;
+
+ /* Copy some data via DMA. */
+ mfc_get (&buf, src, BSIZE, 5, 0, 0); /* Marker DMA */
+ mfc_write_tag_mask (1<<5); /* Marker DMAWait */
+ spu_mfcstat (MFC_TAG_UPDATE_ALL);
+
+ /* Close the file. */
+ close (fd);
+
+ return cnt;
+}
+
+int
+do_mailbox_test ()
+{
+ /* Write to SPU Outbound Mailbox. */
+ if (spu_stat_out_mbox ()) /* Marker Mbox */
+ spu_write_out_mbox (0x12345678);
+
+ /* Write to SPU Outbound Interrupt Mailbox. */
+ if (spu_stat_out_intr_mbox ())
+ spu_write_out_intr_mbox (0x12345678);
+
+ return 0; /* Marker MboxEnd */
+}
+
+int
+do_signal_test ()
+{
+ struct stat fdstat;
+ int context_fd = find_context_fd ();
+ int ret, buf, fd;
+
+ buf = 23; /* Marker Signal */
+ /* Write to signal1. */
+ fd = open_context_file (context_fd, "signal1", O_RDWR);
+ if (fstat (fd, &fdstat) != 0)
+ return -1;
+ ret = write (fd, buf, sizeof (int));
+ close (fd); /* Marker Signal1 */
+
+ /* Write to signal2. */
+ fd = open_context_file (context_fd, "signal2", O_RDWR);
+ if (fstat (fd, &fdstat) != 0)
+ return -1;
+ ret = write (fd, buf, sizeof (int));
+ close (fd); /* Marker Signal2 */
+
+ /* Read signal1. */
+ if (spu_stat_signal1 ())
+ ret = spu_read_signal1 ();
+
+ /* Read signal2. */
+ if (spu_stat_signal2 ())
+ ret = spu_read_signal2 (); /* Marker SignalRead */
+
+ return 0;
+}
+
+int
+main (unsigned long long speid, unsigned long long argp,
+ unsigned long long envp)
+{
+ int res;
+
+ /* info spu event */
+ res = do_event_test ();
+
+ /* info spu dma */
+ res = do_dma_test ();
+
+ /* info spu mailbox */
+ res = do_mailbox_test ();
+
+ /* info spu signal */
+ res = do_signal_test ();
+
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.arch/spu-info.exp b/gdb/testsuite/gdb.arch/spu-info.exp
new file mode 100644
index 0000000..61e997a
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/spu-info.exp
@@ -0,0 +1,243 @@
+# Copyright 2007 Free Software Foundation, Inc.
+#
+# 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.
+#
+# This file is part of the gdb testsuite.
+#
+# Contributed by Markus Deuling <deuling@de.ibm.com>.
+# Tests for 'info spu' commands.
+
+set prms_id 0
+set bug_id 0
+
+if { ![istarget "spu-*-elf"] } then {
+ verbose "Skipping SPU-only testcase"
+ return
+}
+
+set testfile "spu-info"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set sources ${srcdir}/${subdir}/${srcfile}
+
+if { [gdb_compile $sources ${binfile} executable { debug }] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Continue to MARKER
+proc c_to { marker } {
+ global srcfile
+ set line [gdb_get_line_number $marker]
+ gdb_test "break $line" \
+ "Breakpoint.*at.*file.*$srcfile.*line $line.*" \
+ "break $line"
+ gdb_test "continue" \
+ "Continuing.*Breakpoint.*at.*$srcfile.*$line.*" \
+ "continue to $line"
+}
+
+
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+# Check the help.
+gdb_test "info spu" \
+ ".*info spu.* must be followed by the name of an SPU facility.*" \
+ "info spu"
+gdb_test "help info spu" \
+ "Various SPU specific commands.*List of info spu subcommands.*" \
+ "help info spu"
+
+gdb_test "help info spu dma" \
+ "Display MFC DMA status." \
+ "help info spu dma"
+gdb_test "help info spu event" \
+ "Display SPU event facility status." \
+ "help info spu event"
+gdb_test "help info spu mailbox" \
+ "Display SPU mailbox facility status." \
+ "help info spu mailbox"
+gdb_test "help info spu proxydma" \
+ "Display MFC Proxy-DMA status." \
+ "help info spu proxydma"
+gdb_test "help info spu signal" \
+ "Display SPU signal notification facility status." \
+ "help info spu signal"
+
+
+# architecture should be spu:256K.
+gdb_test "show architecture" \
+ "The target architecture is set automatically.*currently spu:256K.*" \
+ "architecture = spu256K"
+
+# 'info spu event'.
+gdb_test "info spu event" \
+ "Event Status.*Event Mask.*" \
+ "info spu event"
+
+# 'info spu signal'.
+gdb_test "info spu signal" \
+ "Signal 1 not pending.*\(Type.*\).*Signal 2 not pending.*\(Type.*\).*" \
+ "info spu signal"
+
+# 'info spu mailbox'.
+gdb_test "info spu mailbox" \
+ "SPU Outbound Mailbox.*SPU Outbound Interrupt Mailbox.*" \
+ "info spu mailbox"
+
+# 'info spu dma'.
+gdb_test "info spu dma" \
+ "Tag-Group Status.*Tag-Group Mask.*Stall-and-Notify .*Atomic Cmd Status.*Opcode.*Tag.*TId.*RId.*EA.*LSA.*Size.*LstAddr.*LstSize.*E.*" \
+ "info spu dma"
+
+# 'info spu proxydma'.
+gdb_test "info spu proxydma" \
+ "Tag-Group Status.*Tag-Group Mask.*Opcode.*Tag.*TId.*RId.*EA.*LSA.*Size.*LstAddr.*LstSize.*E.*" \
+ "info spu proxydma"
+
+# Event tests.
+c_to "Marker Event"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000000.*" \
+ "empty event status"
+
+# MFC_MULTI_SRC_SYNC_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00001000.*" \
+ "event mask 0x1000"
+# MFC_PRIV_ATTN_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000800.*" \
+ "event mask 0x0800"
+# MFC_LLR_LOST_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000400.*" \
+ "event mask 0x0400"
+# MFC_SIGNAL_NOTIFY_1_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000200.*" \
+ "event mask 0x0200"
+# MFC_SIGNAL_NOTIFY_2_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000100.*" \
+ "event mask 0x0100"
+# MFC_OUT_MBOX_AVAILABLE_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000080.*" \
+ "event mask 0x0080"
+# MFC_OUT_INTR_MBOX_AVAILABLE_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000040.*" \
+ "event mask 0x0040"
+# MFC_DECREMENTER_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000020.*" \
+ "event mask 0x0020"
+# MFC_IN_MBOX_AVAILABLE_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000010.*" \
+ "event mask 0x0010"
+# MFC_COMMAND_QUEUE_AVAILABLE_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000008.*" \
+ "event mask 0x0008"
+# MFC_LIST_STALL_NOTIFY_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000002.*" \
+ "event mask 0x0002"
+# MFC_TAG_STATUS_UPDATE_EVENT.
+gdb_test "next" "" "next"
+gdb_test "info spu event" \
+ "Event Status 0x00000000.*Event Mask 0x00000001.*" \
+ "event mask 0x0001"
+
+
+# DMA tests.
+# 'info spu dma' should be empty.
+c_to "Marker DMA"
+gdb_test "info spu dma" \
+ "Tag-Group Status.*0x00000000.*Tag-Group Mask.*0x00000000.*Stall-and-Notify.*0x00000000.*Atomic Cmd Status.*0x00000000.*Opcode.*Tag.*TId.*RId.*EA.*LSA.*Size.*LstAddr.*LstSize.*E.*0.*0.*0.*0.*0x00000 0x00000.*" \
+ "info spu dma (empty)"
+
+# 'info spu dma' should be filled with some data.
+c_to "Marker DMAWait"
+gdb_test "next" "" "next"
+gdb_test "info spu dma" \
+ "Tag-Group Status.*0x00000000.*Tag-Group Mask.*0x00000020.*Stall-and-Notify.*0x00000000.*Atomic Cmd Status.*0x00000000.*Opcode.*Tag.*TId.*RId.*EA.*LSA.*Size.*LstAddr.*LstSize.*E.*getl.*putllc.*get.*mfcsync.*get.*0.*0.*0.*0.*0x00000 0x00000.*" \
+ "info spu dma (non-empty)"
+gdb_test "finish" "" "finish"
+
+# Mailbox Test
+# 'info spu mailbox' should be empty.
+c_to "Marker Mbox"
+gdb_test "info spu mailbox" \
+ "SPU Outbound Mailbox.*0xc0000000.*SPU Outbound Interrupt Mailbox.*0xc0000000.*" \
+ "info spu mailbox"
+
+# 'info spu mailbox' should now contain data.
+c_to "Marker MboxEnd"
+gdb_test "info spu mailbox" \
+ "SPU Outbound Mailbox.*0x12345678.*SPU Outbound Interrupt Mailbox.*0x12345678.*" \
+ "info spu mailbox"
+
+# Signal Test
+# 'info spu signal'.
+c_to "Marker Signal"
+gdb_test "info spu signal" \
+ "Signal 1 not pending.*\(Type.*\).*Signal 2 not pending.*\(Type.*\).*" \
+ "info spu signal"
+
+# 'info spu signal' with signal1 pending.
+c_to "Marker Signal1"
+gdb_test "info spu signal" \
+ "Signal 1 control word 0x801c0800.*Signal 2 not pending.*\(Type.*\).*" \
+ "info spu signal"
+
+# 'info spu signal' with signal1 and signal2 pending.
+c_to "Marker Signal2"
+gdb_test "info spu signal" \
+ "Signal 1 control word 0x801c0800.*Signal 2 control word 0x801c0800.*" \
+ "info spu signal"
+
+# Read signal1. Only signal2 is pending.
+c_to "Marker SignalRead"
+gdb_test "info spu signal" \
+ "Signal 1 not pending.*Signal 2 control word 0x801c0800.*" \
+ "info spu signal"
+
+
+gdb_exit
+
+return 0