Permalink
Browse files

Added a test for spu threads, with dma transfers.

  • Loading branch information...
zerkman committed Jan 4, 2011
1 parent c63ec1a commit 8925210bc6924c92b4a6e4f8eebcfe96276a78c5
View
@@ -0,0 +1,80 @@
+.SUFFIXES:
+ifeq ($(strip $(PSL1GHT)),)
+$(error "PSL1GHT must be set in the environment.")
+endif
+
+include $(PSL1GHT)/Makefile.base
+
+TARGET := $(notdir $(CURDIR))
+BUILD := build
+SOURCE := source
+INCLUDE := include
+DATA := data
+LIBS :=
+
+TITLE := Template - PSL1GHT
+APPID := TEST00003
+CONTENTID := UP0001-$(APPID)_00-0000000000000000
+
+CFLAGS += -g -O2 -Wall --std=gnu99
+CXXFLAGS += -g -O2 -Wall
+
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+
+export OUTPUT := $(CURDIR)/$(TARGET)
+export VPATH := $(foreach dir,$(SOURCE),$(CURDIR)/$(dir)) \
+ $(foreach dir,$(DATA),$(CURDIR)/$(dir))
+export BUILDDIR := $(CURDIR)/$(BUILD)
+export DEPSDIR := $(BUILDDIR)
+
+CFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.c)))
+CXXFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.S)))
+BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.bin))) \
+ spu.bin
+
+export OFILES := $(CFILES:.c=.o) \
+ $(CXXFILES:.cpp=.o) \
+ $(SFILES:.S=.o) \
+ $(BINFILES:.bin=.bin.o)
+
+export BINFILES := $(BINFILES:.bin=.bin.h)
+
+export INCLUDES := $(foreach dir,$(INCLUDE),-I$(CURDIR)/$(dir)) \
+ -I$(CURDIR)/$(BUILD)
+
+.PHONY: $(BUILD) clean pkg run
+
+$(BUILD):
+ @[ -d $@ ] || mkdir -p $@
+ @make --no-print-directory -C spu
+ @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+clean:
+ @make --no-print-directory -C spu clean
+ @echo Clean...
+ @rm -rf $(BUILD) $(OUTPUT).elf $(OUTPUT).self $(OUTPUT).a $(OUTPUT).pkg
+
+pkg: $(BUILD)
+ @echo Creating PKG...
+ @mkdir -p $(BUILD)/pkg
+ @mkdir -p $(BUILD)/pkg/USRDIR
+ @cp $(ICON0) $(BUILD)/pkg/
+ @$(FSELF) -n $(BUILD)/$(TARGET).elf $(BUILD)/pkg/USRDIR/EBOOT.BIN
+ @$(SFO) --title "$(TITLE)" --appid "$(APPID)" -f $(SFOXML) $(BUILD)/pkg/PARAM.SFO
+ @$(PKG) --contentid $(CONTENTID) $(BUILD)/pkg/ $(OUTPUT).pkg
+
+run: $(BUILD)
+ @$(PS3LOADAPP) $(OUTPUT).self
+
+else
+
+DEPENDS := $(OFILES:.o=.d)
+
+$(OUTPUT).self: $(OUTPUT).elf
+$(OUTPUT).elf: $(OFILES)
+$(OFILES): $(BINFILES)
+
+-include $(DEPENDS)
+
+endif
@@ -0,0 +1 @@
+spu.bin
@@ -0,0 +1,83 @@
+#include <psl1ght/lv2.h>
+#include <psl1ght/lv2/spu.h>
+#include <lv2/spu.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "spu.bin.h"
+
+#define ptr2ea(x) ((u64)(void *)(x))
+
+int main(int argc, const char* argv[])
+{
+ sysSpuImage image;
+ u32 entry = 0;
+ u32 segmentcount = 0;
+ sysSpuSegment* segments;
+ u32 thread_id;
+ u32 group_id;
+ Lv2SpuThreadAttributes attr = { ptr2ea("mythread"), 8+1, LV2_SPU_THREAD_ATTRIBUTE_NONE };
+ Lv2SpuThreadArguments arg = { 0, 0, 0, 0 };
+ vu32 ret;
+ u32 cause, status;
+ Lv2SpuThreadGroupAttributes grpattr = { 7+1, ptr2ea("mygroup"), 0, 0 };
+
+ char text[17] __attribute__((aligned(16))) = "abCdefGhIJklMnOP";
+
+ printf("Initializing 6 SPUs... ");
+ printf("%08x\n", lv2SpuInitialize(6, 0));
+
+ printf("Getting ELF information... ");
+ printf("%08x\n", sysSpuElfGetInformation(spu_bin, &entry, &segmentcount));
+ printf("\tEntry Point: %08x\n\tSegment Count: %08x\n", entry, segmentcount);
+
+ size_t segmentsize = sizeof(sysSpuSegment) * segmentcount;
+ segments = (sysSpuSegment*)malloc(segmentsize);
+ memset(segments, 0, segmentsize);
+
+ printf("Getting ELF segments... ");
+ printf("%08x\n", sysSpuElfGetSegments(spu_bin, segments, segmentcount));
+
+ printf("Loading ELF image... ");
+ printf("%08x\n", sysSpuImageImport(&image, spu_bin, 0));
+
+ /* Make up attributes */
+ /* attr.nameAddress = "mythread";
+ attr.nameSize = 8+1;
+ attr.attribute = LV2_SPU_THREAD_ATTRIBUTE_NONE; */
+
+ printf("Creating thread group... ");
+ printf("%08x\n", lv2SpuThreadGroupCreate(&group_id, 1, 100, &grpattr));
+
+ arg.argument1 = ptr2ea(text);
+ arg.argument2 = ptr2ea(&ret);
+ printf("ptrvl = %lu, value = %016lx\n", sizeof(char *), arg.argument1);
+
+ printf("input string = \"%s\"\n", text);
+
+ printf("Creating SPU thread... ");
+ printf("%08x\n", lv2SpuThreadInitialize(&thread_id, group_id, 0, &image, &attr, &arg));
+
+ printf("Starting SPU thread group... ");
+ printf("%08x\n", lv2SpuThreadGroupStart(group_id));
+
+ printf("Waiting for SPU to return...\n");
+ while (ret == 0);
+
+
+
+ printf("Terminating SPU thread group... ");
+ printf("%08x\n", lv2SpuThreadGroupTerminate(group_id, 42));
+
+ printf("Joining SPU thread group... ");
+ printf("%08x\n", lv2SpuThreadGroupJoin(group_id, &cause, &status));
+ printf("cause=%d status=%d\n", cause, status);
+
+ printf("Closing image... ");
+ printf("%08x\n", sysSpuImageClose(&image));
+
+ printf("output string = \"%s\"\n", text);
+ return 0;
+}
@@ -0,0 +1,70 @@
+.SUFFIXES:
+ifeq ($(strip $(PSL1GHT)),)
+$(error "PSL1GHT must be set in the environment.")
+endif
+
+include $(PSL1GHT)/Makefile.base
+
+TARGET := $(notdir $(CURDIR))
+BUILD := build
+SOURCE := source
+INCLUDE := include
+DATA := data
+LIBS :=
+
+CFLAGS := -g -O2 -Wall --std=gnu99
+CXXFLAGS := -g -O2 -Wall
+LDFLAGS :=
+
+PREFIX := spu-
+AR := $(PREFIX)ar
+AS := $(PREFIX)gcc
+CC := $(PREFIX)gcc
+CXX := $(PREFIX)g++
+LD := $(CC)
+
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+
+export OUTPUT := $(CURDIR)/$(TARGET)
+export VPATH := $(foreach dir,$(SOURCE),$(CURDIR)/$(dir)) \
+ $(foreach dir,$(DATA),$(CURDIR)/$(dir))
+export BUILDDIR := $(CURDIR)/$(BUILD)
+export DEPSDIR := $(BUILDDIR)
+
+CFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.c)))
+CXXFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.S)))
+BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.bin)))
+
+export OFILES := $(CFILES:.c=.o) \
+ $(CXXFILES:.cpp=.o) \
+ $(SFILES:.S=.o)
+
+export BINFILES := $(BINFILES:.bin=.bin.h)
+
+export INCLUDES := $(foreach dir,$(INCLUDE),-I$(CURDIR)/$(dir)) \
+ -I$(CURDIR)/$(BUILD)
+
+.PHONY: $(BUILD) clean
+
+$(BUILD):
+ @[ -d $@ ] || mkdir -p $@
+ @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+clean:
+ @echo Clean...
+ @rm -rf $(BUILD) $(OUTPUT).elf $(OUTPUT).a ../data/$(TARGET).bin
+
+else
+
+DEPENDS := $(OFILES:.o=.d)
+
+../../data/spu.bin: $(OUTPUT).elf
+ @cp $< $@
+
+$(OUTPUT).elf: $(OFILES)
+$(OFILES): $(BINFILES)
+
+-include $(DEPENDS)
+
+endif
@@ -0,0 +1,48 @@
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+
+int main(uint64_t ea, uint64_t outptr, uint64_t arg3, uint64_t arg4)
+{
+#if 0
+ /* memory-aligned buffer */
+ volatile vec_uchar16 tmp;
+ char *buf = (char *)&tmp;
+
+ /* fetch the 16 bytes using dma */
+ //mfc_get(buf, ea, 16, 0, 0, 0);
+
+ /* wait for dma transfer to be finished */
+ //mfc_write_tag_mask(1);
+ //spu_mfcstat(MFC_TAG_UPDATE_ALL);
+
+ /* fetch all 16 bytes into a character vector */
+ vec_uchar16 v = tmp;
+
+ /* compare all characters with the small 'a' caracter code */
+ vec_uchar16 cmp = spu_cmpgt(v, spu_splats((unsigned char)'a'));
+
+ /* for all small characters, we remove 0x20 to get the corresponding capital*/
+ vec_uchar16 sub = spu_splats((unsigned char)0x20) & cmp;
+ v = v - sub;
+
+ /* write the updated vector to memory */
+ *((vec_uchar16 *)buf) = v;
+
+ /* send the updated vector to ppe */
+ //mfc_put(buf, ea, 16, 0, 0, 0);
+
+ /* wait for dma transfer to be finished */
+ //mfc_write_tag_mask(1);
+ //spu_mfcstat(MFC_TAG_UPDATE_ALL);
+
+ /* send a message to inform the ppe program that the work is done */
+ //uint32_t ok = 1;
+ //mfc_put(&ok, outptr, 4, 0, 0, 0);
+
+ /* wait for dma transfer to be finished */
+ //mfc_write_tag_mask(1);
+ //spu_mfcstat(MFC_TAG_UPDATE_ALL);
+#endif
+
+ return 0;
+}

0 comments on commit 8925210

Please sign in to comment.