0001
0002
0003 #include <linux/sched/mm.h>
0004 #include "trace.h"
0005 #include "ocxl_internal.h"
0006
0007 int ocxl_global_mmio_read32(struct ocxl_afu *afu, size_t offset,
0008 enum ocxl_endian endian, u32 *val)
0009 {
0010 if (offset > afu->config.global_mmio_size - 4)
0011 return -EINVAL;
0012
0013 #ifdef __BIG_ENDIAN__
0014 if (endian == OCXL_HOST_ENDIAN)
0015 endian = OCXL_BIG_ENDIAN;
0016 #endif
0017
0018 switch (endian) {
0019 case OCXL_BIG_ENDIAN:
0020 *val = readl_be((char *)afu->global_mmio_ptr + offset);
0021 break;
0022
0023 default:
0024 *val = readl((char *)afu->global_mmio_ptr + offset);
0025 break;
0026 }
0027
0028 return 0;
0029 }
0030 EXPORT_SYMBOL_GPL(ocxl_global_mmio_read32);
0031
0032 int ocxl_global_mmio_read64(struct ocxl_afu *afu, size_t offset,
0033 enum ocxl_endian endian, u64 *val)
0034 {
0035 if (offset > afu->config.global_mmio_size - 8)
0036 return -EINVAL;
0037
0038 #ifdef __BIG_ENDIAN__
0039 if (endian == OCXL_HOST_ENDIAN)
0040 endian = OCXL_BIG_ENDIAN;
0041 #endif
0042
0043 switch (endian) {
0044 case OCXL_BIG_ENDIAN:
0045 *val = readq_be((char *)afu->global_mmio_ptr + offset);
0046 break;
0047
0048 default:
0049 *val = readq((char *)afu->global_mmio_ptr + offset);
0050 break;
0051 }
0052
0053 return 0;
0054 }
0055 EXPORT_SYMBOL_GPL(ocxl_global_mmio_read64);
0056
0057 int ocxl_global_mmio_write32(struct ocxl_afu *afu, size_t offset,
0058 enum ocxl_endian endian, u32 val)
0059 {
0060 if (offset > afu->config.global_mmio_size - 4)
0061 return -EINVAL;
0062
0063 #ifdef __BIG_ENDIAN__
0064 if (endian == OCXL_HOST_ENDIAN)
0065 endian = OCXL_BIG_ENDIAN;
0066 #endif
0067
0068 switch (endian) {
0069 case OCXL_BIG_ENDIAN:
0070 writel_be(val, (char *)afu->global_mmio_ptr + offset);
0071 break;
0072
0073 default:
0074 writel(val, (char *)afu->global_mmio_ptr + offset);
0075 break;
0076 }
0077
0078
0079 return 0;
0080 }
0081 EXPORT_SYMBOL_GPL(ocxl_global_mmio_write32);
0082
0083 int ocxl_global_mmio_write64(struct ocxl_afu *afu, size_t offset,
0084 enum ocxl_endian endian, u64 val)
0085 {
0086 if (offset > afu->config.global_mmio_size - 8)
0087 return -EINVAL;
0088
0089 #ifdef __BIG_ENDIAN__
0090 if (endian == OCXL_HOST_ENDIAN)
0091 endian = OCXL_BIG_ENDIAN;
0092 #endif
0093
0094 switch (endian) {
0095 case OCXL_BIG_ENDIAN:
0096 writeq_be(val, (char *)afu->global_mmio_ptr + offset);
0097 break;
0098
0099 default:
0100 writeq(val, (char *)afu->global_mmio_ptr + offset);
0101 break;
0102 }
0103
0104
0105 return 0;
0106 }
0107 EXPORT_SYMBOL_GPL(ocxl_global_mmio_write64);
0108
0109 int ocxl_global_mmio_set32(struct ocxl_afu *afu, size_t offset,
0110 enum ocxl_endian endian, u32 mask)
0111 {
0112 u32 tmp;
0113
0114 if (offset > afu->config.global_mmio_size - 4)
0115 return -EINVAL;
0116
0117 #ifdef __BIG_ENDIAN__
0118 if (endian == OCXL_HOST_ENDIAN)
0119 endian = OCXL_BIG_ENDIAN;
0120 #endif
0121
0122 switch (endian) {
0123 case OCXL_BIG_ENDIAN:
0124 tmp = readl_be((char *)afu->global_mmio_ptr + offset);
0125 tmp |= mask;
0126 writel_be(tmp, (char *)afu->global_mmio_ptr + offset);
0127 break;
0128
0129 default:
0130 tmp = readl((char *)afu->global_mmio_ptr + offset);
0131 tmp |= mask;
0132 writel(tmp, (char *)afu->global_mmio_ptr + offset);
0133 break;
0134 }
0135
0136 return 0;
0137 }
0138 EXPORT_SYMBOL_GPL(ocxl_global_mmio_set32);
0139
0140 int ocxl_global_mmio_set64(struct ocxl_afu *afu, size_t offset,
0141 enum ocxl_endian endian, u64 mask)
0142 {
0143 u64 tmp;
0144
0145 if (offset > afu->config.global_mmio_size - 8)
0146 return -EINVAL;
0147
0148 #ifdef __BIG_ENDIAN__
0149 if (endian == OCXL_HOST_ENDIAN)
0150 endian = OCXL_BIG_ENDIAN;
0151 #endif
0152
0153 switch (endian) {
0154 case OCXL_BIG_ENDIAN:
0155 tmp = readq_be((char *)afu->global_mmio_ptr + offset);
0156 tmp |= mask;
0157 writeq_be(tmp, (char *)afu->global_mmio_ptr + offset);
0158 break;
0159
0160 default:
0161 tmp = readq((char *)afu->global_mmio_ptr + offset);
0162 tmp |= mask;
0163 writeq(tmp, (char *)afu->global_mmio_ptr + offset);
0164 break;
0165 }
0166
0167 return 0;
0168 }
0169 EXPORT_SYMBOL_GPL(ocxl_global_mmio_set64);
0170
0171 int ocxl_global_mmio_clear32(struct ocxl_afu *afu, size_t offset,
0172 enum ocxl_endian endian, u32 mask)
0173 {
0174 u32 tmp;
0175
0176 if (offset > afu->config.global_mmio_size - 4)
0177 return -EINVAL;
0178
0179 #ifdef __BIG_ENDIAN__
0180 if (endian == OCXL_HOST_ENDIAN)
0181 endian = OCXL_BIG_ENDIAN;
0182 #endif
0183
0184 switch (endian) {
0185 case OCXL_BIG_ENDIAN:
0186 tmp = readl_be((char *)afu->global_mmio_ptr + offset);
0187 tmp &= ~mask;
0188 writel_be(tmp, (char *)afu->global_mmio_ptr + offset);
0189 break;
0190
0191 default:
0192 tmp = readl((char *)afu->global_mmio_ptr + offset);
0193 tmp &= ~mask;
0194 writel(tmp, (char *)afu->global_mmio_ptr + offset);
0195 break;
0196 }
0197
0198
0199 return 0;
0200 }
0201 EXPORT_SYMBOL_GPL(ocxl_global_mmio_clear32);
0202
0203 int ocxl_global_mmio_clear64(struct ocxl_afu *afu, size_t offset,
0204 enum ocxl_endian endian, u64 mask)
0205 {
0206 u64 tmp;
0207
0208 if (offset > afu->config.global_mmio_size - 8)
0209 return -EINVAL;
0210
0211 #ifdef __BIG_ENDIAN__
0212 if (endian == OCXL_HOST_ENDIAN)
0213 endian = OCXL_BIG_ENDIAN;
0214 #endif
0215
0216 switch (endian) {
0217 case OCXL_BIG_ENDIAN:
0218 tmp = readq_be((char *)afu->global_mmio_ptr + offset);
0219 tmp &= ~mask;
0220 writeq_be(tmp, (char *)afu->global_mmio_ptr + offset);
0221 break;
0222
0223 default:
0224 tmp = readq((char *)afu->global_mmio_ptr + offset);
0225 tmp &= ~mask;
0226 writeq(tmp, (char *)afu->global_mmio_ptr + offset);
0227 break;
0228 }
0229
0230 writeq(tmp, (char *)afu->global_mmio_ptr + offset);
0231
0232 return 0;
0233 }
0234 EXPORT_SYMBOL_GPL(ocxl_global_mmio_clear64);