Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: pep_util.s | |
5 | * Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
6 | * 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
7 | * | |
8 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License as published by | |
12 | * the Free Software Foundation; version 2 of the License. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 | * | |
23 | * For the avoidance of doubt, and except that if any non-GPL license | |
24 | * choice is available it will apply instead, Sun elects to use only | |
25 | * the General Public License version 2 (GPLv2) at this time for any | |
26 | * software where a choice of GPL license versions is made | |
27 | * available with the language indicating that GPLv2 or any later version | |
28 | * may be used, or where a choice of which version of the GPL is applied is | |
29 | * otherwise unspecified. | |
30 | * | |
31 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
32 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
33 | * have any questions. | |
34 | * | |
35 | * | |
36 | * ========== Copyright Header End ============================================ | |
37 | */ | |
38 | #include "peu_defines.h" | |
39 | #include "dmaept_defines.h" | |
40 | ||
41 | SetupDMA: | |
42 | ! parms are: | |
43 | ! %i0 Engine | |
44 | ! %i1 Address | |
45 | ! %i2 Pattern | |
46 | ! %i3 Interrupt type | |
47 | ! %i4 Packet size, dont use 0. | |
48 | ||
49 | save | |
50 | ||
51 | ! Setup ASI - little-endian access to PCI space | |
52 | wr %g0, ASI_NL, %asi | |
53 | ||
54 | ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since | |
55 | ! BAR is set that way. Physical addresses generated via TSB | |
56 | ! have this offset so mimic that when accessing directly, as here. | |
57 | sllx %i0, 8, %l0 ! Engine ID, multiply by 0x100 | |
58 | setx (N2_PCIE_BASE_ADDR + MEM64_OFFSET_BASE_REG_DATA + PCIE_MEM64_OFFSET + PART_0_BASE), %l1, %l2 | |
59 | add %l0, %l2, %l2 ! %l2 is base address of engine regs | |
60 | ||
61 | ! Store upper half of address | |
62 | srlx %i1, 32, %l0 | |
63 | !setx 0xfffc0000, %l1, %l0 ! Always bypass for now. | |
64 | stwa %l0, [%l2+DMAEPT_DATA_ADDR_UPPER] %asi | |
65 | ||
66 | ! Store lower half of address | |
67 | stwa %i1, [%l2+DMAEPT_DATA_ADDR_LOWER] %asi | |
68 | ||
69 | ! Store pattern value | |
70 | stwa %i2, [%l2+DMAEPT_PATTERN] %asi | |
71 | ||
72 | ! Interrupt type | |
73 | stwa %i3, [%l2+DMAEPT_ENDING_INTERRUPT] %asi | |
74 | ||
75 | ! Packet size | |
76 | stwa %i4, [%l2+DMAEPT_MAX_PYLD] %asi | |
77 | ||
78 | ! Tag for MR operations, use engine ID | |
79 | stwa %i0, [%l2+DMAEPT_TAG] %asi | |
80 | ||
81 | ret | |
82 | restore | |
83 | ||
84 | SetupInterrupt: | |
85 | ! parms are: | |
86 | ! %i0 Engine | |
87 | ! %i1 Interrupt type | |
88 | ||
89 | save | |
90 | ||
91 | ! Setup an ASI for little-endian access to PCI space | |
92 | wr %g0, ASI_NL, %asi | |
93 | ||
94 | ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since | |
95 | ! BAR is set that way. Physical addresses generated via TSB | |
96 | ! have this offset so mimic that when accessing directly, as here. | |
97 | sllx %i0, 8, %l0 ! Engine ID, multiply by 0x100 | |
98 | setx (N2_PCIE_BASE_ADDR + MEM64_OFFSET_BASE_REG_DATA + PCIE_MEM64_OFFSET + PART_0_BASE), %l1, %l2 | |
99 | add %l0, %l2, %l2 ! %l2 is base address of engine regs | |
100 | ||
101 | ! Interrupt type | |
102 | stwa %i1, [%l2+DMAEPT_ENDING_INTERRUPT] %asi | |
103 | ||
104 | ret | |
105 | restore | |
106 | ||
107 | SetupMSI: | |
108 | ! parms are: | |
109 | ! %i0 Engine | |
110 | ! %i1 MSI Address | |
111 | ! %i2 MSI Data | |
112 | ||
113 | save | |
114 | ||
115 | ! Setup an ASI for little-endian access to PCI space | |
116 | wr %g0, ASI_NL, %asi | |
117 | ||
118 | ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since | |
119 | ! BAR is set that way. Physical addresses generated via TSB | |
120 | ! have this offset so mimic that when accessing directly, as here. | |
121 | sllx %i0, 8, %l0 ! Engine ID, multiply by 0x100 | |
122 | setx (N2_PCIE_BASE_ADDR + MEM64_OFFSET_BASE_REG_DATA + PCIE_MEM64_OFFSET + PART_0_BASE), %l1, %l2 | |
123 | add %l0, %l2, %l2 ! %l2 is base address of engine regs | |
124 | ||
125 | ! Store upper half of address | |
126 | srlx %i1, 32, %l0 | |
127 | stwa %l0, [%l2+DMAEPT_MSI_ADDR_UPPER] %asi | |
128 | ||
129 | ! Store lower half of address | |
130 | stwa %i1, [%l2+DMAEPT_MSI_ADDR_LOWER] %asi | |
131 | ||
132 | ! Store MSI data | |
133 | stwa %i2, [%l2+DMAEPT_MSI_DATA] %asi | |
134 | ||
135 | ret | |
136 | restore | |
137 | ||
138 | InitiateDMA: ! Operation & count, this starts the engine. | |
139 | ! parms are: | |
140 | ! %i0 Engine | |
141 | ! %i1 Operation & Count | |
142 | save | |
143 | ||
144 | ! Setup an ASI for little-endian access to PCI space | |
145 | wr %g0, ASI_NL, %asi | |
146 | ||
147 | ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since | |
148 | ! BAR is set that way. Physical addresses generated via TSB | |
149 | ! have this offset so mimic that when accessing directly, as here. | |
150 | sllx %i0, 8, %l0 ! Engine ID, multiply by 0x100 | |
151 | setx (N2_PCIE_BASE_ADDR + MEM64_OFFSET_BASE_REG_DATA + PCIE_MEM64_OFFSET + PART_0_BASE), %l1, %l2 | |
152 | add %l0, %l2, %l2 ! %l2 is base address of engine regs | |
153 | ||
154 | stwa %i1, [%l2+DMAEPT_OPERATION] %asi | |
155 | ||
156 | ret | |
157 | restore | |
158 | ||
159 | WaitOnDMA: | |
160 | ! parms are: | |
161 | ! %i0 Engine | |
162 | ! %i1 Timeout count | |
163 | save | |
164 | ||
165 | ! Setup an ASI for little-endian access to PCI space | |
166 | wr %g0, ASI_NL, %asi | |
167 | ||
168 | ! Offset accesses by PART_0_BASE + PCIE_MEM64_OFFSET since | |
169 | ! BAR is set that way. Physical addresses generated via TSB | |
170 | ! have this offset so mimic that when accessing directly, as here. | |
171 | sllx %i0, 8, %l0 ! Engine ID, multiply by 0x100 | |
172 | setx (N2_PCIE_BASE_ADDR + MEM64_OFFSET_BASE_REG_DATA + PCIE_MEM64_OFFSET + PART_0_BASE), %l1, %l2 | |
173 | add %l0, %l2, %l2 ! %l2 is base address of engine regs | |
174 | ||
175 | ! Setup to read the status register, watching for engine | |
176 | ! to finish, a DMA MR from the endpoint takes a lot longer | |
177 | ! to complete than the DMA MW for some reason. | |
178 | mov %i1, %l4 | |
179 | setx 0xf, %l1, %l5 ! ... state state 0 | |
180 | setx 0x10, %l1, %l6 ! or miscompare | |
181 | ||
182 | LoopOnEnd: | |
183 | lduwa [%l2+DMAEPT_STATUS] %asi, %l1 | |
184 | andcc %l1, %l6, %l0 | |
185 | bne Miscompare | |
186 | setx 1, %l1, %i0 ! Return 1 for miscompare | |
187 | ||
188 | andcc %l1, %l5, %l0 | |
189 | beq Return ! Idle, good | |
190 | clr %i0 ! Return 0 for good | |
191 | cmp %l0, 0x4 ! Also allow for Waiting for interrupt Ack' | |
192 | bge Return | |
193 | ||
194 | dec %l4 | |
195 | brnz %l4, LoopOnEnd | |
196 | nop | |
197 | ||
198 | b Return | |
199 | setx 2, %l1, %i0 ! Return 2 for hang | |
200 | ||
201 | Miscompare: | |
202 | ! Read miscompare info | |
203 | lduwa [%l2+DMAEPT_DATA_MSCMPR_OFFSET] %asi, %i4 | |
204 | lduwa [%l2+DMAEPT_DATA_MSCMPR_VALUE_UPPER] %asi,%i5 | |
205 | lduwa [%l2+DMAEPT_DATA_MSCMPR_VALUE_LOWER] %asi, %i6 | |
206 | ||
207 | Return: | |
208 | ret | |
209 | restore | |
210 | ||
211 |