diff options
author | Henric Jungheim <henric@cvs.openbsd.org> | 2003-03-06 08:26:09 +0000 |
---|---|---|
committer | Henric Jungheim <henric@cvs.openbsd.org> | 2003-03-06 08:26:09 +0000 |
commit | efca87016057d41201643e65d1f1c5d44716db0b (patch) | |
tree | 0a757cfc249bf077773a2182e04fd490183c3e6c /sys/arch/sparc64/dev/iommuvar.h | |
parent | 6216a22d89b680747bfb42b651aed1076b9dbf92 (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.h | 68 |
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); |