Ignore:
File:
1 edited

Legend:

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

    r9d58539 r6eeb4a3  
    4242#include <errno.h>
    4343#include <arch/cpu.h>
     44#include <cpu.h>
    4445#include <arch.h>
    4546#include <align.h>
    46 
    47 /** Enable I/O space range for task.
    48  *
    49  * Interrupts are disabled and task is locked.
    50  *
    51  * @param task   Task.
    52  * @param ioaddr Startign I/O space address.
    53  * @param size   Size of the enabled I/O range.
    54  *
    55  * @return 0 on success or an error code from errno.h.
    56  *
    57  */
    58 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
    59 {
    60         size_t bits = ioaddr + size;
    61         if (bits > IO_PORTS)
    62                 return ENOENT;
    63        
    64         if (task->arch.iomap.bits < bits) {
    65                 /*
    66                  * The I/O permission bitmap is too small and needs to be grown.
    67                  */
    68                
    69                 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
    70                 if (!newmap)
    71                         return ENOMEM;
    72                
    73                 bitmap_t oldiomap;
    74                 bitmap_initialize(&oldiomap, task->arch.iomap.map,
    75                     task->arch.iomap.bits);
    76                 bitmap_initialize(&task->arch.iomap, newmap, bits);
    77                
    78                 /*
    79                  * Mark the new range inaccessible.
    80                  */
    81                 bitmap_set_range(&task->arch.iomap, oldiomap.bits,
    82                     bits - oldiomap.bits);
    83                
    84                 /*
    85                  * In case there really existed smaller iomap,
    86                  * copy its contents and deallocate it.
    87                  */
    88                 if (oldiomap.bits) {
    89                         bitmap_copy(&task->arch.iomap, &oldiomap,
    90                             oldiomap.bits);
    91                         free(oldiomap.map);
    92                 }
    93         }
    94        
    95         /*
    96          * Enable the range and we are done.
    97          */
    98         bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
    99        
    100         /*
    101          * Increment I/O Permission bitmap generation counter.
    102          */
    103         task->arch.iomapver++;
    104        
    105         return 0;
    106 }
    10747
    10848/** Install I/O Permission bitmap.
     
    11858        /* First, copy the I/O Permission Bitmap. */
    11959        irq_spinlock_lock(&TASK->lock, false);
     60       
    12061        size_t ver = TASK->arch.iomapver;
    121         size_t bits = TASK->arch.iomap.bits;
    122         if (bits) {
    123                 ASSERT(TASK->arch.iomap.map);
     62        size_t elements = TASK->arch.iomap.elements;
     63       
     64        if (elements > 0) {
     65                ASSERT(TASK->arch.iomap.bits);
    12466               
    12567                bitmap_t iomap;
    126                 bitmap_initialize(&iomap, CPU->arch.tss->iomap,
    127                     TSS_IOMAP_SIZE * 8);
    128                 bitmap_copy(&iomap, &TASK->arch.iomap, bits);
     68                bitmap_initialize(&iomap, TSS_IOMAP_SIZE * 8,
     69                    CPU->arch.tss->iomap);
     70                bitmap_copy(&iomap, &TASK->arch.iomap, elements);
    12971               
    13072                /*
     
    13274                 * I/O access.
    13375                 */
    134                 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits);
     76                bitmap_set_range(&iomap, elements,
     77                    ALIGN_UP(elements, 8) - elements);
     78               
    13579                /*
    13680                 * It is safe to set the trailing eight bits because of the
    13781                 * extra convenience byte in TSS_IOMAP_SIZE.
    13882                 */
    139                 bitmap_set_range(&iomap, ALIGN_UP(bits, 8), 8);
     83                bitmap_set_range(&iomap, ALIGN_UP(elements, 8), 8);
    14084        }
     85       
    14186        irq_spinlock_unlock(&TASK->lock, false);
    14287       
    14388        /*
    14489         * Second, adjust TSS segment limit.
    145          * Take the extra ending byte will all bits set into account.
     90         * Take the extra ending byte with all bits set into account.
    14691         */
    14792        ptr_16_64_t cpugdtr;
     
    14994       
    15095        descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
    151         gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
     96        size_t size = bitmap_size(elements);
     97        gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + size);
    15298        gdtr_load(&cpugdtr);
    15399       
Note: See TracChangeset for help on using the changeset viewer.