summaryrefslogtreecommitdiff
path: root/src/boot/O2/stackcheck.c
diff options
context:
space:
mode:
authorDerek Hensley <hensley.derek58@gmail.com>2023-09-11 17:38:31 -0700
committerGitHub <noreply@github.com>2023-09-12 10:38:31 +1000
commit190b78549e0fa1a801786e73d914185e1fbca2a6 (patch)
treebc62310b90bbd59005ef01873ca4a007d8c8ef31 /src/boot/O2/stackcheck.c
parent39523baf8c52d59b8ca52832c22e70eadf518f8a (diff)
Non libultra Boot Cleanup (#1370)
* reorganize * math64 * rcp_utils * osSyncPrintfUnused * comment spacing
Diffstat (limited to 'src/boot/O2/stackcheck.c')
-rw-r--r--src/boot/O2/stackcheck.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/boot/O2/stackcheck.c b/src/boot/O2/stackcheck.c
new file mode 100644
index 000000000..edd1e3a30
--- /dev/null
+++ b/src/boot/O2/stackcheck.c
@@ -0,0 +1,122 @@
+#include "stackcheck.h"
+#include "libc/stdbool.h"
+#include "libc/stdint.h"
+
+StackEntry* sStackInfoListStart = NULL;
+StackEntry* sStackInfoListEnd = NULL;
+
+void StackCheck_Init(StackEntry* entry, void* stackBottom, void* stackTop, u32 initValue, s32 minSpace,
+ const char* name) {
+ if (entry == NULL) {
+ sStackInfoListStart = NULL;
+ } else {
+ StackEntry* iter;
+
+ entry->head = stackBottom;
+ entry->tail = stackTop;
+ entry->initValue = initValue;
+ entry->minSpace = minSpace;
+ entry->name = name;
+ iter = sStackInfoListStart;
+ while (iter) {
+ if (iter == entry) {
+ return;
+ }
+ iter = iter->next;
+ }
+
+ entry->prev = sStackInfoListEnd;
+ entry->next = NULL;
+
+ if (sStackInfoListEnd) {
+ sStackInfoListEnd->next = entry;
+ }
+
+ sStackInfoListEnd = entry;
+ if (sStackInfoListStart == NULL) {
+ sStackInfoListStart = entry;
+ }
+
+ if (entry->minSpace != -1) {
+ u32* addr = entry->head;
+
+ while (addr < (u32*)entry->tail) {
+ *addr++ = entry->initValue;
+ }
+ }
+ }
+}
+
+void StackCheck_Cleanup(StackEntry* entry) {
+ u32 inconsistency = false;
+
+ if (entry->prev == NULL) {
+ if (entry == sStackInfoListStart) {
+ sStackInfoListStart = entry->next;
+ } else {
+ inconsistency = true;
+ }
+ } else {
+ entry->prev->next = entry->next;
+ }
+
+ if (!entry->next) {
+ if (entry == sStackInfoListEnd) {
+ sStackInfoListEnd = entry->prev;
+ } else {
+ inconsistency = true;
+ }
+ }
+
+ if (inconsistency) {}
+}
+
+StackStatus StackCheck_GetState(StackEntry* entry) {
+ u32* last;
+ size_t used;
+ size_t free;
+ StackStatus status;
+
+ for (last = entry->head; last < (u32*)entry->tail; last++) {
+ if (entry->initValue != *last) {
+ break;
+ }
+ }
+
+ used = (uintptr_t)entry->tail - (uintptr_t)last;
+ free = (uintptr_t)last - (uintptr_t)entry->head;
+
+ if (free == 0) {
+ status = STACK_STATUS_OVERFLOW;
+ } else if ((free < (size_t)entry->minSpace) && (entry->minSpace != -1)) {
+ status = STACK_STATUS_WARNING;
+ } else {
+ status = STACK_STATUS_OK;
+ }
+
+ return status;
+}
+
+u32 StackCheck_CheckAll(void) {
+ u32 ret = 0;
+ StackEntry* iter = sStackInfoListStart;
+
+ while (iter != NULL) {
+ StackStatus state = StackCheck_GetState(iter);
+
+ if (state != STACK_STATUS_OK) {
+ ret = 1;
+ }
+ iter = iter->next;
+ }
+
+ return ret;
+}
+
+u32 StackCheck_Check(StackEntry* entry) {
+ if (entry == NULL) {
+ return StackCheck_CheckAll();
+ } else {
+ return StackCheck_GetState(entry);
+ }
+}