diff options
| -rw-r--r-- | drivers/staging/tidspbridge/include/dspbridge/proc.h | 46 | ||||
| -rw-r--r-- | drivers/staging/tidspbridge/pmgr/dspapi.c | 34 | ||||
| -rw-r--r-- | drivers/staging/tidspbridge/rmgr/node.c | 20 | ||||
| -rw-r--r-- | drivers/staging/tidspbridge/rmgr/proc.c | 114 |
4 files changed, 197 insertions, 17 deletions
diff --git a/drivers/staging/tidspbridge/include/dspbridge/proc.h b/drivers/staging/tidspbridge/include/dspbridge/proc.h index 2d12aab6b5bf..5e09fd165d9d 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/proc.h +++ b/drivers/staging/tidspbridge/include/dspbridge/proc.h | |||
| @@ -551,6 +551,29 @@ extern int proc_map(void *hprocessor, | |||
| 551 | struct process_context *pr_ctxt); | 551 | struct process_context *pr_ctxt); |
| 552 | 552 | ||
| 553 | /* | 553 | /* |
| 554 | * ======== proc_reserve_memory ======== | ||
| 555 | * Purpose: | ||
| 556 | * Reserve a virtually contiguous region of DSP address space. | ||
| 557 | * Parameters: | ||
| 558 | * hprocessor : The processor handle. | ||
| 559 | * ul_size : Size of the address space to reserve. | ||
| 560 | * pp_rsv_addr : Ptr to DSP side reserved u8 address. | ||
| 561 | * Returns: | ||
| 562 | * 0 : Success. | ||
| 563 | * -EFAULT : Invalid processor handle. | ||
| 564 | * -EPERM : General failure. | ||
| 565 | * -ENOMEM : Cannot reserve chunk of this size. | ||
| 566 | * Requires: | ||
| 567 | * pp_rsv_addr is not NULL | ||
| 568 | * PROC Initialized. | ||
| 569 | * Ensures: | ||
| 570 | * Details: | ||
| 571 | */ | ||
| 572 | extern int proc_reserve_memory(void *hprocessor, | ||
| 573 | u32 ul_size, void **pp_rsv_addr, | ||
| 574 | struct process_context *pr_ctxt); | ||
| 575 | |||
| 576 | /* | ||
| 554 | * ======== proc_un_map ======== | 577 | * ======== proc_un_map ======== |
| 555 | * Purpose: | 578 | * Purpose: |
| 556 | * Removes a MPU buffer mapping from the DSP address space. | 579 | * Removes a MPU buffer mapping from the DSP address space. |
| @@ -572,4 +595,27 @@ extern int proc_map(void *hprocessor, | |||
| 572 | extern int proc_un_map(void *hprocessor, void *map_addr, | 595 | extern int proc_un_map(void *hprocessor, void *map_addr, |
| 573 | struct process_context *pr_ctxt); | 596 | struct process_context *pr_ctxt); |
| 574 | 597 | ||
| 598 | /* | ||
| 599 | * ======== proc_un_reserve_memory ======== | ||
| 600 | * Purpose: | ||
| 601 | * Frees a previously reserved region of DSP address space. | ||
| 602 | * Parameters: | ||
| 603 | * hprocessor : The processor handle. | ||
| 604 | * prsv_addr : Ptr to DSP side reservedBYTE address. | ||
| 605 | * Returns: | ||
| 606 | * 0 : Success. | ||
| 607 | * -EFAULT : Invalid processor handle. | ||
| 608 | * -EPERM : General failure. | ||
| 609 | * -ENOENT : Cannot find a reserved region starting with this | ||
| 610 | * : address. | ||
| 611 | * Requires: | ||
| 612 | * prsv_addr is not NULL | ||
| 613 | * PROC Initialized. | ||
| 614 | * Ensures: | ||
| 615 | * Details: | ||
| 616 | */ | ||
| 617 | extern int proc_un_reserve_memory(void *hprocessor, | ||
| 618 | void *prsv_addr, | ||
| 619 | struct process_context *pr_ctxt); | ||
| 620 | |||
| 575 | #endif /* PROC_ */ | 621 | #endif /* PROC_ */ |
diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c index 981551ce4d78..86ca785f1913 100644 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ b/drivers/staging/tidspbridge/pmgr/dspapi.c | |||
| @@ -993,10 +993,27 @@ u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt) | |||
| 993 | /* | 993 | /* |
| 994 | * ======== procwrap_reserve_memory ======== | 994 | * ======== procwrap_reserve_memory ======== |
| 995 | */ | 995 | */ |
| 996 | u32 __deprecated procwrap_reserve_memory(union trapped_args *args, | 996 | u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt) |
| 997 | void *pr_ctxt) | ||
| 998 | { | 997 | { |
| 999 | return 0; | 998 | int status; |
| 999 | void *prsv_addr; | ||
| 1000 | void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; | ||
| 1001 | |||
| 1002 | if ((args->args_proc_rsvmem.ul_size <= 0) || | ||
| 1003 | (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0) | ||
| 1004 | return -EINVAL; | ||
| 1005 | |||
| 1006 | status = proc_reserve_memory(hprocessor, | ||
| 1007 | args->args_proc_rsvmem.ul_size, &prsv_addr, | ||
| 1008 | pr_ctxt); | ||
| 1009 | if (!status) { | ||
| 1010 | if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) { | ||
| 1011 | status = -EINVAL; | ||
| 1012 | proc_un_reserve_memory(args->args_proc_rsvmem. | ||
| 1013 | hprocessor, prsv_addr, pr_ctxt); | ||
| 1014 | } | ||
| 1015 | } | ||
| 1016 | return status; | ||
| 1000 | } | 1017 | } |
| 1001 | 1018 | ||
| 1002 | /* | 1019 | /* |
| @@ -1025,10 +1042,15 @@ u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt) | |||
| 1025 | /* | 1042 | /* |
| 1026 | * ======== procwrap_un_reserve_memory ======== | 1043 | * ======== procwrap_un_reserve_memory ======== |
| 1027 | */ | 1044 | */ |
| 1028 | u32 __deprecated procwrap_un_reserve_memory(union trapped_args *args, | 1045 | u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt) |
| 1029 | void *pr_ctxt) | ||
| 1030 | { | 1046 | { |
| 1031 | return 0; | 1047 | int status; |
| 1048 | void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor; | ||
| 1049 | |||
| 1050 | status = proc_un_reserve_memory(hprocessor, | ||
| 1051 | args->args_proc_unrsvmem.prsv_addr, | ||
| 1052 | pr_ctxt); | ||
| 1053 | return status; | ||
| 1032 | } | 1054 | } |
| 1033 | 1055 | ||
| 1034 | /* | 1056 | /* |
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c index ccb1811a4700..1562f3c1281c 100644 --- a/drivers/staging/tidspbridge/rmgr/node.c +++ b/drivers/staging/tidspbridge/rmgr/node.c | |||
| @@ -430,6 +430,17 @@ int node_allocate(struct proc_object *hprocessor, | |||
| 430 | if (status) | 430 | if (status) |
| 431 | goto func_cont; | 431 | goto func_cont; |
| 432 | 432 | ||
| 433 | status = proc_reserve_memory(hprocessor, | ||
| 434 | pnode->create_args.asa.task_arg_obj. | ||
| 435 | heap_size + PAGE_SIZE, | ||
| 436 | (void **)&(pnode->create_args.asa. | ||
| 437 | task_arg_obj.udsp_heap_res_addr), | ||
| 438 | pr_ctxt); | ||
| 439 | if (status) { | ||
| 440 | pr_err("%s: Failed to reserve memory for heap: 0x%x\n", | ||
| 441 | __func__, status); | ||
| 442 | goto func_cont; | ||
| 443 | } | ||
| 433 | #ifdef DSP_DMM_DEBUG | 444 | #ifdef DSP_DMM_DEBUG |
| 434 | status = dmm_get_handle(p_proc_object, &dmm_mgr); | 445 | status = dmm_get_handle(p_proc_object, &dmm_mgr); |
| 435 | if (!dmm_mgr) { | 446 | if (!dmm_mgr) { |
| @@ -445,7 +456,8 @@ int node_allocate(struct proc_object *hprocessor, | |||
| 445 | map_attrs |= DSP_MAPVIRTUALADDR; | 456 | map_attrs |= DSP_MAPVIRTUALADDR; |
| 446 | status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr, | 457 | status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr, |
| 447 | pnode->create_args.asa.task_arg_obj.heap_size, | 458 | pnode->create_args.asa.task_arg_obj.heap_size, |
| 448 | NULL, (void **)&mapped_addr, map_attrs, | 459 | (void *)pnode->create_args.asa.task_arg_obj. |
| 460 | udsp_heap_res_addr, (void **)&mapped_addr, map_attrs, | ||
| 449 | pr_ctxt); | 461 | pr_ctxt); |
| 450 | if (status) | 462 | if (status) |
| 451 | pr_err("%s: Failed to map memory for Heap: 0x%x\n", | 463 | pr_err("%s: Failed to map memory for Heap: 0x%x\n", |
| @@ -2564,6 +2576,12 @@ static void delete_node(struct node_object *hnode, | |||
| 2564 | status = proc_un_map(hnode->hprocessor, (void *) | 2576 | status = proc_un_map(hnode->hprocessor, (void *) |
| 2565 | task_arg_obj.udsp_heap_addr, | 2577 | task_arg_obj.udsp_heap_addr, |
| 2566 | pr_ctxt); | 2578 | pr_ctxt); |
| 2579 | |||
| 2580 | status = proc_un_reserve_memory(hnode->hprocessor, | ||
| 2581 | (void *) | ||
| 2582 | task_arg_obj. | ||
| 2583 | udsp_heap_res_addr, | ||
| 2584 | pr_ctxt); | ||
| 2567 | #ifdef DSP_DMM_DEBUG | 2585 | #ifdef DSP_DMM_DEBUG |
| 2568 | status = dmm_get_handle(p_proc_object, &dmm_mgr); | 2586 | status = dmm_get_handle(p_proc_object, &dmm_mgr); |
| 2569 | if (dmm_mgr) | 2587 | if (dmm_mgr) |
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c index 429f3549965a..e5fec5729037 100644 --- a/drivers/staging/tidspbridge/rmgr/proc.c +++ b/drivers/staging/tidspbridge/rmgr/proc.c | |||
| @@ -152,21 +152,34 @@ static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt, | |||
| 152 | return map_obj; | 152 | return map_obj; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static int match_exact_map_obj(struct dmm_map_object *map_obj, | ||
| 156 | u32 dsp_addr, u32 size) | ||
| 157 | { | ||
| 158 | if (map_obj->dsp_addr == dsp_addr && map_obj->size != size) | ||
| 159 | pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n", | ||
| 160 | __func__, dsp_addr, map_obj->size, size); | ||
| 161 | |||
| 162 | return map_obj->dsp_addr == dsp_addr && | ||
| 163 | map_obj->size == size; | ||
| 164 | } | ||
| 165 | |||
| 155 | static void remove_mapping_information(struct process_context *pr_ctxt, | 166 | static void remove_mapping_information(struct process_context *pr_ctxt, |
| 156 | u32 dsp_addr) | 167 | u32 dsp_addr, u32 size) |
| 157 | { | 168 | { |
| 158 | struct dmm_map_object *map_obj; | 169 | struct dmm_map_object *map_obj; |
| 159 | 170 | ||
| 160 | pr_debug("%s: looking for virt 0x%x\n", __func__, dsp_addr); | 171 | pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__, |
| 172 | dsp_addr, size); | ||
| 161 | 173 | ||
| 162 | spin_lock(&pr_ctxt->dmm_map_lock); | 174 | spin_lock(&pr_ctxt->dmm_map_lock); |
| 163 | list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) { | 175 | list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) { |
| 164 | pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x\n", | 176 | pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n", |
| 165 | __func__, | 177 | __func__, |
| 166 | map_obj->mpu_addr, | 178 | map_obj->mpu_addr, |
| 167 | map_obj->dsp_addr); | 179 | map_obj->dsp_addr, |
| 180 | map_obj->size); | ||
| 168 | 181 | ||
| 169 | if (map_obj->dsp_addr == dsp_addr) { | 182 | if (match_exact_map_obj(map_obj, dsp_addr, size)) { |
| 170 | pr_debug("%s: match, deleting map info\n", __func__); | 183 | pr_debug("%s: match, deleting map info\n", __func__); |
| 171 | list_del(&map_obj->link); | 184 | list_del(&map_obj->link); |
| 172 | kfree(map_obj->dma_info.sg); | 185 | kfree(map_obj->dma_info.sg); |
| @@ -1340,6 +1353,7 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, | |||
| 1340 | { | 1353 | { |
| 1341 | u32 va_align; | 1354 | u32 va_align; |
| 1342 | u32 pa_align; | 1355 | u32 pa_align; |
| 1356 | struct dmm_object *dmm_mgr; | ||
| 1343 | u32 size_align; | 1357 | u32 size_align; |
| 1344 | int status = 0; | 1358 | int status = 0; |
| 1345 | struct proc_object *p_proc_object = (struct proc_object *)hprocessor; | 1359 | struct proc_object *p_proc_object = (struct proc_object *)hprocessor; |
| @@ -1368,6 +1382,11 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, | |||
| 1368 | } | 1382 | } |
| 1369 | /* Critical section */ | 1383 | /* Critical section */ |
| 1370 | mutex_lock(&proc_lock); | 1384 | mutex_lock(&proc_lock); |
| 1385 | dmm_get_handle(p_proc_object, &dmm_mgr); | ||
| 1386 | if (dmm_mgr) | ||
| 1387 | status = dmm_map_memory(dmm_mgr, va_align, size_align); | ||
| 1388 | else | ||
| 1389 | status = -EFAULT; | ||
| 1371 | 1390 | ||
| 1372 | /* Add mapping to the page tables. */ | 1391 | /* Add mapping to the page tables. */ |
| 1373 | if (!status) { | 1392 | if (!status) { |
| @@ -1390,9 +1409,9 @@ int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size, | |||
| 1390 | map_obj->dsp_addr = (va_align | | 1409 | map_obj->dsp_addr = (va_align | |
| 1391 | ((u32)pmpu_addr & (PG_SIZE4K - 1))); | 1410 | ((u32)pmpu_addr & (PG_SIZE4K - 1))); |
| 1392 | *pp_map_addr = (void *)map_obj->dsp_addr; | 1411 | *pp_map_addr = (void *)map_obj->dsp_addr; |
| 1393 | pr_err("%s: mapped address %x\n", __func__, *pp_map_addr); | ||
| 1394 | } else { | 1412 | } else { |
| 1395 | remove_mapping_information(pr_ctxt, va_align); | 1413 | remove_mapping_information(pr_ctxt, va_align, size_align); |
| 1414 | dmm_un_map_memory(dmm_mgr, va_align, &size_align); | ||
| 1396 | } | 1415 | } |
| 1397 | mutex_unlock(&proc_lock); | 1416 | mutex_unlock(&proc_lock); |
| 1398 | 1417 | ||
| @@ -1485,6 +1504,38 @@ func_end: | |||
| 1485 | } | 1504 | } |
| 1486 | 1505 | ||
| 1487 | /* | 1506 | /* |
| 1507 | * ======== proc_reserve_memory ======== | ||
| 1508 | * Purpose: | ||
| 1509 | * Reserve a virtually contiguous region of DSP address space. | ||
| 1510 | */ | ||
| 1511 | int proc_reserve_memory(void *hprocessor, u32 ul_size, | ||
| 1512 | void **pp_rsv_addr, | ||
| 1513 | struct process_context *pr_ctxt) | ||
| 1514 | { | ||
| 1515 | struct dmm_object *dmm_mgr; | ||
| 1516 | int status = 0; | ||
| 1517 | struct proc_object *p_proc_object = (struct proc_object *)hprocessor; | ||
| 1518 | |||
| 1519 | if (!p_proc_object) { | ||
| 1520 | status = -EFAULT; | ||
| 1521 | goto func_end; | ||
| 1522 | } | ||
| 1523 | |||
| 1524 | status = dmm_get_handle(p_proc_object, &dmm_mgr); | ||
| 1525 | if (!dmm_mgr) { | ||
| 1526 | status = -EFAULT; | ||
| 1527 | goto func_end; | ||
| 1528 | } | ||
| 1529 | |||
| 1530 | status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr); | ||
| 1531 | func_end: | ||
| 1532 | dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p " | ||
| 1533 | "status 0x%x\n", __func__, hprocessor, | ||
| 1534 | ul_size, pp_rsv_addr, status); | ||
| 1535 | return status; | ||
| 1536 | } | ||
| 1537 | |||
| 1538 | /* | ||
| 1488 | * ======== proc_start ======== | 1539 | * ======== proc_start ======== |
| 1489 | * Purpose: | 1540 | * Purpose: |
| 1490 | * Start a processor running. | 1541 | * Start a processor running. |
| @@ -1632,6 +1683,7 @@ int proc_un_map(void *hprocessor, void *map_addr, | |||
| 1632 | { | 1683 | { |
| 1633 | int status = 0; | 1684 | int status = 0; |
| 1634 | struct proc_object *p_proc_object = (struct proc_object *)hprocessor; | 1685 | struct proc_object *p_proc_object = (struct proc_object *)hprocessor; |
| 1686 | struct dmm_object *dmm_mgr; | ||
| 1635 | u32 va_align; | 1687 | u32 va_align; |
| 1636 | u32 size_align; | 1688 | u32 size_align; |
| 1637 | 1689 | ||
| @@ -1641,11 +1693,23 @@ int proc_un_map(void *hprocessor, void *map_addr, | |||
| 1641 | goto func_end; | 1693 | goto func_end; |
| 1642 | } | 1694 | } |
| 1643 | 1695 | ||
| 1696 | status = dmm_get_handle(hprocessor, &dmm_mgr); | ||
| 1697 | if (!dmm_mgr) { | ||
| 1698 | status = -EFAULT; | ||
| 1699 | goto func_end; | ||
| 1700 | } | ||
| 1701 | |||
| 1644 | /* Critical section */ | 1702 | /* Critical section */ |
| 1645 | mutex_lock(&proc_lock); | 1703 | mutex_lock(&proc_lock); |
| 1704 | /* | ||
| 1705 | * Update DMM structures. Get the size to unmap. | ||
| 1706 | * This function returns error if the VA is not mapped | ||
| 1707 | */ | ||
| 1708 | status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align); | ||
| 1646 | /* Remove mapping from the page tables. */ | 1709 | /* Remove mapping from the page tables. */ |
| 1647 | status = user_to_dsp_unmap(p_proc_object->hbridge_context->dsp_mmu, | 1710 | if (!status) |
| 1648 | va_align); | 1711 | status = user_to_dsp_unmap( |
| 1712 | p_proc_object->hbridge_context->dsp_mmu, va_align); | ||
| 1649 | 1713 | ||
| 1650 | mutex_unlock(&proc_lock); | 1714 | mutex_unlock(&proc_lock); |
| 1651 | if (status) | 1715 | if (status) |
| @@ -1656,7 +1720,7 @@ int proc_un_map(void *hprocessor, void *map_addr, | |||
| 1656 | * from dmm_map_list, so that mapped memory resource tracking | 1720 | * from dmm_map_list, so that mapped memory resource tracking |
| 1657 | * remains uptodate | 1721 | * remains uptodate |
| 1658 | */ | 1722 | */ |
| 1659 | remove_mapping_information(pr_ctxt, (u32) map_addr); | 1723 | remove_mapping_information(pr_ctxt, (u32) map_addr, size_align); |
| 1660 | 1724 | ||
| 1661 | func_end: | 1725 | func_end: |
| 1662 | dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n", | 1726 | dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n", |
| @@ -1665,6 +1729,36 @@ func_end: | |||
| 1665 | } | 1729 | } |
| 1666 | 1730 | ||
| 1667 | /* | 1731 | /* |
| 1732 | * ======== proc_un_reserve_memory ======== | ||
| 1733 | * Purpose: | ||
| 1734 | * Frees a previously reserved region of DSP address space. | ||
| 1735 | */ | ||
| 1736 | int proc_un_reserve_memory(void *hprocessor, void *prsv_addr, | ||
| 1737 | struct process_context *pr_ctxt) | ||
| 1738 | { | ||
| 1739 | struct dmm_object *dmm_mgr; | ||
| 1740 | int status = 0; | ||
| 1741 | struct proc_object *p_proc_object = (struct proc_object *)hprocessor; | ||
| 1742 | |||
| 1743 | if (!p_proc_object) { | ||
| 1744 | status = -EFAULT; | ||
| 1745 | goto func_end; | ||
| 1746 | } | ||
| 1747 | |||
| 1748 | status = dmm_get_handle(p_proc_object, &dmm_mgr); | ||
| 1749 | if (!dmm_mgr) { | ||
| 1750 | status = -EFAULT; | ||
| 1751 | goto func_end; | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr); | ||
| 1755 | func_end: | ||
| 1756 | dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n", | ||
| 1757 | __func__, hprocessor, prsv_addr, status); | ||
| 1758 | return status; | ||
| 1759 | } | ||
| 1760 | |||
| 1761 | /* | ||
| 1668 | * ======== = proc_monitor ======== == | 1762 | * ======== = proc_monitor ======== == |
| 1669 | * Purpose: | 1763 | * Purpose: |
| 1670 | * Place the Processor in Monitor State. This is an internal | 1764 | * Place the Processor in Monitor State. This is an internal |
