Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ddi/ddi.c

    r953bc1ef r2fa10f6  
    4646#include <mm/frame.h>
    4747#include <mm/as.h>
    48 #include <synch/spinlock.h>
     48#include <synch/mutex.h>
    4949#include <syscall/copy.h>
    5050#include <adt/btree.h>
     
    5252#include <align.h>
    5353#include <errno.h>
     54#include <trace.h>
    5455
    5556/** This lock protects the parea_btree. */
    56 SPINLOCK_INITIALIZE(parea_lock);
     57static mutex_t parea_lock;
    5758
    5859/** B+tree with enabled physical memory areas. */
    5960static btree_t parea_btree;
    6061
    61 /** Initialize DDI. */
     62/** Initialize DDI.
     63 *
     64 */
    6265void ddi_init(void)
    6366{
    6467        btree_create(&parea_btree);
     68        mutex_initialize(&parea_lock, MUTEX_PASSIVE);
    6569}
    6670
     
    7276void ddi_parea_register(parea_t *parea)
    7377{
    74         ipl_t ipl = interrupts_disable();
    75         spinlock_lock(&parea_lock);
     78        mutex_lock(&parea_lock);
    7679       
    7780        /*
     
    8083        btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL);
    8184       
    82         spinlock_unlock(&parea_lock);
    83         interrupts_restore(ipl);
     85        mutex_unlock(&parea_lock);
    8486}
    8587
     
    98100 *
    99101 */
    100 static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages, int flags)
     102NO_TRACE static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages,
     103    unsigned int flags)
    101104{
    102105        ASSERT(TASK);
     
    115118        backend_data.frames = pages;
    116119       
    117         ipl_t ipl = interrupts_disable();
    118        
    119120        /* Find the zone of the physical memory */
    120         spinlock_lock(&zones.lock);
     121        irq_spinlock_lock(&zones.lock, true);
    121122        size_t znum = find_zone(ADDR2PFN(pf), pages, 0);
    122123       
     
    125126                 * -> assume it is hardware device and allow mapping
    126127                 */
    127                 spinlock_unlock(&zones.lock);
     128                irq_spinlock_unlock(&zones.lock, true);
    128129                goto map;
    129130        }
     
    131132        if (zones.info[znum].flags & ZONE_FIRMWARE) {
    132133                /* Frames are part of firmware */
    133                 spinlock_unlock(&zones.lock);
     134                irq_spinlock_unlock(&zones.lock, true);
    134135                goto map;
    135136        }
    136137       
    137138        if (zone_flags_available(zones.info[znum].flags)) {
    138                 /* Frames are part of physical memory, check if the memory
     139                /*
     140                 * Frames are part of physical memory, check if the memory
    139141                 * region is enabled for mapping.
    140142                 */
    141                 spinlock_unlock(&zones.lock);
     143                irq_spinlock_unlock(&zones.lock, true);
    142144               
    143                 spinlock_lock(&parea_lock);
     145                mutex_lock(&parea_lock);
    144146                btree_node_t *nodep;
    145147                parea_t *parea = (parea_t *) btree_search(&parea_btree,
    146148                    (btree_key_t) pf, &nodep);
    147149               
    148                 if ((!parea) || (parea->frames < pages))
     150                if ((!parea) || (parea->frames < pages)) {
     151                        mutex_unlock(&parea_lock);
    149152                        goto err;
     153                }
    150154               
    151                 spinlock_unlock(&parea_lock);
     155                mutex_unlock(&parea_lock);
    152156                goto map;
    153157        }
    154158       
     159        irq_spinlock_unlock(&zones.lock, true);
     160       
    155161err:
    156         spinlock_unlock(&zones.lock);
    157         interrupts_restore(ipl);
    158162        return ENOENT;
    159163       
    160164map:
    161         spinlock_lock(&TASK->lock);
    162        
    163165        if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp,
    164166            AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
     
    167169                 * We report it using ENOMEM.
    168170                 */
    169                 spinlock_unlock(&TASK->lock);
    170                 interrupts_restore(ipl);
    171171                return ENOMEM;
    172172        }
     
    175175         * Mapping is created on-demand during page fault.
    176176         */
    177        
    178         spinlock_unlock(&TASK->lock);
    179         interrupts_restore(ipl);
    180177        return 0;
    181178}
     
    191188 *
    192189 */
    193 static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
     190NO_TRACE static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr,
     191    size_t size)
    194192{
    195193        /*
     
    200198                return EPERM;
    201199       
    202         ipl_t ipl = interrupts_disable();
    203         spinlock_lock(&tasks_lock);
     200        irq_spinlock_lock(&tasks_lock, true);
    204201       
    205202        task_t *task = task_find_by_id(id);
     
    211208                 * context.
    212209                 */
    213                 spinlock_unlock(&tasks_lock);
    214                 interrupts_restore(ipl);
     210                irq_spinlock_unlock(&tasks_lock, true);
    215211                return ENOENT;
    216212        }
    217213       
    218214        /* Lock the task and release the lock protecting tasks_btree. */
    219         spinlock_lock(&task->lock);
    220         spinlock_unlock(&tasks_lock);
     215        irq_spinlock_exchange(&tasks_lock, &task->lock);
    221216       
    222217        int rc = ddi_iospace_enable_arch(task, ioaddr, size);
    223218       
    224         spinlock_unlock(&task->lock);
    225         interrupts_restore(ipl);
     219        irq_spinlock_unlock(&task->lock, true);
    226220       
    227221        return rc;
     
    264258}
    265259
    266 /** Disable or enable preemption.
    267  *
    268  * @param enable If non-zero, the preemption counter will be decremented,
    269  *               leading to potential enabling of preemption. Otherwise
    270  *               the preemption counter will be incremented, preventing
    271  *               preemption from occurring.
    272  *
    273  * @return Zero on success or EPERM if callers capabilities are not sufficient.
    274  *
    275  */
    276 unative_t sys_preempt_control(int enable)
    277 {
    278         if (!(cap_get(TASK) & CAP_PREEMPT_CONTROL))
    279                 return EPERM;
    280        
    281         if (enable)
    282                 preemption_enable();
    283         else
    284                 preemption_disable();
    285        
    286         return 0;
    287 }
    288 
    289 /** Disable or enable specified interrupts.
    290  *
    291  * @param irq the interrupt to be enabled/disabled.
    292  * @param enable if true enable the interrupt, disable otherwise.
    293  *
    294  * @retutn Zero on success, error code otherwise.
    295  */
    296 unative_t sys_interrupt_enable(int irq, int enable)
    297 {       
    298         cap_t task_cap = cap_get(TASK);
    299         if (!(task_cap & CAP_PREEMPT_CONTROL) || !(task_cap & CAP_IRQ_REG))
    300                 return EPERM;
    301                
    302         if (irq < 0 || irq > 16) {
    303                 return EINVAL;
    304         }
    305        
    306         uint16_t irq_mask = (uint16_t)(1 << irq);
    307         if (enable) {
    308                 trap_virtual_enable_irqs(irq_mask);
    309         } else {
    310                 trap_virtual_disable_irqs(irq_mask);
    311         }
    312        
    313         return 0;       
    314 }
    315 
    316260/** @}
    317261 */
Note: See TracChangeset for help on using the changeset viewer.