-
Notifications
You must be signed in to change notification settings - Fork 102
/
msd_intel_gen.txt
97 lines (76 loc) · 5.58 KB
/
msd_intel_gen.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
sysdrv_bind()
首先拿到i915_gpu_core_protocol_ops
device->magma_driver = MagmaDriver::Create();
msd_driver_create();
MsdIntelDriver::Create().release();
MsdIntelDriver()
magma_start(device.get());
device->magma_driver->CreateDevice(&device->gpu_core_protocol);
msd_driver_create_device(msd_drv_.get(), device);
MsdIntelDevice::Create(device_handle, start_device_thread);
device->Init(device_handle)
BaseInit(device_handle)
MsdIntelPciDevice::CreateShim(device_handle);
MsdIntelPciDeviceShim(zx_intel_gpu_core_protocol_t* intel_gpu_core)
读取pci config里的device id, revision
映射pci设备的mmio
magma::PlatformBusMapper::Create(platform_device_->GetBusTransactionInitiator());
这个好像是映射内存用的?
platform_device_是 MsdIntelPciDeviceShim
QuerySliceInfo(&subslice_total_, &eu_total_);
InterruptManager::CreateShim(this);
PerProcessGtt::InitPrivatePat(register_io_.get());
Gtt::CreateShim(this)
Sequencer(kFirstSequenceNumber)
RenderEngineCommandStreamer::Create(this);
Scheduler::CreateFifoScheduler();
render_engine_cs_->InitContext(global_context_.get())
GetContextSize()
// page size * 20
MsdIntelBuffer::Create(context_size, "context-buffer")
magma::PlatformBuffer::Create(size, name);
创建context buffer
zx::vmo::create(size, 0, &vmo);
Ringbuffer(MsdIntelBuffer::Create(32 * PAGE_SIZE, "ring-buffer")
创建ring buffer
InitContextBuffer(context_buffer.get(), ringbuffer.get(), context->exec_address_space().get()))
platform_buf->MapCpu(&addr)
把vmo映射好,
context buffer的布局在vol6 command stream programming, page 17
第一个4k页是per-process hw status page.
mmio_ = 8192的意思是:用0x02000h作为所有寄存器的base. 这样在指定地址时只需要指定低12位。
register state context存放了一些mmio register的偏移量。
context->SetEngineState(id(), std::move(context_buffer), std::move(ringbuffer));
做PerEngineState放入global_context
global_context_->Map(gtt_, render_engine_cs_->id())
地址空间类型ADDRESS_SPACE_GGTT
把context buffer, ring buffer映射给GGTT
MsdIntelContext::Map(address_space, id)
GetGpuAddress(id, &gpu_addr)
get_context_buffer(id)->platform_buffer()->MapCpu(&cpu_addr)
hardware status page实际上就是context buffer映射的ggtt offset
RenderEngineInit(true)
render_engine_cs_->InitHardware();
把hardware status page的gpu地址写到0x2080 Hardware Status Page Address Register
把sequence number写道hardware status page的offset 0x20处。这个在公开文档里写的是
Ring Head Pointer Storage。代码里注释是superNDA
execlist enable
设置各种寄存器
render_engine_cs_->CreateRenderInitBatch(device_id_);
render_engine_cs_->RenderInit(global_context_, std::move(init_batch), gtt_))
MsdIntelBuffer::Create(init_batch->size(), "render-init-batch"));
新建一个buffer
init_batch->Init(std::move(buffer), address_space);
用这个buffer来创建batch context
这里要把新的地址写到相应的位置reloc
ExecBatch(std::move(mapped_batch));
MoveBatchToInflight(std::move(mapped_batch)
StartBatchBuffer(context.get(), gpu_addr, context->exec_address_space()->type())
SubmitContext(context.get(), inflight_command_sequences_.back().ringbuffer_offset());
UpdateContext(context, tail)
tail是在ring buffer内部的tail offset
gpuaddr是ring buffer在gtt里的偏移量
SubmitExeclists(context);
device->StartDeviceThread();
std::thread([this] { this->DeviceThreadLoop(); });
线程循环处理请求队列