Changeset 943aaf1b in mainline
- Timestamp:
- 2017-10-02T20:52:27Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7e55bed7, 94868e1
- Parents:
- 6886705
- Location:
- uspace/srv/hw/bus/cuda_adb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/bus/cuda_adb/cuda_adb.c
r6886705 r943aaf1b 54 54 #define NAME "cuda_adb" 55 55 56 static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);57 static int cuda_init( void);58 static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg);59 60 static void cuda_irq_listen( void);61 static void cuda_irq_receive( void);62 static void cuda_irq_rcv_end( void *buf, size_t *len);63 static void cuda_irq_send_start( void);64 static void cuda_irq_send( void);65 66 static void cuda_packet_handle( uint8_t *buf, size_t len);67 static void cuda_send_start( void);68 static void cuda_autopoll_set( bool enable);69 70 static void adb_packet_handle( uint8_t *data, size_t size, bool autopoll);56 static void cuda_connection(ipc_callid_t, ipc_call_t *, void *); 57 static int cuda_init(cuda_instance_t *); 58 static void cuda_irq_handler(ipc_callid_t, ipc_call_t *, void *); 59 60 static void cuda_irq_listen(cuda_instance_t *); 61 static void cuda_irq_receive(cuda_instance_t *); 62 static void cuda_irq_rcv_end(cuda_instance_t *, void *, size_t *); 63 static void cuda_irq_send_start(cuda_instance_t *); 64 static void cuda_irq_send(cuda_instance_t *); 65 66 static void cuda_packet_handle(cuda_instance_t *, uint8_t *, size_t); 67 static void cuda_send_start(cuda_instance_t *); 68 static void cuda_autopoll_set(cuda_instance_t *, bool); 69 70 static void adb_packet_handle(cuda_instance_t *, uint8_t *, size_t, bool); 71 71 72 72 static irq_pio_range_t cuda_ranges[] = { … … 107 107 }; 108 108 109 static cuda_instance_t cinst;110 111 static cuda_instance_t *instance = &cinst;112 static cuda_t *dev;113 114 static adb_dev_t adb_dev[ADB_MAX_ADDR];115 116 109 int main(int argc, char *argv[]) 117 110 { 118 111 service_id_t service_id; 112 cuda_instance_t cinst; 119 113 int rc; 120 114 int i; … … 123 117 124 118 for (i = 0; i < ADB_MAX_ADDR; ++i) { 125 adb_dev[i].client_sess = NULL;126 adb_dev[i].service_id = 0;127 } 128 129 async_set_fallback_port_handler(cuda_connection, NULL);119 cinst.adb_dev[i].client_sess = NULL; 120 cinst.adb_dev[i].service_id = 0; 121 } 122 123 async_set_fallback_port_handler(cuda_connection, &cinst); 130 124 rc = loc_server_register(NAME); 131 125 if (rc < 0) { … … 140 134 } 141 135 142 adb_dev[2].service_id = service_id;143 adb_dev[8].service_id = service_id;136 cinst.adb_dev[2].service_id = service_id; 137 cinst.adb_dev[8].service_id = service_id; 144 138 145 139 rc = loc_service_register("adb/mouse", &service_id); … … 149 143 } 150 144 151 adb_dev[9].service_id = service_id;152 153 if (cuda_init( ) < 0) {145 cinst.adb_dev[9].service_id = service_id; 146 147 if (cuda_init(&cinst) < 0) { 154 148 printf("cuda_init() failed\n"); 155 149 return 1; … … 169 163 sysarg_t method; 170 164 service_id_t dsid; 165 cuda_instance_t *cuda = (cuda_instance_t *) arg; 171 166 int dev_addr, i; 172 167 … … 177 172 dev_addr = -1; 178 173 for (i = 0; i < ADB_MAX_ADDR; i++) { 179 if ( adb_dev[i].service_id == dsid)174 if (cuda->adb_dev[i].service_id == dsid) 180 175 dev_addr = i; 181 176 } … … 202 197 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 203 198 if (sess != NULL) { 204 if ( adb_dev[dev_addr].client_sess == NULL) {205 adb_dev[dev_addr].client_sess = sess;199 if (cuda->adb_dev[dev_addr].client_sess == NULL) { 200 cuda->adb_dev[dev_addr].client_sess = sess; 206 201 207 202 /* … … 210 205 */ 211 206 for (i = 0; i < ADB_MAX_ADDR; ++i) { 212 if ( adb_dev[i].service_id == dsid)213 adb_dev[i].client_sess = sess;207 if (cuda->adb_dev[i].service_id == dsid) 208 cuda->adb_dev[i].client_sess = sess; 214 209 } 215 210 … … 222 217 } 223 218 224 225 static int cuda_init(void) 226 { 227 if (sysinfo_get_value("cuda.address.physical", &(instance->cuda_physical)) != EOK) 219 static int cuda_init(cuda_instance_t *cuda) 220 { 221 if (sysinfo_get_value("cuda.address.physical", &(cuda->cuda_physical)) != EOK) 228 222 return -1; 229 223 230 224 void *vaddr; 231 if (pio_enable((void *) instance->cuda_physical, sizeof(cuda_t), &vaddr) != 0)225 if (pio_enable((void *) cuda->cuda_physical, sizeof(cuda_t), &vaddr) != 0) 232 226 return -1; 233 227 234 dev = vaddr; 235 236 instance->cuda = dev; 237 instance->xstate = cx_listen; 238 instance->bidx = 0; 239 instance->snd_bytes = 0; 240 241 fibril_mutex_initialize(&instance->dev_lock); 228 cuda->regs = vaddr; 229 cuda->xstate = cx_listen; 230 cuda->bidx = 0; 231 cuda->snd_bytes = 0; 232 233 fibril_mutex_initialize(&cuda->dev_lock); 242 234 243 235 /* Disable all interrupts from CUDA. */ 244 pio_write_8(& dev->ier, IER_CLR | ALL_INT);245 246 cuda_irq_code.ranges[0].base = (uintptr_t) instance->cuda_physical;247 cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_physical)->ifr;248 async_irq_subscribe(10, cuda_irq_handler, NULL, &cuda_irq_code);236 pio_write_8(&cuda->regs->ier, IER_CLR | ALL_INT); 237 238 cuda_irq_code.ranges[0].base = (uintptr_t) cuda->cuda_physical; 239 cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) cuda->cuda_physical)->ifr; 240 async_irq_subscribe(10, cuda_irq_handler, cuda, &cuda_irq_code); 249 241 250 242 /* Enable SR interrupt. */ 251 pio_write_8(& dev->ier, TIP | TREQ);252 pio_write_8(& dev->ier, IER_SET | SR_INT);243 pio_write_8(&cuda->regs->ier, TIP | TREQ); 244 pio_write_8(&cuda->regs->ier, IER_SET | SR_INT); 253 245 254 246 /* Enable ADB autopolling. */ 255 cuda_autopoll_set( true);247 cuda_autopoll_set(cuda, true); 256 248 257 249 return 0; … … 261 253 { 262 254 uint8_t rbuf[CUDA_RCV_BUF_SIZE]; 255 cuda_instance_t *cuda = (cuda_instance_t *)arg; 263 256 size_t len; 264 257 bool handle; … … 267 260 len = 0; 268 261 269 fibril_mutex_lock(& instance->dev_lock);270 271 switch ( instance->xstate) {262 fibril_mutex_lock(&cuda->dev_lock); 263 264 switch (cuda->xstate) { 272 265 case cx_listen: 273 cuda_irq_listen( );266 cuda_irq_listen(cuda); 274 267 break; 275 268 case cx_receive: 276 cuda_irq_receive( );269 cuda_irq_receive(cuda); 277 270 break; 278 271 case cx_rcv_end: 279 cuda_irq_rcv_end( rbuf, &len);272 cuda_irq_rcv_end(cuda, rbuf, &len); 280 273 handle = true; 281 274 break; 282 275 case cx_send_start: 283 cuda_irq_send_start( );276 cuda_irq_send_start(cuda); 284 277 break; 285 278 case cx_send: 286 cuda_irq_send( );279 cuda_irq_send(cuda); 287 280 break; 288 281 } 289 282 290 283 /* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */ 291 pio_write_8(& instance->cuda->ifr, SR_INT);292 293 fibril_mutex_unlock(& instance->dev_lock);284 pio_write_8(&cuda->regs->ifr, SR_INT); 285 286 fibril_mutex_unlock(&cuda->dev_lock); 294 287 295 288 /* Handle an incoming packet. */ 296 289 if (handle) 297 cuda_packet_handle( rbuf, len);290 cuda_packet_handle(cuda, rbuf, len); 298 291 } 299 292 … … 301 294 * 302 295 * Start packet reception. 303 */ 304 static void cuda_irq_listen(void) 305 { 306 uint8_t b = pio_read_8(&dev->b); 296 * 297 * @param cuda CUDA instance 298 */ 299 static void cuda_irq_listen(cuda_instance_t *cuda) 300 { 301 uint8_t b = pio_read_8(&cuda->regs->b); 307 302 308 303 if ((b & TREQ) != 0) { … … 311 306 } 312 307 313 pio_write_8(& dev->b, b & ~TIP);314 instance->xstate = cx_receive;308 pio_write_8(&cuda->regs->b, b & ~TIP); 309 cuda->xstate = cx_receive; 315 310 } 316 311 … … 318 313 * 319 314 * Receive next byte of packet. 320 */ 321 static void cuda_irq_receive(void) 322 { 323 uint8_t data = pio_read_8(&dev->sr); 324 if (instance->bidx < CUDA_RCV_BUF_SIZE) 325 instance->rcv_buf[instance->bidx++] = data; 326 327 uint8_t b = pio_read_8(&dev->b); 315 * 316 * @param cuda CUDA instance 317 */ 318 static void cuda_irq_receive(cuda_instance_t *cuda) 319 { 320 uint8_t data = pio_read_8(&cuda->regs->sr); 321 if (cuda->bidx < CUDA_RCV_BUF_SIZE) 322 cuda->rcv_buf[cuda->bidx++] = data; 323 324 uint8_t b = pio_read_8(&cuda->regs->b); 328 325 329 326 if ((b & TREQ) == 0) { 330 pio_write_8(& dev->b, b ^ TACK);327 pio_write_8(&cuda->regs->b, b ^ TACK); 331 328 } else { 332 pio_write_8(& dev->b, b | TACK | TIP);333 instance->xstate = cx_rcv_end;329 pio_write_8(&cuda->regs->b, b | TACK | TIP); 330 cuda->xstate = cx_rcv_end; 334 331 } 335 332 } … … 339 336 * Terminate packet reception. Either go back to listen state or start 340 337 * receiving another packet if CUDA has one for us. 341 */ 342 static void cuda_irq_rcv_end(void *buf, size_t *len) 343 { 344 uint8_t b = pio_read_8(&dev->b); 338 * 339 * @param cuda CUDA instance 340 * @param buf Buffer for storing received packet 341 * @param len Place to store length of received packet 342 */ 343 static void cuda_irq_rcv_end(cuda_instance_t *cuda, void *buf, size_t *len) 344 { 345 uint8_t b = pio_read_8(&cuda->regs->b); 345 346 346 347 if ((b & TREQ) == 0) { 347 instance->xstate = cx_receive;348 pio_write_8(& dev->b, b & ~TIP);348 cuda->xstate = cx_receive; 349 pio_write_8(&cuda->regs->b, b & ~TIP); 349 350 } else { 350 instance->xstate = cx_listen;351 cuda_send_start( );352 } 353 354 memcpy(buf, instance->rcv_buf, instance->bidx);355 *len = instance->bidx;356 instance->bidx = 0;351 cuda->xstate = cx_listen; 352 cuda_send_start(cuda); 353 } 354 355 memcpy(buf, cuda->rcv_buf, cuda->bidx); 356 *len = cuda->bidx; 357 cuda->bidx = 0; 357 358 } 358 359 … … 360 361 * 361 362 * Process result of sending first byte (and send second on success). 362 */ 363 static void cuda_irq_send_start(void) 363 * 364 * @param cuda CUDA instance 365 */ 366 static void cuda_irq_send_start(cuda_instance_t *cuda) 364 367 { 365 368 uint8_t b; 366 369 367 b = pio_read_8(& dev->b);370 b = pio_read_8(&cuda->regs->b); 368 371 369 372 if ((b & TREQ) == 0) { 370 373 /* Collision */ 371 pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT); 372 pio_read_8(&dev->sr); 373 pio_write_8(&dev->b, pio_read_8(&dev->b) | TIP | TACK); 374 instance->xstate = cx_listen; 375 return; 376 } 377 378 pio_write_8(&dev->sr, instance->snd_buf[1]); 379 pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK); 380 instance->bidx = 2; 381 382 instance->xstate = cx_send; 374 pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) & 375 ~SR_OUT); 376 pio_read_8(&cuda->regs->sr); 377 pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) | 378 TIP | TACK); 379 cuda->xstate = cx_listen; 380 return; 381 } 382 383 pio_write_8(&cuda->regs->sr, cuda->snd_buf[1]); 384 pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) ^ TACK); 385 cuda->bidx = 2; 386 387 cuda->xstate = cx_send; 383 388 } 384 389 … … 386 391 * 387 392 * Send next byte or terminate transmission. 388 */ 389 static void cuda_irq_send(void) 390 { 391 if (instance->bidx < instance->snd_bytes) { 393 * 394 * @param cuda CUDA instance 395 */ 396 static void cuda_irq_send(cuda_instance_t *cuda) 397 { 398 if (cuda->bidx < cuda->snd_bytes) { 392 399 /* Send next byte. */ 393 pio_write_8(&dev->sr, instance->snd_buf[instance->bidx++]); 394 pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK); 400 pio_write_8(&cuda->regs->sr, 401 cuda->snd_buf[cuda->bidx++]); 402 pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) ^ TACK); 395 403 return; 396 404 } 397 405 398 406 /* End transfer. */ 399 instance->snd_bytes = 0;400 instance->bidx = 0;401 402 pio_write_8(& dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);403 pio_read_8(& dev->sr);404 pio_write_8(& dev->b, pio_read_8(&dev->b) | TACK | TIP);405 406 instance->xstate = cx_listen;407 cuda->snd_bytes = 0; 408 cuda->bidx = 0; 409 410 pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) & ~SR_OUT); 411 pio_read_8(&cuda->regs->sr); 412 pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) | TACK | TIP); 413 414 cuda->xstate = cx_listen; 407 415 /* TODO: Match reply with request. */ 408 416 } 409 417 410 static void cuda_packet_handle( uint8_t *data, size_t len)418 static void cuda_packet_handle(cuda_instance_t *cuda, uint8_t *data, size_t len) 411 419 { 412 420 if (data[0] != PT_ADB) … … 415 423 return; 416 424 417 adb_packet_handle(data + 2, len - 2, (data[1] & 0x40) != 0); 418 } 419 420 static void adb_packet_handle(uint8_t *data, size_t size, bool autopoll) 425 adb_packet_handle(cuda, data + 2, len - 2, (data[1] & 0x40) != 0); 426 } 427 428 static void adb_packet_handle(cuda_instance_t *cuda, uint8_t *data, 429 size_t size, bool autopoll) 421 430 { 422 431 uint8_t dev_addr; … … 448 457 reg_val = ((uint16_t) data[1] << 8) | (uint16_t) data[2]; 449 458 450 if ( adb_dev[dev_addr].client_sess == NULL)459 if (cuda->adb_dev[dev_addr].client_sess == NULL) 451 460 return; 452 461 453 462 async_exch_t *exch = 454 async_exchange_begin( adb_dev[dev_addr].client_sess);463 async_exchange_begin(cuda->adb_dev[dev_addr].client_sess); 455 464 async_msg_1(exch, ADB_REG_NOTIF, reg_val); 456 465 async_exchange_end(exch); 457 466 } 458 467 459 static void cuda_autopoll_set(bool enable) 460 { 461 instance->snd_buf[0] = PT_CUDA; 462 instance->snd_buf[1] = CPT_AUTOPOLL; 463 instance->snd_buf[2] = enable ? 0x01 : 0x00; 464 instance->snd_bytes = 3; 465 instance->bidx = 0; 466 467 cuda_send_start(); 468 } 469 470 static void cuda_send_start(void) 471 { 472 cuda_t *dev = instance->cuda; 473 474 assert(instance->xstate == cx_listen); 475 476 if (instance->snd_bytes == 0) 468 static void cuda_autopoll_set(cuda_instance_t *cuda, bool enable) 469 { 470 cuda->snd_buf[0] = PT_CUDA; 471 cuda->snd_buf[1] = CPT_AUTOPOLL; 472 cuda->snd_buf[2] = enable ? 0x01 : 0x00; 473 cuda->snd_bytes = 3; 474 cuda->bidx = 0; 475 476 cuda_send_start(cuda); 477 } 478 479 static void cuda_send_start(cuda_instance_t *cuda) 480 { 481 assert(cuda->xstate == cx_listen); 482 483 if (cuda->snd_bytes == 0) 477 484 return; 478 485 479 486 /* Check for incoming data. */ 480 if ((pio_read_8(& dev->b) & TREQ) == 0)481 return; 482 483 pio_write_8(& dev->acr, pio_read_8(&dev->acr) | SR_OUT);484 pio_write_8(& dev->sr, instance->snd_buf[0]);485 pio_write_8(& dev->b, pio_read_8(&dev->b) & ~TIP);486 487 instance->xstate = cx_send_start;487 if ((pio_read_8(&cuda->regs->b) & TREQ) == 0) 488 return; 489 490 pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) | SR_OUT); 491 pio_write_8(&cuda->regs->sr, cuda->snd_buf[0]); 492 pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) & ~TIP); 493 494 cuda->xstate = cx_send_start; 488 495 } 489 496 -
uspace/srv/hw/bus/cuda_adb/cuda_adb.h
r6886705 r943aaf1b 41 41 #include <stddef.h> 42 42 #include <stdint.h> 43 #include "cuda_hw.h" 43 44 44 45 enum { … … 60 61 61 62 typedef struct { 62 struct cuda * cuda;63 struct cuda *regs; 63 64 uintptr_t cuda_physical; 64 65 … … 69 70 enum cuda_xfer_state xstate; 70 71 fibril_mutex_t dev_lock; 72 73 adb_dev_t adb_dev[ADB_MAX_ADDR]; 71 74 } cuda_instance_t; 72 75
Note:
See TracChangeset
for help on using the changeset viewer.