summaryrefslogtreecommitdiffstats
path: root/openpower/patches/p8dtu-patches/hostboot-p8/0010-Adjust-APSS-gain-and-offset-from-PWS-FRU-information.patch
blob: 172d6acc2bb9a213811050c26b50732002007d6a (plain)
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
From bdd6ce1bbfe0ee77feefe84662e961fb253c6195 Mon Sep 17 00:00:00 2001
From: Jim Yuan <jim.yuan@supermicro.com>
Date: Fri, 22 Jul 2016 17:50:57 -0700
Subject: [PATCH 10/14] Adjust APSS gain and offset from PWS FRU information.

Signed-off-by: Jim Yuan <jim.yuan@supermicro.com>
---
 src/include/usr/ipmi/ipmiif.H                      |   4 +-
 src/usr/htmgt/htmgt_cfgdata.C                      |   2 +
 src/usr/hwpf/hwp/start_payload/start_payload.C     | 212 +++++++++++++++++++++
 .../common/xmltohb/attribute_types_hb.xml          |   2 +
 4 files changed, 218 insertions(+), 2 deletions(-)

diff --git a/src/include/usr/ipmi/ipmiif.H b/src/include/usr/ipmi/ipmiif.H
index 9dfd8ee63..5416ddca0 100644
--- a/src/include/usr/ipmi/ipmiif.H
+++ b/src/include/usr/ipmi/ipmiif.H
@@ -251,8 +251,8 @@ namespace IPMI
     inline const command_t set_sel_time(void)
     { return std::make_pair(NETFUN_STORAGE, 0x49); }
 
-    inline const command_t read_fru_data(void)
-    { return std::make_pair(NETFUN_STORAGE, 0x11); }
+	inline const command_t read_fru_data(void)
+	{ return std::make_pair(NETFUN_STORAGE, 0x11); }	
 
     inline const command_t write_fru_data(void)
     { return std::make_pair(NETFUN_STORAGE, 0x12); }
diff --git a/src/usr/htmgt/htmgt_cfgdata.C b/src/usr/htmgt/htmgt_cfgdata.C
index 19e7b21bf..7c42abdb6 100644
--- a/src/usr/htmgt/htmgt_cfgdata.C
+++ b/src/usr/htmgt/htmgt_cfgdata.C
@@ -1025,6 +1025,8 @@ void getApssMessageData(uint8_t* o_data,
     ATTR_ADC_CHANNEL_OFFSETS_type offset;
     sys->tryGetAttr<ATTR_ADC_CHANNEL_OFFSETS>(offset);
 
+    TMGT_INF("getApssMessageData: gain is %d, offset is %d", gain[15], offset[15]); //jim
+
     CPPASSERT(sizeof(function) == sizeof(ground));
     CPPASSERT(sizeof(function) == sizeof(gain));
     CPPASSERT(sizeof(function) == sizeof(offset));
diff --git a/src/usr/hwpf/hwp/start_payload/start_payload.C b/src/usr/hwpf/hwp/start_payload/start_payload.C
index 5d7865a12..ad155f19e 100644
--- a/src/usr/hwpf/hwp/start_payload/start_payload.C
+++ b/src/usr/hwpf/hwp/start_payload/start_payload.C
@@ -88,6 +88,7 @@
 #include    <algorithm>
 #include    <config.h>
 #include    <ipmi/ipmiwatchdog.H>
+#include    <ipmi/ipmiif.H> //jim
 #include    <vpd/vpd_if.H>
 
 #include    <hwpf/hwpf_reasoncodes.H>
@@ -95,6 +96,7 @@
 //  Uncomment these files as they become available:
 // #include    "host_start_payload/host_start_payload.H"
 
+
 namespace   START_PAYLOAD
 {
 
@@ -277,6 +279,214 @@ errlHndl_t setMaxPstate ( void )
 }
 #endif
 
+//jim-start
+enum
+{
+PWS_1600 = 0,
+PWS_1000 = 1,
+PWS_1200 = 2,
+PWS_UNKNOWN = 0xFE,
+};
+
+uint8_t getPSUFRUFromIPMICommands(void)
+{
+	errlHndl_t l_err = NULL;
+	uint8_t* frudata = new uint8_t[120];
+	size_t len = 4;
+	uint8_t fru_header_version = 0;
+	uint8_t j = 0, loop_break = 0, read_offset = 0;
+	
+	//create request data buffer
+	uint8_t* data = new uint8_t[len];
+	
+	IPMI::completion_code cc = IPMI::CC_UNKBAD;
+	
+	data[0] = 60; //try to read from PWS1. 60-PWS1, 61-PWS2
+	data[1] = 0x0;  
+	data[2] = 0x0;  
+	data[3] = 8;  
+	l_err = IPMI::sendrecv(IPMI::read_fru_data(), cc, len, data);
+	
+	for (uint8_t i = 0; i <= 8; i++ )
+	fru_header_version = data[1] & 0xF; //normal should be 0x01.
+	TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "fru header version is %x", fru_header_version);
+	delete[] data;	
+	
+	if((l_err == NULL) && (cc == IPMI::CC_OK) && (fru_header_version == 1))
+	{		
+		TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "could get FRU from PWS1");
+
+		while ((l_err == NULL) && (loop_break == 0) && (read_offset < 100))
+		{			
+		//create request data buffer
+		len = 4; //must set len every time
+		uint8_t* data = new uint8_t[len];
+	
+		IPMI::completion_code cc = IPMI::CC_UNKBAD;
+	
+		data[0] = 60;  //read from PWS1
+		data[1] = read_offset;  
+		data[2] = 0x0;  
+		data[3] = 8;  
+		l_err = IPMI::sendrecv(IPMI::read_fru_data(), cc, len, data);
+		
+		if (cc != IPMI::CC_OK) loop_break = 1;
+		
+		read_offset += 8;
+		for (uint8_t i = 1; i <= 8; i++ )
+			{
+			frudata[j] = data[i];
+			j++;
+			}
+		delete[] data;	
+		}
+		
+
+	}
+	else	
+	{
+		TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "could get FRU from PWS2");
+
+		while ((l_err == NULL) && (loop_break == 0) && (read_offset < 100))
+		{			
+		//create request data buffer
+		len = 4;//must set len every time
+		uint8_t* data = new uint8_t[len];
+	
+		IPMI::completion_code cc = IPMI::CC_UNKBAD;
+	
+		data[0] = 61;  //read from PWS2
+		data[1] = read_offset;  
+		data[2] = 0x0;  
+		data[3] = 8;  
+		l_err = IPMI::sendrecv(IPMI::read_fru_data(), cc, len, data);
+		
+		if (cc != IPMI::CC_OK) loop_break = 1;
+		
+		read_offset += 8;
+		for (uint8_t i = 1; i <= 8; i++ )
+			{
+			frudata[j] = data[i];
+			j++;
+			}	
+		delete[] data;
+		}
+		
+	}
+
+	uint8_t product_info_offset, manufacture_name_offset, manufacture_name_length, product_name_offset, product_name_length; 
+	uint8_t product_partnumber_offset, product_partnumber_length;
+	uint8_t fru_offset, powerSupplyFru = PWS_UNKNOWN;
+	uint8_t pws1600[] = {'P','W','S','-','1','K','6','2','A','-','1','R'};
+	uint8_t pws1000[] = {'P','W','S','-','1','K','0','2','A','-','1','R'};
+	uint8_t pws1200[] = {'P','W','S','-','1','K','2','2','A','-','1','R'};
+
+	//code to calculate product part number size and offset. should use structure. refer to FRU spec.		
+	product_info_offset = frudata[4] * 8;
+	manufacture_name_offset = product_info_offset + 3;
+	manufacture_name_length = frudata[manufacture_name_offset] & 0x3F;
+	product_name_offset = manufacture_name_offset + manufacture_name_length + 1;
+	product_name_length = frudata[product_name_offset] & 0x3F;
+	product_partnumber_offset = product_name_offset + product_name_length + 1;
+	product_partnumber_length = frudata[product_partnumber_offset] & 0x3F;
+	TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "product_partnumber_length is %x", product_partnumber_length);
+	fru_offset = product_partnumber_offset + 1;
+	
+	if (product_partnumber_length == 12)
+	{
+		for (uint8_t i = 0; pws1600[i] == frudata[fru_offset + i] ; i ++)
+			if (i == 11)
+			powerSupplyFru = PWS_1600;
+		
+		for (uint8_t i = 0; pws1000[i] == frudata[fru_offset + i] ; i ++)
+			if (i == 11)
+			powerSupplyFru = PWS_1000;
+		
+		for (uint8_t i = 0; pws1200[i] == frudata[fru_offset + i] ; i ++)
+			if (i == 11)
+			powerSupplyFru = PWS_1200;
+	}
+	else	
+		powerSupplyFru = PWS_UNKNOWN;
+
+	TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "powerSupplyFru is %x", powerSupplyFru);
+	
+	return powerSupplyFru;
+
+}
+//find apss channel number from XML.
+enum
+{
+V12_SENSE = 0,
+PROC0_POWER = 1,
+PROC1_POWER = 2,
+PCIE_PROC0_POWER = 5,
+PCIE_PROC1_POWER = 6,	
+TOTAL_SYSTEM_POWER = 15,	
+};	
+
+void setAPSSGainOffsetFromPWSInfo(void)
+{
+	TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "before load OCC");
+
+	//Get Gain/Offset ATTR
+	TARGETING::Target* sys = NULL;
+	targetService().getTopLevelTarget(sys);
+
+	ATTR_ADC_CHANNEL_GAINS_type gain;
+	sys->tryGetAttr<ATTR_ADC_CHANNEL_GAINS>(gain);
+
+	ATTR_ADC_CHANNEL_OFFSETS_type offset;
+	sys->tryGetAttr<ATTR_ADC_CHANNEL_OFFSETS>(offset);
+
+	TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "gain is %d, offset is %d", gain[15], offset[15]);
+
+	//Note that the function/ APSS channel ids can be indirect. I've hardcoded here, you will need to look at the XML to find the channel/function number that matches
+	//const uint8_t SYS_CHANNEL = 15; //APSS Channel 15 is sys power, ie the gain/offset we need to tweak
+
+	//Get power supply data from BMC
+	uint8_t powerSupplyFru = getPSUFRUFromIPMICommands();
+	
+	switch(powerSupplyFru)
+	{
+	case PWS_1600: //PWS-1K62A-1R (1600W):
+	gain[TOTAL_SYSTEM_POWER] = 67800;
+	offset[TOTAL_SYSTEM_POWER] = 0;
+	break;
+
+	case PWS_1000: //PWS-1K02A-1R (1000W):
+	gain[TOTAL_SYSTEM_POWER] = 41500;
+	offset[TOTAL_SYSTEM_POWER] = 0;
+	break;
+
+	case PWS_1200: //PWS-1K22A-1R (1200W):
+	gain[TOTAL_SYSTEM_POWER] = 50000; 
+	offset[TOTAL_SYSTEM_POWER] = 0;
+	break;
+
+	default:
+	//Do nothing, leave defaults
+	//Gen error for user attention?
+	break;
+	}
+
+	//Now write the attributes back so they get picked up by OCC code
+	if (!sys->trySetAttr<ATTR_ADC_CHANNEL_GAINS>(gain))
+	{
+	//unlikely, crash
+	//Emit failing trace/console data
+	TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "set gain failed");
+	assert(0);
+	}
+
+	if (!sys->trySetAttr<ATTR_ADC_CHANNEL_OFFSETS>(offset))
+	{
+	//unlikely, crash
+	//Emit failing trace/console data
+	TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "set offset failed");
+	assert(0);
+	}
+}
 //
 //  Wrapper function to call host_runtime_setup
 //
@@ -318,6 +528,8 @@ void*    call_host_runtime_setup( void    *io_pArgs )
             break;
         }
 
+	setAPSSGainOffsetFromPWSInfo(); //jim add code before activate OCC. START_OCC_DURING_BOOT is defined in config.
+
         bool l_activateOCC = is_avp_load();
 
 #ifdef CONFIG_START_OCC_DURING_BOOT
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
index c4eb6603d..64a0c9bae 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
@@ -747,6 +747,7 @@
     </simpleType>
     <persistency>non-volatile</persistency>
     <readable/>
+    <writeable/>
 </attribute>
 
 <attribute>
@@ -758,6 +759,7 @@
     </simpleType>
     <persistency>non-volatile</persistency>
     <readable/>
+    <writeable/>
 </attribute>
 
 <attribute>
-- 
2.16.2.windows.1

OpenPOWER on IntegriCloud