intel/tools: Factor out GGTT allocation.
We want to reuse it in execlists_setup(). v2: Rename it to write_ggtt_ptes() (Lionel). v3: Rename it to aub_map_ggtt() (Lionel). Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
This commit is contained in:
parent
a9687c4e05
commit
9968316ed0
|
@ -393,6 +393,69 @@ static const struct engine {
|
|||
},
|
||||
};
|
||||
|
||||
static void
|
||||
aub_map_ggtt(struct aub_file *aub, uint64_t virt_addr, uint64_t size)
|
||||
{
|
||||
/* Makes the code below a bit simpler. In practice all of the write we
|
||||
* receive from error2aub are page aligned.
|
||||
*/
|
||||
assert(virt_addr % 4096 == 0);
|
||||
assert((aub->phys_addrs_allocator + size) < (1UL << 32));
|
||||
|
||||
/* GGTT PT */
|
||||
uint32_t ggtt_ptes = DIV_ROUND_UP(size, 4096);
|
||||
uint64_t phys_addr = aub->phys_addrs_allocator << 12;
|
||||
aub->phys_addrs_allocator += ggtt_ptes;
|
||||
|
||||
if (aub->verbose_log_file) {
|
||||
fprintf(aub->verbose_log_file,
|
||||
" Mapping GGTT address: 0x%" PRIx64 ", size: %" PRIu64" phys_addr=0x%" PRIx64 " entries=%u\n",
|
||||
virt_addr, size, phys_addr, ggtt_ptes);
|
||||
}
|
||||
|
||||
mem_trace_memory_write_header_out(aub,
|
||||
(virt_addr >> 12) * GEN8_PTE_SIZE,
|
||||
ggtt_ptes * GEN8_PTE_SIZE,
|
||||
AUB_MEM_TRACE_MEMORY_ADDRESS_SPACE_GGTT_ENTRY,
|
||||
"GGTT PT");
|
||||
for (uint32_t i = 0; i < ggtt_ptes; i++) {
|
||||
dword_out(aub, 1 + phys_addr + i * 4096);
|
||||
dword_out(aub, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aub_write_ggtt(struct aub_file *aub, uint64_t virt_addr, uint64_t size, const void *data)
|
||||
{
|
||||
/* Default setup assumes a 1 to 1 mapping between physical and virtual GGTT
|
||||
* addresses. This is somewhat incompatible with the aub_write_ggtt()
|
||||
* function. In practice it doesn't matter as the GGTT writes are used to
|
||||
* replace the default setup and we've taken care to setup the PML4 as the
|
||||
* top of the GGTT.
|
||||
*/
|
||||
assert(!aub->has_default_setup);
|
||||
|
||||
aub_map_ggtt(aub, virt_addr, size);
|
||||
|
||||
/* We write the GGTT buffer through the GGTT aub command rather than the
|
||||
* PHYSICAL aub command. This is because the Gen9 simulator seems to have 2
|
||||
* different set of memory pools for GGTT and physical (probably someone
|
||||
* didn't really understand the concept?).
|
||||
*/
|
||||
static const char null_block[8 * 4096];
|
||||
for (uint64_t offset = 0; offset < size; offset += 4096) {
|
||||
uint32_t block_size = min(4096, size - offset);
|
||||
|
||||
mem_trace_memory_write_header_out(aub, virt_addr + offset, block_size,
|
||||
AUB_MEM_TRACE_MEMORY_ADDRESS_SPACE_GGTT,
|
||||
"GGTT buffer");
|
||||
data_out(aub, (char *) data + offset, block_size);
|
||||
|
||||
/* Pad to a multiple of 4 bytes. */
|
||||
data_out(aub, null_block, -block_size & 3);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct engine *
|
||||
engine_from_engine_class(enum drm_i915_gem_engine_class engine_class)
|
||||
{
|
||||
|
@ -547,69 +610,6 @@ aub_write_default_setup(struct aub_file *aub)
|
|||
aub->has_default_setup = true;
|
||||
}
|
||||
|
||||
void
|
||||
aub_write_ggtt(struct aub_file *aub, uint64_t virt_addr, uint64_t size, const void *data)
|
||||
{
|
||||
if (aub->verbose_log_file) {
|
||||
fprintf(aub->verbose_log_file,
|
||||
" Writting GGTT address: 0x%" PRIx64 ", size: %" PRIu64"\n",
|
||||
virt_addr, size);
|
||||
}
|
||||
|
||||
/* Default setup assumes a 1 to 1 mapping between physical and virtual GGTT
|
||||
* addresses. This is somewhat incompatible with the aub_write_ggtt()
|
||||
* function. In practice it doesn't matter as the GGTT writes are used to
|
||||
* replace the default setup and we've taken care to setup the PML4 as the
|
||||
* top of the GGTT.
|
||||
*/
|
||||
assert(!aub->has_default_setup);
|
||||
|
||||
/* Makes the code below a bit simpler. In practice all of the write we
|
||||
* receive from error2aub are page aligned.
|
||||
*/
|
||||
assert(virt_addr % 4096 == 0);
|
||||
assert((aub->phys_addrs_allocator + size) < (1UL << 32));
|
||||
|
||||
/* GGTT PT */
|
||||
uint32_t ggtt_ptes = DIV_ROUND_UP(size, 4096);
|
||||
uint64_t phys_addr = aub->phys_addrs_allocator << 12;
|
||||
aub->phys_addrs_allocator += ggtt_ptes;
|
||||
|
||||
if (aub->verbose_log_file) {
|
||||
fprintf(aub->verbose_log_file,
|
||||
" Writting GGTT address: 0x%" PRIx64 ", size: %" PRIu64" phys_addr=0x%" PRIx64 " entries=%u\n",
|
||||
virt_addr, size, phys_addr, ggtt_ptes);
|
||||
}
|
||||
|
||||
mem_trace_memory_write_header_out(aub,
|
||||
(virt_addr >> 12) * GEN8_PTE_SIZE,
|
||||
ggtt_ptes * GEN8_PTE_SIZE,
|
||||
AUB_MEM_TRACE_MEMORY_ADDRESS_SPACE_GGTT_ENTRY,
|
||||
"GGTT PT");
|
||||
for (uint32_t i = 0; i < ggtt_ptes; i++) {
|
||||
dword_out(aub, 1 + phys_addr + i * 4096);
|
||||
dword_out(aub, 0);
|
||||
}
|
||||
|
||||
/* We write the GGTT buffer through the GGTT aub command rather than the
|
||||
* PHYSICAL aub command. This is because the Gen9 simulator seems to have 2
|
||||
* different set of memory pools for GGTT and physical (probably someone
|
||||
* didn't really understand the concept?).
|
||||
*/
|
||||
static const char null_block[8 * 4096];
|
||||
for (uint64_t offset = 0; offset < size; offset += 4096) {
|
||||
uint32_t block_size = min(4096, size - offset);
|
||||
|
||||
mem_trace_memory_write_header_out(aub, virt_addr + offset, block_size,
|
||||
AUB_MEM_TRACE_MEMORY_ADDRESS_SPACE_GGTT,
|
||||
"GGTT buffer");
|
||||
data_out(aub, (char *) data + offset, block_size);
|
||||
|
||||
/* Pad to a multiple of 4 bytes. */
|
||||
data_out(aub, null_block, -block_size & 3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Break up large objects into multiple writes. Otherwise a 128kb VBO
|
||||
* would overflow the 16 bits of size field in the packet header and
|
||||
|
|
Loading…
Reference in New Issue