goutdram.s
3.06 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
############################################################################
#
# 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
############################################################################
#
#
#
#if !(defined(OUTPUT_DRAM)||defined(OUTPUT_FIFO))
.ent OutputOpen
OutputOpen:
jr return
nop
.end OutputOpen
#endif /* !(OUTPUT_DRAM || OUTPUT_FIFO) */
#
#
#
############################################################################
############################################################################
#
#
#
.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
#
#
#
############################################################################
.unname outsz
.unname dramp
.unname dmemp
##################################################################
## Padding ##
##################################################################
#make code the same length for all 3 versions of output
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop