blob: 48c84dab7d050aa7d968e32c3f80ece81eed9b5e [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef INSTRUCTIONS_H
#define INSTRUCTIONS_H
#include <lib/magma/util/short_macros.h>
#include <lib/magma/util/utils.h>
#include <lib/magma_service/util/instruction_writer.h>
#include <stdint.h>
#include "types.h"
// from intel-gfx-prm-osrc-bdw-vol02a-commandreference-instructions_2.pdf pp.870
class MiNoop {
public:
static constexpr uint32_t kDwordCount = 1;
static constexpr uint32_t kCommandType = 0;
static void write(magma::InstructionWriter* writer) { writer->Write32(kCommandType); }
};
// from intel-gfx-prm-osrc-bdw-vol02a-commandreference-instructions_2.pdf pp.793
class MiBatchBufferStart {
public:
static constexpr uint32_t kDwordCount = 3;
static constexpr uint32_t kCommandType = 0x31 << 23;
static constexpr uint32_t kAddressSpacePpgtt = 1 << 8;
static void write(magma::InstructionWriter* writer, gpu_addr_t gpu_addr,
AddressSpaceType address_space_type) {
writer->Write32(kCommandType | (kDwordCount - 2) |
(address_space_type == ADDRESS_SPACE_PPGTT ? kAddressSpacePpgtt : 0));
writer->Write32(magma::lower_32_bits(gpu_addr));
writer->Write32(magma::upper_32_bits(gpu_addr));
}
};
// from intel-gfx-prm-osrc-skl-vol02a-commandreference-instructions.pdf p.906
class MiBatchBufferEnd {
public:
static constexpr uint32_t kDwordCount = 1;
static constexpr uint32_t kCommandType = 0xA << 23;
static void write(magma::InstructionWriter* writer) { writer->Write32(kCommandType); }
};
// from intel-gfx-prm-osrc-bdw-vol02a-commandreference-instructions_2.pdf pp.940
// https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-tgl-vol02a-commandreference-instructions_0.pdf
// p.1002
class MiLoadDataImmediate {
public:
static constexpr uint32_t kCommandType = 0x22 << 23;
static constexpr uint32_t kForcePosted = 1 << 12;
static constexpr uint32_t kAddMmioBase = 1 << 19;
static uint32_t dword_count(uint32_t register_count) { return 2 * register_count + 1; }
static uint32_t header(uint32_t register_count, bool force_posted) {
uint32_t header = kCommandType | (dword_count(register_count) - 2);
if (force_posted)
header |= kForcePosted;
return header;
}
static void write(magma::InstructionWriter* writer, uint32_t register_offset,
uint32_t register_count, uint32_t dword[]) {
DASSERT((register_offset & 0x3) == 0);
writer->Write32(header(register_count, /*force_posted=*/false));
for (uint32_t i = 0; i < register_count; i++) {
writer->Write32(register_offset + i * sizeof(uint32_t));
writer->Write32(dword[i]);
}
}
static void write(magma::InstructionWriter* writer, uint32_t count, uint32_t offset[],
uint32_t value[]) {
writer->Write32(kCommandType | dword_count(count) - 2);
for (uint32_t i = 0; i < count; i++) {
DASSERT((offset[i] & 0x3) == 0);
writer->Write32(offset[i]);
writer->Write32(value[i]);
}
}
};
// intel-gfx-prm-osrc-kbl-vol02a-commandreference-instructions.pdf p.996
// "HW implicitly detects the Data size to be Qword or Dword to be
// written to memory based on the command dword length programmed"
// Note: TLB invalidations are implicit on every flush sync since Skylake
// (GFX_MODE bit 13 "Flush TLB invalidation Mode", from Broadwell spec, removed).
// This is also validated empirically (test_hw_exec.cc)
class MiFlush {
public:
static constexpr uint32_t kDwordCount = 5;
static constexpr uint32_t kCommandType = 0 << 29;
static constexpr uint32_t kCommandOpcode = 0x26 << 23;
static constexpr uint32_t kPostSyncWriteImmediateBit = 1 << 14;
static constexpr uint32_t kAddressSpaceGlobalGttBit = 1 << 2;
static void write(magma::InstructionWriter* writer, uint32_t sequence_number,
AddressSpaceType address_space_type, uint64_t gpu_addr) {
DASSERT((gpu_addr & 0x7) == 0);
DASSERT((gpu_addr & (1 << 5)) == 0); // HW bug
writer->Write32(kCommandType | kCommandOpcode | kPostSyncWriteImmediateBit | (kDwordCount - 2));
writer->Write32(magma::lower_32_bits(gpu_addr) |
(address_space_type == ADDRESS_SPACE_GGTT ? kAddressSpaceGlobalGttBit : 0));
writer->Write32(magma::upper_32_bits(gpu_addr));
writer->Write32(sequence_number);
writer->Write32(0);
}
};
// intel-gfx-prm-osrc-skl-vol02a-commandreference-instructions.pdf pp.1057
// Note: TLB invalidations are implicit on every flush sync since Skylake
// (GFX_MODE bit 13 "Flush TLB invalidation Mode", from Broadwell spec, removed).
// This is also validated empirically (test_hw_exec.cc)
class MiPipeControl {
public:
static constexpr uint32_t kDwordCount = 6;
static constexpr uint32_t kCommandType = 0x3 << 29;
static constexpr uint32_t kCommandSubType = 0x3 << 27;
static constexpr uint32_t k3dCommandOpcode = 0x2 << 24;
static constexpr uint32_t k3dCommandSubOpcode = 0 << 16;
static constexpr uint32_t kDcFlushEnableBit = 1 << 5;
static constexpr uint32_t kIndirectStatePointersDisableBit = 1 << 9;
static constexpr uint32_t kPostSyncWriteImmediateBit = 1 << 14;
static constexpr uint32_t kGenericMediaStateClearBit = 1 << 16;
static constexpr uint32_t kCommandStreamerStallEnableBit = 1 << 20;
static constexpr uint32_t kAddressSpaceGlobalGttBit = 1 << 24;
static constexpr uint32_t kAddressSpaceGen9ClearEuBit = 1 << 27;
static void write(magma::InstructionWriter* writer, uint32_t sequence_number, uint64_t gpu_addr,
uint32_t flags) {
DASSERT((flags &
~(kCommandStreamerStallEnableBit | kIndirectStatePointersDisableBit |
kGenericMediaStateClearBit | kDcFlushEnableBit | kAddressSpaceGen9ClearEuBit)) == 0);
writer->Write32(kCommandType | kCommandSubType | k3dCommandOpcode | k3dCommandSubOpcode |
(kDwordCount - 2));
writer->Write32(flags | kPostSyncWriteImmediateBit | kAddressSpaceGlobalGttBit);
writer->Write32(magma::lower_32_bits(gpu_addr));
writer->Write32(magma::upper_32_bits(gpu_addr));
writer->Write32(sequence_number);
writer->Write32(0);
}
};
// intel-gfx-prm-osrc-skl-vol02a-commandreference-instructions.pdf pp.1010
class MiUserInterrupt {
public:
static constexpr uint32_t kDwordCount = 1;
static constexpr uint32_t kCommandType = 0x2 << 23;
static void write(magma::InstructionWriter* writer) { writer->Write32(kCommandType); }
};
#endif // INSTRUCTIONS_H