@@ -20,6 +20,8 @@ struct m10bmc_sec {
2020 enum fpga_sec_type type ;
2121};
2222
23+ static const struct image_load * curr_poc ;
24+
2325/* Root Entry Hash (REH) support */
2426#define REH_SHA256_SIZE 32
2527#define REH_SHA384_SIZE 48
@@ -150,6 +152,177 @@ static ssize_t flash_count_show(struct device *dev,
150152}
151153static DEVICE_ATTR_RO (flash_count );
152154
155+ static ssize_t
156+ available_power_on_images_show (struct device * dev ,
157+ struct device_attribute * attr , char * buf )
158+ {
159+ struct fpga_sec_mgr * smgr = to_sec_mgr (dev );
160+ const struct image_load * hndlr ;
161+ ssize_t count = 0 ;
162+
163+ for (hndlr = smgr -> sops -> power_on_image ; hndlr -> name ; hndlr ++ ) {
164+ count += scnprintf (buf + count , PAGE_SIZE - count ,
165+ "%s " , hndlr -> name );
166+ }
167+
168+ buf [count - 1 ] = '\n' ;
169+
170+ return count ;
171+ }
172+ static DEVICE_ATTR_RO (available_power_on_images );
173+
174+ static ssize_t
175+ power_on_image_show (struct device * dev ,
176+ struct device_attribute * attr , char * buf )
177+ {
178+ ssize_t count = 0 ;
179+
180+ if (!curr_poc )
181+ return - EINVAL ;
182+
183+ count = scnprintf (buf + count , PAGE_SIZE - count ,
184+ "%s " , curr_poc -> name );
185+ buf [count - 1 ] = '\n' ;
186+
187+ return count ;
188+ }
189+
190+ static ssize_t
191+ power_on_image_store (struct device * dev ,
192+ struct device_attribute * attr , const char * buf , size_t count )
193+ {
194+ struct fpga_sec_mgr * smgr = to_sec_mgr (dev );
195+ const struct image_load * hndlr ;
196+ int ret = - EINVAL ;
197+
198+ for (hndlr = smgr -> sops -> power_on_image ; hndlr -> name ; hndlr ++ ) {
199+ if (sysfs_streq (buf , hndlr -> name )) {
200+ ret = hndlr -> load_image (smgr );
201+ curr_poc = hndlr ;
202+ break ;
203+ }
204+ }
205+
206+ return ret ? : count ;
207+ }
208+ static DEVICE_ATTR_RW (power_on_image );
209+
210+ static int pmci_sec_power_on_image (struct fpga_sec_mgr * smgr , unsigned char boot_image )
211+ {
212+ struct m10bmc_sec * sec = smgr -> priv ;
213+ u32 poc = 0 ;
214+ int ret ;
215+
216+ if (boot_image > FPGA_POC_FACTORY_U2 ) {
217+ dev_err (sec -> dev , "%s invalid boot image = %d\n" , __func__ , boot_image );
218+ return - EINVAL ;
219+ }
220+
221+ switch (boot_image ) {
222+ case FPGA_POC_USER_IMAGE_1 :
223+ poc |= FIELD_PREP (PMCI_USER_IMAGE_PAGE , POC_USER_IMAGE_1 );
224+ break ;
225+ case FPGA_POC_USER_IMAGE_2 :
226+ poc |= FIELD_PREP (PMCI_USER_IMAGE_PAGE , POC_USER_IMAGE_2 );
227+ break ;
228+ case FPGA_POC_FACTORY_U1 :
229+ poc |= PMCI_FACTORY_IMAGE_PAGE | FIELD_PREP (PMCI_USER_IMAGE_PAGE ,
230+ POC_USER_IMAGE_1 );
231+ break ;
232+ case FPGA_POC_FACTORY_U2 :
233+ poc |= PMCI_FACTORY_IMAGE_PAGE | FIELD_PREP (PMCI_USER_IMAGE_PAGE ,
234+ POC_USER_IMAGE_2 );
235+ break ;
236+ default :
237+ return - EINVAL ;
238+ }
239+
240+ ret = m10bmc_sys_update_bits (sec -> m10bmc ,
241+ m10bmc_base (sec -> m10bmc ) + PMCI_M10BMC_FPGA_POC ,
242+ PMCI_FPGA_POC |
243+ PMCI_USER_IMAGE_PAGE |
244+ PMCI_FACTORY_IMAGE_PAGE ,
245+ poc | PMCI_FPGA_POC );
246+ if (ret )
247+ return ret ;
248+
249+ ret = regmap_read_poll_timeout (sec -> m10bmc -> regmap ,
250+ m10bmc_base (sec -> m10bmc ) + PMCI_M10BMC_FPGA_POC ,
251+ poc ,
252+ (!(poc & PMCI_FPGA_POC )),
253+ NIOS_HANDSHAKE_INTERVAL_US ,
254+ NIOS_HANDSHAKE_TIMEOUT_US );
255+ if (ret || (FIELD_GET (PMCI_NIOS_STATUS , poc ) != NIOS_STATUS_SUCCESS ))
256+ return - EIO ;
257+
258+ return 0 ;
259+ }
260+
261+ static int pmci_sec_power_on_image_0 (struct fpga_sec_mgr * smgr )
262+ {
263+ return pmci_sec_power_on_image (smgr , FPGA_POC_USER_IMAGE_1 );
264+ }
265+
266+ static int pmci_sec_power_on_image_1 (struct fpga_sec_mgr * smgr )
267+ {
268+ return pmci_sec_power_on_image (smgr , FPGA_POC_USER_IMAGE_2 );
269+ }
270+
271+ static int pmci_sec_power_on_image_2 (struct fpga_sec_mgr * smgr )
272+ {
273+ return pmci_sec_power_on_image (smgr , FPGA_POC_FACTORY_U1 );
274+ }
275+
276+ static int pmci_sec_power_on_image_3 (struct fpga_sec_mgr * smgr )
277+ {
278+ return pmci_sec_power_on_image (smgr , FPGA_POC_FACTORY_U2 );
279+ }
280+
281+ static struct image_load pmci_power_on_image_hndlrs [] = {
282+ {
283+ .name = "fpga_user1" ,
284+ .load_image = pmci_sec_power_on_image_0 ,
285+ },
286+ {
287+ .name = "fpga_user2" ,
288+ .load_image = pmci_sec_power_on_image_1 ,
289+ },
290+ {
291+ .name = "fpga_factory" ,
292+ .load_image = pmci_sec_power_on_image_2 ,
293+ },
294+ {
295+ .name = "fpga_factory_option1" ,
296+ .load_image = pmci_sec_power_on_image_3 ,
297+ },
298+ {}
299+ };
300+
301+ static umode_t
302+ m10bmc_image_visible (struct kobject * kobj ,
303+ struct attribute * attr , int n )
304+ {
305+ struct fpga_sec_mgr * smgr = to_sec_mgr (kobj_to_dev (kobj ));
306+ struct m10bmc_sec * sec = smgr -> priv ;
307+ enum fpga_sec_type type = sec -> m10bmc -> type ;
308+
309+ if (type == PMCI_SEC )
310+ return attr -> mode ;
311+
312+ return 0 ;
313+ }
314+
315+ static struct attribute * m10bmc_image_attrs [] = {
316+ & dev_attr_power_on_image .attr ,
317+ & dev_attr_available_power_on_images .attr ,
318+ NULL ,
319+ };
320+
321+ static struct attribute_group m10bmc_image_attr_group = {
322+ .attrs = m10bmc_image_attrs ,
323+ .is_visible = m10bmc_image_visible ,
324+ };
325+
153326static struct attribute * m10bmc_security_attrs [] = {
154327 & dev_attr_flash_count .attr ,
155328 & dev_attr_bmc_root_entry_hash .attr ,
@@ -168,6 +341,7 @@ static struct attribute_group m10bmc_security_attr_group = {
168341
169342static const struct attribute_group * m10bmc_sec_attr_groups [] = {
170343 & m10bmc_security_attr_group ,
344+ & m10bmc_image_attr_group ,
171345 NULL ,
172346};
173347
@@ -922,6 +1096,7 @@ m10bmc_sops_create(struct device *dev, enum fpga_sec_type type)
9221096 if (type == PMCI_SEC ) {
9231097 sops -> write_blk = pmci_sec_write_blk ;
9241098 sops -> image_load = pmci_image_load_hndlrs ;
1099+ sops -> power_on_image = pmci_power_on_image_hndlrs ;
9251100 } else {
9261101 sops -> write_blk = m10bmc_sec_write_blk ;
9271102 }
0 commit comments