xref: /illumos-gate/usr/src/uts/intel/io/vmm/amd/amdvi_priv.h (revision 32640292339b07090f10ce34d455f98711077343)
17c8c0b82SPatrick Mooney /*-
2*32640292SAndy Fiddaman  * SPDX-License-Identifier: BSD-2-Clause
37c8c0b82SPatrick Mooney  *
47c8c0b82SPatrick Mooney  * Copyright (c) 2016 Anish Gupta (anish@freebsd.org)
57c8c0b82SPatrick Mooney  * Copyright (c) 2021 The FreeBSD Foundation
67c8c0b82SPatrick Mooney  *
77c8c0b82SPatrick Mooney  * Portions of this software were developed by Ka Ho Ng
87c8c0b82SPatrick Mooney  * under sponsorship from the FreeBSD Foundation.
97c8c0b82SPatrick Mooney  *
107c8c0b82SPatrick Mooney  * Redistribution and use in source and binary forms, with or without
117c8c0b82SPatrick Mooney  * modification, are permitted provided that the following conditions
127c8c0b82SPatrick Mooney  * are met:
137c8c0b82SPatrick Mooney  * 1. Redistributions of source code must retain the above copyright
147c8c0b82SPatrick Mooney  *    notice unmodified, this list of conditions, and the following
157c8c0b82SPatrick Mooney  *    disclaimer.
167c8c0b82SPatrick Mooney  * 2. Redistributions in binary form must reproduce the above copyright
177c8c0b82SPatrick Mooney  *    notice, this list of conditions and the following disclaimer in the
187c8c0b82SPatrick Mooney  *    documentation and/or other materials provided with the distribution.
197c8c0b82SPatrick Mooney  *
207c8c0b82SPatrick Mooney  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
217c8c0b82SPatrick Mooney  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
227c8c0b82SPatrick Mooney  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
237c8c0b82SPatrick Mooney  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
247c8c0b82SPatrick Mooney  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
257c8c0b82SPatrick Mooney  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
267c8c0b82SPatrick Mooney  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
277c8c0b82SPatrick Mooney  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
287c8c0b82SPatrick Mooney  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
297c8c0b82SPatrick Mooney  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
307c8c0b82SPatrick Mooney  */
317c8c0b82SPatrick Mooney 
327c8c0b82SPatrick Mooney #ifndef _AMDVI_PRIV_H_
337c8c0b82SPatrick Mooney #define _AMDVI_PRIV_H_
347c8c0b82SPatrick Mooney 
357c8c0b82SPatrick Mooney #include <contrib/dev/acpica/include/acpi.h>
367c8c0b82SPatrick Mooney 
377c8c0b82SPatrick Mooney #define	BIT(n)			(1ULL << (n))
387c8c0b82SPatrick Mooney /* Return value of bits[n:m] where n and (n >= ) m are bit positions. */
397c8c0b82SPatrick Mooney #define REG_BITS(x, n, m)	(((x) >> (m)) &			\
407c8c0b82SPatrick Mooney 				((1 << (((n) - (m)) + 1)) - 1))
417c8c0b82SPatrick Mooney 
427c8c0b82SPatrick Mooney /*
437c8c0b82SPatrick Mooney  * IOMMU PCI capability.
447c8c0b82SPatrick Mooney  */
457c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_IOTLB	BIT(0)	/* IOTLB is supported. */
467c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_HT	BIT(1)	/* HyperTransport tunnel support. */
477c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_NPCACHE	BIT(2)	/* Not present page cached. */
487c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_EFR	BIT(3)	/* Extended features. */
497c8c0b82SPatrick Mooney #define AMDVI_PCI_CAP_EXT	BIT(4)	/* Miscellaneous information reg. */
507c8c0b82SPatrick Mooney 
517c8c0b82SPatrick Mooney /*
527c8c0b82SPatrick Mooney  * IOMMU extended features.
537c8c0b82SPatrick Mooney  */
547c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_PREFSUP	BIT(0)	/* Prefetch command support. */
557c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_PPRSUP	BIT(1)	/* PPR support */
567c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_XTSUP	BIT(2)	/* Reserved */
577c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_NXSUP	BIT(3)	/* No-execute. */
587c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_GTSUP	BIT(4)	/* Guest translation support. */
597c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_EFRW	BIT(5)	/* Reserved */
607c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_IASUP	BIT(6)	/* Invalidate all command supp. */
617c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_GASUP	BIT(7)	/* Guest APIC or AVIC support. */
627c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_HESUP	BIT(8)	/* Hardware Error. */
637c8c0b82SPatrick Mooney #define AMDVI_EX_FEA_PCSUP	BIT(9)	/* Performance counters support. */
647c8c0b82SPatrick Mooney /* XXX: add more EFER bits. */
657c8c0b82SPatrick Mooney 
667c8c0b82SPatrick Mooney /*
677c8c0b82SPatrick Mooney  * Device table entry or DTE
687c8c0b82SPatrick Mooney  * NOTE: Must be 256-bits/32 bytes aligned.
697c8c0b82SPatrick Mooney  */
707c8c0b82SPatrick Mooney struct amdvi_dte {
717c8c0b82SPatrick Mooney 	uint32_t dt_valid:1;		/* Device Table valid. */
727c8c0b82SPatrick Mooney 	uint32_t pt_valid:1;		/* Page translation valid. */
737c8c0b82SPatrick Mooney 	uint16_t :7;			/* Reserved[8:2] */
747c8c0b82SPatrick Mooney 	uint8_t	 pt_level:3;		/* Paging level, 0 to disable. */
757c8c0b82SPatrick Mooney 	uint64_t pt_base:40;		/* Page table root pointer. */
767c8c0b82SPatrick Mooney 	uint8_t  :3;			/* Reserved[54:52] */
777c8c0b82SPatrick Mooney 	uint8_t	 gv_valid:1;		/* Revision 2, GVA to SPA. */
787c8c0b82SPatrick Mooney 	uint8_t	 gv_level:2;		/* Revision 2, GLX level. */
797c8c0b82SPatrick Mooney 	uint8_t	 gv_cr3_lsb:3;		/* Revision 2, GCR3[14:12] */
807c8c0b82SPatrick Mooney 	uint8_t	 read_allow:1;		/* I/O read enabled. */
817c8c0b82SPatrick Mooney 	uint8_t	 write_allow:1;		/* I/O write enabled. */
827c8c0b82SPatrick Mooney 	uint8_t  :1;			/* Reserved[63] */
837c8c0b82SPatrick Mooney 	uint16_t domain_id:16;		/* Domain ID */
847c8c0b82SPatrick Mooney 	uint16_t gv_cr3_lsb2:16;	/* Revision 2, GCR3[30:15] */
857c8c0b82SPatrick Mooney 	uint8_t	 iotlb_enable:1;	/* Device support IOTLB */
867c8c0b82SPatrick Mooney 	uint8_t	 sup_second_io_fault:1;	/* Suppress subsequent I/O faults. */
877c8c0b82SPatrick Mooney 	uint8_t	 sup_all_io_fault:1;	/* Suppress all I/O page faults. */
887c8c0b82SPatrick Mooney 	uint8_t	 IOctl:2;		/* Port I/O control. */
897c8c0b82SPatrick Mooney 	uint8_t	 iotlb_cache_disable:1;	/* IOTLB cache hints. */
907c8c0b82SPatrick Mooney 	uint8_t	 snoop_disable:1;	/* Snoop disable. */
917c8c0b82SPatrick Mooney 	uint8_t	 allow_ex:1;		/* Allow exclusion. */
927c8c0b82SPatrick Mooney 	uint8_t	 sysmgmt:2;		/* System management message.*/
937c8c0b82SPatrick Mooney 	uint8_t  :1;			/* Reserved[106] */
947c8c0b82SPatrick Mooney 	uint32_t gv_cr3_msb:21;		/* Revision 2, GCR3[51:31] */
957c8c0b82SPatrick Mooney 	uint8_t	 intmap_valid:1;	/* Interrupt map valid. */
967c8c0b82SPatrick Mooney 	uint8_t	 intmap_len:4;		/* Interrupt map table length. */
977c8c0b82SPatrick Mooney 	uint8_t	 intmap_ign:1;		/* Ignore unmapped interrupts. */
987c8c0b82SPatrick Mooney 	uint64_t intmap_base:46;	/* IntMap base. */
997c8c0b82SPatrick Mooney 	uint8_t  :4;			/* Reserved[183:180] */
1007c8c0b82SPatrick Mooney 	uint8_t	 init_pass:1;		/* INIT pass through or PT */
1017c8c0b82SPatrick Mooney 	uint8_t	 extintr_pass:1;	/* External Interrupt PT */
1027c8c0b82SPatrick Mooney 	uint8_t	 nmi_pass:1;		/* NMI PT */
1037c8c0b82SPatrick Mooney 	uint8_t  :1;			/* Reserved[187] */
1047c8c0b82SPatrick Mooney 	uint8_t	 intr_ctrl:2;		/* Interrupt control */
1057c8c0b82SPatrick Mooney 	uint8_t	 lint0_pass:1;		/* LINT0 PT */
1067c8c0b82SPatrick Mooney 	uint8_t	 lint1_pass:1;		/* LINT1 PT */
1077c8c0b82SPatrick Mooney 	uint64_t :64;			/* Reserved[255:192] */
1087c8c0b82SPatrick Mooney } __attribute__((__packed__));
1097c8c0b82SPatrick Mooney CTASSERT(sizeof(struct amdvi_dte) == 32);
1107c8c0b82SPatrick Mooney 
1117c8c0b82SPatrick Mooney /*
1127c8c0b82SPatrick Mooney  * IOMMU command entry.
1137c8c0b82SPatrick Mooney  */
1147c8c0b82SPatrick Mooney struct amdvi_cmd {
1157c8c0b82SPatrick Mooney 	uint32_t	word0;
1167c8c0b82SPatrick Mooney 	uint32_t	word1:28;
1177c8c0b82SPatrick Mooney 	uint8_t		opcode:4;
1187c8c0b82SPatrick Mooney 	uint64_t	addr;
1197c8c0b82SPatrick Mooney } __attribute__((__packed__));
1207c8c0b82SPatrick Mooney 
1217c8c0b82SPatrick Mooney /* Command opcodes. */
1227c8c0b82SPatrick Mooney #define AMDVI_CMP_WAIT_OPCODE	0x1	/* Completion wait. */
1237c8c0b82SPatrick Mooney #define AMDVI_INVD_DTE_OPCODE	0x2	/* Invalidate device table entry. */
1247c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_OPCODE	0x3	/* Invalidate pages. */
1257c8c0b82SPatrick Mooney #define AMDVI_INVD_IOTLB_OPCODE	0x4	/* Invalidate IOTLB pages. */
1267c8c0b82SPatrick Mooney #define AMDVI_INVD_INTR_OPCODE	0x5	/* Invalidate Interrupt table. */
1277c8c0b82SPatrick Mooney #define AMDVI_PREFETCH_PAGES_OPCODE	0x6	/* Prefetch IOMMU pages. */
1287c8c0b82SPatrick Mooney #define AMDVI_COMP_PPR_OPCODE	0x7	/* Complete PPR request. */
1297c8c0b82SPatrick Mooney #define AMDVI_INV_ALL_OPCODE	0x8	/* Invalidate all. */
1307c8c0b82SPatrick Mooney 
1317c8c0b82SPatrick Mooney /* Completion wait attributes. */
1327c8c0b82SPatrick Mooney #define AMDVI_CMP_WAIT_STORE	BIT(0)	/* Write back data. */
1337c8c0b82SPatrick Mooney #define AMDVI_CMP_WAIT_INTR	BIT(1)	/* Completion wait interrupt. */
1347c8c0b82SPatrick Mooney #define AMDVI_CMP_WAIT_FLUSH	BIT(2)	/* Flush queue. */
1357c8c0b82SPatrick Mooney 
1367c8c0b82SPatrick Mooney /* Invalidate page. */
1377c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_S	BIT(0)	/* Invalidation size. */
1387c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_PDE	BIT(1)	/* Invalidate PDE. */
1397c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_GN_GVA	BIT(2)	/* GPA or GVA. */
1407c8c0b82SPatrick Mooney 
1417c8c0b82SPatrick Mooney #define AMDVI_INVD_PAGE_ALL_ADDR	(0x7FFFFFFFFFFFFULL << 12)
1427c8c0b82SPatrick Mooney 
1437c8c0b82SPatrick Mooney /* Invalidate IOTLB. */
1447c8c0b82SPatrick Mooney #define AMDVI_INVD_IOTLB_S	BIT(0)	/* Invalidation size 4k or addr */
1457c8c0b82SPatrick Mooney #define AMDVI_INVD_IOTLB_GN_GVA	BIT(2)	/* GPA or GVA. */
1467c8c0b82SPatrick Mooney 
1477c8c0b82SPatrick Mooney #define AMDVI_INVD_IOTLB_ALL_ADDR	(0x7FFFFFFFFFFFFULL << 12)
1487c8c0b82SPatrick Mooney /* XXX: add more command entries. */
1497c8c0b82SPatrick Mooney 
1507c8c0b82SPatrick Mooney /*
1517c8c0b82SPatrick Mooney  * IOMMU event entry.
1527c8c0b82SPatrick Mooney  */
1537c8c0b82SPatrick Mooney struct amdvi_event {
1547c8c0b82SPatrick Mooney 	uint16_t	devid;
1557c8c0b82SPatrick Mooney 	uint16_t	pasid_hi;
1567c8c0b82SPatrick Mooney 	uint16_t	pasid_domid;	/* PASID low or DomainID */
1577c8c0b82SPatrick Mooney 	uint16_t	flag:12;
1587c8c0b82SPatrick Mooney 	uint8_t		opcode:4;
1597c8c0b82SPatrick Mooney 	uint64_t	addr;
1607c8c0b82SPatrick Mooney } __attribute__((__packed__));
1617c8c0b82SPatrick Mooney CTASSERT(sizeof(struct amdvi_event) == 16);
1627c8c0b82SPatrick Mooney 
1637c8c0b82SPatrick Mooney /* Various event types. */
1647c8c0b82SPatrick Mooney #define AMDVI_EVENT_INVALID_DTE		0x1
1657c8c0b82SPatrick Mooney #define AMDVI_EVENT_PFAULT		0x2
1667c8c0b82SPatrick Mooney #define AMDVI_EVENT_DTE_HW_ERROR	0x3
1677c8c0b82SPatrick Mooney #define AMDVI_EVENT_PAGE_HW_ERROR	0x4
1687c8c0b82SPatrick Mooney #define AMDVI_EVENT_ILLEGAL_CMD		0x5
1697c8c0b82SPatrick Mooney #define AMDVI_EVENT_CMD_HW_ERROR	0x6
1707c8c0b82SPatrick Mooney #define AMDVI_EVENT_IOTLB_TIMEOUT	0x7
1717c8c0b82SPatrick Mooney #define AMDVI_EVENT_INVALID_DTE_REQ	0x8
1727c8c0b82SPatrick Mooney #define AMDVI_EVENT_INVALID_PPR_REQ	0x9
1737c8c0b82SPatrick Mooney #define AMDVI_EVENT_COUNTER_ZERO	0xA
1747c8c0b82SPatrick Mooney 
1757c8c0b82SPatrick Mooney #define AMDVI_EVENT_FLAG_MASK           0x1FF	/* Mask for event flags. */
1767c8c0b82SPatrick Mooney #define AMDVI_EVENT_FLAG_TYPE(x)        (((x) >> 9) & 0x3)
1777c8c0b82SPatrick Mooney 
1787c8c0b82SPatrick Mooney /*
1797c8c0b82SPatrick Mooney  * IOMMU control block.
1807c8c0b82SPatrick Mooney  */
1817c8c0b82SPatrick Mooney struct amdvi_ctrl {
1827c8c0b82SPatrick Mooney 	struct {
1837c8c0b82SPatrick Mooney 		uint16_t size:9;
1847c8c0b82SPatrick Mooney 		uint16_t :3;
1857c8c0b82SPatrick Mooney 		uint64_t base:40;	/* Devtable register base. */
1867c8c0b82SPatrick Mooney 		uint16_t :12;
1877c8c0b82SPatrick Mooney 	} dte;
1887c8c0b82SPatrick Mooney 	struct {
1897c8c0b82SPatrick Mooney 		uint16_t :12;
1907c8c0b82SPatrick Mooney 		uint64_t base:40;
1917c8c0b82SPatrick Mooney 		uint8_t  :4;
1927c8c0b82SPatrick Mooney 		uint8_t	 len:4;
1937c8c0b82SPatrick Mooney 		uint8_t  :4;
1947c8c0b82SPatrick Mooney 	} cmd;
1957c8c0b82SPatrick Mooney 	struct {
1967c8c0b82SPatrick Mooney 		uint16_t :12;
1977c8c0b82SPatrick Mooney 		uint64_t base:40;
1987c8c0b82SPatrick Mooney 		uint8_t  :4;
1997c8c0b82SPatrick Mooney 		uint8_t	 len:4;
2007c8c0b82SPatrick Mooney 		uint8_t  :4;
2017c8c0b82SPatrick Mooney 	} event;
2027c8c0b82SPatrick Mooney 	uint16_t control :13;
2037c8c0b82SPatrick Mooney 	uint64_t	 :51;
2047c8c0b82SPatrick Mooney 	struct {
2057c8c0b82SPatrick Mooney 		uint8_t	 enable:1;
2067c8c0b82SPatrick Mooney 		uint8_t	 allow:1;
2077c8c0b82SPatrick Mooney 		uint16_t :10;
2087c8c0b82SPatrick Mooney 		uint64_t base:40;
2097c8c0b82SPatrick Mooney 		uint16_t :12;
2107c8c0b82SPatrick Mooney 		uint16_t :12;
2117c8c0b82SPatrick Mooney 		uint64_t limit:40;
2127c8c0b82SPatrick Mooney 		uint16_t :12;
2137c8c0b82SPatrick Mooney 	} excl;
2147c8c0b82SPatrick Mooney 	/*
2157c8c0b82SPatrick Mooney 	 * Revision 2 only.
2167c8c0b82SPatrick Mooney 	 */
2177c8c0b82SPatrick Mooney 	uint64_t ex_feature;
2187c8c0b82SPatrick Mooney 	struct {
2197c8c0b82SPatrick Mooney 		uint16_t :12;
2207c8c0b82SPatrick Mooney 		uint64_t base:40;
2217c8c0b82SPatrick Mooney 		uint8_t  :4;
2227c8c0b82SPatrick Mooney 		uint8_t	 len:4;
2237c8c0b82SPatrick Mooney 		uint8_t  :4;
2247c8c0b82SPatrick Mooney 	} ppr;
2257c8c0b82SPatrick Mooney 	uint64_t first_event;
2267c8c0b82SPatrick Mooney 	uint64_t second_event;
2277c8c0b82SPatrick Mooney 	uint64_t event_status;
2287c8c0b82SPatrick Mooney 	/* Revision 2 only, end. */
2297c8c0b82SPatrick Mooney 	uint8_t	 pad1[0x1FA8];		/* Padding. */
2307c8c0b82SPatrick Mooney 	uint32_t cmd_head:19;
2317c8c0b82SPatrick Mooney 	uint64_t :45;
2327c8c0b82SPatrick Mooney 	uint32_t cmd_tail:19;
2337c8c0b82SPatrick Mooney 	uint64_t :45;
2347c8c0b82SPatrick Mooney 	uint32_t evt_head:19;
2357c8c0b82SPatrick Mooney 	uint64_t :45;
2367c8c0b82SPatrick Mooney 	uint32_t evt_tail:19;
2377c8c0b82SPatrick Mooney 	uint64_t :45;
2387c8c0b82SPatrick Mooney 	uint32_t status:19;
2397c8c0b82SPatrick Mooney 	uint64_t :45;
2407c8c0b82SPatrick Mooney 	uint64_t pad2;
2417c8c0b82SPatrick Mooney 	uint8_t  :4;
2427c8c0b82SPatrick Mooney 	uint16_t ppr_head:15;
2437c8c0b82SPatrick Mooney 	uint64_t :45;
2447c8c0b82SPatrick Mooney 	uint8_t  :4;
2457c8c0b82SPatrick Mooney 	uint16_t ppr_tail:15;
2467c8c0b82SPatrick Mooney 	uint64_t :45;
2477c8c0b82SPatrick Mooney 	uint8_t	 pad3[0x1FC0];		/* Padding. */
2487c8c0b82SPatrick Mooney 
2497c8c0b82SPatrick Mooney 	/* XXX: More for rev2. */
2507c8c0b82SPatrick Mooney } __attribute__((__packed__));
2517c8c0b82SPatrick Mooney CTASSERT(offsetof(struct amdvi_ctrl, pad1)== 0x58);
2527c8c0b82SPatrick Mooney CTASSERT(offsetof(struct amdvi_ctrl, pad2)== 0x2028);
2537c8c0b82SPatrick Mooney CTASSERT(offsetof(struct amdvi_ctrl, pad3)== 0x2040);
2547c8c0b82SPatrick Mooney 
2557c8c0b82SPatrick Mooney #define AMDVI_MMIO_V1_SIZE	(4 * PAGE_SIZE)	/* v1 size */
2567c8c0b82SPatrick Mooney /*
2577c8c0b82SPatrick Mooney  * AMF IOMMU v2 size including event counters
2587c8c0b82SPatrick Mooney  */
2597c8c0b82SPatrick Mooney #define AMDVI_MMIO_V2_SIZE	(8 * PAGE_SIZE)
2607c8c0b82SPatrick Mooney 
2617c8c0b82SPatrick Mooney CTASSERT(sizeof(struct amdvi_ctrl) == 0x4000);
2627c8c0b82SPatrick Mooney CTASSERT(sizeof(struct amdvi_ctrl) == AMDVI_MMIO_V1_SIZE);
2637c8c0b82SPatrick Mooney 
2647c8c0b82SPatrick Mooney /* IVHD flag */
2657c8c0b82SPatrick Mooney #define IVHD_FLAG_HTT		BIT(0)	/* Hypertransport Tunnel. */
2667c8c0b82SPatrick Mooney #define IVHD_FLAG_PPW		BIT(1)	/* Pass posted write. */
2677c8c0b82SPatrick Mooney #define IVHD_FLAG_RPPW		BIT(2)	/* Response pass posted write. */
2687c8c0b82SPatrick Mooney #define IVHD_FLAG_ISOC		BIT(3)	/* Isoc support. */
2697c8c0b82SPatrick Mooney #define IVHD_FLAG_IOTLB		BIT(4)	/* IOTLB support. */
2707c8c0b82SPatrick Mooney #define IVHD_FLAG_COH		BIT(5)	/* Coherent control, default 1 */
2717c8c0b82SPatrick Mooney #define IVHD_FLAG_PFS		BIT(6)	/* Prefetch IOMMU pages. */
2727c8c0b82SPatrick Mooney #define IVHD_FLAG_PPRS		BIT(7)	/* Peripheral page support. */
2737c8c0b82SPatrick Mooney 
2747c8c0b82SPatrick Mooney /* IVHD device entry data setting. */
2757c8c0b82SPatrick Mooney #define IVHD_DEV_LINT0_PASS	BIT(6)	/* LINT0 interrupts. */
2767c8c0b82SPatrick Mooney #define IVHD_DEV_LINT1_PASS	BIT(7)	/* LINT1 interrupts. */
2777c8c0b82SPatrick Mooney 
2787c8c0b82SPatrick Mooney /* Bit[5:4] for System Mgmt. Bit3 is reserved. */
2797c8c0b82SPatrick Mooney #define IVHD_DEV_INIT_PASS	BIT(0)	/* INIT */
2807c8c0b82SPatrick Mooney #define IVHD_DEV_EXTINTR_PASS	BIT(1)	/* ExtInt */
2817c8c0b82SPatrick Mooney #define IVHD_DEV_NMI_PASS	BIT(2)	/* NMI */
2827c8c0b82SPatrick Mooney 
2837c8c0b82SPatrick Mooney /* IVHD 8-byte extended data settings. */
2847c8c0b82SPatrick Mooney #define IVHD_DEV_EXT_ATS_DISABLE	BIT(31)	/* Disable ATS */
2857c8c0b82SPatrick Mooney 
2867c8c0b82SPatrick Mooney /* IOMMU control register. */
2877c8c0b82SPatrick Mooney #define AMDVI_CTRL_EN		BIT(0)	/* IOMMU enable. */
2887c8c0b82SPatrick Mooney #define AMDVI_CTRL_HTT		BIT(1)	/* Hypertransport tunnel enable. */
2897c8c0b82SPatrick Mooney #define AMDVI_CTRL_ELOG		BIT(2)	/* Event log enable. */
2907c8c0b82SPatrick Mooney #define AMDVI_CTRL_ELOGINT	BIT(3)	/* Event log interrupt. */
2917c8c0b82SPatrick Mooney #define AMDVI_CTRL_COMINT	BIT(4)	/* Completion wait interrupt. */
2927c8c0b82SPatrick Mooney #define AMDVI_CTRL_PPW		BIT(8)
2937c8c0b82SPatrick Mooney #define AMDVI_CTRL_RPPW		BIT(9)
2947c8c0b82SPatrick Mooney #define AMDVI_CTRL_COH		BIT(10)
2957c8c0b82SPatrick Mooney #define AMDVI_CTRL_ISOC		BIT(11)
2967c8c0b82SPatrick Mooney #define AMDVI_CTRL_CMD		BIT(12)	/* Command buffer enable. */
2977c8c0b82SPatrick Mooney #define AMDVI_CTRL_PPRLOG	BIT(13)
2987c8c0b82SPatrick Mooney #define AMDVI_CTRL_PPRINT	BIT(14)
2997c8c0b82SPatrick Mooney #define AMDVI_CTRL_PPREN	BIT(15)
3007c8c0b82SPatrick Mooney #define AMDVI_CTRL_GTE		BIT(16)	/* Guest translation enable. */
3017c8c0b82SPatrick Mooney #define AMDVI_CTRL_GAE		BIT(17)	/* Guest APIC enable. */
3027c8c0b82SPatrick Mooney 
3037c8c0b82SPatrick Mooney /* Invalidation timeout. */
3047c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_NO_TO	0	/* No timeout. */
3057c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_1ms	1	/* 1 ms */
3067c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_10ms	2	/* 10 ms */
3077c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_100ms	3	/* 100 ms */
3087c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_1S	4	/* 1 second */
3097c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_10S	5	/* 10 second */
3107c8c0b82SPatrick Mooney #define AMDVI_CTRL_INV_TO_100S	6	/* 100 second */
3117c8c0b82SPatrick Mooney 
3127c8c0b82SPatrick Mooney /*
3137c8c0b82SPatrick Mooney  * Max number of PCI devices.
3147c8c0b82SPatrick Mooney  * 256 bus x 32 slot/devices x 8 functions.
3157c8c0b82SPatrick Mooney  */
3167c8c0b82SPatrick Mooney #define PCI_NUM_DEV_MAX		0x10000
3177c8c0b82SPatrick Mooney 
3187c8c0b82SPatrick Mooney /* Maximum number of domains supported by IOMMU. */
3197c8c0b82SPatrick Mooney #define AMDVI_MAX_DOMAIN	(BIT(16) - 1)
3207c8c0b82SPatrick Mooney 
3217c8c0b82SPatrick Mooney /*
3227c8c0b82SPatrick Mooney  * IOMMU Page Table attributes.
3237c8c0b82SPatrick Mooney  */
3247c8c0b82SPatrick Mooney #define AMDVI_PT_PRESENT	BIT(0)
3257c8c0b82SPatrick Mooney #define AMDVI_PT_COHERENT	BIT(60)
3267c8c0b82SPatrick Mooney #define AMDVI_PT_READ		BIT(61)
3277c8c0b82SPatrick Mooney #define AMDVI_PT_WRITE		BIT(62)
3287c8c0b82SPatrick Mooney 
3297c8c0b82SPatrick Mooney #define AMDVI_PT_RW		(AMDVI_PT_READ | AMDVI_PT_WRITE)
3307c8c0b82SPatrick Mooney #define AMDVI_PT_MASK		0xFFFFFFFFFF000UL /* Only [51:12] for PA */
3317c8c0b82SPatrick Mooney 
3327c8c0b82SPatrick Mooney #define AMDVI_PD_LEVEL_SHIFT	9
3337c8c0b82SPatrick Mooney #define AMDVI_PD_SUPER(x)	(((x) >> AMDVI_PD_LEVEL_SHIFT) == 7)
3347c8c0b82SPatrick Mooney /*
3357c8c0b82SPatrick Mooney  * IOMMU Status, offset 0x2020
3367c8c0b82SPatrick Mooney  */
3377c8c0b82SPatrick Mooney #define AMDVI_STATUS_EV_OF		BIT(0)	/* Event overflow. */
3387c8c0b82SPatrick Mooney #define AMDVI_STATUS_EV_INTR		BIT(1)	/* Event interrupt. */
3397c8c0b82SPatrick Mooney /* Completion wait command completed. */
3407c8c0b82SPatrick Mooney #define AMDVI_STATUS_CMP		BIT(2)
3417c8c0b82SPatrick Mooney 
3427c8c0b82SPatrick Mooney #define	IVRS_CTRL_RID			1	/* MMIO RID */
3437c8c0b82SPatrick Mooney 
3447c8c0b82SPatrick Mooney /* ACPI IVHD */
3457c8c0b82SPatrick Mooney struct ivhd_dev_cfg {
3467c8c0b82SPatrick Mooney 	uint32_t start_id;
3477c8c0b82SPatrick Mooney 	uint32_t end_id;
3487c8c0b82SPatrick Mooney 	uint8_t	 data;			/* Device configuration. */
3497c8c0b82SPatrick Mooney 	bool	 enable_ats;		/* ATS enabled for the device. */
3507c8c0b82SPatrick Mooney 	int	 ats_qlen;		/* ATS invalidation queue depth. */
3517c8c0b82SPatrick Mooney };
3527c8c0b82SPatrick Mooney 
3537c8c0b82SPatrick Mooney struct amdvi_domain {
3547c8c0b82SPatrick Mooney 	uint64_t *ptp;			/* Highest level page table */
3557c8c0b82SPatrick Mooney 	int	ptp_level;		/* Level of page tables */
3567c8c0b82SPatrick Mooney 	u_int	id;			/* Domain id */
3577c8c0b82SPatrick Mooney 	SLIST_ENTRY (amdvi_domain) next;
3587c8c0b82SPatrick Mooney };
3597c8c0b82SPatrick Mooney 
3607c8c0b82SPatrick Mooney /*
3617c8c0b82SPatrick Mooney  * Different type of IVHD.
3627c8c0b82SPatrick Mooney  * XXX: Use AcpiIvrsType once new IVHD types are available.
3637c8c0b82SPatrick Mooney */
3647c8c0b82SPatrick Mooney enum IvrsType
3657c8c0b82SPatrick Mooney {
3667c8c0b82SPatrick Mooney 	IVRS_TYPE_HARDWARE_LEGACY = ACPI_IVRS_TYPE_HARDWARE1,
3677c8c0b82SPatrick Mooney 					/* Legacy without EFRi support. */
3687c8c0b82SPatrick Mooney 	IVRS_TYPE_HARDWARE_EFR	  = ACPI_IVRS_TYPE_HARDWARE2,
3697c8c0b82SPatrick Mooney 						/* With EFR support. */
3707c8c0b82SPatrick Mooney 	IVRS_TYPE_HARDWARE_MIXED  = 0x40, /* Mixed with EFR support. */
3717c8c0b82SPatrick Mooney };
3727c8c0b82SPatrick Mooney 
3737c8c0b82SPatrick Mooney /*
3747c8c0b82SPatrick Mooney  * AMD IOMMU softc.
3757c8c0b82SPatrick Mooney  */
3767c8c0b82SPatrick Mooney struct amdvi_softc {
3777c8c0b82SPatrick Mooney 	struct amdvi_ctrl *ctrl;	/* Control area. */
3787c8c0b82SPatrick Mooney 	device_t	dev;		/* IOMMU device. */
3797c8c0b82SPatrick Mooney 	device_t	pci_dev;	/* IOMMU PCI function device. */
3807c8c0b82SPatrick Mooney 	enum IvrsType   ivhd_type;	/* IOMMU IVHD type. */
3817c8c0b82SPatrick Mooney 	bool		iotlb;		/* IOTLB supported by IOMMU */
3827c8c0b82SPatrick Mooney 	struct amdvi_cmd *cmd;		/* Command descriptor area. */
3837c8c0b82SPatrick Mooney 	int		cmd_max;	/* Max number of commands. */
3847c8c0b82SPatrick Mooney 	uint64_t	cmp_data;	/* Command completion write back. */
3857c8c0b82SPatrick Mooney 	struct amdvi_event *event;	/* Event descriptor area. */
3867c8c0b82SPatrick Mooney 	int		event_max;	/* Max number of events. */
3877c8c0b82SPatrick Mooney 	/* ACPI various flags. */
3887c8c0b82SPatrick Mooney 	uint32_t	ivhd_flag;	/* ACPI IVHD flag. */
3897c8c0b82SPatrick Mooney 	uint32_t	ivhd_feature;	/* ACPI v1 Reserved or v2 attribute. */
3907c8c0b82SPatrick Mooney 	uint64_t	ext_feature;	/* IVHD EFR */
3917c8c0b82SPatrick Mooney 	/* PCI related. */
3927c8c0b82SPatrick Mooney 	uint16_t	cap_off;	/* PCI Capability offset. */
3937c8c0b82SPatrick Mooney 	uint8_t		pci_cap;	/* PCI capability. */
3947c8c0b82SPatrick Mooney 	uint16_t	pci_seg;	/* IOMMU PCI domain/segment. */
3957c8c0b82SPatrick Mooney 	uint16_t	pci_rid;	/* PCI BDF of IOMMU */
3967c8c0b82SPatrick Mooney 	/* ACPI device configuration for end points. */
3977c8c0b82SPatrick Mooney 	struct		ivhd_dev_cfg *dev_cfg;
3987c8c0b82SPatrick Mooney 	int		dev_cfg_cnt;
3997c8c0b82SPatrick Mooney 	int		dev_cfg_cap;
4007c8c0b82SPatrick Mooney 
4017c8c0b82SPatrick Mooney 	/* Software statistics. */
4027c8c0b82SPatrick Mooney 	uint64_t	event_intr_cnt;	/* Total event INTR count. */
4037c8c0b82SPatrick Mooney 	uint64_t	total_cmd;	/* Total number of commands. */
4047c8c0b82SPatrick Mooney };
4057c8c0b82SPatrick Mooney 
4067c8c0b82SPatrick Mooney int	amdvi_setup_hw(struct amdvi_softc *softc);
4077c8c0b82SPatrick Mooney int	amdvi_teardown_hw(struct amdvi_softc *softc);
4087c8c0b82SPatrick Mooney #endif /* _AMDVI_PRIV_H_ */
409