[efi] Attempt to fetch autoexec script via TFTP
[ipxe.git] / src / interface / linux / linux_smbios.c
1 /*
2 * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3 *
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.
8 *
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.
13 *
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
17 * 02110-1301, USA.
18 */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <errno.h>
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>
29
30 /** SMBIOS entry point filename */
31 static const char smbios_entry_filename[] =
32 "/sys/firmware/dmi/tables/smbios_entry_point";
33
34 /** SMBIOS filename */
35 static const char smbios_filename[] = "/sys/firmware/dmi/tables/DMI";
36
37 /** Cache SMBIOS data */
38 static userptr_t smbios_data;
39
40 /**
41 * Find SMBIOS
42 *
43 * @v smbios SMBIOS entry point descriptor structure to fill in
44 * @ret rc Return status code
45 */
46 static int linux_find_smbios ( struct smbios *smbios ) {
47 struct smbios3_entry *smbios3_entry;
48 struct smbios_entry *smbios_entry;
49 userptr_t entry;
50 void *data;
51 int len;
52 int rc;
53
54 /* Read entry point file */
55 len = linux_sysfs_read ( smbios_entry_filename, &entry );
56 if ( len < 0 ) {
57 rc = len;
58 DBGC ( smbios, "SMBIOS could not read %s: %s\n",
59 smbios_entry_filename, strerror ( rc ) );
60 goto err_entry;
61 }
62 data = user_to_virt ( entry, 0 );
63 smbios3_entry = data;
64 smbios_entry = data;
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 );
73 } else {
74 DBGC ( smbios, "SMBIOS invalid entry point %s:\n",
75 smbios_entry_filename );
76 DBGC_HDA ( smbios, 0, data, len );
77 rc = -EINVAL;
78 goto err_version;
79 }
80
81 /* Read SMBIOS file */
82 len = linux_sysfs_read ( smbios_filename, &smbios_data );
83 if ( len < 0 ) {
84 rc = len;
85 DBGC ( smbios, "SMBIOS could not read %s: %s\n",
86 smbios_filename, strerror ( rc ) );
87 goto err_read;
88 }
89
90 /* Populate SMBIOS descriptor */
91 smbios->address = smbios_data;
92 smbios->len = len;
93 smbios->count = 0;
94
95 /* Free entry point */
96 ufree ( entry );
97
98 return 0;
99
100 ufree ( smbios_data );
101 err_read:
102 err_version:
103 ufree ( entry );
104 err_entry:
105 return rc;
106 }
107
108 /**
109 * Free cached SMBIOS data
110 *
111 */
112 static void linux_smbios_shutdown ( int booting __unused ) {
113
114 /* Clear SMBIOS data pointer */
115 smbios_clear();
116
117 /* Free SMBIOS data */
118 ufree ( smbios_data );
119 }
120
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,
125 };
126
127 PROVIDE_SMBIOS ( linux, find_smbios, linux_find_smbios );