PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
packet2_chain.h
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# (c) 2020 h4570 Sandro Sobczyński <sandro.sobczynski@gmail.com>
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
19#ifndef __PACKET2_CHAIN_H__
20#define __PACKET2_CHAIN_H__
21
22#include <packet2.h>
23#include <packet2_types.h>
24#include <assert.h>
25
26#define PACKET2_COUNT_QWC 1 << 16
27
28#ifdef __cplusplus
29extern "C"
30{
31#endif
32
33 // ---
34 // DMA tag management
35 // ---
36
48 static inline void packet2_chain_set_dma_tag(dma_tag_t *tag, u32 qwc, u32 pce, u32 id, u8 irq, const u128 *addr, u8 spr)
49 {
50 tag->QWC = qwc;
51 tag->PCE = pce;
52 tag->ID = id;
53 tag->IRQ = irq;
54 tag->ADDR = (u64)((u32)addr);
55 tag->SPR = spr;
56 }
57
74 static inline void packet2_chain_add_dma_tag(packet2_t *packet2, u32 qwc, u32 pce, enum DmaTagType id, u8 irq, const u128 *addr, u8 spr)
75 {
76 assert(((u32)packet2->next & 0xF) == 0); // Free space in packet is aligned properly.
77 assert(packet2->tag_opened_at == NULL); // All previous tags are closed.
78
79 if (qwc == PACKET2_COUNT_QWC)
80 {
81 packet2_chain_set_dma_tag((dma_tag_t *)packet2->next, 0, pce, id, irq, addr, spr); // placeholder
82 packet2->tag_opened_at = (dma_tag_t *)packet2->next;
83 }
84 else
85 {
86 packet2_chain_set_dma_tag((dma_tag_t *)packet2->next, qwc, pce, id, irq, addr, spr);
87 packet2->tag_opened_at = (dma_tag_t *)NULL;
88 }
89 if (!packet2->tte)
90 packet2_advance_next(packet2, sizeof(dma_tag_t));
91 else
92 packet2_advance_next(packet2, sizeof(u64));
93 }
94
100 static inline void packet2_chain_close_tag(packet2_t *packet2)
101 {
102 assert(packet2->tag_opened_at != NULL); // There is opened tag.
103 assert(((u32)packet2->next & 0xF) == 0); // Free space in packet is aligned properly.
104 packet2->tag_opened_at->QWC = (((u32)packet2->next - (u32)packet2->tag_opened_at) / 16 - 1);
105 packet2->tag_opened_at = (dma_tag_t *)NULL;
106 }
107
108 // ---
109 // DMA tags
110 // ---
111
122 static inline void packet2_chain_open_cnt(packet2_t *packet2, u8 irq, u32 pce, u8 spr)
123 {
124 packet2_chain_add_dma_tag(packet2, PACKET2_COUNT_QWC, pce, P2_DMA_TAG_CNT, irq, 0, spr);
125 }
126
137 static inline void packet2_chain_open_end(packet2_t *packet2, u8 irq, u32 pce)
138 {
139 packet2_chain_add_dma_tag(packet2, PACKET2_COUNT_QWC, pce, P2_DMA_TAG_END, irq, 0, 0);
140 }
141
154 static inline void packet2_chain_ref(packet2_t *packet2, const void *ref_data, u32 qw_length, u8 irq, u8 spr, u32 pce)
155 {
156 assert(((u32)packet2->next & 0xF) == 0); // Free space in packet is aligned properly.
157 packet2_chain_add_dma_tag(packet2, qw_length, pce, P2_DMA_TAG_REF, irq, (const u128 *)ref_data, spr);
158 }
159
170 static inline void packet2_chain_next(packet2_t *packet2, const dma_tag_t *next_tag, u8 irq, u8 spr, u32 pce)
171 {
172 assert(((u32)packet2->next & 0xF) == 0); // Free space in packet is aligned properly.
173 packet2_chain_add_dma_tag(packet2, PACKET2_COUNT_QWC, pce, P2_DMA_TAG_NEXT, irq, (u128 *)next_tag, spr);
174 }
175
188 static inline void packet2_chain_refs(packet2_t *packet2, const void *ref_data, u32 qw_length, u8 irq, u8 spr, u32 pce)
189 {
190 assert(((u32)packet2->next & 0xF) == 0); // Free space in packet is aligned properly.
191 packet2_chain_add_dma_tag(packet2, qw_length, pce, P2_DMA_TAG_REFS, irq, (const u128 *)ref_data, spr);
192 }
193
206 static inline void packet2_chain_refe(packet2_t *packet2, const void *ref_data, u32 qw_length, u8 irq, u8 spr, u32 pce)
207 {
208 assert(((u32)packet2->next & 0xF) == 0); // Free space in packet is aligned properly.
209 packet2_chain_add_dma_tag(packet2, qw_length, pce, P2_DMA_TAG_REFE, irq, (const u128 *)ref_data, spr);
210 }
211
223 static inline void packet2_chain_call(packet2_t *packet2, const void *next_tag, u8 irq, u8 spr, u32 pce)
224 {
225 assert(((u32)packet2->next & 0xF) == 0); // Free space in packet is aligned properly.
226 packet2_chain_add_dma_tag(packet2, PACKET2_COUNT_QWC, pce, P2_DMA_TAG_CALL, irq, (u128 *)next_tag, spr);
227 }
228
238 static inline void packet2_chain_ret(packet2_t *packet2, u8 irq, u32 pce)
239 {
240 packet2_chain_add_dma_tag(packet2, PACKET2_COUNT_QWC, pce, P2_DMA_TAG_RET, irq, 0, 0);
241 }
242
243#ifdef __cplusplus
244}
245#endif
246
247#endif /* __PACKET2_CHAIN_H__ */
248
// end of packet2_chain subgroup
static void packet2_chain_refe(packet2_t *packet2, const void *ref_data, u32 qw_length, u8 irq, u8 spr, u32 pce)
static void packet2_chain_add_dma_tag(packet2_t *packet2, u32 qwc, u32 pce, enum DmaTagType id, u8 irq, const u128 *addr, u8 spr)
static void packet2_chain_close_tag(packet2_t *packet2)
static void packet2_chain_set_dma_tag(dma_tag_t *tag, u32 qwc, u32 pce, u32 id, u8 irq, const u128 *addr, u8 spr)
static void packet2_chain_next(packet2_t *packet2, const dma_tag_t *next_tag, u8 irq, u8 spr, u32 pce)
static void packet2_chain_ref(packet2_t *packet2, const void *ref_data, u32 qw_length, u8 irq, u8 spr, u32 pce)
static void packet2_chain_open_cnt(packet2_t *packet2, u8 irq, u32 pce, u8 spr)
static void packet2_chain_ret(packet2_t *packet2, u8 irq, u32 pce)
static void packet2_chain_open_end(packet2_t *packet2, u8 irq, u32 pce)
static void packet2_chain_refs(packet2_t *packet2, const void *ref_data, u32 qw_length, u8 irq, u8 spr, u32 pce)
static void packet2_chain_call(packet2_t *packet2, const void *next_tag, u8 irq, u8 spr, u32 pce)
dma_tag_t * tag_opened_at
qword_t * next
DmaTagType
@ P2_DMA_TAG_NEXT
@ P2_DMA_TAG_CNT
@ P2_DMA_TAG_RET
@ P2_DMA_TAG_CALL
@ P2_DMA_TAG_REF
@ P2_DMA_TAG_REFS
@ P2_DMA_TAG_END
@ P2_DMA_TAG_REFE
static void packet2_advance_next(packet2_t *packet2, u32 i)
Definition packet2.h:96