summaryrefslogtreecommitdiff
path: root/src/os/osSpTaskLoadGo.c
blob: 66c53524859856ef38635014ad8c59763983eceb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "libultra_internal.h"
#include "hardware.h"
#include <macros.h>

#define _osVirtualToPhysical(ptr)               \
    if (ptr != NULL) {                          \
        ptr = (void*) osVirtualToPhysical(ptr); \
    }

OSTask D_801964C0;
OSTask* _VirtualToPhysicalTask(OSTask* task) {
    OSTask* physicalTask;
    physicalTask = &D_801964C0;
    bcopy(task, physicalTask, sizeof(OSTask));
    _osVirtualToPhysical(physicalTask->t.ucode);
    _osVirtualToPhysical(physicalTask->t.ucode_data);
    _osVirtualToPhysical(physicalTask->t.dram_stack);
    _osVirtualToPhysical(physicalTask->t.output_buff);
    _osVirtualToPhysical(physicalTask->t.output_buff_size);
    _osVirtualToPhysical(physicalTask->t.data_ptr);
    _osVirtualToPhysical(physicalTask->t.yield_data_ptr);
    return physicalTask;
}

void osSpTaskLoad(OSTask* task) {
    OSTask* physicalTask;
    physicalTask = _VirtualToPhysicalTask(task);
    if (physicalTask->t.flags & M_TASK_FLAG0) {
        physicalTask->t.ucode_data = physicalTask->t.yield_data_ptr;
        physicalTask->t.ucode_data_size = physicalTask->t.yield_data_size;
        task->t.flags &= ~M_TASK_FLAG0;
#ifdef VERSION_SH
        if (physicalTask->t.flags & M_TASK_FLAG2) {
            physicalTask->t.ucode = HW_REG((uintptr_t) task->t.yield_data_ptr + 0xBFC, u64*);
        }
#endif
    }
    osWritebackDCache(physicalTask, sizeof(OSTask));
    __osSpSetStatus(SPSTATUS_CLEAR_SIGNAL0 | SPSTATUS_CLEAR_SIGNAL1 | SPSTATUS_CLEAR_SIGNAL2 |
                    SPSTATUS_SET_INTR_ON_BREAK);
    while (__osSpSetPc((void*) SP_IMEM_START) == -1) {
        ;
    }
    while (__osSpRawStartDma(1, (void*) (SP_IMEM_START - sizeof(*physicalTask)), physicalTask, sizeof(OSTask)) == -1) {
        ;
    }
    while (__osSpDeviceBusy()) {
        ;
    }
    while (__osSpRawStartDma(1, (void*) SP_IMEM_START, physicalTask->t.ucode_boot, physicalTask->t.ucode_boot_size) ==
           -1) {
        ;
    }
}

void osSpTaskStartGo(UNUSED OSTask* task) {
    while (__osSpDeviceBusy()) {
        ;
    }
    __osSpSetStatus(SPSTATUS_SET_INTR_ON_BREAK | SPSTATUS_CLEAR_SSTEP | SPSTATUS_CLEAR_BROKE | SPSTATUS_CLEAR_HALT);
}