diff --git a/AppMgr/AppMgr.odin b/AppMgr/AppMgr.odin index faf6cd2..8568bbb 100644 --- a/AppMgr/AppMgr.odin +++ b/AppMgr/AppMgr.odin @@ -4,6 +4,7 @@ import "core:c" import sce "../common" foreign import appmgr "system:SceAppMgr_stub" +foreign import appmgrkern "system:SceAppMgrForDriver_stub" foreign appmgr { /** @@ -194,8 +195,7 @@ foreign appmgr { * * @note SELF file must be located in app0: partition. */ - // TODO: no idea how argv is supposed to be changed to odin types. C type is `char *argv[]` - sceAppMgrLoadExec :: proc(appPath: cstring, argv: [][^]c.char, optParam: ^SceAppMgrExecOptParam) -> c.int --- + sceAppMgrLoadExec :: proc(appPath: cstring, argv: [^]cstring, optParam: ^SceAppMgrExecOptParam) -> c.int --- /** * Start an application by URI @@ -438,3 +438,27 @@ foreign appmgr { sceSharedFbEnd :: proc(fb_id: sce.UID) -> c.int --- sceSharedFbGetInfo :: proc(fb_id: sce.UID, info: ^SceSharedFbInfo) -> c.int --- } + +@(link_prefix = "ksceAppMgr") +foreign appmgrkern { + /** + * @brief Kill a process. + * @param[in] pid The process to kill. + * @return Zero on success, else < 0. + */ + KillProcess :: proc(pid: sce.UID) -> c.int --- + + /** + * @brief Launch an application for debugging + * + * @param[in] path Path to the executable to load + * @param[in] args Arguments to pass to the executable and to configure appmgr + * @param[in] arg_size The size of the args passed in + * @param[in] type Set to 0x80000000 for debugging launch + * @param[in] param pointer to launch params + * @param unk unknown, set to nullptr + * + * @return pid on success, else < 0. + */ + LaunchAppByPath :: proc(path: cstring, args: cstring, arg_size: sce.Size, type: c.uint, #by_ptr param: SceAppMgrLaunchParam, unk: rawptr) -> c.int --- +} diff --git a/AppMgr/types.odin b/AppMgr/types.odin index 0432eb8..19cf020 100644 --- a/AppMgr/types.odin +++ b/AppMgr/types.odin @@ -6,8 +6,7 @@ import apputil "../AppUtil" SCE_APPMGR_MAX_APP_NAME_LENGTH:: (31) -// TODO: should be c.int -SceAppMgrErrorCode :: enum i64 { +SceAppMgrErrorCode :: enum c.uint { BUSY = 0x80802000, //!< Busy STATE = 0x80802013, //!< Invalid state NULL_POINTER = 0x80802016, //!< NULL pointer @@ -168,4 +167,20 @@ SceSharedFbInfo :: struct { unk3: [3]c.int, } +SceAppMgrLaunchParam :: struct { + size: sce.Size, + unk_4: c.uint, // c.int --- + AvrcpSendButton :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + AvrcpSendVolume :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + AvrcpSetPlayStatus :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + AvrcpSetTitle :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + DeleteRegisteredInfo :: proc(mac0: c.uint, mac1: c.uint) -> c.int --- + FreqAudio :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + GetConfiguration :: proc() -> c.int --- // returns 0x0 BT disabled, 0x9 if enabled + GetConnectingInfo :: proc(mac0: c.uint, mac1: c.uint) -> c.int --- // 1 = disconnected?, 2 = connecting?, 5 = connected? + GetDeviceName :: proc(mac0: c.uint, mac1: c.uint, name: [0x79]c.char) -> c.int --- + GetInfoForTest :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + GetLastError :: proc() -> c.int --- + GetRegisteredInfo :: proc(device: c.int, unk: c.int, info: ^SceBtRegisteredInfo, info_size: sce.Size) -> c.int --- + GetStatusForTest :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + GetVidPid :: proc(mac0: c.uint, mac1: c.uint, vid_pid: [2]c.ushort) -> c.int --- + HfpGetCurrentPhoneNumber :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + HfpRequest :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + HidGetReportDescriptor :: proc(mac0: c.uint, mac1: c.uint, buffer: rawptr, size: sce.Size) -> c.int --- + HidTransfer :: proc(mac0: c.uint, mac1: c.uint, request: ^SceBtHidRequest) -> c.int --- + PushBip :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + PushOpp :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + ReadEvent :: proc(events: [^]SceBtEvent, num_events: c.int) -> c.int --- + RecvAudio :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + RecvBip :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + RecvOpp :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + RecvSpp :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + RegisterCallback :: proc(cb: sce.UID, unused: c.int, flags1: c.int, flags2: c.int) -> c.int --- // looks like flags1 is a mask for permitted MACs + ReplyPinCode :: proc(mac0: c.uint, mac1: c.uint, code: ^c.uchar, length: sce.Size) -> c.int --- + ReplyUserConfirmation :: proc(mac0: c.uint, mac1: c.uint, unk: c.int) -> c.int --- + SendAudio :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + SendL2capEchoRequestForTest :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + SendSpp :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + SetConfiguration :: proc(r0: c.int) -> c.int --- //0 = disable bt, 1 = enabling, 2 = enabled 3 = disabling? + SetContentProtection :: proc(r0: c.int) -> c.int --- + SetInquiryResultForTest :: proc(_: ^c.uchar) -> c.int --- + SetInquiryScan :: proc(r0: c.int) -> c.int --- + SetL2capEchoResponseBufferForTest :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + SetStatusForTest :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + StartAudio :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + StartConnect :: proc(mac0: c.uint, mac1: c.uint) -> c.int --- // mac0 can be used as a device index (already paired devices)? + StartDisconnect :: proc(mac0: c.uint, mac1: c.uint) -> c.int --- + StartInquiry :: proc() -> c.int --- + StopAudio :: proc(r0: c.int, r1: c.int, r2: c.int, r3: c.int) -> c.int --- + StopInquiry :: proc() -> c.int --- + UnregisterCallback :: proc(cb: sce.UID) -> c.int --- +} + diff --git a/Bt/types.odin b/Bt/types.odin new file mode 100644 index 0000000..3db0bca --- /dev/null +++ b/Bt/types.odin @@ -0,0 +1,286 @@ +package bt + +import "core:c" + +SceBtErrorCode :: enum c.uint { + REG_NOT_READY = 0x802F0101, + REG_DELETE_NO_ENTRY = 0x802F0102, + REG_UPDATE_CANNOT_SAVE = 0x802F0103, + REG_SET_HID_DESC_BAD_ARG = 0x802F0105, + REG_SET_HID_DESC_NO_REG = 0x802F0106, + REG_GET_HID_DESC_NO_REG = 0x802F0107, + REG_GET_HID_DESC_TOO_SHORT = 0x802F0108, + REG_DELETE_CONNECTING = 0x802F0109, + REG_CANNOT_LOAD = 0x802F010A, + REG_CANNOT_OPEN = 0x802F010B, + REG_CANNOT_READ = 0x802F010C, + REG_CANNOT_WRITE = 0x802F010D, + INQUIRY_START_BUSY = 0x802F0201, + CONNECT_START_NO_REG = 0x802F0202, + CONNECT_START_NOT_CONNECTABLE = 0x802F0203, + CONNECT_START_BUSY = 0x802F0204, + DISCONNECT_START_NOT_CONNECTED = 0x802F0205, + PIN_INVALID_LENGTH = 0x802F0206, + USER_CONFIRM_NOT_CONNECTED = 0x802F0207, + SDP_OPEN_NO_L2C = 0x802F0208, + CONNECT_START_REG_FULL = 0x802F0209, + CONNECT_START_CONNECTED = 0x802F020A, + CONNECT_START_TOO_MANY = 0x802F020D, + CONNECT_START_DELETING = 0x802F020E, + AVDTP_OPEN_NO_L2C = 0x802F0501, + AVDTP_CLOSE_BAD_SERV = 0x802F0502, + AVDTP_CLOSE_BAD_STATE = 0x802F0503, + AVDTP_START_BAD_SERV = 0x802F0504, + AVDTP_START_BAD_STATE = 0x802F0505, + AVDTP_STOP_BAD_SERV = 0x802F0506, + AVDTP_STOP_BAD_STATE = 0x802F0507, + AVDTP_SEND_BAD_STATE = 0x802F0508, + AVDTP_RECONF_BAD_SERV = 0x802F0509, + AVDTP_RECONF_BAD_STATE = 0x802F050A, + AVCTP_OPEN_NO_L2C = 0x802F0601, + AVCTP_SEND_NO_L2C = 0x802F0603, + AVCTP_NOT_CONNECTED = 0x802F0604, + AVCTP_SEND_BUSY = 0x802F0605, + AVCTP_SEND_NO_PRESS = 0x802F0606, + AVCTP_SEND_NO_RELEASE = 0x802F0607, + AVCTP_READ_NO_VOLUME = 0x802F0608, + AVCTP_SEND_NOT_RUBY = 0x802F0609, + HID_OPEN_NO_L2C = 0x802F0901, + HID_CLOSE_NO_L2C = 0x802F0902, + HID_SEND_NO_L2C = 0x802F0903, + HID_NOT_CONNECTED = 0x802F0904, + HID_NO_CAP = 0x802F0905, + HID_INVALID_REQUEST_TYPE = 0x802F0906, + HID_INVALID_BUFFER_ADDRESS = 0x802F0907, + HID_INVALID_PROTOCOL = 0x802F0908, + HID_INVALID_IDLE = 0x802F0909, + HID_NOT_YET = 0x802F090C, + HID_INVALID_LENGTH = 0x802F090D, + HID_INVALID_REPORT_ID = 0x802F090E, + HID_OVERWRITE_REQ = 0x802F090F, + JUMBO_UNLOCK_NOT_OWNER = 0x802F0B01, + HCI_TX_OVERFLOW = 0x802F0B02, + ACL_TX_BUF_OVERFLOW = 0x802F0B03, + ACL_TX_CB_OVERFLOW = 0x802F0B04, + TIMER_CANCEL_BAD_ID = 0x802F0B05, + TIMER_CANCEL_NOT_INITIALIZED = 0x802F0B06, + TIMER_SET_NOT_INITIALIZED = 0x802F0B07, + TIMER_SET_NO_SPACE = 0x802F0B08, + COPYIN_FAILED = 0x802F0B09, + COPYOUT_FAILED = 0x802F0B0A, + GET_NAME_NO_DEVICE = 0x802F0C01, + CB_TOO_MANY = 0x802F0C02, + CB_NOT_REGISTERED = 0x802F0C03, + CB_OVERFLOW = 0x802F0C04, + AUDIO_START_NOT_CONNECTED = 0x802F0D01, + AUDIO_START_NO_CAP = 0x802F0D02, + AUDIO_STOP_NOT_CONNECTED = 0x802F0D03, + AUDIO_STOP_NO_CAP = 0x802F0D04, + AUDIO_SEND_NOT_CONNECTED = 0x802F0D05, + AUDIO_SEND_NOT_STARTED = 0x802F0D06, + AUDIO_SEND_INVALID_LENGTH = 0x802F0D07, + AUDIO_RECV_NOT_CONNECTED = 0x802F0D08, + AUDIO_RECV_NOT_STARTED = 0x802F0D09, + AUDIO_RECV_INVALID_LENGTH = 0x802F0D0A, + AUDIO_START_INVALID_SERV = 0x802F0D0B, + AUDIO_STOP_INVALID_SERV = 0x802F0D0C, + AUDIO_START_SERV_FAILED = 0x802F0D0D, + AUDIO_STOP_SERV_FAILED = 0x802F0D0E, + AUDIO_FREQ_NOT_CONNECTED = 0x802F0D0F, + AUDIO_SEND_NO_CP = 0x802F0D10, + AUDIO_SEND_BAD_TYPE = 0x802F0D11, + AUDIO_RECV_BAD_TYPE = 0x802F0D12, + AUDIO_COMBI_NOT_FOUND = 0x802F0D16, + AUDIO_SEND_NO_L2C = 0x802F0D17, + AUDIO_INTERNAL_1 = 0x802F0D18, + AUDIO_SEND_BUSY = 0x802F0D19, + AUDIO_RECV_BUSY = 0x802F0D1A, + AUDIO_SEND_NO_CAP = 0x802F0D1B, + AUDIO_SEND_SERV_FAILED = 0x802F0D1C, + AUDIO_RECV_NO_CAP = 0x802F0D1D, + AUDIO_RECV_SERV_FAILED = 0x802F0D1E, + HID_RECV_NOT_CONNECTED = 0x802F0E01, + HID_RECV_INVALID_LENGTH = 0x802F0E02, + AVRCP_TOO_LONG_TITLE = 0x802F1201, + AVRCP_INVALID_PLAY_STATUS = 0x802F1202, + CONF_NOT_READY = 0x802F1501, + CONF_INVALID_VALUE = 0x802F1502, + CONF_BT_INACTIVE = 0x802F1503, + CONF_TIMEOUT = 0x802F1504, + CONF_CARD_NOT_FOUND = 0x802F1505, + CONF_FUNCTION_NOT_FOUND = 0x802F1506, + CONF_CANT_ENABLE_FUNCTION = 0x802F1507, + CONF_CANT_DISABLE_FUNCTION = 0x802F1508, + CONF_REGISTER_SUBINTR_HANDLER = 0x802F1509, + CONF_RELEASE_SUBINTR_HANDLER = 0x802F150A, + CONF_ENABLE_SUBINTR = 0x802F150B, + CONF_DISABLE_SUBINTR = 0x802F150C, + CONF_ON_TIMEOUT = 0x802F150D, + CONF_OFF_TIMEOUT = 0x802F150E, + CONF_SUSPEND_TIMEOUT = 0x802F150F, + CONF_CANT_ENTER = 0x802F1520, + NOTIMP = 0x802F2001, + KPROC_CREATE = 0x802F2002, + SDIO_GET_FUNCTION = 0x802F2003, + SDIO_REGISTER_INTR_HANDLER = 0x802F2004, + SDIO_UNREGISTER_INTR_HANDLER = 0x802F2005, + SDIO_LOCK = 0x802F2006, + SDIO_UNLOCK = 0x802F2007, + SDIO_ENABLE_FUNCTION = 0x802F2008, + SDIO_DISABLE_FUNCTION = 0x802F2009, + SDIO_SET_BLOCK_LEN = 0x802F200A, + SDIO_SET_BUS_SPEED = 0x802F200B, + SDIO_READ_DIR = 0x802F200C, + SDIO_WRITE_DIR = 0x802F200D, + SDIO_READ_FIX = 0x802F200E, + SDIO_WRITE_FIX = 0x802F200F, + TSLEEP = 0x802F2010, + GET_DEBUG_INFO_INVALID_REQUEST = 0x802F2101, + SET_DEBUG_INFO_INVALID_REQUEST = 0x802F2102, + GET_DEBUG_INFO_INVALID_SIZE = 0x802F2103, + SET_DEBUG_INFO_INVALID_SIZE = 0x802F2104, + GET_DEBUG_INFO_INVALID_ARGUMENT = 0x802F2105, + SET_DEBUG_INFO_INVALID_ARGUMENT = 0x802F2106, + GET_DEBUG_INFO_INVALID_STATE = 0x802F2107, + SET_DEBUG_INFO_INVALID_STATE = 0x802F2108, + GET_DEBUG_INFO_NOT_CONNECTED = 0x802F2109, + SET_DEBUG_INFO_NOT_CONNECTED = 0x802F210A, + PIN_IS_LE = 0x802F2201, + CONNECT_START_IS_LE = 0x802F2202, + AVCTP_IS_LE = 0x802F2203, + HID_IS_LE = 0x802F2204, + AUDIO_START_IS_LE = 0x802F2205, + AUDIO_STOP_IS_LE = 0x802F2206, + AUDIO_SEND_IS_LE = 0x802F2207, + AUDIO_RECV_IS_LE = 0x802F2208, + AUDIO_FREQ_IS_LE = 0x802F2209, + ATT_BASE = 0x802F2300, + ATT_INVALID_HANDLE = 0x802F2301, + ATT_READ_NOT_PERMITTED = 0x802F2302, + ATT_WRITE_NOT_PERMITTED = 0x802F2303, + ATT_INVALID_PDU = 0x802F2304, + ATT_INSUFFICIENT_AUTHENTICATION = 0x802F2305, + ATT_REQUEST_NOT_SUPPORTED = 0x802F2306, + ATT_INVALID_OFFSET = 0x802F2307, + ATT_INSUFFICIENT_AUTHORIZATION = 0x802F2308, + ATT_PEPARE_QUEUE_FULL = 0x802F2309, + ATT_ATTRIBUTE_NOT_FOUND = 0x802F230A, + ATT_ATTRIBUTE_NOT_LONG = 0x802F230B, + ATT_INSUFFICIENT_ENCRYPTION_KEY_SIZE = 0x802F230C, + ATT_INVALID_ATTRIBUTE_VALUE_LENGTH = 0x802F230D, + ATT_UNLIKELY_ERROR = 0x802F230E, + ATT_INSUFFICIENT_ENCRYPTION = 0x802F230F, + ATT_UNSUPPORTED_GROUP_TYPE = 0x802F2310, + ATT_INSUFFICIENT_RESOURCES = 0x802F2311, + ATT_APPLICATION_ERROR_LO = 0x802F2380, + ATT_APPLICATION_ERROR_HI = 0x802F23FF, + GATT_INVALID_NO = 0x802F2401, + GATT_NOT_CONNECTED = 0x802F2402, + GATT_BUSY = 0x802F2403, + GATT_INVALID_HANDLE = 0x802F2404, + GATT_INVALID_FLAGS = 0x802F2405, + GATT_INVALID_SIZE = 0x802F2406, + GATT_NOT_LE = 0x802F2407, + GATT_TOO_BIG_RECORD = 0x802F2408, + GATT_NOT_YET = 0x802F2409, + GATT_DISCONNECT = 0x802F240A, + GATT_TSLEEP = 0x802F240B, + GATT_ENTER = 0x802F240C, + GATT_TOO_BIG_BUFFER = 0x802F240D, + SM_INVALID_KEY_LENGTH = 0x802F2501, + SM_NOT_DIGIT = 0x802F2502, + SM_NO_REQ = 0x802F2503, + SM_NOT_NEEDED_PIN = 0x802F2504, + SM_INVALID_CONFIRM_REPLY = 0x802F2505, + LE_SET_ADVERTISING_INVALID_REQ = 0x802F2601, + LE_SET_ADVERTISING_INVALID_LENGTH = 0x802F2602, + LE_SET_ADVERTISING_INVALID_INTERVAL_MIN = 0x802F2603, + LE_SET_ADVERTISING_INVALID_INTERVAL_MAX = 0x802F2604, + LE_SET_ADVERTISING_INVALID_OWN_ADDRESS_TYPE = 0x802F2605, + LE_SET_ADVERTISING_INVALID_DIRECT_ADDRESS_TYPE = 0x802F2606, + LE_SET_ADVERTISING_INVALID_DIRECT_ADDRESS = 0x802F2607, + LE_SET_SCAN_INVALID_REQ = 0x802F2701, + LE_SET_SCAN_INVALID_LENGTH = 0x802F2702, + LE_SET_SCAN_INVALID_INTERVAL = 0x802F2703, + LE_SET_SCAN_INVALID_WINDOW = 0x802F2704, + LE_SET_SCAN_INVALID_OWN_ADDRESS_TYPE = 0x802F2705, + LE_GET_ADVERTISING_NOT_FOUND = 0x802F2801, + LE_CREATE_CONNECTION_INVALID_SCAN_INTERVAL = 0x802F2901, + LE_CREATE_CONNECTION_INVALID_SCAN_WINDOW = 0x802F2902, + LE_CREATE_CONNECTION_INVALID_PEER_ADDRESS = 0x802F2903, + LE_CREATE_CONNECTION_INVALID_OWN_ADDRESS_TYPE = 0x802F2904, + LE_CREATE_CONNECTION_INVALID_INTERVAL_MIN = 0x802F2905, + LE_CREATE_CONNECTION_INVALID_INTERVAL_MAX = 0x802F2906, + LE_CREATE_CONNECTION_INVALID_LATENCY = 0x802F2907, + LE_CREATE_CONNECTION_INVALID_TIMEOUT = 0x802F2908, + LE_CREATE_CONNECTION_REG_FULL = 0x802F2909, + LE_CREATE_CONNECTION_REG_ERROR = 0x802F290A, + LE_CREATE_CONNECTION_CONNECTED = 0x802F290B, + LE_CREATE_CONNECTION_FULL = 0x802F290C, + LE_CREATE_CONNECTION_BUSY = 0x802F290D, + ATT_READ_INVALID_NO = 0x802F2A01, + ATT_READ_INVALID_LENGTH = 0x802F2A02, + ATT_READ_INVALID_INTERNAL = 0x802F2A03, + ATT_WRITE_INVALID_NO = 0x802F2A04, + ATT_WRITE_INVALID_LENGTH = 0x802F2A05, + ATT_WRITE_INVALID_INTERNAL = 0x802F2A06, + ATT_NOT_YET = 0x802F2A07, + LE_NOT_SUPPORTED = 0x802F2B01, + PAIRING_OOB_TIMEOUT = 0x802F3101, + PAIRING_OOB_FULL = 0x802F3102, + PAIRING_OOB_CAN_NOT_DISCONNECT = 0x802F3103, + PAIRING_OOB_INTERNAL_ERROR = 0x802F3104, + NOT_READY = 0x802F3201, + GET_JACK_STATUS_NOT_CONNECTED = 0x802F3301, + TOO_MANY_CONNECTION = 0x802F3401, + TOO_MANY_HID = 0x802F3402, + NOT_SUPPORTED_DEVICE = 0x802F3403, + JEDI_VOLUME_GAIN_NOT_CONNECTED = 0x802F3501, + JEDI_SNIFF_NOT_CONNECTED = 0x802F3601, + JEDI_SNIFF_NOT_JEDI = 0x802F3602 +} + +SceBtRegisteredInfo :: struct { + mac: [6]c.uchar, + unk0: c.ushort, + bt_class: c.uint, + unk1: c.uint, + unk2: c.uint, + vid: c.ushort, + pid: c.ushort, + unk3: c.uint, + unk4: c.uint, + name: [128]c.char, + unk5: [0x60]c.uchar, +} +#assert(size_of(SceBtRegisteredInfo) == 0x100) + +SceBtEvent :: struct { + using _: struct #raw_union { + data: [0x10]c.uchar, + using _: struct { + id: c.uchar, + unk1: c.uchar, + unk2: c.ushort, + unk3: c.uint, + mac0: c.uint, + mac1: c.uint, + }, + }, +} +#assert(size_of(SceBtEvent) == 0x10) + +SceBtCallback :: #type ^proc "c" (r0: c.int, r1: c.int, r2: c.int, r3: c.int) + +SceBtHidRequest :: struct #packed { + unk00: c.uint32_t, + unk04: c.uint32_t, + type: c.uint8_t, //!< 0 = read?, 1 = write?, 2 = feature?, 3 = ? + unk09: c.uint8_t, + unk0A: c.uint8_t, + unk0B: c.uint8_t, + buffer: rawptr, + length: c.uint32_t, + next: ^SceBtHidRequest, +} + diff --git a/Camera/types.odin b/Camera/types.odin index 701832f..6b9b738 100644 --- a/Camera/types.odin +++ b/Camera/types.odin @@ -3,9 +3,8 @@ package camera import "core:c" import sce "../common" -// TODO: should be c.int /** Camera error codes. */ -SceCameraErrorCode :: enum i64 { +SceCameraErrorCode :: enum c.uint { PARAM = 0x802E0000, ALREADY_INIT = 0x802E0001, NOT_INIT = 0x802E0002, diff --git a/CommonDialog/types.odin b/CommonDialog/types.odin index ecf8773..d77f068 100644 --- a/CommonDialog/types.odin +++ b/CommonDialog/types.odin @@ -9,8 +9,7 @@ import scePspnet "../PspnetAdhoc" SCE_COMMON_DIALOG_MAGIC_NUMBER :: 0xC0D1A109 /* Errors */ -// TODO: should be c.int -SceCommonDialogErrorCode :: enum i64 { +SceCommonDialogErrorCode :: enum c.uint { BUSY = 0x80020401, NULL = 0x80020402, INVALID_ARGUMENT = 0x80020403, @@ -110,7 +109,6 @@ when size_of(rawptr) == 4 { } -// TODO: SceMsgDialogErrorCode :: enum c.uint { //! Illegal parameter SCE_MSG_DIALOG_ERROR_PARAM = 0x80100A01 @@ -260,8 +258,7 @@ SceMsgDialogResult :: struct { #assert(size_of(SceMsgDialogResult) == 0x2C) -// TODO: -SceNetCheckDialoErrorCode :: enum c.uint { +SceNetCheckDialogErrorCode :: enum c.uint { PARAM = 0x80100C01, INVALID_MODE = 0x80100C02, LACK_OF_LIBHTTP_POOL_SIZE = 0x80100C03, diff --git a/Coredump/Coredump.odin b/Coredump/Coredump.odin new file mode 100644 index 0000000..0c7527a --- /dev/null +++ b/Coredump/Coredump.odin @@ -0,0 +1,24 @@ +package coredump + +import "core:c" +import sce "../common" + +SceCoredumpTriggerParam :: struct { + size: sce.Size, + data_0x04: c.int, + data_0x08: c.int, + data_0x0C: c.int, + data_0x10: c.int, + titleid_len: sce.Size, + titleid: cstring, + app_name_len: sce.Size, + app_name: cstring, + data_0x24: c.int, // ex: 100. maybe progress max number. + data_0x28: c.int, + crash_thid: sce.UID, + data_0x30: c.int, +} + +SceKernelCoredumpStateUpdateCallback :: #type ^proc "c" (task_id: c.int, pid: sce.UID, progress: c.int) -> c.int +SceKernelCoredumpStateFinishCallback :: #type ^proc "c" (task_id: c.int, pid: sce.UID, result: c.int, path: cstring, path_len: sce.Size, unk: c.int) -> c.int + diff --git a/Ctrl/Ctrl.odin b/Ctrl/Ctrl.odin index af257e7..8983cc6 100644 --- a/Ctrl/Ctrl.odin +++ b/Ctrl/Ctrl.odin @@ -4,6 +4,7 @@ import "core:c" import sce "../common" foreign import ctrl "system:SceCtrl_stub" +foreign import ctrlkern "system:SceCtrlForDriver_stub" @(link_prefix = "sceCtrl") foreign ctrl { @@ -273,3 +274,208 @@ foreign ctrl { */ sceCtrlIsMultiControllerSupported :: proc() -> c.int --- } + +@(link_prefix = "ksceCtrl") +foreign ctrlkern { + /** + * Set the controller mode. + * + * @param[in] mode - One of ::SceCtrlPadInputMode. + * + * @return The previous mode, <0 on error. + */ + SetSamplingMode :: proc(mode: c.int) -> c.int --- + + /** + * Get the current controller mode. + * + * @param[out] pMode - Return value, see ::SceCtrlPadInputMode. + * + * @return The current mode, <0 on error. + */ + GetSamplingMode :: proc(pMode: ^c.int) -> c.int --- + + /** + * Get the controller state information (polling, positive logic). + * + * @param[in] port - use 0. + * @param[out] *pad_data - see ::SceCtrlData. + * @param[in] count - Buffers count. + * + * @return Buffers count, between 1 and 'count'. <0 on error. + */ + PeekBufferPositive :: proc(port: c.int, pad_data: ^SceCtrlData, count: c.int) -> c.int --- + + /** + * Get the controller state information (polling, negative logic). + * + * @param[in] port - use 0. + * @param[out] *pad_data - see ::SceCtrlData. + * @param[in] count - Buffers count. + * + * @return Buffers count, between 1 and 'count'. <0 on error. + */ + PeekBufferNegative :: proc(port: c.int, pad_data: ^SceCtrlData, count: c.int) -> c.int --- + + /** + * Get the controller state information (blocking, positive logic). + * + * @param[in] port - use 0. + * @param[out] *pad_data - see ::SceCtrlData. + * @param[in] count - Buffers count. + * + * @return Buffers count, between 1 and 'count'. <0 on error. + */ + ReadBufferPositive :: proc(port: c.int, pad_data: ^SceCtrlData, count: c.int) -> c.int --- + + /** + * Get the controller state information (blocking, negative logic). + * + * @param[in] port - use 0. + * @param[out] *pad_data - see ::SceCtrlData. + * @param[in] count - Buffers count. + * + * @return Buffers count, between 1 and 'count'. <0 on error. + */ + ReadBufferNegative :: proc(port: c.int, pad_data: ^SceCtrlData, count: c.int) -> c.int --- + + /** + * Set rules for button rapid fire + * + * @param[in] port - use 0. + * @param[in] idx - rule index between 0-15 + * @param[in] pRule - structure ::SceCtrlRapidFireRule. + * + * @return 0, <0 on error. + */ + SetRapidFire :: proc(port: c.int, idx: c.int, #by_ptr pRule: SceCtrlRapidFireRule) -> c.int --- + + /** + * Clear rules for button rapid fire + * + * @param[in] port - use 0. + * @param[in] idx - rule index between 0-15 + * + * @return 0, <0 on error. + */ + ClearRapidFire :: proc(port: c.int, idx: c.int) -> c.int --- + + /** + * Get controller port information. + * + * @param[out] info - see ::SceCtrlPortInfo + * @return 0, <0 on error + */ + GetControllerPortInfo :: proc(info: ^SceCtrlPortInfo) -> c.int --- + + /** + * Sets intercept + * + * If true, allows the current thread to intercept controls. The use case + * might be, for example, a game plugin that wishes to capture input without + * having the input sent to the game thread. + * @param[in] intercept Boolean value + * + * @return 0, < 0 on error + */ + SetButtonIntercept :: proc(intercept: c.int) -> c.int --- + + /** + * Gets intercept + * + * @param[out] intercept Boolean value + * + * @return 0, < 0 on error + */ + GetButtonIntercept :: proc(intercept: ^c.int) -> c.int --- + + /** + * Emulate buttons for the digital pad. + * @param port Use 0 + * @param slot The slot used to set the custom values. Between 0 - 3. If multiple slots are used, + * their settings are combined. + * @param userButtons Emulated user buttons of ::SceCtrlButtons. You cannot emulate kernel + * buttons and the emulated buttons will only be applied for applications + * running in user mode. + * @param kernelButtons Emulated buttons of ::SceCtrlButtons (you can emulate both user and + * kernel buttons). The emulated buttons will only be applied for applications + * running in kernel mode. + * @param uiMake Specifies the duration of the emulation. Measured in sampling counts. + * + * @return 0 on success. + */ + SetButtonEmulation :: proc(port: c.uint, slot: c.uchar, userButtons: c.uint, kernelButtons: c.uint, uiMake: c.uint) -> c.int --- + + /** + * Emulate values for the analog pad's X- and Y-axis. + * + * @param port Use 0 + * @param slot The slot used to set the custom values. Between 0 - 3. If multiple slots are used, + * their settings are combined. + * @param user_lX New emulated value for the left joystick's X-axis (userspace). Between 0 - 0xFF. + * @param user_lY New emulate value for the left joystick's Y-axis (userspace). Between 0 - 0xFF. + * @param user_rX New emulated value for the right joystick's X-axis (userspace). Between 0 - 0xFF. + * @param user_rY New emulate value for the right joystick's Y-axis (userspace). Between 0 - 0xFF. + * @param kernel_lX New emulated value for the left joystick's X-axis (kernelspace). Between 0 - 0xFF. + * @param kernel_lY New emulate value for the left joystick's Y-axis (kernelspace). Between 0 - 0xFF. + * @param kernel_rX New emulated value for the right joystick's X-axis (kernelspace). Between 0 - 0xFF. + * @param kernel_rY New emulate value for the right joystick's Y-axis (kernelspace). Between 0 - 0xFF. + * @param uiMake Specifies the duration of the emulation. Measured in sampling counts. + * + * @return 0 on success. + */ + SetAnalogEmulation :: proc(port: c.uint, slot: c.uchar, user_lX: c.uchar, user_lY: c.uchar, user_rX: c.uchar, user_rY: c.uchar, kernel_lX: c.uchar, kernel_lY: c.uchar, kernel_rX: c.uchar, kernel_rY: c.uchar, uiMake: c.uint) -> c.int --- + + /** + * Register virtual controller driver. + * + * This function always overwrites global settings and not exist unregister method. + * + * @param[in] driver - See ::SceCtrlVirtualControllerDriver + * + * @return 0 on success. <0 on error + */ + RegisterVirtualControllerDriver :: proc(driver: ^SceCtrlVirtualControllerDriver) -> c.int --- + + /** + * Update ctrl mask for non shell process + * + * @param[in] clear_mask - The SceCtrlButtons type value + * @param[in] set_mask - The SceCtrlButtons type value + * + * @return always 0. + * + * note - Some values cannot be clear/set. + */ + UpdateMaskForNonShell :: proc(clear_mask: c.int, set_mask: c.int) -> c.int --- + + /** + * Update ctrl mask for all process + * + * @param[in] clear_mask - The SceCtrlButtons type value + * @param[in] set_mask - The SceCtrlButtons type value + * + * @return always 0. + * + * note - Some values cannot be clear/set. + */ + UpdateMaskForAll :: proc(clear_mask: c.int, set_mask: c.int) -> c.int --- + + /** + * Get ctrl mask for non shell process + * + * @param[out] mask - The pointer of SceCtrlButtons type value output + * + * @return 0 on success. < 0 on error. + */ + GetMaskForNonShell :: proc(mask: ^c.uint32_t) -> c.int --- + + /** + * Get ctrl mask for all process + * + * @param[out] mask - The pointer of SceCtrlButtons type value output + * + * @return 0 on success. < 0 on error. + */ + GetMaskForAll :: proc(mask: ^c.uint32_t) -> c.int --- +} diff --git a/Ctrl/types.odin b/Ctrl/types.odin index 66a3c6f..1294512 100644 --- a/Ctrl/types.odin +++ b/Ctrl/types.odin @@ -1,9 +1,9 @@ package ctrl import "core:c" +import sce "../common" -// TODO: this should be a c.int -SceCtrlErrorCode :: enum i64 { +SceCtrlErrorCode :: enum c.uint { INVALID_ARG = 0x80340001, PRIV_REQUIRED = 0x80340002, NO_DEVICE = 0x80340020, @@ -132,3 +132,20 @@ SceCtrlPortInfo :: struct { } #assert(size_of(SceCtrlPortInfo) == 0x10) +/** Structure to pass as argument to ::ksceCtrlRegisterVirtualControllerDriver */ +SceCtrlVirtualControllerDriver :: struct { + readButtons: #type ^proc "c" (port: c.int, pad_data: ^SceCtrlData, count: c.int) -> c.int, + setActuator: #type ^proc "c" (port: c.int, #by_ptr pState: SceCtrlActuator) -> c.int, + getBatteryInfo: #type ^proc "c" (port: c.int, batt: ^sce.UInt8) -> c.int, + disconnect: #type ^proc "c" (port: c.int) -> c.int, + setTurnOffInterval: #type ^proc "c" (port: c.int) -> c.int, + getActiveControllerPort: #type ^proc "c" () -> c.int, + changePortAssign: #type ^proc "c" (port1: c.int, port2: c.int) -> c.int, + unk0: #type ^proc "c" () -> c.int, + getControllerPortInfo: #type ^proc "c" (info: ^SceCtrlPortInfo) -> c.int, + setLightBar: #type ^proc "c" (port: c.int, r: sce.UInt8, g: sce.UInt8, b: sce.UInt8) -> c.int, + resetLightBar: #type ^proc "c" (port: c.int) -> c.int, + unk1: #type ^proc "c" (port: c.int) -> c.int, + singleControllerMode: #type ^proc "c" (port: c.int) -> c.int, +} + diff --git a/Display/Display.odin b/Display/Display.odin index 54a0d57..5889e8d 100644 --- a/Display/Display.odin +++ b/Display/Display.odin @@ -4,6 +4,7 @@ import "core:c" import sce "../common" foreign import _display "system:SceDisplay_stub" +foreign import displaykern "system:SceDisplayForDriver_stub" @(link_prefix = "sceDisplay") foreign _display { @@ -131,3 +132,221 @@ foreign _display { */ UnregisterVblankStartCallback :: proc(uid: sce.UID) -> c.int --- } + +foreign displaykern { + /** + * Set/Update framebuffer parameters + * + * @param[in] pParam - Pointer to a ::SceDisplayFrameBuf structure. + * @param[in] sync - One of ::DisplaySetBufSync + * + * @return 0 on success, < 0 on error. + * @note - If NULL is provided as pParam pointer, output is blacked out. + */ + ksceDisplaySetFrameBuf :: proc(#by_ptr pParam: SceDisplayFrameBuf, sync: c.int) -> c.int --- + + /** + * Set/Update framebuffer parameters for display + * + * @param[in] head - Use 0 for OLED/LCD and 1 for HDMI + * @param[in] index - Can be 0 or 1 + * @param[in] pParam - Pointer to a ::SceDisplayFrameBuf structure. + * @param[in] sync - One of ::DisplaySetBufSync + * + * @return 0 on success, < 0 on error. + * @note - If NULL is provided as pParam pointer, output is blacked out. + */ + ksceDisplaySetFrameBufInternal :: proc(head: c.int, index: c.int, #by_ptr pParam: SceDisplayFrameBuf, sync: c.int) -> c.int --- + + /** + * Get current framebuffer parameters + * + * @param[out] pParam - Pointer to a ::SceDisplayFrameBuf structure + * which will receive framebuffer parameters. + * + * @param[in] sync - One of ::DisplaySetBufSync + * + * @return 0 on success, < 0 on error. + */ + ksceDisplayGetFrameBuf :: proc(pParam: ^SceDisplayFrameBuf, sync: c.int) -> c.int --- + + /** + * Get the configured framebuffer information of a head and its framebuffer index for a PID + * + * @param[in] pid - PID of the process to get the framebuffer information from. + * It can either be a vallid PID, -1 to use the current configured + * framebuffer for the head and index, or 0 to use the PID of the caller. + * @param[in] head - Use 0 for OLED/LCD and 1 for HDMI + * @param[in] index - Can be 0 or 1 + * @param[out] info - Pointer to a ::SceDisplayFrameBufInfo structure + * which will receive the framebuffer information. + * + * @return 0 on success, < 0 on error. + */ + ksceDisplayGetProcFrameBufInternal :: proc(pid: sce.UID, head: c.int, index: c.int, info: ^SceDisplayFrameBufInfo) -> c.int --- + + /** + * Get maximum framebuffer resolution + * + * @param[out] width - Maximum width + * @param[out] height - Maximum height + * + * @return 0 on success, < 0 on error. + */ + ksceDisplayGetMaximumFrameBufResolution :: proc(width: ^c.int, height: ^c.int) -> c.int --- + + /** + * Primary display index + */ + ksceDisplayGetPrimaryHead :: proc() -> c.int --- + + /** + * Number of vertical blank pulses up to now for a display + * + * @param[in] display - Display index + */ + ksceDisplayGetVcountInternal :: proc(display: c.int) -> c.int --- + + /** + * Wait for vertical blank start + */ + ksceDisplayWaitVblankStart :: proc() -> c.int --- + + /** + * Wait for vertical blank start for display + * + * @param[in] display - Display index + */ + ksceDisplayWaitVblankStartInternal :: proc(display: c.int) -> c.int --- + + /** + * Wait for vertical blank start with callback + */ + ksceDisplayWaitVblankStartCB :: proc() -> c.int --- + + /** + * Wait for vertical blank start with callback for display + * + * @param[in] display - Display index + */ + ksceDisplayWaitVblankStartCBInternal :: proc(display: c.int) -> c.int --- + + /** + * Wait for vertical blank start after specified number of vertical periods + * + * @param[in] vcount - Number of vertical periods before waiting for vertical blank start + */ + ksceDisplayWaitVblankStartMulti :: proc(vcount: c.uint) -> c.int --- + + /** + * Wait for vertical blank start after specified number of vertical periods for display + * + * @param[in] display - Display index + * @param[in] vcount - Number of vertical periods before waiting for vertical blank start + */ + ksceDisplayWaitVblankStartMultiInternal :: proc(display: c.int, vcount: c.uint) -> c.int --- + + /** + * Wait for vertical blank start with callback after specified number of vertical periods + * + * @param[in] vcount - Number of vertical periods before waiting for vertical blank start + */ + ksceDisplayWaitVblankStartMultiCB :: proc(vcount: c.uint) -> c.int --- + + /** + * Wait for vertical blank start with callback after specified number of vertical periods for display + * + * @param[in] display - Display index + * @param[in] vcount - Number of vertical periods before waiting for vertical blank start + */ + ksceDisplayWaitVblankStartMultiCBInternal :: proc(display: c.int, vcount: c.uint) -> c.int --- + + /** + * Wait for vertical blank start since last update of framebuffer + */ + ksceDisplayWaitSetFrameBuf :: proc() -> c.int --- + + /** + * Wait for vertical blank start with callback since last update of framebuffer + */ + ksceDisplayWaitSetFrameBufCB :: proc() -> c.int --- + + /** + * Wait for vertical blank start after specified number of vertical periods + * since last update of framebuffer. + * + * @param[in] vcount - Number of vertical periods before waiting for vertical blank start + */ + ksceDisplayWaitSetFrameBufMulti :: proc(vcount: c.uint) -> c.int --- + + /** + * Wait for vertical blank start with callback after specified number of vertical periods + * since last update of framebuffer. + * + * @param[in] vcount - Number of vertical periods before waiting for vertical blank start + */ + ksceDisplayWaitSetFrameBufMultiCB :: proc(vcount: c.uint) -> c.int --- + + /** + * Register callback to be used at each vertical blank start + * + * @param[in] uid - Callback UID + */ + ksceDisplayRegisterVblankStartCallback :: proc(uid: sce.UID) -> c.int --- + + /** + * Register callback to be used at each vertical blank start for a display + * + * @param[in] display - Display index + * @param[in] uid - Callback UID + */ + ksceDisplayRegisterVblankStartCallbackInternal :: proc(display: c.int, uid: sce.UID) -> c.int --- + + /** + * Unregister callback used at each vertical blank start + * + * @param[in] uid - Callback UID + */ + ksceDisplayUnregisterVblankStartCallback :: proc(uid: sce.UID) -> c.int --- + + /** + * Unregister callback used at each vertical blank start for a display + * + * @param[in] display - Display index + * @param[in] uid - Callback UID + */ + ksceDisplayUnregisterVblankStartCallbackInternal :: proc(display: c.int, uid: sce.UID) -> c.int --- + + /** + * Register callback to be used when the framebuffer changes + * + * @param[in] uid - Callback UID + */ + ksceDisplayRegisterFrameBufCallback :: proc(uid: sce.UID) -> c.int --- + + /** + * Register callback to be used when the framebuffer changes for a display + * + * @param[in] display - Display index + * @param[in] uid - Callback UID + */ + ksceDisplayRegisterFrameBufCallbackInternal :: proc(display: c.int, uid: sce.UID) -> c.int --- + + /** + * Enable/disable color inversion for a display. + * + * @param[in] display - Display index + * @param[in] enable - Enable/disable color inversion + */ + ksceDisplaySetInvertColors :: proc(display: c.int, enable: c.int) -> c.int --- + + /** + * Set display plane owner + * + * @param[in] head - Use 0 for OLED/LCD and 1 for HDMI + * @param[in] index - Can be 0 or 1 + * @param[in] pid - PID of the new owner + * + * @return 0 on success, < 0 on error. + */ +} diff --git a/Display/types.odin b/Display/types.odin index 163011e..f3a1862 100644 --- a/Display/types.odin +++ b/Display/types.odin @@ -3,7 +3,6 @@ package display import "core:c" import sce "../common" -// TODO: should be c.int SceDisplayErrorCode :: enum c.uint { OK = 0, INVALID_HEAD = 0x80290000, @@ -54,3 +53,15 @@ when size_of(rawptr) == 4 { #assert(size_of(SceDisplayFrameBuf) == 0x18) } +/** + * Extended framebuffer information +*/ +SceDisplayFrameBufInfo :: struct { + size: sce.Size, //!< sizeof(SceDisplayFrameBufInfo) + pid: sce.UID, //!< PID of the process owning this framebuffer + vblankcount: c.uint, //!< Amount of VBlanks this framebuffer has been displayed + paddr: c.uintptr_t, //!< Physical address + framebuf: SceDisplayFrameBuf, //!< SceDisplayFrameBuf information + resolution: c.uint, //!< Resolution +} + diff --git a/Dsi/Dsi.odin b/Dsi/Dsi.odin new file mode 100644 index 0000000..448f9db --- /dev/null +++ b/Dsi/Dsi.odin @@ -0,0 +1,32 @@ +package dsi + +import "core:c" + +foreign import dsi "system:SceDsiForDriver_stub" + +SceDsiErrorCode :: enum c.uint { + INVALID_HEAD = 0x803F0600, + INVALID_STATE = 0x803F0601, + INVALID_PARAM = 0x803F0602, + HEAD_NOT_ENABLED = 0x803F0603, +} + +SceDsiHead :: enum c.int { + OLED_LCD = 0, + HDMI = 1, +} + +@(link_prefix = "ksceDsi") +foreign dsi { + EnableHead :: proc(head: c.int) -> c.int --- + DisableHead :: proc(head: c.int) -> c.int --- + SendBlankingPacket :: proc(head: c.int) -> c.int --- + SetLanesAndPixelSize :: proc(head: c.int, lanes: c.int, pixelsize: c.int) -> c.int --- + SetVic :: proc(head: c.int, vic: c.int) -> c.int --- + GetVicResolution :: proc(vic: c.int, width: ^c.int, height: ^c.int) -> c.int --- + GetPixelClock :: proc(head: c.int) -> c.int --- + GenericShortWrite :: proc(head: c.int, param0: c.int, param1: c.int, param2: c.int) -> c.int --- + GenericReadRequest :: proc(head: c.int, param: c.int, buff: rawptr, size: c.uint) -> c.int --- + DcsShortWrite :: proc(head: c.int, param0: c.ushort, param1: c.int) -> c.int --- + DcsRead :: proc(head: c.int, param: c.ushort, buff: rawptr, size: c.uint) -> c.int --- +} diff --git a/Fiber/types.odin b/Fiber/types.odin index e06f31e..718efe4 100644 --- a/Fiber/types.odin +++ b/Fiber/types.odin @@ -5,7 +5,6 @@ import sce "../common" // Error Codes -// TODO: should be c.int SceFiberErrorCode :: enum c.uint { NULL = 0x80590001, ALIGNMENT = 0x80590002, diff --git a/Fios2/Fios2.odin b/Fios2/Fios2.odin index 87801cc..a422b23 100644 --- a/Fios2/Fios2.odin +++ b/Fios2/Fios2.odin @@ -4,6 +4,7 @@ import "core:c" import sce "../common" foreign import fios2 "system:SceFios2Kernel_stub" +foreign import fios2kern "system:SceFios2KernelForDriver_stub" @(link_prefix = "_sceFiosKernelOverlay") foreign fios2 { @@ -35,3 +36,49 @@ foreign fios2 { @(link_name = "sceFiosKernelOverlayAddForProcess02") AddForProcess02 :: proc(pid: sce.UID, overlay: ^SceFiosOverlay, outID: ^SceFiosOverlayID) -> c.int --- } + +foreign fios2kern { + /** + * Overlay process file system overlay + * + * @param[in] overlay - Overlay config pointer + * @param[out] outID - outID pointer + * + * @return Error code or zero on success + */ + ksceFiosKernelOverlayAdd :: proc(overlay: ^SceFiosOverlay, outID: ^SceFiosOverlayID) -> c.int --- + + /** + * Overlay process file system overlay + * + * @param[in] pid - Process id + * @param[in] overlay - Overlay config pointer + * @param[out] outID - outID pointer + * + * @return Error code or zero on success + */ + ksceFiosKernelOverlayAddForProcess :: proc(pid: sce.UID, overlay: ^SceFiosOverlay, outID: ^SceFiosOverlayID) -> c.int --- + + /** + * Remove process file system overlay + * + * @param[in] pid - Process id + * @param[in] id - Overlay id + * + * @return Error code or zero on success + */ + ksceFiosKernelOverlayRemoveForProcess :: proc(pid: sce.UID, id: SceFiosOverlayID) -> c.int --- + + /** + * Resolve process file system overlay with sync + * + * @param[in] pid - Process id + * @param[in] resolveFlag - Some flags + * @param[in] inPath - Path input + * @param[out] outPath - Path output + * @param[in] maxPath - Path output max length + * + * @return Error code or zero on success + */ + ksceFiosKernelOverlayResolveSync :: proc(pid: sce.UID, resolveFlag: c.int, inPath: cstring, outPath: [^]c.char, maxPath: sce.Size) -> c.int --- +} diff --git a/Gpio/Gpio.odin b/Gpio/Gpio.odin new file mode 100644 index 0000000..7727a1d --- /dev/null +++ b/Gpio/Gpio.odin @@ -0,0 +1,35 @@ +package gpio + +import "core:c" + +foreign import gpio "system:SceGpioForDriver_stub" + +SceGpioErrorCode :: enum c.uint { + INVALID_BUS = 0x803F0100, + INVALID_PORT = 0x803F0101, + INVALID_MODE = 0x803F0102, +} + +SceGpioPortMasks :: enum c.int { + LED_GAMECARD = 1 << 6, + LED_PS_BUTTON = 1 << 7, +} + +SceGpioPortMode :: enum c.int { + OUTPUT = 0, + INPUT = 1, +} + +@(link_prefix = "ksceGpio") +foreign gpio { + PortRead :: proc(bus: c.int, port: c.int) -> c.int --- + PortSet :: proc(bus: c.int, port: c.int) -> c.int --- + PortClear :: proc(bus: c.int, port: c.int) -> c.int --- + PortReset :: proc(bus: c.int, port: c.int) -> c.int --- + SetPortMode :: proc(bus: c.int, port: c.int, mode: c.int) -> c.int --- + GetPortMode :: proc(bus: c.int, port: c.int) -> c.int --- + SetIntrMode :: proc(bus: c.int, port: c.int, intr_mode: c.int) -> c.int --- + GetIntrMode :: proc(bus: c.int, port: c.int) -> c.int --- + AcquireIntr :: proc(bus: c.int, port: c.int) -> c.int --- + QueryIntr :: proc(bus: c.int, port: c.int) -> c.int --- +} diff --git a/GpuEs4/GpuEs4.odin b/GpuEs4/GpuEs4.odin new file mode 100644 index 0000000..5a5d3a8 --- /dev/null +++ b/GpuEs4/GpuEs4.odin @@ -0,0 +1,15 @@ +package gpues4 + +import "core:c" +import sce "../common" + +foreign import gpues4 "system:SceGpuEs4ForDriver_stub" + +foreign gpues4 { + PVRSRVGetMiscInfoKM :: proc(info: rawptr) -> c.int --- + + ksceGpuGetRegisterDump :: proc(dst: rawptr, size: sce.Size) -> c.int --- + + ksceGpuMmuMapMemory :: proc(mmuContext: rawptr, vaddr: c.uint32_t, base: rawptr, size: c.uint32_t, flags: c.uint32_t) -> c.int --- + ksceGpuMmuUnmapMemory :: proc(mmuContext: rawptr, vaddr: c.uint32_t, size: c.uint32_t) -> c.int --- +} diff --git a/Gxm/types.odin b/Gxm/types.odin index e6aa55e..9ce5791 100644 --- a/Gxm/types.odin +++ b/Gxm/types.odin @@ -5,8 +5,7 @@ import sce "../common" // Error Codes -// TODO: should be c.int -SceGxmErrorCode :: enum i64 { +SceGxmErrorCode :: enum c.uint { UNINITIALIZED = 0x805B0000, ALREADY_INITIALIZED = 0x805B0001, OUT_OF_MEMORY = 0x805B0002, @@ -1391,7 +1390,6 @@ SceGxmRenderTargetParams :: struct { #assert(size_of(SceGxmRenderTargetParams) == 0x14) -// TODO: should be c.int /** GXT error codes */ SceGxtErrorCode :: enum c.uint { INVALID_VALUE = 0x805D0000, diff --git a/Http/Http.odin b/Http/Http.odin index 61d489a..db84f3d 100644 --- a/Http/Http.odin +++ b/Http/Http.odin @@ -25,7 +25,7 @@ foreign http { HttpAbortRequest :: proc(reqId: c.int) -> c.int --- HttpGetResponseContentLength :: proc(reqId: c.int, contentLength: ^c.ulonglong) -> c.int --- HttpGetStatusCode :: proc(reqId: c.int, statusCode: ^c.int) -> c.int --- - HttpGetAllResponseHeaders :: proc(reqId: c.int, header: ^[^]c.char, headerSize: ^c.uint) -> c.int --- // TODO: header is multipointer, cstring or double pointer to char?? + HttpGetAllResponseHeaders :: proc(reqId: c.int, header: ^[^]c.char, headerSize: ^c.uint) -> c.int --- HttpReadData :: proc(reqId: c.int, data: rawptr, size: c.uint) -> c.int --- HttpAddRequestHeader :: proc(id: c.int, name: cstring, value: cstring, mode: c.uint) -> c.int --- HttpRemoveRequestHeader :: proc(id: c.int, name: cstring) -> c.int --- diff --git a/Http/types.odin b/Http/types.odin index 3318439..2ca7057 100644 --- a/Http/types.odin +++ b/Http/types.odin @@ -15,8 +15,7 @@ SCE_HTTP_DEFAULT_TRY_AUTH_MAX : c.uint : (6) SCE_HTTP_INVALID_ID :: 0 -// TODO: this should be a c.int -SceHttpErrorCode :: enum i64 { +SceHttpErrorCode :: enum c.uint { BEFORE_INIT = 0x80431001, ALREADY_INITED = 0x80431020, BUSY = 0x80431021, @@ -58,8 +57,7 @@ SceHttpErrorCode :: enum i64 { RESOLVER_ENORECORD = 0x8043600A, } -// TODO: this should be a c.int -SceHttpsErrorCode :: enum u32 { +SceHttpsErrorCode :: enum c.uint { CERT = 0x80435060, HANDSHAKE = 0x80435061, IO = 0x80435062, @@ -219,7 +217,7 @@ SceHttpSslVersion :: enum c.int { } SceHttpsData :: struct { - ptr: ^c.char, // TODO: multipointer or maybe cstring?? + ptr: ^c.char, size: c.uint, } when size_of(builtin.rawptr) == 4 { @@ -244,7 +242,7 @@ SceHttpAuthInfoCallback :: #type ^proc( password: cstring, needEntity: c.int, entityBody: ^[^]c.uchar, - entitySize: ^c.uint,// TODO:?? + entitySize: ^c.uint, save: ^c.int, userArg: rawptr, ) -> c.int diff --git a/I2c/I2c.odin b/I2c/I2c.odin new file mode 100644 index 0000000..6c0922b --- /dev/null +++ b/I2c/I2c.odin @@ -0,0 +1,33 @@ +package i2c + +import "core:c" + +foreign import i2c "system:SceI2cForDriver_stub" + +SceI2cErrorCode :: enum c.uint { + INVALID_BUS = 0x803F0300, + INVALID_SIZE = 0x803F0302, + INVALID_ADDR = 0x803F0303, +} + +SceI2cDebugHandlers :: struct { + size: c.uint, + write_start: #type ^proc "c" (bus: c.int, addr: c.int, buffer: [^]c.uchar, size: c.int), + write_end: #type ^proc "c" (bus: c.int, error: c.int, result: c.int), + read_start: #type ^proc "c" (bus: c.int, addr: c.int, buffer: [^]c.uchar, size: c.int), + read_end: #type ^proc "c" (bus: c.int, error: c.int, result: c.int), + write_read_start: #type ^proc "c" (bus: c.int, write_addr: c.int, write_buffer: [^]c.uchar, write_size: c.int, + read_addr: c.uint, read_buffer: [^]c.uchar, read_size: c.int), + write_read_end: #type ^proc "c" (bus: c.int, error: c.int, result: c.int), +} + +@(link_prefix = "ksceI2c") +foreign i2c { + Init :: proc(bus: c.int) -> c.int --- + Reset :: proc(bus: c.int) -> c.int --- + TransferRead :: proc(bus: c.int, addr: c.uint, buffer: [^]c.uchar, size: c.int) -> c.int --- + TransferWrite :: proc(bus: c.int, addr: c.uint, buffer: [^]c.uchar, size: c.int) -> c.int --- + TransferWriteRead :: proc(bus: c.int, write_addr: c.uint, write_buffer: [^]c.uchar, write_size: c.int, read_addr: c.uint, read_buffer: [^]c.uchar, read_size: c.int) -> c.int --- + + SetDebugHandlers :: proc(bus: c.int, debug_handlers: ^SceI2cDebugHandlers) -> c.int --- +} diff --git a/IdStorage/IdStorage.odin b/IdStorage/IdStorage.odin new file mode 100644 index 0000000..ebd9009 --- /dev/null +++ b/IdStorage/IdStorage.odin @@ -0,0 +1,27 @@ +package idstorage + +import "core:c" +import sce "../common" + +foreign import idstorage "system:SceIdStorageForDriver_stub" + +@(link_prefix = "ksceIdStorage") +foreign idstorage { + /** + * @param[in] leafnum - The read target leaf number + * @param[out] buf - The leaf data buffer pointer, size is 512 byte + * + * @return 0 on success, < 0 on error. + */ + ReadLeaf :: proc(leafnum: sce.Size, buf: rawptr) -> c.int --- + + /** + * @param[in] leafnum - The write target leaf number + * @param[in] buf - The leaf data buffer pointer, size is 512 byte + * + * @return 0 on success, < 0 on error. + * + * note - Writing to leaf requires manufacturing mode. + */ + WriteLeaf :: proc(leafnum: sce.Size, buf: rawptr) -> c.int --- +} diff --git a/Iftu/Iftu.odin b/Iftu/Iftu.odin new file mode 100644 index 0000000..0ddd5d9 --- /dev/null +++ b/Iftu/Iftu.odin @@ -0,0 +1,11 @@ +package iftu + +import "core:c" + +foreign import iftu "system:SceIftuForDriver_stub" + +@(link_prefix = "ksceIftu") +foreign iftu { + Csc :: proc(dst: ^SceIftuFrameBuf, src: ^SceIftuPlaneState, params: ^SceIftuConvParams) -> c.int --- +} + diff --git a/Iftu/types.odin b/Iftu/types.odin new file mode 100644 index 0000000..1e59b1a --- /dev/null +++ b/Iftu/types.odin @@ -0,0 +1,84 @@ +package iftu + +import "core:c" + +SceIftuErrorCode :: enum c.uint { + INVALID_PLANE = 0x803F0700, + INVALID_PARAM = 0x803F0701, + INVALID_PIXELFORMAT = 0x803F0703, + PLANE_BUSY = 0x803F0704, +} + +SceIftuPixelformat :: enum c.int { + BGR565 = 0x01, + RGB565 = 0x02, + BGRA5551 = 0x04, + RGBA5551 = 0x08, + BGRX8888 = 0x10, + RGBX8888 = 0x20, + BGRA1010102 = 0x40, + RGBA1010102 = 0x80, + BGRP = 0x100, /* 3 planes - R, G, B */ + RGBX8888_MULT = 0x1000, + BGRX8888_MULT = 0x2000, + RGBA1010102_MULT = 0x4000, + BGRA1010102_MULT = 0x8000, + NV12 = 0x10000, /* 2 planes - Y, Cb + Cr interleaved */ + YUV420 = 0x20000, /* 3 planes - Y, Cb, Cr */ + YUV422 = 0x200000, /* 3 planes - Y, Cb, Cr */ +} + +SceIftuCscParams :: struct { + post_add_0: c.uint, /* 10-bit integer */ + post_add_1_2: c.uint, /* 10-bit integer */ + post_clamp_max_0: c.uint, /* 10-bit integer */ + post_clamp_min_0: c.uint, /* 10-bit integer */ + post_clamp_max_1_2: c.uint, /* 10-bit integer */ + post_clamp_min_1_2: c.uint, /* 10-bit integer */ + ctm: [3][3]c.uint, /* S3.9 fixed point format */ +} +#assert(size_of(SceIftuCscParams) == 0x3C) + +SceIftuConvParams :: struct { + size: c.uint, + unk04: c.uint, + csc_params1: ^SceIftuCscParams, + csc_params2: ^SceIftuCscParams, + csc_control: c.uint, + unk14: c.uint, + unk18: c.uint, + unk1C: c.uint, + alpha: c.uint, + unk24: c.uint, +} + +SceIftuFrameBuf :: struct { + pixelformat: c.uint, + width: c.uint, /* Aligned to 16 */ + height: c.uint, /* Aligned to 8 */ + leftover_stride: c.uint, /* (pitch - aligned_w) * bpp */ + leftover_align: c.uint, /* if YCbCr: (width >> 1) & 0xF [chroma align?] */ + paddr0: c.uint, /* Physical address of the first plane */ + paddr1: c.uint, /* Physical address of the second plane */ + paddr2: c.uint, /* Physical address of the third plane */ +} +#assert(size_of(SceIftuFrameBuf) == 0x20) + +SceIftuPlaneState :: struct { + fb: SceIftuFrameBuf, + unk20: c.uint, + src_x: c.uint, /* In (0x10000 / 960) multiples */ + src_y: c.uint, /* in (0x10000 / 544) multiples */ + src_w: c.uint, /* in (0x10000 / 960) multiples */ + src_h: c.uint, /* in (0x10000 / 544) multiples */ + dst_x: c.uint, + dst_y: c.uint, + dst_w: c.uint, + dst_h: c.uint, + vtop_padding: c.uint, + vbot_padding: c.uint, /* h - aligned_h */ + hleft_padding: c.uint, + hright_padding: c.uint, /* w - aligned_w */ +} +#assert(size_of(SceIftuPlaneState) == 0x54) + diff --git a/Ime/types.odin b/Ime/types.odin index 76aea0f..a9574ce 100644 --- a/Ime/types.odin +++ b/Ime/types.odin @@ -12,7 +12,6 @@ SCE_IME_WORK_BUFFER_SIZE :: (20*1024) SCE_IME_MAX_PREEDIT_LENGTH :: (30) SCE_IME_MAX_TEXT_LENGTH :: (2048) -// TODO: should be c.int SceImeDialogErrorCode :: enum c.uint { PARAM = 0x80102001, INTERNAL = 0x80102002, @@ -71,7 +70,6 @@ SceImeDialogResult :: struct { } #assert(size_of(SceImeDialogResult) == 0x24) -// TODO: should be c.int SceImeErrorCode :: enum c.uint { ALREADY_OPENED = 0x80100700, NOT_OPENED = 0x80100701, diff --git a/IncomingDialog/types.odin b/IncomingDialog/types.odin index c394bad..149e45e 100644 --- a/IncomingDialog/types.odin +++ b/IncomingDialog/types.odin @@ -19,7 +19,6 @@ SceIncomingDialogStatus :: enum c.int { /** * Error Codes */ -// TODO: should be c.int SceIncomingDialogErrorCode :: enum c.uint { INVALID_ARG = 0x80106201 } diff --git a/Io/Io.odin b/Io/Io.odin index f2957ca..8a2674f 100644 --- a/Io/Io.odin +++ b/Io/Io.odin @@ -5,6 +5,7 @@ import sce "../common" foreign import libkernel "system:SceLibKernel_stub" foreign import iofilemgr "system:SceIofilemgr_stub" +foreign import iofilemgrkern "system:SceIofilemgrForDriver_stub" @(link_prefix = "sceIo") foreign libkernel { @@ -335,3 +336,270 @@ foreign iofilemgr { SetProcessDefaultPriority :: proc(priority: c.int) -> c.int --- SetThreadDefaultPriority :: proc(priority: c.int) -> c.int --- } + +foreign iofilemgrkern { + /** + * Send a devctl command to a device. + * + * @par Example: Sending a simple command to a device + * @code + * SceIoDevInfo info + * ksceIoDevctl("ux0:", 0x3001, NULL, 0, &info, sizeof(SceIoDevInfo)) + * @endcode + * + * @param dev - String for the device to send the devctl to (e.g. "ux0:") + * @param cmd - The command to send to the device + * @param indata - A data block to send to the device, if NULL sends no data + * @param inlen - Length of indata, if 0 sends no data + * @param outdata - A data block to receive the result of a command, if NULL receives no data + * @param outlen - Length of outdata, if 0 receives no data + * @return 0 on success, < 0 on error + */ + ksceIoDevctl :: proc(dev: cstring, cmd: c.uint, indata: rawptr, inlen: c.int, outdata: rawptr, outlen: c.int) -> c.int --- + + /** + * Open a directory + * + * @par Example: + * @code + * int dfd + * dfd = ksceIoDopen("device:/") + * if(dfd >= 0) + * { Do something with the file descriptor } + * @endcode + * @param dirname - The directory to open for reading. + * @return If >= 0 then a valid file descriptor, otherwise a Sony error code. + */ + ksceIoDopen :: proc(dirname: cstring) -> sce.UID --- + + /** + * Reads an entry from an opened file descriptor. + * + * @param fd - Already opened file descriptor (using ::ksceIoDopen) + * @param dir - Pointer to an ::SceIoDirent structure to hold the file information + * + * @return Read status + * - 0 - No more directory entries left + * - > 0 - More directory entries to go + * - < 0 - Error + */ + ksceIoDread :: proc(fd: sce.UID, dir: ^SceIoDirent) -> c.int --- + + /** + * Close an opened directory file descriptor + * + * @param fd - Already opened file descriptor (using ::ksceIoDopen) + * @return < 0 on error + */ + ksceIoDclose :: proc(fd: sce.UID) -> c.int --- + + /** + * Open or create a file for reading or writing + * + * @par Example1: Open a file for reading + * @code + * if(!(fd = ksceIoOpen("device:/path/to/file", SCE_O_RDONLY, 0777)) { + * // error + * } + * @endcode + * @par Example2: Open a file for writing, creating it if it doesn't exist + * @code + * if(!(fd = ksceIoOpen("device:/path/to/file", SCE_O_WRONLY|SCE_O_CREAT, 0777)) { + * // error + * } + * @endcode + * + * @param file - Pointer to a string holding the name of the file to open + * @param flags - Libc styled flags that are or'ed together + * @param mode - File access mode (One or more ::SceIoMode). + * @return A non-negative integer is a valid fd, anything else an error + */ + ksceIoOpen :: proc(file: cstring, flags: c.int, mode: sce.Mode) -> sce.UID --- + + /** + * Delete a descriptor + * + * @code + * ksceIoClose(fd) + * @endcode + * + * @param fd - File descriptor to close + * @return < 0 on error + */ + ksceIoClose :: proc(fd: sce.UID) -> c.int --- + + /** + * Read input + * + * @par Example: + * @code + * bytes_read = ksceIoRead(fd, data, 100) + * @endcode + * + * @param fd - Opened file descriptor to read from + * @param data - Pointer to the buffer where the read data will be placed + * @param size - Size of the read in bytes + * + * @return The number of bytes read + */ + ksceIoRead :: proc(fd: sce.UID, data: rawptr, size: sce.Size) -> c.int --- + + /** + * Read input at offset + * + * @par Example: + * @code + * bytes_read = ksceIoPread(fd, data, 100, 0x1000) + * @endcode + * + * @param fd - Opened file descriptor to read from + * @param data - Pointer to the buffer where the read data will be placed + * @param size - Size of the read in bytes + * @param offset - Offset to read + * + * @return < 0 on error. + */ + ksceIoPread :: proc(fd: sce.UID, data: rawptr, size: sce.Size, offset: sce.Off) -> c.int --- + + /** + * Write output + * + * @par Example: + * @code + * bytes_written = ksceIoWrite(fd, data, 100) + * @endcode + * + * @param fd - Opened file descriptor to write to + * @param data - Pointer to the data to write + * @param size - Size of data to write + * + * @return The number of bytes written + */ + ksceIoWrite :: proc(fd: sce.UID, data: rawptr, size: sce.Size) -> c.int --- + + /** + * Write output at offset + * + * @par Example: + * @code + * bytes_written = ksceIoPwrite(fd, data, 100, 0x1000) + * @endcode + * + * @param fd - Opened file descriptor to write to + * @param data - Pointer to the data to write + * @param size - Size of data to write + * @param offset - Offset to write + * + * @return The number of bytes written + */ + ksceIoPwrite :: proc(fd: sce.UID, data: rawptr, size: sce.Size, offset: sce.Off) -> c.int --- + + /** + * Reposition read/write file descriptor offset + * + * @par Example: + * @code + * pos = ksceIoLseek(fd, -10, SCE_SEEK_END) + * @endcode + * + * @param fd - Opened file descriptor with which to seek + * @param offset - Relative offset from the start position given by whence + * @param whence - One of ::SceIoSeekMode. + * + * @return The position in the file after the seek. + */ + ksceIoLseek :: proc(fd: sce.UID, offset: sce.Off, whence: c.int) -> sce.Off --- + + /** + * Remove directory entry + * + * @param file - Path to the file to remove + * @return < 0 on error + */ + ksceIoRemove :: proc(file: cstring) -> c.int --- + + /** + * Change the name of a file + * + * @param oldname - The old filename + * @param newname - The new filename + * @return < 0 on error. + */ + ksceIoRename :: proc(oldname: cstring, newname: cstring) -> c.int --- + + /** + * Synchronize the file data on the device. + * + * @param device - The device to synchronize (e.g. msfat0:) + * @param unk - Unknown + */ + ksceIoSync :: proc(device: cstring, unk: c.uint) -> c.int --- + + /** + * Synchronize the file data for one file + * + * @param fd - Opened file descriptor to sync + * + * @return < 0 on error. + */ + ksceIoSyncByFd :: proc(fd: sce.UID) -> c.int --- + + /** + * Make a directory file + * + * @param dir - The path to the directory + * @param mode - Access mode (One or more ::SceIoAccessMode). + * @return Returns the value 0 if it's successful, otherwise -1 + */ + ksceIoMkdir :: proc(dir: cstring, mode: sce.Mode) -> c.int --- + + /** + * Remove a directory file + * + * @param path - Removes a directory file pointed by the string path + * @return Returns the value 0 if it's successful, otherwise -1 + */ + ksceIoRmdir :: proc(path: cstring) -> c.int --- + + /** + * Get the status of a file. + * + * @param file - The path to the file. + * @param stat - A pointer to a ::SceIoStat structure. + * + * @return < 0 on error. + */ + ksceIoGetstat :: proc(file: cstring, stat: SceIoStat) -> c.int --- + + /** + * Get the status of a file descriptor. + * + * @param fd - The file descriptor. + * @param stat - A pointer to a ::SceIoStat structure. + * + * @return < 0 on error. + */ + ksceIoGetstatByFd :: proc(fd: sce.UID, stat: ^SceIoStat) -> c.int --- + + /** + * Change the status of a file. + * + * @param file - The path to the file. + * @param stat - A pointer to a ::SceIoStat structure. + * @param bits - Bitmask defining which bits to change. + * + * @return < 0 on error. + */ + ksceIoChstat :: proc(file: cstring, stat: ^SceIoStat, bits: c.int) -> c.int --- + + /** + * Change the status of a file descriptor. + * + * @param fd - The file descriptor. + * @param stat - A pointer to an io_stat_t structure. + * @param bits - Bitmask defining which bits to change. + * + * @return < 0 on error. + */ + ksceIoChstatByFd :: proc(fd: sce.UID, stat: ^SceIoStat, bits: c.int) -> c.int --- +} diff --git a/Io/types.odin b/Io/types.odin index d534c23..7552f4f 100644 --- a/Io/types.odin +++ b/Io/types.odin @@ -100,12 +100,6 @@ SceIoAccessMode :: enum c.int { S_IFMT = 0170000, //!< Format bits mask } -// TODO: -// File mode checking macros -//#define SCE_S_ISLNK(m) (((m) & SCE_S_IFMT) == SCE_S_IFLNK) -//#define SCE_S_ISREG(m) (((m) & SCE_S_IFMT) == SCE_S_IFREG) -//#define SCE_S_ISDIR(m) (((m) & SCE_S_IFMT) == SCE_S_IFDIR) - /** File modes, used for the st_attr parameter in ::SceIoStat. */ SceIoFileMode :: enum c.int { SO_IXOTH = 0x0001, //!< Hidden execute permission @@ -117,12 +111,6 @@ SceIoFileMode :: enum c.int { SO_IFMT = 0x0038, //!< Format mask } -// TODO: -// File mode checking macros -//#define SCE_SO_ISLNK(m) (((m) & SCE_SO_IFMT) == SCE_SO_IFLNK) -//#define SCE_SO_ISREG(m) (((m) & SCE_SO_IFMT) == SCE_SO_IFREG) -//#define SCE_SO_ISDIR(m) (((m) & SCE_SO_IFMT) == SCE_SO_IFDIR) - /** Structure to hold the status information about a file */ SceIoStat :: struct { st_mode: sce.Mode, //!< One or more ::SceIoAccessMode diff --git a/Jpeg/Jpeg.odin b/Jpeg/Jpeg.odin index 1ab5d2b..d37ee9e 100644 --- a/Jpeg/Jpeg.odin +++ b/Jpeg/Jpeg.odin @@ -7,6 +7,7 @@ foreign import jpeg "system:SceJpeg_stub" foreign import jpegarm "system:SceJpegArm_stub" foreign import jpegenc "system:SceJpegEnc_stub" foreign import jpegencarm "system:SceJpegEncArm_stub" +foreign import jpegkern "system:SceAvcodecForDriver_stub" @(link_prefix = "sceJpeg") foreign jpeg { @@ -256,3 +257,101 @@ foreign jpegencarm { */ sceJpegArmEncoderSetHeaderMode :: proc(_context: SceJpegArmEncoderContext, mode: SceJpegArmEncoderHeaderMode) -> c.int --- } + +foreign jpegkern { + /** + * Initialize a jpeg encoder + * + * @param[in] _context - A pointer to a big enough allocated memory block + * @param[in] inWidth - Input width in pixels + * @param[in] inHeight - Input height in pixels + * @param[in] pixelformat - A valid ::SceJpegEncoderPixelFormat set of values + * @param[in] outBuffer - A physically continuous memory block 256 bytes aligned + * @param[in] outSize - Output size in bytes + * + * @return 0 on success, < 0 on error. + */ + ksceJpegEncoderInit :: proc(_context: SceJpegEncoderContext, inWidth: c.int, inHeight: c.int, pixelformat: SceJpegEncoderPixelFormat, outBuffer: rawptr, outSize: sce.Size) -> c.int --- + + /** + * Terminate a jpeg encoder + * + * @param[in] _context - A pointer to an already initialized ::SceJpegEncoderContext + * + * @return 0 on success, < 0 on error. + */ + ksceJpegEncoderEnd :: proc(_context: SceJpegEncoderContext) -> c.int --- + + /** + * Execute a jpeg encode + * + * @param[in] _context - A pointer to an already initialized ::SceJpegEncoderContext + * @param[in] inBuffer - A physically continuous memory block 256 bytes aligned + * + * @return 0 on success, < 0 on error. + */ + ksceJpegEncoderEncode :: proc(_context: SceJpegEncoderContext, inBuffer: rawptr) -> c.int --- + + /** + * Set encoder compression ratio + * + * @param[in] _context - A pointer to an already initialized ::SceJpegEncoderContext + * @param[in] ratio - A value between 0 and 255 (higher = better compression, lower = better speed) + * + * @return 0 on success, < 0 on error. + */ + ksceJpegEncoderSetCompressionRatio :: proc(_context: SceJpegEncoderContext, ratio: c.int) -> c.int --- + + + /** + * Set encoder output address + * + * @param[in] _context - A pointer to an already initialized ::SceJpegEncoderContext + * @param[in] outBuffer - A physically continuous memory block 256 bytes aligned + * @param[in] outSize - Output buffer size in bytes + * + * @return 0 on success, < 0 on error. + */ + ksceJpegEncoderSetOutputAddr :: proc(_context: SceJpegEncoderContext, outBuffer: rawptr, outSize: sce.Size) -> c.int --- + + /** + * Execute a color conversion from ARGB to YCbCr + * + * @param[in] _context - A pointer to an already initialized ::SceJpegEncoderContext + * @param[in] outBuffer - A physical continuous memory block 256 bytes aligned + * @param[in] inBuffer - A pointer to a valid ARGB buffer + * @param[in] inPitch - Input pitch value in pixels + * @param[in] inPixelFormat - A valid ::SceJpegEncoderPixelFormat set of values + * + * @return 0 on success, < 0 on error. + */ + ksceJpegEncoderCsc :: proc(_context: SceJpegEncoderContext, outBuffer: rawptr, inBuffer: rawptr, inPitch: c.int, inPixelFormat: SceJpegEncoderPixelFormat) -> c.int --- + + /** + * Return required free size to allocate a jpeg encoder + * + * @return Required free memory size in bytes, < 0 on error. + */ + ksceJpegEncoderGetContextSize :: proc() -> c.int --- + + /** + * Set encoder valid region (?) + * + * @param[in] _context - A pointer to an already initialized ::SceJpegEncoderContext + * @param[in] inWidth - Input width in pixels + * @param[in] inHeight - Input height in pixels + * + * @return 0 on success, < 0 on error. + */ + ksceJpegEncoderSetValidRegion :: proc(_context: SceJpegEncoderContext, inWidth: c.int, inHeight: c.int) -> c.int --- + + /** + * Set header used for output file + * + * @param[in] _context - A pointer to an already initialized ::SceJpegEncoderContext + * @param[in] mode - One of ::SceJpegEncoderHeaderMode + * + * @return 0 on success, < 0 on error. + */ + ksceJpegEncoderSetHeaderMode :: proc(_context: SceJpegEncoderContext, mode: c.int) -> c.int --- +} diff --git a/Jpeg/types.odin b/Jpeg/types.odin index 49ed3ae..c615984 100644 --- a/Jpeg/types.odin +++ b/Jpeg/types.odin @@ -70,7 +70,6 @@ when size_of(rawptr) == 4 { /** * Error Codes */ - // TODO: should be c.int SceJpegEncArmErrorCode :: enum c.uint { /** * The image dimensions given are not supported, or are larger @@ -120,7 +119,6 @@ when size_of(rawptr) == 4 { #assert(size_of(SceJpegEncoderContext) == 4) } -// TODO: should be c.int SceJpegEncErrorCode :: enum c.uint { IMAGE_SIZE = 0x80650200, INSUFFICIENT_BUFFER = 0x80650201, diff --git a/Kernel/types.odin b/Kernel/types.odin index a82e76b..1c1eb99 100644 --- a/Kernel/types.odin +++ b/Kernel/types.odin @@ -3,8 +3,7 @@ package kernel import "core:c" import sce "../common" -// TODO: this should be a c.int -SceKernelErrorCode :: enum i64 { +SceKernelErrorCode :: enum c.uint { OK = 0x0, ERROR = 0x80020001, NOT_IMPLEMENTED = 0x80020002, diff --git a/Location/types.odin b/Location/types.odin index 2b80c41..d6fbef4 100644 --- a/Location/types.odin +++ b/Location/types.odin @@ -6,7 +6,6 @@ import sce "../common" SCE_LOCATION_DATA_INVALID :: -9999.0 /** Location error codes */ -// TODO: SceLocationErrorCode :: enum c.uint { SUCCESS = 0, diff --git a/Motion/types.odin b/Motion/types.odin index f5da836..064748c 100644 --- a/Motion/types.odin +++ b/Motion/types.odin @@ -9,7 +9,6 @@ SceMotionMagFieldStability :: enum c.int { STABLE = 2 } -// TODO: SceMotionErrorCode :: enum c.uint { DATA_INVALID = 0x80360200, READING = 0x80360201, diff --git a/Net/Net.odin b/Net/Net.odin index b46ef92..2565352 100644 --- a/Net/Net.odin +++ b/Net/Net.odin @@ -2,6 +2,7 @@ package net import "core:c" foreign import net "system:SceNet_stub" +foreign import netps "system:SceNetPsForDriver_stub" @(link_prefix = "sceNet") foreign net { @@ -74,8 +75,6 @@ foreign net { InetNtop :: proc(af: c.int, src: rawptr, dst: cstring, size: c.uint) -> cstring --- InetPton :: proc(af: c.int, src: cstring, dst: rawptr) -> c.int --- - //TODO : create BSD aliases ? - Htonll :: proc(host64: c.ulonglong) -> c.ulonglong --- Htonl :: proc(host32: c.uint) -> c.uint --- Htons :: proc(host16: c.ushort) -> c.ushort --- @@ -90,3 +89,15 @@ foreign net { */ ErrnoLoc :: proc() -> ^c.int --- } + +foreign netps { + ksceNetSocket :: proc(name: cstring, domain: c.int, type: c.int, protocol: c.int) -> c.int --- + ksceNetAccept :: proc(s: c.int, addr: ^SceNetSockaddr, addrlen: ^c.uint) -> c.int --- + ksceNetBind :: proc(s: c.int, #by_ptr addr: SceNetSockaddr, addrlen: c.uint) -> c.int --- + ksceNetConnect :: proc(s: c.int, #by_ptr name: SceNetSockaddr, namelen: c.uint) -> c.int --- + ksceNetListen :: proc(s: c.int, backlog: c.int) -> c.int --- + ksceNetRecvfrom :: proc(s: c.int, buf: rawptr, len: c.uint, flags: c.int, from: ^SceNetSockaddr, fromlen: ^c.uint) -> c.int --- + ksceNetSendto :: proc(s: c.int, msg: rawptr, len: c.uint, flags: c.int, #by_ptr to: SceNetSockaddr, tolen: c.uint) -> c.int --- + ksceNetSetsockopt :: proc(s: c.int, level: c.int, optname: c.int, optval: rawptr, optlen: c.uint) -> c.int --- + ksceNetClose :: proc(s: c.int) -> c.int --- +} diff --git a/Net/types.odin b/Net/types.odin index 0efeaef..57dad7f 100644 --- a/Net/types.odin +++ b/Net/types.odin @@ -185,8 +185,7 @@ when size_of(rawptr) == 4 { } /** Net Error Codes */ -// TODO: this should be a c.int -SceNetErrorCode :: enum i64 { +SceNetErrorCode :: enum c.uint { EPERM = 0x80410101, ENOENT = 0x80410102, ESRCH = 0x80410103, diff --git a/NotificationUtil/types.odin b/NotificationUtil/types.odin index 30183f9..6a3fc4f 100644 --- a/NotificationUtil/types.odin +++ b/NotificationUtil/types.odin @@ -11,7 +11,6 @@ SCE_NOTIFICATIONUTIL_TEXT_MAX :: 0x3F /** * Error Codes */ -// TODO: SceNotificationUitlErrorCode :: enum c.uint { INTERNAL = 0x80106300 } diff --git a/NpDrm/NpDrm.odin b/NpDrm/NpDrm.odin index 24f21ab..2f77e75 100644 --- a/NpDrm/NpDrm.odin +++ b/NpDrm/NpDrm.odin @@ -5,6 +5,7 @@ import sce "../common" foreign import npdrm "system:SceNpDrm_stub" foreign import npdrmpackage "system:SceNpDrmPackage_stub" +foreign import npdrmkern "system:SceNpDrmForDriver_stub" foreign npdrm { /** @@ -98,3 +99,172 @@ foreign npdrmpackage { */ Decrypt :: proc(#no_alias buffer: rawptr, size: sce.Size, #no_alias opt: ^_sceNpDrmPackageDecrypt_opt) -> c.int --- } + +foreign npdrmkern { + /** + * Get license file name + * + * @param[out] name - The pointer of license file name output buffer. size is 0x30. + * @param[in] aid - The license account id + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmGetRifName :: proc(name: [^]c.char, aid: sce.UInt64) -> c.int --- + + /** + * Get license file name with fixed + * + * @param[out] name - The pointer of license file name output buffer. size is 0x30. + * @param[in] aid - The license account id + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmGetFixedRifName :: proc(name: [^]c.char, aid: sce.UInt64) -> c.int --- + + /** + * Get current activation data + * + * @param[out] act_data - The pointer of output activation data see:SceNpDrmActivationData. if ecdsa or rsa verify fail, will be all 0. + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmReadActData :: proc(act_data: ^SceNpDrmActivationData) -> c.int --- + + /** + * Check you have npdrm activation data, and get information from it + * + * @param[out] act_type - The pointer of activation type output. + * @param[out] version_flag - The pointer of version flag output. + * @param[out] account_id - The pointer of activated account id output. + * @param[out] act_start_time - The pointer of activation data start time output. + * @param[out] act_exp_time - The pointer of activation data expire time output + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmCheckActData :: proc(act_type: ^c.int, version_flag: ^c.int, account_id: ^sce.UInt64, act_start_time: ^sce.UInt64, act_end_time: ^sce.UInt64) -> c.int --- + + /** + * Get license key info + * + * @param[in] license - The pointer of license data. see:SceNpDrmLicense + * @param[out] klicense - The pointer of klicense output buffer. size is 0x10. + * @param[out] flags - The pointer of flags output. + * @param[out] sku_flags - The pointer of sku flags output. + * @param[out] lic_start_time - The pointer of license start time output. + * @param[out] lic_exp_time - The pointer of license exp time output. + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmGetRifVitaKey :: proc(license: rawptr, klicense: rawptr, flags: ^c.int, sku_flags: ^c.int, lic_start_time: ^sce.UInt64, lic_exp_time: ^sce.UInt64) -> c.int --- + + /** + * Get license key info for a PSP game + * + * @param[in] license - The pointer of license data. see:SceNpDrmLicense + * @param[out] klicense - The pointer of klicense output buffer. size is 0x10. + * @param[out] flags - The pointer of flags output. + * @param[out] lic_start_time - The pointer of license start time output. + * @param[out] lic_exp_time - The pointer of license exp time output. + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmGetRifPspKey :: proc(license: rawptr, klicense: rawptr, flags: c.int, lic_start_time: ^sce.UInt64, lic_exp_time: ^sce.UInt64) -> c.int --- + + /** + * Get license info + * + * @param[in] license - The pointer of license data. see:SceNpDrmLicense + * @param[in] license_size - The license data size. 0x200 etc + * @param[in] check_sign - The license signature check flag. if pass 1, do check. + * @param[out] content_id - The pointer of license content_id output buffer. size is 0x30. + * @param[out] account_id - The pointer of license account_id output. + * @param[out] license_version - The pointer of license version output. + * @param[out] license_flags - The pointer of license flags output. + * @param[out] flags - The pointer of flags output. + * @param[out] sku_flags - The pointer of sku flags output. + * @param[out] lic_start_time - The pointer of license start time output. + * @param[out] lic_exp_time - The pointer of license exp time output. + * @param[out] flags2 - The pointer of flags2 output. + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmGetRifInfo :: proc(license: rawptr, license_size: sce.Size, check_sign: c.int, content_id: [^]c.char, account_id: ^sce.UInt64, license_version: ^c.int, license_flags: ^c.int, flags: ^c.int, sku_flags: ^c.int, lic_start_time: ^sce.Int64, lic_exp_time: ^sce.Int64, flags2: ^sce.UInt64) -> c.int --- + + /** + * Verify a eboot.pbp signature "__sce_ebootpbp" + * + * @param[in] eboot_pbp_path - The pointer of the file path of the EBOOT.PBP file + * @param[in] eboot_signature - The pointer of data of __sce_ebootpbp signature. size is 0x200 + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmEbootSigVerify :: proc(eboot_pbp_path: cstring, eboot_signature: rawptr) -> c.int --- + + /** + * Verify an older 0x100 byte eboot.pbp signature "__sce_ebootpbp" from firmware <2.00 + * + * @param[in] eboot_pbp_path - The pointer of the file path of the EBOOT.PBP file + * @param[in] eboot_signature - The pointer of data of __sce_ebootpbp signature. size is 0x100 + * + * @return 0 on success, < 0 on error. + */ + ksceNpDrmPspEbootVerify :: proc(eboot_pbp_path: cstring, eboot_signature: rawptr) -> c.int --- + + /** + * Generate an older 0x100 byte eboot.pbp signature "__sce_ebootpbp" for a PSP game - this is unused in firmware >2.00 + * + * @param[in] eboot_pbp_path - The pointer of the file path of the EBOOT.PBP file + * @param[in] eboot_sha256 - The pointer of SHA256 hash of first (data.psar offset + 0x1C0000) bytes into the EBOOT.PBP file + * @param[out] eboot_signature - The pointer of the output eboot signature data. size is 0x100 + * + * @return eboot_signature size on success, < 0 on error. + */ + ksceNpDrmPspEbootSigGen :: proc(eboot_pbp_path: cstring, eboot_sha256: rawptr, eboot_signature: rawptr) -> c.int --- + + /** + * Convert an older 0x100 byte eboot.pbp signature "__sce_ebootpbp" to a 0x200 byte one used in firmwares >2.00 + * + * @param[in] eboot_pbp_path - The pointer of the file path of the EBOOT.PBP file + * @param[in] old_eboot_signature - The pointer of old eboot signature data. size is 0x100 + * @param[out] new_eboot_signature - The pointer of new eboot signature data. size is 0x200 + * + * @return eboot_signature size on success, < 0 on error. + */ + ksceNpDrmEbootSigConvert :: proc(eboot_pbp_path: cstring, old_eboot_signature: rawptr, new_eboot_signature: rawptr) -> c.int --- + + /** + * Generate eboot.pbp signature "__sce_ebootpbp" for a PSP game + * + * @param[in] eboot_pbp_path - The pointer of the file path of the EBOOT.PBP file + * @param[in] eboot_sha256 - The pointer of SHA256 hash of first (data.psar offset + 0x1C0000) bytes into the EBOOT.PBP file + * @param[out] eboot_signature - The pointer of the output eboot signature data. size is 0x200 + * @param[in] sw_version - The minimum firmware version the signature can be used on. cannot be lower than current firmware + * + * @return eboot_signature size on success, < 0 on error. + */ + ksceNpDrmEbootSigGenPsp :: proc(eboot_pbp_path: cstring, eboot_sha256: rawptr, eboot_signature: rawptr, sw_version: c.int) -> c.int --- + + /** + * Generate eboot.pbp signature "__sce_ebootpbp" for a single-disc PS1 game + * + * @param[in] eboot_pbp_path - The pointer of the file path of the EBOOT.PBP file + * @param[in] eboot_sha256 - The pointer of SHA256 hash of first (data.psar offset + 0x1C0000) bytes into the EBOOT.PBP file + * @param[out] eboot_signature - The pointer of the output eboot signature data. size is 0x200 + * @param[in] sw_version - The minimum firmware version the signature can be used on. cannot be lower than current firmware + * + * @return eboot_signature size on success, < 0 on error. + */ + ksceNpDrmEbootSigGenPs1 :: proc(eboot_pbp_path: cstring, eboot_sha256: rawptr, eboot_signature: rawptr, sw_version: c.int) -> c.int --- + + /** + * Generate eboot.pbp signature "__sce_discinfo" for a multi-disc PS1 game + * + * @param[in] eboot_pbp_path - The pointer of the file path of the EBOOT.PBP file + * @param[in] sce_discinfo - The pointer of contents of vs0:/app/NPXS10028/__sce_discinfo + * @param[out] eboot_signature - The pointer of the output eboot signature data. size is 0x100 + * @param[in] sw_version - The minimum firmware version the signature can be used on. cannot be lower than current firmware + * + * @return eboot_signature size on success, < 0 on error. + */ + ksceNpDrmEbootSigGenMultiDisc :: proc(eboot_pbp_path: cstring, sce_discinfo: rawptr, eboot_signature: rawptr, sw_version: c.int) -> c.int --- +} diff --git a/Pervasive/Pervasive.odin b/Pervasive/Pervasive.odin new file mode 100644 index 0000000..f741b5a --- /dev/null +++ b/Pervasive/Pervasive.odin @@ -0,0 +1,40 @@ +package pervasive + +import "core:c" +import sce "../common" + +foreign import pervasive "system:ScePervasiveForDriver_stub" + +foreign pervasive { + UartClockDisable :: proc(port: c.int) -> c.int --- + UartResetEnable :: proc(port: c.int) -> c.int --- + UartResetDisable :: proc(port: c.int) -> c.int --- + UartClockEnable :: proc(port: c.int) -> c.int --- + UartSetBaudrate :: proc(port: c.int, baudrate: c.uint) -> c.int --- + + GpioResetEnable :: proc() -> c.int --- + GpioResetDisable :: proc() -> c.int --- + GpioClockEnable :: proc() -> c.int --- + GpioClockDisable :: proc() -> c.int --- + + SpiResetEnable :: proc(port: c.int) -> c.int --- + SpiResetDisable :: proc(port: c.int) -> c.int --- + SpiClockDisable :: proc(port: c.int) -> c.int --- + SpiClockEnable :: proc(port: c.int) -> c.int --- + + DsiResetEnable :: proc(port: c.int, mask: c.uint) -> c.int --- + DsiResetDisable :: proc(port: c.int, mask: c.uint) -> c.int --- + DsiClockEnable :: proc(port: c.int, mask: c.uint) -> c.int --- + DsiClockDisable :: proc(port: c.int, mask: c.uint) -> c.int --- + DsiSetPixelClock :: proc(port: c.int, pixelclock: c.int) -> c.int --- + + MsifResetEnable :: proc() -> c.int --- + MsifResetDisable :: proc() -> c.int --- + MsifClockEnable :: proc() -> c.int --- + MsifClockDisable :: proc() -> c.int --- + MsifSetClock :: proc(clock: c.uint) -> c.int --- + + RemovableMemoryGetCardInsertState :: proc() -> c.int --- + + GetSoCRevision :: proc() -> sce.UInt32 --- +} diff --git a/PfsMgr/PfsMgr.odin b/PfsMgr/PfsMgr.odin new file mode 100644 index 0000000..ed70802 --- /dev/null +++ b/PfsMgr/PfsMgr.odin @@ -0,0 +1,51 @@ +package pfsmgr + +import "core:c" +import sce "../common" + +foreign import pfsmgr "system:ScePfsMgeForKernel_stub" + +ScePfsRndDriveId :: struct { + drive_id: [0x10]c.char, +} +#assert(size_of(ScePfsRndDriveId) == 0x10) + +@(link_prefix = "kscePfs") +foreign pfsmgr { + /** + * Mount pfs directory + * + * @param[in] path - The pfs encrypted directory path + * @param[in] rnd_drive_id - The pfs mount target Pseudo Drive strings + * @param[in] authid - The authid + * @param[in] klicensee - The klicensee + * @param[in] mode_index - The mode_index + * + * @return 0 on success, < 0 on error. + */ + Mount :: proc(path: cstring, #by_ptr rnd_drive_id: ScePfsRndDriveId, program_authority_id: sce.UInt64, klicensee: rawptr, mode_index: c.uint16_t) -> c.int --- + + /** + * Mount pfs directory without authid + * + * @param[in] path - The pfs encrypted directory path + * @param[in] rnd_drive_id - The pfs mount target Pseudo Drive strings + * @param[in] klicensee - The klicensee + * @param[in] mode_index - The mode_index + * + * @return 0 on success, < 0 on error. + */ + Mount2 :: proc(path: cstring, #by_ptr rnd_drive_id: ScePfsRndDriveId, klicensee: rawptr, mode_index: c.uint16_t) -> c.int --- + + /** + * Unmount pfs directory + * + * @param[in] rnd_drive_id - The pfs mount drive strings + * + * @return 0 on success, < 0 on error. + */ + Unmount :: proc(#by_ptr rnd_drive_id: ScePfsRndDriveId) -> c.int --- + + Approve :: proc(#by_ptr rnd_drive_id: ScePfsRndDriveId, program_authority_id: sce.UInt64) -> c.int --- + Disapprove :: proc(#by_ptr rnd_drive_id: ScePfsRndDriveId, program_authority_id: sce.UInt64) -> c.int --- +} diff --git a/Pgf/types.odin b/Pgf/types.odin index 9311328..106ec25 100644 --- a/Pgf/types.odin +++ b/Pgf/types.odin @@ -8,7 +8,6 @@ SceFontHandle :: rawptr /* struct */ -// TODO: SceFontErrorCode :: enum c.uint { OUT_OF_MEMORY = 0x80460001, INVALID_LIBID = 0x80460002, diff --git a/PostSsMgr/PostSsMgr.odin b/PostSsMgr/PostSsMgr.odin new file mode 100644 index 0000000..2ee431c --- /dev/null +++ b/PostSsMgr/PostSsMgr.odin @@ -0,0 +1,32 @@ +package postssmgr + +import "core:c" + +foreign import postssmgr "system:SceSblSsMgrForDriver_stub" + +@(link_prefix = "ksceSbl") +foreign postssmgr { + /** + * Create the new RSA signature + * + * @param[inout] rsa_signature - The RSA signature result + * @param[in] hash - The RSA signature hash + * @param[in] private_key - The RSA private key + * @param[in] type - The RSA signature type. [2, 4, 5, 0xB, 0xC, 0xD, 0xE] + * + * @return SCE_OK on success, < 0 on error + */ + RSA2048CreateSignature :: proc(rsa_signature: ^SceSblRsaDataParam, hash: ^SceSblRsaDataParam, private_key: SceSblRsaPrivateKeyParam, type: c.int) -> c.int --- + + /** + * Verufy the new RSA signature + * + * @param[in] rsa_signature - The RSA signature input + * @param[in] hash - The RSA signature hash + * @param[in] public_key - The RSA public key + * @param[in] type - The RSA signature type. [2, 4, 5, 0xB, 0xC, 0xD, 0xE] + * + * @return SCE_OK on success, < 0 on error + */ + RSA2048VerifySignature :: proc(rsa_signature: ^SceSblRsaDataParam, hash: ^SceSblRsaDataParam, public_key: ^SceSblRsaPublicKeyParam, type: c.int) -> c.int --- +} diff --git a/PostSsMgr/types.odin b/PostSsMgr/types.odin new file mode 100644 index 0000000..110040e --- /dev/null +++ b/PostSsMgr/types.odin @@ -0,0 +1,26 @@ +package postssmgr + +import "core:c" + +SceSblRsaDataParam :: struct { + data: rawptr, + size: c.uint, +} + +SceSblRsaPublicKeyParam :: struct { + n: rawptr, + k: rawptr, // e/d +} + +SceSblRsaPrivateKeyParam :: struct { + unk_0x00: c.int, + unk_0x04: c.int, + unk_0x08: c.int, + unk_0x0C: c.int, + p: rawptr, + q: rawptr, + dp: rawptr, // d % (p - 1) + dq: rawptr, // d % (q - 1) + qp: rawptr, // q^-1 % p +} + diff --git a/Power/Power.odin b/Power/Power.odin index 05428aa..9a51cc5 100644 --- a/Power/Power.odin +++ b/Power/Power.odin @@ -4,6 +4,7 @@ import "core:c" import sce "../common" foreign import power "system:ScePower_stub" +foreign import powerkern "system:ScePowerForDriver_stub" @(link_prefix = "scePower") foreign power { @@ -237,3 +238,216 @@ foreign power { */ GetUsingWireless :: proc() -> c.int --- } + +foreign powerkern { + /** + * Registers a ScePower Callback + * + * @param cbid - The UID of the specified callback + * + * @return 0 on success, < 0 on error + */ + kscePowerRegisterCallback :: proc(cbid: sce.UID) -> c.int --- + + /** + * Unregister a callback + * + * @param cbid - The UID of the specified callback + * + * @return 0 on success, < 0 on error + */ + kscePowerUnregisterCallback :: proc(cbid: sce.UID) -> c.int --- + + /** + * Returns battery charging status + * + * @return SCE_TRUE if under charge, SCE_FALSE otherwise + */ + kscePowerIsBatteryCharging :: proc() -> sce.Bool --- + + /** + * Returns battery life percentage + * + * @return Battery life percentage + */ + kscePowerGetBatteryLifePercent :: proc() -> c.int --- + + /** + * Check if a suspend is required + * + * @return SCE_TRUE if suspend is required, SCE_FALSE otherwise + */ + kscePowerIsSuspendRequired :: proc() -> sce.Bool --- + + /** + * Check if AC is plugged in + * + * @return SCE_TRUE if plugged in, SCE_FALSE otherwise + */ + kscePowerIsPowerOnline :: proc() -> sce.Bool --- + + /** + * Returns battery life time + * + * @return Battery life time in minutes + */ + kscePowerGetBatteryLifeTime :: proc() -> c.int --- + + /** + * Returns battery remaining capacity + * + * @return battery remaining capacity in mAh (milliampere hour) + */ + kscePowerGetBatteryRemainCapacity :: proc() -> c.int --- + + /** + * Returns battery state + * + * @return SCE_TRUE if battery is low, SCE_FALSE otherwise + */ + kscePowerIsLowBattery :: proc() -> sce.Bool --- + + /** + * Returns battery full capacity + * + * @return battery full capacity in mAh (milliampere hour) + */ + kscePowerGetBatteryFullCapacity :: proc() -> c.int --- + + /** + * Returns battery temperature + * + * @return temperature in degrees celcius * 100 + */ + kscePowerGetBatteryTemp :: proc() -> c.int --- + + /** + * Returns battery voltage + * + * @return battery voltage in mV (millivolts) + */ + kscePowerGetBatteryVolt :: proc() -> c.int --- + + /** + * Returns battery state of health + * + * @return battery state of health percent + */ + kscePowerGetBatterySOH :: proc() -> c.int --- + + /** + * Returns battery cycle count + * + * @return battery cycle count + */ + kscePowerGetBatteryCycleCount :: proc() -> c.int --- + + /** + * Returns CPU clock frequency + * + * @return CPU clock frequency in Mhz + */ + kscePowerGetArmClockFrequency :: proc() -> c.int --- + + /** + * Returns BUS clock frequency + * + * @return BUS clock frequency in Mhz + */ + kscePowerGetBusClockFrequency :: proc() -> c.int --- + + /** + * Returns Sys clock frequency + * + * @return Sys clock frequency in Mhz + */ + kscePowerGetSysClockFrequency :: proc() -> c.int --- + + /** + * Returns GPU crossbar clock frequency + * + * @return GPU crossbar clock frequency in Mhz + */ + kscePowerGetGpuXbarClockFrequency :: proc() -> c.int --- + + /** + * Requests PS Vita to do a soft reset + * + * @return always 0 + */ + kscePowerRequestSoftReset :: proc() -> c.int --- + + /** + * Requests PS Vita to do a cold reset + * + * @return always 0 + */ + kscePowerRequestColdReset :: proc() -> c.int --- + + /** + * Requests PS Vita to go into standby + * + * @return always 0 + */ + kscePowerRequestStandby :: proc() -> c.int --- + + /** + * Requests PS Vita to suspend + * + * @return always 0 + */ + kscePowerRequestSuspend :: proc() -> c.int --- + + /** + * Request display off + * + * @return always 0 + */ + kscePowerRequestDisplayOff :: proc() -> c.int --- + + /** + * Set the screen brightness. + * @see ::sceAVConfigSetDisplayBrightness for userland counterpart. + * + * @param brightness Brightness that the screen will be set to (range 21-65536, 0 turns off the screen). + * + * @return ? + */ + kscePowerSetDisplayBrightness :: proc(brightness: c.int) -> c.int --- + + /** + * Sets CPU clock frequency + * + * @param freq - Frequency to set in Mhz + * + * @return 0 on success, < 0 on error + */ + kscePowerSetArmClockFrequency :: proc(freq: c.int) -> c.int --- + + /** + * Sets BUS clock frequency + * + * @param freq - Frequency to set in Mhz + * + * @return 0 on success, < 0 on error + */ + kscePowerSetBusClockFrequency :: proc(freq: c.int) -> c.int --- + + /** + * Sets GPU clock frequency + * + * @param freq - Frequency to set in Mhz + * + * @return 0 on success, < 0 on error + */ + kscePowerSetGpuClockFrequency :: proc(freq: c.int) -> c.int --- + + /** + * Sets GPU crossbar clock frequency + * + * @param freq - Frequency to set in Mhz + * + * @return 0 on success, < 0 on error + */ + kscePowerSetGpuXbarClockFrequency :: proc(freq: c.int) -> c.int --- +} diff --git a/Power/types.odin b/Power/types.odin index 76c2a1b..1a88c39 100644 --- a/Power/types.odin +++ b/Power/types.odin @@ -3,7 +3,6 @@ package power import "core:c" import sce "../common" -// TODO: ScePowerErrorCode :: enum c.uint { INVALID_VALUE = 0x802B0000, ALREADY_REGISTERED = 0x802B0001, @@ -15,10 +14,10 @@ ScePowerErrorCode :: enum c.uint { #assert(size_of(ScePowerErrorCode) == 4) ScePowerCallbackType :: enum c.uint { - AFTER_SYSTEM_RESUME = 0x00000080, /* TODO: confirm */ + AFTER_SYSTEM_RESUME = 0x00000080, BATTERY_ONLINE = 0x00000100, - THERMAL_SUSPEND = 0x00000200, /* TODO: confirm */ - LOW_BATTERY_SUSPEND = 0x00000400, /* TODO: confirm */ + THERMAL_SUSPEND = 0x00000200, + LOW_BATTERY_SUSPEND = 0x00000400, LOW_BATTERY = 0x00000800, POWER_ONLINE = 0x00001000, SYSTEM_SUSPEND = 0x00010000, @@ -27,7 +26,7 @@ ScePowerCallbackType :: enum c.uint { UNK_0x100000 = 0x00100000, /* Related to proc_event::display_switch */ APP_RESUME = 0x00200000, APP_SUSPEND = 0x00400000, - APP_RESUMING = 0x00800000, /* TODO: confirm */ + APP_RESUMING = 0x00800000, BUTTON_PS_START_PRESS = 0x04000000, BUTTON_PS_POWER_PRESS = 0x08000000, BUTTON_PS_HOLD = 0x10000000, diff --git a/PspnetAdhoc/types.odin b/PspnetAdhoc/types.odin index dd243f9..59bf8b7 100644 --- a/PspnetAdhoc/types.odin +++ b/PspnetAdhoc/types.odin @@ -12,7 +12,6 @@ SCE_NET_ADHOCCTL_GROUPNAME_LEN :: 8 SCE_NET_ADHOCCTL_NICKNAME_LEN :: 128 SCE_NET_ADHOCCTL_BSSID_LEN :: 6 -// TODO: ScePspnetAdhocErrorCode :: enum c.uint { INVALID_SOCKET_ID = 0x80410701, INVALID_ADDR = 0x80410702, @@ -106,7 +105,6 @@ ScePspnetAdhocFlags :: enum c.int { ALERTALL = ALERTSEND | ALERTRECV | ALERTPOLL | ALERTCONNECT | ALERTACCEPT | ALERTFLUSH, } -// TODO: ScePspnetAdhocctlErrorCode :: enum c.uint { INVALID_ARG = 0x80410B04, ALREADY_INITIALIZED = 0x80410B07, diff --git a/README.md b/README.md index 638d113..24116b4 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ [vitasdk](https://github.com/vitasdk/vita-headers) bindings for [Odin](https://orin-lang.org) ### TODO: -- [ ] Json library (not sure how to bind this, might completely skip it) -- [ ] Add Bindings for the `psp2kern` libraries -- [ ] Clean up TODOs and make sure the types used are mostly correct +- [-] Json library (not sure how to bind this, might completely skip it) +- [x] Add Bindings for the `psp2kern` libraries +- [x] Clean up TODOs and make sure the types used are mostly correct #### NOTE: The vita-headers submodule is only there to show which version the bindings currently adhere to. diff --git a/RegistryMgr/RegistryMgr.odin b/RegistryMgr/RegistryMgr.odin index 947c265..ecc14f5 100644 --- a/RegistryMgr/RegistryMgr.odin +++ b/RegistryMgr/RegistryMgr.odin @@ -1,8 +1,10 @@ package registrymgr import "core:c" +import sce "../common" foreign import registrymgr "system:SceRegistryMgr_stub" +foreign import registrymgrkern "system:SceRegMgrForDriver_stub" @(link_prefix = "sceRegMgr") foreign registrymgr { @@ -141,3 +143,75 @@ foreign registrymgr { */ GetRegVersion :: proc(version: c.int, buf: [^]c.char) -> c.int --- } + +foreign registrymgrkern { + /** + * Get a key's information by category and name + * + * @param category - The path to the directory to be opened (e.g. /CONFIG/SYSTEM) + * @param name - Name of the key + * @param buf - Pointer to a buffer to hold the value + * @param size - The size of the buffer + * + * @return 0 on success, < 0 on error + */ + ksceRegMgrGetKeyBin :: proc(category: cstring, name: cstring, buf: rawptr, size: sce.Size) -> c.int --- + + /** + * Get a key's information by category and name + * + * @param category - The path to the directory to be opened (e.g. /CONFIG/SYSTEM) + * @param name - Name of the key + * @param buf - Pointer to a int buffer to hold the value + * + * @return 0 on success, < 0 on error + */ + ksceRegMgrGetKeyInt :: proc(category: cstring, name: cstring, buf: ^c.int) -> c.int --- + + /** + * Get a key's information by category and name + * + * @param category - The path to the directory to be opened (e.g. /CONFIG/SYSTEM) + * @param name - Name of the key + * @param buf - Pointer to a char buffer to hold the value + * @param size - The size of the buffer + * + * @return 0 on success, < 0 on error + */ + ksceRegMgrGetKeyStr :: proc(category: cstring, name: cstring, buf: [^]c.char, size: sce.Size) -> c.int --- + + /** + * Set a key's information by category and name + * + * @param category - The path to the directory to be opened (e.g. /CONFIG/SYSTEM) + * @param name - Name of the key + * @param buf - Pointer to a buffer to hold the value + * @param size - The size of the buffer + * + * @return 0 on success, < 0 on error + */ + ksceRegMgrSetKeyBin :: proc(category: cstring, name: cstring, buf: rawptr, size: sce.Size) -> c.int --- + + /** + * Set a key's information by category and name + * + * @param category - The path to the directory to be opened (e.g. /CONFIG/SYSTEM) + * @param name - Name of the key + * @param buf - Pointer to an int buffer to hold the value + * + * @return 0 on success, < 0 on error + */ + ksceRegMgrSetKeyInt :: proc(category: cstring, name: cstring, buf: c.int) -> c.int --- + + /** + * Set a key's information by category and name + * + * @param category - The path to the directory to be opened (e.g. /CONFIG/SYSTEM) + * @param name - Name of the key + * @param buf - Pointer to a char buffer to hold the value + * @param size - The size of the buffer + * + * @return 0 on success, < 0 on error + */ + ksceRegMgrSetKeyStr :: proc(category: cstring, name: cstring, buf: [^]c.char, size: sce.Size) -> c.int --- +} diff --git a/ScreenShot/types.odin b/ScreenShot/types.odin index f820394..db7c5bf 100644 --- a/ScreenShot/types.odin +++ b/ScreenShot/types.odin @@ -24,7 +24,6 @@ SCE_SCREENSHOT_MAX_GAME_COMMENT_LEN :: (128) //! Max size of comment (description) (includes NUL terminator) SCE_SCREENSHOT_MAX_GAME_COMMENT_SIZE :: (SCE_SCREENSHOT_MAX_GAME_COMMENT_LEN * 4) -// TODO: SceScreenshotErrorCode :: enum c.uint { INVALID_ARGUMENT = 0x80102F01, NO_MEMORY = 0x80102F02, diff --git a/ShutterSound/ShutterSound.odin b/ShutterSound/ShutterSound.odin index 8e6e8c9..32c3915 100644 --- a/ShutterSound/ShutterSound.odin +++ b/ShutterSound/ShutterSound.odin @@ -4,7 +4,6 @@ import "core:c" foreign import shuttersound "system:SceShutterSound_stub" -// TODO: SceShutterSoundErrorCode :: enum c.uint { INVALID_ARGUMENT = 0x80105201, //!< Invalid argument INTERNAL = 0x80105202, //!< Internal error diff --git a/Ssl/Ssl.odin b/Ssl/Ssl.odin index 5d469c4..e0ad5e8 100644 --- a/Ssl/Ssl.odin +++ b/Ssl/Ssl.odin @@ -5,7 +5,6 @@ import sce "../common" foreign import ssl "system:SceSsl_stub" -// TODO: should be c.int SceSslErrorCode :: enum c.uint { BEFORE_INIT = 0x80435001, ALREADY_INITED = 0x80435020, diff --git a/Sysmodule/types.odin b/Sysmodule/types.odin index 21192f0..1daf7e6 100644 --- a/Sysmodule/types.odin +++ b/Sysmodule/types.odin @@ -3,7 +3,6 @@ package sysmodule import "core:c" /** Errorcodes for SceSysmodule */ -// TODO: SceSysmoduleErrorCode :: enum c.uint { LOADED = 0, //!< Module is already loaded ERROR_INVALID_VALUE = 0x805A1000, //!< Invalid value diff --git a/Touch/Touch.odin b/Touch/Touch.odin index 73f21b5..178e172 100644 --- a/Touch/Touch.odin +++ b/Touch/Touch.odin @@ -4,6 +4,7 @@ import "core:c" import sce "../common" foreign import touch "system:SceTouch_stub" +foreign import touchkern "system:SceTouchForDriver_stub" @(link_prefix = "sceTouch") foreign touch { @@ -67,3 +68,15 @@ foreign touch { */ DisableTouchForce :: proc(port: sce.UInt32) -> c.int --- } + +foreign touchkern { + /** + * Set touch enable flag + * + * @param[in] port - The port number. + * @param[in] enable - The enable flag. + * + * @return 0 on success. < 0 on error. + */ + ksceTouchSetEnableFlag :: proc(port: sce.UInt32, enable: sce.Bool) -> c.int --- +} diff --git a/Touch/types.odin b/Touch/types.odin index 8ac5db6..44994c3 100644 --- a/Touch/types.odin +++ b/Touch/types.odin @@ -3,7 +3,7 @@ package touch import "core:c" import sce "../common" -SCE_TOUCH_MAX_REPORT :: 8 //!< FIXME 6 on front | 4 on back +SCE_TOUCH_MAX_REPORT :: 8 /** Touch error codes */ SceTouchErrorCode :: enum c.uint { diff --git a/Udcd/Udcd.odin b/Udcd/Udcd.odin index a327275..f05888f 100644 --- a/Udcd/Udcd.odin +++ b/Udcd/Udcd.odin @@ -4,6 +4,7 @@ import "core:c" import sce "../common" foreign import udcd "system:SceUdcd_stub" +foreign import udcdkern "system:SceUdcdForDriver_stub" @(link_prefix = "sceUdcd") foreign udcd { @@ -63,3 +64,314 @@ foreign udcd { */ WaitState :: proc(waitParam: ^SceUdcdWaitParam, timeout: c.uint) -> c.int --- } + +foreign udcdkern { + /** + * Waits until an UDCD bus is initialized + * + * @param[in] timeout - Timeout + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdWaitBusInitialized :: proc(timeout: c.uint, bus: c.int) -> c.int --- + + /** + * Start a USB driver. + * + * @param driverName - Name of the USB driver to start + * @param size - Size of arguments to pass to USB driver start + * @param args - Arguments to pass to USB driver start + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdStart :: proc(driverName: cstring, size: c.int, args: rawptr) -> c.int --- + + /** + * Start a USB driver for an UDCD bus. + * + * @param driverName - Name of the USB driver to start + * @param size - Size of arguments to pass to USB driver start + * @param args - Arguments to pass to USB driver start + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdStartInternal :: proc(driverName: cstring, size: c.int, args: rawptr, bus: c.int) -> c.int --- + + /** + * Starts the current USB driver for an UDCD bus. + * + * @param[in] unused - Unused + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdStartCurrentInternal :: proc(unused: c.int, bus: c.int) -> c.int --- + + /** + * Stop a USB driver. + * + * @param driverName - Name of the USB driver to stop + * @param size - Size of arguments to pass to USB driver start + * @param args - Arguments to pass to USB driver start + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdStop :: proc(driverName: cstring, size: c.int, args: rawptr) -> c.int --- + + /** + * Stop a USB driver for an UDCD bus. + * + * @param driverName - Name of the USB driver to stop + * @param size - Size of arguments to pass to USB driver start + * @param args - Arguments to pass to USB driver start + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdStopInternal :: proc(driverName: cstring, size: c.int, args: rawptr, bus: c.int) -> c.int --- + + /** + * Stops the current USB driver for an UDCD bus. + * + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdStopCurrentInternal :: proc(bus: c.int) -> c.int --- + + /** + * Activate a USB driver. + * + * @param pid - Product ID for the default USB Driver + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdActivate :: proc(productId: c.uint) -> c.int --- + + /** + * Activate a USB driver for an UDCD bus. + * + * @param pid - Product ID for the default USB Driver + * @param[in] bus_powered - Enable USB bus power + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdActivateInternal :: proc(productId: c.uint, bus_powered: c.uint, bus: c.int) -> c.int --- + + /** + * Deactivate USB driver. + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdDeactivate :: proc() -> c.int --- + + /** + * Deactivate USB driver for an UDCD bus. + * + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdDeactivateInternal :: proc(bus: c.int) -> c.int --- + + /** + * Get USB state + * + * @return One or more ::SceUdcdStatus. + */ + ksceUdcdGetDeviceState :: proc() -> c.int --- + + /** + * Get USB state for an UDCD bus + * + * @param[in] bus - UDCD bus (default is 2) + * + * @return One or more ::SceUdcdStatus. + */ + ksceUdcdGetDeviceStateInternal :: proc(bus: c.int) -> c.int --- + + /** + * Get device information + * + * @param[out] devInfo - Device information + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdGetDeviceInfo :: proc(devInfo: ^SceUdcdDeviceInfo) -> c.int --- + + /** + * Get device information for an UDCD bus + * + * @param[out] devInfo - Device information + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdGetDeviceInfoInternal :: proc(devInfo: ^SceUdcdDeviceInfo, bus: c.int) -> c.int --- + + /** + * Get state of a specific USB driver + * + * @param driverName - name of USB driver to get status from + * + * @return SCE_UDCD_STATUS_DRIVER_STARTED if the driver has been started, SCE_UDCD_STATUS_DRIVER_REGISTERED if it is stopped + */ + ksceUdcdGetDrvState :: proc(driverName: cstring) -> c.int --- + + /** + * Get state of a specific USB driver for an UDCD bus + * + * @param driverName - name of USB driver to get status from + * @param[in] bus - UDCD bus (default is 2) + * + * @return SCE_UDCD_STATUS_DRIVER_STARTED if the driver has been started, SCE_UDCD_STATUS_DRIVER_REGISTERED if it is stopped + */ + ksceUdcdGetDrvStateInternal :: proc(driverName: cstring, bus: c.int) -> c.int --- + + /** + * Wait for state + * + * @param[in] waitParam - Wait parameter + * @param[in] timeout - Timeout + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdWaitState :: proc(waitParam: ^SceUdcdWaitParam, timeout: c.uint) -> c.int --- + + /** + * Wait for state for an UDCD bus + * + * @param[in] waitParam - Wait parameter + * @param[in] timeout - Timeout + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error. + */ + ksceUdcdWaitStateInternal :: proc(waitParam: ^SceUdcdWaitParam, timeout: c.uint, bus: c.int) -> c.int --- + + /** + * Register a USB driver. + * + * @param drv - Pointer to a filled out USB driver + * + * @return 0 on success, < 0 on error + */ + ksceUdcdRegister :: proc(drv: ^SceUdcdDriver) -> c.int --- + + /** + * Register a USB driver to a specific USB bus. + * + * @param drv - Pointer to a filled out USB driver + * @param bus - The USB bus index (usually 2) + * + * @return 0 on success, < 0 on error + */ + ksceUdcdRegisterInternal :: proc(drv: ^SceUdcdDriver, bus: c.int) -> c.int --- + + /** + * Unregister a USB driver + * + * @param drv - Pointer to a filled out USB driver + * + * @return 0 on success, < 0 on error + */ + ksceUdcdUnregister :: proc(drv: ^SceUdcdDriver) -> c.int --- + + /** + * Unregister a USB driver for an UDCD bus + * + * @param drv - Pointer to a filled out USB driver + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error + */ + ksceUdcdUnregisterInternal :: proc(drv: ^SceUdcdDriver, bus: c.int) -> c.int --- + + /** + * Clear the FIFO on an endpoint + * + * @param endp - The endpoint to clear + * + * @return 0 on success, < 0 on error + */ + ksceUdcdClearFIFO :: proc(endp: ^SceUdcdEndpoint) -> c.int --- + + /** + * Clear the FIFO on an endpoint for an UDCD bus + * + * @param endp - The endpoint to clear + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error + */ + ksceUdcdClearFIFOInternal :: proc(endp: ^SceUdcdEndpoint, bus: c.int) -> c.int --- + + /** + * Cancel any pending requests on an endpoint. + * + * @param endp - The endpoint to cancel + * + * @return 0 on success, < 0 on error + */ + ksceUdcdReqCancelAll :: proc(endp: ^SceUdcdEndpoint) -> c.int --- + + /** + * Stall an endpoint + * + * @param endp - The endpoint to stall + * + * @return 0 on success, < 0 on error + */ + ksceUdcdStall :: proc(endp: ^SceUdcdEndpoint) -> c.int --- + + /** + * Stall an endpoint for an UDCD bus + * + * @param endp - The endpoint to stall + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error + */ + ksceUdcdStallInternal :: proc(endp: ^SceUdcdEndpoint, bus: c.int) -> c.int --- + + /** + * Queue a send request (IN from host pov) + * + * @param req - Pointer to a filled out ::SceUdcdDeviceRequest structure. + * + * @return 0 on success, < 0 on error + */ + ksceUdcdReqSend :: proc(req: ^SceUdcdDeviceRequest) -> c.int --- + + /** + * Queue a send request (IN from host pov) for an UDCD bus + * + * @param req - Pointer to a filled out ::SceUdcdDeviceRequest structure. + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error + */ + ksceUdcdReqSendInternal :: proc(req: ^SceUdcdDeviceRequest, bus: c.int) -> c.int --- + + /** + * Queue a receive request (OUT from host pov) + * + * @param req - Pointer to a filled out ::SceUdcdDeviceRequest structure + * + * @return 0 on success, < 0 on error + */ + ksceUdcdReqRecv :: proc(req: ^SceUdcdDeviceRequest) -> c.int --- + + /** + * Queue a receive request (OUT from host pov) for an UDCD bus + * + * @param req - Pointer to a filled out ::SceUdcdDeviceRequest structure + * @param[in] bus - UDCD bus (default is 2) + * + * @return 0 on success, < 0 on error + */ + ksceUdcdReqRecvInternal :: proc(req: ^SceUdcdDeviceRequest, bus: c.int) -> c.int --- +} diff --git a/Udcd/types.odin b/Udcd/types.odin index 50cbc10..87724b1 100644 --- a/Udcd/types.odin +++ b/Udcd/types.odin @@ -46,3 +46,361 @@ SceUdcdDeviceState :: struct { } #assert(size_of(SceUdcdDeviceState) == 0x18) + +/** Enumeration for Device and/or Interface Class codes + */ +SceUdcdUsbClass :: enum c.int { + PER_INTERFACE = 0x00, //!< for DeviceClass + AUDIO = 0x01, + COMM = 0x02, + HID = 0x03, + PTP = 0x06, + PRINTER = 0x07, + MASS_STORAGE = 0x08, + HUB = 0x09, + DATA = 0x0A, + VIDEO = 0x0E, + VENDOR_SPEC = 0xFF +} + +/** Enumeration for descriptor types + */ +SceUdcdUsbDt :: enum c.int { + DEVICE = 0x01, + CONFIG = 0x02, + STRING = 0x03, + INTERFACE = 0x04, + ENDPOINT = 0x05 +} + +/** Enumeration for standard requests + */ +SceUdcdUsbReq :: enum c.int { + GET_STATUS = 0x00, + CLEAR_FEATURE = 0x01, + SET_FEATURE = 0x03, + SET_ADDRESS = 0x05, + GET_DESCRIPTOR = 0x06, + SET_DESCRIPTOR = 0x07, + GET_CONFIG = 0x08, + SET_CONFIG = 0x09, + GET_INTERFACE = 0x0A, + SET_INTERFACE = 0x0B, + SYNC_FRAME = 0x0C +} + +/** + * Descriptor sizes per descriptor type + */ +USB_DT_DEVICE_SIZE :: 18 +USB_DT_CONFIG_SIZE :: 9 +USB_DT_INTERFACE_SIZE :: 9 +USB_DT_ENDPOINT_SIZE :: 7 +USB_DT_ENDPOINT_AUDIO_SIZE :: 9 //!< Audio extension +USB_DT_HUB_NONVAR_SIZE :: 7 + +/** Control message request type bitmask + */ +USB_CTRLTYPE_DIR_MASK :: 0x80 +USB_CTRLTYPE_DIR_HOST2DEVICE :: (0 << 7) +USB_CTRLTYPE_DIR_DEVICE2HOST :: (1 << 7) +USB_CTRLTYPE_TYPE_MASK :: 0x60 +USB_CTRLTYPE_TYPE_STANDARD :: (0 << 5) +USB_CTRLTYPE_TYPE_CLASS :: (1 << 5) +USB_CTRLTYPE_TYPE_VENDOR :: (2 << 5) +USB_CTRLTYPE_TYPE_RESERVED :: (3 << 5) +USB_CTRLTYPE_REC_MASK :: 0x1f +USB_CTRLTYPE_REC_DEVICE :: 0 +USB_CTRLTYPE_REC_INTERFACE :: 1 +USB_CTRLTYPE_REC_ENDPOINT :: 2 +USB_CTRLTYPE_REC_OTHER :: 3 + +/** Endpoint types and masks + */ +USB_ENDPOINT_ADDRESS_MASK :: 0x0f /* in bEndpointAddress */ +USB_ENDPOINT_DIR_MASK :: 0x80 + +USB_FEATURE_ENDPOINT_HALT :: 0 + +USB_ENDPOINT_IN :: 0x80 +USB_ENDPOINT_OUT :: 0x00 + +USB_ENDPOINT_TYPE_MASK :: 0x03 /* in bmAttributes */ +USB_ENDPOINT_TYPE_CONTROL :: 0 +USB_ENDPOINT_TYPE_ISOCHRONOUS :: 1 +USB_ENDPOINT_TYPE_BULK :: 2 +USB_ENDPOINT_TYPE_INTERRUPT :: 3 + +/* HID constants. Not part of chapter 9 */ + +/** Class-Specific Requests + */ +SceUdcdHidRequest :: enum c.int { + GET_REPORT = 0x01, + GET_IDLE = 0x02, + GET_PROTOCOL = 0x03, + SET_REPORT = 0x09, + SET_IDLE = 0x0A, + SET_PROTOCOL = 0x0B +} + +/** Class Descriptor Types + */ +SceUdcdHidDescriptor :: enum c.int { + HID = 0x21, + REPORT = 0x22, + PHY = 0x23 +} + +/** Protocol Selection + */ +SceUdcdProtocol :: enum c.int { + BOOT_PROTOCOL = 0x00, + RPT_PROTOCOL = 0x01 +} + +/** HID Interface Class Code + */ +HID_INTF :: 0x03 + +/** HID Interface Class SubClass Codes + */ +BOOT_INTF_SUBCLASS :: 0x01 + +/** HID Interface Class Protocol Codes + */ +SceUdcdHidProtocol :: enum c.int { + NONE = 0x00, + KEYBOARD = 0x01, + MOUSE = 0x02 +} + +/** USB limits + */ +SCE_UDCD_MAX_INTERFACES :: 8 +SCE_UDCD_MAX_ENDPOINTS :: 9 +SCE_UDCD_MAX_ALTERNATE :: 2 + +SceUdcdRetcode :: enum c.int { + CANCEL = -1, + CANCEL_ALL = -2, + CANCEL_TRANSMISSION = -3, + SUCCESS = 0, + SEND = 1, + RECV = 2 +} + +/** Error codes + */ +SceUdcdErrorCode :: enum c.uint { + ILLEGAL_CONTEXT = 0x80000030, + INVALID_POINTER = 0x80000103, + INVALID_FLAG = 0x80000105, + INVALID_VALUE = 0x800001FE, + ALREADY_DONE = 0x80243001, + INVALID_ARGUMENT = 0x80243002, + ARGUMENT_EXCEEDED_LIMIT = 0x80243003, + MEMORY_EXHAUSTED = 0x80243004, + DRIVER_NOT_FOUND = 0x80243005, + DRIVER_IN_PROGRESS = 0x80243006, + BUS_DRIVER_NOT_STARTED = 0x80243007, + WAIT_TIMEOUT = 0x80243008, + WAIT_CANCEL = 0x80243009, + USBDRIVER_INVALID_DRIVER = 0x80243200, + USBDRIVER_INVALID_NAME = 0x80243201, + USBDRIVER_INVALID_FUNCS = 0x80243202 +} + +/** SceUdcdDeviceRequest Flags + */ +SceUdcdDeviceRequestAttr :: enum c.int { + PHYCONT = 0x00000001 +} + +/** USB string descriptor + */ +SceUdcdStringDescriptor :: struct { + bLength: c.uchar, + bDescriptorType: c.uchar, + bString: [31]c.short, +} +#assert(size_of(SceUdcdStringDescriptor) == 0x40) + +/** USB device descriptor + */ +SceUdcdDeviceDescriptor :: struct #align(4) { + bLength: c.uchar, + bDescriptorType: c.uchar, + bcdUSB: c.ushort, + bDeviceClass: c.uchar, + bDeviceSubClass: c.uchar, + bDeviceProtocol: c.uchar, + bMaxPacketSize0: c.uchar, + idVendor: c.ushort, + idProduct: c.ushort, + bcdDevice: c.ushort, + iManufacturer: c.uchar, + iProduct: c.uchar, + iSerialNumber: c.uchar, + bNumConfigurations: c.uchar, +} +#assert(size_of(SceUdcdDeviceDescriptor) == 0x14) + +/** USB device qualifier descriptor + */ +SceUdcdDeviceQualifierDescriptor :: struct #align(4) { + bLength: c.uchar, + bDescriptorType: c.uchar, + bcdUSB: c.ushort, + bDeviceClass: c.uchar, + bDeviceSubClass: c.uchar, + bDeviceProtocol: c.uchar, + bMaxPacketSize0: c.uchar, + bNumConfigurations: c.uchar, + bReserved: c.uchar, +} +#assert(size_of(SceUdcdDeviceQualifierDescriptor) == 0xC) + +/** USB configuration descriptor + */ +SceUdcdConfigDescriptor :: struct { + bLength: c.uchar, + bDescriptorType: c.uchar, + wTotalLength: c.ushort, + bNumInterfaces: c.uchar, + bConfigurationValue: c.uchar, + iConfiguration: c.uchar, + bmAttributes: c.uchar, + bMaxPower: c.uchar, + settings: ^SceUdcdInterfaceSettings, + extra: [^]c.char, //!< Extra descriptors + extraLength: c.int, +} + +/** USB driver interfaces structure + */ +SceUdcdInterfaceSettings :: struct { + descriptors: [^]SceUdcdInterfaceDescriptor, //!< Pointers to the individual interface descriptors + alternateSetting: c.uint, + numDescriptors: c.uint, //!< Number of interface descriptors +} + +/** USB Interface descriptor + */ +SceUdcdInterfaceDescriptor :: struct { + bLength: c.uchar, + bDescriptorType: c.uchar, + bInterfaceNumber: c.uchar, + bAlternateSetting: c.uchar, + bNumEndpoints: c.uchar, + bInterfaceClass: c.uchar, + bInterfaceSubClass: c.uchar, + bInterfaceProtocol: c.uchar, + iInterface: c.uchar, + endpoints: [^]SceUdcdEndpointDescriptor, + extra: [^]c.char, //!< Extra descriptors + extraLength: c.int, +} + +/** USB endpoint descriptor + */ +SceUdcdEndpointDescriptor :: struct { + bLength: c.uchar, + bDescriptorType: c.uchar, + bEndpointAddress: c.uchar, + bmAttributes: c.uchar, + wMaxPacketSize: c.ushort, + bInterval: c.uchar, + extra: [^]c.char, //!< Extra descriptors + extraLength: c.int, +} + +/** USB driver interface + */ +SceUdcdInterface :: struct { + expectNumber: c.int, //!< Expectant interface number (interface number or -1) + interfaceNumber: c.int, //!< End interface + numInterfaces: c.int, //!< Number of interfaces +} +#assert(size_of(SceUdcdInterface) == 0xC) + +/** USB driver endpoint + */ +SceUdcdEndpoint :: struct { + direction: c.int, //!< USB_ENDPOINT_IN / USB_ENDPOINT_OUT + driverEndpointNumber: c.int, //!< Driver Endpoint number (must be filled in sequentially) + endpointNumber: c.int, //!< Endpoint number (Filled in by the bus driver) + transmittedBytes: c.int, //!< Number of transmitted bytes +} +#assert(size_of(SceUdcdEndpoint) == 0x10) + +/** USB driver configuration + */ +SceUdcdConfiguration :: struct { + configDescriptors: ^SceUdcdConfigDescriptor, //!< Pointer to the configuration descriptors + settings: ^SceUdcdInterfaceSettings, //!< USB driver interface settings + interfaceDescriptors: ^SceUdcdInterfaceDescriptor, //!< Pointer to the first interface descriptor + endpointDescriptors: ^SceUdcdEndpointDescriptor, //!< Pointer to the first endpoint descriptor +} + +/** USB EP0 Device Request + */ +SceUdcdEP0DeviceRequest :: struct { + bmRequestType: c.uchar, + bRequest: c.uchar, + wValue: c.ushort, + wIndex: c.ushort, + wLength: c.ushort, +} +#assert(size_of(SceUdcdEP0DeviceRequest) == 8) + +/** USB driver structure + */ +SceUdcdDriver :: struct { + driverName: cstring, //!< Name of the USB driver + numEndpoints: c.int, //!< Number of endpoints in this driver (including default control) + endpoints: ^SceUdcdEndpoint, //!< List of endpoint structures (used when calling other functions) + interface: ^SceUdcdInterface, //!< Interface list + descriptor_hi: ^SceUdcdDeviceDescriptor, //!< Pointer to hi-speed device descriptor + configuration_hi: ^SceUdcdConfiguration, //!< Pointer to hi-speed device configuration + descriptor: ^SceUdcdDeviceDescriptor, //!< Pointer to full-speed device descriptor + configuration: ^SceUdcdConfiguration, //!< Pointer to full-speed device configuration + stringDescriptors: ^SceUdcdStringDescriptor, //!< Default string descriptors + stringDescriptorProduct: ^SceUdcdStringDescriptor, //!< Product string descriptor (iProduct has to be 2) + stringDescriptorSerial: ^SceUdcdStringDescriptor, //!< Serial string descriptor (iSerial has to be 3) + processRequest: #type ^proc "c" (recipient: c.int, arg: c.int, req: ^SceUdcdEP0DeviceRequest, user_data: rawptr) -> c.int,//!< Received a control request + changeSetting: #type ^proc "c" (interfaceNumber: c.int, alternateSetting: c.int, bus: c.int) -> c.int,//!< Change alternate setting + attach: #type ^proc "c" (usb_version: c.int, user_data: rawptr) -> c.int,//!< Configuration set (attach) function + detach: #type ^proc "c" (user_data: rawptr),//!< Configuration unset (detach) function + configure: #type ^proc "c" (usb_version: c.int, desc_count: c.int, settings: ^SceUdcdInterfaceSettings, user_data: rawptr), //!< Configure the device + start: #type ^proc "c" (size: c.int, args: rawptr, user_data: rawptr) -> c.int, //!< Function called when the driver is started + stop: #type ^proc "c" (size: c.int, args: rawptr, user_data: rawptr) -> c.int,//!< Function called when the driver is stopped + user_data: rawptr, //!< User data + bus: c.int, //!< USB bus + link: ^SceUdcdDriver, //!< Link to next USB driver in the chain, set to NULL +} + +/** USB device request + */ +SceUdcdDeviceRequest :: struct { + endpoint: ^SceUdcdEndpoint, //!< Pointer to the endpoint to queue request on + data: rawptr, //!< Pointer to the data buffer to use in the request + attributes: c.uint, //!< Request attributes (See ::SceUdcdDeviceRequestAttr) + size: c.int, //!< Size of the data buffer + isControlRequest: c.int, //!< Is a control request? + onComplete: #type ^proc "c" (req: ^SceUdcdDeviceRequest), //!< Pointer to the function to call on completion + transmitted: c.int, //!< Number of transmitted bytes + returnCode: c.int, //!< Return code of the request (See ::SceUdcdRetcode) + next: ^SceUdcdDeviceRequest, //!< Link pointer to next request used by the driver, set it to NULL + unused: rawptr, //!< An unused value (maybe an argument) + physicalAddress: rawptr, //!< Physical address +} + +/** USB driver name + */ +SceUdcdDriverName :: struct #align(16) { + size: c.int, + name: [32]c.char, + flags: c.int, +} + diff --git a/UsbAudioIn/types.odin b/UsbAudioIn/types.odin index 34298b3..d7012c4 100644 --- a/UsbAudioIn/types.odin +++ b/UsbAudioIn/types.odin @@ -3,7 +3,6 @@ package usbaudioin import "core:c" import sce "../common" -// TODO: SceUsbAudioInErrorCode :: enum c.uint { INVALID_ARGUMENT = 0x803e0001, DUPLICATE_ID = 0x803e0002, diff --git a/UsbSerial/UsbSerial.odin b/UsbSerial/UsbSerial.odin index cbcdeea..a1464b3 100644 --- a/UsbSerial/UsbSerial.odin +++ b/UsbSerial/UsbSerial.odin @@ -1,8 +1,10 @@ package usbserial import "core:c" +import sce "../common" foreign import usbserial "system:SceUsbSerial_stub" +foreign import usbserialkern "system:SceUsbSerialForDriver_stub" @(link_prefix = "sceUsbSerial") foreign usbserial { @@ -76,3 +78,64 @@ foreign usbserial { */ Recv :: proc(buffer: rawptr, max_len: c.uint, unk1: c.int, unk2: c.int) -> c.uint --- } + +foreign usbserialkern { + /** + * Activate USB serial device + * + * @return 0 on success, < 0 on error + * + * @note The user is responsible for making sure no other UDC driver is active. This activates UDC as a "PS Vita" Type D device. + */ + ksceUsbSerialStart :: proc() -> c.int --- + + /** + * Setup USB serial device + * + * @return 0 on success, < 0 on error + * + * @param unk Unknown + */ + ksceUsbSerialSetup :: proc(unk: c.int) -> c.int --- + + /** + * Get USB device status + * + * @return Returns 1 when serial port is open + */ + ksceUsbSerialStatus :: proc() -> c.int --- + + /** + * Close USB serial device + */ + ksceUsbSerialClose :: proc() -> c.int --- + + /** + * Get receive buffer length + * + * @return Returns length of USB rx buffer + */ + ksceUsbSerialGetRecvBufferSize :: proc() -> c.uint --- + + /** + * Send data + * + * @param[in] *buffer data to send over usb + * @param[in] len int len of serial buffer data + * @param unk1 Unknown + * @param unk2 Unknown + * @note max send length is 0x10000 + */ + ksceUsbSerialSend :: proc(buffer: rawptr, len: sce.Size, unk1: c.int, unk2: c.int) -> sce.Size --- + + /** + * Receive Data + * + * @param[out] *buffer buffer for incoming data + * @param[in] max_len max data length to receive + * @param unk1 Unknown + * @param unk2 Unknown + * @note max recv length is 0x10000 + */ + ksceUsbSerialRecv :: proc(buffer: rawptr, max_len: sce.Size, unk1: c.int, unk2: c.int) -> sce.Size --- +} diff --git a/UsbServ/UsbServ.odin b/UsbServ/UsbServ.odin index 79e0682..ac5c861 100644 --- a/UsbServ/UsbServ.odin +++ b/UsbServ/UsbServ.odin @@ -1,10 +1,11 @@ package usbserv import "core:c" +import sce "../common" foreign import usbserv "system:SceUsbServ_stub" +foreign import usbservkern "system:SceUsbServForDriver_stub" -// TODO: SceUsbservErrorCode :: enum c.uint { UNAVAILABLE = 0x80248002, INVALID_PARAM = 0x80248003, @@ -30,3 +31,73 @@ foreign usbserv { */ AccessoryDeactivate :: proc() -> c.int --- } + +foreign usbservkern { + /** + * Enable PSTV ethernet + * + * @return 0 on success, < 0 on error + * + * @note NID 0x30AE5F66 + */ + ksceUsbServEtherEnable :: proc() -> c.int --- + + /** + * Disable PSTV ethernet + * + * @return 0 on success, < 0 on error + * + * @note NID 0xD787B191 + */ + ksceUsbServEtherDisable :: proc() -> c.int --- + + /** + * Enable accessory port + * + * @return 0 on success, < 0 on error + * + * @note NID 0xAA6D4409 + */ + ksceUsbServAccessoryActivate :: proc() -> c.int --- + + /** + * Disable accessory port + * + * @return 0 on success, < 0 on error + * + * @note NID 0x853CB8E4 + */ + ksceUsbServAccessoryDeactivate :: proc() -> c.int --- + + /** + * Set USB port mode + * + * @return 0 on success, < 0 on error + * + * @param usbPort usb port number (0,1,2) + * @param clientMode 0 = host mode, 1 = client mode + * + * @note NID 0x7AD36284 + */ + ksceUsbServMacSelect :: proc(usbPort: sce.UInt, clientMode: sce.Bool) -> c.int --- + + /** + * Get USB port mode + * + * @return usb port mode (1 = client, 0 = host) + * + * @param usbPort usb port number (0,1,2) + * + * @note NID 0xF0553A69 + */ + ksceUsbServMacGet :: proc(usbPort: sce.UInt) -> sce.Bool --- + + /** + * Prevent PSTV ethernet hibernation + * + * @return 0 on success, < 0 on error + * + * @note NID 0x6D738018, guessed name + */ + ksceUsbServDisableEtherSuspend :: proc() -> c.int --- +} diff --git a/Usbd/Usbd.odin b/Usbd/Usbd.odin index 22f2b15..c8df129 100644 --- a/Usbd/Usbd.odin +++ b/Usbd/Usbd.odin @@ -4,6 +4,7 @@ import "core:c" import sce "../common" foreign import usbd "system:SceUsbd_stub" +foreign import usbdkern "system:SceUsbdForDriver_stub" @(link_prefix = "sceUsbd") foreign usbd { @@ -277,3 +278,183 @@ foreign usbd { */ AttachCompositeLdd :: proc(uid: sce.UID, param: ^SceUsbdAttachCompositeParam) -> c.int --- } + +foreign usbdkern { + /** + * Register USB driver + * + * @return 0 on success, < 0 on error + * + * @param driver driver struct + * + */ + ksceUsbdRegisterDriver :: proc(#by_ptr driver: SceUsbdDriver) -> c.int --- + + /** + * Register USB driver for composite devices + * + * @return 0 on success, < 0 on error + * + * @param driver driver struct + * + */ + ksceUsbdRegisterCompositeLdd :: proc(#by_ptr driver: SceUsbdCompositeDriver) -> c.int --- + + /** + * De-register USB driver + * + * @return 0 on success, < 0 on error + * + * @param driver driver struct + * + */ + ksceUsbdUnregisterDriver :: proc(#by_ptr driver: SceUsbdDriver) -> c.int --- + + /** + * De-register USB driver for composite devices + * + * @return 0 on success, < 0 on error + * + * @param driver driver struct + * + */ + ksceUsbdUnregisterCompositeLdd :: proc(#by_ptr driver: SceUsbdCompositeDriver) -> c.int --- + + + /** + * Return usb descriptor + * + * @return descriptor data on success, NULL on error + * + * @param device_id device id + * @param start pointer to descriptor to start scanning from (may be NULL) + * @param type descriptor type + * + */ + ksceUsbdScanStaticDescriptor :: proc(device_id: sce.UID, start: rawptr, type: SceUsbdDescriptorType) -> rawptr --- + + /** + * Open communication pipe to endpoint + * + * @return pipe uid on success, < 0 on error + * + * @param device_id device id + * @param endpoint endpoint (may be null for default configuration endpoint) + * + */ + ksceUsbdOpenPipe :: proc(device_id: c.int, endpoint: ^SceUsbdEndpointDescriptor) -> sce.UID --- + + /** + * Close communication pipe to endpoint + * + * @return 0 on success, < 0 on error + * + * @param pipe_id pipe id + * + */ + ksceUsbdClosePipe :: proc(pipe_id: sce.UID) -> c.int --- + + /** + * Transfer data to/from endpoint + * + * @return 0 on success, < 0 on error + * + * @param pipe_id pipe id + * @param req transfer request + * @param buffer data + * @param cb transfer callback + * @param user_data userdata to pass to callback + * + */ + ksceUsbdControlTransfer :: proc(pipe_id: sce.UID, #by_ptr req: SceUsbdDeviceRequest, buffer: [^]c.uchar, cb: ksceUsbdDoneCallback, user_data: rawptr) -> c.int --- + + /** + * Transfer data to/from interrupt endpoint + * + * @return 0 on success, < 0 on error + * + * @param pipe_id pipe id + * @param buffer data + * @param length data length + * @param cb transfer callback + * @param user_data userdata to pass to callback + * + */ + ksceUsbdInterruptTransfer :: proc(pipe_id: sce.UID, buffer: [^]c.uchar, length: sce.Size, cb: ksceUsbdDoneCallback, user_data: rawptr) -> c.int --- + + /** + * Transfer isochronous data to/from endpoint + * + * @return 0 on success, < 0 on error + * + * @param pipe_id pipe id + * @param transfer transfer request + * @param cb transfer callback + * @param user_data userdata to pass to callback + * + */ + ksceUsbdIsochronousTransfer :: proc(pipe_id: sce.UID, transfer: ^ksceUsbdIsochTransfer, cb: ksceUsbdIsochDoneCallback, user_data: rawptr) -> c.int --- + + /** + * Transfer data to/from endpoint + * + * @return 0 on success, < 0 on error + * + * @param pipe_id pipe id + * @param buffer data + * @param length data length + * @param cb transfer callback + * @param user_data userdata to pass to callback + * + * @note buffer pointer must be 64b aligned + */ + ksceUsbdBulkTransfer :: proc(pipe_id: sce.UID, buffer: [^]c.uchar, length: c.uint, cb: ksceUsbdDoneCallback, user_data: rawptr) -> c.int --- + + /** + * Transfer data to/from endpoint + * + * @return 0 on success, < 0 on error + * + * @param pipe_id pipe id + * @param buffer data + * @param length data length + * @param cb transfer callback + * @param user_data userdata to pass to callback + * + * @note buffer pointer must be 64b aligned + */ + ksceUsbdBulkTransfer2 :: proc(pipe_id: c.int, buffer: [^]c.uchar, length: c.uint, cb: ksceUsbdDoneCallback, user_data: rawptr) -> c.int --- + + + /** + * Get device location + * + * @return 0 on success, < 0 on error + * + * @param device_id device id + * @param[out] location device location data (port) + * + */ + ksceUsbdGetDeviceLocation :: proc(device_id: sce.UID, location: ^c.uint8_t) -> c.int --- + + ksceUsbdSuspend :: proc(port: c.int) -> c.int --- + ksceUsbdSuspendPhase2 :: proc(port: c.int, flag: c.int) -> c.int --- + ksceUsbdResume :: proc(port: c.int) -> c.int --- + + ksceUsbdHostStop :: proc(port: c.int) -> c.int --- + ksceUsbdHostStart :: proc(port: c.int) -> c.int --- + + /** + * Get device speed + * + * @return 0 on success, < 0 on error + * + * @param device_id device id + * @param[out] speed device speed + * + */ + ksceUsbdGetDeviceSpeed :: proc(device_id: c.int, speed: ^c.uint8_t) -> c.int --- + + ksceUsbd_05073925 :: proc(device_id: sce.UID, unk1: ^c.int, unk2: ^c.int) -> c.int --- + ksceUsbd_7938DAC7 :: proc(pipe_id: sce.UID) -> c.int --- // clear halt? +} diff --git a/Usbd/types.odin b/Usbd/types.odin index d4b5e54..b42c392 100644 --- a/Usbd/types.odin +++ b/Usbd/types.odin @@ -52,7 +52,6 @@ SCE_USBD_DEVICE_SPEED_LS :: 0 SCE_USBD_DEVICE_SPEED_FS :: 1 SCE_USBD_DEVICE_SPEED_HS :: 2 -// TODO: SceUsbdErrorCode :: enum c.uint { ERROR_NOT_INITIALIZED = 0x80240001, ERROR_ALREADY_INITIALIZED = 0x80240002, @@ -241,3 +240,118 @@ SceUsbdIsochTransferStatus :: struct { unk2: ^c.uintptr_t, // ret up to 0x28 buff. 10 * 4 bytes. or 8*5 bytes unk3: c.uint32_t, // ret 4. ptr? } + +SCE_USBD_PROBE_SUCCEEDED :: (0) +SCE_USBD_PROBE_FAILED :: (-1) +SCE_USBD_ATTACH_SUCCEEDED :: (0) +SCE_USBD_ATTACH_FAILED :: (-1) +SCE_USBD_DETACH_SUCCEEDED :: (0) +SCE_USBD_DETACH_FAILED :: (-1) + +SCE_USBD_MAX_LS_CONTROL_PACKET_SIZE :: 8 +SCE_USBD_MAX_FS_CONTROL_PACKET_SIZE :: 64 +SCE_USBD_MAX_ISOCHRONOUS_PACKET_SIZE :: 1023 +SCE_USBD_MAX_LS_INTERRUPT_PACKET_SIZE :: 8 +SCE_USBD_MAX_FS_INTERRUPT_PACKET_SIZE :: 64 +SCE_USBD_MAX_BULK_PACKET_SIZE :: 64 + +SCE_USBD_FEATURE_ENDPOINT_HALT :: 0x00 +SCE_USBD_FEATURE_DEVICE_REMOTE_WAKEUP :: 0x01 + +SceUsbdDriver :: struct { + name: cstring, + probe: #type ^proc "c" (device_id: c.int) -> c.int, + attach: #type ^proc "c" (device_id: c.int) -> c.int, + detach: #type ^proc "c" (device_id: c.int) -> c.int, +} + +SceUsbdCompositeDriver :: struct { + name: cstring, + probe: #type ^proc "c" (device_id: c.int, desc: ^SceUsbdEndpointDescriptor) -> c.int, // endpoint descriptor should be interface one + attach: #type ^proc "c" (device_id: c.int) -> c.int, + detach: #type ^proc "c" (device_id: c.int) -> c.int, +} + +SceUsbdDeviceRequest :: struct { + bmRequestType: c.uint8_t, + bRequest: c.uint8_t, + wValue: c.uint16_t, + wIndex: c.uint16_t, + wLength: c.uint16_t, +} +#assert(size_of(SceUsbdDeviceRequest) == 8) + +SceUsbdReqtype :: enum c.int { + DIR_BITS = 0x80, + DIR_TO_DEVICE = 0x00, + DIR_TO_HOST = 0x80, + TYPE_BITS = 0x60, + TYPE_STANDARD = 0x00, + TYPE_CLASS = 0x20, + TYPE_VENDOR = 0x40, + TYPE_RESERVED = 0x60, + RECIP_BITS = 0x1f, + RECIP_DEVICE = 0x00, + RECIP_INTERFACE = 0x01, + RECIP_ENDPOINT = 0x02, + RECIP_OTHER = 0x03, +} + +SceUsbdRequest :: enum c.int { + GET_STATUS = 0x00, + CLEAR_FEATURE = 0x01, + SET_FEATURE = 0x03, + SET_ADDRESS = 0x05, + GET_DESCRIPTOR = 0x06, + SET_DESCRIPTOR = 0x07, + GET_CONFIGURATION = 0x08, + SET_CONFIGURATION = 0x09, + GET_INTERFACE = 0x0a, + SET_INTERFACE = 0x0b, + SYNCH_FRAME = 0x0c +} + +ksceUsbdIsochPswLen :: bit_field c.uint16_t { + len: c.uint16_t | 12, + PSW: c.uint16_t | 4, +} +#assert(size_of(ksceUsbdIsochPswLen) == 2) + +ksceUsbdIsochTransfer :: struct { + buffer_base: rawptr, + relative_start_frame: c.int32_t, + num_packets: c.int32_t, + packets: [8]ksceUsbdIsochPswLen, +} + +ksceUsbdDoneCallback :: #type ^proc "c" (result: c.int32_t, count: c.int32_t, arg: rawptr) +ksceUsbdIsochDoneCallback :: #type ^proc "c" (result: c.int32_t, req: ^ksceUsbdIsochTransfer, arg: rawptr) + +// OHCI/EHCI completion codes +OHCI_CC_NO_ERROR :: 0x0 +OHCI_CC_CRC :: 0x1 +OHCI_CC_BIT_STUFFING :: 0x2 +OHCI_CC_DATA_TOGGLE_MISMATCH :: 0x3 +OHCI_CC_STALL :: 0x4 +OHCI_CC_DEVICE_NOT_RESPONDING :: 0x5 +OHCI_CC_PID_CHECK_FAILURE :: 0x6 +OHCI_CC_UNEXPECTED_PID :: 0x7 +OHCI_CC_DATA_OVERRUN :: 0x8 +OHCI_CC_DATA_UNDERRUN :: 0x9 +OHCI_CC_BUFFER_OVERRUN :: 0xc +OHCI_CC_BUFFER_UNDERRUN :: 0xd +OHCI_CC_NOT_ACCESSED1 :: 0xe +OHCI_CC_NOT_ACCESSED2 :: 0xf +EHCI_CC_MISSED_MICRO_FRAME :: 0x10 +EHCI_CC_XACT :: 0x20 +EHCI_CC_BABBLE :: 0x30 +EHCI_CC_DATABUF :: 0x40 +EHCI_CC_HALTED :: 0x50 + +// Isochronous transfer(PSW) completion codes +USBD_CC_NOERR :: 0x0 +USBD_CC_MISSED_MICRO_FRAME :: 0x1 +USBD_CC_XACTERR :: 0x2 +USBD_CC_BABBLE :: 0x4 +USBD_CC_DATABUF :: 0x8 + diff --git a/Videodec/types.odin b/Videodec/types.odin index f5cc6c3..fcc429f 100644 --- a/Videodec/types.odin +++ b/Videodec/types.odin @@ -2,7 +2,6 @@ package videodec import "core:c" -// TODO: SceVideodecErrorCode :: enum c.uint { INVALID_TYPE = 0x80620801, INVALID_PARAM = 0x80620802, @@ -24,7 +23,6 @@ SceVideodecType :: enum c.int { HW_AVCDEC = 0x1001 } -// TODO: SceAvcdecErrorCode :: enum c.uint { INVALID_TYPE = 0x80620001, INVALID_PARAM = 0x80620002, diff --git a/common/types.odin b/common/types.odin index c9445ab..cac92c1 100644 --- a/common/types.odin +++ b/common/types.odin @@ -196,7 +196,6 @@ SceSystemParamTimeFormat :: enum c.int { // rtc.h start // -// TODO: should be c.int RtcErrorCode :: enum c.uint { INVALID_VALUE = 0x80251000, INVALID_POINTER = 0x80251001,