2 * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 FILE_LICENCE ( GPL2_OR_LATER
);
23 #include <ipxe/linux_api.h>
24 #include <ipxe/linux_sysfs.h>
25 #include <ipxe/linux.h>
26 #include <ipxe/umalloc.h>
27 #include <ipxe/init.h>
28 #include <ipxe/smbios.h>
30 /** SMBIOS entry point filename */
31 static const char smbios_entry_filename
[] =
32 "/sys/firmware/dmi/tables/smbios_entry_point";
34 /** SMBIOS filename */
35 static const char smbios_filename
[] = "/sys/firmware/dmi/tables/DMI";
37 /** Cache SMBIOS data */
38 static userptr_t smbios_data
;
43 * @v smbios SMBIOS entry point descriptor structure to fill in
44 * @ret rc Return status code
46 static int linux_find_smbios ( struct smbios
*smbios
) {
47 struct smbios3_entry
*smbios3_entry
;
48 struct smbios_entry
*smbios_entry
;
54 /* Read entry point file */
55 len
= linux_sysfs_read ( smbios_entry_filename
, &entry
);
58 DBGC ( smbios
, "SMBIOS could not read %s: %s\n",
59 smbios_entry_filename
, strerror ( rc
) );
62 data
= user_to_virt ( entry
, 0 );
65 if ( ( len
>= ( ( int ) sizeof ( *smbios3_entry
) ) ) &&
66 ( smbios3_entry
->signature
== SMBIOS3_SIGNATURE
) ) {
67 smbios
->version
= SMBIOS_VERSION ( smbios3_entry
->major
,
68 smbios3_entry
->minor
);
69 } else if ( ( len
>= ( ( int ) sizeof ( *smbios_entry
) ) ) &&
70 ( smbios_entry
->signature
== SMBIOS_SIGNATURE
) ) {
71 smbios
->version
= SMBIOS_VERSION ( smbios_entry
->major
,
72 smbios_entry
->minor
);
74 DBGC ( smbios
, "SMBIOS invalid entry point %s:\n",
75 smbios_entry_filename
);
76 DBGC_HDA ( smbios
, 0, data
, len
);
81 /* Read SMBIOS file */
82 len
= linux_sysfs_read ( smbios_filename
, &smbios_data
);
85 DBGC ( smbios
, "SMBIOS could not read %s: %s\n",
86 smbios_filename
, strerror ( rc
) );
90 /* Populate SMBIOS descriptor */
91 smbios
->address
= smbios_data
;
95 /* Free entry point */
100 ufree ( smbios_data
);
109 * Free cached SMBIOS data
112 static void linux_smbios_shutdown ( int booting __unused
) {
114 /* Clear SMBIOS data pointer */
117 /* Free SMBIOS data */
118 ufree ( smbios_data
);
121 /** SMBIOS shutdown function */
122 struct startup_fn linux_smbios_startup_fn
__startup_fn ( STARTUP_NORMAL
) = {
123 .name
= "linux_smbios",
124 .shutdown
= linux_smbios_shutdown
,
127 PROVIDE_SMBIOS ( linux
, find_smbios
, linux_find_smbios
);