This repository has been archived by the owner on Jun 12, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
/
sram.c
127 lines (89 loc) · 2.82 KB
/
sram.c
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <malloc.h>
#include <stdint.h>
#include <string.h>
#include "sys.h"
#include "types.h"
#include "utils.h"
#include "sram.h"
void PI_Init(void) {
PI_DMAWait();
IO_WRITE(PI_STATUS_REG, 0x03);
}
// Inits PI for sram transfer
void PI_Init_SRAM(void) {
IO_WRITE(PI_BSD_DOM2_LAT_REG, 0x05);
IO_WRITE(PI_BSD_DOM2_PWD_REG, 0x0C);
IO_WRITE(PI_BSD_DOM2_PGS_REG, 0x0D);
IO_WRITE(PI_BSD_DOM2_RLS_REG, 0x02);
}
void PI_DMAWait(void) {
/*PI DMA wait
1. Read PI_STATUS_REG then AND it with 0x3, if its true... then wait until
it is not true.
*/
while (IO_READ(PI_STATUS_REG) & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY));
}
void PI_DMAFromSRAM(void *dest, u32 offset, u32 size) {
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(dest));
IO_WRITE(PI_CART_ADDR_REG, (0xA8000000 + offset));
asm volatile ("" : : : "memory");
IO_WRITE(PI_WR_LEN_REG, (size - 1));
asm volatile ("" : : : "memory");
/*
PI_DMAWait();
IO_WRITE(PI_STATUS_REG, 0x03);
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(dest));
IO_WRITE(PI_CART_ADDR_REG, (0xA8000000 + offset));
_data_cache_invalidate_all();
IO_WRITE(PI_WR_LEN_REG, (size - 1));
*/
}
void PI_DMAToSRAM(void *src, u32 offset, u32 size) { //void*
PI_DMAWait();
IO_WRITE(PI_STATUS_REG, 2);
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(src));
IO_WRITE(PI_CART_ADDR_REG, (0xA8000000 + offset));
_data_cache_invalidate_all();
//data_cache_hit_writeback_invalidate(src,size);
/* Write back . nusys - only writeback
osWritebackDCache((void*)buf_ptr, (s32)size);
*/
//libdragon equivalent
// data_cache_hit_writeback (src, size);
IO_WRITE(PI_RD_LEN_REG, (size - 1));
}
void PI_DMAFromCart(void* dest, void* src, u32 size) {
PI_DMAWait();
IO_WRITE(PI_STATUS_REG, 0x03);
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(dest));
IO_WRITE(PI_CART_ADDR_REG, K0_TO_PHYS(src));
//_data_cache_invalidate_all();
IO_WRITE(PI_WR_LEN_REG, (size - 1));
}
void PI_DMAToCart(void* dest, void* src, u32 size) {
PI_DMAWait();
IO_WRITE(PI_STATUS_REG, 0x02);
IO_WRITE(PI_DRAM_ADDR_REG, K1_TO_PHYS(src));
IO_WRITE(PI_CART_ADDR_REG, K0_TO_PHYS(dest));
//_data_cache_invalidate_all();
IO_WRITE(PI_RD_LEN_REG, (size - 1));
}
// Wrapper to support unaligned access to memory
void PI_SafeDMAFromCart(void *dest, void *src, u32 size) {
if (!dest || !src || !size) return;
u32 unalignedSrc = ((u32)src) % 2;
u32 unalignedDest = ((u32)dest) % 8;
//FIXME: Do i really need to check if size is 16bit aligned?
if (!unalignedDest && !unalignedSrc && !(size % 2)) {
PI_DMAFromCart(dest, src, size);
PI_DMAWait();
return;
}
void* newSrc = (void*)(((u32)src) - unalignedSrc);
u32 newSize = (size + unalignedSrc) + ((size + unalignedSrc) % 2);
u8 *buffer = memalign(8, newSize);
PI_DMAFromCart(buffer, newSrc, newSize);
PI_DMAWait();
memcpy(dest, (buffer + unalignedSrc), size);
free(buffer);
}