Nouveau源码分析(七)
虽然各个SUBDEV/EGINE的初始化实际还是在nouveau_drm_load里,但还是换个标题吧. 等把各个SUBDEV/ENGINE之类的说完再换回去.
上次已经按着初始化的顺序介绍了一下各个subdev的用途,现在按顺序,首先来看VBIOS的ctor函数:
// /drivers/gpu/drm/nouveau/core/subdev/bios/base.c
537 struct nouveau_oclass
538 nouveau_bios_oclass = {
539 .handle = NV_SUBDEV(VBIOS, 0x00),
540 .ofuncs = &(struct nouveau_ofuncs) {
541 .ctor = nouveau_bios_ctor,
542 .dtor = nouveau_bios_dtor,
543 .init = nouveau_bios_init,
544 .fini = nouveau_bios_fini,
545 .rd08 = nouveau_bios_rd08,
546 .rd16 = nouveau_bios_rd16,
547 .rd32 = nouveau_bios_rd32,
548 .wr08 = nouveau_bios_wr08,
549 .wr16 = nouveau_bios_wr16,
550 .wr32 = nouveau_bios_wr32,
551 },
552 };
// /drivers/gpu/drm/nouveau/core/subdev/bios/base.c
459 static int
460 nouveau_bios_ctor(struct nouveau_object *parent,
461 struct nouveau_object *engine,
462 struct nouveau_oclass *oclass, void *data, u32 size,
463 struct nouveau_object **pobject)
464 {
465 struct nouveau_bios *bios;
466 struct bit_entry bit_i;
467 int ret;
468
469 ret = nouveau_subdev_create(parent, engine, oclass, 0,
470 "VBIOS", "bios", &bios);
471 *pobject = nv_object(bios);
472 if (ret)
473 return ret;
474
475 ret = nouveau_bios_shadow(bios);
476 if (ret)
477 return ret;
478
479 /* detect type of vbios we're dealing with */
480 bios->bmp_offset = nvbios_findstr(bios->data, bios->size,
481 "\xff\x7f""NV\0", 5);
482 if (bios->bmp_offset) {
483 nv_info(bios, "BMP version %x.%x\n",
484 bmp_version(bios) >> 8,
485 bmp_version(bios) & 0xff);
486 }
487
488 bios->bit_offset = nvbios_findstr(bios->data, bios->size,
489 "\xff\xb8""BIT", 5);
490 if (bios->bit_offset)
491 nv_info(bios, "BIT signature found\n");
492
493 /* determine the vbios version number */
494 if (!bit_entry(bios, 'i', &bit_i) && bit_i.length >= 4) {
495 bios->version.major = nv_ro08(bios, bit_i.offset + 3);
496 bios->version.chip = nv_ro08(bios, bit_i.offset + 2);
497 bios->version.minor = nv_ro08(bios, bit_i.offset + 1);
498 bios->version.micro = nv_ro08(bios, bit_i.offset + 0);
499 bios->version.patch = nv_ro08(bios, bit_i.offset + 4);
500 } else
501 if (bmp_version(bios)) {
502 bios->version.major = nv_ro08(bios, bios->bmp_offset + 13);
503 bios->version.chip = nv_ro08(bios, bios->bmp_offset + 12);
504 bios->version.minor = nv_ro08(bios, bios->bmp_offset + 11);
505 bi