15
15
#include <linux/platform_device.h>
16
16
#include <linux/acpi.h>
17
17
#include <linux/dma-mapping.h>
18
+ #include <linux/dmi.h>
18
19
#include <linux/errno.h>
19
20
#include <linux/cpu.h>
20
21
#include <linux/gfp.h>
34
35
#include "dcdbas.h"
35
36
36
37
#define DRIVER_NAME "dcdbas"
37
- #define DRIVER_VERSION "5.6.0-3.3 "
38
+ #define DRIVER_VERSION "5.6.0-3.4 "
38
39
#define DRIVER_DESCRIPTION "Dell Systems Management Base Driver"
39
40
40
41
static struct platform_device * dcdbas_pdev ;
@@ -45,7 +46,7 @@ static unsigned long smi_data_buf_size;
45
46
static unsigned long max_smi_data_buf_size = MAX_SMI_DATA_BUF_SIZE ;
46
47
static u32 smi_data_buf_phys_addr ;
47
48
static DEFINE_MUTEX (smi_data_lock );
48
- static u8 * eps_buffer ;
49
+ static u8 * bios_buffer ;
49
50
50
51
static unsigned int host_control_action ;
51
52
static unsigned int host_control_smi_type ;
@@ -518,8 +519,10 @@ static inline struct smm_eps_table *check_eps_table(u8 *addr)
518
519
519
520
static int dcdbas_check_wsmt (void )
520
521
{
522
+ const struct dmi_device * dev = NULL ;
521
523
struct acpi_table_wsmt * wsmt = NULL ;
522
524
struct smm_eps_table * eps = NULL ;
525
+ u64 bios_buf_paddr ;
523
526
u64 remap_size ;
524
527
u8 * addr ;
525
528
@@ -532,6 +535,17 @@ static int dcdbas_check_wsmt(void)
532
535
!(wsmt -> protection_flags & ACPI_WSMT_COMM_BUFFER_NESTED_PTR_PROTECTION ))
533
536
return 0 ;
534
537
538
+ /*
539
+ * BIOS could provide the address/size of the protected buffer
540
+ * in an SMBIOS string or in an EPS structure in 0xFxxxx.
541
+ */
542
+
543
+ /* Check SMBIOS for buffer address */
544
+ while ((dev = dmi_find_device (DMI_DEV_TYPE_OEM_STRING , NULL , dev )))
545
+ if (sscanf (dev -> name , "30[%16llx;%8llx]" , & bios_buf_paddr ,
546
+ & remap_size ) == 2 )
547
+ goto remap ;
548
+
535
549
/* Scan for EPS (entry point structure) */
536
550
for (addr = (u8 * )__va (0xf0000 );
537
551
addr < (u8 * )__va (0x100000 - sizeof (struct smm_eps_table ));
@@ -542,34 +556,37 @@ static int dcdbas_check_wsmt(void)
542
556
}
543
557
544
558
if (!eps ) {
545
- dev_dbg (& dcdbas_pdev -> dev , "found WSMT, but no EPS found\n" );
559
+ dev_dbg (& dcdbas_pdev -> dev , "found WSMT, but no firmware buffer found\n" );
546
560
return - ENODEV ;
547
561
}
562
+ bios_buf_paddr = eps -> smm_comm_buff_addr ;
563
+ remap_size = eps -> num_of_4k_pages * PAGE_SIZE ;
548
564
565
+ remap :
549
566
/*
550
567
* Get physical address of buffer and map to virtual address.
551
568
* Table gives size in 4K pages, regardless of actual system page size.
552
569
*/
553
- if (upper_32_bits (eps -> smm_comm_buff_addr + 8 )) {
554
- dev_warn (& dcdbas_pdev -> dev , "found WSMT, but EPS buffer address is above 4GB\n" );
570
+ if (upper_32_bits (bios_buf_paddr + 8 )) {
571
+ dev_warn (& dcdbas_pdev -> dev , "found WSMT, but buffer address is above 4GB\n" );
555
572
return - EINVAL ;
556
573
}
557
574
/*
558
575
* Limit remap size to MAX_SMI_DATA_BUF_SIZE + 8 (since the first 8
559
576
* bytes are used for a semaphore, not the data buffer itself).
560
577
*/
561
- remap_size = eps -> num_of_4k_pages * PAGE_SIZE ;
562
578
if (remap_size > MAX_SMI_DATA_BUF_SIZE + 8 )
563
579
remap_size = MAX_SMI_DATA_BUF_SIZE + 8 ;
564
- eps_buffer = memremap (eps -> smm_comm_buff_addr , remap_size , MEMREMAP_WB );
565
- if (!eps_buffer ) {
566
- dev_warn (& dcdbas_pdev -> dev , "found WSMT, but failed to map EPS buffer\n" );
580
+
581
+ bios_buffer = memremap (bios_buf_paddr , remap_size , MEMREMAP_WB );
582
+ if (!bios_buffer ) {
583
+ dev_warn (& dcdbas_pdev -> dev , "found WSMT, but failed to map buffer\n" );
567
584
return - ENOMEM ;
568
585
}
569
586
570
587
/* First 8 bytes is for a semaphore, not part of the smi_data_buf */
571
- smi_data_buf_phys_addr = eps -> smm_comm_buff_addr + 8 ;
572
- smi_data_buf = eps_buffer + 8 ;
588
+ smi_data_buf_phys_addr = bios_buf_paddr + 8 ;
589
+ smi_data_buf = bios_buffer + 8 ;
573
590
smi_data_buf_size = remap_size - 8 ;
574
591
max_smi_data_buf_size = smi_data_buf_size ;
575
592
wsmt_enabled = true;
@@ -736,8 +753,8 @@ static void __exit dcdbas_exit(void)
736
753
*/
737
754
if (dcdbas_pdev )
738
755
smi_data_buf_free ();
739
- if (eps_buffer )
740
- memunmap (eps_buffer );
756
+ if (bios_buffer )
757
+ memunmap (bios_buffer );
741
758
platform_device_unregister (dcdbas_pdev_reg );
742
759
platform_driver_unregister (& dcdbas_driver );
743
760
}
0 commit comments