-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmemory.c
277 lines (242 loc) · 8.38 KB
/
memory.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
* memory.c ver. 1.1
*
* Created on: 2011/09/03
* Author: noname
*/
#include <pspkernel.h>
#include <kubridge.h>
#include "memory.h"
static int mem_mode = 0;
static int mem_partition = 0;
/*---------------------------------------------------------------------------
メモリ確保する場所の設定
int mode: これから確保するメモリのパーティションを指定、
0の場合は自動判定するが、動作が遅くなる
return: 設定値を返す
---------------------------------------------------------------------------*/
int mem_set_alloc_mode(int part)
{
mem_mode = part;
return part;
}
/*---------------------------------------------------------------------------
優先順位番号からパーティション番号を取得
int num : 優先順位 0~5
return : パーティション番号
---------------------------------------------------------------------------*/
static int mem_get_auto_partition(int num)
{
int partitionid;
int tid;
SceKernelThreadInfo tinfo;
// Model
// 0 : 1000
// 1 : 2000
// 2 : 3000
// 3 : 3000
// 4 : go
// 5 : 3000?
// 6 : 3000?
// 7 : 3000?
// 8 : 3000
#define TABLE_LEN 7
// 冗長かもしれないが、今後のことを考えて全てテーブル化
int partition_kern[2][3][9][TABLE_LEN] = {
{ // 5.xx
{ // VSH
{ 2, 5, 4, 1, 0, 0, 0}, // fat 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // go 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
},
{ // GAME
{ 1, 2, 0, 0, 0, 0, 0}, // fat 9/15 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // go 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
},
{ // POPS
{ 4, 1, 2, 0, 0, 0, 0}, // fat 9/2 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // go 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
{ 8, 10, 4, 1, 2, 0, 0}, // slim 9/3 fix
},
},
{ // 6.xx
{ // VSH
{ 2, 5, 4, 1, 0, 0, 0}, // fat 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // go 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
{ 2, 5, 4, 1, 0, 0, 0}, // slim 9/2 fix
},
{ // GAME
{ 1, 2, 0, 0, 0, 0, 0}, // fat 9/15 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // go 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
},
{ // POPS
{ 4, 1, 2, 0, 0, 0, 0}, // fat 9/3 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // go 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
{ 9, 11, 8, 4, 1, 2, 0}, // slim 9/2 fix
},
},
};
int partition_user = MEM_USER;
int fw;
int model;
int mode;
if(mem_mode == MEM_AUTO)
{
tid = sceKernelGetThreadId();
tinfo.size = sizeof(SceKernelThreadInfo);
sceKernelReferThreadStatus(tid, &tinfo);
if((tinfo.attr & PSP_THREAD_ATTR_USER) != PSP_THREAD_ATTR_USER)
{
// カーネルモード
fw = (sceKernelDevkitVersion() >> 24) - 5; // 0 = ~5.xx, 1 = 6.xx
mode = (sceKernelInitKeyConfig() >> 8) - 1; // 0 = VSH, 1 = GAME, 2 = POPS
model = kuKernelGetModel(); // 0 = 1000, 1 = 2000, 2,3,5,6,7,8 = 3000, 4 = go
if(num < TABLE_LEN)
partitionid = partition_kern[fw][mode][model][num];
else
partitionid = 0;
}
else
{
// ユーザーモード
if(num == 0)
partitionid = partition_user;
else
partitionid = 0;
}
}
else
{
if(num == 0)
partitionid = mem_mode;
else
partitionid = 0;
}
return partitionid;
}
/*---------------------------------------------------------------------------
メモリ確保するパーティションの読取
return: 設定値を返す
---------------------------------------------------------------------------*/
/*
int mem_get_alloc_mode(void)
{
return mem_mode;
}
*/
/*---------------------------------------------------------------------------
直前に確保したメモリのパーティションを読取
return : パーティション番号, 未取得の場合は0を返す
---------------------------------------------------------------------------*/
/*
int mem_get_alloc_partition(void)
{
return mem_partition;
}
*/
/*---------------------------------------------------------------------------
メモリ確保
int size: 利用メモリサイズ
return: 確保したメモリへのポインタ
エラーの場合はNULLを返す
---------------------------------------------------------------------------*/
void* mem_alloc(int size)
{
SceUID* p;
int h_block;
int partitionid;
int loop = 0;
if(size == 0) return NULL;
while(partitionid = mem_get_auto_partition(loop), partitionid != 0)
{
h_block = sceKernelAllocPartitionMemory(partitionid, "mem_alloc", PSP_SMEM_Low, size + sizeof(SceUID*), NULL);
if(h_block > 0)
break;
loop++;
}
if(partitionid == 0)
{
mem_partition = 0;
return NULL;
}
mem_partition = partitionid;
p = sceKernelGetBlockHeadAddr(h_block);
*p = h_block;
return (void *)(p + 1);
}
/*---------------------------------------------------------------------------
アライメントを指定したメモリ確保
int align : アライメントサイズ(2^nであること)
int size : 利用メモリサイズ
return: 確保したメモリへのポインタ
エラーの場合はNULLを返す
---------------------------------------------------------------------------*/
/*
void* mem_align(int align, int size)
{
//
// *--------------------------合計確保サイズ-----------------------------+
// +-free用領域-+-----------必要サイズ----------+-----アライメント用-----+
// +--空き--+-free用領域-+---アライメント指定後の必要サイズ---+---空き---+
//
SceUID *p;
SceUID *align_mem;
p = mem_alloc(size + align + sizeof(SceUID*));
if(p == NULL)
return NULL;
// 確保したメモリ位置を調整
align_mem = (SceUID*)(((int)p + align - 1) & ~(align - 1));
// mem_free出来るように返すメモリ位置の直前にSceUIDを書込む
*(align_mem - 1) = *(p - 1);
return align_mem;
}
*/
/*---------------------------------------------------------------------------
メモリ解放
*ptr: 確保したメモリへのポインタ
return: エラーの場合は負の値を返す
---------------------------------------------------------------------------*/
s32 mem_free(void *ptr)
{
if(ptr == NULL)
return 0;
return sceKernelFreePartitionMemory((SceUID)*((u32 *)ptr - 1));
}