test RSX DMA with positive and negative pitch values
[ps3freebsd_ps3gpu_test.git] / ps3gpu_test.c
blob4a4c1656f172952199fe71f90ecb0d3c85d4f450
1 /*-
2 * Copyright (C) 2011, 2012 glevand <geoffrey.levand@mail.ru>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * $FreeBSD$
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/uio.h>
37 #include <sys/ioctl.h>
38 #include <sys/mman.h>
39 #include <sys/fbio.h>
40 #include <sys/consio.h>
41 #include <fcntl.h>
42 #include <unistd.h>
44 #include "ps3gpu_ctl.h"
45 #include "ps3gpu_mth.h"
47 #define PS3GPU_DEV_PATH "/dev/ps3gpu"
49 #define DISPLAY_WIDTH 1920
50 #define DISPLAY_HEIGHT 1080
51 #define DISPLAY_BPP 4
52 #define DISPLAY_PITCH (DISPLAY_WIDTH * DISPLAY_BPP)
54 static uint32_t reset_gpu_state[] = {
55 /* These commands are executed every time after flip to reset GPU state !!! */
57 /* program 1 */
59 0x00040000,
60 0x31337000,
62 0x003c0180,
63 0x66604200,
64 0xfeed0000,
65 0xfeed0001,
66 0xfeed0000,
67 0x00000000,
68 0xfeed0000,
69 0xfeed0000,
70 0xfeed0000,
71 0xfeed0001,
72 0x66606660,
73 0x66626660,
74 0x00000000,
75 0x00000000,
76 0xfeed0000,
77 0xfeed0000,
79 0x00040060,
80 0x66616661,
82 0x00340200,
83 0x00000000,
84 0x00000000,
85 0x00000121,
86 0x00000040,
87 0x00000000,
88 0x00000000,
89 0x00000000,
90 0x00000040,
91 0x00000001,
92 0x00000080,
93 0x00000100,
94 0x00000040,
95 0x00000000,
97 0x00100280,
98 0x00000040,
99 0x00000040,
100 0x00000000,
101 0x00000000,
103 0x00041d80,
104 0x00000003,
106 0x004802b8,
107 0x00000000,
108 0x00000000,
109 0x0fff0000,
110 0x0fff0000,
111 0x0fff0000,
112 0x0fff0000,
113 0x0fff0000,
114 0x0fff0000,
115 0x0fff0000,
116 0x0fff0000,
117 0x0fff0000,
118 0x0fff0000,
119 0x0fff0000,
120 0x0fff0000,
121 0x0fff0000,
122 0x0fff0000,
123 0x0fff0000,
124 0x0fff0000,
126 0x00081d98,
127 0x0fff0000,
128 0x0fff0000,
130 0x00041da4,
131 0x00000000,
133 0x000403b0,
134 0x00100000,
136 0x00041454,
137 0x00000000,
139 0x00041ff4,
140 0x003fffff,
142 0x00181fc0,
143 0x00000000,
144 0x06144321,
145 0xedcba987,
146 0x0000006f,
147 0x00171615,
148 0x001b1a19,
150 0x00280b40,
151 0x00000000,
152 0x00000000,
153 0x00000000,
154 0x00000000,
155 0x00000000,
156 0x00000000,
157 0x00000000,
158 0x00000000,
159 0x00000000,
160 0x00000000,
162 0x00040a0c,
163 0x00000000,
165 0x000c0a60,
166 0x00000000,
167 0x00000000,
168 0x00000000,
170 0x00080a78,
171 0x00000000,
172 0x00000000,
174 0x00041428,
175 0x00000001,
177 0x00041d88,
178 0x00001000,
180 0x00041e94,
181 0x00000011,
183 0x00041450,
184 0x00080003,
186 0x00041d64,
187 0x02000000,
189 0x0004145c,
190 0x00000001,
192 0x00041fe0,
193 0x00000001,
195 0x00400b00,
196 0x00002dc8,
197 0x00002dc8,
198 0x00002dc8,
199 0x00002dc8,
200 0x00002dc8,
201 0x00002dc8,
202 0x00002dc8,
203 0x00002dc8,
204 0x00002dc8,
205 0x00002dc8,
206 0x00002dc8,
207 0x00002dc8,
208 0x00002dc8,
209 0x00002dc8,
210 0x00002dc8,
211 0x00002dc8,
213 0x001008cc,
214 0x00000800,
215 0x00000000,
216 0x00000000,
217 0x00000000,
219 0x00100240,
220 0x0000ffff,
221 0x00000000,
222 0x00000000,
223 0x00000000,
225 0x00c003c0,
226 0x00010101,
227 0x00010101,
228 0x00010101,
229 0x00010101,
230 0x00010101,
231 0x00010101,
232 0x00010101,
233 0x00010101,
234 0x00010101,
235 0x00010101,
236 0x00010101,
237 0x00010101,
238 0x00010101,
239 0x00010101,
240 0x00010101,
241 0x00010101,
242 0x00007421,
243 0x00007421,
244 0x00007421,
245 0x00007421,
246 0x00007421,
247 0x00007421,
248 0x00007421,
249 0x00007421,
250 0x00007421,
251 0x00007421,
252 0x00007421,
253 0x00007421,
254 0x00007421,
255 0x00007421,
256 0x00007421,
257 0x00007421,
258 0x9aabaa98,
259 0x66666789,
260 0x98766666,
261 0x89aabaa9,
262 0x99999999,
263 0x88888889,
264 0x98888888,
265 0x99999999,
266 0x56676654,
267 0x33333345,
268 0x54333333,
269 0x45667665,
270 0xaabbba99,
271 0x66667899,
272 0x99876666,
273 0x99abbbaa,
275 0x00081738,
276 0x00000000,
277 0x00000000,
279 0x0004e000,
280 0xcafebabe,
282 /* program 2 */
284 0x00080308,
285 0x00000207,
286 0x00000000,
288 0x00040304,
289 0x00000000,
291 0x000c0350,
292 0x00000207,
293 0x00000000,
294 0x000000ff,
296 0x0004034c,
297 0x000000ff,
299 0x000c035c,
300 0x00001e00,
301 0x00001e00,
302 0x00001e00,
304 0x0004031c,
305 0x00000000,
307 0x0004037c,
308 0x00000000,
310 0x00040310, /* blend control */
311 0x00000000, /* disable */
313 0x0004036c,
314 0x00000000,
316 0x00040320,
317 0x80068006,
319 0x00080314,
320 0x00010001,
321 0x00000000,
323 0x00041d8c,
324 0xffffff00,
326 0x00041d94,
327 0x00000000,
329 0x00040100,
330 0x00000000,
332 0x00040324,
333 0x01010101,
335 0x0004183c,
336 0x00000000,
338 0x00041830,
339 0x00000405,
341 0x00080384,
342 0x00000000,
343 0x3f800000,
345 0x00040380,
346 0x00000000,
348 0x00040a6c,
349 0x00000201,
351 0x00040a70,
352 0x00000001,
354 0x00040a74,
355 0x00000000,
357 0x00040300,
358 0x00000001,
360 0x00041fec,
361 0x00000000,
363 0x00041fc0,
364 0x00000000,
366 0x00041834, /* set front face mode */
367 0x00000901, /* ccw */
369 0x000403b8,
370 0x00000008,
372 0x00040374, /* logic op control */
373 0x00000000, /* disable */
375 0x00040378, /* set logic op */
376 0x00001503, /* copy */
378 0x00041ee0,
379 0x3f800000,
381 0x00040a68,
382 0x00000000,
384 0x00080a78,
385 0x00000000,
386 0x00000000,
388 0x00041dac,
389 0x00000000,
391 0x00041db0,
392 0xffffffff,
394 0x000808c0,
395 0x10000000,
396 0x10000000,
398 0x00040368, /* set shade model */
399 0x00001d01, /* smooth */
401 0x000c0330,
402 0x00000207,
403 0x00000000,
404 0x000000ff,
406 0x0004032c,
407 0x000000ff,
409 0x000c033c,
410 0x00001e00,
411 0x00001e00,
412 0x00001e00,
414 0x00040328,
415 0x00000000,
417 0x00041a08,
418 0x00030101,
420 0x00041a1c,
421 0x00000000,
423 0x00041a0c,
424 0x00060000,
426 0x00041a14,
427 0x02052000,
429 0x00041a28,
430 0x00030101,
432 0x00041a3c,
433 0x00000000,
435 0x00041a2c,
436 0x00060000,
438 0x00041a34,
439 0x02052000,
441 0x00041a48,
442 0x00030101,
444 0x00041a5c,
445 0x00000000,
447 0x00041a4c,
448 0x00060000,
450 0x00041a54,
451 0x02052000,
453 0x00041a68,
454 0x00030101,
456 0x00041a7c,
457 0x00000000,
459 0x00041a6c,
460 0x00060000,
462 0x00041a74,
463 0x02052000,
465 0x00041a88,
466 0x00030101,
468 0x00041a9c,
469 0x00000000,
471 0x00041a8c,
472 0x00060000,
474 0x00041a94,
475 0x02052000,
477 0x00041aa8,
478 0x00030101,
480 0x00041abc,
481 0x00000000,
483 0x00041aac,
484 0x00060000,
486 0x00041ab4,
487 0x02052000,
489 0x00041ac8,
490 0x00030101,
492 0x00041adc,
493 0x00000000,
495 0x00041acc,
496 0x00060000,
498 0x00041ad4,
499 0x02052000,
501 0x00041ae8,
502 0x00030101,
504 0x00041afc,
505 0x00000000,
507 0x00041aec,
508 0x00060000,
510 0x00041af4,
511 0x02052000,
513 0x00041b08,
514 0x00030101,
516 0x00041b1c,
517 0x00000000,
519 0x00041b0c,
520 0x00060000,
522 0x00041b14,
523 0x02052000,
525 0x00041b28,
526 0x00030101,
528 0x00041b3c,
529 0x00000000,
531 0x00041b2c,
532 0x00060000,
534 0x00041b34,
535 0x02052000,
537 0x00041b48,
538 0x00030101,
540 0x00041b5c,
541 0x00000000,
543 0x00041b4c,
544 0x00060000,
546 0x00041b54,
547 0x02052000,
549 0x00041b68,
550 0x00030101,
552 0x00041b7c,
553 0x00000000,
555 0x00041b6c,
556 0x00060000,
558 0x00041b74,
559 0x02052000,
561 0x00041b88,
562 0x00030101,
564 0x00041b9c,
565 0x00000000,
567 0x00041b8c,
568 0x00060000,
570 0x00041b94,
571 0x02052000,
573 0x00041ba8,
574 0x00030101,
576 0x00041bbc,
577 0x00000000,
579 0x00041bac,
580 0x00060000,
582 0x00041bb4,
583 0x02052000,
585 0x00041bc8,
586 0x00030101,
588 0x00041bdc,
589 0x00000000,
591 0x00041bcc,
592 0x00060000,
594 0x00041bd4,
595 0x02052000,
597 0x00041be8,
598 0x00030101,
600 0x00041bfc,
601 0x00000000,
603 0x00041bec,
604 0x00060000,
606 0x00041bf4,
607 0x02052000,
609 0x00040348,
610 0x00000000,
612 0x00041740,
613 0x00000002,
615 0x00041680,
616 0x00000000,
618 0x00041744,
619 0x00000002,
621 0x00041684,
622 0x00000000,
624 0x00041748,
625 0x00000002,
627 0x00041688,
628 0x00000000,
630 0x0004174c,
631 0x00000002,
633 0x0004168c,
634 0x00000000,
636 0x00041750,
637 0x00000002,
639 0x00041690,
640 0x00000000,
642 0x00041754,
643 0x00000002,
645 0x00041694,
646 0x00000000,
648 0x00041758,
649 0x00000002,
651 0x00041698,
652 0x00000000,
654 0x0004175c,
655 0x00000002,
657 0x0004169c,
658 0x00000000,
660 0x00041760,
661 0x00000002,
663 0x000416a0,
664 0x00000000,
666 0x00041764,
667 0x00000002,
669 0x000416a4,
670 0x00000000,
672 0x00041768,
673 0x00000002,
675 0x000416a8,
676 0x00000000,
678 0x0004176c,
679 0x00000002,
681 0x000416ac,
682 0x00000000,
684 0x00041770,
685 0x00000002,
687 0x000416b0,
688 0x00000000,
690 0x00041774,
691 0x00000002,
693 0x000416b4,
694 0x00000000,
696 0x00041778,
697 0x00000002,
699 0x000416b8,
700 0x00000000,
702 0x0004177c,
703 0x00000002,
705 0x000416bc,
706 0x00000000,
708 0x00080a00,
709 0x10000000,
710 0x10000000,
711 0x00080394,
712 0x00000000,
713 0x3f800000,
715 0x00200a20,
716 0x45000000,
717 0x45000000,
718 0x3f000000,
719 0x00000000,
720 0x45000000,
721 0x45000000,
722 0x3f000000,
723 0x00000000,
725 0x00200a20,
726 0x45000000,
727 0x45000000,
728 0x3f000000,
729 0x00000000,
730 0x45000000,
731 0x45000000,
732 0x3f000000,
733 0x00000000,
735 0x00041d7c,
736 0xffff0000,
738 0x0004182c,
739 0x00001b02,
741 0x00041d90,
742 0x00000000,
744 0x00040370,
745 0x00000000,
747 0x00041828,
748 0x00001b02,
750 0x000403bc,
751 0x00000000,
753 0x00041db4,
754 0x00000000,
756 0x00041ee4,
757 0x00000000,
759 0x00041ee8,
760 0x00000000,
762 0x00041838,
763 0x00000000,
765 0x0004147c,
766 0x00000000,
768 0x00041e98,
769 0x01000000,
771 0x00041478,
772 0x00000000,
774 0x00041ff0,
775 0x0000ffff,
777 0x000417cc,
778 0x00000000,
780 0x00040908,
781 0x00000101,
783 0x0004091c,
784 0x00000000,
786 0x0004090c,
787 0x00060000,
789 0x00040914,
790 0x00000000,
792 0x00040928,
793 0x00000101,
795 0x0004093c,
796 0x00000000,
798 0x0004092c,
799 0x00060000,
801 0x00040934,
802 0x00000000,
804 0x00040948,
805 0x00000101,
807 0x0004095c,
808 0x00000000,
810 0x0004094c,
811 0x00060000,
813 0x00040954,
814 0x00000000,
816 0x00040968,
817 0x00000101,
819 0x0004097c,
820 0x00000000,
822 0x0004096c,
823 0x00060000,
825 0x00040974,
826 0x00000000,
828 0x00040238,
829 0x00000000,
831 0x00041d78,
832 0x00000001,
834 0x0004142c,
835 0x00000000,
837 0x00041ff8,
838 0x00000000,
840 0x00041fe8,
841 0x00000000,
843 /* program 3 */
845 0x00042000,
846 0x31337303,
848 0x000c2180,
849 0x66604200,
850 0xfeed0001,
851 0xfeed0000,
853 0x00046000,
854 0x313371c3,
857 0x000c6180,
858 0x66604200,
859 0xfeed0000,
860 0xfeed0000,
863 0x0004a000,
864 0x31337808,
866 0x0020a180,
867 0x66604200,
868 0x00000000,
869 0x00000000,
870 0x00000000,
871 0x00000000,
872 0x00000000,
873 0x00000000,
874 0x313371c3,
876 0x0008a2fc,
877 0x00000003,
878 0x00000004,
880 0x00048000,
881 0x31337a73,
883 0x00088180,
884 0x66604200,
885 0xfeed0000,
887 0x0004c000,
888 0x3137af00,
890 0x0004c180,
891 0x66604200,
893 0x00020000, /* return */
896 static const uint64_t cursor_bitmap[64] = {
897 0x000000ffff000000,
898 0x0000ff0000ff0000,
899 0x00ff00000000ff00,
900 0xff000000000000ff,
901 0xff000000000000ff,
902 0xff000000000000ff,
903 0xff000000000000ff,
904 0xff000000000000ff,
905 0xff000000000000ff,
906 0xff000000000000ff,
907 0xff000000000000ff,
908 0xff000000000000ff,
909 0xff000000000000ff,
910 0xff000000000000ff,
911 0xff000000000000ff,
912 0xff000000000000ff,
913 0xff000000000000ff,
914 0xff000000000000ff,
915 0xff000000000000ff,
916 0xff000000000000ff,
917 0xff000000000000ff,
918 0xff000000000000ff,
919 0xff000000000000ff,
920 0xff000000000000ff,
921 0xff000000000000ff,
922 0xff000000000000ff,
923 0xff000000000000ff,
924 0xff000000000000ff,
925 0xff000000000000ff,
926 0xff000000000000ff,
927 0xff000000000000ff,
928 0xff000000000000ff,
929 0xff000000000000ff,
930 0xff000000000000ff,
931 0xff000000000000ff,
932 0xff000000000000ff,
933 0xff000000000000ff,
934 0xff000000000000ff,
935 0xff000000000000ff,
936 0xff000000000000ff,
937 0xff000000000000ff,
938 0xff000000000000ff,
939 0xff000000000000ff,
940 0xff000000000000ff,
941 0xff000000000000ff,
942 0xff000000000000ff,
943 0xff000000000000ff,
944 0xff000000000000ff,
945 0xff000000000000ff,
946 0xff000000000000ff,
947 0xff000000000000ff,
948 0xff000000000000ff,
949 0xff000000000000ff,
950 0xff000000000000ff,
951 0xff000000000000ff,
952 0xff000000000000ff,
953 0xff000000000000ff,
954 0xff000000000000ff,
955 0xff000000000000ff,
956 0xff000000000000ff,
957 0xff000000000000ff,
958 0x00ff00000000ff00,
959 0x0000ff0000ff0000,
960 0x000000ffff000000,
963 static int
964 update_cursor(int fd, int context_id, int head, unsigned long offset,
965 int x, int y, int enable)
967 struct ps3gpu_ctl_cursor_enable cursor_enable;
968 struct ps3gpu_ctl_cursor_set_image cursor_set_image;
969 struct ps3gpu_ctl_cursor_set_position cursor_set_position;
970 int err;
972 /* Disable cursor */
974 cursor_enable.context_id = context_id;
975 cursor_enable.head = head;
976 cursor_enable.enable = 0;
978 err = ioctl(fd, PS3GPU_CTL_CURSOR_ENABLE, &cursor_enable);
979 if (err < 0) {
980 perror("ioctl");
981 return (err);
984 /* Set cursor image */
986 cursor_set_image.context_id = context_id;
987 cursor_set_image.head = head;
988 cursor_set_image.offset = offset;
990 err = ioctl(fd, PS3GPU_CTL_CURSOR_SET_IMAGE, &cursor_set_image);
991 if (err < 0) {
992 perror("ioctl");
993 return (err);
996 /* Set cursor position */
998 cursor_set_position.context_id = context_id;
999 cursor_set_position.head = head;
1000 cursor_set_position.x = x;
1001 cursor_set_position.y = y;
1003 err = ioctl(fd, PS3GPU_CTL_CURSOR_SET_POSITION, &cursor_set_position);
1004 if (err < 0) {
1005 perror("ioctl");
1006 return (err);
1009 /* Enable cursor */
1011 cursor_enable.context_id = context_id;
1012 cursor_enable.head = head;
1013 cursor_enable.enable = enable;
1015 err = ioctl(fd, PS3GPU_CTL_CURSOR_ENABLE, &cursor_enable);
1016 if (err < 0) {
1017 perror("ioctl");
1018 return (err);
1021 return (0);
1024 static int
1025 transfer_data(uint32_t *fifo, uint32_t src, uint32_t dst,
1026 uint32_t dst_offset, int32_t dst_pitch, int32_t src_offset, uint32_t src_pitch,
1027 uint32_t row_length, uint32_t row_count)
1029 int h;
1030 int i = 0;
1032 fifo[i++] = 0x00082184;
1033 fifo[i++] = src;
1034 fifo[i++] = dst;
1036 while (row_count) {
1037 h = row_count;
1038 if (h > 2047)
1039 h = 2047;
1041 fifo[i++] = 0x0020230c;
1042 fifo[i++] = src_offset;
1043 fifo[i++] = dst_offset;
1044 fifo[i++] = src_pitch;
1045 fifo[i++] = dst_pitch;
1046 fifo[i++] = row_length;
1047 fifo[i++] = h;
1048 fifo[i++] = 0x00000101;
1049 fifo[i++] = 0x00000000;
1051 src_offset += h * src_pitch;
1052 dst_offset += h * dst_pitch;
1053 row_count -= h;
1056 fifo[i++] = 0x00042310;
1057 fifo[i++] = 0x00000000;
1059 return (i);
1063 main(int argc, char **argv)
1065 struct ps3gpu_ctl_context_allocate context_allocate;
1066 struct ps3gpu_ctl_context_free context_free;
1067 struct ps3gpu_ctl_memory_allocate memory_allocate;
1068 struct ps3gpu_ctl_setup_control setup_control;
1069 struct ps3gpu_ctl_flip flip;
1070 int context_id;
1071 volatile uint32_t *control;
1072 uint32_t *fifo, *reset_gpu, *vram, *cursor;
1073 unsigned long fifo_handle, vram_handle, cursor_handle;
1074 unsigned int fifo_gaddr, reset_gpu_gaddr, vram_gaddr;
1075 int fd = -1;
1076 int x, y;
1077 int x1, y1, x2, y2, w, h;
1078 int err;
1080 /* Open GPU device */
1082 fd = open(PS3GPU_DEV_PATH, O_RDWR);
1083 if (fd < 0) {
1084 perror("open");
1085 goto done;
1088 /* Create GPU context */
1090 context_allocate.vram_size = 64; /* MB */
1092 err = ioctl(fd, PS3GPU_CTL_CONTEXT_ALLOCATE, &context_allocate);
1093 if (err < 0) {
1094 perror("ioctl");
1095 goto done;
1098 context_id = context_allocate.context_id;
1100 printf("context id %d\n", context_id);
1101 printf("control handle 0x%lx size %d\n",
1102 context_allocate.control_handle, context_allocate.control_size);
1104 /* Map control registers */
1106 control = mmap(NULL, context_allocate.control_size,
1107 PROT_READ | PROT_WRITE, MAP_SHARED, fd, context_allocate.control_handle);
1108 if (control == (void *) MAP_FAILED) {
1109 perror("mmap");
1110 goto done;
1113 /* Allocate FIFO */
1115 memory_allocate.context_id = context_id;
1116 memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_GART;
1117 memory_allocate.size = 64 * 1024;
1118 memory_allocate.align = 12;
1120 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
1121 if (err < 0) {
1122 perror("ioctl");
1123 goto done;
1126 fifo_handle = memory_allocate.handle;
1127 fifo_gaddr = memory_allocate.gpu_addr;
1129 printf("fifo handle 0x%lx gpu addr 0x08%x\n",
1130 fifo_handle, fifo_gaddr);
1132 /* Map FIFO */
1134 fifo = mmap(NULL, memory_allocate.size,
1135 PROT_READ | PROT_WRITE, MAP_SHARED, fd, fifo_handle);
1136 if (fifo == (void *) MAP_FAILED) {
1137 perror("mmap");
1138 goto done;
1141 /* Setup FIFO */
1143 setup_control.context_id = context_id;
1144 setup_control.put = fifo_handle;
1145 setup_control.get = fifo_handle;
1146 setup_control.ref = 0xdeadbabe;
1148 err = ioctl(fd, PS3GPU_CTL_SETUP_CONTROL, &setup_control);
1149 if (err < 0) {
1150 perror("ioctl");
1151 goto done;
1154 printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n",
1155 control[0x10], control[0x11], control[0x12]);
1157 /* Allocate FIFO for resetting GPU state */
1159 memory_allocate.context_id = context_id;
1160 memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_GART;
1161 memory_allocate.size = 8 * 1024;
1162 memory_allocate.align = 12;
1164 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
1165 if (err < 0) {
1166 perror("ioctl");
1167 goto done;
1170 reset_gpu_gaddr = memory_allocate.gpu_addr;
1172 printf("reset GPU state handle 0x%lx gpu addr 0x%08x\n",
1173 memory_allocate.handle, reset_gpu_gaddr);
1175 /* Map FIFO for resetting GPU state */
1177 reset_gpu = mmap(NULL, memory_allocate.size,
1178 PROT_READ | PROT_WRITE, MAP_SHARED, fd, memory_allocate.handle);
1179 if (reset_gpu == (void *) MAP_FAILED) {
1180 perror("mmap");
1181 goto done;
1184 memcpy(reset_gpu, reset_gpu_state, sizeof(reset_gpu_state));
1186 /* Kick FIFO */
1188 fifo[0] = PS3GPU_MTH_HDR(0, 0, reset_gpu_gaddr | PS3GPU_MTH_ADDR_CALL);
1189 fifo[1] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_REF);
1190 fifo[2] = 0xcafef00d;
1192 control[0x10] = fifo_gaddr + 3 * sizeof(uint32_t);
1194 while (control[0x10] != control[0x11])
1195 usleep(1000);
1197 printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n",
1198 control[0x10], control[0x11], control[0x12]);
1200 /* Allocate VRAM */
1202 memory_allocate.context_id = context_id;
1203 memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_VIDEO;
1204 memory_allocate.size = 9 * 1024 * 1024;
1205 memory_allocate.align = 12;
1207 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
1208 if (err < 0) {
1209 perror("ioctl");
1210 goto done;
1213 vram_handle = memory_allocate.handle;
1214 vram_gaddr = memory_allocate.gpu_addr;
1216 printf("VRAM handle 0x%lx gpu addr 0x%08x\n",
1217 vram_handle, vram_gaddr);
1219 /* Map VRAM */
1221 vram = mmap(NULL, memory_allocate.size,
1222 PROT_READ | PROT_WRITE, MAP_SHARED, fd, vram_handle);
1223 if (vram == (void *) MAP_FAILED) {
1224 perror("mmap");
1225 goto done;
1228 memset(vram, 0x40, memory_allocate.size);
1230 /* Allocate cursor */
1232 memory_allocate.context_id = context_id;
1233 memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_VIDEO;
1234 memory_allocate.size = 16 * 1024;
1235 memory_allocate.align = 20;
1237 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
1238 if (err < 0) {
1239 perror("ioctl");
1240 goto done;
1243 cursor_handle = memory_allocate.handle;
1245 printf("cursor handle 0x%lx gpu addr 0x%08x\n",
1246 cursor_handle, memory_allocate.gpu_addr);
1248 /* Map cursor */
1250 cursor = mmap(NULL, memory_allocate.size,
1251 PROT_READ | PROT_WRITE, MAP_SHARED, fd, cursor_handle);
1252 if (cursor == (void *) MAP_FAILED) {
1253 perror("mmap");
1254 goto done;
1257 /* Create cursor image */
1259 for (y = 0; y < 64; y++) {
1260 for (x = 0; x < 64; x++)
1261 if (cursor_bitmap[(y * 64 + x) >> 6] &
1262 (1ul << ((63 - (y * 64 + x)) & 0x3f)))
1263 cursor[y * 64 + x] = 0xffffff00;
1264 else
1265 cursor[y * 64 + x] = 0x00000000;
1268 /* Update cursor */
1270 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_A,
1271 cursor_handle, 100, 100, 1);
1272 if (err)
1273 goto done;
1275 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_B,
1276 cursor_handle, 100, 100, 1);
1277 if (err)
1278 goto done;
1280 /* Flip */
1282 flip.context_id = context_id;
1283 flip.head = PS3GPU_CTL_HEAD_A;
1284 flip.offset = vram_handle;
1286 err = ioctl(fd, PS3GPU_CTL_FLIP, &flip);
1287 if (err < 0) {
1288 perror("ioctl");
1289 goto done;
1292 flip.context_id = context_id;
1293 flip.head = PS3GPU_CTL_HEAD_B;
1294 flip.offset = vram_handle;
1296 err = ioctl(fd, PS3GPU_CTL_FLIP, &flip);
1297 if (err < 0) {
1298 perror("ioctl");
1299 goto done;
1302 usleep(2000000);
1304 /* Update cursor */
1306 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_A,
1307 cursor_handle, 300, 300, 1);
1308 if (err) {
1309 fprintf(stderr, "could not update cursor\n");
1310 goto done;
1313 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_B,
1314 cursor_handle, 300, 300, 1);
1315 if (err) {
1316 fprintf(stderr, "could not update cursor\n");
1317 goto done;
1320 usleep(2000000);
1322 /* Test RSX DMA */
1324 x2 = 800;
1325 y2 = 400;
1326 w = 200;
1327 h = 200;
1329 for (y = y2; y < y2 + h; y++) {
1330 for (x = x2; x < x2 + w; x++) {
1331 if (y < (y2 + h / 2))
1332 vram[y * DISPLAY_WIDTH + x] = 0x0000ff00;
1333 else
1334 vram[y * DISPLAY_WIDTH + x] = 0xffffff00;
1338 /* RSX DMA supports positive and negative pitches */
1340 /* Test positive pitch */
1342 setup_control.context_id = context_id;
1343 setup_control.put = fifo_handle;
1344 setup_control.get = fifo_handle;
1345 setup_control.ref = 0xdeadbabe;
1347 err = ioctl(fd, PS3GPU_CTL_SETUP_CONTROL, &setup_control);
1348 if (err < 0) {
1349 perror("ioctl");
1350 goto done;
1353 x1 = 200;
1354 y1 = 800;
1356 err = transfer_data(fifo, 0xfeed0000, 0xfeed0000,
1357 y1 * DISPLAY_PITCH + x1 * DISPLAY_BPP, DISPLAY_PITCH,
1358 y2 * DISPLAY_PITCH + x2 * DISPLAY_BPP, DISPLAY_PITCH,
1359 w * DISPLAY_BPP, h);
1361 control[0x10] = fifo_gaddr + err * sizeof(uint32_t);
1363 while (control[0x10] != control[0x11])
1364 usleep(1000);
1366 printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n",
1367 control[0x10], control[0x11], control[0x12]);
1369 /* Test negative pitch */
1371 setup_control.context_id = context_id;
1372 setup_control.put = fifo_handle;
1373 setup_control.get = fifo_handle;
1374 setup_control.ref = 0xdeadbabe;
1376 err = ioctl(fd, PS3GPU_CTL_SETUP_CONTROL, &setup_control);
1377 if (err < 0) {
1378 perror("ioctl");
1379 goto done;
1382 x1 = 1500;
1383 y1 = 800;
1385 err = transfer_data(fifo, 0xfeed0000, 0xfeed0000,
1386 (y1 + h - 1) * DISPLAY_PITCH + x1 * DISPLAY_BPP, -1 * DISPLAY_PITCH,
1387 (y2 + h - 1) * DISPLAY_PITCH + x2 * DISPLAY_BPP, -1 * DISPLAY_PITCH,
1388 w * DISPLAY_BPP, h);
1390 control[0x10] = fifo_gaddr + err * sizeof(uint32_t);
1392 while (control[0x10] != control[0x11])
1393 usleep(1000);
1395 printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n",
1396 control[0x10], control[0x11], control[0x12]);
1398 usleep(5000000);
1400 /* Destroy GPU context */
1402 context_free.context_id = context_id;
1404 err = ioctl(fd, PS3GPU_CTL_CONTEXT_FREE, &context_free);
1405 if (err < 0) {
1406 perror("ioctl");
1407 goto done;
1410 done:
1412 if (fd >= 0)
1413 close(fd);
1415 /* Restore console */
1417 ioctl(0, SW_TEXT_80x25, NULL);
1419 exit(0);