Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/ddi/ddi.c

    r6eeb4a3 r9d58539  
    4646#include <align.h>
    4747
     48/** Enable I/O space range for task.
     49 *
     50 * Interrupts are disabled and task is locked.
     51 *
     52 * @param task   Task.
     53 * @param ioaddr Startign I/O space address.
     54 * @param size   Size of the enabled I/O range.
     55 *
     56 * @return 0 on success or an error code from errno.h.
     57 *
     58 */
     59int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     60{
     61        size_t bits = ioaddr + size;
     62        if (bits > IO_PORTS)
     63                return ENOENT;
     64       
     65        if (task->arch.iomap.bits < bits) {
     66                /*
     67                 * The I/O permission bitmap is too small and needs to be grown.
     68                 */
     69               
     70                uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
     71                if (!newmap)
     72                        return ENOMEM;
     73               
     74                bitmap_t oldiomap;
     75                bitmap_initialize(&oldiomap, task->arch.iomap.map,
     76                    task->arch.iomap.bits);
     77                bitmap_initialize(&task->arch.iomap, newmap, bits);
     78               
     79                /*
     80                 * Mark the new range inaccessible.
     81                 */
     82                bitmap_set_range(&task->arch.iomap, oldiomap.bits,
     83                    bits - oldiomap.bits);
     84               
     85                /*
     86                 * In case there really existed smaller iomap,
     87                 * copy its contents and deallocate it.
     88                 */
     89                if (oldiomap.bits) {
     90                        bitmap_copy(&task->arch.iomap, &oldiomap,
     91                            oldiomap.bits);
     92                        free(oldiomap.map);
     93                }
     94        }
     95       
     96        /*
     97         * Enable the range and we are done.
     98         */
     99        bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
     100       
     101        /*
     102         * Increment I/O Permission bitmap generation counter.
     103         */
     104        task->arch.iomapver++;
     105       
     106        return 0;
     107}
     108
    48109/** Install I/O Permission bitmap.
    49110 *
     
    58119        /* First, copy the I/O Permission Bitmap. */
    59120        irq_spinlock_lock(&TASK->lock, false);
    60        
    61121        size_t ver = TASK->arch.iomapver;
    62         size_t elements = TASK->arch.iomap.elements;
    63        
    64         if (elements > 0) {
    65                 ASSERT(TASK->arch.iomap.bits);
     122        size_t bits = TASK->arch.iomap.bits;
     123        if (bits) {
     124                ASSERT(TASK->arch.iomap.map);
    66125               
    67126                bitmap_t iomap;
    68                 bitmap_initialize(&iomap, TSS_IOMAP_SIZE * 8,
    69                     CPU->arch.tss->iomap);
    70                 bitmap_copy(&iomap, &TASK->arch.iomap, elements);
     127                bitmap_initialize(&iomap, CPU->arch.tss->iomap,
     128                    TSS_IOMAP_SIZE * 8);
     129                bitmap_copy(&iomap, &TASK->arch.iomap, bits);
    71130               
    72131                /*
     
    74133                 * I/O access.
    75134                 */
    76                 bitmap_set_range(&iomap, elements,
    77                     ALIGN_UP(elements, 8) - elements);
    78                
     135                bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits);
    79136                /*
    80137                 * It is safe to set the trailing eight bits because of the
    81138                 * extra convenience byte in TSS_IOMAP_SIZE.
    82139                 */
    83                 bitmap_set_range(&iomap, ALIGN_UP(elements, 8), 8);
     140                bitmap_set_range(&iomap, ALIGN_UP(bits, 8), 8);
    84141        }
    85        
    86142        irq_spinlock_unlock(&TASK->lock, false);
    87143       
     
    94150       
    95151        descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
    96         size_t size = bitmap_size(elements);
    97         gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + size);
     152        gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
    98153        gdtr_load(&cpugdtr);
    99154       
Note: See TracChangeset for help on using the changeset viewer.