static status_t MapDevice(DeviceInfo& di) { SharedInfo& si = *(di.sharedInfo); pci_info& pciInfo = di.pciInfo; // Enable memory mapped IO and bus master. SetPCI(pciInfo, PCI_command, 2, GetPCI(pciInfo, PCI_command, 2) | PCI_command_io | PCI_command_memory | PCI_command_master); // Map the video memory. phys_addr_t videoRamAddr = pciInfo.u.h0.base_registers[0]; uint32 videoRamSize = pciInfo.u.h0.base_register_sizes[0]; si.videoMemPCI = videoRamAddr; char frameBufferAreaName[] = "ATI frame buffer"; si.videoMemArea = map_physical_memory( frameBufferAreaName, videoRamAddr, videoRamSize, B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC, B_READ_AREA + B_WRITE_AREA, (void**)&(si.videoMemAddr)); if (si.videoMemArea < 0) { // Try to map this time without write combining. si.videoMemArea = map_physical_memory( frameBufferAreaName, videoRamAddr, videoRamSize, B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA + B_WRITE_AREA, (void**)&(si.videoMemAddr)); } if (si.videoMemArea < 0) return si.videoMemArea; // Map the MMIO register area. phys_addr_t regsBase = pciInfo.u.h0.base_registers[2]; uint32 regAreaSize = pciInfo.u.h0.base_register_sizes[2]; // If the register area address or size is not in the PCI info, it should // be at the end of the video memory. Check if it is there. if (MACH64_FAMILY(si.chipType) && (regsBase == 0 || regAreaSize == 0)) { uint32 regsOffset = 0x7ff000; // offset to regs area in video memory uint32 regs = uint32(si.videoMemAddr) + regsOffset; uint32 chipInfo = *((vuint32*)(regs + M64_CONFIG_CHIP_ID)); if (si.deviceID != (chipInfo & M64_CFG_CHIP_TYPE)) { // Register area not found; delete any other areas that were // created. delete_area(si.videoMemArea); si.videoMemArea = -1; TRACE("Mach64 register area not found\n"); return B_ERROR; } // Adjust params for creating register area below. regsBase = videoRamAddr + regsOffset; regAreaSize = 0x1000; TRACE("Register address is at end of frame buffer memory at 0x%lx\n", uint32(regsBase)); } si.regsArea = map_physical_memory("ATI mmio registers", regsBase, regAreaSize, B_ANY_KERNEL_ADDRESS, 0, // neither read nor write, to hide it from user space apps (void**)&di.regs); // If there was an error, delete other areas. if (si.regsArea < 0) { delete_area(si.videoMemArea); si.videoMemArea = -1; } return si.regsArea; }
static status_t MapDevice(DeviceInfo& di) { char areaName[B_OS_NAME_LENGTH]; SharedInfo& si = *(di.sharedInfo); pci_info& pciInfo = di.pciInfo; TRACE("enter MapDevice()\n"); // Enable memory mapped IO and bus master. SetPCI(pciInfo, PCI_command, 2, GetPCI(pciInfo, PCI_command, 2) | PCI_command_io | PCI_command_memory | PCI_command_master); const uint32 SavageMmioRegBaseOld = 0x1000000; // 16 MB const uint32 SavageMmioRegBaseNew = 0x0000000; const uint32 SavageMmioRegSize = 0x0080000; // 512 KB reg area size const uint32 VirgeMmioRegBase = 0x1000000; // 16 MB const uint32 VirgeMmioRegSize = 0x10000; // 64 KB reg area size uint32 videoRamAddr = 0; uint32 videoRamSize = 0; uint32 regsBase = 0; uint32 regAreaSize = 0; // Since we do not know at this point the actual size of the video // memory, set it to the largest value that the respective chipset // family can have. if (S3_SAVAGE_FAMILY(di.pChipInfo->chipType)) { if (S3_SAVAGE_3D_SERIES(di.pChipInfo->chipType)) { // Savage 3D & Savage MX chips. regsBase = pciInfo.u.h0.base_registers[0] + SavageMmioRegBaseOld; regAreaSize = SavageMmioRegSize; videoRamAddr = pciInfo.u.h0.base_registers[0]; videoRamSize = 16 * 1024 * 1024; // 16 MB is max for 3D series si.videoMemPCI = (void *)(pciInfo.u.h0.base_registers_pci[0]); } else { // All other Savage chips. regsBase = pciInfo.u.h0.base_registers[0] + SavageMmioRegBaseNew; regAreaSize = SavageMmioRegSize; videoRamAddr = pciInfo.u.h0.base_registers[1]; videoRamSize = pciInfo.u.h0.base_register_sizes[1]; si.videoMemPCI = (void *)(pciInfo.u.h0.base_registers_pci[1]); } } else { // Trio/Virge chips. regsBase = pciInfo.u.h0.base_registers[0] + VirgeMmioRegBase; regAreaSize = VirgeMmioRegSize; videoRamAddr = pciInfo.u.h0.base_registers[0]; videoRamSize = 8 * 1024 * 1024; // 8 MB is max for Trio/Virge chips si.videoMemPCI = (void *)(pciInfo.u.h0.base_registers_pci[0]); } // Map the MMIO register area. sprintf(areaName, DEVICE_FORMAT " regs", pciInfo.vendor_id, pciInfo.device_id, pciInfo.bus, pciInfo.device, pciInfo.function); si.regsArea = map_physical_memory(areaName, regsBase, regAreaSize, B_ANY_KERNEL_ADDRESS, 0, // neither read nor write, to hide it from user space apps (void**)(&(di.regs))); if (si.regsArea < 0) return si.regsArea; // return error code // Map the video memory. sprintf(areaName, DEVICE_FORMAT " framebuffer", pciInfo.vendor_id, pciInfo.device_id, pciInfo.bus, pciInfo.device, pciInfo.function); si.videoMemArea = map_physical_memory( areaName, videoRamAddr, videoRamSize, B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC, B_READ_AREA + B_WRITE_AREA, &(si.videoMemAddr)); if (si.videoMemArea < 0) { // Try to map this time without write combining. si.videoMemArea = map_physical_memory( areaName, videoRamAddr, videoRamSize, B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA + B_WRITE_AREA, &(si.videoMemAddr)); } TRACE("Video memory, area: %ld, addr: 0x%lX\n", si.videoMemArea, (uint32)(si.videoMemAddr)); // If there was an error, delete other areas. if (si.videoMemArea < 0) { delete_area(si.regsArea); si.regsArea = -1; } TRACE("leave MapDevice(); result: %ld\n", si.videoMemArea); return si.videoMemArea; }