PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
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
25packet2_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
60packet2_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
81void 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
88void 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
108void 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}
vif_code_t * vif_code_opened_at
enum Packet2Mode mode
enum Packet2Type type
dma_tag_t * tag_opened_at
u16 max_qwords_count
qword_t * next
Packet2Mode
Packet2Type
@ P2_TYPE_UNCACHED_ACCL
@ P2_TYPE_UNCACHED
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
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
packet2_t * packet2_create(u16 qwords, enum Packet2Type type, enum Packet2Mode mode, u8 tte)
Definition packet2.c:25