1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 3219820Sjeff * 4219820Sjeff * This software is available to you under a choice of one of two 5219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 6219820Sjeff * General Public License (GPL) Version 2, available from the file 7219820Sjeff * COPYING in the main directory of this source tree, or the 8219820Sjeff * OpenIB.org BSD license below: 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or 11219820Sjeff * without modification, are permitted provided that the following 12219820Sjeff * conditions are met: 13219820Sjeff * 14219820Sjeff * - Redistributions of source code must retain the above 15219820Sjeff * copyright notice, this list of conditions and the following 16219820Sjeff * disclaimer. 17219820Sjeff * 18219820Sjeff * - Redistributions in binary form must reproduce the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer in the documentation and/or other materials 21219820Sjeff * provided with the distribution. 22219820Sjeff * 23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30219820Sjeff * SOFTWARE. 31219820Sjeff */ 32219820Sjeff 33219820Sjeff#ifndef DOORBELL_H 34219820Sjeff#define DOORBELL_H 35219820Sjeff 36219820Sjeff#ifdef __i386__ 37219820Sjeff 38219820Sjeffstatic inline void mthca_write64(uint32_t val[2], struct mthca_context *ctx, int offset) 39219820Sjeff{ 40219820Sjeff /* i386 stack is aligned to 8 bytes, so this should be OK: */ 41219820Sjeff uint8_t xmmsave[8] __attribute__((aligned(8))); 42219820Sjeff 43219820Sjeff asm volatile ( 44219820Sjeff "movlps %%xmm0,(%0); \n\t" 45219820Sjeff "movlps (%1),%%xmm0; \n\t" 46219820Sjeff "movlps %%xmm0,(%2); \n\t" 47219820Sjeff "movlps (%0),%%xmm0; \n\t" 48219820Sjeff : 49219820Sjeff : "r" (xmmsave), "r" (val), "r" (ctx->uar + offset) 50219820Sjeff : "memory" ); 51219820Sjeff} 52219820Sjeff 53219820Sjeffstatic inline void mthca_write_db_rec(uint32_t val[2], uint32_t *db) 54219820Sjeff{ 55219820Sjeff /* i386 stack is aligned to 8 bytes, so this should be OK: */ 56219820Sjeff uint8_t xmmsave[8] __attribute__((aligned(8))); 57219820Sjeff 58219820Sjeff asm volatile ( 59219820Sjeff "movlps %%xmm0,(%0); \n\t" 60219820Sjeff "movlps (%1),%%xmm0; \n\t" 61219820Sjeff "movlps %%xmm0,(%2); \n\t" 62219820Sjeff "movlps (%0),%%xmm0; \n\t" 63219820Sjeff : 64219820Sjeff : "r" (xmmsave), "r" (val), "r" (db) 65219820Sjeff : "memory" ); 66219820Sjeff} 67219820Sjeff 68219820Sjeff#elif SIZEOF_LONG == 8 69219820Sjeff 70219820Sjeff#if __BYTE_ORDER == __LITTLE_ENDIAN 71219820Sjeff# define MTHCA_PAIR_TO_64(val) ((uint64_t) val[1] << 32 | val[0]) 72219820Sjeff#elif __BYTE_ORDER == __BIG_ENDIAN 73219820Sjeff# define MTHCA_PAIR_TO_64(val) ((uint64_t) val[0] << 32 | val[1]) 74219820Sjeff#else 75219820Sjeff# error __BYTE_ORDER not defined 76219820Sjeff#endif 77219820Sjeff 78219820Sjeffstatic inline void mthca_write64(uint32_t val[2], struct mthca_context *ctx, int offset) 79219820Sjeff{ 80219820Sjeff *(volatile uint64_t *) (ctx->uar + offset) = MTHCA_PAIR_TO_64(val); 81219820Sjeff} 82219820Sjeff 83219820Sjeffstatic inline void mthca_write_db_rec(uint32_t val[2], uint32_t *db) 84219820Sjeff{ 85219820Sjeff *(volatile uint64_t *) db = MTHCA_PAIR_TO_64(val); 86219820Sjeff} 87219820Sjeff 88219820Sjeff#else 89219820Sjeff 90219820Sjeffstatic inline void mthca_write64(uint32_t val[2], struct mthca_context *ctx, int offset) 91219820Sjeff{ 92219820Sjeff pthread_spin_lock(&ctx->uar_lock); 93219820Sjeff *(volatile uint32_t *) (ctx->uar + offset) = val[0]; 94219820Sjeff *(volatile uint32_t *) (ctx->uar + offset + 4) = val[1]; 95219820Sjeff pthread_spin_unlock(&ctx->uar_lock); 96219820Sjeff} 97219820Sjeff 98219820Sjeffstatic inline void mthca_write_db_rec(uint32_t val[2], uint32_t *db) 99219820Sjeff{ 100219820Sjeff *(volatile uint32_t *) db = val[0]; 101219820Sjeff mb(); 102219820Sjeff *(volatile uint32_t *) (db + 1) = val[1]; 103219820Sjeff} 104219820Sjeff 105219820Sjeff#endif 106219820Sjeff 107219820Sjeff#endif /* MTHCA_H */ 108