wrsm_intr_impl.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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
* 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 2001-2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _WRSM_INTR_IMPL_H
#define _WRSM_INTR_IMPL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/* Setting up recvq overflow */
#define WRSM_CMMU_0_ERROR_BIT 0x2
#define WRSM_CMMU_0_VALID 0x4000000
/*
* Recvq pointers are stored in a 2-level tree, implemented as an array of
* pointers to an array of recvq pointers. The recvq_tables array gives access
* to a table of 256 pointers. Each entry in recvq_tables will remain NULL
* until all the entries in all the existing tables are used, and a new
* table needs to be allocated. Tables will never be deleted to eliminate the
* need to lock a table from a TL1 interrupt. Given a 16-bit mondo vector
* argument, the macro MONDOARG2TABLE generates the index into recvq_tables,
* while the macro MONDOARG2TABLEINDEX generates the index into the selected
* table, which provides the recvq pointer.
*
*
* recvq_tables[256]
* _____________________________..__________
* |0 |1 |2 |3 |4 |5 |6 | |254|255|
* | * |nul|nul|nul|nul|nul|nul| |nul|nul|
* |_|_|___|___|___|___|___|___|_..__|___|___|
* |
* | table[256]
* _V_
* |0 |
* | *-+--> recvq with mondo arg 0
* |___|
* |1 |
* | *-+--> recvq with mondo arg 1
* |___|
* |2 |
* |nul|
* |___|
* | |
* ~ ~
* | |
* |___|
* |255|
* |nul|
* |___|
*
*/
#define WRSM_INTR_RECVQ_TABLE_SIZE 256
#define WRSM_INTR_RECVQ_TABLES 256
#define WRSM_INTR_TABLE_MASK 0xff
#define WRSM_INTR_TABLE_SHIFT 8
#define WRSM_INTR_INDEX_MASK 0xff
#define WRSM_INTR_INDEX_SHIFT 0
/* Values for the PSL when it is empty */
/* Empty, but softint is active */
/* Empty and no softint running; can't cast, as used in wrsm_trap.s */
#define WRSM_INTR_PSL_IDLE 1
#define WRSM_MONDO2TABLE(m) \
(((m) >> WRSM_INTR_TABLE_SHIFT) & WRSM_INTR_TABLE_MASK)
#define WRSM_MONDO2INDEX(m) \
(((m) >> WRSM_INTR_INDEX_SHIFT) & WRSM_INTR_INDEX_MASK)
/* Each table array contains pointers to WRSM_INTR_RECVQ_TABLES tables */
#define WRSM_INTR_RECVQ_TABLES_ARRAY_SIZE \
(WRSM_INTR_RECVQ_TABLES * sizeof (void *))
#define WRSM_INTR_PACKET_SIZE 64
#ifndef _ASM
/*
* Receive Queue structures
*/
typedef struct __rsm_send_q_handle wrsm_sendq_t;
/* Describes an interrupt drainer (software interrupt thread) */
typedef struct wrsm_intr_drainer {
struct wrsm_intr_recvq *drainer_psl;
/* Describes an interrupt target CPU */
typedef struct wrsm_intr_target {
struct wrsm_intr_recvq *recvq_list;
int intr_dist_mondo;
/* An element in a linked-list of intr handlers, part of wrsm_intr_service */
typedef struct wrsm_intr_handler {
struct wrsm_intr_handler *next;
/* Describes an interrupt service, including list of handlers and a recvq */
typedef struct wrsm_intr_service {
struct wrsm_intr_recvq *recvq_list;
/* State of packet ring. Must be 64-bits for casx */
typedef struct {
typedef union {
/* The receive queue structure */
struct wrsm_intr_recvq {
/* Pointers for various linked lists */
struct wrsm_intr_recvq *service_next;
struct wrsm_intr_recvq *target_next;
struct wrsm_intr_recvq *drainer_next;
struct wrsm_intr_recvq *recvq_next;
void *exportseg; /* info for small puts */
/* count of how often high-water mark has been reached */
};
/*
* Used to map a DMV argument (16-bits) to a recvq struct pointer. The
* The wrsm_interrupt_t structure contains an array of 256 pointers to
* recvq_table, which contains 256 recvq pointers. Use the macros
* MONDOARG2TABLE to get the table pointer from the wrsm_interrupt structure,
* the the macro MONDOARG2TABLEINDEX to index into the wrsm_intr_recvq_table
* to select the correct recvq pointer.
*/
/* The sendq structure */
struct __rsm_send_q_handle {
int flags;
};
/*
* Interrupt Structure part of wrsm_network_t
*/
struct wrsm_interrupt {
/*
* The following arrays is used for flow control. If the trap
* handler detects a high water condition on a recvq, it must
* set the user_error flag in that recvq's cmmu for all WCIs
* (actually, it's sufficient to set the cmmu entry to valid
* and user_error). To do that, it must know the address of
* the sram. The array cmmu_paddr contains the physical address
* of the CMMU entry in sram (or NULL) for every WCI in this
* controller.
*/
};
/*
* Local Function Prototypes
*/
static void handler_fini(wrsm_intr_handler_t *);
static void service_fini(wrsm_intr_service_t *);
static void service_list_fini(wrsm_interrupt_t *);
static void target_fini(wrsm_intr_target_t *);
static void target_print(wrsm_intr_target_t *);
static void target_list_init(wrsm_interrupt_t *);
static void target_list_fini(wrsm_interrupt_t *);
static void target_list_print(wrsm_interrupt_t *);
static int drainer_init(wrsm_intr_drainer_t *);
static void drainer_fini(wrsm_intr_drainer_t *);
static void drainer_print(wrsm_intr_drainer_t *);
static int drainer_list_init(wrsm_interrupt_t *);
static void drainer_list_fini(wrsm_interrupt_t *);
static void drainer_list_print(wrsm_interrupt_t *);
static void recvq_callback(wrsm_intr_recvq_t *);
static void recvq_print(wrsm_intr_recvq_t *);
static void recvq_table_init(wrsm_interrupt_t *);
static int recvq_table_alloc_entry(wrsm_interrupt_t *);
static void recvq_table_print(wrsm_interrupt_t *);
extern void wrsm_tl1_handler();
#endif /* _ASM */
#ifdef __cplusplus
}
#endif
#endif /* _WRSM_INTR_IMPL_H */