diff options
Diffstat (limited to 'usr/src/uts/sun4u/sys/sysiosbus.h')
| -rw-r--r-- | usr/src/uts/sun4u/sys/sysiosbus.h | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/usr/src/uts/sun4u/sys/sysiosbus.h b/usr/src/uts/sun4u/sys/sysiosbus.h new file mode 100644 index 0000000000..d72c1c0aa3 --- /dev/null +++ b/usr/src/uts/sun4u/sys/sysiosbus.h @@ -0,0 +1,421 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_SYSIOSBUS_H +#define _SYS_SYSIOSBUS_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifndef _ASM +#include <sys/avintr.h> +#include <sys/vmem.h> +#include <sys/ontrap.h> +#include <sys/machsystm.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Things for debugging */ +#ifdef SYSIO_MEM_DEBUG +#define IO_MEMUSAGE +#endif /* SYSIO_MEM_DEBUG */ + +/* + * sysio sbus constant definitions. + */ +#define NATURAL_REG_SIZE 0x8 /* 8 Bytes is Fusion reg size */ +#define MIN_REG_SIZE 0x4 /* Smallest Fusion reg size */ +#define OFF_SYSIO_CTRL_REG 0x10 +#define SYSIO_CTRL_REG_SIZE (NATURAL_REG_SIZE) +#define OFF_SBUS_CTRL_REG 0x2000 +#define SBUS_CTRL_REG_SIZE (NATURAL_REG_SIZE) +#define OFF_SBUS_SLOT_CONFIG 0x2020 +#define SBUS_SLOT_CONFIG_SIZE (NATURAL_REG_SIZE * 7) +#define OFF_INTR_MAPPING_REG 0x2c00 +/* #define INTR_MAPPING_REG_SIZE (NATURAL_REG_SIZE * 16 * 8) */ +#define INTR_MAPPING_REG_SIZE 0x490 +#define OFF_CLR_INTR_REG 0x3408 +/* #define CLR_INTR_REG_SIZE (NATURAL_REG_SIZE * 16 * 8) */ +#define CLR_INTR_REG_SIZE 0x488 +#define OFF_INTR_RETRY_REG 0x2c20 +#define INTR_RETRY_REG_SIZE (MIN_REG_SIZE) +#define OFF_SBUS_INTR_STATE_REG 0x4800 +#define SBUS_INTR_STATE_REG_SIZE (NATURAL_REG_SIZE * 2) +#define SYSIO_IGN 46 +#define SBUS_ARBIT_ALL 0x3full +#define SYSIO_VER_SHIFT 56 + +/* Error registers */ +#define OFF_SYSIO_ECC_REGS 0x20 +#define SYSIO_ECC_REGS_SIZE NATURAL_REG_SIZE +#define OFF_SYSIO_UE_REGS 0x30 +#define SYSIO_UE_REGS_SIZE (NATURAL_REG_SIZE * 2) +#define OFF_SYSIO_CE_REGS 0x40 +#define SYSIO_CE_REGS_SIZE (NATURAL_REG_SIZE * 2) +#define OFF_SBUS_ERR_REGS 0x2010 +#define SBUS_ERR_REGS_SIZE (NATURAL_REG_SIZE * 2) + +/* Interrupts */ +#define INTERRUPT_CPU_FIELD 26 /* Bit shift for mondo TID field */ +#define INTERRUPT_GROUP_NUMBER 6 /* Bit shift for mondo IGN field */ +#define INTERRUPT_VALID 0x80000000ull /* Mondo valid bit */ +#define SBUS_INTR_IDLE 0ull +#define INT_PENDING 3 /* state of the interrupt dispatch */ +/* + * Fix these (RAZ) + * Interrupt Mapping Register defines + */ +#define IMR_VALID 0x80000000ull /* Valid bit */ +#define IMR_TID 0x7C000000ull /* TID bits */ +#define IMR_IGN 0x000007C0ull /* IGN bits */ +#define IMR_INO 0x0000003Full /* INO bits */ +#define IMR_TID_SHIFT 26 /* Bit shift for TID field */ +#define IMR_IGN_SHIFT 6 /* Bit shift for IGN field */ + +#define MAX_SBUS (30) +#define MAX_SBUS_LEVEL (7) +#define MAX_SBUS_SLOTS (7) /* 4 external slots + 3 internal */ +#define EXT_SBUS_SLOTS 4 /* Number of external sbus slots */ +#define MAX_SBUS_SLOT_ADDR 0x10 /* Max slot address on SYSIO */ +#define SYSIO_BURST_RANGE (0x7f) /* 32 bit: 64 Byte to 1 Byte burst */ +#define SYSIO64_BURST_RANGE (0x78) /* 64 bit: 64 Byte to 8 Byte burst */ +#define SYSIO_BURST_MASK 0xffff +#define SYSIO64_BURST_MASK 0xffff0000 +#define SYSIO64_BURST_SHIFT 16 +#define MAX_PIL 16 + +/* Slot config register defines */ +#define SBUS_ETM 0x4000ull +#define SYSIO_SLAVEBURST_MASK 0x1e /* Mask for hardware register */ +#define SYSIO_SLAVEBURST_RANGE (0x78) /* 32 bit: 64 Byte to 8 Byte burst */ +#define SYSIO64_SLAVEBURST_RANGE (0x78) /* 64 bit: 64 Byte to 8 Byte burst */ +#define SYSIO_SLAVEBURST_REGSHIFT 2 /* Convert bit positions 2**8 to 2**1 */ + +/* + * Offsets of sysio, sbus, registers + */ +/* Slot configuration register mapping offsets */ +#define SBUS_SLOT0_CONFIG 0x0 +#define SBUS_SLOT1_CONFIG 0x1 +#define SBUS_SLOT2_CONFIG 0x2 +#define SBUS_SLOT3_CONFIG 0x3 +#define SBUS_SLOT4_CONFIG 0x4 +#define SBUS_SLOT5_CONFIG 0x5 +#define SBUS_SLOT6_CONFIG 0x6 + +/* Interrupt mapping register mapping offsets */ +#define SBUS_SLOT0_MAPREG 0x0 +#define SBUS_SLOT1_MAPREG 0x1 +#define SBUS_SLOT2_MAPREG 0x2 +#define SBUS_SLOT3_MAPREG 0x3 +#define ESP_MAPREG 0x80 +#define ETHER_MAPREG 0x81 +#define PP_MAPREG 0x82 +#define AUDIO_MAPREG 0x83 +#define KBDMOUSE_MAPREG 0x85 +#define FLOPPY_MAPREG 0x86 +#define THERMAL_MAPREG 0x87 +#define TIMER0_MAPREG 0x8C +#define TIMER1_MAPREG 0x8D +#define UE_ECC_MAPREG 0x8E +#define CE_ECC_MAPREG 0x8F +#define SBUS_ERR_MAPREG 0x90 +#define PM_WAKEUP_MAPREG 0x91 +#define FFB_MAPPING_REG 0x92 +#define EXP_MAPPING_REG 0x93 + +/* Interrupt clear register mapping offsets */ +#define SBUS_SLOT0_L1_CLEAR 0x0 +#define SBUS_SLOT0_L2_CLEAR 0x1 +#define SBUS_SLOT0_L3_CLEAR 0x2 +#define SBUS_SLOT0_L4_CLEAR 0x3 +#define SBUS_SLOT0_L5_CLEAR 0x4 +#define SBUS_SLOT0_L6_CLEAR 0x5 +#define SBUS_SLOT0_L7_CLEAR 0x6 +#define SBUS_SLOT1_L1_CLEAR 0x8 +#define SBUS_SLOT1_L2_CLEAR 0x9 +#define SBUS_SLOT1_L3_CLEAR 0xa +#define SBUS_SLOT1_L4_CLEAR 0xb +#define SBUS_SLOT1_L5_CLEAR 0xc +#define SBUS_SLOT1_L6_CLEAR 0xd +#define SBUS_SLOT1_L7_CLEAR 0xe +#define SBUS_SLOT2_L1_CLEAR 0x10 +#define SBUS_SLOT2_L2_CLEAR 0x11 +#define SBUS_SLOT2_L3_CLEAR 0x12 +#define SBUS_SLOT2_L4_CLEAR 0x13 +#define SBUS_SLOT2_L5_CLEAR 0x14 +#define SBUS_SLOT2_L6_CLEAR 0x15 +#define SBUS_SLOT2_L7_CLEAR 0x16 +#define SBUS_SLOT3_L1_CLEAR 0x18 +#define SBUS_SLOT3_L2_CLEAR 0x19 +#define SBUS_SLOT3_L3_CLEAR 0x1a +#define SBUS_SLOT3_L4_CLEAR 0x1b +#define SBUS_SLOT3_L5_CLEAR 0x1c +#define SBUS_SLOT3_L6_CLEAR 0x1d +#define SBUS_SLOT3_L7_CLEAR 0x1e +#define ESP_CLEAR 0x7f +#define ETHER_CLEAR 0x80 +#define PP_CLEAR 0x81 +#define AUDIO_CLEAR 0x82 +#define KBDMOUSE_CLEAR 0x84 +#define FLOPPY_CLEAR 0x85 +#define THERMAL_CLEAR 0x86 +#define TIMER0_CLEAR 0x8B +#define TIMER1_CLEAR 0x8C +#define UE_ECC_CLEAR 0x8D +#define CE_ECC_CLEAR 0x8E +#define SBUS_ERR_CLEAR 0x8F +#define PM_WAKEUP_CLEAR 0x90 + +/* + * Bit shift for accessing the keyboard mouse interrupt state reg. + * note - The external devices are the only other devices where + * we need to check the interrupt state before adding or removing + * interrupts. There is an algorithm to calculate their bit shift. + */ +#define ESP_INTR_STATE_SHIFT 0 +#define ETHER_INTR_STATE_SHIFT 2 +#define PP_INTR_STATE_SHIFT 4 +#define AUDIO_INTR_STATE_SHIFT 6 +#define KBDMOUSE_INTR_STATE_SHIFT 10 +#define FLOPPY_INTR_STATE_SHIFT 12 +#define THERMAL_INTR_STATE_SHIFT 14 +#define TIMER0_INTR_STATE_SHIFT 22 +#define TIMER1_INTR_STATE_SHIFT 24 +#define UE_INTR_STATE_SHIFT 26 +#define CE_INTR_STATE_SHIFT 28 +#define SERR_INTR_STATE_SHIFT 30 +#define PM_INTR_STATE_SHIFT 32 + +#define MAX_INO_TABLE_SIZE 58 /* Max num of sbus devices on sysio */ +#define MAX_MONDO_EXTERNAL 0x1f +#define SBUS_MAX_INO 0x3f +#define THERMAL_MONDO 0x2a +#define UE_ECC_MONDO 0x34 +#define CE_ECC_MONDO 0x35 +#define SBUS_ERR_MONDO 0x36 + +/* used for the picN kstats */ +#define SBUS_NUM_PICS 2 +#define SBUS_NUM_EVENTS 14 +#define SBUS_PIC0_MASK 0x00000000FFFFFFFFULL /* pic0 bits of %pic */ + +/* Offsets for Performance registers */ +#define OFF_SBUS_PCR 0x100 +#define OFF_SBUS_PIC 0x108 + +/* + * used to build array of event-names and pcr-mask values + */ +typedef struct sbus_event_mask { + char *event_name; + uint64_t pcr_mask; +} sbus_event_mask_t; + +/* + * This type is used to describe addresses that we expect a device + * to place on a bus i.e. addresses from the iommu address space. + */ +typedef uint32_t ioaddr_t; + + +/* + * sysio sbus soft state data structure. + * We use the sbus_ctrl_reg to flush hardware store buffers because + * there is very little hardware contention on this register. + */ +struct sbus_soft_state { + dev_info_t *dip; /* dev info of myself */ + int upa_id; /* UPA ID of this SYSIO */ + + /* + * device node address property: + */ + caddr_t address; + + /* + * access handles in case we need to map the registers ourself: + */ + ddi_acc_handle_t ac; + + volatile uint64_t *iommu_flush_reg; /* IOMMU regs */ + volatile uint64_t *iommu_ctrl_reg; + volatile uint64_t *tsb_base_addr; /* Hardware reg for phys TSB base */ + volatile uint64_t *soft_tsb_base_addr; /* virtual address of TSB base */ + volatile uint64_t *iommu_tlb_tag; + volatile uint64_t *iommu_tlb_data; + + size_t iommu_dvma_size; + ioaddr_t iommu_dvma_base; + uint16_t iommu_tsb_cookie; + + + volatile uint64_t *sysio_ctrl_reg; /* sysio regs */ + volatile uint64_t *sbus_ctrl_reg; /* also used to flush store bufs */ + volatile uint64_t *sbus_slot_config_reg; + uint_t sbus_slave_burstsizes[MAX_SBUS_SLOTS]; + + volatile uint64_t *intr_mapping_reg; /* Interrupt regs */ + volatile uint64_t *clr_intr_reg; + volatile uint64_t *intr_retry_reg; + volatile uint64_t *sbus_intr_state; + volatile uint64_t *obio_intr_state; + int8_t intr_hndlr_cnt[MAX_SBUS_SLOT_ADDR]; /* intmapreg cntr by slot */ + uchar_t spurious_cntrs[MAX_PIL + 1]; /* Spurious intr counter */ + + volatile uint64_t *sysio_ecc_reg; /* sysio ecc control reg */ + volatile uint64_t *sysio_ue_reg; /* sysio ue ecc error regs */ + volatile uint64_t *sysio_ce_reg; /* sysio ce ecc error regs */ + volatile uint64_t *sbus_err_reg; /* sbus async error regs */ + + volatile uint64_t *str_buf_ctrl_reg; /* streaming buffer regs */ + volatile uint64_t *str_buf_flush_reg; + volatile uint64_t *str_buf_sync_reg; + volatile uint64_t *str_buf_pg_tag_diag; + kmutex_t sync_reg_lock; /* lock around sync flush reg */ + int stream_buf_off; + + uint_t sbus_burst_sizes; + uint_t sbus64_burst_sizes; + + vmem_t *dvma_arena; /* DVMA arena for this IOMMU */ + uintptr_t dvma_call_list_id; /* DVMA callback list */ + kmutex_t dma_pool_lock; + caddr_t dmaimplbase; /* dma_pool_lock protects this */ + int dma_reserve; /* Size reserved for fast DVMA */ + + struct sbus_wrapper_arg *intr_list[MAX_INO_TABLE_SIZE]; + kmutex_t intr_poll_list_lock; /* to add/rem to intr poll list */ + kmutex_t pokefault_mutex; /* mutex for pokefaults */ + on_trap_data_t *ontrap_data; /* Data used to handle poke faults */ + hrtime_t bto_timestamp; /* time of first timeout */ + int bto_ctr; /* counter for timeouts thereafter */ + pfn_t sbus_io_lo_pfn; + pfn_t sbus_io_hi_pfn; + struct iophyslist *sbus_io_ranges; + int intr_mapping_ign; /* placeholder for the IGN */ +#ifdef _STARFIRE + caddr_t ittrans_cookie; /* starfire intr target translation */ +#endif /* _STARFIRE */ +#ifdef DEBUG + kmutex_t iomemlock; /* Memory usage lock (debug only) */ + struct io_mem_list *iomem; /* Memory usage list (debug only) */ +#endif /* DEBUG */ + /* + * Performance registers and kstat. + */ + volatile uint64_t *sbus_pcr; /* perf counter control */ + volatile uint64_t *sbus_pic; /* perf counter register */ + kstat_t *sbus_counters_ksp; /* perf counter kstat */ +}; + + +/* + * Ugly interrupt cruft due to sysio inconsistencies. + */ +struct sbus_slot_entry { + uint64_t slot_config; + uint64_t mapping_reg; + uint64_t clear_reg; + int diagreg_shift; +}; + +struct sbus_intr_handler { + dev_info_t *dip; + uint32_t inum; + uint_t (*funcp)(); + caddr_t arg1; + caddr_t arg2; + uint_t intr_state; + struct sbus_intr_handler *next; +}; + +/* sbus Interrupt routine wrapper structure */ +struct sbus_wrapper_arg { + struct sbus_soft_state *softsp; + volatile uint64_t *clear_reg; + uint32_t pil; + struct sbus_intr_handler *handler_list; +}; + + +/* + * SYSIO parent private data structure contains register, interrupt, property + * and range information. + * Note: the only thing different from the "generic" sbus parent private + * data is the interrupt specification. + */ +struct sysio_parent_private_data { + int par_nreg; /* number of regs */ + struct regspec *par_reg; /* array of regs */ + int par_nintr; /* number of interrupts */ + struct sysiointrspec *par_intr; /* array of possible interrupts */ + int par_nrng; /* number of ranges */ + struct rangespec *par_rng; /* array of ranges */ + uint_t slot; /* Slot number, on this sbus */ + uint_t offset; /* Offset of first real "reg" */ +}; +#define SYSIO_PD(d) \ + ((struct sysio_parent_private_data *)DEVI((d))->devi_parent_data) + +#define sysio_pd_getnreg(dev) (SYSIO_PD(dev)->par_nreg) +#define sysio_pd_getnintr(dev) (SYSIO_PD(dev)->par_nintr) +#define sysio_pd_getnrng(dev) (SYSIO_PD(dev)->par_nrng) +#define sysio_pd_getslot(dev) (SYSIO_PD(dev)->slot) +#define sysio_pd_getoffset(dev) (SYSIO_PD(dev)->offset) + +#define sysio_pd_getreg(dev, n) (&SYSIO_PD(dev)->par_reg[(n)]) +#define sysio_pd_getintr(dev, n) (&SYSIO_PD(dev)->par_intr[(n)]) +#define sysio_pd_getrng(dev, n) (&SYSIO_PD(dev)->par_rng[(n)]) + +#define IS_INTRA_SBUS(softsp, pfn) (pfn >= softsp->sbus_io_lo_pfn && \ + pfn <= softsp->sbus_io_hi_pfn) + +/* Used for legacy interrupts */ +#define SBUS_INTR_STATE_DISABLE 0 /* disabled */ +#define SBUS_INTR_STATE_ENABLE 1 /* enabled */ + +struct io_mem_list { + dev_info_t *rdip; + ulong_t ioaddr; + ulong_t addr; + pgcnt_t npages; + pfn_t *pfn; + struct io_mem_list *next; +}; + +/* + * Function prototypes. + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_SYSIOSBUS_H */ |
