Permalink
Browse files

Merge branch 'master' of https://github.com/fgalea/PSL1GHT

  • Loading branch information...
2 parents a1e96b0 + 5c88330 commit 9a9f7c6d4d1ab5bb23ab9536f8ca03789f5940a3 root committed Jan 10, 2011
@@ -21,6 +21,13 @@ typedef struct {
u32 attribute;
} Lv2SpuThreadAttributes;
+typedef struct {
+ u32 nameSize;
+ u32 nameAddress;
+ u32 groupType;
+ u32 memContainer;
+} Lv2SpuThreadGroupAttributes;
+
LV2_SYSCALL lv2SpuInitialize(u32 spus, u32 rawspus) { return Lv2Syscall2(169, spus, rawspus); }
LV2_SYSCALL lv2SpuRawCreate(u32* spu, u32* attributes) { return Lv2Syscall2(160, (u64)spu, (u64)attributes); }
@@ -38,7 +45,7 @@ LV2_SYSCALL lv2SpuRawRecoverPageFault(u32 spu) { return Lv2Syscall1(199, spu); }
LV2_SYSCALL lv2SpuImageOpen(sysSpuImage* image, const char* path) { return Lv2Syscall2(156, (u64)image, (u64)path); }
LV2_SYSCALL lv2SpuImageOpenFd(sysSpuImage* image, Lv2FsFile fd, u64 offset) { return Lv2Syscall3(260, (u64)image, fd, offset); }
-LV2_SYSCALL lv2SpuThreadInitialize(u32* thread, u32* group, u32 spu, sysSpuImage* image, Lv2SpuThreadAttributes* attributes, Lv2SpuThreadArguments* arguments) { return Lv2Syscall6(172, (u64)thread, (u64)group, spu, (u64)image, (u64)attributes, (u64)arguments); }
+LV2_SYSCALL lv2SpuThreadInitialize(u32* thread, u32 group, u32 spu, sysSpuImage* image, Lv2SpuThreadAttributes* attributes, Lv2SpuThreadArguments* arguments) { return Lv2Syscall6(172, (u64)thread, (u64)group, spu, (u64)image, (u64)attributes, (u64)arguments); }
LV2_SYSCALL lv2SpuThreadSetArguments(u32 thread, Lv2SpuThreadArguments* arguments) { return Lv2Syscall2(166, thread, (u64)arguments); }
LV2_SYSCALL lv2SpuThreadGetExitStatus(u32 thread, int* status) { return Lv2Syscall2(165, thread, (u64)status); }
LV2_SYSCALL lv2SpuThreadConnectEvent(u32 thread, u32 queue, u32 type, u8 spup) { return Lv2Syscall4(191, thread, queue, type, spup); }
@@ -52,11 +59,29 @@ LV2_SYSCALL lv2SpuThreadGetConfiguration(u32 thread, u64* value) { return Lv2Sys
LV2_SYSCALL lv2SpuThreadWriteMb(u32 thread, u32 value) { return Lv2Syscall2(190, thread, value); }
LV2_SYSCALL lv2SpuThreadRecoverPageFault(u32 thread) { return Lv2Syscall1(198, thread); }
+LV2_SYSCALL lv2SpuThreadGroupCreate(u32* group, u32 num, u32 pri, Lv2SpuThreadGroupAttributes * attr) { return Lv2Syscall4(170, (u64)group, num, pri, (u64)attr); }
+LV2_SYSCALL lv2SpuThreadGroupDestroy(u32 group) { return Lv2Syscall1(171, group); }
+LV2_SYSCALL lv2SpuThreadGroupStart(u32 group) { return Lv2Syscall1(173, group); }
+LV2_SYSCALL lv2SpuThreadGroupSuspend(u32 group) { return Lv2Syscall1(174, group); }
+LV2_SYSCALL lv2SpuThreadGroupResume(u32 group) { return Lv2Syscall1(175, group); }
+LV2_SYSCALL lv2SpuThreadGroupYield(u32 group) { return Lv2Syscall1(176, group); }
+LV2_SYSCALL lv2SpuThreadGroupTerminate(u32 group, u32 value) { return Lv2Syscall2(177, group, value); }
+LV2_SYSCALL lv2SpuThreadGroupJoin(u32 gid, u32 *cause, u32 *status) { return Lv2Syscall3(178, gid, (u64) cause, (u64)status); }
+LV2_SYSCALL lv2SpuThreadGroupSetPriority(u32 group, u32 pri) { return Lv2Syscall2(179, group, pri); }
+LV2_SYSCALL lv2SpuThreadGroupGetPriority(u32 group, u32 *pri) { return Lv2Syscall2(180, group, (u64)pri); }
+LV2_SYSCALL lv2SpuThreadGroupConnectEvent(u32 group, u32 eq, u32 et) { return Lv2Syscall3(185, group, eq, et); }
+LV2_SYSCALL lv2SpuThreadGroupDisconnectEvent(u32 group, u32 et) { return Lv2Syscall2(186, group, et); }
+LV2_SYSCALL lv2SpuThreadGroupConnectEventAllThreads(u32 group, u32 eq, u64 req, u8 *spup) { return Lv2Syscall4(251, group, eq, req, (u64)spup); }
+LV2_SYSCALL lv2SpuThreadGroupDisconnectEventAllThreads(u32 group, u8 spup) { return Lv2Syscall2(252, group, spup); }
+
#define LV2_SPU_RAW_BASE 0xE0000000ULL
#define LV2_SPU_RAW_OFFSET 0x00100000ULL
#define LV2_SPU_RAW_LOCAL_OFFSET 0x00000000ULL
#define LV2_SPU_RAW_PROBLEM_OFFSET 0x00040000ULL
+#define LV2_SPU_THREAD_BASE 0xF0000000ULL
+#define LV2_SPU_THREAD_OFFSET 0x00100000ULL
+
// Problem State Registers
#define MFC_LSA 0x00003004
#define MFC_EAH 0x00003008
@@ -68,18 +93,22 @@ LV2_SYSCALL lv2SpuThreadRecoverPageFault(u32 thread) { return Lv2Syscall1(198, t
#define Prxy_QueryType 0x00003204
#define Prxy_QueryMask 0x0000321C
#define Prxy_TagStatus 0x0000322C
+#define SPU_Out_Intr_MBox 0x00004000
#define SPU_Out_MBox 0x00004004
#define SPU_In_MBox 0x0000400C
#define SPU_MBox_Status 0x00004014
#define SPU_RunCntl 0x0000401C
#define SPU_Status 0x00004024
#define SPU_NPC 0x00004034
+#define SPU_Sig_Notify_1 0x0001400C
+#define SPU_Sig_Notify_2 0x0001C00C
#define LV2_SPU_RAW_GET_BASE_OFFSET(spu) \
(LV2_SPU_RAW_BASE + LV2_SPU_RAW_OFFSET * (spu))
#define LV2_SPU_RAW_GET_PROBLEM_STORAGE(spu, reg) \
(vu32*)(LV2_SPU_RAW_GET_BASE_OFFSET(spu) + LV2_SPU_RAW_PROBLEM_OFFSET + reg)
+
static inline void lv2SpuRawWriteProblemStorage(u32 spu, u32 reg, u32 value) {
*LV2_SPU_RAW_GET_PROBLEM_STORAGE(spu, reg) = value;
}
@@ -97,3 +126,30 @@ static inline void lv2SpuRawWriteLocalStorage(u32 spu, u32 reg, u32 value) {
static inline u32 lv2SpuRawReadLocalStorage(u32 spu, u32 reg) {
return *LV2_SPU_RAW_GET_LOCAL_STORAGE(spu, reg);
}
+
+#define LV2_SPU_THREAD_GET_BASE_OFFSET(spu) \
+ (LV2_SPU_THREAD_BASE + LV2_SPU_THREAD_OFFSET * (spu))
+
+#define LV2_SPU_THREAD_GET_PROBLEM_STORAGE(spu, reg) \
+ (vu32*)(LV2_SPU_THREAD_GET_BASE_OFFSET(spu) + LV2_SPU_RAW_PROBLEM_OFFSET + reg)
+
+static inline void lv2SpuThreadWriteProblemStorage(u32 spu, u32 reg, u32 value) {
+ *LV2_SPU_THREAD_GET_PROBLEM_STORAGE(spu, reg) = value;
+}
+
+static inline u32 lv2SpuThreadReadProblemStorage(u32 spu, u32 reg) {
+ return *LV2_SPU_THREAD_GET_PROBLEM_STORAGE(spu, reg);
+}
+
+#define LV2_SPU_THREAD_GET_LOCAL_STORAGE(spu, reg) \
+ (vu32*)(LV2_SPU_THREAD_GET_BASE_OFFSET(spu) + LV2_SPU_RAW_LOCAL_OFFSET + reg)
+
+/*
+static inline void lv2SpuThreadWriteLocalStorage(u32 spu, u32 reg, u32 value) {
+ *LV2_SPU_THREAD_GET_LOCAL_STORAGE(spu, reg) = value;
+}
+
+static inline u32 lv2SpuThreadReadLocalStorage(u32 spu, u32 reg) {
+ return *LV2_SPU_THREAD_GET_LOCAL_STORAGE(spu, reg);
+}
+*/
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,73 @@
+#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 };
+ static vu32 ret __attribute__((aligned(16)));
+ u32 cause, status;
+ Lv2SpuThreadGroupAttributes grpattr = { 7+1, ptr2ea("mygroup"), 0, 0 };
+
+ static 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));
+
+ 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("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,44 @@
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+
+#define TAG 1
+
+extern void spu_thread_exit(uint32_t);
+
+/* wait for dma transfer to be finished */
+static void wait_for_completion(void) {
+ mfc_write_tag_mask(1<<TAG);
+ spu_mfcstat(MFC_TAG_UPDATE_ALL);
+}
+
+int main(uint64_t ea, uint64_t outptr, uint64_t arg3, uint64_t arg4)
+{
+ /* memory-aligned buffer (vectors always are properly aligned) */
+ volatile vec_uchar16 v;
+
+ /* fetch the 16 bytes using dma */
+ mfc_get(&v, ea, 16, TAG, 0, 0);
+ wait_for_completion();
+
+ /* compare all characters with the small 'a' character code */
+ vec_uchar16 cmp = spu_cmpgt(v, spu_splats((unsigned char)('a'-1)));
+
+ /* for all small characters, we remove 0x20 to get the corresponding capital*/
+ vec_uchar16 sub = spu_splats((unsigned char)0x20) & cmp;
+
+ /* convert all small characters to capitals */
+ v = v - sub;
+
+ /* send the updated vector to ppe */
+ mfc_put(&v, ea, 16, TAG, 0, 0);
+ wait_for_completion();
+
+ /* send a message to inform the ppe program that the work is done */
+ uint32_t ok __attribute__((aligned(16))) = 1;
+ mfc_put(&ok, outptr, 4, TAG, 0, 0);
+ wait_for_completion();
+
+ /* properly exit the thread */
+ spu_thread_exit(0);
+ return 0;
+}
@@ -0,0 +1,7 @@
+ .globl spu_thread_exit
+
+spu_thread_exit:
+ wrch $ch28,$3
+ stop 0x102
+ bi $0
+ lnop

0 comments on commit 9a9f7c6

Please sign in to comment.