mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Moved cache.s to arm/, implemented kernel/version.c, get rid of broken uart driver [for now]
This commit is contained in:
parent
fd128b0ae2
commit
9a67c39fd0
@ -24,7 +24,7 @@ VERSION := $(LIBNX_MAJOR).$(LIBNX_MINOR).$(LIBNX_PATCH)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := nx
|
TARGET := nx
|
||||||
#BUILD := build
|
#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
|
DATA := data
|
||||||
INCLUDES := include
|
INCLUDES := include
|
||||||
|
@ -11,14 +11,15 @@ extern "C" {
|
|||||||
#include <switch/types.h>
|
#include <switch/types.h>
|
||||||
#include <switch/result.h>
|
#include <switch/result.h>
|
||||||
#include <switch/svc.h>
|
#include <switch/svc.h>
|
||||||
|
#include <switch/arm.h>
|
||||||
#include <switch/ipc.h>
|
#include <switch/ipc.h>
|
||||||
#include <switch/os.h>
|
|
||||||
|
|
||||||
#include <switch/kernel/tmem.h>
|
#include <switch/kernel/tmem.h>
|
||||||
#include <switch/kernel/shmem.h>
|
#include <switch/kernel/shmem.h>
|
||||||
#include <switch/kernel/mutex.h>
|
#include <switch/kernel/mutex.h>
|
||||||
#include <switch/kernel/thread.h>
|
#include <switch/kernel/thread.h>
|
||||||
#include <switch/kernel/virtmem.h>
|
#include <switch/kernel/virtmem.h>
|
||||||
|
#include <switch/kernel/version.h>
|
||||||
|
|
||||||
#include <switch/services/sm.h>
|
#include <switch/services/sm.h>
|
||||||
#include <switch/services/fs.h>
|
#include <switch/services/fs.h>
|
||||||
@ -30,8 +31,6 @@ extern "C" {
|
|||||||
#include <switch/services/hid.h>
|
#include <switch/services/hid.h>
|
||||||
#include <switch/services/vi.h>
|
#include <switch/services/vi.h>
|
||||||
|
|
||||||
#include <switch/devices/usb_dev.h>
|
|
||||||
|
|
||||||
#include <switch/gfx/gfx.h>
|
#include <switch/gfx/gfx.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
7
nx/include/switch/arm.h
Normal file
7
nx/include/switch/arm.h
Normal file
@ -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);
|
3
nx/include/switch/kernel/version.h
Normal file
3
nx/include/switch/kernel/version.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Copyright 2017 plutoo
|
||||||
|
bool kernelAbove200();
|
||||||
|
bool kernelAbove300();
|
@ -1 +0,0 @@
|
|||||||
void osDCacheFlush(void* addr, size_t size);
|
|
@ -12,12 +12,6 @@
|
|||||||
/// Pseudo handle for the current thread
|
/// Pseudo handle for the current thread
|
||||||
#define CUR_THREAD_HANDLE 0xFFFF8000
|
#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 {
|
typedef struct {
|
||||||
u64 base_addr;
|
u64 base_addr;
|
||||||
u64 size;
|
u64 size;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
.cfi_endproc
|
.cfi_endproc
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
CODE_BEGIN osDCacheFlush
|
CODE_BEGIN armDCacheFlush
|
||||||
add x1, x1, x0
|
add x1, x1, x0
|
||||||
mrs x8, CTR_EL0
|
mrs x8, CTR_EL0
|
||||||
lsr x8, x8, #16
|
lsr x8, x8, #16
|
||||||
@ -22,11 +22,11 @@ CODE_BEGIN osDCacheFlush
|
|||||||
bic x8, x0, x10
|
bic x8, x0, x10
|
||||||
mov x10, x1
|
mov x10, x1
|
||||||
|
|
||||||
osDCacheFlush_L0:
|
armDCacheFlush_L0:
|
||||||
dc civac, x8
|
dc civac, x8
|
||||||
add x8, x8, x9
|
add x8, x8, x9
|
||||||
cmp x8, x10
|
cmp x8, x10
|
||||||
bcc osDCacheFlush_L0
|
bcc armDCacheFlush_L0
|
||||||
|
|
||||||
dsb sy
|
dsb sy
|
||||||
ret
|
ret
|
@ -1,296 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <switch.h>
|
|
||||||
|
|
||||||
//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 (size<chunksize) chunksize = size;
|
|
||||||
|
|
||||||
//Start a host->device 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(size<chunksize)chunksize = size+2;
|
|
||||||
last_chunksize = chunksize;
|
|
||||||
|
|
||||||
g_usbDev_endpoint_in_buffer[bufpos+0] = 0x11;//2-byte header then the actual data.
|
|
||||||
g_usbDev_endpoint_in_buffer[bufpos+1] = 0x1;
|
|
||||||
memcpy(&g_usbDev_endpoint_in_buffer[bufpos+2], bufptr, chunksize-2);
|
|
||||||
|
|
||||||
size-= chunksize-2;
|
|
||||||
bufptr+= chunksize-2;
|
|
||||||
transfer_size+= chunksize;
|
|
||||||
total_chunks++;
|
|
||||||
|
|
||||||
if(size==0)break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Start a device->host 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<transfer_size; bufpos+=0x200)
|
|
||||||
{
|
|
||||||
if(tmp_transferredSize < bufpos+2) {
|
|
||||||
partial_transfer = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunksize = 0x200;
|
|
||||||
if(total_chunks==1)chunksize = last_chunksize;
|
|
||||||
total_chunks--;
|
|
||||||
|
|
||||||
if (tmp_transferredSize < bufpos+chunksize) {
|
|
||||||
total_transferredSize+= tmp_transferredSize - bufpos - 2;
|
|
||||||
partial_transfer = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_transferredSize+= chunksize-2;
|
|
||||||
}
|
|
||||||
if (partial_transfer) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (transferredSize) *transferredSize = total_transferredSize;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t usbDevRead(void* buffer, size_t size)
|
|
||||||
{
|
|
||||||
size_t transferredSize=0;
|
|
||||||
Result ret = _usbDevRead(buffer, size, &transferredSize);
|
|
||||||
if (R_FAILED(ret)) fatalSimple(ret);
|
|
||||||
return transferredSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t usbDevWrite(const void* buffer, size_t size)
|
|
||||||
{
|
|
||||||
size_t transferredSize=0;
|
|
||||||
Result ret = _usbDevWrite(buffer, size, &transferredSize);
|
|
||||||
if (R_FAILED(ret)) fatalSimple(ret);
|
|
||||||
return transferredSize;
|
|
||||||
}
|
|
||||||
|
|
12
nx/source/kernel/version.c
Normal file
12
nx/source/kernel/version.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2017 plutoo
|
||||||
|
#include <switch.h>
|
||||||
|
|
||||||
|
bool kernelAbove200() {
|
||||||
|
u64 tmp;
|
||||||
|
return svcGetInfo(&tmp, 12, INVALID_HANDLE, 0) != 0xF001;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool kernelAbove300() {
|
||||||
|
u64 tmp;
|
||||||
|
return svcGetInfo(&tmp, 18, INVALID_HANDLE, 0) != 0xF001;
|
||||||
|
}
|
@ -29,7 +29,10 @@ Result usbDsInitialize(usbComplexId complexId, const usbDsDeviceInfo* deviceinfo
|
|||||||
if (R_SUCCEEDED(rc))rc = _usbDsBindDevice(complexId);
|
if (R_SUCCEEDED(rc))rc = _usbDsBindDevice(complexId);
|
||||||
if (R_SUCCEEDED(rc))rc = _usbDsBindClientProcess(CUR_PROCESS_HANDLE);
|
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 = _usbDsGetEvent(g_usbDsServiceSession, &g_usbDsStateChangeEvent, 3);// GetStateChangeEvent
|
||||||
if (R_SUCCEEDED(rc))rc = _usbDsSetVidPidBcd(deviceinfo);
|
|
||||||
|
if (R_SUCCEEDED(rc) && kernelAbove200()) {
|
||||||
|
rc = _usbDsSetVidPidBcd(deviceinfo);
|
||||||
|
}
|
||||||
|
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
if(g_usbDsStateChangeEvent) {
|
if(g_usbDsStateChangeEvent) {
|
||||||
|
Loading…
Reference in New Issue
Block a user