1414#include <linux/platform_device.h>
1515#include <linux/slab.h>
1616
17+ struct m10bmc_sec ;
18+
1719/* Supported fpga secure manager types */
1820enum fpga_sec_type {
1921 N3000BMC_SEC ,
@@ -22,10 +24,31 @@ enum fpga_sec_type {
2224 N6010BMC_SEC
2325};
2426
27+ /* Supported names for power-on images */
28+ enum fpga_image {
29+ FPGA_FACTORY ,
30+ FPGA_USER1 ,
31+ FPGA_USER2 ,
32+ FPGA_MAX
33+ };
34+
35+ static const char * const fpga_image_names [] = {
36+ [FPGA_FACTORY ] = "fpga_factory" ,
37+ [FPGA_USER1 ] = "fpga_user1" ,
38+ [FPGA_USER2 ] = "fpga_user2"
39+ };
40+
41+ struct fpga_power_on {
42+ u32 avail_image_mask ;
43+ int (* get_sequence )(struct m10bmc_sec * sec , char * buf );
44+ int (* set_sequence )(struct m10bmc_sec * sec , enum fpga_image images []);
45+ };
46+
2547struct m10bmc_sec {
2648 struct device * dev ;
2749 struct intel_m10bmc * m10bmc ;
2850 enum fpga_sec_type type ;
51+ const struct fpga_power_on * poc ; /* power on image configuration */
2952};
3053
3154/* Root Entry Hash (REH) support */
@@ -158,6 +181,189 @@ static ssize_t flash_count_show(struct device *dev,
158181}
159182static DEVICE_ATTR_RO (flash_count );
160183
184+ static enum fpga_image
185+ fpga_image_by_name (struct m10bmc_sec * sec , char * image_name )
186+ {
187+ enum fpga_image i ;
188+
189+ for (i = 0 ; i < FPGA_MAX ; i ++ )
190+ if (sysfs_streq (image_name , fpga_image_names [i ]))
191+ return i ;
192+
193+ return FPGA_MAX ;
194+ }
195+
196+ static int
197+ fpga_images (struct m10bmc_sec * sec , char * names , enum fpga_image images [])
198+ {
199+ u32 image_mask = sec -> poc -> avail_image_mask ;
200+ enum fpga_image image ;
201+ char * image_name ;
202+ int i = 0 ;
203+
204+ while ((image_name = strsep (& names , " \n" ))) {
205+ image = fpga_image_by_name (sec , image_name );
206+ if (image >= FPGA_MAX || !(image_mask & BIT (image )))
207+ return - EINVAL ;
208+
209+ images [i ++ ] = image ;
210+ image_mask &= ~BIT (image );
211+ }
212+
213+ return (i == 0 ) ? - EINVAL : 0 ;
214+ }
215+
216+ static int
217+ pmci_set_power_on_image (struct m10bmc_sec * sec , enum fpga_image images [])
218+ {
219+ u32 poc_mask = PMCI_FACTORY_IMAGE_SEL ;
220+ int ret , first_user = 0 ;
221+ u32 poc = 0 ;
222+
223+ if (images [1 ] == FPGA_FACTORY )
224+ return - EINVAL ;
225+
226+ if (images [0 ] == FPGA_FACTORY ) {
227+ poc = PMCI_FACTORY_IMAGE_SEL ;
228+ first_user = 1 ;
229+ }
230+
231+ if (images [first_user ] == FPGA_USER1 || images [first_user ] == FPGA_USER2 ) {
232+ poc_mask |= PMCI_USER_IMAGE_PAGE ;
233+ if (images [first_user ] == FPGA_USER1 )
234+ poc |= FIELD_PREP (PMCI_USER_IMAGE_PAGE , POC_USER_IMAGE_1 );
235+ else
236+ poc |= FIELD_PREP (PMCI_USER_IMAGE_PAGE , POC_USER_IMAGE_2 );
237+ }
238+
239+ ret = m10bmc_sys_update_bits (sec -> m10bmc ,
240+ m10bmc_base (sec -> m10bmc ) + M10BMC_PMCI_FPGA_POC ,
241+ poc_mask | PMCI_FPGA_POC , poc | PMCI_FPGA_POC );
242+ if (ret )
243+ return ret ;
244+
245+ ret = regmap_read_poll_timeout (sec -> m10bmc -> regmap ,
246+ m10bmc_base (sec -> m10bmc ) + M10BMC_PMCI_FPGA_POC ,
247+ poc ,
248+ (!(poc & PMCI_FPGA_POC )),
249+ NIOS_HANDSHAKE_INTERVAL_US ,
250+ NIOS_HANDSHAKE_TIMEOUT_US );
251+
252+ if (ret || (FIELD_GET (PMCI_NIOS_STATUS , poc ) != NIOS_STATUS_SUCCESS ))
253+ return - EIO ;
254+
255+ return 0 ;
256+ }
257+
258+ static int pmci_get_power_on_image (struct m10bmc_sec * sec , char * buf )
259+ {
260+ const char * image_names [FPGA_MAX ] = { 0 };
261+ int ret , i = 0 ;
262+ u32 poc ;
263+
264+ ret = m10bmc_sys_read (sec -> m10bmc , M10BMC_PMCI_FPGA_POC , & poc );
265+ if (ret )
266+ return ret ;
267+
268+ if (poc & PMCI_FACTORY_IMAGE_SEL )
269+ image_names [i ++ ] = fpga_image_names [FPGA_FACTORY ];
270+
271+ if (FIELD_GET (PMCI_USER_IMAGE_PAGE , poc ) == POC_USER_IMAGE_1 ) {
272+ image_names [i ++ ] = fpga_image_names [FPGA_USER1 ];
273+ image_names [i ++ ] = fpga_image_names [FPGA_USER2 ];
274+ } else {
275+ image_names [i ++ ] = fpga_image_names [FPGA_USER2 ];
276+ image_names [i ++ ] = fpga_image_names [FPGA_USER1 ];
277+ }
278+
279+ if (!(poc & PMCI_FACTORY_IMAGE_SEL ))
280+ image_names [i ] = fpga_image_names [FPGA_FACTORY ];
281+
282+ return sysfs_emit (buf , "%s %s %s\n" , image_names [0 ],
283+ image_names [1 ], image_names [2 ]);
284+ }
285+
286+ static ssize_t
287+ available_fpga_images_show (struct device * dev ,
288+ struct device_attribute * attr , char * buf )
289+ {
290+ struct m10bmc_sec * sec = dev_get_drvdata (dev );
291+ ssize_t count = 0 ;
292+ enum fpga_image i ;
293+
294+ for (i = 0 ; i < FPGA_MAX ; i ++ )
295+ if (BIT (i ) & sec -> poc -> avail_image_mask )
296+ count += scnprintf (buf + count , PAGE_SIZE - count ,
297+ "%s " , fpga_image_names [i ]);
298+ buf [count - 1 ] = '\n' ;
299+
300+ return count ;
301+ }
302+ static DEVICE_ATTR_RO (available_fpga_images );
303+
304+ static ssize_t
305+ power_on_image_show (struct device * dev ,
306+ struct device_attribute * attr , char * buf )
307+ {
308+ struct m10bmc_sec * sec = dev_get_drvdata (dev );
309+
310+ return sec -> poc -> get_sequence (sec , buf );
311+ }
312+
313+ static ssize_t
314+ power_on_image_store (struct device * dev ,
315+ struct device_attribute * attr , const char * buf , size_t count )
316+ {
317+ enum fpga_image images [FPGA_MAX ] = { [0 ... FPGA_MAX - 1 ] = FPGA_MAX };
318+ struct m10bmc_sec * sec = dev_get_drvdata (dev );
319+ char * tokens ;
320+ int ret ;
321+
322+ tokens = kmemdup_nul (buf , count , GFP_KERNEL );
323+ if (!tokens )
324+ ret = - ENOMEM ;
325+
326+ ret = fpga_images (sec , tokens , images );
327+ if (ret )
328+ goto free_exit ;
329+
330+ ret = sec -> poc -> set_sequence (sec , images );
331+
332+ free_exit :
333+ kfree (tokens );
334+ return ret ? : count ;
335+ }
336+ static DEVICE_ATTR_RW (power_on_image );
337+
338+ static umode_t
339+ m10bmc_is_visible (struct kobject * kobj ,
340+ struct attribute * attr , int n )
341+ {
342+ struct m10bmc_sec * sec = dev_get_drvdata (kobj_to_dev (kobj ));
343+
344+ if (sec -> type != N6010BMC_SEC )
345+ return 0 ;
346+
347+ return attr -> mode ;
348+ }
349+
350+ static const struct fpga_power_on pmci_power_on_image = {
351+ .avail_image_mask = BIT (FPGA_FACTORY ) | BIT (FPGA_USER1 ) | BIT (FPGA_USER2 ),
352+ .set_sequence = pmci_set_power_on_image ,
353+ .get_sequence = pmci_get_power_on_image ,
354+ };
355+
356+ static struct attribute * m10bmc_image_attrs [] = {
357+ & dev_attr_power_on_image .attr ,
358+ & dev_attr_available_fpga_images .attr ,
359+ NULL ,
360+ };
361+
362+ static struct attribute_group m10bmc_image_attr_group = {
363+ .attrs = m10bmc_image_attrs ,
364+ .is_visible = m10bmc_is_visible ,
365+ };
366+
161367static struct attribute * m10bmc_security_attrs [] = {
162368 & dev_attr_flash_count .attr ,
163369 & dev_attr_bmc_root_entry_hash .attr ,
@@ -176,6 +382,7 @@ static struct attribute_group m10bmc_security_attr_group = {
176382
177383static const struct attribute_group * m10bmc_sec_attr_groups [] = {
178384 & m10bmc_security_attr_group ,
385+ & m10bmc_image_attr_group ,
179386 NULL ,
180387};
181388
@@ -981,6 +1188,9 @@ static int m10bmc_secure_probe(struct platform_device *pdev)
9811188 return - EINVAL ;
9821189 }
9831190
1191+ if (type == N6010BMC_SEC )
1192+ sec -> poc = & pmci_power_on_image ;
1193+
9841194 smgr = devm_fpga_sec_mgr_create (sec -> dev , "Max10 BMC Secure Update" ,
9851195 sops , sec );
9861196 if (!smgr ) {
0 commit comments