Implemented nvioctlNvmap_FromID() and nvioctlNvmap_GetID().

Added PARCEL_LOGGING define in parcel.c.
Fixed the 'code' value used in gfxproducerQueueBuffer().
Moved some gfxproducer init into nvgfx.
Moved some nvgfx event init into nvgfxEventInit().
Updated the code using gfxproducerBufferInit() for setting the nvmap-handles.
Disabled a nvQueryEvent() call which now fails.
Other changes.
The setup framebuf/windowbuf is now displayed.
This commit is contained in:
yellows8 2017-11-17 01:16:17 -05:00
parent 24fa9b0f4b
commit b577367011
7 changed files with 146 additions and 68 deletions

View File

@ -1,2 +1,3 @@
Result nvgfxInitialize(void);
void nvgfxExit(void);
Result nvgfxEventInit(void);

View File

@ -92,7 +92,9 @@ Result nvioctlNvhostAsGpu_GetVARegions(u32 fd, nvioctl_va_region regions[2]);
Result nvioctlNvhostAsGpu_InitializeEx(u32 fd, u32 big_page_size);
Result nvioctlNvmap_Create(u32 fd, u32 size, u32 *nvmap_handle);
Result nvioctlNvmap_FromID(u32 fd, u32 id, u32 *nvmap_handle);
Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32 align, u8 kind, void* addr);
Result nvioctlNvmap_GetID(u32 fd, u32 nvmap_handle, u32 *id);
Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd);
Result nvioctlChannel_SubmitGPFIFO(u32 fd, nvioctl_gpfifo_entry *entries, u32 num_entries, u32 flags, nvioctl_fence *fence_out);

View File

@ -24,38 +24,6 @@ static u32 g_gfxQueueBufferData[0x5c>>2] = {
0xffffffff, 0x0,
0xffffffff, 0x0, 0xffffffff, 0x0};
static u32 g_gfxBufferInitData[0x178>>2] = {
0x1, 0x16c, 0x0,
0x47424652,
1280, 720,
1280,
0x1, 0xb00, 0x2a, 0x0,
0x0, 0x51, 0xffffffff, 0xcb8,
0x0, 0xdaffcaff, 0x2a, 0x0,
0xb00, 0x1, 0x1, 1280,
0x3c0000, 0x1, 0x0, 1280,
720, 0x532120, 0x1, 0x3,
0x1400, 0xcb8,
0x0,
0xfe,
0x4, 0x0, 0x0, 0x0,
0x0, 0x3c0000, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0,
0x0, 0x0 //Unknown, some timestamp perhaps?
};
static Result _gfxGetNativeWindowID(u8 *buf, u64 size, s32 *out_ID) {
u32 *bufptr = (u32*)buf;
@ -94,9 +62,7 @@ static Result _gfxQueueBuffer(s32 buf) {
static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 LayerFlags, u64 LayerId, nvServiceType nv_servicetype, size_t nv_transfermem_size) {
Result rc=0;
s32 tmp=0;
u32 i=0;
u64 *ptr64 = (u64*)g_gfxBufferInitData;
if(g_gfxInitialized)return 0;
@ -124,23 +90,11 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
if (R_SUCCEEDED(rc)) rc = nvInitialize(nv_servicetype, nv_transfermem_size);
if (R_SUCCEEDED(rc)) rc = nvgfxInitialize();
if (R_SUCCEEDED(rc)) rc = gfxproducerInitialize(&g_gfxBinderSession);
if (R_SUCCEEDED(rc)) rc = gfxproducerConnect(2, 0);
if (R_SUCCEEDED(rc)) rc = gfxproducerQuery(2, &tmp);//"NATIVE_WINDOW_FORMAT"
if (R_SUCCEEDED(rc)) {
for(i=0; i<2; i++) {
g_gfxBufferInitData[0xa] = i;
g_gfxBufferInitData[0x21] = 0x3c0000*i;
ptr64[0x170>>3] = svcGetSystemTick();
rc = gfxproducerBufferInit(i, (u8*)g_gfxBufferInitData);
if (R_FAILED(rc)) break;
}
}
if (R_SUCCEEDED(rc)) rc = nvgfxInitialize();
if (R_SUCCEEDED(rc)) {
for(i=0; i<2; i++) {
@ -150,16 +104,20 @@ static Result _gfxInit(viServiceType servicetype, const char *DisplayName, u32 L
rc = gfxproducerRequestBuffer(i);//reply_parcel currently contains an error, presumably due to _gfxDequeueBuffer() failing as mentioned above.
if (R_FAILED(rc)) break;
//Officially, nvioctlNvmap_FromID() and nvioctlChannel_SubmitGPFIFO() are used here.
rc = _gfxQueueBuffer(i);//reply_parcel currently contains the same error as gfxproducerRequestBuffer() above.
if (R_FAILED(rc)) break;
}
}
if (R_SUCCEEDED(rc)) rc = nvgfxEventInit();
if (R_SUCCEEDED(rc)) rc = _gfxDequeueBuffer();
if (R_FAILED(rc)) {
gfxproducerExit();
nvgfxExit();
gfxproducerExit();
nvExit();
binderExitSession(&g_gfxBinderSession);
viCloseLayer(&g_gfxLayer);
@ -197,9 +155,10 @@ void gfxInitDefault(void) {
void gfxExit(void) {
if(!g_gfxInitialized)return;
nvgfxExit();
gfxproducerExit();
nvgfxExit();
nvExit();
binderExitSession(&g_gfxBinderSession);

View File

@ -94,7 +94,7 @@ Result gfxproducerQueueBuffer(s32 buf, u8 input[0x5c]) {
parcelWriteInt32(&parcel, buf);
parcelWriteData(&parcel, input, 0x5c);
rc = parcelTransact(g_gfxproducerBinderSession, DEQUEUE_BUFFER, &parcel, &parcel_reply);
rc = parcelTransact(g_gfxproducerBinderSession, QUEUE_BUFFER, &parcel, &parcel_reply);
if (R_FAILED(rc)) return rc;
//TODO: parse reply

View File

@ -37,6 +37,40 @@ static nvmapobj nvmap_objs[18];
static u64 nvmap_obj6_mapbuffer_xdb_offset;
static u32 g_gfxprod_BufferInitData[0x178>>2] = {
0x1, 0x16c, 0x0,
0x47424652,
1280, 720,
1280,
0x1, 0xb00, 0x2a, 0x0,
0x0, 0x51, 0xffffffff,
0x0, //nvmap handle
0x0, 0xdaffcaff, 0x2a, 0x0,
0xb00, 0x1, 0x1, 1280,
0x3c0000, 0x1, 0x0, 1280,
720, 0x532120, 0x1, 0x3,
0x1400,
0x0, //nvmap handle
0x0,
0xfe,
0x4, 0x0, 0x0, 0x0,
0x0, 0x3c0000, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0,
0x0, 0x0 //Unknown, some timestamp perhaps?
};
Result nvmapobjInitialize(nvmapobj *obj, size_t size) {
Result rc=0;
@ -83,7 +117,10 @@ Result nvmapobjSetup(nvmapobj *obj, u32 heapmask, u32 flags, u32 align, u8 kind)
Result nvgfxInitialize(void) {
Result rc=0;
u32 pos=0;
u32 pos=0, i=0;
s32 tmp=0;
u32 tmpval=0;
u64 *ptr64 = (u64*)g_gfxprod_BufferInitData;
if(g_nvgfxInitialized)return 0;
u32 zcullbind_data[4] = {0x58000, 0x5, 0x2, 0x0};
@ -151,7 +188,8 @@ Result nvgfxInitialize(void) {
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_ZCullGetCtxSize(g_nvgfx_fd_nvhostctrlgpu, &g_nvgfx_zcullctxsize);
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_ZCullGetInfo(g_nvgfx_fd_nvhostctrlgpu, g_nvgfx_zcullinfo);
if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrlgpu, 2, &g_nvgfx_nvhostctrlgpu_event2);
//Currently broken.
//if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrlgpu, 2, &g_nvgfx_nvhostctrlgpu_event2);
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvhostasgpu, "/dev/nvhost-as-gpu");
@ -242,7 +280,35 @@ Result nvgfxInitialize(void) {
rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 0x100, pos<3 ? 0xdb : 0x86, framebuf_nvmap_handle, 0, pos*0x3c0000, 0x3c0000, nvmap_obj6_mapbuffer_xdb_offset, NULL);
if (R_FAILED(rc)) break;
//Officially NVMAP_IOC_GET_ID, NVMAP_IOC_FROM_ID, NVMAP_IOC_GET_ID, and NVMAP_IOC_FROM_ID are used after the second *MapBufferEx.
if(pos==2) {
rc = gfxproducerQuery(2, &tmp);//"NATIVE_WINDOW_FORMAT"
if (R_FAILED(rc)) break;
for(i=0; i<2; i++) {
tmpval = 0;
rc = nvioctlNvmap_GetID(g_nvgfx_fd_nvmap, nvmap_objs[6].handle, &tmpval);
if (R_FAILED(rc)) break;
if(tmpval==~0) {
rc = 6;//official error
break;
}
rc = nvioctlNvmap_FromID(g_nvgfx_fd_nvmap, tmpval, &tmpval);
if (R_FAILED(rc)) break;
//The above gets a nvmap_handle, but normally it's the same value passed to nvioctlNvmap_GetID().
g_gfxprod_BufferInitData[0xa] = i;
g_gfxprod_BufferInitData[0xe] = tmpval;
g_gfxprod_BufferInitData[0x20] = tmpval;
g_gfxprod_BufferInitData[0x21] = 0x3c0000*i;
ptr64[0x170>>3] = svcGetSystemTick();
rc = gfxproducerBufferInit(i, (u8*)g_gfxprod_BufferInitData);
if (R_FAILED(rc)) break;
}
if (R_FAILED(rc)) break;
}
}
}
@ -290,17 +356,6 @@ Result nvgfxInitialize(void) {
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvhostctrl, "/dev/nvhost-ctrl");
if (R_SUCCEEDED(rc)) {
do {
rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, 0x42, 0x1ca7, 0x64, 0, &g_nvgfx_nvhostctrl_eventres);
} while(rc==5);//timeout error
}
//Currently broken.
//if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres, &g_nvgfx_nvhostctrl_eventhandle);
//if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrl_EventSignal(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres);
//if (R_SUCCEEDED(rc)) rc = -1;
if (R_FAILED(rc)) {
@ -382,3 +437,20 @@ void nvgfxExit(void) {
g_nvgfxInitialized = 0;
}
Result nvgfxEventInit(void) {
Result rc=0;
if (R_SUCCEEDED(rc)) {
do {
rc = nvioctlNvhostCtrl_EventWait(g_nvgfx_fd_nvhostctrl, 0x42, 0x1ca7, 0x64, 0, &g_nvgfx_nvhostctrl_eventres);
} while(rc==5);//timeout error
}
//Currently broken.
//if (R_SUCCEEDED(rc)) rc = nvQueryEvent(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres, &g_nvgfx_nvhostctrl_eventhandle);
//if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrl_EventSignal(g_nvgfx_fd_nvhostctrl, g_nvgfx_nvhostctrl_eventres);
return rc;
}

View File

@ -264,6 +264,25 @@ Result nvioctlNvmap_Create(u32 fd, u32 size, u32 *nvmap_handle) {
return rc;
}
Result nvioctlNvmap_FromID(u32 fd, u32 id, u32 *nvmap_handle) {
Result rc=0;
struct {
u32 id;//in
u32 handle;//out
} data;
memset(&data, 0, sizeof(data));
data.id = id;
rc = nvIoctl(fd, _IOWR(0x01, 0x03, data), &data);
if (R_FAILED(rc)) return rc;
*nvmap_handle = data.handle;
return rc;
}
Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32 align, u8 kind, void* addr) {
struct {
u32 handle;//in
@ -286,6 +305,25 @@ Result nvioctlNvmap_Alloc(u32 fd, u32 nvmap_handle, u32 heapmask, u32 flags, u32
return nvIoctl(fd, _IOWR(0x01, 0x04, data), &data);
}
Result nvioctlNvmap_GetID(u32 fd, u32 nvmap_handle, u32 *id) {
Result rc=0;
struct {
u32 id;//out
u32 handle;//in
} data;
memset(&data, 0, sizeof(data));
data.handle = nvmap_handle;
rc = nvIoctl(fd, _IOWR(0x01, 0x0E, data), &data);
if (R_FAILED(rc)) return rc;
*id = data.id;
return rc;
}
Result nvioctlChannel_SetNvmapFd(u32 fd, u32 nvmap_fd) {
struct {
u32 fd;//in

View File

@ -3,8 +3,12 @@
//This implements Android Parcel, hence names etc here are based on Android Parcel.cpp.
/*u8 parcel_reply_log[0x10000] = {0};
size_t parcel_reply_log_size = 0;*/
//#define PARCEL_LOGGING
#ifdef PARCEL_LOGGING
u8 parcel_reply_log[0x10000] = {0};
size_t parcel_reply_log_size = 0;
#endif
void parcelInitializeContext(parcelContext *ctx) {
memset(ctx, 0, sizeof(parcelContext));
@ -44,12 +48,14 @@ Result parcelTransact(binderSession *session, u32 code, parcelContext *in_parcel
memcpy(parcel_reply->ParcelData, &outparcel[outparcel32[1]], outparcel32[0]);
parcel_reply->ParcelData_size = outparcel32[0];
/*if(parcel_reply_log_size + sizeof(inparcel) + outparcel_size <= sizeof(parcel_reply_log)) {
#ifdef PARCEL_LOGGING
if(parcel_reply_log_size + sizeof(inparcel) + outparcel_size <= sizeof(parcel_reply_log)) {
memcpy(&parcel_reply_log[parcel_reply_log_size], inparcel, sizeof(inparcel));
parcel_reply_log_size+= sizeof(inparcel);
memcpy(&parcel_reply_log[parcel_reply_log_size], outparcel, outparcel_size);
parcel_reply_log_size+= outparcel_size;
}*/
}
#endif
return 0;
}