1/* 2 Copyright 1999, Be Incorporated. All Rights Reserved. 3 This file may be used under the terms of the Be Sample Code License. 4 5 Other authors: 6 Mark Watson; 7 Rudolf Cornelissen 3/2002-6/2008. 8*/ 9 10 11#include "DriverInterface.h" 12#include "nv_macros.h" 13 14#include <graphic_driver.h> 15#include <KernelExport.h> 16#include <ISA.h> 17#include <PCI.h> 18#include <OS.h> 19#include <directories.h> 20#include <driver_settings.h> 21 22#include <stdlib.h> 23#include <stdio.h> 24#include <string.h> 25 26#define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s)) 27#define set_pci(o, s, v) (*pci_bus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v)) 28 29#define MAX_DEVICES 8 30 31#ifndef __HAIKU__ 32# undef B_USER_CLONEABLE_AREA 33# define B_USER_CLONEABLE_AREA 0 34#endif 35 36/* Tell the kernel what revision of the driver API we support */ 37int32 api_version = B_CUR_DRIVER_API_VERSION; 38 39/* these structures are private to the kernel driver */ 40typedef struct device_info device_info; 41 42typedef struct { 43 timer te; /* timer entry for add_timer() */ 44 device_info *di; /* pointer to the owning device */ 45 bigtime_t when_target; /* when we're supposed to wake up */ 46} timer_info; 47 48struct device_info { 49 uint32 is_open; /* a count of how many times the devices has been opened */ 50 area_id shared_area; /* the area shared between the driver and all of the accelerants */ 51 shared_info *si; /* a pointer to the shared area, for convenience */ 52 vuint32 *regs; /* kernel's pointer to memory mapped registers */ 53 pci_info pcii; /* a convenience copy of the pci info for this device */ 54 char name[B_OS_NAME_LENGTH]; /* where we keep the name of the device for publishing and comparing */ 55}; 56 57typedef struct { 58 uint32 count; /* number of devices actually found */ 59 benaphore kernel; /* for serializing opens/closes */ 60 char *device_names[MAX_DEVICES+1]; /* device name pointer storage */ 61 device_info di[MAX_DEVICES]; /* device specific stuff */ 62} DeviceData; 63 64/* prototypes for our private functions */ 65static status_t open_hook(const char* name, uint32 flags, void** cookie); 66static status_t close_hook(void* dev); 67static status_t free_hook(void* dev); 68static status_t read_hook(void* dev, off_t pos, void* buf, size_t* len); 69static status_t write_hook(void* dev, off_t pos, const void* buf, size_t* len); 70static status_t control_hook(void* dev, uint32 msg, void *buf, size_t len); 71static status_t map_device(device_info *di); 72static void unmap_device(device_info *di); 73static void probe_devices(void); 74static int32 nv_interrupt(void *data); 75 76static DeviceData *pd; 77static isa_module_info *isa_bus = NULL; 78static pci_module_info *pci_bus = NULL; 79static device_hooks graphics_device_hooks = { 80 open_hook, 81 close_hook, 82 free_hook, 83 control_hook, 84 read_hook, 85 write_hook, 86 NULL, 87 NULL, 88 NULL, 89 NULL 90}; 91 92#define VENDOR_ID_NVIDIA 0x10de /* Nvidia */ 93#define VENDOR_ID_ELSA 0x1048 /* Elsa GmbH */ 94#define VENDOR_ID_NVSTBSGS 0x12d2 /* Nvidia STB/SGS-Thompson */ 95#define VENDOR_ID_VARISYS 0x1888 /* Varisys Limited */ 96 97static uint16 nvidia_device_list[] = { 98#if 0 99 // TODO: these cards are not yet supported 100 0x0191, /* Nvidia GeForce 8800 GTX (G80) */ 101 0x0193, /* Nvidia GeForce 8800 GTS (G80) */ 102 0x0194, /* Nvidia GeForce 8800 Ultra (G80) */ 103 0x0400, /* Nvidia GeForce 8600 GTS (G84) */ 104 0x0401, /* Nvidia GeForce 8600 GT (G84) */ 105 0x0402, /* Nvidia GeForce 8600 GT (G84) */ 106 0x0403, /* Nvidia GeForce 8600 GS (G84) */ 107 0x0404, /* Nvidia GeForce 8400 GS (G84) */ 108 0x0406, /* Nvidia GeForce 8300 GS (G84) */ 109 0x0407, /* Nvidia GeForce 8600M GT */ 110 0x0420, /* Nvidia GeForce 8400 SE (G86) */ 111 0x0421, /* Nvidia GeForce 8500 GT (G86) */ 112 0x0422, /* Nvidia GeForce 8400 GS (G86) */ 113 0x0423, /* Nvidia GeForce 8300 GS (G86) */ 114 0x0424, /* Nvidia GeForce 8400 GS (G86) */ 115 0x0426, /* Nvidia GeForce 8400M GT (G86M) */ 116 0x0600, /* Nvidia GeForce 8800 GTS 512 (G92) */ 117 0x0602, /* Nvidia GeForce 8800 GT (G92) */ 118 0x0606, /* Nvidia GeForce 8800 GS (G92) */ 119 0x060d, /* Nvidia GeForce 8800 GS (G92) */ 120 0x0611, /* Nvidia GeForce 8800 GT (G92) */ 121 0x0642, /* Nvidia GeForce 8400 GS (G96) */ 122 0x06e2, /* Nvidia GeForce 8400 (G98) */ 123 0x06e3, /* Nvidia GeForce 8300 GS (G98) */ 124 0x06e4, /* Nvidia GeForce 8400 GS (G98) */ 125#endif 126 0 127}; 128 129static struct { 130 uint16 vendor; 131 uint16 *devices; 132} SupportedDevices[] = { 133 {VENDOR_ID_NVIDIA, nvidia_device_list}, 134 {0x0000, NULL} 135}; 136 137static nv_settings sSettings = { // see comments in nvidia_gpgpu.settings 138 /* for driver */ 139 DRIVER_PREFIX ".accelerant", 140 "none", // primary 141 false, // dumprom 142 /* for accelerant */ 143 0x00000000, // logmask 144 0, // memory 145 true, // usebios 146 true, // hardcursor 147 false, // switchhead 148 false, // pgm_panel 149 false, // force_sync 150 true, // force_ws 151 0, // gpu_clk 152 0, // ram_clk 153}; 154 155 156static void 157dumprom(void *rom, uint32 size, pci_info pcii) 158{ 159 int fd; 160 uint32 cnt; 161 char fname[64]; 162 163 /* determine the romfile name: we need split-up per card in the system */ 164 sprintf (fname, kUserDirectory "/" DRIVER_PREFIX "." DEVICE_FORMAT ".rom", 165 pcii.vendor_id, pcii.device_id, pcii.bus, pcii.device, pcii.function); 166 167 fd = open (fname, O_WRONLY | O_CREAT, 0666); 168 if (fd < 0) return; 169 170 /* apparantly max. 32kb may be written at once; 171 * the ROM size is a multiple of that anyway. */ 172 for (cnt = 0; (cnt < size); cnt += 32768) 173 write (fd, ((void *)(((uint8 *)rom) + cnt)), 32768); 174 close (fd); 175} 176 177 178/*! return 1 if vblank interrupt has occured */ 179static int 180caused_vbi_crtc1(vuint32 * regs) 181{ 182 return (NV_REG32(NV32_CRTC_INTS) & 0x00000001); 183} 184 185 186/*! clear the vblank interrupt */ 187static void 188clear_vbi_crtc1(vuint32 * regs) 189{ 190 NV_REG32(NV32_CRTC_INTS) = 0x00000001; 191} 192 193 194static void 195enable_vbi_crtc1(vuint32 * regs) 196{ 197 /* clear the vblank interrupt */ 198 NV_REG32(NV32_CRTC_INTS) = 0x00000001; 199 /* enable nVidia interrupt source vblank */ 200 NV_REG32(NV32_CRTC_INTE) |= 0x00000001; 201 /* enable nVidia interrupt system hardware (b0-1) */ 202 NV_REG32(NV32_MAIN_INTE) = 0x00000001; 203} 204 205 206static void 207disable_vbi_crtc1(vuint32 * regs) 208{ 209 /* disable nVidia interrupt source vblank */ 210 NV_REG32(NV32_CRTC_INTE) &= 0xfffffffe; 211 /* clear the vblank interrupt */ 212 NV_REG32(NV32_CRTC_INTS) = 0x00000001; 213} 214 215 216/*! return 1 if vblank interrupt has occured */ 217static int 218caused_vbi_crtc2(vuint32 * regs) 219{ 220 return (NV_REG32(NV32_CRTC2_INTS) & 0x00000001); 221} 222 223 224/*! clear the vblank interrupt */ 225static void 226clear_vbi_crtc2(vuint32 * regs) 227{ 228 NV_REG32(NV32_CRTC2_INTS) = 0x00000001; 229} 230 231 232static void 233enable_vbi_crtc2(vuint32 * regs) 234{ 235 /* clear the vblank interrupt */ 236 NV_REG32(NV32_CRTC2_INTS) = 0x00000001; 237 /* enable nVidia interrupt source vblank */ 238 NV_REG32(NV32_CRTC2_INTE) |= 0x00000001; 239 /* enable nVidia interrupt system hardware (b0-1) */ 240 NV_REG32(NV32_MAIN_INTE) = 0x00000001; 241} 242 243 244static void 245disable_vbi_crtc2(vuint32 * regs) 246{ 247 /* disable nVidia interrupt source vblank */ 248 NV_REG32(NV32_CRTC2_INTE) &= 0xfffffffe; 249 /* clear the vblank interrupt */ 250 NV_REG32(NV32_CRTC2_INTS) = 0x00000001; 251} 252 253 254//fixme: 255//dangerous code, on singlehead cards better not try accessing secondary head 256//registers (card might react in unpredictable ways, though there's only a small 257//chance we actually run into this). 258//fix requires (some) card recognition code to be moved from accelerant to 259//kerneldriver... 260static void 261disable_vbi_all(vuint32 * regs) 262{ 263 /* disable nVidia interrupt source vblank */ 264 NV_REG32(NV32_CRTC_INTE) &= 0xfffffffe; 265 /* clear the vblank interrupt */ 266 NV_REG32(NV32_CRTC_INTS) = 0x00000001; 267 268 /* disable nVidia interrupt source vblank */ 269 NV_REG32(NV32_CRTC2_INTE) &= 0xfffffffe; 270 /* clear the vblank interrupt */ 271 NV_REG32(NV32_CRTC2_INTS) = 0x00000001; 272 273 /* disable nVidia interrupt system hardware (b0-1) */ 274 NV_REG32(NV32_MAIN_INTE) = 0x00000000; 275} 276 277 278static status_t 279map_device(device_info *di) 280{ 281 char buffer[B_OS_NAME_LENGTH]; /*memory for device name*/ 282 shared_info *si = di->si; 283 uint32 tmpUlong, tmpROMshadow; 284 pci_info *pcii = &(di->pcii); 285 system_info sysinfo; 286 287 /* variables for making copy of ROM */ 288 uint8* rom_temp; 289 area_id rom_area = -1; 290 291 /* Nvidia cards have registers in [0] and framebuffer in [1] */ 292 int registers = 0; 293 int frame_buffer = 1; 294 295 /* enable memory mapped IO, disable VGA I/O - this is defined in the PCI standard */ 296 tmpUlong = get_pci(PCI_command, 2); 297 /* enable PCI access */ 298 tmpUlong |= PCI_command_memory; 299 /* enable busmastering */ 300 tmpUlong |= PCI_command_master; 301 /* disable ISA I/O access */ 302 tmpUlong &= ~PCI_command_io; 303 set_pci(PCI_command, 2, tmpUlong); 304 305 /*work out which version of BeOS is running*/ 306 get_system_info(&sysinfo); 307 if (0)//sysinfo.kernel_build_date[0]=='J')/*FIXME - better ID version*/ 308 { 309 si->use_clone_bugfix = 1; 310 } 311 else 312 { 313 si->use_clone_bugfix = 0; 314 } 315 316 /* work out a name for the register mapping */ 317 sprintf(buffer, DEVICE_FORMAT " regs", 318 di->pcii.vendor_id, di->pcii.device_id, 319 di->pcii.bus, di->pcii.device, di->pcii.function); 320 321 /* get a virtual memory address for the registers*/ 322 si->regs_area = map_physical_memory( 323 buffer, 324 /* WARNING: Nvidia needs to map regs as viewed from PCI space! */ 325 di->pcii.u.h0.base_registers_pci[registers], 326 di->pcii.u.h0.base_register_sizes[registers], 327 B_ANY_KERNEL_ADDRESS, 328 B_USER_CLONEABLE_AREA | (si->use_clone_bugfix ? B_READ_AREA|B_WRITE_AREA : 0), 329 (void **)&(di->regs)); 330 si->clone_bugfix_regs = (uint32 *) di->regs; 331 332 /* if mapping registers to vmem failed then pass on error */ 333 if (si->regs_area < 0) return si->regs_area; 334 335 /* work out a name for the ROM mapping*/ 336 sprintf(buffer, DEVICE_FORMAT " rom", 337 di->pcii.vendor_id, di->pcii.device_id, 338 di->pcii.bus, di->pcii.device, di->pcii.function); 339 340 /* preserve ROM shadowing setting, we need to restore the current state later on. */ 341 /* warning: 342 * 'don't touch': (confirmed) NV04, NV05, NV05-M64, NV11 all shutoff otherwise. 343 * NV18, NV28 and NV34 keep working. 344 * confirmed NV28 and NV34 to use upper part of shadowed ROM for scratch purposes, 345 * however the actual ROM content (so the used part) is intact (confirmed). */ 346 tmpROMshadow = get_pci(NVCFG_ROMSHADOW, 4); 347 /* temporary disable ROM shadowing, we want the guaranteed exact contents of the chip */ 348 set_pci(NVCFG_ROMSHADOW, 4, 0); 349 350 /* get ROM memory mapped base adress - this is defined in the PCI standard */ 351 tmpUlong = get_pci(PCI_rom_base, 4); 352 //fixme?: if (!tmpUlong) try to map the ROM ourselves. Confirmed a PCIe system not 353 //having the ROM mapped on PCI and PCIe cards. Falling back to fetching from ISA 354 //legacy space will get us into trouble if we aren't the primary graphics card!! 355 //(as legacy space always has the primary card's ROM 'mapped'!) 356 if (tmpUlong) { 357 /* ROM was assigned an adress, so enable ROM decoding - see PCI standard */ 358 tmpUlong |= 0x00000001; 359 set_pci(PCI_rom_base, 4, tmpUlong); 360 361 rom_area = map_physical_memory( 362 buffer, 363 di->pcii.u.h0.rom_base_pci, 364 di->pcii.u.h0.rom_size, 365 B_ANY_KERNEL_ADDRESS, 366 B_READ_AREA, 367 (void **)&(rom_temp) 368 ); 369 370 /* check if we got the BIOS and signature (might fail on laptops..) */ 371 if (rom_area >= 0) { 372 if ((rom_temp[0] != 0x55) || (rom_temp[1] != 0xaa)) { 373 /* apparantly no ROM is mapped here */ 374 delete_area(rom_area); 375 rom_area = -1; 376 /* force using ISA legacy map as fall-back */ 377 tmpUlong = 0x00000000; 378 } 379 } else { 380 /* mapping failed: force using ISA legacy map as fall-back */ 381 tmpUlong = 0x00000000; 382 } 383 } 384 385 if (!tmpUlong) { 386 /* ROM was not assigned an adress, fetch it from ISA legacy memory map! */ 387 rom_area = map_physical_memory(buffer, 0x000c0000, 388 65536, B_ANY_KERNEL_ADDRESS, B_READ_AREA, (void **)&(rom_temp)); 389 } 390 391 /* if mapping ROM to vmem failed then clean up and pass on error */ 392 if (rom_area < 0) { 393 delete_area(si->regs_area); 394 si->regs_area = -1; 395 return rom_area; 396 } 397 398 /* dump ROM to file if selected in nvidia.settings 399 * (ROM always fits in 64Kb: checked TNT1 - FX5950) */ 400 if (sSettings.dumprom) 401 dumprom(rom_temp, 65536, di->pcii); 402 403 /* make a copy of ROM for future reference */ 404 memcpy(si->rom_mirror, rom_temp, 65536); 405 406 /* disable ROM decoding - this is defined in the PCI standard, and delete the area */ 407 tmpUlong = get_pci(PCI_rom_base, 4); 408 tmpUlong &= 0xfffffffe; 409 set_pci(PCI_rom_base, 4, tmpUlong); 410 delete_area(rom_area); 411 412 /* restore original ROM shadowing setting to prevent trouble starting (some) cards */ 413 set_pci(NVCFG_ROMSHADOW, 4, tmpROMshadow); 414 415 /* work out a name for the framebuffer mapping*/ 416 sprintf(buffer, DEVICE_FORMAT " framebuffer", 417 di->pcii.vendor_id, di->pcii.device_id, 418 di->pcii.bus, di->pcii.device, di->pcii.function); 419 420 /* map the framebuffer into vmem, using Write Combining*/ 421 si->fb_area = map_physical_memory(buffer, 422 /* WARNING: Nvidia needs to map framebuffer as viewed from PCI space! */ 423 di->pcii.u.h0.base_registers_pci[frame_buffer], 424 di->pcii.u.h0.base_register_sizes[frame_buffer], 425 B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC, 426 B_READ_AREA | B_WRITE_AREA, 427 &(si->framebuffer)); 428 429 /*if failed with write combining try again without*/ 430 if (si->fb_area < 0) { 431 si->fb_area = map_physical_memory(buffer, 432 /* WARNING: Nvidia needs to map framebuffer as viewed from PCI space! */ 433 di->pcii.u.h0.base_registers_pci[frame_buffer], 434 di->pcii.u.h0.base_register_sizes[frame_buffer], 435 B_ANY_KERNEL_BLOCK_ADDRESS, 436 B_READ_AREA | B_WRITE_AREA, 437 &(si->framebuffer)); 438 } 439 440 /* if there was an error, delete our other areas and pass on error*/ 441 if (si->fb_area < 0) { 442 delete_area(si->regs_area); 443 si->regs_area = -1; 444 return si->fb_area; 445 } 446 447 //fixme: retest for card coldstart and PCI/virt_mem mapping!! 448 /* remember the DMA address of the frame buffer for BDirectWindow?? purposes */ 449 si->framebuffer_pci = (void *) di->pcii.u.h0.base_registers_pci[frame_buffer]; 450 451 // remember settings for use here and in accelerant 452 si->settings = sSettings; 453 454 /* in any case, return the result */ 455 return si->fb_area; 456} 457 458 459static void 460unmap_device(device_info *di) 461{ 462 shared_info *si = di->si; 463 uint32 tmpUlong; 464 pci_info *pcii = &(di->pcii); 465 466 /* disable memory mapped IO */ 467 tmpUlong = get_pci(PCI_command, 4); 468 tmpUlong &= 0xfffffffc; 469 set_pci(PCI_command, 4, tmpUlong); 470 /* delete the areas */ 471 if (si->regs_area >= 0) 472 delete_area(si->regs_area); 473 if (si->fb_area >= 0) 474 delete_area(si->fb_area); 475 si->regs_area = si->fb_area = -1; 476 si->framebuffer = NULL; 477 di->regs = NULL; 478} 479 480 481static void 482probe_devices(void) 483{ 484 uint32 pci_index = 0; 485 uint32 count = 0; 486 device_info *di = pd->di; 487 char tmp_name[B_OS_NAME_LENGTH]; 488 489 /* while there are more pci devices */ 490 while (count < MAX_DEVICES 491 && (*pci_bus->get_nth_pci_info)(pci_index, &(di->pcii)) == B_OK) { 492 int vendor = 0; 493 494 /* if we match a supported vendor */ 495 while (SupportedDevices[vendor].vendor) { 496 if (SupportedDevices[vendor].vendor == di->pcii.vendor_id) { 497 uint16 *devices = SupportedDevices[vendor].devices; 498 /* while there are more supported devices */ 499 while (*devices) { 500 /* if we match a supported device */ 501 if (*devices == di->pcii.device_id ) { 502 /* publish the device name */ 503 sprintf(tmp_name, DEVICE_FORMAT, 504 di->pcii.vendor_id, di->pcii.device_id, 505 di->pcii.bus, di->pcii.device, di->pcii.function); 506 /* tweak the exported name to show first in the alphabetically ordered /dev/ 507 * hierarchy folder, so the system will use it as primary adaptor if requested 508 * via nvidia.settings. */ 509 if (strcmp(tmp_name, sSettings.primary) == 0) 510 sprintf(tmp_name, "-%s", sSettings.primary); 511 /* add /dev/ hierarchy path */ 512 sprintf(di->name, "graphics/%s", tmp_name); 513 /* remember the name */ 514 pd->device_names[count] = di->name; 515 /* mark the driver as available for R/W open */ 516 di->is_open = 0; 517 /* mark areas as not yet created */ 518 di->shared_area = -1; 519 /* mark pointer to shared data as invalid */ 520 di->si = NULL; 521 /* inc pointer to device info */ 522 di++; 523 /* inc count */ 524 count++; 525 /* break out of these while loops */ 526 goto next_device; 527 } 528 /* next supported device */ 529 devices++; 530 } 531 } 532 vendor++; 533 } 534next_device: 535 /* next pci_info struct, please */ 536 pci_index++; 537 } 538 /* propagate count */ 539 pd->count = count; 540 /* terminate list of device names with a null pointer */ 541 pd->device_names[pd->count] = NULL; 542} 543 544 545static uint32 546thread_interrupt_work(int32 *flags, vuint32 *regs, shared_info *si) 547{ 548 uint32 handled = B_HANDLED_INTERRUPT; 549 /* release the vblank semaphore */ 550 if (si->vblank >= 0) { 551 int32 blocked; 552 if ((get_sem_count(si->vblank, &blocked) == B_OK) && (blocked < 0)) { 553 release_sem_etc(si->vblank, -blocked, B_DO_NOT_RESCHEDULE); 554 handled = B_INVOKE_SCHEDULER; 555 } 556 } 557 return handled; 558} 559 560 561static int32 562nv_interrupt(void *data) 563{ 564 int32 handled = B_UNHANDLED_INTERRUPT; 565 device_info *di = (device_info *)data; 566 shared_info *si = di->si; 567 int32 *flags = &(si->flags); 568 vuint32 *regs; 569 570 /* is someone already handling an interrupt for this device? */ 571 if (atomic_or(flags, SKD_HANDLER_INSTALLED) & SKD_HANDLER_INSTALLED) goto exit0; 572 573 /* get regs */ 574 regs = di->regs; 575 576 /* was it a VBI? */ 577 /* note: si->ps.secondary_head was cleared by kerneldriver earlier! (at least) */ 578 if (si->ps.secondary_head) { 579 //fixme: 580 //rewrite once we use one driver instance 'per head' (instead of 'per card') 581 if (caused_vbi_crtc1(regs) || caused_vbi_crtc2(regs)) { 582 /* clear the interrupt(s) */ 583 clear_vbi_crtc1(regs); 584 clear_vbi_crtc2(regs); 585 /* release the semaphore */ 586 handled = thread_interrupt_work(flags, regs, si); 587 } 588 } else { 589 if (caused_vbi_crtc1(regs)) { 590 /* clear the interrupt */ 591 clear_vbi_crtc1(regs); 592 /* release the semaphore */ 593 handled = thread_interrupt_work(flags, regs, si); 594 } 595 } 596 597 /* note that we're not in the handler any more */ 598 atomic_and(flags, ~SKD_HANDLER_INSTALLED); 599 600exit0: 601 return handled; 602} 603 604 605// #pragma mark - device hooks 606 607 608static status_t 609open_hook(const char* name, uint32 flags, void** cookie) 610{ 611 int32 index = 0; 612 device_info *di; 613 shared_info *si; 614 thread_id thid; 615 thread_info thinfo; 616 status_t result = B_OK; 617 char shared_name[B_OS_NAME_LENGTH]; 618 physical_entry map[1]; 619 size_t net_buf_size; 620 void *unaligned_dma_buffer; 621 622 /* find the device name in the list of devices */ 623 /* we're never passed a name we didn't publish */ 624 while (pd->device_names[index] 625 && (strcmp(name, pd->device_names[index]) != 0)) 626 index++; 627 628 /* for convienience */ 629 di = &(pd->di[index]); 630 631 /* make sure no one else has write access to the common data */ 632 AQUIRE_BEN(pd->kernel); 633 634 /* if it's already open for writing */ 635 if (di->is_open) { 636 /* mark it open another time */ 637 goto mark_as_open; 638 } 639 /* create the shared_info area */ 640 sprintf(shared_name, DEVICE_FORMAT " shared", 641 di->pcii.vendor_id, di->pcii.device_id, 642 di->pcii.bus, di->pcii.device, di->pcii.function); 643 /* create this area with NO user-space read or write permissions, to prevent accidental damage */ 644 di->shared_area = create_area(shared_name, (void **)&(di->si), B_ANY_KERNEL_ADDRESS, 645 ((sizeof(shared_info) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1)), B_FULL_LOCK, 646 B_USER_CLONEABLE_AREA); 647 if (di->shared_area < 0) { 648 /* return the error */ 649 result = di->shared_area; 650 goto done; 651 } 652 653 /* save a few dereferences */ 654 si = di->si; 655 656 /* create the DMA command buffer area */ 657 //fixme? for R4.5 a workaround for cloning would be needed! 658 /* we want to setup a 1Mb buffer (size must be multiple of B_PAGE_SIZE) */ 659 net_buf_size = ((1 * 1024 * 1024) + (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1); 660 /* create the area that will hold the DMA command buffer */ 661 si->unaligned_dma_area = 662 create_area("NV DMA cmd buffer", 663 (void **)&unaligned_dma_buffer, 664 B_ANY_KERNEL_ADDRESS, 665 2 * net_buf_size, /* take twice the net size so we can have MTRR-WC even on old systems */ 666 B_32_BIT_CONTIGUOUS, /* GPU always needs access */ 667 B_USER_CLONEABLE_AREA | B_READ_AREA | B_WRITE_AREA); 668 // TODO: Physical aligning can be done without waste using the 669 // private create_area_etc(). 670 /* on error, abort */ 671 if (si->unaligned_dma_area < 0) 672 { 673 /* free the already created shared_info area, and return the error */ 674 result = si->unaligned_dma_area; 675 goto free_shared; 676 } 677 /* we (also) need the physical adress our DMA buffer is at, as this needs to be 678 * fed into the GPU's engine later on. Get an aligned adress so we can use MTRR-WC 679 * even on older CPU's. */ 680 get_memory_map(unaligned_dma_buffer, B_PAGE_SIZE, map, 1); 681 si->dma_buffer_pci = (void*) 682 ((map[0].address + net_buf_size - 1) & ~(net_buf_size - 1)); 683 684 /* map the net DMA command buffer into vmem, using Write Combining */ 685 si->dma_area = map_physical_memory( 686 "NV aligned DMA cmd buffer", (addr_t)si->dma_buffer_pci, net_buf_size, 687 B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC, 688 B_READ_AREA | B_WRITE_AREA, &(si->dma_buffer)); 689 /* if failed with write combining try again without */ 690 if (si->dma_area < 0) { 691 si->dma_area = map_physical_memory( 692 "NV aligned DMA cmd buffer", (addr_t)si->dma_buffer_pci, 693 net_buf_size, B_ANY_KERNEL_BLOCK_ADDRESS, 694 B_READ_AREA | B_WRITE_AREA, &(si->dma_buffer)); 695 } 696 /* if there was an error, delete our other areas and pass on error*/ 697 if (si->dma_area < 0) 698 { 699 /* free the already created areas, and return the error */ 700 result = si->dma_area; 701 goto free_shared_and_uadma; 702 } 703 704 /* save the vendor and device IDs */ 705 si->vendor_id = di->pcii.vendor_id; 706 si->device_id = di->pcii.device_id; 707 si->revision = di->pcii.revision; 708 si->bus = di->pcii.bus; 709 si->device = di->pcii.device; 710 si->function = di->pcii.function; 711 712 /* ensure that the accelerant's INIT_ACCELERANT function can be executed */ 713 si->accelerant_in_use = false; 714 /* preset singlehead card to prevent early INT routine calls (once installed) to 715 * wrongly identify the INT request coming from us! */ 716 si->ps.secondary_head = false; 717 718 /* note the amount of system RAM the system BIOS assigned to the card if applicable: 719 * unified memory architecture (UMA) */ 720 switch ((((uint32)(si->device_id)) << 16) | si->vendor_id) 721 { 722 case 0x01a010de: /* Nvidia GeForce2 Integrated GPU */ 723 /* device at bus #0, device #0, function #1 holds value at byte-index 0x7C */ 724 si->ps.memory_size = 1024 * 1024 * 725 (((((*pci_bus->read_pci_config)(0, 0, 1, 0x7c, 4)) & 0x000007c0) >> 6) + 1); 726 /* last 64kB RAM is used for the BIOS (or something else?) */ 727 si->ps.memory_size -= (64 * 1024); 728 break; 729 case 0x01f010de: /* Nvidia GeForce4 MX Integrated GPU */ 730 /* device at bus #0, device #0, function #1 holds value at byte-index 0x84 */ 731 si->ps.memory_size = 1024 * 1024 * 732 (((((*pci_bus->read_pci_config)(0, 0, 1, 0x84, 4)) & 0x000007f0) >> 4) + 1); 733 /* last 64kB RAM is used for the BIOS (or something else?) */ 734 si->ps.memory_size -= (64 * 1024); 735 break; 736 default: 737 /* all other cards have own RAM: the amount of which is determined in the 738 * accelerant. */ 739 break; 740 } 741 742 /* map the device */ 743 result = map_device(di); 744 if (result < 0) goto free_shared_and_alldma; 745 746 /* we will be returning OK status for sure now */ 747 result = B_OK; 748 749 /* disable and clear any pending interrupts */ 750 //fixme: 751 //distinquish between crtc1/crtc2 once all heads get seperate driver instances! 752 disable_vbi_all(di->regs); 753 754 /* preset we can't use INT related functions */ 755 si->ps.int_assigned = false; 756 757 /* create a semaphore for vertical blank management */ 758 si->vblank = create_sem(0, di->name); 759 if (si->vblank < 0) goto mark_as_open; 760 761 /* change the owner of the semaphores to the opener's team */ 762 /* this is required because apps can't aquire kernel semaphores */ 763 thid = find_thread(NULL); 764 get_thread_info(thid, &thinfo); 765 set_sem_owner(si->vblank, thinfo.team); 766 767 /* If there is a valid interrupt line assigned then set up interrupts */ 768 if ((di->pcii.u.h0.interrupt_pin == 0x00) || 769 (di->pcii.u.h0.interrupt_line == 0xff) || /* no IRQ assigned */ 770 (di->pcii.u.h0.interrupt_line <= 0x02)) /* system IRQ assigned */ 771 { 772 /* delete the semaphore as it won't be used */ 773 delete_sem(si->vblank); 774 si->vblank = -1; 775 } 776 else 777 { 778 /* otherwise install our interrupt handler */ 779 result = install_io_interrupt_handler(di->pcii.u.h0.interrupt_line, nv_interrupt, (void *)di, 0); 780 /* bail if we couldn't install the handler */ 781 if (result != B_OK) 782 { 783 /* delete the semaphore as it won't be used */ 784 delete_sem(si->vblank); 785 si->vblank = -1; 786 } 787 else 788 { 789 /* inform accelerant(s) we can use INT related functions */ 790 si->ps.int_assigned = true; 791 } 792 } 793 794mark_as_open: 795 /* mark the device open */ 796 di->is_open++; 797 798 /* send the cookie to the opener */ 799 *cookie = di; 800 801 goto done; 802 803 804free_shared_and_alldma: 805 /* clean up our aligned DMA area */ 806 delete_area(si->dma_area); 807 si->dma_area = -1; 808 si->dma_buffer = NULL; 809 810free_shared_and_uadma: 811 /* clean up our unaligned DMA area */ 812 delete_area(si->unaligned_dma_area); 813 si->unaligned_dma_area = -1; 814 si->dma_buffer_pci = NULL; 815 816free_shared: 817 /* clean up our shared area */ 818 delete_area(di->shared_area); 819 di->shared_area = -1; 820 di->si = NULL; 821 822done: 823 /* end of critical section */ 824 RELEASE_BEN(pd->kernel); 825 826 /* all done, return the status */ 827 return result; 828} 829 830 831static status_t 832read_hook(void* dev, off_t pos, void* buf, size_t* len) 833{ 834 *len = 0; 835 return B_NOT_ALLOWED; 836} 837 838 839static status_t 840write_hook(void* dev, off_t pos, const void* buf, size_t* len) 841{ 842 *len = 0; 843 return B_NOT_ALLOWED; 844} 845 846 847static status_t 848close_hook(void* dev) 849{ 850 /* we don't do anything on close: there might be dup'd fd */ 851 return B_NO_ERROR; 852} 853 854 855static status_t 856free_hook(void* dev) 857{ 858 device_info *di = (device_info *)dev; 859 shared_info *si = di->si; 860 vuint32 *regs = di->regs; 861 862 /* lock the driver */ 863 AQUIRE_BEN(pd->kernel); 864 865 /* if opened multiple times, decrement the open count and exit */ 866 if (di->is_open > 1) 867 goto unlock_and_exit; 868 869 /* disable and clear any pending interrupts */ 870 //fixme: 871 //distinquish between crtc1/crtc2 once all heads get seperate driver instances! 872 disable_vbi_all(regs); 873 874 if (si->ps.int_assigned) { 875 /* remove interrupt handler */ 876 remove_io_interrupt_handler(di->pcii.u.h0.interrupt_line, nv_interrupt, di); 877 878 /* delete the semaphores, ignoring any errors ('cause the owning 879 team may have died on us) */ 880 delete_sem(si->vblank); 881 si->vblank = -1; 882 } 883 884 /* free regs and framebuffer areas */ 885 unmap_device(di); 886 887 /* clean up our aligned DMA area */ 888 delete_area(si->dma_area); 889 si->dma_area = -1; 890 si->dma_buffer = NULL; 891 892 /* clean up our unaligned DMA area */ 893 delete_area(si->unaligned_dma_area); 894 si->unaligned_dma_area = -1; 895 si->dma_buffer_pci = NULL; 896 897 /* clean up our shared area */ 898 delete_area(di->shared_area); 899 di->shared_area = -1; 900 di->si = NULL; 901 902unlock_and_exit: 903 /* mark the device available */ 904 di->is_open--; 905 /* unlock the driver */ 906 RELEASE_BEN(pd->kernel); 907 /* all done */ 908 return B_OK; 909} 910 911 912static status_t 913control_hook(void* dev, uint32 msg, void *buf, size_t len) 914{ 915 device_info *di = (device_info *)dev; 916 status_t result = B_DEV_INVALID_IOCTL; 917 uint32 tmpUlong; 918 919 switch (msg) { 920 /* the only PUBLIC ioctl */ 921 case B_GET_ACCELERANT_SIGNATURE: 922 { 923 strcpy((char* )buf, sSettings.accelerant); 924 result = B_OK; 925 break; 926 } 927 928 /* PRIVATE ioctl from here on */ 929 case NV_GET_PRIVATE_DATA: 930 { 931 nv_get_private_data *gpd = (nv_get_private_data *)buf; 932 if (gpd->magic == NV_PRIVATE_DATA_MAGIC) { 933 gpd->shared_info_area = di->shared_area; 934 result = B_OK; 935 } 936 break; 937 } 938 939 case NV_GET_PCI: 940 { 941 nv_get_set_pci *gsp = (nv_get_set_pci *)buf; 942 if (gsp->magic == NV_PRIVATE_DATA_MAGIC) { 943 pci_info *pcii = &(di->pcii); 944 gsp->value = get_pci(gsp->offset, gsp->size); 945 result = B_OK; 946 } 947 break; 948 } 949 950 case NV_SET_PCI: 951 { 952 nv_get_set_pci *gsp = (nv_get_set_pci *)buf; 953 if (gsp->magic == NV_PRIVATE_DATA_MAGIC) { 954 pci_info *pcii = &(di->pcii); 955 set_pci(gsp->offset, gsp->size, gsp->value); 956 result = B_OK; 957 } 958 break; 959 } 960 961 case NV_DEVICE_NAME: 962 { 963 nv_device_name *dn = (nv_device_name *)buf; 964 if (dn->magic == NV_PRIVATE_DATA_MAGIC) { 965 strcpy(dn->name, di->name); 966 result = B_OK; 967 } 968 break; 969 } 970 971 case NV_RUN_INTERRUPTS: 972 { 973 nv_set_vblank_int *vi = (nv_set_vblank_int *)buf; 974 if (vi->magic == NV_PRIVATE_DATA_MAGIC) { 975 vuint32 *regs = di->regs; 976 if (!(vi->crtc)) { 977 if (vi->do_it) { 978 enable_vbi_crtc1(regs); 979 } else { 980 disable_vbi_crtc1(regs); 981 } 982 } else { 983 if (vi->do_it) { 984 enable_vbi_crtc2(regs); 985 } else { 986 disable_vbi_crtc2(regs); 987 } 988 } 989 result = B_OK; 990 } 991 break; 992 } 993 994 case NV_ISA_OUT: 995 { 996 nv_in_out_isa *io_isa = (nv_in_out_isa *)buf; 997 if (io_isa->magic == NV_PRIVATE_DATA_MAGIC) { 998 pci_info *pcii = &(di->pcii); 999 1000 /* lock the driver: 1001 * no other graphics card may have ISA I/O enabled when we enter */ 1002 AQUIRE_BEN(pd->kernel); 1003 1004 /* enable ISA I/O access */ 1005 tmpUlong = get_pci(PCI_command, 2); 1006 tmpUlong |= PCI_command_io; 1007 set_pci(PCI_command, 2, tmpUlong); 1008 1009 if (io_isa->size == 1) 1010 isa_bus->write_io_8(io_isa->adress, (uint8)io_isa->data); 1011 else 1012 isa_bus->write_io_16(io_isa->adress, io_isa->data); 1013 result = B_OK; 1014 1015 /* disable ISA I/O access */ 1016 tmpUlong = get_pci(PCI_command, 2); 1017 tmpUlong &= ~PCI_command_io; 1018 set_pci(PCI_command, 2, tmpUlong); 1019 1020 /* end of critical section */ 1021 RELEASE_BEN(pd->kernel); 1022 } 1023 break; 1024 } 1025 1026 case NV_ISA_IN: 1027 { 1028 nv_in_out_isa *io_isa = (nv_in_out_isa *)buf; 1029 if (io_isa->magic == NV_PRIVATE_DATA_MAGIC) { 1030 pci_info *pcii = &(di->pcii); 1031 1032 /* lock the driver: 1033 * no other graphics card may have ISA I/O enabled when we enter */ 1034 AQUIRE_BEN(pd->kernel); 1035 1036 /* enable ISA I/O access */ 1037 tmpUlong = get_pci(PCI_command, 2); 1038 tmpUlong |= PCI_command_io; 1039 set_pci(PCI_command, 2, tmpUlong); 1040 1041 if (io_isa->size == 1) 1042 io_isa->data = isa_bus->read_io_8(io_isa->adress); 1043 else 1044 io_isa->data = isa_bus->read_io_16(io_isa->adress); 1045 result = B_OK; 1046 1047 /* disable ISA I/O access */ 1048 tmpUlong = get_pci(PCI_command, 2); 1049 tmpUlong &= ~PCI_command_io; 1050 set_pci(PCI_command, 2, tmpUlong); 1051 1052 /* end of critical section */ 1053 RELEASE_BEN(pd->kernel); 1054 } 1055 break; 1056 } 1057 } 1058 1059 return result; 1060} 1061 1062 1063// #pragma mark - driver API 1064 1065 1066status_t 1067init_hardware(void) 1068{ 1069 long index = 0; 1070 pci_info pcii; 1071 bool found = false; 1072 1073 /* choke if we can't find the PCI bus */ 1074 if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK) 1075 return B_ERROR; 1076 1077 /* choke if we can't find the ISA bus */ 1078 if (get_module(B_ISA_MODULE_NAME, (module_info **)&isa_bus) != B_OK) 1079 { 1080 put_module(B_PCI_MODULE_NAME); 1081 return B_ERROR; 1082 } 1083 1084 /* while there are more pci devices */ 1085 while ((*pci_bus->get_nth_pci_info)(index, &pcii) == B_NO_ERROR) { 1086 int vendor = 0; 1087 1088 /* if we match a supported vendor */ 1089 while (SupportedDevices[vendor].vendor) { 1090 if (SupportedDevices[vendor].vendor == pcii.vendor_id) { 1091 uint16 *devices = SupportedDevices[vendor].devices; 1092 /* while there are more supported devices */ 1093 while (*devices) { 1094 /* if we match a supported device */ 1095 if (*devices == pcii.device_id ) { 1096 1097 found = true; 1098 goto done; 1099 } 1100 /* next supported device */ 1101 devices++; 1102 } 1103 } 1104 vendor++; 1105 } 1106 /* next pci_info struct, please */ 1107 index++; 1108 } 1109 1110done: 1111 /* put away the module manager */ 1112 put_module(B_PCI_MODULE_NAME); 1113 return found ? B_OK : B_ERROR; 1114} 1115 1116 1117status_t 1118init_driver(void) 1119{ 1120 void *settings; 1121 1122 // get driver/accelerant settings 1123 settings = load_driver_settings(DRIVER_PREFIX ".settings"); 1124 if (settings != NULL) { 1125 const char *item; 1126 char *end; 1127 uint32 value; 1128 1129 // for driver 1130 item = get_driver_parameter(settings, "accelerant", "", ""); 1131 if (item[0] && strlen(item) < sizeof(sSettings.accelerant) - 1) 1132 strcpy (sSettings.accelerant, item); 1133 1134 item = get_driver_parameter(settings, "primary", "", ""); 1135 if (item[0] && strlen(item) < sizeof(sSettings.primary) - 1) 1136 strcpy(sSettings.primary, item); 1137 1138 sSettings.dumprom = get_driver_boolean_parameter(settings, 1139 "dumprom", false, false); 1140 1141 // for accelerant 1142 item = get_driver_parameter(settings, "logmask", 1143 "0x00000000", "0x00000000"); 1144 value = strtoul(item, &end, 0); 1145 if (*end == '\0') 1146 sSettings.logmask = value; 1147 1148 item = get_driver_parameter(settings, "memory", "0", "0"); 1149 value = strtoul(item, &end, 0); 1150 if (*end == '\0') 1151 sSettings.memory = value; 1152 1153 sSettings.hardcursor = get_driver_boolean_parameter(settings, 1154 "hardcursor", false, false); 1155 sSettings.usebios = get_driver_boolean_parameter(settings, 1156 "usebios", false, false); 1157 sSettings.switchhead = get_driver_boolean_parameter(settings, 1158 "switchhead", false, false); 1159 sSettings.pgm_panel = get_driver_boolean_parameter(settings, 1160 "pgm_panel", false, false); 1161 sSettings.force_sync = get_driver_boolean_parameter(settings, 1162 "force_sync", false, false); 1163 sSettings.force_ws = get_driver_boolean_parameter(settings, 1164 "force_ws", false, false); 1165 1166 item = get_driver_parameter(settings, "gpu_clk", "0", "0"); 1167 value = strtoul(item, &end, 0); 1168 if (*end == '\0') 1169 sSettings.gpu_clk = value; 1170 1171 item = get_driver_parameter(settings, "ram_clk", "0", "0"); 1172 value = strtoul(item, &end, 0); 1173 if (*end == '\0') 1174 sSettings.ram_clk = value; 1175 1176 unload_driver_settings(settings); 1177 } 1178 1179 /* get a handle for the pci bus */ 1180 if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK) 1181 return B_ERROR; 1182 1183 /* get a handle for the isa bus */ 1184 if (get_module(B_ISA_MODULE_NAME, (module_info **)&isa_bus) != B_OK) { 1185 put_module(B_PCI_MODULE_NAME); 1186 return B_ERROR; 1187 } 1188 1189 /* driver private data */ 1190 pd = (DeviceData *)calloc(1, sizeof(DeviceData)); 1191 if (!pd) { 1192 put_module(B_PCI_MODULE_NAME); 1193 return B_ERROR; 1194 } 1195 /* initialize the benaphore */ 1196 INIT_BEN(pd->kernel); 1197 /* find all of our supported devices */ 1198 probe_devices(); 1199 return B_OK; 1200} 1201 1202 1203const char ** 1204publish_devices(void) 1205{ 1206 /* return the list of supported devices */ 1207 return (const char **)pd->device_names; 1208} 1209 1210 1211device_hooks * 1212find_device(const char *name) 1213{ 1214 int index = 0; 1215 while (pd->device_names[index]) { 1216 if (strcmp(name, pd->device_names[index]) == 0) 1217 return &graphics_device_hooks; 1218 index++; 1219 } 1220 return NULL; 1221 1222} 1223 1224 1225void 1226uninit_driver(void) 1227{ 1228 /* free the driver data */ 1229 DELETE_BEN(pd->kernel); 1230 free(pd); 1231 pd = NULL; 1232 1233 /* put the pci module away */ 1234 put_module(B_PCI_MODULE_NAME); 1235 put_module(B_ISA_MODULE_NAME); 1236} 1237 1238