.. _peephole: ========================================== PEEPHOLE: indirect memory access from host ========================================== .. contents:: Introduction ============ PEEPHOLE is a mechanism to indirectly access memory form the CPU. It is present on NV30+ cards. On NV30:G80, it accesses physical [unpaged] VRAM. On G80+, it can access either physical VRAM, or virtual [paged] memory via standard VM circuitry. Additionally, on G84+, the PEEPHOLE MMIO registers are stuffed into a dedicated range [0x060000:0x061000], so that the driver can allow userspace programs access to the PEEPHOLE and nothing else. PEEPHOLE is part of PBUS and thus not affected by any PMC.ENABLE bit. The actual memory access is handled by PFIFO on G80+ cards. The PEEPHOLE has two ports: a write-only port and a read-write port. The ports share a common VM context on G80+, but are otherwise independent. The write-only port is only present on NV30:GF100. The addresses used for PEEPHOLE accesses have to be 4-byte aligned, and the window for indirect access is 4 bytes long. The addresses are 29-bit on NV30:G80 [enough to address all of VRAM], 32-bit on G80:GF100, 40-bit on GF100+. For details on setting up the target physical/VM space on G80:GF100, see :ref:`g80-host-mem`; for GF100+ see :ref:`gf100-host-mem`. Note that, on NV30:GF100 cards, the PEEPHOLE is subject to PMC hidden window masking - see :ref:`pmc-vram-hide` for details. .. _peephole-mmio: MMIO registers ============== The following MMIO registers deal with PEEPHOLE: ======== ========== ===================== ==================== Address Present on Name Description ======== ========== ===================== ==================== 0x00155c NV30:GF100 PEEPHOLE_W_CTRL :ref:`write port control ` 0x001560 NV30:G84 PEEPHOLE_W_ADDR :ref:`write port address ` 0x001564 NV30:G84 PEEPHOLE_W_DATA :ref:`write port data ` 0x001570 NV30:G84 PEEPHOLE_RW_ADDR :ref:`read-write port address ` 0x001574 NV30:G84 PEEPHOLE_RW_DATA :ref:`read-write port data ` ======== ========== ===================== ==================== .. space:: 8 peephole 0x1000 indirect VM access .. todo:: convert 0x060000 G84:GF100 PEEPHOLE_W_ADDR :ref:`write port address ` 0x060004 G84:GF100 PEEPHOLE_W_DATA :ref:`write port data ` 0x06000c GF100- PEEPHOLE_RW_ADDR_HIGH :ref:`read-write port address, high part ` 0x060010 G84- PEEPHOLE_RW_ADDR_LOW :ref:`read-write port address, low part ` 0x060014 G84- PEEPHOLE_RW_DATA :ref:`read-write port data ` In addition, PEEPHOLE uses PBUS interrupt #12 for its write port. .. _pbus-intr-peephole-w-pair-mismatch: .. _peephole-mmio-w: Write port ========== Write port is present on NV30:GF100 cards only. The write port consists of an address register, a data register, and a control register. It can operate in two modes: - paired write mode: The address and data registers are supposed to be accessed by two back-to-back writes, in either order. The back-to-back write is supposed to be generated by software doing a 64-bit write on the address covering both of these registers. Writing these registers in any other way, or doing any other MMIO write between the writes, is an error and will cause an interrupt. The memory write will be performed on the second write of the pair. - freeform mode: both registers can be accessed in any manner, any write to the data register will perform a memory write. The mode of operation and current status can be read/written via the PEEPHOLE_W_CTRL register: MMIO 0x00155c: PEEPHOLE_W_CTRL [NV30:GF100] - bit 0: PAIR_ADDR_VALID - 1 when an address write has been performed, and the hw is waiting for a data write - bit 1: PAIR_DATA_VALID - 1 when a data write has been performed, and the hw is waiting for an address write - bit 8: MODE - 0: PAIR - selects paired write mode - 1: FREEFORM - selects freeform mode The address and data registers are: MMIO 0x001560: PEEPHOLE_W_ADDR [NV30:G84] MMIO 0x060000: PEEPHOLE_W_ADDR [G84:GF100] The address register. On NV30:G80, only bits 2-28 are valid. On G80+, only bits 2-31 are valid. MMIO 0x001564: PEEPHOLE_W_DATA [NV30:G84] MMIO 0x060004: PEEPHOLE_W_DATA [G84:GF100] The data register. This register is actually RW, and a read will return the last written value. Writes other than 32-bit are accepted, but will translate to appropriately-sized memory writes *only if the memory write is triggered by the data register write* - if the memory write is triggered by address register write, a 32-bit memory write will be performed instead, with junk in the remaining bytes. PEEPHOLE_W_ADDR write operation:: PEEPHOLE_W_ADDR = value; if (MODE == PAIR) { if (PAIR_ADDR_VALID) { raise_irq(PBUS.INTR.PEEPHOLE_W_PAIR_MISMATCH); } else if (PAIR_DATA_VALID) { peephole_write32(PEEPHOLE_W_ADDR, PEEPHOLE_W_DATA); PAIR_DATA_VALID = 0; } else { PAIR_ADDR_VALID = 1; } } PEEPHOLE_W_DATA write operation:: PEEPHOLE_W_DATA = value; if (MODE == PAIR) { if (PAIR_DATA_VALID) { raise_irq(PBUS.INTR.PEEPHOLE_W_PAIR_MISMATCH); } else if (PAIR_ADDR_VALID) { peephole_write_be(PEEPHOLE_W_ADDR, value, value_be); /* memory write byte enables copied from the MMIO access */ PAIR_ADDR_VALID = 0; } else { PAIR_DATA_VALID = 1; } } else { peephole_write_be(PEEPHOLE_W_ADDR, value, value_be); /* memory write byte enables copied from the MMIO access */ } The PEEPHOLE_W_PAIR_MISMATCH interrupt is reported in :ref:`PBUS.INTR bit 12 `. .. _peephole-mmio-rw: RW port operation ================= The RW port is available on all NV30+ cards. There is an address register and a data register. Accesses to the address register merely read/write that register. All accesses to the data register are translated to equivalent memory accesses at the address selected by the address register, and cause the address register to auto-increment by 4. The translation preserves byte enables, thus it's possible to do accesses smaller than 32 bits [though the address will always autoincrement by 4]. MMIO 0x06000c: PEEPHOLE_RW_ADDR_HIGH [GF100-] The high part of the address register - bits 0-7 are valid and correspond to address bits 32-39. MMIO 0x001570: PEEPHOLE_RW_ADDR [NV30:G84] MMIO 0x060010: PEEPHOLE_RW_ADDR_LOW [G84-] The low part of the address register. On NV30:G80, only bits 2-28 are valid. On G80+, only bits 2-31 are valid. MMIO 0x001574: PEEPHOLE_RW_DATA [NV30:G84] MMIO 0x060014: PEEPHOLE_RW_DATA [G84-] The data port. Any access to this address will be translated to a corresponding memory read/write and cause the address register to be autoincremented by 4. On GF100+, the carry from LOW to HIGH is handled properly.