ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
packet2.c
Go to the documentation of this file.
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 }
Packet2Mode
Definition: packet2_types.h:32
Packet2Type
Definition: packet2_types.h:39
@ P2_TYPE_UNCACHED_ACCL
Definition: packet2_types.h:45
@ P2_TYPE_UNCACHED
Definition: packet2_types.h:43
void packet2_print(packet2_t *packet2, u32 qw_count)
Definition: packet2.c:108
void packet2_free(packet2_t *packet2)
Definition: packet2.c:81
void packet2_print_qw_count(packet2_t *packet2)
Definition: packet2.c:127
void packet2_reset(packet2_t *packet2, u8 clear_mem)
Definition: packet2.c:88
packet2_t * packet2_create(u16 qwords, enum Packet2Type type, enum Packet2Mode mode, u8 tte)
Definition: packet2.c:25
static u32 packet2_get_qw_count(packet2_t *packet2)
Definition: packet2.h:200
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
void packet2_add(packet2_t *a, packet2_t *b)
Definition: packet2.c:101
void FlushCache(s32 operation)
#define P2_ALIGNMENT
Definition: packet2.c:18
#define P2_MAKE_PTR_NORMAL(PTR)
Definition: packet2.c:19
s32 mode
Definition: rpc_client.c:15
vif_code_t * vif_code_opened_at
enum Packet2Mode mode
enum Packet2Type type
dma_tag_t * tag_opened_at
qword_t * base
u16 max_qwords_count
qword_t * next
#define NULL
Definition: tamtypes.h:91
unsigned int u32
Definition: tamtypes.h:30
unsigned short u16
Definition: tamtypes.h:24
unsigned char u8
Definition: tamtypes.h:23