bioscalls.c (13255B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * bioscalls.c - the lowlevel layer of the PnPBIOS driver 4 */ 5 6#include <linux/types.h> 7#include <linux/module.h> 8#include <linux/init.h> 9#include <linux/linkage.h> 10#include <linux/kernel.h> 11#include <linux/device.h> 12#include <linux/pnp.h> 13#include <linux/mm.h> 14#include <linux/smp.h> 15#include <linux/kmod.h> 16#include <linux/completion.h> 17#include <linux/spinlock.h> 18 19#include <asm/page.h> 20#include <asm/desc.h> 21#include <asm/byteorder.h> 22 23#include "pnpbios.h" 24 25__visible struct { 26 u16 offset; 27 u16 segment; 28} pnp_bios_callpoint; 29 30/* 31 * These are some opcodes for a "static asmlinkage" 32 * As this code is *not* executed inside the linux kernel segment, but in a 33 * alias at offset 0, we need a far return that can not be compiled by 34 * default (please, prove me wrong! this is *really* ugly!) 35 * This is the only way to get the bios to return into the kernel code, 36 * because the bios code runs in 16 bit protected mode and therefore can only 37 * return to the caller if the call is within the first 64kB, and the linux 38 * kernel begins at offset 3GB... 39 */ 40 41asmlinkage __visible void pnp_bios_callfunc(void); 42 43__asm__(".text \n" 44 __ALIGN_STR "\n" 45 ".globl pnp_bios_callfunc\n" 46 "pnp_bios_callfunc:\n" 47 " pushl %edx \n" 48 " pushl %ecx \n" 49 " pushl %ebx \n" 50 " pushl %eax \n" 51 " lcallw *pnp_bios_callpoint\n" 52 " addl $16, %esp \n" 53 " lret \n" 54 ".previous \n"); 55 56#define Q2_SET_SEL(cpu, selname, address, size) \ 57do { \ 58 struct desc_struct *gdt = get_cpu_gdt_rw((cpu)); \ 59 set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \ 60 set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \ 61} while(0) 62 63static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092, 64 (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1); 65 66/* 67 * At some point we want to use this stack frame pointer to unwind 68 * after PnP BIOS oopses. 69 */ 70 71__visible u32 pnp_bios_fault_esp; 72__visible u32 pnp_bios_fault_eip; 73__visible u32 pnp_bios_is_utter_crap = 0; 74 75static DEFINE_SPINLOCK(pnp_bios_lock); 76 77/* 78 * Support Functions 79 */ 80 81static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, 82 u16 arg4, u16 arg5, u16 arg6, u16 arg7, 83 void *ts1_base, u32 ts1_size, 84 void *ts2_base, u32 ts2_size) 85{ 86 unsigned long flags; 87 u16 status; 88 struct desc_struct save_desc_40; 89 int cpu; 90 91 /* 92 * PnP BIOSes are generally not terribly re-entrant. 93 * Also, don't rely on them to save everything correctly. 94 */ 95 if (pnp_bios_is_utter_crap) 96 return PNP_FUNCTION_NOT_SUPPORTED; 97 98 cpu = get_cpu(); 99 save_desc_40 = get_cpu_gdt_rw(cpu)[0x40 / 8]; 100 get_cpu_gdt_rw(cpu)[0x40 / 8] = bad_bios_desc; 101 102 /* On some boxes IRQ's during PnP BIOS calls are deadly. */ 103 spin_lock_irqsave(&pnp_bios_lock, flags); 104 105 /* The lock prevents us bouncing CPU here */ 106 if (ts1_size) 107 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size); 108 if (ts2_size) 109 Q2_SET_SEL(smp_processor_id(), PNP_TS2, ts2_base, ts2_size); 110 111 __asm__ __volatile__("pushl %%ebp\n\t" 112 "pushl %%edi\n\t" 113 "pushl %%esi\n\t" 114 "pushl %%ds\n\t" 115 "pushl %%es\n\t" 116 "pushl %%fs\n\t" 117 "pushl %%gs\n\t" 118 "pushfl\n\t" 119 "movl %%esp, pnp_bios_fault_esp\n\t" 120 "movl $1f, pnp_bios_fault_eip\n\t" 121 "lcall %5,%6\n\t" 122 "1:popfl\n\t" 123 "popl %%gs\n\t" 124 "popl %%fs\n\t" 125 "popl %%es\n\t" 126 "popl %%ds\n\t" 127 "popl %%esi\n\t" 128 "popl %%edi\n\t" 129 "popl %%ebp\n\t":"=a"(status) 130 :"0"((func) | (((u32) arg1) << 16)), 131 "b"((arg2) | (((u32) arg3) << 16)), 132 "c"((arg4) | (((u32) arg5) << 16)), 133 "d"((arg6) | (((u32) arg7) << 16)), 134 "i"(PNP_CS32), "i"(0) 135 :"memory"); 136 spin_unlock_irqrestore(&pnp_bios_lock, flags); 137 138 get_cpu_gdt_rw(cpu)[0x40 / 8] = save_desc_40; 139 put_cpu(); 140 141 /* If we get here and this is set then the PnP BIOS faulted on us. */ 142 if (pnp_bios_is_utter_crap) { 143 printk(KERN_ERR 144 "PnPBIOS: Warning! Your PnP BIOS caused a fatal error. Attempting to continue\n"); 145 printk(KERN_ERR 146 "PnPBIOS: You may need to reboot with the \"pnpbios=off\" option to operate stably\n"); 147 printk(KERN_ERR 148 "PnPBIOS: Check with your vendor for an updated BIOS\n"); 149 } 150 151 return status; 152} 153 154void pnpbios_print_status(const char *module, u16 status) 155{ 156 switch (status) { 157 case PNP_SUCCESS: 158 printk(KERN_ERR "PnPBIOS: %s: function successful\n", module); 159 break; 160 case PNP_NOT_SET_STATICALLY: 161 printk(KERN_ERR "PnPBIOS: %s: unable to set static resources\n", 162 module); 163 break; 164 case PNP_UNKNOWN_FUNCTION: 165 printk(KERN_ERR "PnPBIOS: %s: invalid function number passed\n", 166 module); 167 break; 168 case PNP_FUNCTION_NOT_SUPPORTED: 169 printk(KERN_ERR 170 "PnPBIOS: %s: function not supported on this system\n", 171 module); 172 break; 173 case PNP_INVALID_HANDLE: 174 printk(KERN_ERR "PnPBIOS: %s: invalid handle\n", module); 175 break; 176 case PNP_BAD_PARAMETER: 177 printk(KERN_ERR "PnPBIOS: %s: invalid parameters were passed\n", 178 module); 179 break; 180 case PNP_SET_FAILED: 181 printk(KERN_ERR "PnPBIOS: %s: unable to set resources\n", 182 module); 183 break; 184 case PNP_EVENTS_NOT_PENDING: 185 printk(KERN_ERR "PnPBIOS: %s: no events are pending\n", module); 186 break; 187 case PNP_SYSTEM_NOT_DOCKED: 188 printk(KERN_ERR "PnPBIOS: %s: the system is not docked\n", 189 module); 190 break; 191 case PNP_NO_ISA_PNP_CARDS: 192 printk(KERN_ERR 193 "PnPBIOS: %s: no isapnp cards are installed on this system\n", 194 module); 195 break; 196 case PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES: 197 printk(KERN_ERR 198 "PnPBIOS: %s: cannot determine the capabilities of the docking station\n", 199 module); 200 break; 201 case PNP_CONFIG_CHANGE_FAILED_NO_BATTERY: 202 printk(KERN_ERR 203 "PnPBIOS: %s: unable to undock, the system does not have a battery\n", 204 module); 205 break; 206 case PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT: 207 printk(KERN_ERR 208 "PnPBIOS: %s: could not dock due to resource conflicts\n", 209 module); 210 break; 211 case PNP_BUFFER_TOO_SMALL: 212 printk(KERN_ERR "PnPBIOS: %s: the buffer passed is too small\n", 213 module); 214 break; 215 case PNP_USE_ESCD_SUPPORT: 216 printk(KERN_ERR "PnPBIOS: %s: use ESCD instead\n", module); 217 break; 218 case PNP_MESSAGE_NOT_SUPPORTED: 219 printk(KERN_ERR "PnPBIOS: %s: the message is unsupported\n", 220 module); 221 break; 222 case PNP_HARDWARE_ERROR: 223 printk(KERN_ERR "PnPBIOS: %s: a hardware failure has occurred\n", 224 module); 225 break; 226 default: 227 printk(KERN_ERR "PnPBIOS: %s: unexpected status 0x%x\n", module, 228 status); 229 break; 230 } 231} 232 233/* 234 * PnP BIOS Low Level Calls 235 */ 236 237#define PNP_GET_NUM_SYS_DEV_NODES 0x00 238#define PNP_GET_SYS_DEV_NODE 0x01 239#define PNP_SET_SYS_DEV_NODE 0x02 240#define PNP_GET_EVENT 0x03 241#define PNP_SEND_MESSAGE 0x04 242#define PNP_GET_DOCKING_STATION_INFORMATION 0x05 243#define PNP_SET_STATIC_ALLOCED_RES_INFO 0x09 244#define PNP_GET_STATIC_ALLOCED_RES_INFO 0x0a 245#define PNP_GET_APM_ID_TABLE 0x0b 246#define PNP_GET_PNP_ISA_CONFIG_STRUC 0x40 247#define PNP_GET_ESCD_INFO 0x41 248#define PNP_READ_ESCD 0x42 249#define PNP_WRITE_ESCD 0x43 250 251/* 252 * Call PnP BIOS with function 0x00, "get number of system device nodes" 253 */ 254static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data) 255{ 256 u16 status; 257 258 if (!pnp_bios_present()) 259 return PNP_FUNCTION_NOT_SUPPORTED; 260 status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, 261 PNP_TS1, PNP_DS, 0, 0, data, 262 sizeof(struct pnp_dev_node_info), NULL, 0); 263 data->no_nodes &= 0xff; 264 return status; 265} 266 267int pnp_bios_dev_node_info(struct pnp_dev_node_info *data) 268{ 269 int status = __pnp_bios_dev_node_info(data); 270 271 if (status) 272 pnpbios_print_status("dev_node_info", status); 273 return status; 274} 275 276/* 277 * Note that some PnP BIOSes (e.g., on Sony Vaio laptops) die a horrible 278 * death if they are asked to access the "current" configuration. 279 * Therefore, if it's a matter of indifference, it's better to call 280 * get_dev_node() and set_dev_node() with boot=1 rather than with boot=0. 281 */ 282 283/* 284 * Call PnP BIOS with function 0x01, "get system device node" 285 * Input: *nodenum = desired node, 286 * boot = whether to get nonvolatile boot (!=0) 287 * or volatile current (0) config 288 * Output: *nodenum=next node or 0xff if no more nodes 289 */ 290static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, 291 struct pnp_bios_node *data) 292{ 293 u16 status; 294 u16 tmp_nodenum; 295 296 if (!pnp_bios_present()) 297 return PNP_FUNCTION_NOT_SUPPORTED; 298 if (!boot && pnpbios_dont_use_current_config) 299 return PNP_FUNCTION_NOT_SUPPORTED; 300 tmp_nodenum = *nodenum; 301 status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, 302 boot ? 2 : 1, PNP_DS, 0, &tmp_nodenum, 303 sizeof(tmp_nodenum), data, 65536); 304 *nodenum = tmp_nodenum; 305 return status; 306} 307 308int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data) 309{ 310 int status; 311 312 status = __pnp_bios_get_dev_node(nodenum, boot, data); 313 if (status) 314 pnpbios_print_status("get_dev_node", status); 315 return status; 316} 317 318/* 319 * Call PnP BIOS with function 0x02, "set system device node" 320 * Input: *nodenum = desired node, 321 * boot = whether to set nonvolatile boot (!=0) 322 * or volatile current (0) config 323 */ 324static int __pnp_bios_set_dev_node(u8 nodenum, char boot, 325 struct pnp_bios_node *data) 326{ 327 u16 status; 328 329 if (!pnp_bios_present()) 330 return PNP_FUNCTION_NOT_SUPPORTED; 331 if (!boot && pnpbios_dont_use_current_config) 332 return PNP_FUNCTION_NOT_SUPPORTED; 333 status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, 334 boot ? 2 : 1, PNP_DS, 0, 0, data, 65536, NULL, 335 0); 336 return status; 337} 338 339int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data) 340{ 341 int status; 342 343 status = __pnp_bios_set_dev_node(nodenum, boot, data); 344 if (status) { 345 pnpbios_print_status("set_dev_node", status); 346 return status; 347 } 348 if (!boot) { /* Update devlist */ 349 status = pnp_bios_get_dev_node(&nodenum, boot, data); 350 if (status) 351 return status; 352 } 353 return status; 354} 355 356/* 357 * Call PnP BIOS with function 0x05, "get docking station information" 358 */ 359int pnp_bios_dock_station_info(struct pnp_docking_station_info *data) 360{ 361 u16 status; 362 363 if (!pnp_bios_present()) 364 return PNP_FUNCTION_NOT_SUPPORTED; 365 status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, 366 PNP_DS, 0, 0, 0, 0, data, 367 sizeof(struct pnp_docking_station_info), NULL, 368 0); 369 return status; 370} 371 372/* 373 * Call PnP BIOS with function 0x0a, "get statically allocated resource 374 * information" 375 */ 376static int __pnp_bios_get_stat_res(char *info) 377{ 378 u16 status; 379 380 if (!pnp_bios_present()) 381 return PNP_FUNCTION_NOT_SUPPORTED; 382 status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, 383 PNP_DS, 0, 0, 0, 0, info, 65536, NULL, 0); 384 return status; 385} 386 387int pnp_bios_get_stat_res(char *info) 388{ 389 int status; 390 391 status = __pnp_bios_get_stat_res(info); 392 if (status) 393 pnpbios_print_status("get_stat_res", status); 394 return status; 395} 396 397/* 398 * Call PnP BIOS with function 0x40, "get isa pnp configuration structure" 399 */ 400static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data) 401{ 402 u16 status; 403 404 if (!pnp_bios_present()) 405 return PNP_FUNCTION_NOT_SUPPORTED; 406 status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 407 0, 0, 0, 0, data, 408 sizeof(struct pnp_isa_config_struc), NULL, 0); 409 return status; 410} 411 412int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data) 413{ 414 int status; 415 416 status = __pnp_bios_isapnp_config(data); 417 if (status) 418 pnpbios_print_status("isapnp_config", status); 419 return status; 420} 421 422/* 423 * Call PnP BIOS with function 0x41, "get ESCD info" 424 */ 425static int __pnp_bios_escd_info(struct escd_info_struc *data) 426{ 427 u16 status; 428 429 if (!pnp_bios_present()) 430 return ESCD_FUNCTION_NOT_SUPPORTED; 431 status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, 432 PNP_TS1, PNP_DS, data, 433 sizeof(struct escd_info_struc), NULL, 0); 434 return status; 435} 436 437int pnp_bios_escd_info(struct escd_info_struc *data) 438{ 439 int status; 440 441 status = __pnp_bios_escd_info(data); 442 if (status) 443 pnpbios_print_status("escd_info", status); 444 return status; 445} 446 447/* 448 * Call PnP BIOS function 0x42, "read ESCD" 449 * nvram_base is determined by calling escd_info 450 */ 451static int __pnp_bios_read_escd(char *data, u32 nvram_base) 452{ 453 u16 status; 454 455 if (!pnp_bios_present()) 456 return ESCD_FUNCTION_NOT_SUPPORTED; 457 status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 458 0, data, 65536, __va(nvram_base), 65536); 459 return status; 460} 461 462int pnp_bios_read_escd(char *data, u32 nvram_base) 463{ 464 int status; 465 466 status = __pnp_bios_read_escd(data, nvram_base); 467 if (status) 468 pnpbios_print_status("read_escd", status); 469 return status; 470} 471 472void pnpbios_calls_init(union pnp_bios_install_struct *header) 473{ 474 int i; 475 476 pnp_bios_callpoint.offset = header->fields.pm16offset; 477 pnp_bios_callpoint.segment = PNP_CS16; 478 479 for_each_possible_cpu(i) { 480 struct desc_struct *gdt = get_cpu_gdt_rw(i); 481 if (!gdt) 482 continue; 483 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32], 484 (unsigned long)&pnp_bios_callfunc); 485 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS16], 486 (unsigned long)__va(header->fields.pm16cseg)); 487 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_DS], 488 (unsigned long)__va(header->fields.pm16dseg)); 489 } 490}