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