diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2007-06-12 14:35:26 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2007-06-12 14:35:26 +0000 |
commit | 23d964e7b6625bec3822bcb9613f65362b9b3026 (patch) | |
tree | c9c8d4a9f98b11ad39dc14dddc8f41374747fc33 /gdb/testsuite/gdb.arch | |
parent | 374c1d382bcb2271b3a39ee369717f255ca0777a (diff) | |
download | gdb-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.c | 236 | ||||
-rw-r--r-- | gdb/testsuite/gdb.arch/spu-info.exp | 243 |
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 |