Commit 819e712bfe40f0706689a98f9968f842e3aaccd1
1 parent
28b9b5af
cuda fixes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@950 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
138 additions
and
66 deletions
hw/adb.c
| @@ -63,8 +63,8 @@ void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len) | @@ -63,8 +63,8 @@ void adb_receive_packet(ADBBusState *s, const uint8_t *buf, int len) | ||
| 63 | int devaddr, cmd, i; | 63 | int devaddr, cmd, i; |
| 64 | uint8_t obuf[4]; | 64 | uint8_t obuf[4]; |
| 65 | 65 | ||
| 66 | - cmd = buf[1] & 0xf; | ||
| 67 | - devaddr = buf[1] >> 4; | 66 | + cmd = buf[0] & 0xf; |
| 67 | + devaddr = buf[0] >> 4; | ||
| 68 | if (buf[1] == ADB_BUSRESET) { | 68 | if (buf[1] == ADB_BUSRESET) { |
| 69 | obuf[0] = 0x00; | 69 | obuf[0] = 0x00; |
| 70 | obuf[1] = 0x00; | 70 | obuf[1] = 0x00; |
hw/cuda.c
| @@ -23,6 +23,9 @@ | @@ -23,6 +23,9 @@ | ||
| 23 | */ | 23 | */ |
| 24 | #include "vl.h" | 24 | #include "vl.h" |
| 25 | 25 | ||
| 26 | +//#define DEBUG_CUDA | ||
| 27 | +//#define DEBUG_CUDA_PACKET | ||
| 28 | + | ||
| 26 | /* Bits in B data register: all active low */ | 29 | /* Bits in B data register: all active low */ |
| 27 | #define TREQ 0x08 /* Transfer request (input) */ | 30 | #define TREQ 0x08 /* Transfer request (input) */ |
| 28 | #define TACK 0x10 /* Transfer acknowledge (output) */ | 31 | #define TACK 0x10 /* Transfer acknowledge (output) */ |
| @@ -114,6 +117,7 @@ typedef struct CUDAState { | @@ -114,6 +117,7 @@ typedef struct CUDAState { | ||
| 114 | int data_out_index; | 117 | int data_out_index; |
| 115 | 118 | ||
| 116 | int irq; | 119 | int irq; |
| 120 | + openpic_t *openpic; | ||
| 117 | uint8_t autopoll; | 121 | uint8_t autopoll; |
| 118 | uint8_t data_in[128]; | 122 | uint8_t data_in[128]; |
| 119 | uint8_t data_out[16]; | 123 | uint8_t data_out[16]; |
| @@ -125,13 +129,15 @@ ADBBusState adb_bus; | @@ -125,13 +129,15 @@ ADBBusState adb_bus; | ||
| 125 | static void cuda_update(CUDAState *s); | 129 | static void cuda_update(CUDAState *s); |
| 126 | static void cuda_receive_packet_from_host(CUDAState *s, | 130 | static void cuda_receive_packet_from_host(CUDAState *s, |
| 127 | const uint8_t *data, int len); | 131 | const uint8_t *data, int len); |
| 132 | +static void cuda_timer_update(CUDAState *s, CUDATimer *ti, | ||
| 133 | + int64_t current_time); | ||
| 128 | 134 | ||
| 129 | static void cuda_update_irq(CUDAState *s) | 135 | static void cuda_update_irq(CUDAState *s) |
| 130 | { | 136 | { |
| 131 | - if (s->ifr & s->ier & SR_INT) { | ||
| 132 | - pic_set_irq(s->irq, 1); | 137 | + if (s->ifr & s->ier & (SR_INT | T1_INT)) { |
| 138 | + openpic_set_irq(s->openpic, s->irq, 1); | ||
| 133 | } else { | 139 | } else { |
| 134 | - pic_set_irq(s->irq, 0); | 140 | + openpic_set_irq(s->openpic, s->irq, 0); |
| 135 | } | 141 | } |
| 136 | } | 142 | } |
| 137 | 143 | ||
| @@ -150,10 +156,15 @@ static unsigned int get_counter(CUDATimer *s) | @@ -150,10 +156,15 @@ static unsigned int get_counter(CUDATimer *s) | ||
| 150 | return counter; | 156 | return counter; |
| 151 | } | 157 | } |
| 152 | 158 | ||
| 153 | -static void set_counter(CUDATimer *s, unsigned int val) | 159 | +static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val) |
| 154 | { | 160 | { |
| 155 | - s->load_time = qemu_get_clock(vm_clock); | ||
| 156 | - s->counter_value = val; | 161 | +#ifdef DEBUG_CUDA |
| 162 | + printf("cuda: T%d.counter=%d\n", | ||
| 163 | + 1 + (ti->timer == NULL), val); | ||
| 164 | +#endif | ||
| 165 | + ti->load_time = qemu_get_clock(vm_clock); | ||
| 166 | + ti->counter_value = val; | ||
| 167 | + cuda_timer_update(s, ti, ti->load_time); | ||
| 157 | } | 168 | } |
| 158 | 169 | ||
| 159 | static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time) | 170 | static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time) |
| @@ -165,10 +176,14 @@ static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time) | @@ -165,10 +176,14 @@ static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time) | ||
| 165 | if (d <= s->counter_value) { | 176 | if (d <= s->counter_value) { |
| 166 | next_time = s->counter_value + 1; | 177 | next_time = s->counter_value + 1; |
| 167 | } else { | 178 | } else { |
| 168 | - base = ((d - s->counter_value) % s->latch); | 179 | + base = ((d - s->counter_value) / s->latch); |
| 169 | base = (base * s->latch) + s->counter_value; | 180 | base = (base * s->latch) + s->counter_value; |
| 170 | next_time = base + s->latch; | 181 | next_time = base + s->latch; |
| 171 | } | 182 | } |
| 183 | +#ifdef DEBUG_CUDA | ||
| 184 | + printf("latch=%d counter=%lld delta_next=%lld\n", | ||
| 185 | + s->latch, d, next_time - d); | ||
| 186 | +#endif | ||
| 172 | next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) + | 187 | next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) + |
| 173 | s->load_time; | 188 | s->load_time; |
| 174 | if (next_time <= current_time) | 189 | if (next_time <= current_time) |
| @@ -176,13 +191,25 @@ static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time) | @@ -176,13 +191,25 @@ static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time) | ||
| 176 | return next_time; | 191 | return next_time; |
| 177 | } | 192 | } |
| 178 | 193 | ||
| 194 | +static void cuda_timer_update(CUDAState *s, CUDATimer *ti, | ||
| 195 | + int64_t current_time) | ||
| 196 | +{ | ||
| 197 | + if (!ti->timer) | ||
| 198 | + return; | ||
| 199 | + if ((s->acr & T1MODE) != T1MODE_CONT) { | ||
| 200 | + qemu_del_timer(ti->timer); | ||
| 201 | + } else { | ||
| 202 | + ti->next_irq_time = get_next_irq_time(ti, current_time); | ||
| 203 | + qemu_mod_timer(ti->timer, ti->next_irq_time); | ||
| 204 | + } | ||
| 205 | +} | ||
| 206 | + | ||
| 179 | static void cuda_timer1(void *opaque) | 207 | static void cuda_timer1(void *opaque) |
| 180 | { | 208 | { |
| 181 | CUDAState *s = opaque; | 209 | CUDAState *s = opaque; |
| 182 | CUDATimer *ti = &s->timers[0]; | 210 | CUDATimer *ti = &s->timers[0]; |
| 183 | 211 | ||
| 184 | - ti->next_irq_time = get_next_irq_time(ti, ti->next_irq_time); | ||
| 185 | - qemu_mod_timer(ti->timer, ti->next_irq_time); | 212 | + cuda_timer_update(s, ti, ti->next_irq_time); |
| 186 | s->ifr |= T1_INT; | 213 | s->ifr |= T1_INT; |
| 187 | cuda_update_irq(s); | 214 | cuda_update_irq(s); |
| 188 | } | 215 | } |
| @@ -229,11 +256,9 @@ static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr) | @@ -229,11 +256,9 @@ static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr) | ||
| 229 | val = get_counter(&s->timers[1]) >> 8; | 256 | val = get_counter(&s->timers[1]) >> 8; |
| 230 | break; | 257 | break; |
| 231 | case 10: | 258 | case 10: |
| 232 | - if (s->data_in_index < s->data_in_size) { | ||
| 233 | - val = s->data_in[s->data_in_index]; | ||
| 234 | - } else { | ||
| 235 | - val = 0; | ||
| 236 | - } | 259 | + val = s->sr; |
| 260 | + s->ifr &= ~SR_INT; | ||
| 261 | + cuda_update_irq(s); | ||
| 237 | break; | 262 | break; |
| 238 | case 11: | 263 | case 11: |
| 239 | val = s->acr; | 264 | val = s->acr; |
| @@ -253,7 +278,8 @@ static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr) | @@ -253,7 +278,8 @@ static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr) | ||
| 253 | break; | 278 | break; |
| 254 | } | 279 | } |
| 255 | #ifdef DEBUG_CUDA | 280 | #ifdef DEBUG_CUDA |
| 256 | - printf("cuda: read: reg=0x%x val=%02x\n", addr, val); | 281 | + if (addr != 13 || val != 0) |
| 282 | + printf("cuda: read: reg=0x%x val=%02x\n", addr, val); | ||
| 257 | #endif | 283 | #endif |
| 258 | return val; | 284 | return val; |
| 259 | } | 285 | } |
| @@ -283,44 +309,34 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) | @@ -283,44 +309,34 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) | ||
| 283 | break; | 309 | break; |
| 284 | case 4: | 310 | case 4: |
| 285 | val = val | (get_counter(&s->timers[0]) & 0xff00); | 311 | val = val | (get_counter(&s->timers[0]) & 0xff00); |
| 286 | - set_counter(&s->timers[0], val); | 312 | + set_counter(s, &s->timers[0], val); |
| 287 | break; | 313 | break; |
| 288 | case 5: | 314 | case 5: |
| 289 | val = (val << 8) | (get_counter(&s->timers[0]) & 0xff); | 315 | val = (val << 8) | (get_counter(&s->timers[0]) & 0xff); |
| 290 | - set_counter(&s->timers[0], val); | 316 | + set_counter(s, &s->timers[0], val); |
| 291 | break; | 317 | break; |
| 292 | case 6: | 318 | case 6: |
| 293 | s->timers[0].latch = (s->timers[0].latch & 0xff00) | val; | 319 | s->timers[0].latch = (s->timers[0].latch & 0xff00) | val; |
| 320 | + cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); | ||
| 294 | break; | 321 | break; |
| 295 | case 7: | 322 | case 7: |
| 296 | s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8); | 323 | s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8); |
| 324 | + cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); | ||
| 297 | break; | 325 | break; |
| 298 | case 8: | 326 | case 8: |
| 299 | val = val | (get_counter(&s->timers[1]) & 0xff00); | 327 | val = val | (get_counter(&s->timers[1]) & 0xff00); |
| 300 | - set_counter(&s->timers[1], val); | 328 | + set_counter(s, &s->timers[1], val); |
| 301 | break; | 329 | break; |
| 302 | case 9: | 330 | case 9: |
| 303 | val = (val << 8) | (get_counter(&s->timers[1]) & 0xff); | 331 | val = (val << 8) | (get_counter(&s->timers[1]) & 0xff); |
| 304 | - set_counter(&s->timers[1], val); | 332 | + set_counter(s, &s->timers[1], val); |
| 305 | break; | 333 | break; |
| 306 | case 10: | 334 | case 10: |
| 307 | s->sr = val; | 335 | s->sr = val; |
| 308 | break; | 336 | break; |
| 309 | case 11: | 337 | case 11: |
| 310 | s->acr = val; | 338 | s->acr = val; |
| 311 | - if ((s->acr & T1MODE) == T1MODE_CONT) { | ||
| 312 | - if ((s->last_acr & T1MODE) != T1MODE_CONT) { | ||
| 313 | - CUDATimer *ti = &s->timers[0]; | ||
| 314 | - /* activate timer interrupt */ | ||
| 315 | - ti->next_irq_time = get_next_irq_time(ti, qemu_get_clock(vm_clock)); | ||
| 316 | - qemu_mod_timer(ti->timer, ti->next_irq_time); | ||
| 317 | - } | ||
| 318 | - } else { | ||
| 319 | - if ((s->last_acr & T1MODE) == T1MODE_CONT) { | ||
| 320 | - CUDATimer *ti = &s->timers[0]; | ||
| 321 | - qemu_del_timer(ti->timer); | ||
| 322 | - } | ||
| 323 | - } | 339 | + cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); |
| 324 | cuda_update(s); | 340 | cuda_update(s); |
| 325 | break; | 341 | break; |
| 326 | case 12: | 342 | case 12: |
| @@ -351,47 +367,90 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) | @@ -351,47 +367,90 @@ static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) | ||
| 351 | /* NOTE: TIP and TREQ are negated */ | 367 | /* NOTE: TIP and TREQ are negated */ |
| 352 | static void cuda_update(CUDAState *s) | 368 | static void cuda_update(CUDAState *s) |
| 353 | { | 369 | { |
| 354 | - if (s->data_in_index < s->data_in_size) { | ||
| 355 | - /* data input */ | ||
| 356 | - if (!(s->b & TIP) && | ||
| 357 | - (s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) { | ||
| 358 | - s->sr = s->data_in[s->data_in_index++]; | ||
| 359 | - s->ifr |= SR_INT; | ||
| 360 | - cuda_update_irq(s); | ||
| 361 | - } | ||
| 362 | - } | ||
| 363 | - if (s->data_in_index < s->data_in_size) { | ||
| 364 | - /* there is some data to read */ | ||
| 365 | - s->b = (s->b & ~TREQ); | ||
| 366 | - } else { | ||
| 367 | - s->b = (s->b | TREQ); | ||
| 368 | - } | 370 | + int packet_received, len; |
| 371 | + | ||
| 372 | + packet_received = 0; | ||
| 373 | + if (!(s->b & TIP)) { | ||
| 374 | + /* transfer requested from host */ | ||
| 369 | 375 | ||
| 370 | - if (s->acr & SR_OUT) { | ||
| 371 | - /* data output */ | ||
| 372 | - if (!(s->b & TIP) && | ||
| 373 | - (s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) { | ||
| 374 | - if (s->data_out_index < sizeof(s->data_out)) { | ||
| 375 | - s->data_out[s->data_out_index++] = s->sr; | 376 | + if (s->acr & SR_OUT) { |
| 377 | + /* data output */ | ||
| 378 | + if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) { | ||
| 379 | + if (s->data_out_index < sizeof(s->data_out)) { | ||
| 380 | +#ifdef DEBUG_CUDA | ||
| 381 | + printf("cuda: send: %02x\n", s->sr); | ||
| 382 | +#endif | ||
| 383 | + s->data_out[s->data_out_index++] = s->sr; | ||
| 384 | + s->ifr |= SR_INT; | ||
| 385 | + cuda_update_irq(s); | ||
| 386 | + } | ||
| 387 | + } | ||
| 388 | + } else { | ||
| 389 | + if (s->data_in_index < s->data_in_size) { | ||
| 390 | + /* data input */ | ||
| 391 | + if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) { | ||
| 392 | + s->sr = s->data_in[s->data_in_index++]; | ||
| 393 | +#ifdef DEBUG_CUDA | ||
| 394 | + printf("cuda: recv: %02x\n", s->sr); | ||
| 395 | +#endif | ||
| 396 | + /* indicate end of transfer */ | ||
| 397 | + if (s->data_in_index >= s->data_in_size) { | ||
| 398 | + s->b = (s->b | TREQ); | ||
| 399 | + } | ||
| 400 | + s->ifr |= SR_INT; | ||
| 401 | + cuda_update_irq(s); | ||
| 402 | + } | ||
| 376 | } | 403 | } |
| 404 | + } | ||
| 405 | + } else { | ||
| 406 | + /* no transfer requested: handle sync case */ | ||
| 407 | + if ((s->last_b & TIP) && (s->b & TACK) != (s->last_b & TACK)) { | ||
| 408 | + /* update TREQ state each time TACK change state */ | ||
| 409 | + if (s->b & TACK) | ||
| 410 | + s->b = (s->b | TREQ); | ||
| 411 | + else | ||
| 412 | + s->b = (s->b & ~TREQ); | ||
| 377 | s->ifr |= SR_INT; | 413 | s->ifr |= SR_INT; |
| 378 | cuda_update_irq(s); | 414 | cuda_update_irq(s); |
| 415 | + } else { | ||
| 416 | + if (!(s->last_b & TIP)) { | ||
| 417 | + /* handle end of host to cuda transfert */ | ||
| 418 | + packet_received = (s->data_out_index > 0); | ||
| 419 | + /* always an IRQ at the end of transfert */ | ||
| 420 | + s->ifr |= SR_INT; | ||
| 421 | + cuda_update_irq(s); | ||
| 422 | + } | ||
| 423 | + /* signal if there is data to read */ | ||
| 424 | + if (s->data_in_index < s->data_in_size) { | ||
| 425 | + s->b = (s->b & ~TREQ); | ||
| 426 | + } | ||
| 379 | } | 427 | } |
| 380 | } | 428 | } |
| 381 | 429 | ||
| 382 | - /* check end of data output */ | ||
| 383 | - if (!(s->acr & SR_OUT) && (s->last_acr & SR_OUT)) { | ||
| 384 | - if (s->data_out_index > 0) | ||
| 385 | - cuda_receive_packet_from_host(s, s->data_out, s->data_out_index); | ||
| 386 | - s->data_out_index = 0; | ||
| 387 | - } | ||
| 388 | s->last_acr = s->acr; | 430 | s->last_acr = s->acr; |
| 389 | s->last_b = s->b; | 431 | s->last_b = s->b; |
| 432 | + | ||
| 433 | + /* NOTE: cuda_receive_packet_from_host() can call cuda_update() | ||
| 434 | + recursively */ | ||
| 435 | + if (packet_received) { | ||
| 436 | + len = s->data_out_index; | ||
| 437 | + s->data_out_index = 0; | ||
| 438 | + cuda_receive_packet_from_host(s, s->data_out, len); | ||
| 439 | + } | ||
| 390 | } | 440 | } |
| 391 | 441 | ||
| 392 | static void cuda_send_packet_to_host(CUDAState *s, | 442 | static void cuda_send_packet_to_host(CUDAState *s, |
| 393 | const uint8_t *data, int len) | 443 | const uint8_t *data, int len) |
| 394 | { | 444 | { |
| 445 | +#ifdef DEBUG_CUDA_PACKET | ||
| 446 | + { | ||
| 447 | + int i; | ||
| 448 | + printf("cuda_send_packet_to_host:\n"); | ||
| 449 | + for(i = 0; i < len; i++) | ||
| 450 | + printf(" %02x", data[i]); | ||
| 451 | + printf("\n"); | ||
| 452 | + } | ||
| 453 | +#endif | ||
| 395 | memcpy(s->data_in, data, len); | 454 | memcpy(s->data_in, data, len); |
| 396 | s->data_in_size = len; | 455 | s->data_in_size = len; |
| 397 | s->data_in_index = 0; | 456 | s->data_in_index = 0; |
| @@ -425,7 +484,7 @@ static void cuda_receive_packet(CUDAState *s, | @@ -425,7 +484,7 @@ static void cuda_receive_packet(CUDAState *s, | ||
| 425 | break; | 484 | break; |
| 426 | case CUDA_GET_TIME: | 485 | case CUDA_GET_TIME: |
| 427 | /* XXX: add time support ? */ | 486 | /* XXX: add time support ? */ |
| 428 | - ti = 0; | 487 | + ti = time(NULL); |
| 429 | obuf[0] = CUDA_PACKET; | 488 | obuf[0] = CUDA_PACKET; |
| 430 | obuf[1] = 0; | 489 | obuf[1] = 0; |
| 431 | obuf[2] = 0; | 490 | obuf[2] = 0; |
| @@ -452,6 +511,15 @@ static void cuda_receive_packet(CUDAState *s, | @@ -452,6 +511,15 @@ static void cuda_receive_packet(CUDAState *s, | ||
| 452 | static void cuda_receive_packet_from_host(CUDAState *s, | 511 | static void cuda_receive_packet_from_host(CUDAState *s, |
| 453 | const uint8_t *data, int len) | 512 | const uint8_t *data, int len) |
| 454 | { | 513 | { |
| 514 | +#ifdef DEBUG_CUDA_PACKET | ||
| 515 | + { | ||
| 516 | + int i; | ||
| 517 | + printf("cuda_receive_packet_to_host:\n"); | ||
| 518 | + for(i = 0; i < len; i++) | ||
| 519 | + printf(" %02x", data[i]); | ||
| 520 | + printf("\n"); | ||
| 521 | + } | ||
| 522 | +#endif | ||
| 455 | switch(data[0]) { | 523 | switch(data[0]) { |
| 456 | case ADB_PACKET: | 524 | case ADB_PACKET: |
| 457 | adb_receive_packet(&adb_bus, data + 1, len - 1); | 525 | adb_receive_packet(&adb_bus, data + 1, len - 1); |
| @@ -492,16 +560,20 @@ static CPUReadMemoryFunc *cuda_read[] = { | @@ -492,16 +560,20 @@ static CPUReadMemoryFunc *cuda_read[] = { | ||
| 492 | &cuda_readl, | 560 | &cuda_readl, |
| 493 | }; | 561 | }; |
| 494 | 562 | ||
| 495 | -int cuda_init(void) | 563 | +int cuda_init(openpic_t *openpic, int irq) |
| 496 | { | 564 | { |
| 497 | CUDAState *s = &cuda_state; | 565 | CUDAState *s = &cuda_state; |
| 498 | int cuda_mem_index; | 566 | int cuda_mem_index; |
| 499 | 567 | ||
| 500 | - s->timers[0].latch = 0x10000; | ||
| 501 | - set_counter(&s->timers[0], 0xffff); | 568 | + s->openpic = openpic; |
| 569 | + s->irq = irq; | ||
| 570 | + | ||
| 502 | s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s); | 571 | s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s); |
| 572 | + s->timers[0].latch = 0x10000; | ||
| 573 | + set_counter(s, &s->timers[0], 0xffff); | ||
| 503 | s->timers[1].latch = 0x10000; | 574 | s->timers[1].latch = 0x10000; |
| 504 | - set_counter(&s->timers[1], 0xffff); | 575 | + s->ier = T1_INT | SR_INT; |
| 576 | + set_counter(s, &s->timers[1], 0xffff); | ||
| 505 | cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); | 577 | cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); |
| 506 | return cuda_mem_index; | 578 | return cuda_mem_index; |
| 507 | } | 579 | } |