Changeset 3751
- Timestamp:
- 12/28/07 21:50:54 (5 years ago)
- File:
-
- 1 edited
-
trunk/src/host/qemu-neo1973/hw/ar6000.c (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/host/qemu-neo1973/hw/ar6000.c
r3745 r3751 27 27 #include "hw.h" 28 28 #include "net.h" 29 #include "qemu-timer.h" 29 30 #include "sd.h" 30 31 #include "pcmcia.h" … … 945 946 struct sdio_s sd; 946 947 NICInfo *nd; 948 947 949 struct { 948 950 uint8_t host_int_stat; … … 957 959 uint8_t err_int_stat_ena; 958 960 uint8_t cnt_int_stat_ena; 959 uint8_t cnt[ 8];960 uint32_t cnt_ dec[8];961 uint8_t cnt[4]; 962 uint32_t cnt_tx[4]; 961 963 uint8_t scratch[8]; 964 uint8_t wlan_int; 962 965 963 966 uint8_t mbox[0x800 * 4]; … … 967 970 int done; 968 971 } bmi; 972 973 QEMUTimer *cnt_irq_update; 974 969 975 uint8_t cis[0]; 970 976 }; 971 977 978 static inline void ar6k_hif_intr_update(struct ar6k_s *s) 979 { 980 qemu_set_irq(s->sd.func_irq[0], 981 !!(s->hif.host_int_stat & s->hif.int_stat_ena)); 982 } 983 984 static void ar6k_hif_error_intr_update(struct ar6k_s *s) 985 { 986 uint8_t orig = s->hif.host_int_stat; 987 988 if (s->hif.error_int_stat & s->hif.err_int_stat_ena) 989 s->hif.host_int_stat |= 1 << 7; /* STATUS_ERROR */ 990 else 991 s->hif.host_int_stat &= ~(1 << 7); /* STATUS_ERROR */ 992 993 if (orig != s->hif.host_int_stat) 994 ar6k_hif_intr_update(s); 995 } 996 997 static void ar6k_hif_cpu_intr_update(struct ar6k_s *s) 998 { 999 uint8_t orig = s->hif.host_int_stat; 1000 1001 if (s->hif.cpu_int_stat & s->hif.cpu_int_stat_ena) 1002 s->hif.host_int_stat |= 1 << 6; /* STATUS_CPU */ 1003 else 1004 s->hif.host_int_stat &= ~(1 << 6); /* STATUS_CPU */ 1005 1006 if (orig != s->hif.host_int_stat) 1007 ar6k_hif_intr_update(s); 1008 } 1009 1010 static void ar6k_hif_counter_intr_update(struct ar6k_s *s) 1011 { 1012 uint8_t orig = s->hif.host_int_stat; 1013 1014 if (s->hif.counter_int_stat & s->hif.cnt_int_stat_ena) 1015 s->hif.host_int_stat |= 1 << 4; /* STATUS_COUNTER */ 1016 else 1017 s->hif.host_int_stat &= ~(1 << 4); /* STATUS_COUNTER */ 1018 1019 if (orig != s->hif.host_int_stat) 1020 ar6k_hif_intr_update(s); 1021 } 1022 1023 static void ar6k_hif_counter_intr_sched(struct ar6k_s *s) 1024 { 1025 qemu_mod_timer(s->cnt_irq_update, qemu_get_clock(vm_clock) + 1026 (ticks_per_sec >> 6)); 1027 } 1028 1029 static void ar6k_hif_cnt_irq_tick(void *opaque) 1030 { 1031 struct ar6k_s *s = (void *) opaque; 1032 1033 ar6k_hif_counter_intr_update(s); 1034 } 1035 972 1036 static void ar6k_bmi_reset(struct ar6k_s *s) 973 1037 { 974 1038 int i; 975 1039 976 for (i = 0; i < 8; i ++) {1040 for (i = 0; i < 4; i ++) { 977 1041 s->hif.cnt[i] = 0x00; 978 s->hif.cnt_dec[i] = 0xff; 979 } 980 981 for (i = 0; i < 4; i ++) 1042 s->hif.cnt_tx[i] = 0xff; 982 1043 s->hif.mbox_count[i] = 0; 1044 } 983 1045 984 1046 s->bmi.done = 0; 1047 1048 s->hif.host_int_stat = 0x00; 1049 s->hif.cpu_int_stat = 0x00; 1050 s->hif.error_int_stat = 0x00; 1051 s->hif.counter_int_stat = 0xf0; 1052 s->hif.int_stat_ena = 0x00; 1053 s->hif.cpu_int_stat_ena = 0x00; 1054 s->hif.err_int_stat_ena = 0x00; 1055 s->hif.cnt_int_stat_ena = 0x00; 1056 1057 ar6k_hif_cpu_intr_update(s); 1058 ar6k_hif_error_intr_update(s); 1059 ar6k_hif_counter_intr_update(s); 985 1060 } 986 1061 … … 1045 1120 } 1046 1121 1047 s->hif.cnt_dec[4] = 0xff; 1048 s->hif.cnt[4] = rlen; 1122 s->hif.cnt[0] = rlen; 1123 } 1124 1125 static void ar6k_hif_txcredit_reset(struct ar6k_s *s, int mbox) 1126 { 1127 s->hif.cnt_tx[mbox] = 0; 1128 if (!(s->hif.counter_int_stat & (1 << mbox))) { 1129 s->hif.counter_int_stat |= 1 << mbox; 1130 ar6k_hif_counter_intr_sched(s); 1131 } 1132 } 1133 1134 static void ar6k_hif_txcredit_grant(struct ar6k_s *s, int mbox) 1135 { 1136 s->hif.cnt_tx[mbox] = 0xff; 1137 if (!(s->hif.counter_int_stat & (1 << (mbox + 4)))) { 1138 s->hif.counter_int_stat |= 1 << (mbox + 4); 1139 ar6k_hif_counter_intr_sched(s); 1140 } 1049 1141 } 1050 1142 … … 1064 1156 #define AR6K_COUNTER_INT_STAT_ENABLE 0x41b 1065 1157 #define AR6K_COUNT 0x420 1066 #define AR6K_COUNT_DEC 0x440 1158 #define AR6K_COUNT_RESET 0x440 1159 #define AR6K_COUNT_DEC 0x450 1067 1160 #define AR6K_SCRATCH 0x460 1068 1161 #define AR6K_FIFO_TIMEOUT 0x468 … … 1090 1183 1091 1184 switch (addr) { 1185 case AR6K_HOST_INT_STAT: 1186 if (s->hif.host_int_stat & value) { 1187 s->hif.host_int_stat &= ~value; 1188 ar6k_hif_intr_update(s); 1189 } 1190 break; 1191 case AR6K_CPU_INT_STAT: 1192 if (s->hif.cpu_int_stat & value) { 1193 s->hif.cpu_int_stat &= ~value; 1194 ar6k_hif_cpu_intr_update(s); 1195 } 1196 break; 1197 case AR6K_ERROR_INT_STAT: 1198 if (s->hif.error_int_stat & value) { 1199 s->hif.error_int_stat &= ~value; 1200 ar6k_hif_error_intr_update(s); 1201 } 1202 break; 1203 case AR6K_COUNTER_INT_STAT: 1204 if (s->hif.counter_int_stat & value) { 1205 s->hif.counter_int_stat &= ~value; 1206 ar6k_hif_counter_intr_update(s); 1207 } 1208 break; 1092 1209 case AR6K_MBOX_FRAME: 1093 1210 s->hif.mbox_frame = value; … … 1109 1226 break; 1110 1227 case AR6K_INT_STAT_ENABLE: 1111 s->hif.int_stat_ena = value; 1228 if (s->hif.int_stat_ena ^ value) { 1229 s->hif.int_stat_ena = value; 1230 ar6k_hif_intr_update(s); 1231 } 1112 1232 break; 1113 1233 case AR6K_CPU_INT_STAT_ENABLE: 1114 s->hif.cpu_int_stat_ena = value; 1234 if (s->hif.cpu_int_stat_ena ^ value) { 1235 s->hif.cpu_int_stat_ena = value; 1236 ar6k_hif_cpu_intr_update(s); 1237 } 1115 1238 break; 1116 1239 case AR6K_ERROR_STAT_ENABLE: 1117 s->hif.err_int_stat_ena = value; 1240 if (s->hif.err_int_stat_ena ^ value) { 1241 s->hif.err_int_stat_ena = value; 1242 ar6k_hif_error_intr_update(s); 1243 } 1118 1244 break; 1119 1245 case AR6K_COUNTER_INT_STAT_ENABLE: 1120 s->hif.cnt_int_stat_ena = value; 1246 if (s->hif.cnt_int_stat_ena ^ value) { 1247 s->hif.cnt_int_stat_ena = value; 1248 ar6k_hif_counter_intr_sched(s); 1249 } 1121 1250 break; 1122 1251 case AR6K_SCRATCH ... (AR6K_SCRATCH + 7): … … 1128 1257 case AR6K_LOCAL_BUS_ENDIAN: 1129 1258 case AR6K_LOCAL_BUS: 1259 goto bad_reg; 1260 1130 1261 case AR6K_INT_WLAN: 1262 s->hif.wlan_int = value; 1263 if (value) 1264 fprintf(stderr, "%s: WLAN interrupt\n", __FUNCTION__); 1265 break; 1266 1131 1267 case AR6K_WINDOW_DATA: 1132 1268 case AR6K_WRITE_ADDR: … … 1134 1270 case AR6K_SPI_CONFIG: 1135 1271 goto bad_reg; 1272 1136 1273 case AR6K_HIF_MBOX_BASE ... AR6K_HIF_MBOX_END: 1137 1274 mbox = (addr - AR6K_HIF_MBOX_BASE) >> 11; 1138 1275 s->hif.mbox[addr - AR6K_HIF_MBOX_BASE] = value; 1139 1276 s->hif.mbox_count[mbox] ++; 1140 /* XXX how do we know when a BMI command is executed? */ 1141 if (mbox == 0 && !s->bmi.done) { 1142 s->hif.cnt_dec[4] = 0x00; 1143 s->hif.cnt[4] = 0x00; 1144 if ((addr & 0x7ff) == 0x7ff) { 1277 /* XXX how else do we know when a command is executed? */ 1278 if ((addr & 0x7ff) == 0x7ff) { 1279 ar6k_hif_txcredit_reset(s, mbox); 1280 if (mbox == 0 && !s->bmi.done) { 1145 1281 ar6k_bmi_write(s, s->hif.mbox + (mbox << 11), 1146 s->hif.mbox_count[0]); 1147 s->hif.mbox_count[mbox] = 0; 1282 s->hif.mbox_count[mbox]); 1283 } else { 1284 /* TODO */ 1148 1285 } 1286 s->hif.mbox_count[mbox] = 0; 1287 ar6k_hif_txcredit_grant(s, mbox); 1149 1288 } 1150 1289 break; … … 1158 1297 static uint8_t ar6k_hif_read(struct ar6k_s *s, uint32_t addr) 1159 1298 { 1299 int mbox = 0; 1300 1160 1301 switch (addr) { 1161 1302 case AR6K_HOST_INT_STAT: … … 1167 1308 case AR6K_COUNTER_INT_STAT: 1168 1309 return s->hif.counter_int_stat; 1310 1169 1311 case AR6K_MBOX_FRAME: 1170 1312 return s->hif.mbox_frame; 1313 1171 1314 case AR6K_RX_LOOKAHEAD_VALID: 1172 1315 return s->hif.rx_la_valid; … … 1179 1322 case AR6K_RX_LOOKAHEAD3: 1180 1323 return s->hif.rx_la[3]; 1324 1181 1325 case AR6K_INT_STAT_ENABLE: 1182 1326 return s->hif.int_stat_ena; … … 1187 1331 case AR6K_COUNTER_INT_STAT_ENABLE: 1188 1332 return s->hif.cnt_int_stat_ena; 1189 case AR6K_COUNT ... (AR6K_COUNT + 0x7): 1190 return s->hif.cnt[addr - AR6K_COUNT]; 1191 case AR6K_COUNT_DEC + 0x00: 1192 case AR6K_COUNT_DEC + 0x04: 1193 case AR6K_COUNT_DEC + 0x08: 1194 case AR6K_COUNT_DEC + 0x0c: 1195 case AR6K_COUNT_DEC + 0x10: 1196 case AR6K_COUNT_DEC + 0x14: 1197 case AR6K_COUNT_DEC + 0x18: 1198 case AR6K_COUNT_DEC + 0x1c: 1199 return s->hif.cnt_dec[(addr - AR6K_COUNT_DEC) >> 2]; 1333 1334 case (AR6K_COUNT + 0x4) ... (AR6K_COUNT + 0x7): 1335 /* XXX What's at (AR6K_COUNT + 0x0) ... (AR6K_COUNT + 0x3)? */ 1336 /* FIXME clear some interrupts etc */ 1337 return s->hif.cnt[addr - AR6K_COUNT - 4]; 1338 1339 case AR6K_COUNT_RESET + 0xc: mbox ++; 1340 case AR6K_COUNT_RESET + 0x8: mbox ++; 1341 case AR6K_COUNT_RESET + 0x4: mbox ++; 1342 case AR6K_COUNT_RESET + 0x0: 1343 if (s->hif.counter_int_stat & (1 << mbox)) { 1344 s->hif.counter_int_stat &= ~(1 << mbox); 1345 ar6k_hif_counter_intr_update(s); 1346 } 1347 return s->hif.cnt_tx[mbox]; 1348 1349 case AR6K_COUNT_DEC + 0xc: mbox ++; 1350 case AR6K_COUNT_DEC + 0x8: mbox ++; 1351 case AR6K_COUNT_DEC + 0x4: mbox ++; 1352 case AR6K_COUNT_DEC + 0x0: 1353 return s->hif.cnt_tx[mbox]; 1354 1200 1355 case AR6K_SCRATCH ... (AR6K_SCRATCH + 7): 1201 1356 return s->hif.scratch[addr - AR6K_SCRATCH]; 1357 1202 1358 case AR6K_FIFO_TIMEOUT: 1203 1359 case AR6K_FIFO_TIMEOUT_ENABLE: … … 1205 1361 case AR6K_LOCAL_BUS_ENDIAN: 1206 1362 case AR6K_LOCAL_BUS: 1363 goto bad_reg; 1364 1207 1365 case AR6K_INT_WLAN: 1366 return s->hif.wlan_int; 1367 1208 1368 case AR6K_WINDOW_DATA: 1209 1369 case AR6K_WRITE_ADDR: … … 1327 1487 1328 1488 s->nd = nd; 1489 s->cnt_irq_update = qemu_new_timer(vm_clock, ar6k_hif_cnt_irq_tick, s); 1329 1490 s->sd.reset = (void *) ar6k_reset; 1330 1491 s->sd.fbr[0].stdfn = 0 | sdio_fn_none;
Note: See TracChangeset
for help on using the changeset viewer.
