0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012
0013 #define _COMPONENT ACPI_UTILITIES
0014 ACPI_MODULE_NAME("utosi")
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 static struct acpi_interface_info acpi_default_supported_interfaces[] = {
0054
0055
0056 {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000},
0057 {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP},
0058 {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1},
0059 {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003},
0060 {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2},
0061 {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1},
0062 {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA},
0063 {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008},
0064 {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1},
0065 {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2},
0066 {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7},
0067 {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8},
0068 {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8_1},
0069 {"Windows 2015", NULL, 0, ACPI_OSI_WIN_10},
0070 {"Windows 2016", NULL, 0, ACPI_OSI_WIN_10_RS1},
0071 {"Windows 2017", NULL, 0, ACPI_OSI_WIN_10_RS2},
0072 {"Windows 2017.2", NULL, 0, ACPI_OSI_WIN_10_RS3},
0073 {"Windows 2018", NULL, 0, ACPI_OSI_WIN_10_RS4},
0074 {"Windows 2018.2", NULL, 0, ACPI_OSI_WIN_10_RS5},
0075 {"Windows 2019", NULL, 0, ACPI_OSI_WIN_10_19H1},
0076 {"Windows 2020", NULL, 0, ACPI_OSI_WIN_10_20H1},
0077 {"Windows 2021", NULL, 0, ACPI_OSI_WIN_11},
0078
0079
0080
0081 {"Extended Address Space Descriptor", NULL, ACPI_OSI_FEATURE, 0},
0082
0083
0084
0085
0086
0087
0088
0089
0090 {"Module Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
0091 {"Processor Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
0092 {"3.0 Thermal Model", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
0093 {"3.0 _SCP Extensions", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0},
0094 {"Processor Aggregator Device", NULL, ACPI_OSI_OPTIONAL_FEATURE, 0}
0095 };
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 acpi_status acpi_ut_initialize_interfaces(void)
0110 {
0111 acpi_status status;
0112 u32 i;
0113
0114 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
0115 if (ACPI_FAILURE(status)) {
0116 return (status);
0117 }
0118
0119 acpi_gbl_supported_interfaces = acpi_default_supported_interfaces;
0120
0121
0122
0123 for (i = 0;
0124 i < (ACPI_ARRAY_LENGTH(acpi_default_supported_interfaces) - 1);
0125 i++) {
0126 acpi_default_supported_interfaces[i].next =
0127 &acpi_default_supported_interfaces[(acpi_size)i + 1];
0128 }
0129
0130 acpi_os_release_mutex(acpi_gbl_osi_mutex);
0131 return (AE_OK);
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 acpi_status acpi_ut_interface_terminate(void)
0148 {
0149 acpi_status status;
0150 struct acpi_interface_info *next_interface;
0151
0152 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
0153 if (ACPI_FAILURE(status)) {
0154 return (status);
0155 }
0156
0157 next_interface = acpi_gbl_supported_interfaces;
0158 while (next_interface) {
0159 acpi_gbl_supported_interfaces = next_interface->next;
0160
0161 if (next_interface->flags & ACPI_OSI_DYNAMIC) {
0162
0163
0164
0165 ACPI_FREE(next_interface->name);
0166 ACPI_FREE(next_interface);
0167 } else {
0168
0169
0170 if (next_interface->flags & ACPI_OSI_DEFAULT_INVALID) {
0171 next_interface->flags |= ACPI_OSI_INVALID;
0172 } else {
0173 next_interface->flags &= ~ACPI_OSI_INVALID;
0174 }
0175 }
0176
0177 next_interface = acpi_gbl_supported_interfaces;
0178 }
0179
0180 acpi_os_release_mutex(acpi_gbl_osi_mutex);
0181 return (AE_OK);
0182 }
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 acpi_status acpi_ut_install_interface(acpi_string interface_name)
0198 {
0199 struct acpi_interface_info *interface_info;
0200
0201
0202
0203 interface_info =
0204 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info));
0205 if (!interface_info) {
0206 return (AE_NO_MEMORY);
0207 }
0208
0209 interface_info->name = ACPI_ALLOCATE_ZEROED(strlen(interface_name) + 1);
0210 if (!interface_info->name) {
0211 ACPI_FREE(interface_info);
0212 return (AE_NO_MEMORY);
0213 }
0214
0215
0216
0217 strcpy(interface_info->name, interface_name);
0218 interface_info->flags = ACPI_OSI_DYNAMIC;
0219 interface_info->next = acpi_gbl_supported_interfaces;
0220
0221 acpi_gbl_supported_interfaces = interface_info;
0222 return (AE_OK);
0223 }
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238 acpi_status acpi_ut_remove_interface(acpi_string interface_name)
0239 {
0240 struct acpi_interface_info *previous_interface;
0241 struct acpi_interface_info *next_interface;
0242
0243 previous_interface = next_interface = acpi_gbl_supported_interfaces;
0244 while (next_interface) {
0245 if (!strcmp(interface_name, next_interface->name)) {
0246
0247
0248
0249
0250 if (next_interface->flags & ACPI_OSI_DYNAMIC) {
0251
0252
0253
0254 if (previous_interface == next_interface) {
0255 acpi_gbl_supported_interfaces =
0256 next_interface->next;
0257 } else {
0258 previous_interface->next =
0259 next_interface->next;
0260 }
0261
0262 ACPI_FREE(next_interface->name);
0263 ACPI_FREE(next_interface);
0264 } else {
0265
0266
0267
0268
0269 if (next_interface->flags & ACPI_OSI_INVALID) {
0270 return (AE_NOT_EXIST);
0271 }
0272
0273 next_interface->flags |= ACPI_OSI_INVALID;
0274 }
0275
0276 return (AE_OK);
0277 }
0278
0279 previous_interface = next_interface;
0280 next_interface = next_interface->next;
0281 }
0282
0283
0284
0285 return (AE_NOT_EXIST);
0286 }
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303 acpi_status acpi_ut_update_interfaces(u8 action)
0304 {
0305 struct acpi_interface_info *next_interface;
0306
0307 next_interface = acpi_gbl_supported_interfaces;
0308 while (next_interface) {
0309 if (((next_interface->flags & ACPI_OSI_FEATURE) &&
0310 (action & ACPI_FEATURE_STRINGS)) ||
0311 (!(next_interface->flags & ACPI_OSI_FEATURE) &&
0312 (action & ACPI_VENDOR_STRINGS))) {
0313 if (action & ACPI_DISABLE_INTERFACES) {
0314
0315
0316
0317 next_interface->flags |= ACPI_OSI_INVALID;
0318 } else {
0319
0320
0321 next_interface->flags &= ~ACPI_OSI_INVALID;
0322 }
0323 }
0324
0325 next_interface = next_interface->next;
0326 }
0327
0328 return (AE_OK);
0329 }
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344 struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name)
0345 {
0346 struct acpi_interface_info *next_interface;
0347
0348 next_interface = acpi_gbl_supported_interfaces;
0349 while (next_interface) {
0350 if (!strcmp(interface_name, next_interface->name)) {
0351 return (next_interface);
0352 }
0353
0354 next_interface = next_interface->next;
0355 }
0356
0357 return (NULL);
0358 }
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385 acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
0386 {
0387 union acpi_operand_object *string_desc;
0388 union acpi_operand_object *return_desc;
0389 struct acpi_interface_info *interface_info;
0390 acpi_interface_handler interface_handler;
0391 acpi_status status;
0392 u64 return_value;
0393
0394 ACPI_FUNCTION_TRACE(ut_osi_implementation);
0395
0396
0397
0398 string_desc = walk_state->arguments[0].object;
0399 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
0400 return_ACPI_STATUS(AE_TYPE);
0401 }
0402
0403
0404
0405 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
0406 if (!return_desc) {
0407 return_ACPI_STATUS(AE_NO_MEMORY);
0408 }
0409
0410
0411
0412 return_value = 0;
0413 status = acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
0414 if (ACPI_FAILURE(status)) {
0415 acpi_ut_remove_reference(return_desc);
0416 return_ACPI_STATUS(status);
0417 }
0418
0419
0420
0421 interface_info = acpi_ut_get_interface(string_desc->string.pointer);
0422 if (interface_info && !(interface_info->flags & ACPI_OSI_INVALID)) {
0423
0424
0425
0426
0427
0428 if (interface_info->value > acpi_gbl_osi_data) {
0429 acpi_gbl_osi_data = interface_info->value;
0430 }
0431
0432 return_value = ACPI_UINT64_MAX;
0433 }
0434
0435 acpi_os_release_mutex(acpi_gbl_osi_mutex);
0436
0437
0438
0439
0440
0441
0442 interface_handler = acpi_gbl_interface_handler;
0443 if (interface_handler) {
0444 if (interface_handler
0445 (string_desc->string.pointer, (u32)return_value)) {
0446 return_value = ACPI_UINT64_MAX;
0447 }
0448 }
0449
0450 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
0451 "ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
0452 string_desc->string.pointer,
0453 return_value == 0 ? "not " : ""));
0454
0455
0456
0457 return_desc->integer.value = return_value;
0458 walk_state->return_desc = return_desc;
0459 return_ACPI_STATUS(AE_OK);
0460 }