diff --git a/nx/Makefile b/nx/Makefile index 2aed2ada..71ccaac2 100644 --- a/nx/Makefile +++ b/nx/Makefile @@ -24,7 +24,7 @@ VERSION := $(LIBNX_MAJOR).$(LIBNX_MINOR).$(LIBNX_PATCH) #--------------------------------------------------------------------------------- TARGET := nx #BUILD := build -SOURCES := source/system source/kernel source/services source/devices source/gfx +SOURCES := source/arm source/system source/kernel source/services source/gfx DATA := data INCLUDES := include diff --git a/nx/include/switch.h b/nx/include/switch.h index 8d485618..b1afb9f8 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -11,14 +11,15 @@ extern "C" { #include #include #include +#include #include -#include #include #include #include #include #include +#include #include #include @@ -30,8 +31,6 @@ extern "C" { #include #include -#include - #include #ifdef __cplusplus diff --git a/nx/include/switch/arm.h b/nx/include/switch/arm.h new file mode 100644 index 00000000..9a429fef --- /dev/null +++ b/nx/include/switch/arm.h @@ -0,0 +1,7 @@ +static inline void* armGetTls(void) { + void* ret; + __asm__ ("mrs %x[data], tpidrro_el0" : [data] "=r" (ret)); + return ret; +} + +void osDCacheFlush(void* addr, size_t size); diff --git a/nx/include/switch/kernel/version.h b/nx/include/switch/kernel/version.h new file mode 100644 index 00000000..a9844bc5 --- /dev/null +++ b/nx/include/switch/kernel/version.h @@ -0,0 +1,3 @@ +// Copyright 2017 plutoo +bool kernelAbove200(); +bool kernelAbove300(); diff --git a/nx/include/switch/os.h b/nx/include/switch/os.h deleted file mode 100644 index 2f6a8cc8..00000000 --- a/nx/include/switch/os.h +++ /dev/null @@ -1 +0,0 @@ -void osDCacheFlush(void* addr, size_t size); diff --git a/nx/include/switch/svc.h b/nx/include/switch/svc.h index d36f54dc..0206bad9 100644 --- a/nx/include/switch/svc.h +++ b/nx/include/switch/svc.h @@ -12,12 +12,6 @@ /// Pseudo handle for the current thread #define CUR_THREAD_HANDLE 0xFFFF8000 -static inline void* armGetTls(void) { - void* ret; - __asm__ ("mrs %x[data], tpidrro_el0" : [data] "=r" (ret)); - return ret; -} - typedef struct { u64 base_addr; u64 size; diff --git a/nx/source/kernel/cache.s b/nx/source/arm/cache.s similarity index 85% rename from nx/source/kernel/cache.s rename to nx/source/arm/cache.s index 816b921e..ca029b20 100644 --- a/nx/source/kernel/cache.s +++ b/nx/source/arm/cache.s @@ -11,7 +11,7 @@ .cfi_endproc .endm -CODE_BEGIN osDCacheFlush +CODE_BEGIN armDCacheFlush add x1, x1, x0 mrs x8, CTR_EL0 lsr x8, x8, #16 @@ -22,11 +22,11 @@ CODE_BEGIN osDCacheFlush bic x8, x0, x10 mov x10, x1 -osDCacheFlush_L0: +armDCacheFlush_L0: dc civac, x8 add x8, x8, x9 cmp x8, x10 - bcc osDCacheFlush_L0 + bcc armDCacheFlush_L0 dsb sy ret diff --git a/nx/source/devices/usb_dev.c b/nx/source/devices/usb_dev.c deleted file mode 100644 index 4d9351a2..00000000 --- a/nx/source/devices/usb_dev.c +++ /dev/null @@ -1,296 +0,0 @@ -#include -#include -#include - -//TODO: devoptab support - -static bool g_usbDevInitialized = false; - -static UsbDsInterface* interface = NULL; -static UsbDsEndpoint *g_usbDev_endpoint_in = NULL, *g_usbDev_endpoint_out = NULL; - -static u8 *g_usbDev_endpoint_in_buffer = NULL, *g_usbDev_endpoint_out_buffer = NULL; - -static Result _usbDevInit(void); - -static Result _usbDevWrite(const void* buffer, size_t size, size_t *transferredSize); - -Result usbDevInitialize(void) -{ - if (g_usbDevInitialized) return 0; - - Result ret=0; - - usbDsDeviceInfo deviceinfo = { - .idVendor = 0x0403, // "Future Technology Devices International, Ltd" - .idProduct = 0x6001, // "FT232 USB-Serial (UART) IC" - .bcdDevice = 0x0200, - .Manufacturer = "libnx", - .Product = "usbDev", - .SerialNumber = "1337", - }; - - ret = usbDsInitialize(USBCOMPLEXID_Default, &deviceinfo); - - if (R_SUCCEEDED(ret)) { - //The buffer for PostBufferAsync commands must be 0x1000-byte aligned. - g_usbDev_endpoint_in_buffer = memalign(0x1000, 0x1000); - if (g_usbDev_endpoint_in_buffer==NULL) ret = MAKERESULT(MODULE_LIBNX, LIBNX_OUTOFMEM); - - if (R_SUCCEEDED(ret)) { - g_usbDev_endpoint_out_buffer = memalign(0x1000, 0x1000); - if (g_usbDev_endpoint_out_buffer==NULL) ret = MAKERESULT(MODULE_LIBNX, LIBNX_OUTOFMEM); - } - - if (R_SUCCEEDED(ret)) { - memset(g_usbDev_endpoint_in_buffer, 0, 0x1000); - memset(g_usbDev_endpoint_out_buffer, 0, 0x1000); - ret = _usbDevInit(); - } - - if (R_FAILED(ret)) { - usbDsExit(); - - if (g_usbDev_endpoint_in_buffer) { - free(g_usbDev_endpoint_in_buffer); - g_usbDev_endpoint_in_buffer = NULL; - } - - if (g_usbDev_endpoint_out) { - free(g_usbDev_endpoint_out_buffer); - g_usbDev_endpoint_out_buffer = NULL; - } - } - } - - if (R_SUCCEEDED(ret)) g_usbDevInitialized=true; - - return ret; -} - -void usbDevExit(void) -{ - if (!g_usbDevInitialized) return; - - usbDsExit(); - - g_usbDevInitialized = false; - - g_usbDev_endpoint_in = NULL; - g_usbDev_endpoint_out = NULL; - - if (g_usbDev_endpoint_in_buffer) { - free(g_usbDev_endpoint_in_buffer); - g_usbDev_endpoint_in_buffer = NULL; - } - - if (g_usbDev_endpoint_out) { - free(g_usbDev_endpoint_out_buffer); - g_usbDev_endpoint_out_buffer = NULL; - } -} - -static Result _usbDevInit(void) -{ - Result ret=0; - size_t transferredSize=0; - - struct usb_interface_descriptor interface_descriptor = { - .bLength = USB_DT_INTERFACE_SIZE, - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = USBDS_DEFAULT_InterfaceNumber, - .bInterfaceClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceSubClass = USB_CLASS_VENDOR_SPEC, - .bInterfaceProtocol = USB_CLASS_VENDOR_SPEC, - }; - - struct usb_endpoint_descriptor endpoint_descriptor_in = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_ENDPOINT_IN, - .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 0x200, - }; - - struct usb_endpoint_descriptor endpoint_descriptor_out = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_ENDPOINT_OUT, - .bmAttributes = USB_TRANSFER_TYPE_BULK, - .wMaxPacketSize = 0x200, - }; - - //Setup interface. - ret = usbDsGetDsInterface(&interface, &interface_descriptor, "usb"); - if (R_FAILED(ret)) return ret; - - //Setup endpoints. - ret = usbDsInterface_GetDsEndpoint(interface, &g_usbDev_endpoint_in, &endpoint_descriptor_in);//device->host - if (R_FAILED(ret)) return ret; - - ret = usbDsInterface_GetDsEndpoint(interface, &g_usbDev_endpoint_out, &endpoint_descriptor_out);//host->device - if (R_FAILED(ret)) return ret; - - ret = usbDsInterface_EnableInterface(interface); - if (R_FAILED(ret)) return ret; - - //Host-side serial handling breaks with binary data without this. - ret = _usbDevWrite("\n", 1, &transferredSize); - if (R_SUCCEEDED(ret) && transferredSize!=1) ret = MAKERESULT(MODULE_LIBNX, LIBNX_IOERROR); - - return ret; -} - -static Result _usbDevRead(void* buffer, size_t size, size_t *transferredSize) -{ - Result ret=0; - u32 urbId=0; - u8 *bufptr = (u8*)buffer; - s32 tmpindex=0; - u32 chunksize=0; - u32 tmp_transferredSize = 0; - size_t total_transferredSize=0; - usbDsReportData reportdata; - - //Makes sure endpoints are ready for data-transfer / wait for init if needed. - ret = usbDsWaitReady(); - if (R_FAILED(ret)) return ret; - - while(size) - { - chunksize = 0x1000; - if (sizedevice transfer. - ret = usbDsEndpoint_PostBufferAsync(g_usbDev_endpoint_out, g_usbDev_endpoint_out_buffer, chunksize, &urbId); - if (R_FAILED(ret)) return ret; - - //Wait for the transfer to finish. - svcWaitSynchronization(&tmpindex, &g_usbDev_endpoint_out->CompletionEvent, 1, U64_MAX); - svcClearEvent(g_usbDev_endpoint_out->CompletionEvent); - - ret = usbDsEndpoint_GetReportData(g_usbDev_endpoint_out, &reportdata); - if (R_FAILED(ret)) return ret; - - ret = usbDsParseReportData(&reportdata, urbId, NULL, &tmp_transferredSize); - if (R_FAILED(ret)) return ret; - - if (tmp_transferredSize > chunksize) tmp_transferredSize = chunksize; - total_transferredSize+= (size_t)tmp_transferredSize; - - memcpy(bufptr, g_usbDev_endpoint_out_buffer, chunksize); - bufptr+= chunksize; - size-= chunksize; - - if(tmp_transferredSize < chunksize)break; - } - - if (transferredSize) *transferredSize = total_transferredSize; - - return ret; -} - -static Result _usbDevWrite(const void* buffer, size_t size, size_t *transferredSize) -{ - Result ret=0; - u32 urbId=0; - u32 chunksize=0; - u32 bufpos=0; - u32 transfer_size=0; - u32 total_chunks=0; - u32 last_chunksize=0; - u8 *bufptr = (u8*)buffer; - s32 tmpindex=0; - u32 tmp_transferredSize = 0; - u32 partial_transfer=0; - size_t total_transferredSize=0; - usbDsReportData reportdata; - - //Makes sure endpoints are ready for data-transfer / wait for init if needed. - ret = usbDsWaitReady(); - if (R_FAILED(ret)) return ret; - - while(size) - { - memset(g_usbDev_endpoint_in_buffer, 0, 0x1000); - transfer_size = 0; - total_chunks = 0; - - for(bufpos=0; bufpos<0x1000; bufpos+=0x200) - { - chunksize = 0x200; - if(sizehost transfer. - ret = usbDsEndpoint_PostBufferAsync(g_usbDev_endpoint_in, g_usbDev_endpoint_in_buffer, transfer_size, &urbId); - if(R_FAILED(ret))return ret; - - //Wait for the transfer to finish. - svcWaitSynchronization(&tmpindex, &g_usbDev_endpoint_in->CompletionEvent, 1, U64_MAX); - svcClearEvent(g_usbDev_endpoint_in->CompletionEvent); - - ret = usbDsEndpoint_GetReportData(g_usbDev_endpoint_in, &reportdata); - if (R_FAILED(ret)) return ret; - - ret = usbDsParseReportData(&reportdata, urbId, NULL, &tmp_transferredSize); - if (R_FAILED(ret)) return ret; - - if (tmp_transferredSize > transfer_size) tmp_transferredSize = transfer_size; - - partial_transfer = 0; - for(bufpos=0; bufpos + +bool kernelAbove200() { + u64 tmp; + return svcGetInfo(&tmp, 12, INVALID_HANDLE, 0) != 0xF001; +} + +bool kernelAbove300() { + u64 tmp; + return svcGetInfo(&tmp, 18, INVALID_HANDLE, 0) != 0xF001; +} diff --git a/nx/source/services/usb.c b/nx/source/services/usb.c index 82c30f1c..f4e1b62c 100644 --- a/nx/source/services/usb.c +++ b/nx/source/services/usb.c @@ -28,8 +28,11 @@ Result usbDsInitialize(usbComplexId complexId, const usbDsDeviceInfo* deviceinfo if (R_SUCCEEDED(rc))rc = _usbDsBindDevice(complexId); if (R_SUCCEEDED(rc))rc = _usbDsBindClientProcess(CUR_PROCESS_HANDLE); - if (R_SUCCEEDED(rc))rc = _usbDsGetEvent(g_usbDsServiceSession, &g_usbDsStateChangeEvent, 3);//GetStateChangeEvent - if (R_SUCCEEDED(rc))rc = _usbDsSetVidPidBcd(deviceinfo); + if (R_SUCCEEDED(rc))rc = _usbDsGetEvent(g_usbDsServiceSession, &g_usbDsStateChangeEvent, 3);// GetStateChangeEvent + + if (R_SUCCEEDED(rc) && kernelAbove200()) { + rc = _usbDsSetVidPidBcd(deviceinfo); + } if (R_FAILED(rc)) { if(g_usbDsStateChangeEvent) {