]> Chaos Git - corbenik/ctrulib.git/commitdiff
Expose err:f global port
authorchaoskagami <chaos.kagami@gmail.com>
Thu, 14 Jul 2016 20:30:55 +0000 (16:30 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Thu, 14 Jul 2016 22:07:30 +0000 (18:07 -0400)
libctru/include/3ds.h
libctru/include/3ds/errf.h [new file with mode: 0644]
libctru/source/errf.c [new file with mode: 0644]

index 1dc1683ab54a943d14b3bbd8704d15b477fb386a..b5c0cb636916895b4c20ccbf8048a781b680361a 100644 (file)
@@ -14,6 +14,7 @@ extern "C" {
 #include <3ds/ipc.h>
 #include <3ds/svc.h>
 #include <3ds/srv.h>
+#include <3ds/errf.h>
 #include <3ds/os.h>
 #include <3ds/synchronization.h>
 #include <3ds/thread.h>
@@ -106,4 +107,4 @@ extern "C" {
  * @example threads/event/source/main.c
  * @example time/rtc/source/main.c
  */
+
diff --git a/libctru/include/3ds/errf.h b/libctru/include/3ds/errf.h
new file mode 100644 (file)
index 0000000..d79de34
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * @file errf.h
+ * @brief Error Display API
+ */
+
+#pragma once
+
+#include <3ds/types.h>
+
+/// Used for register dumps.
+typedef struct {
+       u32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, cpsr;
+} ERRF_ExceptionContext;
+
+/// Types of errors that can be thrown by err:f.
+typedef enum {
+       ERRF_ERRTYPE_GENERIC    = 0, ///< For generic errors. Shows miscellaneous info.
+       ERRF_ERRTYPE_EXCEPTION  = 3, ///< For exceptions, or more specifically 'crashes'. union data should be exception_data.
+       ERRF_ERRTYPE_FAILURE    = 4, ///< For general failure. Shows a message. union data should have a string set in failure_mesg
+       ERRF_ERRTYPE_LOGGED     = 5  ///< Outputs logs to NAND in some cases.
+} ERRF_ErrType;
+
+/// Types of 'Exceptions' thrown for ERRF_ERRTYPE_EXCEPTION
+typedef enum {
+       ERRF_EXCEPTION_PREFETCH_ABORT = 0, ///< Prefetch Abort
+       ERRF_EXCEPTION_DATA_ABORT     = 1, ///< Data abort
+       ERRF_EXCEPTION_UNDEFINED      = 2, ///< Undefined instruction
+       ERRF_EXCEPTION_VFP            = 3  ///< VFP (floating point) exception.
+} ERRF_ExceptionType;
+
+typedef struct {
+       ERRF_ExceptionType type; ///< Type of the exception. One of the ERRF_EXCEPTION_* values.
+       u8  reserved[3];
+       u32 reg1;                ///< If type is prefetch, this should be ifsr, and on data abort dfsr
+       u32 reg2;                ///< If type is prefetch, this should be r15, and dfar on data abort
+       u32 fpexc;
+       u32 fpinst;
+       u32 fpint2;
+} ERRF_ExceptionInfo;
+
+typedef struct {
+       ERRF_ExceptionInfo excep;   ///< Exception info struct
+       ERRF_ExceptionContext regs; ///< Register dump.
+       u8 pad[4];
+} ERRF_ExceptionData;
+
+typedef struct {
+       ERRF_ErrType type; ///< Type, one of the ERRF_ERRTYPE_* enum
+       u8  revHigh;       ///< High revison ID
+       u16 revLow;        ///< Low revision ID
+       u32 resCode;       ///< Result code
+       u32 pcAddr;        ///< PC address at exception
+       u32 procId;        ///< Process ID.
+       u64 titleId;       ///< Title ID.
+       u64 appTitleId;    ///< Application Title ID.
+       union {
+               ERRF_ExceptionData exception_data; ///< Data for when type is ERRF_ERRTYPE_EXCEPTION
+               char failure_mesg[60];             ///< String for when type is ERRF_ERRTYPE_FAILURE
+       } data;                                ///< The different types of data for errors.
+} ERRF_FatalErrInfo;
+
+/// Initializes ERR:f.
+Result errfInit(void);
+
+/// Exits ERR:f.
+void errfExit(void);
+
+/**
+ * @brief Gets the current err:f API session handle.
+ * @return The current err:f API session handle.
+ */
+Handle *errfGetSessionHandle(void);
+
+/**
+ * @brief Throws a system error and possibly results in ErrDisp triggering. After performing this,
+ * the system may panic and need to be rebooted. Extra information will be displayed on the
+ * top screen with a developer console or the proper patches in a CFW applied.
+ * @param error Error to throw.
+ */
+Result ERRF_Throw(ERRF_FatalErrInfo *error);
diff --git a/libctru/source/errf.c b/libctru/source/errf.c
new file mode 100644 (file)
index 0000000..a15a719
--- /dev/null
@@ -0,0 +1,52 @@
+#include <string.h>
+#include <3ds/types.h>
+#include <3ds/result.h>
+#include <3ds/svc.h>
+#include <3ds/synchronization.h>
+#include <3ds/errf.h>
+#include <3ds/ipc.h>
+#include <3ds/env.h>
+#include "internal.h"
+
+static Handle errfHandle;
+static int errfRefCount;
+
+Result errfInit(void)
+{
+       Result rc = 0;
+
+       if (AtomicPostIncrement(&errfRefCount)) return 0;
+
+       rc = svcConnectToPort(&errfHandle, "err:f");
+       if (R_FAILED(rc)) goto end;
+
+end:
+       if (R_FAILED(rc)) errfExit();
+       return rc;
+}
+
+void errfExit(void)
+{
+       if (AtomicDecrement(&errfRefCount))
+               return;
+       svcCloseHandle(errfHandle);
+}
+
+Handle* errfGetSessionHandle(void)
+{
+       return &errfHandle;
+}
+
+Result ERRF_Throw(ERRF_FatalErrInfo *error)
+{
+       uint32_t *cmdbuf = getThreadCommandBuffer();
+
+       cmdbuf[0] = 0x10800;
+       memcpy(&cmdbuf[1], error, sizeof(ERRF_FatalErrInfo));
+
+       Result ret = 0;
+       if (R_FAILED(ret = svcSendSyncRequest(errfHandle)))
+               return ret;
+
+       return cmdbuf[1];
+}