Merge pull request #164 from Lectem/dsp
IPC stuff and DSP service commands
This commit is contained in:
commit
c9ad04f70a
@ -6,6 +6,7 @@ extern "C" {
|
|||||||
|
|
||||||
//might be missing some
|
//might be missing some
|
||||||
#include <3ds/types.h>
|
#include <3ds/types.h>
|
||||||
|
#include <3ds/ipc.h>
|
||||||
#include <3ds/svc.h>
|
#include <3ds/svc.h>
|
||||||
#include <3ds/srv.h>
|
#include <3ds/srv.h>
|
||||||
#include <3ds/linear.h>
|
#include <3ds/linear.h>
|
||||||
@ -21,6 +22,7 @@ extern "C" {
|
|||||||
#include <3ds/services/cfgnor.h>
|
#include <3ds/services/cfgnor.h>
|
||||||
#include <3ds/services/cfgu.h>
|
#include <3ds/services/cfgu.h>
|
||||||
#include <3ds/services/csnd.h>
|
#include <3ds/services/csnd.h>
|
||||||
|
#include <3ds/services/dsp.h>
|
||||||
#include <3ds/services/fs.h>
|
#include <3ds/services/fs.h>
|
||||||
#include <3ds/services/gsp.h>
|
#include <3ds/services/gsp.h>
|
||||||
#include <3ds/services/hid.h>
|
#include <3ds/services/hid.h>
|
||||||
|
101
libctru/include/3ds/ipc.h
Normal file
101
libctru/include/3ds/ipc.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* @file ipc.h
|
||||||
|
* @brief Inter Process Communication helpers
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <3ds/types.h>
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
IPC_BUFFER_R = 0x2,
|
||||||
|
IPC_BUFFER_W = 0x4,
|
||||||
|
} IPC_BufferRights;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Command header to be used for IPC
|
||||||
|
* @param normal_params Number of normal parameters. Up to 63.
|
||||||
|
* @param translate_params Number of translate parameters. Up to 63.
|
||||||
|
*/
|
||||||
|
static inline u32 IPC_MakeHeader(u16 command_id, unsigned normal_params, unsigned translate_params)
|
||||||
|
{
|
||||||
|
return ((u32) command_id << 16) | (((u32) normal_params & 0x3F) << 6) | (((u32) translate_params & 0x3F) << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates the header to share handles
|
||||||
|
* @param number The number of handles following this header. Max 64.
|
||||||
|
*
|
||||||
|
* The #number next values are handles that will be shared between the two processes.
|
||||||
|
*
|
||||||
|
* @note Zero values will have no effect.
|
||||||
|
*/
|
||||||
|
static inline u32 IPC_Desc_SharedHandles(unsigned number)
|
||||||
|
{
|
||||||
|
return ((u32)(number - 1) << 26);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates the header to transfer handle ownership
|
||||||
|
* @param number The number of handles following this header. Max 64.
|
||||||
|
*
|
||||||
|
* The #number next values are handles that will be duplicated and closed by the other process.
|
||||||
|
*
|
||||||
|
* @note Zero values will have no effect.
|
||||||
|
*/
|
||||||
|
static inline u32 IPC_Desc_MoveHandles(unsigned number)
|
||||||
|
{
|
||||||
|
return ((u32)(number - 1) << 26) | 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Asks the kernel to fill the handle with the current process handle.
|
||||||
|
*
|
||||||
|
* The next value is a placeholder that will be replaced by the current process handle by the kernel.
|
||||||
|
*/
|
||||||
|
static inline u32 IPC_Desc_CurProcessHandle(void)
|
||||||
|
{
|
||||||
|
return 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a header describing a static buffer.
|
||||||
|
* @param size Size of the buffer. Max ?0x03FFFF?.
|
||||||
|
* @param buffer_id The Id of the buffer. Max 0xF.
|
||||||
|
*
|
||||||
|
* The next value is a pointer to the buffer. It will be copied to TLS offset 0x180 + static_buffer_id*8.
|
||||||
|
*/
|
||||||
|
static inline u32 IPC_Desc_StaticBuffer(size_t size, unsigned buffer_id)
|
||||||
|
{
|
||||||
|
return (size << 14) | ((buffer_id & 0xF) << 10) | 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a header describing a buffer to be sent over PXI.
|
||||||
|
* @param size Size of the buffer. Max 0x00FFFFFF.
|
||||||
|
* @param buffer_id The Id of the buffer. Max 0xF.
|
||||||
|
* @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have read-write access.
|
||||||
|
*
|
||||||
|
* The next value is a phys-address of a table located in the BASE memregion.
|
||||||
|
*/
|
||||||
|
static inline u32 IPC_Desc_PXIBuffer(size_t size, unsigned buffer_id,bool is_read_only)
|
||||||
|
{
|
||||||
|
u8 type = 0x4;
|
||||||
|
if(is_read_only)type = 0x6;
|
||||||
|
return (size << 8) | ((buffer_id & 0xF) << 4) | type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a header describing a buffer from the main memory.
|
||||||
|
* @param size Size of the buffer. Max 0x0FFFFFFF.
|
||||||
|
* @param rights The rights of the buffer for the destination process
|
||||||
|
*
|
||||||
|
* The next value is a pointer to the buffer.
|
||||||
|
*/
|
||||||
|
static inline u32 IPC_Desc_Buffer(size_t size, IPC_BufferRights rights)
|
||||||
|
{
|
||||||
|
return (size << 4) | 0x8 | rights;
|
||||||
|
}
|
137
libctru/include/3ds/services/dsp.h
Normal file
137
libctru/include/3ds/services/dsp.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* @file dsp.h
|
||||||
|
* @brief DSP Service to access the DSP processor commands (sound)
|
||||||
|
*
|
||||||
|
* The DSP has access to the Linear memory region, and to the DSP memory region if allowed in the exheader.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <3ds/types.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DSP_INTERRUPT_PIPE = 2
|
||||||
|
} DSP_InterruptType;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DSP_PIPE_INPUT = 0, ///< DSP to ARM
|
||||||
|
DSP_PIPE_OUTPUT = 1 ///< ARM to DSP
|
||||||
|
} DSP_PipeDirection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the dsp service.
|
||||||
|
*
|
||||||
|
* Call this before calling any DSP_* function.
|
||||||
|
* @note This will also unload any previously loaded DSP binary.
|
||||||
|
* It is done this way since you have to provide your binary when the 3DS leaves sleep mode anyway.
|
||||||
|
*/
|
||||||
|
Result dspInit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes the dsp service.
|
||||||
|
* @note This will also unload the DSP binary.
|
||||||
|
*/
|
||||||
|
Result dspExit(void);
|
||||||
|
|
||||||
|
///Checks if a headphone is inserted.
|
||||||
|
Result DSP_GetHeadphoneStatus(bool* is_inserted);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flushes the cache
|
||||||
|
* @param address Beginning of the memory range to flush, inside the Linear or DSP memory regions
|
||||||
|
* @param size Size of the memory range to flush
|
||||||
|
*
|
||||||
|
* Flushes the cache for the specified memory range and invalidates the cache
|
||||||
|
*/
|
||||||
|
Result DSP_FlushDataCache(u32 address, u32 size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Invalidates the cache
|
||||||
|
* @param address Beginning of the memory range to invalidate, inside the Linear or DSP memory regions
|
||||||
|
* @param size Size of the memory range to flush
|
||||||
|
*
|
||||||
|
* Invalidates the cache for the specified memory range
|
||||||
|
*/
|
||||||
|
Result DSP_InvalidateDataCache(u32 address, u32 size);
|
||||||
|
|
||||||
|
///Retrieves the handle of the DSP semaphore
|
||||||
|
Result DSP_GetSemaphoreHandle(Handle* semaphore);
|
||||||
|
|
||||||
|
///Sets the DSP hardware semaphore value
|
||||||
|
Result DSP_SetSemaphore(u16 value);
|
||||||
|
|
||||||
|
///Masks the DSP hardware semaphore value
|
||||||
|
Result DSP_SetSemaphoreMask(u16 mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads a DSP binary and starts the DSP
|
||||||
|
* @param component The program file address in memory
|
||||||
|
* @param size The size of the program
|
||||||
|
* @param prog_mask DSP memory block related ? Default is 0xff.
|
||||||
|
* @param data_mask DSP memory block related ? Default is 0xff.
|
||||||
|
* @param is_loaded Indicates if the DSP was succesfully loaded.
|
||||||
|
*
|
||||||
|
* @note The binary must be signed (http://3dbrew.org/wiki/DSP_Binary)
|
||||||
|
* @note Seems to be called when the 3ds leaves the Sleep mode
|
||||||
|
*/
|
||||||
|
Result DSP_LoadComponent(u8 const* component,u32 size,u16 prog_mask,u16 data_mask,bool * is_loaded);
|
||||||
|
|
||||||
|
///Stops the DSP by unloading the binary
|
||||||
|
Result DSP_UnloadComponent(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers an event handle with the DSP through IPC
|
||||||
|
* @param interrut The type of interrupt that will trigger the event. Usual value is DSP_INTERRUPT_PIPE.
|
||||||
|
* @param channel The pipe channel. Usual value is 2
|
||||||
|
*
|
||||||
|
* @note It is possible that interrupt are inverted
|
||||||
|
*/
|
||||||
|
Result DSP_RegisterInterruptEvents(Handle handle,u32 interrupt,u32 channel);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param channel ?????? TODO usually 2
|
||||||
|
* @param buffer The buffer that will store the values read from the pipe
|
||||||
|
* @param length Length of the buffer
|
||||||
|
* @param length_read Number of bytes read by the command
|
||||||
|
*/
|
||||||
|
Result DSP_ReadPipeIfPossible(u32 channel, u8 const *buffer, u16 length, u16* length_read);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param channel ?????? TODO usually 2
|
||||||
|
* @param buffer The message to send to the DSP process
|
||||||
|
* @param length Length of the message
|
||||||
|
*/
|
||||||
|
Result DSP_WriteProcessPipe(u32 channel,u8 const* buffer,u32 length);
|
||||||
|
|
||||||
|
|
||||||
|
///Converts a DSP memory to a virtual address usable by the process
|
||||||
|
Result DSP_ConvertProcessAddressFromDspDram(u32 dsp_address, u32 *arm_address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads a DSP register
|
||||||
|
* @param regNo Offset of the hardware register, base address is 0x1EC40000
|
||||||
|
*/
|
||||||
|
Result DSP_RecvData(u16 regNo, u16 * value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if you can read a DSP register
|
||||||
|
* @param regNo Offset of the hardware register, base address is 0x1EC40000
|
||||||
|
*
|
||||||
|
* @warning This call might hang if the data is not ready. See @ref DSP_SendDataIsEmpty.
|
||||||
|
*/
|
||||||
|
Result DSP_RecvDataIsReady(u16 regNo, bool * is_ready);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes to a DSP register
|
||||||
|
* @param regNo Offset of the hardware register, base address is 0x1EC40000
|
||||||
|
*
|
||||||
|
* @warning This call might hang if the SendData is not empty. See @ref DSP_SendDataIsEmpty.
|
||||||
|
*/
|
||||||
|
Result DSP_SendData(u16 regNo, u16 value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if you can write to a DSP register ?
|
||||||
|
* @param regNo Offset of the hardware register, base address is 0x1EC40000
|
||||||
|
*/
|
||||||
|
Result DSP_SendDataIsEmpty(u16 regNo, bool * is_empty);
|
@ -8,6 +8,9 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
|
||||||
|
/// Pseudo handle for the current process
|
||||||
|
#define CUR_PROCESS_HANDLE 0xFFFF8001
|
||||||
|
|
||||||
///@name Memory management
|
///@name Memory management
|
||||||
///@{
|
///@{
|
||||||
|
|
||||||
@ -89,6 +92,9 @@ typedef enum {
|
|||||||
THREADINFO_TYPE_UNKNOWN
|
THREADINFO_TYPE_UNKNOWN
|
||||||
} ThreadInfoType;
|
} ThreadInfoType;
|
||||||
|
|
||||||
|
/// Pseudo handle for the current thread
|
||||||
|
#define CUR_THREAD_HANDLE 0xFFFF8000
|
||||||
|
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
|
|
||||||
@ -227,6 +233,11 @@ static inline u32* getThreadCommandBuffer(void)
|
|||||||
return (u32*)((u8*)getThreadLocalStorage() + 0x80);
|
return (u32*)((u8*)getThreadLocalStorage() + 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32* getThreadStaticBuffers(void)
|
||||||
|
{
|
||||||
|
return (u32*)((u8*)getThreadLocalStorage() + 0x180);
|
||||||
|
}
|
||||||
|
|
||||||
///@name Memory management
|
///@name Memory management
|
||||||
///@{
|
///@{
|
||||||
|
|
||||||
|
254
libctru/source/services/dsp.c
Normal file
254
libctru/source/services/dsp.c
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
#include <3ds/types.h>
|
||||||
|
#include <3ds/svc.h>
|
||||||
|
#include <3ds/srv.h>
|
||||||
|
#include <3ds/ipc.h>
|
||||||
|
#include <3ds/services/dsp.h>
|
||||||
|
|
||||||
|
Handle dspHandle = 0;
|
||||||
|
|
||||||
|
|
||||||
|
Result dspInit(void)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
|
||||||
|
if (dspHandle == 0)
|
||||||
|
{
|
||||||
|
ret = srvGetServiceHandle(&dspHandle, "dsp::DSP");
|
||||||
|
if (ret < 0) return ret;
|
||||||
|
}
|
||||||
|
if (ret < 0) return ret;
|
||||||
|
DSP_UnloadComponent();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result dspExit(void)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
//No need to call unload, it will be done automatically by closing the handle
|
||||||
|
if (dspHandle != 0)
|
||||||
|
{
|
||||||
|
ret = svcCloseHandle(dspHandle);
|
||||||
|
if (ret < 0) return ret;
|
||||||
|
dspHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result DSP_GetHeadphoneStatus(bool* is_inserted)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x001F,0,0);
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
*is_inserted = cmdbuf[2] & 0xFF;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result DSP_FlushDataCache(u32 address, u32 size)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x13,2,2);
|
||||||
|
cmdbuf[1] = address;
|
||||||
|
cmdbuf[2] = size;
|
||||||
|
cmdbuf[3] = IPC_Desc_SharedHandles(1);
|
||||||
|
cmdbuf[4] = CUR_PROCESS_HANDLE;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result DSP_InvalidateDataCache(u32 address, u32 size)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x14,2,2);
|
||||||
|
cmdbuf[1] = address;
|
||||||
|
cmdbuf[2] = size;
|
||||||
|
cmdbuf[3] = IPC_Desc_SharedHandles(1);
|
||||||
|
cmdbuf[4] = CUR_PROCESS_HANDLE;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Result DSP_SetSemaphore(u16 value)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x7,1,0);
|
||||||
|
cmdbuf[1] = value;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Result DSP_SetSemaphoreMask(u16 mask)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x17,1,0);
|
||||||
|
cmdbuf[1] = mask;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DSP_GetSemaphoreHandle(Handle* semaphore)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x16,0,0);
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
*semaphore = cmdbuf[3];
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DSP_LoadComponent(u8 const* component,u32 size,u16 prog_mask,u16 data_mask,bool * is_loaded)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x11,3,2);
|
||||||
|
cmdbuf[1] = size;
|
||||||
|
cmdbuf[2] = prog_mask;
|
||||||
|
cmdbuf[3] = data_mask;
|
||||||
|
cmdbuf[4] = IPC_Desc_Buffer(size,IPC_BUFFER_R);
|
||||||
|
cmdbuf[5] = (u32) component;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
*is_loaded = cmdbuf[2] & 0xFF;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Result DSP_UnloadComponent(void)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x12,0,0);
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DSP_RegisterInterruptEvents(Handle handle, u32 interrupt, u32 channel)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x15,2,2);
|
||||||
|
cmdbuf[1] = interrupt;
|
||||||
|
cmdbuf[2] = channel;
|
||||||
|
cmdbuf[3] = IPC_Desc_SharedHandles(1);
|
||||||
|
cmdbuf[4] = handle;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result DSP_ReadPipeIfPossibleEx(u32 channel,u32 unk1, u8 const *buffer, u16 length, u16* length_read)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x10,3,0);
|
||||||
|
cmdbuf[1] = channel;
|
||||||
|
cmdbuf[2] = unk1;
|
||||||
|
cmdbuf[3] = length;
|
||||||
|
|
||||||
|
u32 * staticbufs = cmdbuf + 0x100;
|
||||||
|
|
||||||
|
u32 saved1 = staticbufs[0x0];
|
||||||
|
u32 saved2 = staticbufs[0x4];
|
||||||
|
|
||||||
|
staticbufs[0] = (length<<14) | 2;
|
||||||
|
staticbufs[4] = (u32)buffer;
|
||||||
|
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
|
||||||
|
staticbufs[0] = saved1;
|
||||||
|
staticbufs[4] = saved2;
|
||||||
|
|
||||||
|
*length_read = cmdbuf[2] & 0xFFFF;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO change DSP_ReadPipeIfPossibleEx into DSP_ReadPipeIfPossible once unk1 is figured out
|
||||||
|
//However it seems that it is always used with value 0
|
||||||
|
Result DSP_ReadPipeIfPossible(u32 channel, u8 const *buffer, u16 length, u16* length_read)
|
||||||
|
{
|
||||||
|
return DSP_ReadPipeIfPossibleEx(channel,0,buffer,length, length_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DSP_WriteProcessPipe(u32 channel, u8 const *buffer, u32 length)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0xd,2,2);
|
||||||
|
cmdbuf[1] = channel;
|
||||||
|
cmdbuf[2] = length;
|
||||||
|
cmdbuf[3] = IPC_Desc_StaticBuffer(length,1);
|
||||||
|
cmdbuf[4] = (u32) buffer;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DSP_ConvertProcessAddressFromDspDram(u32 dsp_address, u32 *arm_address)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0xc,1,0);
|
||||||
|
cmdbuf[1] = dsp_address;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
*arm_address = cmdbuf[2];
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DSP_RecvData(u16 regNo, u16 * value)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x1,1,0) ;
|
||||||
|
cmdbuf[1] = regNo;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
*value = cmdbuf[2] & 0xFFFF;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DSP_RecvDataIsReady(u16 regNo, bool * is_ready)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x2,1,0);
|
||||||
|
cmdbuf[1] = regNo;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
*is_ready = cmdbuf[2] & 0xFF;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Writes data to the reg regNo
|
||||||
|
// *(_WORD *)(8 * regNo + 0x1ED03024) = value
|
||||||
|
Result DSP_SendData(u16 regNo, u16 value)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x3,2,0);
|
||||||
|
cmdbuf[1] = regNo;
|
||||||
|
cmdbuf[1] = value;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DSP_SendDataIsEmpty(u16 regNo, bool * is_empty)
|
||||||
|
{
|
||||||
|
Result ret = 0;
|
||||||
|
u32* cmdbuf = getThreadCommandBuffer();
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x4,1,0);
|
||||||
|
cmdbuf[1] = regNo;
|
||||||
|
if ((ret = svcSendSyncRequest(dspHandle)) != 0) return ret;
|
||||||
|
*is_empty = cmdbuf[2] & 0xFF;
|
||||||
|
return cmdbuf[1];
|
||||||
|
}
|
||||||
|
|
@ -184,7 +184,7 @@ Result GSPGPU_FlushDataCache(const void* adr, u32 size)
|
|||||||
cmdbuf[1]=(u32)adr;
|
cmdbuf[1]=(u32)adr;
|
||||||
cmdbuf[2]=size;
|
cmdbuf[2]=size;
|
||||||
cmdbuf[3]=0x0;
|
cmdbuf[3]=0x0;
|
||||||
cmdbuf[4]=0xffff8001;
|
cmdbuf[4]=CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
Result ret=0;
|
Result ret=0;
|
||||||
if((ret=svcSendSyncRequest(gspGpuHandle)))return ret;
|
if((ret=svcSendSyncRequest(gspGpuHandle)))return ret;
|
||||||
@ -200,7 +200,7 @@ Result GSPGPU_InvalidateDataCache(const void* adr, u32 size)
|
|||||||
cmdbuf[1] = (u32)adr;
|
cmdbuf[1] = (u32)adr;
|
||||||
cmdbuf[2] = size;
|
cmdbuf[2] = size;
|
||||||
cmdbuf[3] = 0;
|
cmdbuf[3] = 0;
|
||||||
cmdbuf[4] = 0xFFFF8001;
|
cmdbuf[4] = CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
Result ret=0;
|
Result ret=0;
|
||||||
if((ret=svcSendSyncRequest(gspGpuHandle)))return ret;
|
if((ret=svcSendSyncRequest(gspGpuHandle)))return ret;
|
||||||
@ -265,7 +265,7 @@ Result GSPGPU_AcquireRight(u8 flags)
|
|||||||
cmdbuf[0]=0x160042; //request header code
|
cmdbuf[0]=0x160042; //request header code
|
||||||
cmdbuf[1]=flags;
|
cmdbuf[1]=flags;
|
||||||
cmdbuf[2]=0x0;
|
cmdbuf[2]=0x0;
|
||||||
cmdbuf[3]=0xffff8001;
|
cmdbuf[3]=CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
Result ret=0;
|
Result ret=0;
|
||||||
if((ret=svcSendSyncRequest(gspGpuHandle)))return ret;
|
if((ret=svcSendSyncRequest(gspGpuHandle)))return ret;
|
||||||
|
@ -23,7 +23,7 @@ Result HB_FlushInvalidateCache(void)
|
|||||||
cmdbuf[0] = 0x00010042;
|
cmdbuf[0] = 0x00010042;
|
||||||
cmdbuf[1] = 0x00000000;
|
cmdbuf[1] = 0x00000000;
|
||||||
cmdbuf[2] = 0x00000000;
|
cmdbuf[2] = 0x00000000;
|
||||||
cmdbuf[3] = 0xFFFF8001;
|
cmdbuf[3] = CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
if((ret = svcSendSyncRequest(hbHandle))!=0) return ret;
|
if((ret = svcSendSyncRequest(hbHandle))!=0) return ret;
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ Result mvdstdSetConfig(mvdstdConfig *config)
|
|||||||
cmdbuf[0] = 0x001E0044; //request header code
|
cmdbuf[0] = 0x001E0044; //request header code
|
||||||
cmdbuf[1] = sizeof(mvdstdConfig);
|
cmdbuf[1] = sizeof(mvdstdConfig);
|
||||||
cmdbuf[2] = 0;
|
cmdbuf[2] = 0;
|
||||||
cmdbuf[3] = 0xffff8001;
|
cmdbuf[3] = CUR_PROCESS_HANDLE;
|
||||||
cmdbuf[4] = (sizeof(mvdstdConfig)<<4) | 10;
|
cmdbuf[4] = (sizeof(mvdstdConfig)<<4) | 10;
|
||||||
cmdbuf[5] = (u32)config;
|
cmdbuf[5] = (u32)config;
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ Result mvdstdInit(mvdstdMode mode, mvdstdTypeInput input_type, mvdstdTypeOutput
|
|||||||
mvdstd_workbuf = linearAlloc(mvdstd_workbufsize);
|
mvdstd_workbuf = linearAlloc(mvdstd_workbufsize);
|
||||||
if(mvdstd_workbuf==NULL)return -1;
|
if(mvdstd_workbuf==NULL)return -1;
|
||||||
|
|
||||||
ret = mvdstdipc_Initialize((u32*)osConvertOldLINEARMemToNew((u32)mvdstd_workbuf), mvdstd_workbufsize, 0xffff8001);
|
ret = mvdstdipc_Initialize((u32*)osConvertOldLINEARMemToNew((u32)mvdstd_workbuf), mvdstd_workbufsize, CUR_PROCESS_HANDLE);
|
||||||
if(ret<0)
|
if(ret<0)
|
||||||
{
|
{
|
||||||
svcCloseHandle(mvdstdHandle);
|
svcCloseHandle(mvdstdHandle);
|
||||||
|
@ -130,7 +130,7 @@ Result Y2RU_SetSendingY(const void* src_buf, u32 image_size, s16 transfer_unit,
|
|||||||
cmdbuf[3] = transfer_unit;
|
cmdbuf[3] = transfer_unit;
|
||||||
cmdbuf[4] = transfer_gap;
|
cmdbuf[4] = transfer_gap;
|
||||||
cmdbuf[5] = 0;
|
cmdbuf[5] = 0;
|
||||||
cmdbuf[6] = 0xFFFF8001;
|
cmdbuf[6] = CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
||||||
return cmdbuf[1];
|
return cmdbuf[1];
|
||||||
@ -146,7 +146,7 @@ Result Y2RU_SetSendingU(const void* src_buf, u32 image_size, s16 transfer_unit,
|
|||||||
cmdbuf[3] = transfer_unit;
|
cmdbuf[3] = transfer_unit;
|
||||||
cmdbuf[4] = transfer_gap;
|
cmdbuf[4] = transfer_gap;
|
||||||
cmdbuf[5] = 0;
|
cmdbuf[5] = 0;
|
||||||
cmdbuf[6] = 0xFFFF8001;
|
cmdbuf[6] = CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
||||||
return cmdbuf[1];
|
return cmdbuf[1];
|
||||||
@ -162,7 +162,7 @@ Result Y2RU_SetSendingV(const void* src_buf, u32 image_size, s16 transfer_unit,
|
|||||||
cmdbuf[3] = transfer_unit;
|
cmdbuf[3] = transfer_unit;
|
||||||
cmdbuf[4] = transfer_gap;
|
cmdbuf[4] = transfer_gap;
|
||||||
cmdbuf[5] = 0;
|
cmdbuf[5] = 0;
|
||||||
cmdbuf[6] = 0xFFFF8001;
|
cmdbuf[6] = CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
||||||
return cmdbuf[1];
|
return cmdbuf[1];
|
||||||
@ -178,7 +178,7 @@ Result Y2RU_SetSendingYUYV(const void* src_buf, u32 image_size, s16 transfer_uni
|
|||||||
cmdbuf[3] = transfer_unit;
|
cmdbuf[3] = transfer_unit;
|
||||||
cmdbuf[4] = transfer_gap;
|
cmdbuf[4] = transfer_gap;
|
||||||
cmdbuf[5] = 0;
|
cmdbuf[5] = 0;
|
||||||
cmdbuf[6] = 0xFFFF8001;
|
cmdbuf[6] = CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
||||||
return cmdbuf[1];
|
return cmdbuf[1];
|
||||||
@ -238,7 +238,7 @@ Result Y2RU_SetReceiving(void* dst_buf, u32 image_size, s16 transfer_unit, s16 t
|
|||||||
cmdbuf[3] = transfer_unit;
|
cmdbuf[3] = transfer_unit;
|
||||||
cmdbuf[4] = transfer_gap;
|
cmdbuf[4] = transfer_gap;
|
||||||
cmdbuf[5] = 0;
|
cmdbuf[5] = 0;
|
||||||
cmdbuf[6] = 0xFFFF8001;
|
cmdbuf[6] = CUR_PROCESS_HANDLE;
|
||||||
|
|
||||||
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
if ((ret = svcSendSyncRequest(y2rHandle)) != 0) return ret;
|
||||||
return cmdbuf[1];
|
return cmdbuf[1];
|
||||||
|
Loading…
Reference in New Issue
Block a user