Skip to content

Commit 6d1fd2c

Browse files
steffenchrisrjknight
authored andcommitted
Alink Hot Repair Fix
Change-Id: Ie6fc10cefe5084af41a14c5edfd31d4cdc6f591d CQ: HW446279 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/61067 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Reviewed-by: Gary A. Peterson <garyp@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Joseph J. McGill <jmcgill@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
1 parent 169b85d commit 6d1fd2c

File tree

9 files changed

+7621
-13
lines changed

9 files changed

+7621
-13
lines changed
Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
/* IBM_PROLOG_BEGIN_TAG */
2+
/* This is an automatically generated prolog. */
3+
/* */
4+
/* $Source: import/chips/p9/procedures/ppe_closed/ippe/ioa/io_lib.c $ */
5+
/* */
6+
/* OpenPOWER HCODE Project */
7+
/* */
8+
/* COPYRIGHT 2018 */
9+
/* [+] International Business Machines Corp. */
10+
/* */
11+
/* */
12+
/* Licensed under the Apache License, Version 2.0 (the "License"); */
13+
/* you may not use this file except in compliance with the License. */
14+
/* You may obtain a copy of the License at */
15+
/* */
16+
/* http://www.apache.org/licenses/LICENSE-2.0 */
17+
/* */
18+
/* Unless required by applicable law or agreed to in writing, software */
19+
/* distributed under the License is distributed on an "AS IS" BASIS, */
20+
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
21+
/* implied. See the License for the specific language governing */
22+
/* permissions and limitations under the License. */
23+
/* */
24+
/* IBM_PROLOG_END_TAG */
25+
// *!---------------------------------------------------------------------------
26+
// *! (C) Copyright International Business Machines Corp. 2016
27+
// *! All Rights Reserved -- Property of IBM
28+
// *! *** IBM Confidential ***
29+
// *!---------------------------------------------------------------------------
30+
// *! FILENAME : io_lib.c
31+
// *! TITLE :
32+
// *! DESCRIPTION :
33+
// *!
34+
// *! OWNER NAME : John Rell Email: jgrell@us.ibm.com
35+
// *! BACKUP NAME : Mike Spear Email: mspear@us.ibm.com
36+
// *!
37+
// *!---------------------------------------------------------------------------
38+
// CHANGE HISTORY:
39+
//------------------------------------------------------------------------------
40+
// Version ID: |Author: | Comment:
41+
// ------------|--------|-------------------------------------------------------
42+
// vbr17072600 |vbr | Copied gcr_wr_raw from other branch.
43+
// vbr16081800 |vbr | Moved some functions from eo_common to io_lib (and renamed some).
44+
// vbr16070700 |vbr | Removed deprecated put/get; minor stack/code size optimizations
45+
// vbr16070100 |vbr | Removed RMW option from put_ptr_int (only does RMW).
46+
// vbr16062800 |vbr | Optimization
47+
// mbs16062400 |mbs | Added gcr_addr struct
48+
// mbs16062400 |mbs | Added put_ptr, put_ptr_fast, and get_ptr functions
49+
// vbr16050500 |vbr |- Moved mem_regs and various functions from eo_common to io_lib
50+
// vbr16050300 |vbr |- Added lcl_get()
51+
// mbs16040800 |mbs |- Added instance parm to mmio_put and mmio_get, and adjusted bit fields
52+
// -----------------------------------------------------------------------------
53+
54+
#include "io_lib.h"
55+
#include "pk.h"
56+
57+
#include "ppe_mem_reg_const_pkg.h"
58+
#include "ppe_com_reg_const_pkg.h"
59+
#include "ppe_opt_reg_const_pkg.h"
60+
61+
62+
63+
////////////////////////////////////////////////////////////////////////////////////////////
64+
// GCR ADDRESS FORMING FUNCTIONS
65+
////////////////////////////////////////////////////////////////////////////////////////////
66+
67+
// These functions are setup to interace with a "t_gcr_addr" structure which is only infrequently updated.
68+
// A pointer to this structure can be passed down the call stack and provide all the necessary information
69+
// to put and get functions as well as precalculated masks
70+
71+
void set_gcr_addr(t_gcr_addr* gcr_addr, int bus_id, int reg_id, int lane)
72+
{
73+
gcr_addr->bus_id = bus_id;
74+
gcr_addr->reg_id = reg_id;
75+
gcr_addr->lane = lane;
76+
77+
// Single thread on gcr_port 0
78+
gcr_addr->gcr_port_addr = 0xC0000200;
79+
80+
gcr_addr->gcr_read_packet =
81+
0x9000000000E00000 //base_gcr_write_msg
82+
| ((uint64_t)bus_id << (63 - 10)) // 53
83+
| ((uint64_t)reg_id << (63 - 16)) // 47
84+
| ((uint64_t)lane << (63 - 31)); // 32
85+
86+
gcr_addr->gcr_write_packet = gcr_addr->gcr_read_packet | 0x0800000000000000;
87+
88+
return;
89+
};
90+
91+
92+
void set_gcr_addr_bus_id(t_gcr_addr* gcr_addr, int bus_id)
93+
{
94+
gcr_addr->bus_id = bus_id;
95+
96+
gcr_addr->gcr_read_packet = (gcr_addr->gcr_read_packet & 0xf81fffffffffffff)
97+
| ((uint64_t)bus_id << (63 - 10));
98+
99+
gcr_addr->gcr_write_packet = gcr_addr->gcr_read_packet | 0x0800000000000000;
100+
101+
return;
102+
}
103+
104+
void set_gcr_addr_reg_id(t_gcr_addr* gcr_addr, int reg_id)
105+
{
106+
gcr_addr->reg_id = reg_id;
107+
108+
gcr_addr->gcr_read_packet = (gcr_addr->gcr_read_packet & 0xffe07fffffffffff)
109+
| ((uint64_t)reg_id << (63 - 16));
110+
111+
gcr_addr->gcr_write_packet = gcr_addr->gcr_read_packet | 0x0800000000000000;
112+
113+
return;
114+
}
115+
116+
void set_gcr_addr_lane(t_gcr_addr* gcr_addr, int lane)
117+
{
118+
gcr_addr->lane = lane;
119+
120+
gcr_addr->gcr_read_packet = (gcr_addr->gcr_read_packet & 0xffffffe0ffffffff)
121+
| ((uint64_t)lane << (63 - 31));
122+
123+
gcr_addr->gcr_write_packet = gcr_addr->gcr_read_packet | 0x0800000000000000;
124+
125+
return;
126+
}
127+
128+
129+
////////////////////////////////////////////////////////////////////////////////////////////
130+
// HW I/O FUNCTIONS
131+
////////////////////////////////////////////////////////////////////////////////////////////
132+
133+
void mmio_put(int instance, int addr, int data)
134+
{
135+
uint64_t volatile* lclmem_addr = (uint64_t*)(0xC0000250);
136+
137+
(*lclmem_addr) =
138+
0x8000000000000000 // 0, write
139+
| ((uint64_t)instance << (63 - 11)) // 2:3, DL Instance (00 : DL0, 01 : DL1, 10 : DL2, 11 : PHY)
140+
| ((uint64_t)addr << (63 - 11)) // 11:31
141+
| ((uint64_t)data); // 32:63
142+
143+
// poll for msg rcvd flag to indicate an echo
144+
while ( ((*lclmem_addr) & 0x3) == 0x0 );
145+
146+
return;
147+
}
148+
149+
uint32_t mmio_get(int instance, int addr)
150+
{
151+
uint64_t volatile* lclmem_addr = (uint64_t*)(0xC0000250);
152+
153+
(*lclmem_addr) =
154+
0x0000000000000000 // 0, read
155+
| ((uint64_t)instance << (63 - 11)) // 2:3, DL Instance (00 : DL0, 01 : DL1, 10 : DL2, 11 : PHY)
156+
| ((uint64_t)addr << (63 - 11)); // 11:31
157+
158+
// poll for read data flag
159+
uint64_t result = (*lclmem_addr);
160+
161+
while ( (result & 0x1) == 0x0 )
162+
{
163+
result = (*lclmem_addr);
164+
};
165+
166+
uint32_t r_data = (uint32_t)(result >> 32);
167+
168+
return r_data; // 16 bits
169+
170+
//return;
171+
}
172+
173+
174+
// This allows writing a raw GCR packet to the bus.
175+
// Primarily meant as a workaround for the GCR interrupt packet not being ack'd.
176+
void gcr_wr_raw(t_gcr_addr* gcr_addr, uint64_t packet)
177+
{
178+
// Setup the pointer
179+
uint64_t volatile* lclmem_addr = (uint64_t*)gcr_addr->gcr_port_addr;
180+
181+
// wait on previous op while start bit is set but echo flag is not set
182+
while (((*lclmem_addr) & 0xC000000000000003) == 0x8000000000000000 );
183+
184+
// send write op and exit
185+
(*lclmem_addr) = packet;
186+
} //gcr_wr_raw
187+
188+
189+
// fast put where the packet is preformed and the data field uses all 16 bits so we just need to fill in the reg addr and 16-bit data
190+
//void put_ptr_fast_int(t_gcr_addr *gcr_addr, int reg_addr, int endbit, int data) {
191+
void put_ptr_fast_int(t_gcr_addr* gcr_addr, uint64_t reg_addr, int shift_amt, int data)
192+
{
193+
//uint64_t w_data = data << (15+4 - endbit);
194+
uint64_t w_data = data << shift_amt;
195+
196+
uint64_t packet =
197+
gcr_addr->gcr_write_packet
198+
| ((uint64_t)reg_addr) // already shifted
199+
| ((uint64_t)w_data);
200+
201+
// Put result to reg
202+
uint64_t volatile* lclmem_addr = (uint64_t*)gcr_addr->gcr_port_addr;
203+
204+
// wait on previous op while start bit is set but echo flag is not set
205+
while (((*lclmem_addr) & 0xC000000000000003) == 0x8000000000000000 );
206+
207+
// send write op and exit
208+
(*lclmem_addr) = packet;
209+
210+
return;
211+
}
212+
213+
214+
// put where the packet is preformed. always does read-modify-write.
215+
void put_ptr_int(t_gcr_addr* gcr_addr, uint64_t reg_addr, uint64_t and_mask, int shift_amt, int data)
216+
{
217+
uint64_t volatile* lclmem_addr = (uint64_t*)gcr_addr->gcr_port_addr;
218+
uint64_t packet;
219+
uint64_t w_data;
220+
221+
// For a read-modify-write, first do a read of the register in question.
222+
// However we don't need to do a full get() because we don't care about shifting the
223+
// data around.
224+
225+
packet =
226+
gcr_addr->gcr_read_packet
227+
| ((uint64_t)reg_addr);// already shifted
228+
229+
// wait on previous op while start bit is set but echo flag or read response flag is not set
230+
while (((*lclmem_addr) & 0xC000000000000003) == 0x8000000000000000 );
231+
232+
(*lclmem_addr) = packet;
233+
234+
235+
// ******************************************************************
236+
// Form AND and OR masks - do all this while the read command is running
237+
// ******************************************************************
238+
239+
/*
240+
// Form the mask by shifting a one N+1 times and then subtracting one to make a ones mask of length N
241+
uint64_t and_mask = (1 << (endbit - startbit + 1)) - 1;
242+
243+
// Shift the mask into the proper bit field for the gcr packet
244+
and_mask <<= (15+4 - endbit);
245+
246+
// Invert the mask so all the bits except the start/end bit data field are ones (e.g. xfffffffffffff1ff)
247+
and_mask = (~and_mask);
248+
249+
// Now mask off all but the actual 16 bit data field, so we have ones with hole in the middle (e.g. x00000000000ff1f0)
250+
and_mask &= 0x00000000000ffff0;
251+
252+
w_data = data << (15+4 - endbit);
253+
*/
254+
w_data = data << shift_amt;
255+
256+
// Prepare or_mask
257+
uint64_t or_mask =
258+
gcr_addr->gcr_write_packet
259+
| ((uint64_t)reg_addr) // already shifted
260+
| ((uint64_t)w_data); // 4
261+
262+
// ******************************************************************
263+
264+
// poll for read response packet flag to indicate returned data
265+
packet = (*lclmem_addr);
266+
267+
while ( (packet & 0x4000000000000000) == 0x0 )
268+
{
269+
packet = (*lclmem_addr);
270+
};
271+
272+
// Apply masks
273+
packet &= and_mask;
274+
275+
packet |= or_mask;
276+
277+
// write data back and exit
278+
(*lclmem_addr) = packet;
279+
280+
// poll for msg rcvd flag to indicate an echo
281+
//while ( ((*lclmem_addr) & 0x3) == 0x0 );
282+
283+
return;
284+
} //put_ptr_int
285+
286+
void put_ptr_fast_id(t_gcr_addr* gcr_addr, int reg_id, uint64_t reg_addr, int endbit, int data)
287+
{
288+
set_gcr_addr_reg_id(gcr_addr, reg_id);
289+
put_ptr_fast(gcr_addr, reg_addr, endbit, data);
290+
}
291+
292+
void put_ptr_id (t_gcr_addr* gcr_addr, int reg_id, uint64_t reg_addr, int startbit, int endbit, int data, int rmw)
293+
{
294+
set_gcr_addr_reg_id(gcr_addr, reg_id);
295+
put_ptr(gcr_addr, reg_addr, startbit, endbit, data, rmw);
296+
}
297+
298+
uint32_t get_ptr_id (t_gcr_addr* gcr_addr, int reg_id, uint64_t reg_addr, int startbit, int endbit)
299+
{
300+
set_gcr_addr_reg_id(gcr_addr, reg_id);
301+
return get_ptr(gcr_addr, reg_addr, startbit, endbit);
302+
}
303+
304+
305+
// get where the packet is preformed
306+
//uint32_t get_ptr_int(t_gcr_addr *gcr_addr, int reg_addr, int startbit, int endbit) {
307+
uint32_t get_ptr_int(t_gcr_addr* gcr_addr, uint64_t reg_addr, uint64_t and_mask, int shift_amt)
308+
{
309+
uint64_t volatile* lclmem_addr = (uint64_t*)(gcr_addr->gcr_port_addr);
310+
311+
(*lclmem_addr) =
312+
gcr_addr->gcr_read_packet
313+
| ((uint64_t)reg_addr);// already shifted
314+
315+
/*
316+
// ******************************************************************
317+
// Form AND mask - do all this while the read command is running
318+
// ******************************************************************
319+
// Form the mask by shifting a one N+1 times and then subtracting one to make a ones mask of length N
320+
uint64_t and_mask = (1 << (endbit - startbit + 1)) - 1;
321+
322+
// Shift the mask into the proper bit field for the gcr packet
323+
uint32_t shift_amt = (4 + 15 - endbit);
324+
325+
and_mask <<= shift_amt;
326+
327+
// ******************************************************************
328+
*/
329+
330+
// poll for read response packet flag to indicate returned data
331+
uint64_t result = (*lclmem_addr);
332+
333+
while ( (result & 0x4000000000000000) == 0x0 )
334+
{
335+
result = (*lclmem_addr);
336+
};
337+
338+
uint32_t r_data = (uint32_t)((result & and_mask) >> shift_amt);
339+
340+
return r_data; // 16 bits
341+
}
342+
343+
344+
void lcl_put(int reg_addr, int width, int data)
345+
{
346+
347+
uint64_t volatile* lclmem_addr = (uint64_t*)(0xC0000000 | reg_addr);
348+
349+
(*lclmem_addr) = (uint64_t)data << (64 - width);
350+
351+
return;
352+
}
353+
354+
uint32_t lcl_get(int reg_addr, int width)
355+
{
356+
uint64_t volatile* lclmem_addr = (uint64_t*)(0xC0000000 | reg_addr);
357+
uint32_t r_data = (uint32_t)((*lclmem_addr) >> (64 - width));
358+
return r_data;
359+
}
360+
361+
void set_fir()
362+
{
363+
uint64_t volatile* fir_addr = (uint64_t*)(0xC0000240);
364+
365+
(*fir_addr) = 0x1; // Any write will trigger the FIR, regardless of data
366+
367+
return;
368+
}

0 commit comments

Comments
 (0)