21IRX_ID(
"IOP_SIF_manager", 2, 5);
35 void (*func)(
void *userdata);
37} sif_completion_cb_info_t;
41 sif_completion_cb_info_t info[32];
43} sif_completion_cb_info_arr_t;
51 sif_info_t *sif_curbuf;
52 sif_info_t sif_buf1[32];
53 sif_info_t sif_buf2[32];
54 sif_completion_cb_info_arr_t *sif_otherbufcom;
55 sif_completion_cb_info_arr_t *sif_curbufcom;
56 sif_completion_cb_info_arr_t sif_bufcom1;
57 sif_completion_cb_info_arr_t sif_bufcom2;
58 void (*dma_intr_handler)(
void *userdata);
59 void *dma_intr_handler_userdata;
67static sifman_internals_t sifman_internals;
68static u32 sif_dma2_inited = 0;
69static u32 sif_inited = 0;
71int _start(
int ac,
char **av)
74 USE_IOP_MMIO_HWPORT();
75 USE_SIF_MMIO_HWPORT();
83 if ( (iop_mmio_hwport->iop_sbus_ctrl[0] & 8) == 0 )
85 if ( sif_mmio_hwport->unk60 == 0x1D000060 )
86 return RegisterLibraryEntries(&_exp_sifman) != 0;
87 if ( (sif_mmio_hwport->unk60 & 0xFFFFF000) == 0 )
88 return RegisterLibraryEntries(&_exp_sifman) != 0;
94static u32 get_msflag()
97 USE_SIF_MMIO_HWPORT();
99 for ( result = sif_mmio_hwport->msflag; result != sif_mmio_hwport->msflag; result = sif_mmio_hwport->msflag )
104static u32 get_smflag()
107 USE_SIF_MMIO_HWPORT();
109 for ( result = sif_mmio_hwport->smflag; result != sif_mmio_hwport->smflag; result = sif_mmio_hwport->smflag )
116 USE_IOP_MMIO_HWPORT();
118 if ( !sif_dma2_inited )
120 iop_mmio_hwport->dmac1.oldch[2].chcr = 0;
121 iop_mmio_hwport->dmac1.dpcr1 |= 0x800;
126static int sif_dma_init(
void);
132 USE_IOP_MMIO_HWPORT();
133 USE_SIF_MMIO_HWPORT();
137 iop_mmio_hwport->dmac2.dpcr2 |= 0x8800;
138 iop_mmio_hwport->dmac2.newch[2].chcr = 0;
139 iop_mmio_hwport->dmac2.newch[3].chcr = 0;
141 if ( (iop_mmio_hwport->iop_sbus_ctrl[0] & 0x10) != 0 )
143 iop_mmio_hwport->iop_sbus_ctrl[0] |= 0x10;
145 iop_mmio_hwport->iop_sbus_ctrl[0] |= 1;
150 msflag = get_msflag();
163 USE_IOP_MMIO_HWPORT();
167 iop_mmio_hwport->dmac2.newch[2].chcr = 0;
168 iop_mmio_hwport->dmac2.newch[3].chcr = 0;
169 if ( iop_mmio_hwport->iop_sbus_ctrl[0] & 0x10 )
171 iop_mmio_hwport->iop_sbus_ctrl[0] |= 0x10;
181void sceSifSetDChain(
void)
183 USE_IOP_MMIO_HWPORT();
184 USE_SIF_MMIO_HWPORT();
186 if ( (sif_mmio_hwport->controlreg & 0x40) == 0 )
187 sif_mmio_hwport->controlreg = 64;
188 iop_mmio_hwport->dmac2.newch[3].chcr = 0;
189 iop_mmio_hwport->dmac2.newch[3].bcr = (iop_mmio_hwport->dmac2.newch[3].bcr & 0xFFFF0000) | 32;
190 iop_mmio_hwport->dmac2.newch[3].chcr = 0x41000300;
193void sceSifSetDmaIntrHandler(
void (*handler)(
void *userdata),
void *arg)
195 sifman_internals.dma_intr_handler = handler;
196 sifman_internals.dma_intr_handler_userdata = arg;
199void sceSifResetDmaIntrHandler()
201 sifman_internals.dma_intr_handler = NULL;
202 sifman_internals.dma_intr_handler_userdata = NULL;
205static int sifman_interrupt_handler(
void *userdata)
207 void (*dma_intr_handler)(
void *userdata);
208 sif_completion_cb_info_arr_t *sif_otherbufcom;
210 sif_completion_cb_info_arr_t *p_sif_bufcom1;
211 sifman_internals_t *smi;
212 USE_IOP_MMIO_HWPORT();
213 USE_SIF_MMIO_HWPORT();
215 smi = (sifman_internals_t *)userdata;
216 dma_intr_handler = smi->dma_intr_handler;
217 if ( dma_intr_handler )
218 dma_intr_handler(smi->dma_intr_handler_userdata);
219 sif_otherbufcom = smi->sif_otherbufcom;
221 if ( sif_otherbufcom->count > 0 )
229 sif_otherbufcom->info[v5].func(sif_otherbufcom->info[v5].userdata);
230 sif_otherbufcom = smi->sif_otherbufcom;
232 }
while ( v4 < sif_otherbufcom->
count );
234 smi->sif_otherbufcom->count = 0;
235 if ( (iop_mmio_hwport->dmac2.newch[2].chcr & 0x1000000) == 0 && smi->dmatag_index > 0 )
237 iop_mmio_hwport->dmac2.newch[2].chcr = 0;
238 iop_mmio_hwport->dmac2.newch[2].tadr = (uiptr)(smi->sif_curbuf);
239 iop_mmio_hwport->dmac2.newch[2].bcr = (iop_mmio_hwport->dmac2.newch[2].bcr & 0xFFFF0000) | 32;
240 if ( (sif_mmio_hwport->controlreg & 0x20) == 0 )
241 sif_mmio_hwport->controlreg = 32;
243 smi->dmatag_index = 0;
244 if ( smi->sif_curbuf == smi->sif_buf1 )
246 smi->sif_curbuf = smi->sif_buf2;
247 smi->sif_curbufcom = &smi->sif_bufcom2;
248 p_sif_bufcom1 = &smi->sif_bufcom1;
252 smi->sif_curbufcom = &smi->sif_bufcom1;
253 p_sif_bufcom1 = &smi->sif_bufcom2;
254 smi->sif_curbuf = smi->sif_buf1;
256 smi->sif_otherbufcom = p_sif_bufcom1;
257 iop_mmio_hwport->dmac2.newch[2].chcr = 0x1000701;
262static int sif_dma_init(
void)
266 sifman_internals.sif_curbuf = sifman_internals.sif_buf1;
267 sifman_internals.sif_curbufcom = &sifman_internals.sif_bufcom1;
268 sifman_internals.dmatag_index = 0;
269 sifman_internals.sif_bufcom1.count = 0;
270 sifman_internals.sif_bufcom2.count = 0;
271 sifman_internals.sif_otherbufcom = &sifman_internals.sif_bufcom2;
272 sifman_internals.dma_intr_handler = 0;
273 sifman_internals.dma_intr_handler_userdata = 0;
280static int sif_dma_setup_tag(SifDmaTransfer_t *a1)
288 v1 = &sifman_internals.sif_curbuf[sifman_internals.dmatag_index];
289 v2 = (int)a1->src & 0xFFFFFF;
293 if ( (a1->attr & 2) != 0 )
294 v1->data = v2 | 0x40000000;
295 v1->words = v4 & 0xFFFFFF;
299 v1->count = v5 | 0x10000000;
300 if ( (a1->attr & 4) != 0 )
301 v1->count |= 0x80000000;
302 v1->addr = (int)a1->dest & 0x1FFFFFFF;
303 return ++sifman_internals.dmatag_index;
306static int set_dma_inner(SifDmaTransfer_t *dmat,
int count,
void (*func)(
void *userdata),
void *data)
312 sif_completion_cb_info_arr_t *p_sif_bufcom1;
313 USE_IOP_MMIO_HWPORT();
314 USE_SIF_MMIO_HWPORT();
316 if ( 32 - sifman_internals.dmatag_index <
count )
318 dmatag_index = sifman_internals.dmatag_index;
319 dma_count = sifman_internals.dma_count;
320 if ( sifman_internals.dmatag_index )
321 sifman_internals.sif_curbuf[sifman_internals.dmatag_index - 1].data &= ~0x80000000;
322 for ( i = 0; i <
count; ++dmat )
324 sif_dma_setup_tag(dmat);
327 sifman_internals.sif_curbuf[sifman_internals.dmatag_index - 1].data |= 0x80000000;
330 sifman_internals.sif_curbufcom->info[sifman_internals.sif_curbufcom->count].func = func;
331 sifman_internals.sif_curbufcom->info[sifman_internals.sif_curbufcom->count++].userdata = data;
333 v14 = dma_count << 16;
334 if ( (iop_mmio_hwport->dmac2.newch[2].chcr & 0x1000000) == 0 )
336 v14 = dma_count << 16;
337 if ( iop_mmio_hwport->dmac2.new_unusedch.madr == 0 )
339 v14 = dma_count << 16;
340 if ( (iop_mmio_hwport->dmac2.dicr2 & 0x4000000) == 0 )
342 iop_mmio_hwport->dmac2.newch[2].chcr = 0;
343 iop_mmio_hwport->dmac2.newch[2].tadr = (uiptr)(sifman_internals.sif_curbuf);
344 if ( (sif_mmio_hwport->controlreg & 0x20) == 0 )
345 sif_mmio_hwport->controlreg = 32;
346 iop_mmio_hwport->dmac2.newch[2].bcr = (iop_mmio_hwport->dmac2.newch[2].bcr & 0xFFFF0000) | 32;
347 sifman_internals.dmatag_index = 0;
348 ++sifman_internals.dma_count;
349 if ( sifman_internals.sif_curbuf == sifman_internals.sif_buf1 )
351 sifman_internals.sif_curbuf = sifman_internals.sif_buf2;
352 sifman_internals.sif_curbufcom = &sifman_internals.sif_bufcom2;
353 p_sif_bufcom1 = &sifman_internals.sif_bufcom1;
357 sifman_internals.sif_curbuf = sifman_internals.sif_buf1;
358 sifman_internals.sif_curbufcom = &sifman_internals.sif_bufcom1;
359 p_sif_bufcom1 = &sifman_internals.sif_bufcom2;
361 sifman_internals.sif_otherbufcom = p_sif_bufcom1;
362 iop_mmio_hwport->dmac2.newch[2].chcr = 0x1000701;
363 v14 = dma_count << 16;
367 return v14 | (dmatag_index << 8) | (u8)
count;
370int sceSifSetDma(SifDmaTransfer_t *dmat,
int count)
372 return set_dma_inner(dmat,
count, 0, 0);
375unsigned int sceSifSetDmaIntr(SifDmaTransfer_t *dmat,
int count,
void (*completioncb)(
void *userdata),
void *userdata)
377 return set_dma_inner(dmat,
count, completioncb, userdata);
380static int dma_stat_inner(
unsigned int a1)
382 USE_IOP_MMIO_HWPORT();
384 if ( (iop_mmio_hwport->dmac2.newch[2].chcr & 0x1000000) == 0 && !iop_mmio_hwport->dmac2.new_unusedch.madr )
386 if ( (iop_mmio_hwport->dmac2.dicr2 & 0x4000000) == 0 )
389 if ( sifman_internals.dma_count != ((a1 >> 16) & 0xFFFF) )
391 if ( sifman_internals.dma_count == (u16)(((a1 >> 16) & 0xFFFF) + 1) )
398int sceSifDmaStat(
int trid)
404 return dma_stat_inner(trid);
406 v2 = dma_stat_inner(trid);
411void sceSifSetOneDma(SifDmaTransfer_t dmat)
416 USE_IOP_MMIO_HWPORT();
417 USE_SIF_MMIO_HWPORT();
419 v1 = ((int)dmat.src & 0xFFFFFF) | 0x80000000;
420 v2 = ((
unsigned int)dmat.size >> 2) + ((dmat.size & 3) != 0);
421 sifman_internals.one.data = v1;
422 sifman_internals.one.words = v2 & 0xFFFFFF;
423 if ( (dmat.attr & 2) != 0 )
424 sifman_internals.one.data = v1 | 0x40000000;
428 sifman_internals.one.count = v3 | 0x10000000;
429 if ( (dmat.attr & 4) != 0 )
430 sifman_internals.one.count |= 0x80000000;
431 sifman_internals.one.addr = (int)dmat.dest & 0xFFFFFFF;
432 if ( (sif_mmio_hwport->controlreg & 0x20) == 0 )
433 sif_mmio_hwport->controlreg = 32;
434 iop_mmio_hwport->dmac2.newch[2].chcr = 0;
435 iop_mmio_hwport->dmac2.newch[2].tadr = (uiptr)&sifman_internals.one;
436 iop_mmio_hwport->dmac2.newch[2].bcr = (iop_mmio_hwport->dmac2.newch[2].bcr & 0xFFFF0000) | 32;
437 iop_mmio_hwport->dmac2.newch[2].chcr = 0x1000701;
442 USE_IOP_MMIO_HWPORT();
444 while ( iop_mmio_hwport->dmac2.newch[2].chcr & 0x1000000 )
450 USE_IOP_MMIO_HWPORT();
452 return iop_mmio_hwport->dmac2.newch[2].chcr & 0x1000000;
455void sceSifDma0Transfer(
void *addr,
int size,
int mode)
459 USE_IOP_MMIO_HWPORT();
460 USE_SIF_MMIO_HWPORT();
464 v4 = ((
unsigned int)size >> 2) + ((size & 3) != 0);
465 if ( (sif_mmio_hwport->controlreg & 0x20) == 0 )
466 sif_mmio_hwport->controlreg = 32;
467 iop_mmio_hwport->dmac2.newch[2].chcr = 0;
468 iop_mmio_hwport->dmac2.newch[2].madr = (
unsigned int)addr & 0xFFFFFF;
469 if ( (v4 & 0x1F) != 0 )
473 iop_mmio_hwport->dmac2.newch[2].bcr = ((v5 & 0xFFFF) << 16) | 32;
474 iop_mmio_hwport->dmac2.newch[2].chcr = 0x1000201;
479 USE_IOP_MMIO_HWPORT();
481 while ( iop_mmio_hwport->dmac2.newch[2].chcr & 0x1000000 )
485int sceSifDma0Sending()
487 USE_IOP_MMIO_HWPORT();
489 return iop_mmio_hwport->dmac2.newch[2].chcr & 0x1000000;
492void sceSifDma1Transfer(
void *addr,
int size,
int mode)
497 USE_IOP_MMIO_HWPORT();
498 USE_SIF_MMIO_HWPORT();
500 v4 = ((
unsigned int)size >> 2) + ((size & 3) != 0);
501 if ( (sif_mmio_hwport->controlreg & 0x40) == 0 )
502 sif_mmio_hwport->controlreg = 64;
503 iop_mmio_hwport->dmac2.newch[3].chcr = 0;
504 iop_mmio_hwport->dmac2.newch[3].madr = (
unsigned int)addr & 0xFFFFFF;
505 if ( (v4 & 0x1F) != 0 )
509 iop_mmio_hwport->dmac2.newch[3].bcr = ((v5 & 0xFFFF) << 16) | 32;
510 if ( (mode & 0x10) != 0 )
514 iop_mmio_hwport->dmac2.newch[3].chcr = v6 | 0x200;
519 USE_IOP_MMIO_HWPORT();
521 while ( iop_mmio_hwport->dmac2.newch[3].chcr & 0x1000000 )
525int sceSifDma1Sending()
527 USE_IOP_MMIO_HWPORT();
529 return iop_mmio_hwport->dmac2.newch[3].chcr & 0x1000000;
532void sceSifDma2Transfer(
void *addr,
int size,
int mode)
538 USE_IOP_MMIO_HWPORT();
539 USE_SIF_MMIO_HWPORT();
541 v4 = ((
unsigned int)size >> 2) + ((size & 3) != 0);
542 if ( (sif_mmio_hwport->controlreg & 0x80) == 0 )
543 sif_mmio_hwport->controlreg = 128;
545 iop_mmio_hwport->dmac1.oldch[2].chcr = 0;
546 iop_mmio_hwport->dmac1.oldch[2].madr = (
unsigned int)addr & 0xFFFFFF;
549 if ( (v4 & 0x1F) != 0 )
553 iop_mmio_hwport->dmac1.oldch[2].bcr = ((v6 & 0xFFFF) << 16) | (v5 & 0xFFFF);
554 if ( (mode & 1) != 0 )
562 if ( (mode & 0x10) != 0 )
568 iop_mmio_hwport->dmac1.oldch[2].chcr = v7;
573 USE_IOP_MMIO_HWPORT();
575 while ( iop_mmio_hwport->dmac1.oldch[2].chcr & 0x1000000 )
579int sceSifDma2Sending()
581 USE_IOP_MMIO_HWPORT();
583 return iop_mmio_hwport->dmac1.oldch[2].chcr & 0x1000000;
591u32 sceSifSetMSFlag(u32 val)
593 USE_SIF_MMIO_HWPORT();
595 sif_mmio_hwport->msflag = val;
604u32 sceSifSetSMFlag(u32 val)
606 USE_SIF_MMIO_HWPORT();
608 sif_mmio_hwport->smflag = val;
612u32 sceSifGetMainAddr()
614 USE_SIF_MMIO_HWPORT();
616 return sif_mmio_hwport->mscom;
619u32 sceSifGetSubAddr()
621 USE_SIF_MMIO_HWPORT();
623 return sif_mmio_hwport->smcom;
626u32 sceSifSetSubAddr(u32 addr)
628 USE_SIF_MMIO_HWPORT();
630 sif_mmio_hwport->smcom = addr;
631 return sif_mmio_hwport->smcom;
637 USE_IOP_MMIO_HWPORT();
639 v0 = iop_mmio_hwport->iop_sbus_ctrl[0];
640 iop_mmio_hwport->iop_sbus_ctrl[0] = v0 | 2;
642 iop_mmio_hwport->iop_sbus_ctrl[0] = v0 & 0xFFFFFFFD;
int CpuResumeIntr(int state)
int ReleaseIntrHandler(int irq)
int QueryIntrContext(void)
int DisableIntr(int irq, int *res)
int CpuSuspendIntr(int *state)
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)
u32 count
start sector of fragmented bd/file