Nouveau源码分析(六):NVIDIA设备初始化之nouveau_drm_load (3)

本文是Nouveau源码分析系列的第六篇,主要探讨NVIDIA设备的初始化过程,详细解析nouveau_drm_load函数的实现,揭示Linux下NVIDIA驱动的工作原理。
摘要由CSDN通过智能技术生成

Nouveau源码分析(六)

上一篇中我们暂时忽略了两个函数,第一个是用于创建nvif_device对应的nouveau_object的ctor函数:
// /drivers/gpu/drm/nouveau/core/engine/device/base.c
488 static struct nouveau_ofuncs
489 nouveau_devobj_ofuncs = {
490         .ctor = nouveau_devobj_ctor,
491         .dtor = nouveau_devobj_dtor,
492         .init = _nouveau_parent_init,
493         .fini = _nouveau_parent_fini,
494         .mthd = nouveau_devobj_mthd,
495 };
也就是对应的nouveau_devobj_ctor,这个函数的主要功能就是识别NVIDIA设备类型,然后初始化每一个subdev.
// /drivers/gpu/drm/nouveau/core/engine/device/base.c
274 static int
275 nouveau_devobj_ctor(struct nouveau_object *parent,
276                     struct nouveau_object *engine,
277                     struct nouveau_oclass *oclass, void *data, u32 size,
278                     struct nouveau_object **pobject)
279 {
280         union {
281                 struct nv_device_v0 v0;
282         } *args = data;
283         struct nouveau_client *client = nv_client(parent);
284         struct nouveau_device *device;
285         struct nouveau_devobj *devobj;
286         u32 boot0, strap;
287         u64 disable, mmio_base, mmio_size;
288         void __iomem *map;
289         int ret, i, c;
290 
291         nv_ioctl(parent, "create device size %d\n", size);
292         if (nvif_unpack(args->v0, 0, 0, false)) {
293                 nv_ioctl(parent, "create device v%d device %016llx "
294                                  "disable %016llx debug0 %016llx\n",
295                          args->v0.version, args->v0.device,
296                          args->v0.disable, args->v0.debug0);
297         } else
298                 return ret;
299 
300         /* give priviledged clients register access */
301         if (client->super)
302                 oclass = &nouveau_devobj_oclass_super;
303 
304         /* find the device subdev that matches what the client requested */
305         device = nv_device(client->device);
306         if (args->v0.device != ~0) {
307                 device = nouveau_device_find(args->v0.device);
308                 if (!device)
309                         return -ENODEV;
310         }
311 
312         ret = nouveau_parent_create(parent, nv_object(device), oclass, 0,
313                                     nouveau_control_oclass,
314                                     (1ULL << NVDEV_ENGINE_DMAOBJ) |
315                                     (1ULL << NVDEV_ENGINE_FIFO) |
316                                     (1ULL << NVDEV_ENGINE_DISP) |
317                                     (1ULL << NVDEV_ENGINE_PERFMON), &devobj);
318         *pobject = nv_object(devobj);
319         if (ret)
320                 return ret;
321 
322         mmio_base = nv_device_resource_start(device, 0);
323         mmio_size = nv_device_resource_len(device, 0);
324 
325         /* translate api disable mask into internal mapping */
326         disable = args->v0.debug0;
327         for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
328                 if (args->v0.disable & disable_map[i])
329                         disable |= (1ULL << i);
330         }
331 
332         /* identify the chipset, and determine classes of subdev/engines */
333         if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_IDENTIFY) &&
334             !device->card_type) {
335                 map = ioremap(mmio_base, 0x102000);
336                 if (map == NULL)
337                         return -ENOMEM;
338 
339                 /* switch mmio to cpu's native endianness */
340 #ifndef __BIG_ENDIAN
341                 if (ioread32_native(map + 0x000004) != 0x00000000)
342 #else
343                 if (ioread32_native(map + 0x000004) == 0x00000000)
344 #endif
345                         iowrite32_native(0x01000001, map + 0x000004);
346 
347                 /* read boot0 and strapping information */
348                 boot0 = ioread32_native(map + 0x000000);
349                 strap = ioread32_native(map + 0x101000);
350                 iounmap(map);
351 
352                 /* determine chipset and derive architecture from it */
353                 if ((boot0 & 0x1f000000) > 0) {
354                         device->chipset = (boot0 & 0x1ff00000) >> 20;
355                         switch (device->chipset & 0x1f0) {
356                         case 0x010: {
357                                 if (0x461 & (1 << (device->chipset & 0xf)))
358                                         device->card_type = NV_10;
359                                 else
360                                         device->card_type = NV_11;
361                                 break;
362                         }
363                         case 0x020: device->card_type = NV_20; break;
364                         case 0x030: device->card_type = NV_30; break;
365                         case 0x040:
366                         case 0x060: device->card_type = NV_40; break;
367                         case 0x050:
368                         case 0x080:
369                         case 0x090:
370                         case 0x0a0: device->card_type = NV_50; break;
371                         case 0x0c0:
372                         case 0x0d0: device->card_type = NV_C0; break;
373                         case 0x0e0:
374                         case 0x0f0:
375                         case 0x100: device->card_type = NV_E0; break;
376                         case 0x110: device->card_type = GM100; break;
377                         default:
378                                 break;
379              
### 回答1: nouveau 0000:01:00.0 是一种开源 NVIDIA 驱动程序,它通过 Linux 内核中的 DRM 框架与 NVIDIA 显卡进行交互。这个编号表示它正在使用第 1 个 PCI 总线上的第 0 个设备,也就是显卡。 ### 回答2: nouveau 0000:01:00.0 是一个Linux内核中的驱动程序,它用来支持NVIDIA的图形处理器。这个驱动程序是开源的,由社区开发和维护。在Linux系统中,它提供了对NVIDIA显卡的开源支持,使得用户可以在Linux系统中使用NVIDIA显卡进行图形计算、游戏和其他图形相关的任务。 0000:01:00.0 是NVIDIA显卡在计算机系统中的物理地址。在计算机硬件中,每个设备都有一个唯一的物理地址,用来标识它在计算机总线上的位置。0000:01:00.0 表示该显卡位于PCI总线上的第一个插槽,也就是编号为0x01的插槽。 通过nouveau 0000:01:00.0 驱动程序,Linux系统可以与这个NVIDIA显卡进行通信,并运行相关的应用程序。这个驱动程序提供了图形加速、视频解码、显示输出等核心功能,保证了NVIDIA显卡在Linux系统中的正常工作。 nouveau驱动程序是由社区团队开发和维护的,因此它通常与操作系统的发行版本捆绑在一起。用户在安装Linux操作系统后,通常会自动获取、安装和配置nouveau驱动程序。然而,有时用户也可以选择手动下载和安装最新版本的驱动程序,以获取更好的性能和支持。 总之,nouveau 0000:01:00.0 是一个Linux系统中用来支持NVIDIA显卡的开源驱动程序。它提供了对显卡的核心功能支持,使得用户可以在Linux系统中充分利用NVIDIA显卡的图形处理能力。 ### 回答3: nouveau是一个开源的显卡驱动程序,用于支持NVIDIA的显卡。0000:01:00.0则代表着PCI总线上的一个设备地址,用于唯一标识一块显卡。 在计算机中,显卡是用于处理和呈现图形的硬件设备。而NVIDIA是一个著名的显卡制造商,其产品在高性能计算、游戏和数据处理等领域广泛使用。nouveau则是为NVIDIA显卡开发的一个开源驱动程序,它的目的是提供一种免费的、开放源代码的解决方案,取代NVIDIA官方闭源驱动。 而0000:01:00.0这个地址则是唯一标识一块显卡的方式之一,它采用PCI总线的寻址方式。在计算机系统中,每个设备都会有一个唯一的地址,这使得操作系统能够准确地找到设备并与其进行通信。因此,0000:01:00.0可以被看作是一块显卡在计算机中的身份证明。 总而言之,nouveau 0000:01:00.0代表着一块使用开源驱动NVIDIA显卡,在计算机中具有唯一的地址,并且可以通过该地址进行准确的通信和操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值