toutdram.s
2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <rsp.h>
#include "mbi.h"
#include "tdmem_label.h"
#include "tst_regs.h"
############################################################################
#
# Output coordination routines:
#
# We support two cases:
#
# 1.) output directly to RDP using DMEM as buffer. Requires
# producer/consumer synchronization.
#
# 2.) output routed to DRAM. In this case, we use DMEM as
# a temporary buffer, then DMA out to DRAM.
#
# Goals:
#
# - small code size.
# - efficient and non-obtrusive
# - flexible, can easily route to DRAM or RDP.
#
# In order to do this, and make it transparent to the parts of the
# code which do the writing, we implement an open/close interface.
#
# FUNCTION: OUTPUT TO RDP: OUTPUT TO DRAM:
#-------------------------------------------------------------------------
# open(size) - wait for size avail in - does nothing
# ring buffer.
# - possibly handle wrap
# - wait for 'current' to get
# out of the way
#
# close() - advance CP0 pointer - do DMA of cmd to DRAM
# - increment pointers
# - reset DMEM buffer
#
# In between the open() and close(), the ucode writes the data to DMEM.
# (to either the RDP ring buffer or a temp buffer to be DMA'd)
#
############################################################################
#
# These registers used by both routines.
#
.name dmemp, $20
.name dramp, $19
.name outsz, $18 # set by caller to max size to write
############################################################################
#
#
#
.ent OutputOpen
OutputOpen:
jr return
nop
.end OutputOpen
#
#
#
############################################################################
############################################################################
#
#
#
.ent OutputClose
OutputClose:
lw dramp, RSP_STATE_DRAM_OUTP(rsp_state)
addi dmemp, zero, RSP_OUTPUT_OFFSET
.name outlen, $17
lw outlen, (RSP_STATE_DRAM_OUT_LEN+4)(rsp_state)
sub outsz, outp, dmemp
add outlen, outlen, outsz
sw outlen, (RSP_STATE_DRAM_OUT_LEN+4)(rsp_state)
addi outsz, outsz, -1
.unname outlen
# DEBUG:
# safety precaution, only do DMA if outsz >= 0
bltz outsz, OutputDone
add $21, zero, return
# if outsz < 0, we will drop data on the floor
OutputData:
jal DMAproc
addi $17, zero, 1 # set 'iswrite'
jal DMAwait
nop
# update pointers...
# (dmemp gets trashed in DMAwait routine...)
OutputDone:
addi outp, zero, RSP_OUTPUT_OFFSET
add dramp, dramp, outsz
addi dramp, dramp, 1
jr $21
sw dramp, RSP_STATE_DRAM_OUTP(rsp_state)
.end OutputClose
nop
nop
nop
nop
#
#
#
############################################################################
.unname outsz
.unname dramp
.unname dmemp