From 9588ffb89ad30db6a993c65c40b9f6eb53a9c148 Mon Sep 17 00:00:00 2001 From: SuchMemeManySkill Date: Fri, 25 Dec 2020 21:16:24 +0100 Subject: [PATCH] Add exceptions, start file menu --- source/err.c | 20 +++++----- source/err.h | 6 ++- source/fs/menus/explorer.c | 18 ++++----- source/fs/menus/filemenu.c | 58 ++++++++++++++++++++++++++- source/fs/menus/filemenu.h | 4 +- source/gfx/menu.c | 28 ++++++++----- source/gfx/menu.h | 4 ++ source/main.c | 69 +++++++++++++++++++++++++++++++++ source/start.S | 6 +-- source/tegraexplorer/mainmenu.c | 10 ++++- source/tegraexplorer/tconf.c | 17 +++++++- source/tegraexplorer/tconf.h | 19 +++++---- source/utils/utils.c | 2 +- 13 files changed, 215 insertions(+), 46 deletions(-) diff --git a/source/err.c b/source/err.c index f45cebb..447facc 100644 --- a/source/err.c +++ b/source/err.c @@ -3,7 +3,7 @@ #include "hid/hid.h" #include "gfx/gfxutils.h" -const char *fatfsErrors[] = { +const char *TEErrors[] = { "I/O ERROR", "NO DISK", "NOT READY", @@ -17,20 +17,18 @@ const char *fatfsErrors[] = { "INVALID DRIVE", "NO MEM", "NO FAT", - "MKFS ABORT" -}; - -const char *TEErrors[] = { - "Unimplemented" + "MKFS ABORT", + [TE_ERR_UNIMPLEMENTED - 1] = "Unimplemented", + [TE_EXCEPTION_RESET - 1] = "E Reset", + [TE_EXCEPTION_UNDEFINED - 1] = "E Undefined", + [TE_EXCEPTION_PREF_ABORT - 1] = "E Pref abort", + [TE_EXCEPTION_DATA_ABORT - 1] = "E Data abort", }; const char *GetErrStr(u32 err){ --err; // obv error codes cannot be 0 - if (err >= 0 && err < ARRAY_SIZE(fatfsErrors)) - return fatfsErrors[err]; - - if (err >= 20 && err < ARRAY_SIZE(TEErrors) + 20) - return TEErrors[err - 20]; + if (err >= 0 && err < ARRAY_SIZE(TEErrors)) + return TEErrors[err]; return "(Unknown)"; } diff --git a/source/err.h b/source/err.h index 8a7eaf9..5dc1bf4 100644 --- a/source/err.h +++ b/source/err.h @@ -8,7 +8,11 @@ typedef struct { } ErrCode_t; enum { - TE_ERR_UNIMPLEMENTED = 21, + TE_ERR_UNIMPLEMENTED = 15, + TE_EXCEPTION_RESET, + TE_EXCEPTION_UNDEFINED, + TE_EXCEPTION_PREF_ABORT, + TE_EXCEPTION_DATA_ABORT }; #define newErrCode(err) (ErrCode_t) {err, __LINE__, __FILE__} diff --git a/source/fs/menus/explorer.c b/source/fs/menus/explorer.c index 41a0e9e..9c82993 100644 --- a/source/fs/menus/explorer.c +++ b/source/fs/menus/explorer.c @@ -34,7 +34,7 @@ void clearFileVector(Vector_t *v){ } void FileExplorer(char *path){ - char *storedPath = path; + char *storedPath = CpyStr(path); int res = 0; while (1){ @@ -54,7 +54,7 @@ void FileExplorer(char *path){ vecAddElem(&entries, a); } - gfx_con_setpos(144, 16); + gfx_con_setpos(144, 24); gfx_boxGrey(0, 16, 160, 31, 0x1B); if (res >= fileVec.count + ARR_LEN(topEntries)) @@ -62,25 +62,25 @@ void FileExplorer(char *path){ res = newMenu(&entries, res, 60, 42, ENABLEB | ENABLEPAGECOUNT, (int)fileVec.count); + char *oldPath = storedPath; + if (res < ARR_LEN(topEntries)) { if (!strcmp(storedPath, path)){ clearFileVector(&fileVec); return; } - char *copy = CpyStr(storedPath); - storedPath = EscapeFolder(copy); - free(copy); + storedPath = EscapeFolder(oldPath); + free(oldPath); res = 0; } else if (fsEntries[res - ARR_LEN(topEntries)].isDir) { - char *copy = CpyStr(storedPath); - storedPath = CombinePaths(copy, fsEntries[res - ARR_LEN(topEntries)].name); - free(copy); + storedPath = CombinePaths(storedPath, fsEntries[res - ARR_LEN(topEntries)].name); + free(oldPath); res = 0; } else { - FileMenu(fsEntries[res - ARR_LEN(topEntries)]); + FileMenu(storedPath, fsEntries[res - ARR_LEN(topEntries)]); } diff --git a/source/fs/menus/filemenu.c b/source/fs/menus/filemenu.c index a4588b4..c49457c 100644 --- a/source/fs/menus/filemenu.c +++ b/source/fs/menus/filemenu.c @@ -1,11 +1,67 @@ #include "filemenu.h" #include "../../err.h" #include "../../gfx/menu.h" +#include "../../gfx/gfxutils.h" +#include "../fsutils.h" +#include +#include +#include +#include "../../tegraexplorer/tconf.h" +#include "../../hid/hid.h" MenuEntry_t FileMenuEntries[] = { // Still have to think up the options + {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "-- File menu --"}, + {.optionUnion = COLORTORGB(COLOR_GREEN) | SKIPBIT}, // For the file name and size + {.optionUnion = COLORTORGB(COLOR_VIOLET) | SKIPBIT}, // For the file Attribs + {.optionUnion = HIDEBIT}, + {.optionUnion = COLORTORGB(COLOR_WHITE), .name = "<- Back"}, + {.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Copy to clipboard"}, + {.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Move to clipboard"}, + {.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Rename file"}, + {.optionUnion = COLORTORGB(COLOR_RED), .name = "Delete file"}, + {.optionUnion = COLORTORGB(COLOR_GREEN), .name = "View hex"}, + {.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "Launch Payload"}, + {.optionUnion = COLORTORGB(COLOR_YELLOW), .name = "Launch Script"}, }; -void FileMenu(FSEntry_t entry){ + +void UnimplementedException(char *path, FSEntry_t entry){ DrawError(newErrCode(TE_ERR_UNIMPLEMENTED)); +} + +extern int launch_payload(char *path); + +void LaunchPayload(char *path, FSEntry_t entry){ + launch_payload(CombinePaths(path, entry.name)); +} + +menuPaths FileMenuPaths[] = { + UnimplementedException, + UnimplementedException, + UnimplementedException, + UnimplementedException, + UnimplementedException, + LaunchPayload, + UnimplementedException +}; + +void FileMenu(char *path, FSEntry_t entry){ + FileMenuEntries[1].name = entry.name; + FileMenuEntries[1].sizeUnion = entry.sizeUnion; + char attribs[15]; + char *attribList = GetFileAttribs(entry); + sprintf(attribs, "Attribs:%s", attribList); + free(attribList); + FileMenuEntries[2].name = attribs; + + Vector_t ent = vecFromArray(FileMenuEntries, ARR_LEN(FileMenuEntries), sizeof(MenuEntry_t)); + gfx_boxGrey(384, 200, 384 + 512, 200 + 320, 0x33); + gfx_con_setpos(384 + 16, 200 + 16); + int res = newMenu(&ent, 0, 30, 19, ENABLEB | ALWAYSREDRAW | USELIGHTGREY, ent.count); + + if (res <= 4) + return; + + FileMenuPaths[res - 5](path, entry); } \ No newline at end of file diff --git a/source/fs/menus/filemenu.h b/source/fs/menus/filemenu.h index db2ca6e..15554fc 100644 --- a/source/fs/menus/filemenu.h +++ b/source/fs/menus/filemenu.h @@ -1,4 +1,6 @@ #pragma once #include "../fstypes.h" -void FileMenu(FSEntry_t entry); \ No newline at end of file +typedef void (*fileMenuPath)(char *path, FSEntry_t entry); + +void FileMenu(char *path, FSEntry_t entry); \ No newline at end of file diff --git a/source/gfx/menu.c b/source/gfx/menu.c index 7690b00..8b12cda 100644 --- a/source/gfx/menu.c +++ b/source/gfx/menu.c @@ -5,6 +5,8 @@ #include "../hid/hid.h" #include #include +#include +#include const char *sizeDefs[] = { "B ", @@ -13,11 +15,11 @@ const char *sizeDefs[] = { "GB" }; -void _printEntry(MenuEntry_t entry, u32 maxLen, u8 highlighted){ +void _printEntry(MenuEntry_t entry, u32 maxLen, u8 highlighted, u32 bg){ if (entry.hide) return; - (highlighted) ? SETCOLOR(COLOR_DEFAULT, FromRGBtoU32(entry.R, entry.G, entry.B)) : SETCOLOR(FromRGBtoU32(entry.R, entry.G, entry.B), COLOR_DEFAULT); + (highlighted) ? SETCOLOR(bg, FromRGBtoU32(entry.R, entry.G, entry.B)) : SETCOLOR(FromRGBtoU32(entry.R, entry.G, entry.B), bg); if (entry.icon){ gfx_putc(entry.icon); @@ -29,7 +31,7 @@ void _printEntry(MenuEntry_t entry, u32 maxLen, u8 highlighted){ gfx_con_getpos(&curX, &curY); gfx_puts_limit(entry.name, maxLen - ((entry.showSize) ? 8 : 0)); if (entry.showSize){ - (highlighted) ? SETCOLOR(COLOR_DEFAULT, COLOR_BLUE) : SETCOLOR(COLOR_BLUE, COLOR_DEFAULT); + (highlighted) ? SETCOLOR(bg, COLOR_BLUE) : SETCOLOR(COLOR_BLUE, bg); gfx_con_setpos(curX + (maxLen - 6) * 16, curY); gfx_printf("%4d", entry.size); gfx_puts_small(sizeDefs[entry.sizeDef]); @@ -58,10 +60,14 @@ int newMenu(Vector_t* vec, int startIndex, int screenLenX, int screenLenY, u8 op u32 startX = 0, startY = 0; gfx_con_getpos(&startX, &startY); + u32 bgColor = (options & USELIGHTGREY) ? COLOR_DARKGREY : COLOR_DEFAULT; + + /* if (options & ENABLEPAGECOUNT){ screenLenY -= 2; startY += 32; } + */ bool redrawScreen = true; Input_t *input = hidRead(); @@ -75,20 +81,22 @@ int newMenu(Vector_t* vec, int startIndex, int screenLenX, int screenLenY, u8 op u32 lastDraw = get_tmr_ms(); if (redrawScreen || options & ALWAYSREDRAW){ if (options & ENABLEPAGECOUNT){ - gfx_con_setpos(startX, startY - 32); - RESETCOLOR; - gfx_printf("Page %d / %d | Total %d entries ", (selected / screenLenY) + 1, (vec->count / screenLenY) + 1, entryCount); + SETCOLOR(COLOR_DEFAULT, COLOR_WHITE); + char temp[40] = ""; + sprintf(temp, " Page %d / %d | Total %d entries", (selected / screenLenY) + 1, (vec->count / screenLenY) + 1, entryCount); + gfx_con_setpos(YLEFT - strlen(temp) * 18, 0); + gfx_printf(temp); } gfx_con_setpos(startX, startY); if (redrawScreen) - gfx_boxGrey(startX, startY, startX + screenLenX * 16, startY + screenLenY * 16, 0x1B); + gfx_boxGrey(startX, startY, startX + screenLenX * 16, startY + screenLenY * 16, (options & USELIGHTGREY) ? 0x33 : 0x1B); int start = selected / screenLenY * screenLenY; for (int i = start; i < MIN(vec->count, start + screenLenY); i++){ gfx_con_setpos(startX, startY + ((i % screenLenY) * 16)); - _printEntry(entries[i], screenLenX, (i == selected)); + _printEntry(entries[i], screenLenX, (i == selected), bgColor); } } @@ -96,9 +104,9 @@ int newMenu(Vector_t* vec, int startIndex, int screenLenX, int screenLenY, u8 op u32 minLastCur = MIN(lastIndex, selected); u32 maxLastCur = MAX(lastIndex, selected); gfx_con_setpos(startX, startY + ((minLastCur % screenLenY) * 16)); - _printEntry(entries[minLastCur], screenLenX, (minLastCur == selected)); + _printEntry(entries[minLastCur], screenLenX, (minLastCur == selected), bgColor); gfx_con_setpos(startX, startY + ((maxLastCur % screenLenY) * 16)); - _printEntry(entries[maxLastCur], screenLenX, (minLastCur != selected)); + _printEntry(entries[maxLastCur], screenLenX, (minLastCur != selected), bgColor); } lastIndex = selected; diff --git a/source/gfx/menu.h b/source/gfx/menu.h index e6a4a19..8133549 100644 --- a/source/gfx/menu.h +++ b/source/gfx/menu.h @@ -37,6 +37,10 @@ typedef struct _menuEntry { #define ENABLEB BIT(0) #define ENABLEPAGECOUNT BIT(1) #define ALWAYSREDRAW BIT(2) +#define USELIGHTGREY BIT(3) + +#define ScreenDefaultLenX 79 +#define ScreenDefaultLenY 30 #define ARR_LEN(x) (sizeof(x) / sizeof(*x)) diff --git a/source/main.c b/source/main.c index 8f3ba10..d8e9d19 100644 --- a/source/main.c +++ b/source/main.c @@ -48,6 +48,7 @@ #include "tegraexplorer/mainmenu.h" #include "tegraexplorer/tconf.h" #include "err.h" +#include hekate_config h_cfg; @@ -154,6 +155,70 @@ int launch_payload(char *path) extern void pivot_stack(u32 stack_top); +#define EXCP_EN_ADDR 0x4003FFFC +#define EXCP_MAGIC 0x30505645 // EVP0 +#define EXCP_TYPE_ADDR 0x4003FFF8 +#define EXCP_TYPE_RESET 0x545352 // RST +#define EXCP_TYPE_UNDEF 0x464455 // UDF +#define EXCP_TYPE_PABRT 0x54424150 // PABT +#define EXCP_TYPE_DABRT 0x54424144 // DABT +#define EXCP_LR_ADDR 0x4003FFF4 + +static inline void _show_errors() +{ + u32 *excp_enabled = (u32 *)EXCP_EN_ADDR; + u32 *excp_type = (u32 *)EXCP_TYPE_ADDR; + u32 *excp_lr = (u32 *)EXCP_LR_ADDR; + + if (*excp_enabled == EXCP_MAGIC) + h_cfg.errors |= ERR_EXCEPTION; + + if (h_cfg.errors) + { + + + /* + if (h_cfg.errors & ERR_SD_BOOT_EN) + WPRINTF("Failed to mount SD!\n"); + + if (h_cfg.errors & ERR_LIBSYS_LP0) + WPRINTF("Missing LP0 (sleep mode) lib!\n"); + if (h_cfg.errors & ERR_LIBSYS_MTC) + WPRINTF("Missing or old Minerva lib!\n"); + + if (h_cfg.errors & (ERR_LIBSYS_LP0 | ERR_LIBSYS_MTC)) + WPRINTF("\nUpdate bootloader folder!\n\n"); + */ + + if (h_cfg.errors & ERR_EXCEPTION) + { + gfx_clearscreen(); + WPRINTFARGS("LR %08X", *excp_lr); + u16 exception = TE_EXCEPTION_RESET; + /* + switch (*excp_type) + { + case EXCP_TYPE_RESET: + exception = TE_EXCEPTION_RESET; + break; + case EXCP_TYPE_UNDEF: + exception = TE_EXCEPTION_UNDEFINED; + break; + case EXCP_TYPE_PABRT: + exception = TE_EXCEPTION_PREF_ABORT; + break; + case EXCP_TYPE_DABRT: + exception = TE_EXCEPTION_DATA_ABORT; + break; + }*/ + + // Clear the exception. + *excp_enabled = 0; + DrawError(newErrCode(exception)); + } + } +} + void ipl_main() { // Do initial HW configuration. This is compatible with consecutive reruns without a reset. @@ -212,6 +277,10 @@ void ipl_main() //gfx_clearscreen(); //DrawError(newErrCode(1)); + // TODO: Write exceptions in err.c and check them here + + _show_errors(); + EnterMainMenu(); // Halt BPMP if we managed to get out of execution. diff --git a/source/start.S b/source/start.S index 534f963..269f2c7 100644 --- a/source/start.S +++ b/source/start.S @@ -23,8 +23,8 @@ .extern memset .type memset, %function -.extern ipl_main -.type ipl_main, %function +.extern _irq_setup +.type _irq_setup, %function .globl _start .type _start, %function @@ -67,7 +67,7 @@ _real_start: LDR R2, =__bss_end SUB R2, R2, R0 BL memset - BL ipl_main + BL _irq_setup B . .globl pivot_stack diff --git a/source/tegraexplorer/mainmenu.c b/source/tegraexplorer/mainmenu.c index b06aabf..f030ddd 100644 --- a/source/tegraexplorer/mainmenu.c +++ b/source/tegraexplorer/mainmenu.c @@ -7,16 +7,19 @@ #include "../fs/menus/explorer.h" #include #include +#include "tconf.h" MenuEntry_t mainMenuEntries[] = { {.R = 255, .G = 255, .B = 255, .skip = 1, .name = "-- Main Menu --"}, {.G = 255, .name = "SD:/"}, {.B = 255, .G = 255, .name = "Test Controllers"}, + {.R = 255, .name = "Cause an exception"}, {.R = 255, .name = "Reboot to payload"} }; void HandleSD(){ gfx_clearscreen(); + TConf.curExplorerLoc = LOC_SD; if (!sd_mount()){ gfx_printf("Sd is not mounted!"); hidWait(); @@ -25,16 +28,21 @@ void HandleSD(){ FileExplorer("sd:/"); } +void CrashTE(){ + gfx_printf("%d", *((int*)0)); +} + menuPaths mainMenuPaths[] = { NULL, HandleSD, TestControllers, + CrashTE, RebootToPayload }; void EnterMainMenu(){ while (1){ - FunctionMenuHandler(mainMenuEntries, 4, mainMenuPaths, 0); + FunctionMenuHandler(mainMenuEntries, ARR_LEN(mainMenuEntries), mainMenuPaths, 0); } } diff --git a/source/tegraexplorer/tconf.c b/source/tegraexplorer/tconf.c index d7d004c..46a3828 100644 --- a/source/tegraexplorer/tconf.c +++ b/source/tegraexplorer/tconf.c @@ -1,2 +1,17 @@ #include "tconf.h" -TConf_t TConf = {0}; \ No newline at end of file +#include +TConf_t TConf = {0}; + +void ResetCopyParams(){ + TConf.heldExplorerCopyLoc = LOC_None; + if (TConf.srcCopy != NULL) + free(TConf.srcCopy); + TConf.explorerCopyMode = CMODE_None; +} + +void SetCopyParams(char *path, u8 mode){ + ResetCopyParams(); + TConf.heldExplorerCopyLoc = TConf.curExplorerLoc; + TConf.explorerCopyMode = mode; + TConf.srcCopy = path; +} \ No newline at end of file diff --git a/source/tegraexplorer/tconf.h b/source/tegraexplorer/tconf.h index ff5de1d..43de6ad 100644 --- a/source/tegraexplorer/tconf.h +++ b/source/tegraexplorer/tconf.h @@ -2,7 +2,8 @@ #include enum { - LOC_SD = 0, + LOC_None = 0, + LOC_SD, LOC_EMMC, LOC_EMUMMC }; @@ -24,14 +25,18 @@ typedef struct { char *srcCopy; union { struct { - u8 minervaEnabled:1; - u8 lastExplorerLoc:2; - u8 explorerCopyMode:2; - u8 currentlyMounted:2; + u16 minervaEnabled:1; + u16 curExplorerLoc:2; + u16 heldExplorerCopyLoc:2; + u16 explorerCopyMode:2; + u16 currentMMCMounted:2; }; - u8 optionUnion; + u16 optionUnion; }; // Add keys here } TConf_t; -extern TConf_t TConf; \ No newline at end of file +extern TConf_t TConf; + +void ResetCopyParams(); +void SetCopyParams(char *path, u8 mode); \ No newline at end of file diff --git a/source/utils/utils.c b/source/utils/utils.c index 042fa74..1427626 100644 --- a/source/utils/utils.c +++ b/source/utils/utils.c @@ -14,7 +14,7 @@ char *CpyStr(const char* in){ void MaskIn(char *mod, u32 bitstream, char mask){ u32 len = strlen(mod); for (int i = 0; i < len; i++){ - if (bitstream & 1) + if (!(bitstream & 1)) *mod = mask; bitstream >>= 1;