summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64/dev/iommuvar.h
diff options
context:
space:
mode:
authorHenric Jungheim <henric@cvs.openbsd.org>2003-03-06 08:26:09 +0000
committerHenric Jungheim <henric@cvs.openbsd.org>2003-03-06 08:26:09 +0000
commitefca87016057d41201643e65d1f1c5d44716db0b (patch)
tree0a757cfc249bf077773a2182e04fd490183c3e6c /sys/arch/sparc64/dev/iommuvar.h
parent6216a22d89b680747bfb42b651aed1076b9dbf92 (diff)
The existing IOMMU code had a rounding problem that was most noticeable
on faster systems under heavy network load. This replaces some of the unreadable iommu functions with something a little less dense and a lot less crash prone. The bus_dma function pointer/cookie handling was broken. Change them to work like the stacked bus_space drivers (where "work" is the key word). Tested my many (thanks). ok jason@ deraadt@
Diffstat (limited to 'sys/arch/sparc64/dev/iommuvar.h')
-rw-r--r--sys/arch/sparc64/dev/iommuvar.h68
1 files changed, 60 insertions, 8 deletions
diff --git a/sys/arch/sparc64/dev/iommuvar.h b/sys/arch/sparc64/dev/iommuvar.h
index 6dfccb6dea0..f2726150aa0 100644
--- a/sys/arch/sparc64/dev/iommuvar.h
+++ b/sys/arch/sparc64/dev/iommuvar.h
@@ -1,7 +1,8 @@
-/* $OpenBSD: iommuvar.h,v 1.7 2003/02/17 01:29:20 henric Exp $ */
+/* $OpenBSD: iommuvar.h,v 1.8 2003/03/06 08:26:08 henric Exp $ */
/* $NetBSD: iommuvar.h,v 1.9 2001/10/07 20:30:41 eeh Exp $ */
/*
+ * Copyright (c) 2003 Henric Jungheim
* Copyright (c) 1999 Matthew R. Green
* All rights reserved.
*
@@ -32,18 +33,66 @@
#ifndef _SPARC64_DEV_IOMMUVAR_H_
#define _SPARC64_DEV_IOMMUVAR_H_
+#ifndef _SYS_TREE_H_
+#include <sys/tree.h>
+#endif
+
/*
* per-Streaming Buffer state
*/
-
struct strbuf_ctl {
bus_space_tag_t sb_bustag; /* streaming buffer registers */
bus_space_handle_t sb_sb; /* Handle for our regs */
+ struct iommu_state *sb_iommu; /* Associated IOMMU */
+ /*
+ * Since implementing the per-map IOMMU state, these per-STC
+ * flush areas are not used other than as a boolean flag to indicate
+ * the presence of a working and enabled STC. For inconsistency's
+ * sake, the "sb" pointers of iommu_state are sometimes used for the
+ * same purpose. This should be consolidated.
+ */
paddr_t sb_flushpa; /* to flush streaming buffers */
volatile int64_t *sb_flush;
};
/*
+ * per-map STC flush area
+ */
+struct strbuf_flush {
+ char sbf_area[0x80]; /* Holds 64-byte long/aligned buffer */
+ void *sbf_flush; /* Kernel virtual address of buffer */
+ paddr_t sbf_flushpa; /* Physical address of buffer area */
+};
+
+/*
+ * per-map DVMA page table
+ */
+struct iommu_page_entry {
+ SPLAY_ENTRY(iommu_page_entry) ipe_node;
+ paddr_t ipe_pa;
+ vaddr_t ipe_va;
+};
+struct iommu_page_map {
+ SPLAY_HEAD(iommu_page_tree, iommu_page_entry) ipm_tree;
+ int ipm_maxpage; /* Size of allocated page map */
+ int ipm_pagecnt; /* Number of entries in use */
+ struct iommu_page_entry ipm_map[1];
+};
+
+/*
+ * per-map IOMMU state
+ *
+ * This is what bus_dvmamap_t'c _dm_cookie should be pointing to.
+ */
+struct iommu_map_state {
+ struct strbuf_flush ims_flush; /* flush should be first (alignment) */
+ struct strbuf_ctl *ims_sb; /* Link to parent */
+ int ims_flags;
+ struct iommu_page_map ims_map; /* map must be last (array at end) */
+};
+#define IOMMU_MAP_STREAM 1
+
+/*
* per-IOMMU state
*/
struct iommu_state {
@@ -52,7 +101,7 @@ struct iommu_state {
int is_tsbsize; /* 0 = 8K, ... */
u_int is_dvmabase;
u_int is_dvmaend;
- int64_t is_cr; /* IOMMU control register value */
+ int64_t is_cr; /* Control register value */
struct extent *is_dvmamap; /* DVMA map for this instance */
struct strbuf_ctl *is_sb[2]; /* Streaming buffers if any */
@@ -65,18 +114,21 @@ struct iommu_state {
/* interfaces for PCI/SBUS code */
void iommu_init(char *, struct iommu_state *, int, u_int32_t);
void iommu_reset(struct iommu_state *);
-void iommu_enter(struct iommu_state *, vaddr_t, int64_t, int);
-void iommu_remove(struct iommu_state *, vaddr_t, size_t);
paddr_t iommu_extract(struct iommu_state *, vaddr_t);
-
+int64_t iommu_lookup_tte(struct iommu_state *, vaddr_t);
+int64_t iommu_fetch_tte(struct iommu_state *, paddr_t);
+int iommu_dvmamap_create(bus_dma_tag_t, struct iommu_state *,
+ struct strbuf_ctl *, bus_size_t, int, bus_size_t, bus_size_t,
+ int, bus_dmamap_t *);
+void iommu_dvmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
int iommu_dvmamap_load(bus_dma_tag_t, struct iommu_state *,
bus_dmamap_t, void *, bus_size_t, struct proc *, int);
void iommu_dvmamap_unload(bus_dma_tag_t, struct iommu_state *,
bus_dmamap_t);
int iommu_dvmamap_load_raw(bus_dma_tag_t, struct iommu_state *,
bus_dmamap_t, bus_dma_segment_t *, int, int, bus_size_t);
-void iommu_dvmamap_sync(bus_dma_tag_t, struct iommu_state *,
- bus_dmamap_t, bus_addr_t, bus_size_t, int);
+void iommu_dvmamap_sync(bus_dma_tag_t, struct iommu_state *, bus_dmamap_t,
+ bus_addr_t, bus_size_t, int);
int iommu_dvmamem_alloc(bus_dma_tag_t, struct iommu_state *,
bus_size_t, bus_size_t, bus_size_t, bus_dma_segment_t *,
int, int *, int);