PS2SDK
PS2 Homebrew Libraries
packet2.c
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 
11 #include <malloc.h>
12 #include <kernel.h>
13 #include <assert.h>
14 #include <packet2.h>
15 #include <string.h>
16 #include <stdio.h>
17 
18 #define P2_ALIGNMENT 64
19 #define P2_MAKE_PTR_NORMAL(PTR) ((u32)(PTR)&0x0FFFFFFF)
20 
21 // ---
22 // Packet2 management
23 // ---
24 
25 packet2_t *packet2_create(u16 qwords, enum Packet2Type type, enum Packet2Mode mode, u8 tte)
26 {
27  packet2_t *packet2 = (packet2_t *)calloc(1, sizeof(packet2_t));
28  if (packet2 == NULL)
29  return NULL;
30 
31  packet2->max_qwords_count = qwords;
32  packet2->type = type;
33  packet2->mode = mode;
34  packet2->tte = tte;
35  packet2->tag_opened_at = NULL;
36  packet2->vif_code_opened_at = NULL;
37 
38  // Dma buffer size should be a whole number of cache lines (64 bytes = 4 quads)
39  assert(!((packet2->type == P2_TYPE_UNCACHED || packet2->type == P2_TYPE_UNCACHED_ACCL) && packet2->max_qwords_count & (4 - 1)));
40 
41  u32 byte_size = packet2->max_qwords_count << 4;
42 
43  if ((packet2->base = memalign(P2_ALIGNMENT, byte_size)) == NULL)
44  {
45  free(packet2);
46  return NULL;
47  }
48 
49  packet2->base = packet2->next = (qword_t *)((u32)packet2->base | packet2->type);
50 
51  memset(packet2->base, 0, byte_size);
52 
53  // "I hate to do this, but I've wasted FAR too much time hunting down cache incoherency"
54  if (packet2->type == P2_TYPE_UNCACHED || packet2->type == P2_TYPE_UNCACHED_ACCL)
55  FlushCache(0);
56 
57  return packet2;
58 }
59 
60 packet2_t *packet2_create_from(qword_t *base, qword_t *next, u16 qwords, enum Packet2Type type, enum Packet2Mode mode, u8 tte)
61 {
62  // Dma buffer size should be a whole number of cache lines (64 bytes = 4 quads)
63  assert(!((type == P2_TYPE_UNCACHED || type == P2_TYPE_UNCACHED_ACCL) && qwords & (4 - 1)));
64 
65  // Dma buffer should be aligned on a cache line (64-byte boundary)
66  assert(!((type == P2_TYPE_UNCACHED || type == P2_TYPE_UNCACHED_ACCL) && (u32)base & (64 - 1)));
67 
68  packet2_t *packet2 = (packet2_t *)calloc(1, sizeof(packet2_t));
69  if (packet2 == NULL)
70  return NULL;
71 
72  packet2->base = base;
73  packet2->next = next;
74  packet2->max_qwords_count = qwords;
75  packet2->type = type;
76  packet2->tte = tte;
77  packet2->mode = mode;
78  return packet2;
79 }
80 
81 void packet2_free(packet2_t *packet2)
82 {
83  if (packet2->base != NULL)
84  free((qword_t *)P2_MAKE_PTR_NORMAL(packet2->base));
85  free(packet2);
86 }
87 
88 void packet2_reset(packet2_t *packet2, u8 clear_mem)
89 {
90  packet2->next = packet2->base;
91  packet2->vif_code_opened_at = NULL;
92  packet2->tag_opened_at = NULL;
93  if (clear_mem)
94  memset(packet2->base, 0, packet2->max_qwords_count << 4);
95 }
96 
97 // ---
98 // Utils
99 // ---
100 
102 {
104  memcpy(a->next, b->base, (u32)b->next - (u32)b->base);
105  a->next = a->base + packet2_get_qw_count(b) + 1;
106 }
107 
108 void packet2_print(packet2_t *packet2, u32 qw_count)
109 {
110  if (qw_count == 0)
111  qw_count = ((u32)packet2->next - (u32)packet2->base) >> 4;
112  printf("\n============================\n");
113  printf("Packet2: Dumping %d words...\n", ((u32)packet2->next - (u32)packet2->base) >> 2);
114  u32 i = 0;
115  u32 *nextWord;
116  for (nextWord = (u32 *)packet2->base; nextWord != (u32 *)packet2->next; nextWord++, i++)
117  {
118  if ((i % 4) == 0)
119  printf("\n0x%08x: ", (u32)nextWord);
120  printf("0x%08x ", *nextWord);
121  if (i / 4 == qw_count)
122  break;
123  }
124  printf("\n============================\n");
125 }
126 
128 {
129  printf("Packet2: Qwords count:%d \n", packet2_get_qw_count(packet2));
130 }
kernel.h
P2_TYPE_UNCACHED_ACCL
@ P2_TYPE_UNCACHED_ACCL
Definition: packet2_types.h:45
packet2_t::mode
enum Packet2Mode mode
Definition: packet2_types.h:307
packet2_t::tte
u8 tte
Definition: packet2_types.h:315
packet2_print
void packet2_print(packet2_t *packet2, u32 qw_count)
Definition: packet2.c:108
Packet2Mode
Packet2Mode
Definition: packet2_types.h:31
packet2_create
packet2_t * packet2_create(u16 qwords, enum Packet2Type type, enum Packet2Mode mode, u8 tte)
Definition: packet2.c:25
packet2_t
Definition: packet2_types.h:300
packet2_t::next
qword_t * next
Definition: packet2_types.h:319
packet2_create_from
packet2_t * packet2_create_from(qword_t *base, qword_t *next, u16 qwords, enum Packet2Type type, enum Packet2Mode mode, u8 tte)
Definition: packet2.c:60
packet2_get_qw_count
static u32 packet2_get_qw_count(packet2_t *packet2)
Definition: packet2.h:200
stdio.h
packet2_t::tag_opened_at
dma_tag_t * tag_opened_at
Definition: packet2_types.h:324
packet2_free
void packet2_free(packet2_t *packet2)
Definition: packet2.c:81
packet2_reset
void packet2_reset(packet2_t *packet2, u8 clear_mem)
Definition: packet2.c:88
packet2_t::vif_code_opened_at
vif_code_t * vif_code_opened_at
Definition: packet2_types.h:329
P2_TYPE_UNCACHED
@ P2_TYPE_UNCACHED
Definition: packet2_types.h:43
packet2_t::type
enum Packet2Type type
Definition: packet2_types.h:305
packet2_t::max_qwords_count
u16 max_qwords_count
Definition: packet2_types.h:303
packet2_add
void packet2_add(packet2_t *a, packet2_t *b)
Definition: packet2.c:101
packet2_print_qw_count
void packet2_print_qw_count(packet2_t *packet2)
Definition: packet2.c:127
Packet2Type
Packet2Type
Definition: packet2_types.h:38