From 23d964e7b6625bec3822bcb9613f65362b9b3026 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 12 Jun 2007 14:35:26 +0000 Subject: * 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. --- gdb/testsuite/gdb.arch/spu-info.c | 236 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 gdb/testsuite/gdb.arch/spu-info.c (limited to 'gdb/testsuite/gdb.arch/spu-info.c') diff --git a/gdb/testsuite/gdb.arch/spu-info.c b/gdb/testsuite/gdb.arch/spu-info.c new file mode 100644 index 00000000000..1fc83ec076c --- /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 . + Tests for 'info spu' commands. */ + +#include +#include +#include +#include +#include +#include + + +/* 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; +} + -- cgit v1.2.1